Инженеры из компании Google раскрыли детали уязвимости (CVE-2024-56161), позволяющей обойти механизм проверки цифровой подписи при обновлении микрокода в процессорах AMD на базе 1-4 поколений микроархитектуры Zen. Одновременно под лицензией Apache 2.0 опубликован инструментарий Zentool, разработанный в процессе исследования методов работы с микрокодом в процессорах AMD. Также подготовлено руководство по микроархитектуре RISC86, применяемой в микрокоде AMD, и заметка по созданию собственного микрокода. Показано как можно создавать собственные процессорные инструкции, реализуемые на микрокоде RISC86, менять поведение существующих инструкций и загружать изменения микрокода в процессор.
Для упрощения работы разработан инструментарий Zentool, позволяющий анализировать микрокод, манипулировать микрокодом и создавать патчи, которые можно использовать для изменения микрокода в процессорах AMD Zen.
В дальнейшем разработчики планируют продолжить расширение возможностей инструментария и предоставить своеобразный аналог binutils, но не для традиционного машинного кода, а для микрокода.
В текущем виде в состав Zentool входят такие команды, как “zentool edit” – редактирует параметры файлов с микрокодом, изменяет микрокод и заменяет отдельные инструкции; “zentool print” – выводит информацию о структурах и параметрах микрокода; “zentool load” – загружает микрокод в CPU; “zentool resign” – корректирует цифровую подпись с учётом добавленных в микрокод изменений. В состав также входят утилиты mcas и mcop с реализациями ассемблера и дизассемблера для микрокода.
Возможностей zentool достаточно для подготовки и загрузки в процессор своих патчей c микрокодом. В качестве примера подготовлен патч к микрокоду, меняющий логику работы процессорной инструкции RDRAND. После изменения микрокода инструкция RDRAND начинает возвращать вместо псевдослучайных последовательностей только число 4.
Загрузка собственных патчей для микрокода процессоров AMD Zen 1-4 стала возможна благодаря уязвимости, вызванной использованием в процессе верификации алгоритма имитовставки CMAC вместо надёжной хэш-функции.
Компания AMD устранила уязвимость в декабрьском обновлении микрокода путём замены CMAC на криптографически стойкую хэш-функцию.
Для заверения загружаемого в процессор микрокода цифровой подписью AMD использует закрытый ключ RSA, а в составе патча с микрокодом добавляет открытый ключ. Для проверки, что открытый ключ соответствует оригинальной паре RSA-ключей, процессор выполняет сопоставление хэша от открытого ключа AMD, вшитого во время производства в CPU, с хэшем от открытого ключа, указанного в патче.
Проверка подлинности микрокода в патче осуществляется путём сравнения значения хэша, заверенного цифровой подписью, и хэша, вычисленного на основе фактически поставляемого в патче микрокода. Если эталонный и вычисленный хэши совпадают – патч загружается во внутреннюю память CPU. Таким образом, для организации загрузки фиктивного патча с микрокодом требуется или взлом цифровой подписи на базе RSA или взлом хэш-функции.
В CPU AMD Zen задействован стандартный алгоритм цифровой подписи RSASSA-PKCS1-v1_5, но вместо использования рекомендованных хэш-функций применён алгоритм CMAC, не рассчитанный на подобные операции и не защищённый от подбора коллизий. CMAC не является хэш-функцией, а реализует имитовставку (Message Authentication Code), зависящую от ключа шифрования. Работа AES-CMAC сводится к использованию криптографического алгоритма AES и объединению результата его применения со следующим блоком данных при помощи операции XOR.

Подобная схема гарантирует, что изменение входных данных приведёт к непредсказуемому изменению данных на выходе. При этом CMAC недопустимо использовать в качестве хэш-функции, так как любой кто знает исходный ключ шифрования может узнать промежуточные состояния шифрования и вычислить значения, которые смогут компенсировать изменение во входных данных так, что результат применения CMAC останется неизменным.
AMD применяет для AES-CMAC единый ключ шифрования, поставляемый на всех CPU, начиная с Zen 1 и заканчивая Zen 4. Таким образом, достаточно извлечь данный ключ из любого CPU AMD и он будет применим ко всем остальным CPU. Исследователи обнаружили, что в поколениях процессоров c Zen 1 по Zen 4 для шифрования AES-CMAC использован известный ключ, взятый из примера, упомянутого в рекомендациях по использованию блочных шифров NIST SP 800-38B.
Так как AES-CMAC используется для хэширования вшитого в патч RSA-ключа и содержимого микрокода, определив ключ шифрования AES-CMAC, появилась возможность подстановки в патч другого открытого RSA-ключа и изменения содержимого микрокода. Для создания фиктивного патча достаточно сформировать новый открытый ключ, генерирующий тот же хэш, что формировался подлинным открытым ключом AMD, а также подобрать коллизии для цифровой подписи. Коллизии формируются путём прикрепления к микрокоду добавочного блока, выглядящего как набор случайных данных. Подобным образом можно подготовить изменённый патч с микрокодом, соответствующий цифровой подписи, которой был заверен оригинальный патч от AMD.