Ресурсы: техническое описание TLS, LaTeX - в картинки (img), криптографическая библиотека Arduino, шифр "Кузнечик" на ассемблере AMD64/AVX и ARM64
В журнале “Интернет изнутри” опубликована моя статья “Постквантовая криптография и практика TLS в браузерах”. Статья, в основном, про то, как “квантовые вычисления” связаны с теоретико-информационной криптографией, и как это влияет на TLS в архитектурном смысле, но также рассмотрен свежий пример с Kyber768 в браузере Chrome.
Цитата:
“Квантовые вычисления в философском смысле – это попытка получить доступ на самом низком, самом прямом и «железячном» уровне к центральному «процессору» (ЦПУ) вселенных, то есть, к необозримому «чипу», на котором, возможно, окружающая действительность исполняется в режиме виртуализации. Это неплохо соответствует фольклорной интерпретации термина «квантовый» в отношении компьютера: элементы полупроводниковых чипов, находящихся внутри этого ящика, становились всё меньше и меньше, и вот, за гонкой нанометровых технологий, ситуация проваливается в квантовые элементы – получите квантовый компьютер. И действительно, пусть сам предполагаемый принцип квантовых вычислений не имеет ничего общего с уменьшением линейных размеров полупроводниковых вентилей и законами Мура, попытки физической реализации квантовых вычислителей уже сейчас подразумевают управление отдельными атомами. Если квантовый компьютер сделать не получится, эти наработки наверняка пригодятся для дальнейшей миниатюризации компьютеров классических. Что же касается теоретико-информационной криптографии, то она, похоже, выигрывает и тут.”
Комментировать »
Записка про процесс валидации TLS-сертификатов, сопоставления сертификата с TLS-узлом и аутентификации этого узла; всё – на примере TLS для веба (то есть, “HTTPS в браузерах”).
Валидация – это проверка и подтверждение того, что сертификат действует, соответствует сценарию использования ключа и подписан доверенным Удостоверяющим Центром (УЦ или CA в английском варианте). Аутентификация, в данном случае, состоит в проверке соответствия имён (в сертификате и в параметрах соединения) и получении подтверждения, что аутентифицируемый узел имеет доступ к секретному ключу, соответствующему открытому ключу из сертификата.
В самом первом приближении, процесс может быть описан весьма просто, однако внутри есть большое количество важных деталей. Некоторые из этих деталей рассмотрены в данной записке. В качестве примера здесь используется типичный сценарий работы с веб-сайтом по HTTPS: то есть, современный веб-браузер в качестве клиента, а современный веб-сервер – в качестве, как нетрудно угадать, сервера.
Для описания процесса, прежде всего, важны три типа сертификатов:
1) сертификат доверенного УЦ; обычно, это самоподписанный сертификат (см. ниже), который содержит открытый ключ корневого доверенного УЦ, список таких сертификатов входит либо в дистрибутив браузера, либо в дистрибутив операционной системы;
2) сертификат промежуточного УЦ; это как раз пункт, который традиционно является источником многих хитрых деталей; промежуточный УЦ возникает потому, что непосредственно от корневых ключей “обычные” (оконечные) сертификаты сейчас на практике не выпускают, а выпускают сертификаты промежуточных УЦ – секретные ключи, соответствующие открытым ключам из этих сертификатов, служат для подписи оконечных сертификатов, которые описаны в следующем пункте;
3) оконечный, серверный сертификат – это сертификат, который является, так сказать, целью проверки; он выпущен для сетевого имени, соответствующего параметрам (контексту) соединения, а секретный ключ, соответствующий открытому, должен быть известен серверу (либо должен быть доступ к операциям с этим ключом); именно оконечный сертификат непосредственно используется при установлении соединения для аутентификации сервера клиентом (бывают ещё клиентские оконечные сертификаты, схема валидации там такая же, но работает на стороне сервера; здесь случай клиентского сертификата не рассматриваем).
В ходе валидации выстраивается так называемая “цепочка доверия”. Цепочка выстраивается при помощи проверки подписей на сертификатах, но не только. Эта цепочка – иерархия сертификатов, в которой они соединяются по соответствию имён и открытых ключей. В сертификатах есть поля Issuer/Subject. Issuer – “Издатель”, название того УЦ, который этот сертификат выпустил. Subject – “Субъект”, название, к которому этот сертификат привязывает опубликованный в нём открытый ключ при помощи подписи от ключа Issuer (“Издателя”).
Например, для dxdt.ru цепочка может быть такой (здесь корневой сертификат – слева, ISRG Root X1, а “доверие” распространяется справа налево): ISRG Root X1 — R3 — dxdt.ru. Открытые ключи привязываются в этой цепочке к именам при помощи проверки подписей. Если проверка удалась, то ключ – верный. Ключи и имена обычно используются парой (в принципе, в списке может оказаться несколько одинаковых имён с разными ключами, хоть так быть и не должно, – в таком случае, приоритет будет у значения ключа).
Для корневого УЦ сертификат является просто контейнером ключа, этот сертификат “самоподписанный” – то есть, подпись от того же ключа, открытое представление которого указано в сертификате, совпадающие значения Issuer и Subject. На других сертификатах подпись вычисляется от ключа, соответствующего другому сертификату (на него тоже указывает имя из Issuer).
Для всех сертификатов цепочки должно быть проверено время действия. В сертификате, в специальных полях, записаны метки времени, обозначающие два момента: когда сертификат начинает действовать и когда сертификат заканчивает действовать (это время GMT с точностью до секунд). Сертификат не должен приниматься за пределами указанного интервала: то есть, сертификат может не только истечь (закончился срок действия, обычное дело), но может ещё не начать действовать (а это весьма экзотический для веба случай).
Все сертификаты в цепочке содержат указания на то, как можно использовать ключи, указанные в этих сертификатах. Например, сертификаты УЦ содержат флаг, который обозначает, что (секретный) ключ может использоваться для подписывания других сертификатов и, например, для подписывания списков отзыва (см. ниже). Это всё помимо отдельного флага, обозначающего, что данный сертификат – сертификат УЦ. Использование ключа должно соответствовать схеме проверки – например, валидатор не должен принимать сертификат, подписанный от ключа, (доверенный) сертификат которого не содержит флага УЦ или флагов, разрешающих подписывание.
Оконечный сертификат сопоставляется по имени с именем узла, с которым браузер пытается установить соединение. Это часть процесса аутентификации узла, использующая сертификат существенным образом. Современные спецификации таковы, что тут учитывается не имя узла из поля Subject, как можно подумать. В TLS-сертификатах есть специальное расширение SAN (Subject Alternative Name), где могут быть перечислены дополнительные имена. Именно тут должно быть указано имя сервера. Например, dxdt.ru. Иначе, согласно спецификациям валидации для современного веба, которым следуют браузеры, сертификат будет невалидным для заданного имени (даже если имя указано в Subject).
Сертификаты могут быть отозваны до достижения ими срока окончания действия. Поэтому, в теории, для каждого сертификата в цепочке валидации должен быть проверен его статус (отозван или нет). В практике веба отзыв проверяется далеко не всегда. Есть два базовых способа проверки статуса сертификата – файл со списком серийных номеров отозванных сертификатов (CRL – Certificate Revocation List) и респондер протокола OCSP (Online Certificate Status Protocol); а есть специальные способы, поддерживаемые современными браузерами, например, Chrome/Chromium, и серверами. Специальные способы возникли потому, что всякое обращение к сервисам проверки статусов сертификатов раскрывает некоторую информацию о сессии браузера в сторону УЦ. Вести сервисы статуса непосредственно могут только либо сами УЦ, либо организации, которым УЦ прямо поручили реализацию такой функции, это связано с необходимым доверием, чтобы сертификаты не могли “отзывать” произвольные участники системы. Поэтому, при типовых схемах, УЦ будет узнавать о проверках статуса и видеть имена, к которым были обращения. Но можно предложить способы различного “проксирования” статусов сертификатов: сюда относятся “концентраторы” списков отзывов – пример: OneCRL, – записи “слепков” ответов OCSP – OCSP stapling, – и включение статичных списков отзыва в состав обновлений браузера (это, прежде всего, Chrome, но для важных сертификатов используют и другие браузеры, например, Firefox).
О том, где можно проверить статус сертификата, валидатор может узнаёт из состава сертификата. Адреса узлов, публикующих CRL (списки отзыва), адреса OCSP-респондеров – прямо указаны в специальных расширениях.
С отзывом сертификатов связаны два практических вывода: 1) отзыв сертификатов и корректное “оборачивание” его в необходимые сервисы – одна из больших проблем для всякого УЦ; 2) в современном вебе отзыв сертификатов сайтов, фактически, не работает (но эту неработоспособность уже несколько лет активно пытаются компенсировать внедрением сертификатов с коротким сроком действия).
Если все подписи цепочки сошлись, то, в результате успешной валидации, браузер получает доверенный открытый ключ сервера – этот ключ содержится в оконечном сертификате. Остаётся ещё один важнейший шаг аутентификации узла: нужно проверить, что узел, приславший валидный сертификат, имеет доступ к соответствующему секретному ключу. В современных версиях TLS это реализуется при помощи подписывания сервером сообщения, состав которого определяется клиентом (чтобы нельзя было подготовить заранее подписанное сообщение). Если клиент успешно проверил подпись, полученную от сервера, при помощи ключа из сертификата, то сервер считается аутентифицированным (соответствие имён проверено раньше).
Ссылка по теме: техническое описание TLS (где про сертификаты не так много, поскольку их техническое значение в TLS не очень велико, так как основное их значение – административное).
Комментировать »
Скриншот из издания “Элементов” Евклида на английском (первый перевод, Henry Billingsley), 1570 год. Кстати, настоящий язык Шекспира: whereunto и пр. Автором “Элементов”, как нетрудно прочитать, здесь обозначен Евклид из Мегары, а не просто Евклид (то есть, Евклид из Александрии); это, впрочем, обычное, – пусть и немного загадочное, – дело для старых публикаций.

