Читаем Разработка ядра Linux полностью

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

Функция add_mouse_randomness() использует позицию указателя мыши и интервалы времени между прерываниями для заполнения пула. Параметр mouse_data — это позиция указателя, которая возвращается аппаратным обеспечением.

Эти три функции добавляют передаваемые данные в пул энтропии, вычисляют оценку энтропии добавляемых данных и увеличивают оценку энтропии пула на вычисленное значение.

Все эти экспортируемые интерфейсы используют внутреннюю функцию add_timer_randomness() для ввода данных в пул. Эта функция вычисляет интервалы времени между успешными событиями одного типа и добавляет эти значения в пул. Например, интервалы времени между успешными прерываниями жесткого диска достаточно случайны, особенно если измерять достаточно точно. Самые младшие биты — это обычно электрический шум. После того как эта функция вводит данные в пул, она вычисляет количественную характеристику того, насколько эти данные случайны. Это делается путем вычисления отклонения первого, второго и третьего порядка от предыдущего момента времени и изменения этих отклонений первого, второго и третьего порядка. Наибольшее из этих отклонений, округленное до 12 бит, используется в качестве оценки энтропии.

Интерфейсы для вывода энтропии

Для получения случайных чисел внутри ядра экспортируется один интерфейс.

void get_random_bytes(void *buf, int nbytes);

Эта функция сохраняет nbytes случайных байтов в буфере памяти, на который указывает параметр buf. Функция возвращает данные, даже если оценка энтропии равна нулю. Для ядра это не так критично, как для пользовательских криптографических программ. Случайные данные мало используются в ядре, в основном они нужны сетевой подсистеме для генерации стартового номера последовательности сегментов при соединении по протоколу TCP.

Код ядра может выполнить следующий код для получения случайных данных размером в одно машинное слово.

unsigned long rand;


get_random_bytes(&rand, sizeof(rand));

Для программ, которые выполняются в пространстве пользователя, предоставляется два символьных устройства: /dev/random и /dev/urandom. Первое устройство, /dev/random, используется, когда необходимы гарантированно случайные данные для криптографических приложений с высоким уровнем безопасности. Это устройство выдает только то количество битов данных, которое соответствует оценке энтропии в ядре. Когда оценка энтропии становится равной нулю, операция чтения устройства /dev/random блокируется и не возвращает данные, пока значение энтропии не станет существенно положительным. Устройство /dev/urandom не имеет последней возможности, а в остальном работает аналогично. Оба устройства возвращают данные из одного и того же пула.

Чтение из обоих файлов выполняется очень просто. Ниже показана функция пользовательской программы, которая служит для считывания одного машинного слова случайных данных.

unsigned long get_random(void) {

 unsigned long seed = 0;

 int fd;


 fd = open("/dev/urandom", O_RDONLY);

 if (fd == -1) {

  perror("open");

  return 0;

 }

 if (read(fd, &seed, sizeof(seed)) < 0) {

  perror("read");

  seed = 0;

 }

 if (close(fd))

  perror("close");


 return seed;

}

Можно также считать $bytes байтов в файл $file, используя программу dd.

dd if=/dev/urandom of=$file count=1 bs=$bytes

Приложение В

Сложность алгоритмов

Перейти на страницу:

Похожие книги

C++: базовый курс
C++: базовый курс

В этой книге описаны все основные средства языка С++ - от элементарных понятий до супервозможностей. После рассмотрения основ программирования на C++ (переменных, операторов, инструкций управления, функций, классов и объектов) читатель освоит такие более сложные средства языка, как механизм обработки исключительных ситуаций (исключений), шаблоны, пространства имен, динамическая идентификация типов, стандартная библиотека шаблонов (STL), а также познакомится с расширенным набором ключевых слов, используемым в .NET-программировании. Автор справочника - общепризнанный авторитет в области программирования на языках C и C++, Java и C# - включил в текст своей книги и советы программистам, которые позволят повысить эффективность их работы. Книга рассчитана на широкий круг читателей, желающих изучить язык программирования С++.

Герберт Шилдт

Программирование, программы, базы данных