[devel] rngd vs haveged vs crng (khwrngd)

Alexey V. Vissarionov gremlin на altlinux.org
Вт Сен 3 02:59:13 MSK 2019


On 2019-09-03 00:31:05 +0300, Leonid Krivoshein wrote:

 >>>>> systemd, равно как и ядро, не решают проблему наполнения
 >>>>> пула качественной энтропией на ранней стадии загрузки
 >>>> Что любопытно, ядро эту задачу прекрасно решает. Особенно
 >>>> если его об этом грамотно попросить.
 >>> Если имеется ввиду |rng_core.default_quality=1000| , это тоже
 >>> не совсем доверенный источник,
 >> Нет - я про дисковые и сетевые контроллеры.
 >> Для первых существует специальная функция add_disk_randomness(),
 >> а вторые вызывают срабатывание add_interrupt_randomness() через
 >> handle_irq_event_percpu()

(1)

 >>> да и про |CONFIG_RANDOM_TRUST_CPU=y| некоторые скажут, что
 >>> эту хрень не надо никогда использовать.
 >> Использовать ее можно, но при соблюдении двух простых условий:
 >> 1. должны быть и другие источники энтропии;
 > Вот их нет. Совсем!

См. (1) - они есть всегда, просто особо одуренные явно отказываются
их использовать.

 >> 2. к моменту начала использования недоверенного RNG пул должен
 >> быть заполнен данными из других источников.
 > Вот он ещё не заполнен. Почти... а уже надо!

Если почти, то можно и недоверенный источник подмешивать.

 >> И хорошо бы, чтобы продолжал хотя бы чучуть пополняться из них.
 >> После этого можно хоть cat /dev/zero > /dev/random запускать -
 >> на качество энтропии это уже не повлияет :-)
 > Энтропия -- это не продукт алгоритмов криптостойкого
 > хэширования с начальным состоянием, это "совершенно случайные
 > нули и единицы".

Вообще-то энтропия - это просто мера неопределенности. Численно
определяется как двоичный логарифм от количества состояний системы
(в дебри определений от Шеннона, Рени и Хайзенберга не полезу).

 > Но вывод /dev/random и getrandom(), как я сейчас понимаю,
 > это не чистая энтропия, а всё же переработанная,

Перемешивание и отбеливание. Еще недавно использовали SHA2, щас
зачем-то поменяли хеш на Poly1305.

 > хотяи с заданными пороговыми значениями, чтобы число бит на
 > выходе не было меньше реальной энтропии на входе.

Дядя, ты как сам-то? Если не меньше - значит, строго равно (ибо
больше оно не может быть по определению), но после отбеливания
оно может быть только строго меньше.

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

 > Если же такое качество не требуется, достаточно брать случайные
 > числа из /dev/urandom,

Я бы сказал, что /dev/urandom следует использовать почти для всего.
Единственное разумное исключение, где нужен /dev/random - генерация
ключевых пар для алгоритмов с открытым ключом.

 > только вот с недавних пор лишь после инициализации начального
 > состояния.

Оно всегда так было. Только время загрузки ядра было таким, что
одних только IRQ14 и IRQ15 (а то и IRQ6) хватало на полноценный
/dev/random (а ведь еще были IRQ1 и всякие IRQ10 с IRQ11).

Вот интересно: кто из тутошних читателей сможет назвать все
устройства, генерирующие перечисленные мной прерывания (кроме
двух последних), не пользуясь справочными материалами? :-)

 >>>>> остаётся два варианта: использовать дополнительный
 >>>>> аппаратный (доверенный) источник
 >>>> Разве что на компутерах, где живет какой-нибудь CA... для
 >>>> всего остального хватает грамотно собранного ядра (которое
 >>>> накапливает энтропию начиная уже где-то с третьей секунды
 >>>> работы и к запуску init успевает наполнить пул).
 >>> Так в том и проблема, что есть железо, где не успевает.
 >> Полностью детерминированное железо? Где? Хочу!
 >> Продам - стану миллиардером.
 > Один такой ТОНК отправлен в Обнинск.

Видел я эти ваши тонки... нихренасеньки они не детерминированные,
обычная писюшатина.

 > Вообще подверженное проблеме железо периодически всплывает.
 > Можем завести тему в ответ на данный запрос -- список с
 > наименованиями конкретных железок будет полезен многим.

Сильно подозреваю, что источник проблемы - в явном отказе от
использования доверенных и проверенных (десятилетиями!) источников
случайных данных.

 >>> Только о нём спич. И здесь речь о случайных числах для запуска
 >>> самого systemd, который может стартануть и быстрее, чем через
 >>> три секунды.
 >> Он при всем желании не может стартануть раньше, чем ядро скажет
 >> run_init_process("/sbin/init");
 > Процессы инициализации ядра и запуска /sbin/init асинхронны.

Они могут быть сколько угодно асинхронными, но run_init_process()
ядро выполнит никак не раньше, чем mount_block_root()

 > Единственное, что делается ДО -- инициализация devtmpfs.

Вроде бы достаточно очевидно, что devtmpfs_mount() выполняется до
run_init_process(), но после mount_block_root()

 > К моменту запуска /sbin/init может быть даже не загружено ещё
 > никаких модулей.

И это очень плохо. Потому что очень многие из них используют как
минимум один способ (из четырех возможных) помочь ядерному ГСЧ
набрать энтропию перед run_init_process()

 > Процесс асинхронной инициализации хорошо виден в dmesg и
 > journalctl. У нас, правда, тут не systemd сейчас стартует, а
 > другой /sbin/init. Но надо понимать, что прохождение stage1
 > зависит от железа и конфигурации системы.

Что ты в данном случае называешь stage1?

 > К моменту stage2, где в качестве /sbin/init будет уже systemd,
 > загрузка модулей продолжится, службы же начнут запускаться
 > по-новой.

Пофигу: все это - уже работа процессов в userspace.

 >> А к этому времени пул энтропии уже должен быть хотя бы не
 >> пустым. И достигается это (внезапно!) грамотной настройкой
 >> ядра.
 > Осталось лишь огласить способ "грамотной настройки".

Такой, чтобы источники энтропии запускались до run_init_process()

 >>>>> ЛИБО ослаблять энтропию программными демонами типа
 >>>>> rngd/haveged/etc.
 >>>> А вот эту срань вообще использовать нельзя. Нигде и никогда.
 >> Здесь, насколько я понимаю, возражений нет?
 > А что делать тем, кому "аппаратный" вариант недоступен?

Чаво?! Дисковый контроллер недоступен? Или сетевой адаптер?

 > Блокировку на этапе загрузки можно рассматривать не только как
 > баг юзабилити. В ряде задач это тоже CVE, вплоть до DoS для
 > всего HA-кластера. В конце концов, подкопив энтропии, можно
 > обновить состояние инициализации CRNG.

Да: низкоэнтропийная криптография - это уязвимость. Исправлять ее
будем, или как обычно?

 > А терпеть тормоза при загрузке можно далеко не во всех сценариях.

При вводе системы в промышленную эксплуатацию сервер должен быть
запущен позавчера.


-- 
Alexey V. Vissarionov
gremlin ПРИ altlinux ТЧК org; +vii-cmiii-ccxxix-lxxix-xlii
GPG: 0D92F19E1C0DC36E27F61A29CD17E2B43D879005 @ hkp://keys.gnupg.net


Подробная информация о списке рассылки Devel