Комментарии (5) »
Попался забавный корпус для Raspberry Pi 5 (RPi) – на Aliexpress он называется Armor Case v5, заявлено, что сделан из “алюминиевого сплава”. Корпус этот работает как один большой радиатор, поэтому внутри предусмотрены контактные площадки для отвода тепла от элементов Raspberry Pi. Теплопроводное соединение обеспечивается через мягкие прокладки, которые нужно наклеить при сборке. Прокладки идут в комплекте (см. картинку).

Большая прокладка слева, белая, внутри корпуса, – для нижней части платы; меньшие прокладки – лежат ещё левее, вместе с винтами, они наклеиваются на соответствующие “колонны”, которые сделаны в верхней части корпуса (справа на картинке), эти “колонны” попадают на горячие элементы RPi. То есть, это правильный способ отвода тепла, который работает даже для герметичных корпусов (тут можно вспомнить всякие специальные газоанализаторы, безопасные блоки питания и тому подобные изделия, кому с чем приходилось сталкиваться). Этот корпус собирается из двух частей, которые фиксируются прилагаемыми винтами. Он, конечно, не герметичный, но всё равно сделан довольно тесным: все точки крепления подходят, однако втиснуть туда плату RPi не так просто. Это, впрочем, преодолимо, а основные проблемы при сборке доставило отверстие для кнопки питания и прилагаемый к нему мягкий “клапан”, который больше мешает. В целом – корпус хороший.

