
Комментарии 9
как одна строка условной компиляции может обнулить годы работы инженеров
Очень неудачная строка. И кто автор?
Вероятно, что кто-то из инженеров компании недоглядел. Исходный код прошивок публичен (https://github.com/Coldcard/firmware), а независимые эксперты увидели проблему и опубликовали детали 30 июля. В этот же день начали выводить средства на "безопасные" адреса.
Можно поспекулировать, что это авторы деталей уязвимости могли подготовиться, опубликовать информацию, а затем сами же и воспользовались. Но также равнозначным выглядит и сценарий, что интернет-краулер хакеров постоянно мониторит новостной фон и оперативно доложил об очередной возможности, а ребята оперативно подсуетились и собрали сливки. Как и писал, перебор рабочих параметров у меня на ноуте за пару-тройку часов подыскал 184 рабочих сид-фразы от порядка 800 кошельков из первой волны.
Директива
#ifdefпроверяет только «определён ли макрос», но не его значение. А макрос был определён — просто равным нулю.#ifdefсчёл его включённым и скомпилировал ветку с программным генератором. Корректная#ifпотребовала бы ненулевого значения и отправила бы прошивку в правильную ветку.
> …
/* Было (ошибочно): /
#ifdef MICROPY_HW_ENABLE_RNG
/ использовать аппаратный TRNG /
#else
/ программный резервный генератор */
#endif
Да-что-чёрт-побери-такое-ты-несёшь? ©
#ifdef MICROPY_HW_ENABLE_RNG проверяет только наличие макроса, поэтому пофиг какое у него значение, если он определён. Если там было значение 0, это всё равно определённое значение. Включилась бы ветка аппаратного RNG.
Может быть и так, не берусь судить. Я доверился мнению авторов уязвимости (Predictable RNG Fallback and 32-Bit Reseed in COLDCARD Firmware), которые озвучили такое мнение, и использовал их наработки.
Я доверился мнению авторов уязвимости
— Это напоминает анекдот про то, что периодическая система хим. элементов прежде, чем присниться Менделееву, была показана во сне Пушкину, но тот в ней нихрена не понял.
вот то самое мнение, там другой кусок кода вообще:

Спасибо, за уточнение.
Не совсем верно понял детали уязвимости и причина не в ifdef вместо if, а в комбинации условий: MICROPY_HW_ENABLE_RNG (0) и проверка #ifndef в libngu, которая не отклоняет макрос с нулевым значением. Поправлю формулировки в статье.
Чес. сказать, там уровень кода такой, что я бы им не то что биток не доверил, копейку бы туда не положил. Вот такое #define CHIP_TRNG_32() rng_get() к примеру это как «вместо тысячи слов». Это дно. Наверное Asuswrt и то приличней (хотя, конечно, вряд ли). В общем, одним словом — копроэкономика.
Согласен с Вашей оценкой кода. Для устройства, которое позиционируется как защищённый кошелёк с открытой прошивкой, подобное отношение неприемлемо из-за отсутствия quality gates в процессах.
При этом не могу обвинять исключительно данного производителя — все вовлечены в гонку за TTM. Перекос между скоростью вывода продукта и качеством кода — системная болезнь мировой экономики, а не чья-то отдельная вина. Я и сам в работе стараюсь сдвигать этот баланс в сторону качества, хотя получается совсем не всегда.
Кмк неочевидно конфигурируемые вещи, если они зачем то есть, должны быть подперты static_assert ами или еще как нибудь, хотя бы warning ами. Чтобы собрать прошивку с ослабленной защитой было хотя бы неудобно.
Ваш холодный криптокошелёк взломан. Разбор уязвимости RNG у Coldcard Mk2–Mk5