Для такого вот аппаратного ключа администратора нам понадобилось провести статический анализ кода. Как мы это делали — в статье.
Добрый день, уважаемые коллеги!
Хотел бы сегодня рассказать о несколько необычном опыте анализа кода. Предваряю возмущение многих – да, мсье действительно знает толк в извращениях 😊
Итак, о них родимых. В одном нашем изделии понадобилось защитить от несанкционированного доступа администраторскую консоль управления, банальный COM-порт с мостиком USB-UART на основе FT232. К сожалению, классическое решение с логином/паролем было обставлено целым частоколом формальных требований в виде (1) срока жизни паролей, (2) логирования успешных/неуспешных попыток, (3) минимальной длины паролей, (4) минимальным их алфавитом, (5) требований к применению больших и малых букв, и цифр, и спезнаков, именно «И», а не «ИЛИ». Перечислять можно бы и дальше, но зачем?
Объехать все эти требования по обочине было решено нестандартным путём – поскольку все требования относились к программному продукту, а про аппаратные устройства ничего не было сказано, то мы просто применили АКА – аппаратный ключ администратора. Он втыкается в разрыв USB-кабеля, идущего от АРМ администратора к устройству, и по свободным линиям обменивается с Изделием сообщениями по схеме challenge-response, не передавая напрямую через линии связи общий секрет, при этом перехват сообщений злоумышленнику не даёт ровно ничего. Если кому интересно, как конкретно это сделано – пишите в комменты или в личку.
Поскольку к историческому моменту принятия решения мы все были в жёстком цейтноте, изготовление АКА поручили стажёру. А он возьми и выбери за основу для разработки «голубую пилюлю (BluePill)» и STM32. Возмущаться, спорить и учить вечному было уже некогда, и тимлид, махнув рукой, согласился. Забегая вперёд, скажу, что отказов и/или сбоев АКА как с самого начала не наблюдалось, так и не наблюдается по сей день. Да, наверное, ПЛК на Ардуине – это уже слишком, но костыль и велосипед проходит вполне (рискую быть бит жёлтыми тряпками, но что было, то было).
Всё это было введение. А теперь про анализ кода. Уполномоченные принимать результат товарищи попросили (таким тоном, что не откажешь) провести ну хотя бы статический анализ кода АКА, чтобы быть уверенными в его качестве. В этом-то и заключалась засада и неприятная неожиданность. Мы рассчитывали на то, что от Ардуинки как от продукта с полностью открытым исходным кодом будет достаточно всех исходников, ан нет.
Шорт-лист продуктов для проверки состоял всего из двух пунктов: Cppcheck и PVS Studio. Гугление, отягощённое признаками ИИ, показало, что последний продукт (А) платный, (Б) больше предназначен для поиска плохо обнаружимых ошибок, не дающих нормально работать гаджету. Жаба оказалась непобедимой и мы выбрали Cppcheck.
Что в Cppcheck хорошо:
-
Можно выбрать нужную архитектуру, STM32 тут имеется. Надо сказать, что работать с кодом для архитектуры ARM Cortex M могут далеко не все анализаторы.
-
Продукт терпим к нестандартному синтаксису, чем обычно знамениты Embedded-приложения.
-
Не требует своего участия в компиляции продукта, работает с чистым исходным кодом.
-
Хорошо детектирует проблемы с неопределённым поведением: с выходом за границы массивов, неинициализированными переменными и утечками памяти.
К сожалению, просто натравить Cppcheck на папку с проектом в Arduino IDE ни к чему хорошему не привело. Первая причина в том, что Arduino IDE по сути работает с неким синтетическим языком (называемым Wired), сделанным в основном из макросов CPP, и пока Cppcheck их все не увидит и не распознает, ничего стоящего не получится.
Вторая причина – Cppcheck по умолчанию не знает, где искать заголовочные файлы для нашего микроконтроллера. Все пути нужно так или иначе указать. И тут вылезает ещё одна засада – сначала мы взяли просто рабочий ноут, на котором разрабатывалось ПО для АКА. Но вот беда – IDE на этом ноуте обросла целой тучей библиотек от других контроллеров, с которыми разработчик имел дело: от ATMega до ESP32. Было даже забавно: первый прогон показал четыре неподключенных библиотеки, мы научили Cppcheck, где их взять, и число нужных include возросло до трёх десятков ☹ В общем, под конец число подключённых библиотек доросло до 6000+
Пришлось собрать «стерильную» IDE на чистом ПК, только с необходимыми библиотеками, и тогда число их немного превышало 2000. В общем, не поленитесь потратить время на чистую сборку – это окупится.
В-третьих, нужно не забыть указать Cppcheck волшебный параметр —platform=arm32-wchar_t4, без которого анализатор не понимает, что имеет дело с архитектурой CortexM.
И наконец, нам оказалось проще расставить в исходном тексте программы в некоторых местах директивы «// cppcheck-suppress <идентификатор_ошибки>», чтобы замаскировать некоторые совсем странные конструкции, которыми иногда пользуется Ардуинка. Опыт показывает, что если этого не делать, то всё равно для того, чтобы аргументированно доказать, что мы имеем дело с ложным срабатыванием анализатора, приходится лезть в исходный код. Пусть уж лучше маскирующая директива и пояснение к ней сразу будут в коде – это экономит время.
К нашему удивлению, Cppcheck на нашем весьма небольшом коде нашёл с десяток недочётов, с которыми автор согласился и исправил. Ещё одно интересное наблюдение – все ошибки находились в написанном нами коде, в библиотеках ни одной Cppcheck не обнаружил. Правда, источником библиотек были Arduino IDE и проект STM32Duino, мусорного кода из сомнительных источников мы не тянули.
В заключение хочу сказать, что если Вам нужно разобраться с нестабильным поведением Вашего Embedded-решения, провести вот прямо очень серьёзный статический анализ, Вы используете серьёзные решения, а не Arduino IDE, то скорее всего Вашим выбором должна стать PVS Studio.
Для полноты картины — рендер обратной стороны АКА. Если кому интересно, пишите в комменты или в личку — выложу фото.

ссылка на оригинал статьи https://habr.com/ru/articles/1023056/