Собранный корпус выглядит довольно прочным, каких-то вентиляционных отверстий нет, но RPi, действительно, охлаждается приемлемо. Особо точных тестов я не проводил, но под нагрузкой на всех ядрах процессор не разогревается выше 58 градусов Цельсия. Это по показаниям встроенного датчика, поэтому как там реально – не очень понятно, но “троттлинга” не наблюдается. Зато наблюдается, что при этом до 47 градусов разогревается сам корпус, целиком; впрочем, вполне предсказуемый результат.
Комментировать »
Предположим, найдены два различных сообщения, для которых значения (криптографической) хеш-функции отличаются только в одном байте (то есть, всего несколько близких битов различаются). Пусть разрядность хеш-функции 256 бит, то есть 32 байта. Заметьте: тут важна и локализация отличий – не просто несколько битов, но ещё и в одном байте. Что именно обнаружение таких сообщений означает для хеш-функции? Как ни странно, но, без прочих обстоятельств, – практически ничего нового, кроме того, что хеш-функцию, эмпирически, станут считать менее стойкой: то, что два сообщения с описанным свойством существуют – и так было известно.
Другое дело, если предъявлен метод, позволяющий быстро находить пары сообщений с близкими значениями хеш-функции. Тогда, конечно, хеш-функция перестаёт быть действительно криптографической. Однако и в случае предъявления метода возникают всякие оговорки. Близки ли входные сообщения из пары? (Кстати, тут можно вспомнить, про нужные в некоторых задачах хеш-функции (не криптографические) с “хорошей” локализацией, – LSH.) Если близки, то как метод поиска таких сообщений связан с алгоритмом хеш-функции? Можно ли успешно отыскать сообщение, парное к заданному? Известны ли свойства получающихся разбиений? Поднимается ли структура разбиений в алгоритм поиска их представителей (то есть, можно ли записать формулу разбиений)? В общем, много уточнений.
Очевидно, впрочем, что возможность быстрого нахождения близких по значению входных сообщений, дающих близкие же, до одного отличающегося байта, значения хеш-функции, позволяет хеш-функцию сломать совсем (для перебора остаются небольшие сегменты, соответствующие различным битам в найденных значениях). Но это если находить нужные пары сообщений можно быстро.
На поиске близких значений хеш-функций, например, построена схема доказательства работы в протоколе цифровой валюты Биткойн (и далеко не только там). В биткойн-сети узлы должны подбирать входные массивы так, чтобы значение хеш-функции от них было меньше заданного порога (параметр “сложности”), это означает, что несколько старших байтов записи подряд должны быть нулевыми. То есть, все использованные значения хеш-функций (SHA-256) совпадают по нескольким последовательным крайним байтам. Эта ситуация, конечно, отличается от описанной в предыдущем абзаце, но только тем, что тут совпадает меньшее количество байтов (в исходной идее требуется различие, максимум, в одном байте). При этом, в случае с биткойнами, довольно велика вероятность того, что в ходе работы сети “майнеров” либо уже были обнаружены полноценные коллизии SHA-256, либо такие коллизии будут обнаружены в течение нескольких лет (если ничего не изменится кардинально, конечно). Это так не только по причине парадокса дней рождения, но и из-за возможных дефектов SHA-256. Другое дело, что такие коллизии вряд ли кто-то заметил – объёмов памяти для хранения всех перебираемых значений нет в принципе.
Комментировать »
Цитата из внутреннего бюллетеня АНБ “Tales Of the Krypt“, 1995 год. Это небольшой фрагмент саркастически-юмористического отзыва об известной конференции CRYPTO, со страницы 257 (перевод – ниже):

