vak: (Daemon)
[personal profile] vak
Почему NetBSD часто тормозит на i486 процессоре? Выяснились две причины: шифрование свопа и нехватка энтропии.

Не знаю, кто придумал включить по умолчанию шифрование страниц, откачиваемых в своп. Без аппаратной поддержки шифрования это убивает производительность напрочь. Отключается легко: достаточно добавить строчку "vm.swap_encrypt=0" в файл /etc/sysctl.conf.

С энтропией ситуация сложнее. При загрузке ядро NetBSD выдает строчку, означающую, что дело плохо.
WARNING: system needs entropy for security; see entropy(7)
За последние 10 лет мы привыкли к защищённым протоколам типа HTTPS и SSH, и не интересуемся деталями. А им для работы нужен качественный источник случайности. Иначе протокол станет слишком предсказуемым, а значит хакеры могут взломать его, легко подобрав ключ.

Когда вы подключаетесь к веб-сайту через HTTPS, ваш браузер и сервер выполняют «рукопожатие», чтобы согласовать секретный ключ шифрования. Если этот ключ генерируется с использованием низкой энтропии (предсказуемые данные), хакеру не нужно «взламывать» шифрование; ему достаточно угадать ключ. Стандартный 128-битный ключ имеет много возможных комбинаций. Если ваша система обладает высокой энтропией, хакеру придется перебрать почти все из них (что займет миллиарды лет). Если ваша энтропия низкая, ему, возможно, потребуется перебрать всего несколько тысяч.

В процессе передачи с каждым сообщением отправляется дополнительная случайная строка, чтобы гарантировать, что даже если вы отправите одну и ту же команду дважды (например, «Заплатить 10 долларов»), зашифрованные данные будут выглядеть совершенно по-разному каждый раз. Без высокой энтропии эти одноразовые числа могут повторяться или следовать определенному шаблону. Злоумышленник может записать старое зашифрованное сообщение и «воспроизвести» его позже, чтобы обмануть сервер.

Откуда протокол берёт эту энтропию? В ядре операционной системы имеется специальный буфер, где хранится некоторый запас, обычно несколько тысяч качественных случайных бит. Установление каждого нового HTTPS-соединения потребляет примерно от 256 до 512 бит (от 32 до 64 байт) из этого запаса, то есть порядка 10%. На каждый передаваемый пакет тоже нужно немного случайности, но там уже работает псевдослучайный генератор. В активных системах (особенно на серверах или небольших устройствах IoT) запас энтропии может опустеть, если нужно быстро сгенерировать слишком много ключей. Система может замереть и ждать, пока не будет собрано больше случайных данных. Источником служит или специальный аппаратный генератор шума (TRNG), встроенный в современный процессор, или драйверы некоторых периферийных устройств. Скажем, можно отслеживать микроизменения времени, необходимого жесткому диску для поиска данных.

Мы не замечаем проблемы энтропии, потому что на современных устройствах генераторы шума встроены в процессор. На древнем же компьютере ничего такого нет, и поэтому вход по SSH на мой Cx486 занимает 78 секунд. Время уходит на сбор энтропии и генерацию одноразового ключа для защищённого сеанса.

Энтропию в ядро можно легко добавлять, просто записывая случайные данные в /dev/urandom. Вопрос, откуда брать качественную случайность. Скажем, можно соорудить девайс на микроконтроллере RP2350 и подключить его на COM порт. В этом чипе есть блок TRNG, способный выдавать 7500 случайных бит в секунду. Это примерно 938 байт/сек. Хватит с запасом на все потребности.

Date: 2025-12-24 16:05 (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Энтропию в ядро можно легко добавлять, просто записывая случайные данные в /dev/urandom.

Интересно, что будет при cat /dev/zero > /dev/urandom.

Date: 2025-12-25 13:42 (UTC)
netch80: (Default)
From: [personal profile] netch80
Подмешает точно так же.
Современные хэши, начиная с SHA-256, достаточно надёжны, чтобы от этого не страдать.

Если один накопительный пул (вариант Linux), то просто будет регулярное выполнение операции:

K[n+1] = Hash(K[n] ‖ Hash(pool))

где K - ключ для генерации текущей порции данных каким-то потоковым (stream) шифром.

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

В варианте Fortuna (вроде бы все BSD) ещё и регулярно подключаются разные пулы из массива пулов, так что надо знать полное состояние генератора, чтобы хоть что-то хоть как-то предсказать, и то на короткое время. Такой себе самовосстанавливающийся самоусиливающийся хаос, годится для тёмной фэнтези. Ну а текущий ключ и значения пулов генератора даже руту сложно достать.

Последние лет 20 не было движений в сторону усложнения механизма или хотя бы расширения ширины ключа. Значит, хватает.