Добавить в корзинуПозвонить
Найти в Дзене
DigiNews

Как GNU C Compiler стал «Clippy» в мире криптографии

FOSDEM 2026: Разработчики безопасности вынуждены скрывать булеву логику от излишне усердных оптимизаторов. Современные компиляторы могут нарушать меры безопасности, усложняя работу криптографов. — theregister.com FOSDEM 2026 Создатели программного обеспечения для обеспечения безопасности столкнулись с неожиданным противником в своих попытках защитить нас: современными компиляторами. Современные компиляторы сводят код к наиболее эффективной форме, но при этом могут отменять меры предосторожности. «Современные компиляторы программного обеспечения ломают наш код», — заявил Рене Мойзель, поделившись своими опасениями в ходе выступления на FOSDEM 1 февраля. Мойзель руководит криптографической библиотекой Botan, а также является старшим инженером-программистом в Rohde & Schwarz Cybersecurity. Будучи сопровождающим Botan, Мойзель знает обо всех возможных способах обхода шифрования. Недостаточно просто правильно реализовать математику. Ваше программное обеспечение также должно безопасно шифров
Оглавление

FOSDEM 2026: Разработчики безопасности вынуждены скрывать булеву логику от излишне усердных оптимизаторов. Современные компиляторы могут нарушать меры безопасности, усложняя работу криптографов. — theregister.com

FOSDEM 2026 Создатели программного обеспечения для обеспечения безопасности столкнулись с неожиданным противником в своих попытках защитить нас: современными компиляторами.

Современные компиляторы сводят код к наиболее эффективной форме, но при этом могут отменять меры предосторожности.

«Современные компиляторы программного обеспечения ломают наш код», — заявил Рене Мойзель, поделившись своими опасениями в ходе выступления на FOSDEM 1 февраля.

Мойзель руководит криптографической библиотекой Botan, а также является старшим инженером-программистом в Rohde & Schwarz Cybersecurity.

Будучи сопровождающим Botan, Мойзель знает обо всех возможных способах обхода шифрования. Недостаточно просто правильно реализовать математику. Ваше программное обеспечение также должно безопасно шифровать и дешифровать данные.

Написание кода для выполнения этой задачи может быть сложнее, чем некоторые предполагают. И компиляторы этому не помогают.

Блокировка побочного канала

Мойзель привел пример проблемы, с которой он сталкивается при реализации простой системы входа в систему.

Пользователь вводит пароль, который проверяется по базе данных посимвольно. Как только первый символ не совпадает, возвращается сообщение об ошибке.

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

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

Хорошо, что криптографы от природы параноики. Они уже создали превентивные функции для выравнивания времени ответа пользователю, чтобы оно не было столь показательным. Эти реализации с постоянным временем выполнения «делают время выполнения независимым от пароля», — сказал Мойзель.

Проблема решена? Не если компилятор имеет свои планы

Компилятор GNU C отлично справляется с логическими значениями. Возможно, он слишком умен. На уровне Microsoft Clippy.

Мойзель запустил реализацию с постоянным временем выполнения через GCC 15.2 (с параметрами -std=c++23 -O3).

Цикл проверки символа завершается досрочно, когда символ совпадает, поэтому GCC предположил, что остальная часть функции не нужна. Но остальная часть кода, которая фактически исправляла время выполнения, была отброшена, и уязвимость по побочному каналу снова была раскрыта. Спасибо, GCC.

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

Булевы решения означают ветвление, что дорого для оборудования, поэтому компилятор просто предпочитает преобразовать ваш код с ветвлениями в логику управления без ветвлений, и это здорово, не так ли?

Это что, какая-то булева логика?

Хитрость заключается в том, чтобы скрыть семантику этой маленькой программы от компилятора, посоветовал Мойзель.

Первый шаг — заменить булево значение, которое получает цикл, на двухбитное целое число, и использовать побитовый сдвиг или побитовые операции для маскирования входных данных (Мойзель предоставляет необходимый код в своем докладе, так что ознакомьтесь с слайдами для всех гиковских подробностей).

Вы бы подумали, что этого будет достаточно.

Но GCC умнее. Он может увидеть, когда вы пытаетесь произвести хитрое булево сравнение.

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

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

«Вот как это делается в наши дни», — добавил он.

Удел криптографического кодера

«Теперь вы можете сказать: «Ну, это становится довольно сложным и очень легко сделать ошибку»… и вы будете правы», — сказал Мойзель.

Справедливо ли требовать от среднего программиста понимания встраиваемого ассемблера или любой из этих других, по своей сути, туманных техник обфускации? Не говоря уже о сопровождающих этого программного обеспечения в будущем? И сколько еще токенов потребуется ИИ, чтобы разобраться во всех этих уловках?

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

Другие компиляторы, несомненно, имеют свои особенности. Кто знает, какие ужасы скрываются в Intel C++ Compiler или Clang. И с каждым новым поколением компиляторов появляются новые оптимизации, с которыми приходится бороться, — посетовал Мойзель.

Знайте местность, путешествуйте группами

Из доклада Мойзеля можно сделать несколько выводов, главный из которых: может быть, просто отключить кнопку оптимизации в GCC?

Тем не менее, разработчики компиляторов могут захотеть рассмотреть факторы, отличные от эффективности кода.

«Они хотят сделать ваш код быстрым, и они действительно хороши в этом, но они не учитывают никаких других качественных требований к вашей реализации», — сказал Мойзель.

Как предложил один из слушателей, возможно, однажды компилятор сможет принимать команды, указывающие, какие области кода не следует изменять.

А пока разработчикам программного обеспечения для обеспечения безопасности придется учитывать все части проектируемой ими системы, включая используемые инструменты разработки и то, как они работают.

Для них Мойзель рекомендовал valgrind, инструмент для отладки памяти с открытым исходным кодом. Он может предупредить вас, например, если ваша программа зависит от неопределенного значения.

Наконец, реализация безопасности — это сложно, и не только из-за involved математики. Слишком сложно делать это в одиночку. Не изобретайте велосипед; присоединяйтесь к проекту, посоветовал Мойзель. ®

Всегда имейте в виду, что редакции могут придерживаться предвзятых взглядов в освещении новостей.

Автор – Joab Jackson

Оригинал статьи