CRYPTO is a worthwhile meeting for NSAers to attend because it provides a window into the “academic” cryptologic community. Their “cryptology” is quite different from ours, reflecting the difference in their background, their goals, and their methods. They write books and papers which seem to be completely unrelated to what we think of as cryptology. Many of them would be unhappy (and very unsuccessful) as NSA employees.
(CRYPTO это дельная конференция для посещения сотрудниками АНБ [буквально: “для аэнбешников”], потому что она открывает окно в “академическое” криптологическое сообщество. Их “криптология” весьма отличается от нашей, отражая, тем самым, отличие их бэкграунда, их целей, их методов. Они пишут книги и статьи, которые выглядят как совсем не относящиеся к тому, что мы считаем криптологией. Многие из них были бы недовольными (и весьма неуспешными) сотрудниками АНБ.)
Кстати, в той же заметке, помимо доклада LAN Crypto, упоминается распространявшаяся в рамках конференции статья про (старый) ГОСТ-алгоритм электронной подписи.
(via)
Комментировать »
В марте довольно много писали про новую атаку на SHA-256, “с обнаружением коллизий”. Вообще, тут нужно отделять академические атаки от практики, условно говоря, всяких биткойнов: в исходной работе (“New Records in Collision Attacks on SHA-2”, Li, Liu, Wang) речь идёт про академические атаки на урезанную “функцию сжатия” (см. ниже) из состава SHA-2 (SHA-256 – это разновидность SHA-2), да ещё и со специально подобранным предыдущим состоянием. Это общепринятый подход к исследованию стойкости хеш-функций, результат существенно лучше предыдущих достижений, но нужно учитывать, что он не обязательно приводит к практической атаке на полную хеш-функцию. В статье сказано именно про “практическую атаку”, это верно, однако это разная “практика”.
Возьмём в качестве примера SHA-256 и одну из практических (в академическом смысле) атак, представленных в упомянутой выше работе. Ядром схемы хеш-функции SHA-256 являются преобразования, соответствующие симметричному шифру. Повторно выполняемые раунды преобразований шифра, внутри хеш-функции, и образуют так называемую “функцию сжатия” – это важнейший элемент. Входной текст для преобразования в SHA-256 разбивается на блоки. Блок – это последовательность байтов, соответствующая разрядности функции, здесь – 256 бит или 32 байта. Блоки обрабатываются функцией сжатия, внутри которой выполняется заданное количество раундов – то есть, повторное применение одних и тех же преобразований, в цикле, к обрабатываемому блоку. Далее речь будет идти только про один блок, а не про полный входной текст.
После каждого раунда, блок, в результате применения преобразований, изменяется и потом снова подвергается тем же преобразованиям, которые опять изменяют блок. Эта комбинаторная часть позволяет добиться нужного разрежения для отображения входных блоков в выходные значения. Штатная схема SHA-256 использует 64 раунда в функции сжатия. Атака, о которой идёт речь, работает для 39 раундов (обратите внимание: с подобранным начальным состоянием – это очень важный момент).
Что это означает? Это означает, что исследователи нашли и предъявили кортеж из трёх конкретных значений (чисел или массивов байтов – как хотите), которые, будучи подставленными в урезанную до 39 раундов сжатия версию хеш-функции SHA-256, дают одинаковый результат. Одно из этих значений – это начальное состояние, устанавливаемое перед вызовом функции сжатия внутри урезанной SHA-256. То есть, при штатной реализации SHA-256 – этим состоянием либо был бы предыдущий обработанный блок, либо начальные константы из спецификации SHA-256. Два других упомянутых значения – это различающиеся в некоторых байтах входные блоки. Обработка этих блоков при указанных, весьма строгих, условиях – даёт коллизию. То есть, академическая “практическая” демонстрация, с конкретными числами. Это вполне себе строгий и разумный способ анализа стойкости преобразований. В данной науке это называется SFS-коллизия (от Semi-Free-Start). Но, опять же, очень далеко от демонстрации реальной, практической, “уничтожающей” коллизии SHA-256, то есть, демонстрации двух различных входных текстов, дающих одинаковый результат хеш-функции. (Что, конечно, не отменяет заметного продвижения.)
Сколько раундов для функции сжатия вообще важны? Важны все раунды, указанные в спецификации. Каждый раунд очень важен и блокирует атаки, успешные для урезанных вариантов. Раунды именно для этого и служат. Потому что, если значение хеш-функции изменяется даже только в результате последнего раунда, то на выходе всё равно получаются разные значения и, строго говоря, коллизии нет (но может быть “почти коллизия” и т.д.).
Естественно, обнаружение точек совпадения для уменьшенного количества раундов нередко даёт инструменты для взлома всей хеш-функции целиком. Именно поэтому академические атаки на примитивы с урезанным количеством раундов – важнейший инструмент. Однако, является ли тот факт, что коллизия найдена для более чем половины количества раундов, автоматической гарантией успешного применения того же метода к, предположим, половине оставшейся половины? Нет, совсем не является. Методы тут развиваются, так сказать, полностью “нелинейно”, так что непреодолимое вычислительное препятствие может возникнуть хоть бы и на каждом следующем раунде – потребуется полностью переделать метод атаки. Собственно, это очередное улучшение атак на SHA-2 как раз построено на новых методах, если сравнивать с теми методами, которые использовали для атак на MD5 и пр.
Конкретный пример, взятый из исходной работы: для 39 раундов SHA-256, при заданном начальном состоянии, получаются совпадающие значения для разных входных блоков (выдача программы, прилагаемой к работе):
431cadcd ce6893bb d6c9689a 334854e8 3baae1ab 038a195a ccf54a19 1c40606d 431cadcd ce6893bb d6c9689a 334854e8 3baae1ab 038a195a ccf54a19 1c40606d
Можно было бы предположить, что раз точка совпадения найдена, то и дальнейшие раунды дадут одинаковые результаты. Но это далеко не так – состояние хеш-функции шире, чем конкретный результат преобразования блока. Так, если в той же программе указать 42 раунда (всего на три раунда больше), то значения уже заметно разойдутся:
d33c0cff 17c9de13 21f528f0 3362e217 563f1779 521a1b9c df062e86 19fb5973 105d6c34 43ceb0ad 120ba1a0 3362e217 d6dd86e0 7da567b5 cf1ca736 19fb5973
Это, ещё раз, никак не уменьшает ценности результата для 39 раундов, но показывает, что для полной SHA-256 всё, – пока что, – хорошо.
Криптографические хеш-функции отображают сообщения произвольной длины в блоки фиксированной длины, так что, математически, коллизии там есть по определению. Другое дело, что если хеш-функция хорошо отображает множество входных текстов в, скажем, 2^256 выходных значений, то о коллизиях “на полном переборе” можно не особенно задумываться: мало кто может создать и записать даже 2^128 текстов. Атаки с обнаружением точек совпадения в функции сжатия как раз, потенциально, выявляют дефекты отображения, которые могут позволить найти коллизии без необходимости полного перебора. А возможно, что и позволят найти способы решения гораздо более сложной задачи вычисления прообраза, – то есть, подбора входного текста по значению хеш-функции.
Комментировать »
Некоторые избранные записки, опубликованные в марте 2024 года:
Алгоритмы преобразования в биометрии – процесс сравнения биометрических данных, который реализуют аппаратные и программные системы проверки, всегда связан с потерей точности; эта потеря точности – ведёт к потере избирательности; в результате оказывается, что для таких практических систем вообще не работает декларируемое предположение вида “биометрические показатели строго индивидуальны”.
Варп и квантовые компьютеры – необычная записка о борелевском шамане, который выигрывает у теоретического квантового компьютера с теоретическим алгоритмом Шора потому, что шаман лучше слышит ритм.
Компиляторы и ассемблер – современные компиляторы генерируют хороший машинный код, но место для использования разработчиком ассемблера всё равно остаётся; потому что компилятор – это, пока ещё, не разработчик.
Спутниковый радар Umbra – пример, – в картинках, – работы системы радаров, находящихся на низкоорбитальных спутниках.
Архитектура микропроцессоров и изоляция уровней исполнения – простой конвейерный “префетчер” команд использовался ещё в микропроцессоре Intel 8086, однако для “уязвимостей” типа Metdown/Spectre требуется ещё два шага: “префетчер” должен получить ветвящуюся логику, управляемую теми же кодами команд, которые “префетчер” обрабатывает, а для процессора в целом должно быть декларировано аппаратное разделение многих исполняемых потоков команд на базе общих для этих потоков элементов аппаратуры.
Комментировать »
Воскресное чтение манускриптов. Ну или не столько чтение, сколько рассматривание чертежей. В этот раз – продолжение манускрипта Vat.gr 1164, который уже упоминался в записке про баллисту инженера-конструктора Герона. На скриншоте ниже – фрагмент из труда “Полиоркетика” Аполлодора Дамасского. Да, в одну книгу, формируемую библиотекарями скрипториев, входили разные труды разных авторов (Герона и Аполлодора, например), нередко, в формате, так сказать, хрестоматии. Тут почти целую страницу занимает схема атаки отдельной круглой крепостной башни при помощи некоторой “огневой машины”.

