1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
/*
*******************************************************************************
\file rng.h
\brief Entropy sources and random number generators
\project bee2 [cryptographic library]
\created 2014.10.13
\version 2023.12.19
\copyright The Bee2 authors
\license Licensed under the Apache License, Version 2.0 (see LICENSE.txt).
*******************************************************************************
*/
/*!
*******************************************************************************
\file rng.h
\brief Источники случайности и генераторы случайных чисел
*******************************************************************************
*/
#ifndef __BEE2_RNG_H
#define __BEE2_RNG_H
#include "bee2/defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/*!
*******************************************************************************
\file rng.h
\section rng-stat Статистическое тестирование
Реализованы статистические тесты стандарта FIPS 140-2. В этих тестах
обрабатывает последовательность двоичных символов длины 20000 (2500 байтов).
Уровень значимости тестов p = 0.01. С такой вероятностью истинно случайная
последовательность не пройдет тест. Известно, что тесты FIPS слабо зависимы.
Поэтому истинно случайная последовательность не пройдет батарею из n тестов
с вероятностью 1 - (1 - p)^n \approx n p.
\safe Обрабатываемые в тестах данные не считаются секретными. Эти данные
не должны использовать для построения ключей.
*******************************************************************************
*/
/*! \brief Тест знаков FIPS 140
К последовательности buf применяется тест знаков FIPS.
\pre Буфер buf корректен.
\return Признак успешного прохождения теста.
\remark Определяется величина S -- число единиц в последовательности.
Тест пройден, если 9725 < S < 10275.
*/
bool_t rngTestFIPS1(
const octet buf[2500] /*!< [in] тестируемая последовательность */
);
/*! \brief Покер-тест FIPS 140
К последовательности buf применяется покер-тест FIPS.
\pre Буфер buf корректен.
\return Признак успешного прохождения теста.
\remark Последовательность разбивается на 5000 тетрад. Тетрады
интерпретируются как числа от 0 до 15. Определяется статистика
S = 16 \sum _{i=0}^15 S_i^2 - (5000)^2, где S_i -- количество появлений
числа i среди тетрад. Тест пройден, если 10800 < S < 230850.
*/
bool_t rngTestFIPS2(
const octet buf[2500] /*!< [in] тестируемая последовательность */
);
/*! \brief Тест серий FIPS 140
К последовательности buf применяется тест серий FIPS.
\pre Буфер buf корректен.
\return Признак успешного прохождения теста.
\remark Определяются серии (максимальные последовательности
повторяющихся соседних битов) различных длин.
Тест пройден, если и для серий из нулей, и для серий из единиц
выполняется: S_1 \in [2315, 2685], S_2 \in [1114, 1386],
S_3 \in [527, 723], S_4 \in [240, 384], S_5, S_6+ \in [103, 209].
Здесь S_i -- количество серий длины i = 1, 2, ..., S_6+ = S_6 + S_7 + ....
\remark Бит с номером i: wwTestBit((const word*)buf, i).
*/
bool_t rngTestFIPS3(
const octet buf[2500] /*!< [in] тестируемая последовательность */
);
/*! \brief Тест длинных серий FIPS 140
К последовательности buf применяется тест серий FIPS.
\pre Буфер buf корректен.
\return Признак успешного прохождения теста.
\remark Тест пройден, если в последовательности отсутствуют серии
длины 26 и больше.
\remark Бит с номером i: wwTestBit((const word*)buf, i).
*/
bool_t rngTestFIPS4(
const octet buf[2500] /*!< [in] тестируемая последовательность */
);
/*!
*******************************************************************************
\file rng.h
\section rng-es Источники энтропии
В системе может быть несколько источников энтропии. Чтение данных от
источников реализуется через интерфейс read_i. Внутренние источники
поддерживаются функцией rngESRead().
При обработке запроса на чтение данных источники обрабатывает свои наблюдения,
учитывая оценки энтропии. При необходимости наблюдения сжимаются. В результате
обработки запроса будут возвращены высокоэнтропийные данные. Их объем может
быть меньше запрошенного.
При обработке запроса может произойти сбой источника или время снятия
наблюдений может оказаться неприемлемо большим. В таких случаях также будет
возвращено меньше данных, чем запрашивалось.
*******************************************************************************
*/
/*! \brief Чтение данных от источника энтропии
Данные от источника энтропии source записываются в буфер [count]buf.
По адресу read возвращается число прочитанных октетов.
Поддерживаются следующие источники:
- "trng": физический генератор случайных чисел;
- "trng2": дополнительный физический генератор случайных чисел;
- "timer": высокоточный таймер. Наблюдениями являются разности между
показаниями таймера до и после передачи управления ядру операционной
системы;
- "sys": источник операционной системы.
.
\pre Буфер buf корректен.
\pre Указатель read корректен.
\return ERR_OK, если получено определенное число октетов (возможно
меньшее count и возможно нулевое) и источник сохранил работоспособность,
ERR_BAD_ENTROPY, если получено меньше чем count октетов и источник
отказал, или другой код ошибки.
\warning Если при работе с источниками "trng", "trng2" длина выходного
буфера меньше 4, то функция возвратит ERR_OK, но ни одного октета данных
сгенерировано не будет.
\remark Ошибкой не считается ситуация, когда сгенерировано меньше
чем count октетов. Данная ситуация может быть связана с ожиданием
накопления наблюдений.
\remark Передавая count == 0, можно проверить наличие источника.
\remark Поддержан интерфейс read_i.
*/
err_t rngESRead(
size_t* read, /*!< [out] число прочитанных октетов */
void* buf, /*!< [out] прочитанные данные */
size_t count, /*!< [in] длина buf в октетах */
const char* source /*!< [in] источник */
);
/*! \brief Статистическое тестирование источника энтропии
Проводится статистическое тестирование источника энтропии source:
к данным, полученным от источника, применяются тесты FIPS. Тестирование
завершается успешно, если все тесты FIPS пройдены.
\return ERR_OK, если тестирование прошло успешно, и код ошибки в противном
случае.
*/
err_t rngESTest(
const char* source /*!< [in] источник */
);
/*! \brief Проверка работоспособности источников энтропии
Проверяется, что cреди штатных источников энтропии, которые выдерживают
статистическое тестирование, имеется один физический источник либо не
менее двух разных альтернативных.
\return ERR_OK, если проверка прошла успешно, ERR_NOT_ENOUGH_ENTROPY,
если недостает одного работоспособного источника, и ERR_BAD_ENTROPY
в остальных случаях.
\remark Проверяемые требования -- это требования СТБ 34.101.27 уровня 1.
*/
err_t rngESHealth();
/*! \brief Усиленная проверка работоспособности источников энтропии
Проверяется, что среди источников энтропии, которые выдерживают
статистическое тестирование, имеется один физический источник.
\return ERR_OK, если проверка прошло успешно, и ERR_BAD_ENTROPY
в противном случае.
\remark Проверяемые требования -- это требования СТБ 34.101.27 уровня 2
и выше.
*/
err_t rngESHealth2();
/*!
*******************************************************************************
\file rng.h
\section rng-rng Генератор случайных чисел
Выходные случайные числа можно использовать для построения ключей и других
критических объектов.
Генератор является единственным в библиотеке.
Генератор можно использовать в многопоточных приложениях.
При создании генератора опрашиваются все доступные источники случайности.
Данные от источников объединяются и хэшируются с помощью механизма
beltHash (см. crypto/belt.h). Хэш-значение используется как ключ механизма
brngCTR (см. crypto/brng.h).
При функционировании генератора выполняются последовательные обращения
к brngCTR. При подготовке обращений могут использоваться данные
от доступных источников случайности. Эти данные используются в качестве
входного буфера функции brngCTRStepR().
Данные от источников используются в функции rngStepR() и не используются
в функции rngStepR2(). Первую функцию можно применять время от времени
(например, во время согласования общего ключа перед передачей данных),
вторую -- регулярно (в процессе передачи данных).
С помощью функции rngRekey() можно обновить ключ генератора. После обновления
ключа случайные числа, сгенерированные ранее, будет невозможно определить
даже если при их генерации не использовались источники энтропии, а новый ключ
стал известен противнику.
*******************************************************************************
*/
/*! \brief Создание генератора
Создается генератор случайных чисел. При создании используются источники,
поддерживаемые функцией rngESRead(), а также возможно дополнительный
источник source с состоянием source_state.
\expect{ERR_NOT_ENOUGH_ENTROPY} В совокупности все работоспособные
источники выдают не менее 32 октетов случайных данных.
\expect Источники случайности выдают высокоэнтропийные данные.
\return Признак успеха.
\remark При нулевом source дополнительный источник не используется.
\remark Функцию rngCreate() можно вызывать многократно. При повторных
обращениях накопленные энтропийные данные сохраняются,
к ним добавляются данные, полученные от дополнительного источника source.
\remark У каждого источника запрашивается 32 октета данных, но он может
выдать меньше. Данные не запрашиваются, если источник отсутствует.
\remark Поддерживается счетчик обращений к rngCreate(). Счетчик
уменьшается функцией rngClose(). При достижении счетчиком нулевого
значения накопленные энтропийные данные (в том числе ключ
криптографической постобработки) уничтожаются.
*/
err_t rngCreate(
read_i source, /*!< [in] дополнительный источник */
void* source_state /*!< [in] состояние дополнительного источника */
);
/*! \brief Корректный генератор?
Проверяется корректность генератора случайных чисел.
\return Признак корректности.
*/
bool_t rngIsValid();
/*! \brief Генерация случайных чисел
В буфер [count]buf записываются случайные октеты, построенные с помощью
генератора случайных чисел. При формировании выходных октетов используются
данные от источников случайности.
\pre Генератор корректен.
\expect rngСreate() < rngStepR()*.
\remark Поддержан интерфейс gen_i (defs.h).
\remark Состояние state не используется. Оно передается в функцию только
для того, чтобы поддержать интерфейс gen_i.
\remark Запрашивается count октетов от источников. Будет возвращено
меньше октетов только если все источники отказали.
*/
void rngStepR(
void* buf, /*!< [out] буфер */
size_t count, /*!< [in] размер буфера (в октетах) */
void* state /*!< [in,out] состояние (игнорируется) */
);
/*! \brief Облегченная генерация случайных чисел
В буфер [count]buf записываются случайные октеты, построенные с помощью
генератора случайных чисел. При формировании выходных октетов данные от
источников энтропии не используются.
\pre Генератор корректен.
\expect rngСreate() < rngStepR2()*.
\remark Поддержан интерфейс gen_i (defs.h).
\remark Состояние state не используется. Оно передается в функцию только
для того, чтобы поддержать интерфейс gen_i.
*/
void rngStepR2(
void* buf, /*!< [out] буфер */
size_t count, /*!< [in] размер буфера (в октетах) */
void* state /*!< [in,out] состояние (игнорируется) */
);
/*! \brief Обновление ключа генератора
Ключ генератора обновляется: в его качестве выступают генеририруемые
случайные числа. При обновлении ключа данные от источников энтропии
не используются.
\pre Генератор корректен.
\expect rngСreate() < rngRekey()*.
*/
void rngRekey();
/*! \brief Закрытие генератора
Генератор случайных чисел закрывается.
\pre Генератор корректен.
*/
void rngClose();
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __BEE2_RNG_H */