Как объясняется в тексте, предшествующем чертежу, машина использует угольную топку и меха для создания огня, а двойную железную (наверное, стальную) трубу – для доставки этого огня на атакуемую стену, всё с целью “расшатывания” каменной кладки. Насколько подобный метод был реализуем и, в случае успешной реализации, эффективен – судить довольно трудно.
Комментировать »
Касательно свежей истории с обнаружением закладки/бэкдора (CVE-2024-3094) в пакете xz (liblzma), которая на системах с systemd/glibc, потенциально, протягивалась в sshd: понятно, что такого может быть ещё много в уже массово используемых библиотеках, но всё равно это весьма неплохая и практическая демонстрация того, что подобное удаётся быстро обнаружить силами сообщества. По этой теме я не так давно писал, что, во-первых, добавление закладок и прочего вредоносного кода – это совсем не какая-то особенность Open Source; во-вторых – доступность исходников связана с возможностями по добавлению и обнаружению вредоносного кода, но вовсе не так прямо, как часто говорят и пишут.
Комментировать »
В продолжение предыдущей записки. Различные “аппаратурные” атаки, типа разновидностей Spectre/Meltdown, которые преодолевают механизмы разграничения доступа современных процессоров, имеют интересную связь с концепцией “диагонализации”: то есть, такие атаки всегда возможны, если только процессор пытается оптимизировать использование вычислительных ресурсов достаточно сложным способом. Под “достаточно сложным” тут подразумевается наличие механизмов вида “предикторов” (упреждающего анализа потока команд), задействованных на уровне над “межпотоковым” взаимодействием.
Вообще, в x86 “префетчинг” (предварительное извлечение) кодов команд появился ещё в микропроцессоре 8086. Но тогда соответствующая схема считалась просто конвейером команд. Это был отдельный компонент, со своими регистрами и системой счётчиков, который асинхронно считывал коды команд с внешней шины, когда та была свободна, что существенно ускоряло работу процессора. Понятно, что в 8086 не было ни каких-то особых механизмов аппаратного разграничения потоков команд и адресного пространства, ни обособленных полноценных ядер, исполняющих код, так что и проблем с побочными эффектами от работы схем конвейера тоже быть ещё не могло. Однако состояние этого конвейера, вмещавшего всего несколько кодов (четыре 8-битных регистра), изменяло состояние процессора вне зависимости от исполняемой основным “протоядром” команды, поскольку конвейер содержал пару указателей, несколько флагов и т.д. Впрочем, технические детали устройства исторического микропроцессора тут не важны – важно, что, во-первых, этот простой конвейер работал только на уровне последовательности кодов команд (не со свойствами самих команд); во-вторых, не было потоков и общих элементов, совместно используемых этими потоками.
Отличие “уязвимых” схем современных процессоров в том, что здесь добавляется новый уровень – те самые “предикторы”, оснащённые логикой, которая учитывает уже не порядок кодов команд, а свойства этих команд и состояние процессора, а кроме того, добавляются общие для нескольких потоков элементы (схемы кэширования и пр.) на работу которых прямо влияют предикторы. И, конечно, возникает аппаратное разграничение доступа, которое и предлагается преодолевать при помощи атак, использующих аппаратные уязвимости.
Базовая логика таких атак – использование “оракулов”, сигналы которых пробивают границы, устанавливаемые (формально) аппаратной архитектурой процессора для фрагментов программного кода. Тут нужно учитывать, что границы эти только декларируются, а в реальности – сигналы через них проходят (иначе тут не было бы предмета), потому что процессору необходимо оптимизировать исполнение кода и доступ к памяти. Эти сигналы обязательно будут возникать именно потому, что в процессоре появился уровень, исполняющий “программу над программой”: упреждающий анализ команд работает по собственной программе (пусть и записанной непосредственно в аппаратуре); эта программа не только использует все потоки и фрагменты кода в качестве входных данных, но и влияет на состояние общих для изолируемых фрагментов кода элементов (кэш и очереди команд). То есть, схема аппаратной оптимизации тут всегда будет сквозной, можно сказать, что неустранимой. Вопрос в том, нужно ли считать такую архитектурную черту уязвимостью. Получается, что общая программа смотрит на команды в разных потоках и переключает состояние общих элементов, чтобы оптимизировать процесс. Изолируемые процессы находят способ измерения времени переключения состояний и – строится очередная уязвимость.
Если попробовать бороться с возникающими по описанным только что принципам сигналами, но попытаться сохранять общие элементы процессора, то каждый новый слой просто будет приводить к появлению более хитрых способов измерения: многими “атакующими” потоками, по накопленной статистике, ещё как-то. Если в архитектуру процессора, предположим, введут некоторое зашумление переключений кеша и предикторов, то носителем сигнала окажется схема, реализующая зашумление. Всякое подобное усложнение, добавление новых уровней, приводит к тому, что появляются и носители новых сигналов (это и есть “диагонализация”). При этом защита от “уязвимостей” программными методами, снижающими общее быстродействие, выглядит несколько странно, потому что предлагается прилагать дополнительные усилия для создания затруднений в работе оптимизирующих схем, которые и в процессоре уже встроены (то есть, потрачена площадь подложки и элементарные логические узлы), и само ПО при этом всё равно работает на общей аппаратуре.
Радикальное решение предполагает либо полную и точную аппаратную изоляцию уровней и ядер, когда все компоненты продублированы и работают независимо, либо полную замену системы команд (не стоит списывать со счетов, что в x86 уже и некоторые отдельные команды обладают тьюринг-полной реализацией). Однако это противоречит самой идее аппаратурной оптимизации на границе между логическим представлением команд процессора и машинным микрокодом. Да и приведёт внедрение таких методов только к тому, что очередной “пробой изоляции” между потоками выявят на стороне шин и контроллеров, взаимодействующих с ОЗУ и периферийными устройствами.
Комментировать »
Новый