1 | /* $NetBSD: nist_ctr_drbg.c,v 1.1 2011/11/19 22:51:22 tls Exp $ */ |
2 | |
3 | /*- |
4 | * Copyright (c) 2011 The NetBSD Foundation, Inc. |
5 | * All rights reserved. |
6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Thor Lancelot Simon. |
9 | * |
10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions |
12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. |
15 | * 2. Redistributions in binary form must reproduce the above copyright |
16 | * notice, this list of conditions and the following disclaimer in the |
17 | * documentation and/or other materials provided with the distribution. |
18 | * |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ |
31 | |
32 | /* |
33 | * Copyright (c) 2007 Henric Jungheim <software@henric.info> |
34 | * |
35 | * Permission to use, copy, modify, and distribute this software for any |
36 | * purpose with or without fee is hereby granted, provided that the above |
37 | * copyright notice and this permission notice appear in all copies. |
38 | * |
39 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
40 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
41 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
42 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
43 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
44 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
45 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
46 | */ |
47 | |
48 | /* |
49 | * NIST SP 800-90 CTR_DRBG (Random Number Generator) |
50 | */ |
51 | #include <sys/types.h> |
52 | #include <sys/systm.h> |
53 | |
54 | #include <crypto/nist_ctr_drbg/nist_ctr_drbg.h> |
55 | |
56 | #include <sys/cdefs.h> |
57 | __KERNEL_RCSID(0, "$NetBSD: nist_ctr_drbg.c,v 1.1 2011/11/19 22:51:22 tls Exp $" ); |
58 | |
59 | /* |
60 | * NIST SP 800-90 March 2007 |
61 | * 10.4.2 Derivation Function Using a Block Cipher Algorithm |
62 | * Global Constants |
63 | */ |
64 | static NIST_Key nist_cipher_df_ctx; |
65 | static unsigned char nist_cipher_df_encrypted_iv[NIST_BLOCK_SEEDLEN / NIST_BLOCK_OUTLEN][NIST_BLOCK_OUTLEN_BYTES]; |
66 | |
67 | /* |
68 | * NIST SP 800-90 March 2007 |
69 | * 10.2.1.3.2 The Process Steps for Instantiation When a Derivation |
70 | * Function is Used |
71 | * Global Constants |
72 | */ |
73 | static NIST_Key nist_cipher_zero_ctx; |
74 | |
75 | /* |
76 | * NIST SP 800-90 March 2007 |
77 | * 10.2.1.5.2 The Process Steps for Generating Pseudorandom Bits When a |
78 | * Derivation Function is Used for the DRBG Implementation |
79 | * Global Constants |
80 | */ |
81 | static const unsigned int |
82 | nist_ctr_drgb_generate_null_input[NIST_BLOCK_SEEDLEN_INTS] = { 0 }; |
83 | |
84 | /* |
85 | * Utility |
86 | */ |
87 | /* |
88 | * nist_increment_block |
89 | * Increment the output block as a big-endian number. |
90 | */ |
91 | static inline void |
92 | nist_increment_block(unsigned long *V) |
93 | { |
94 | int i; |
95 | unsigned long x; |
96 | |
97 | for (i = NIST_BLOCK_OUTLEN_LONGS - 1; i >= 0; --i) { |
98 | x = NIST_NTOHL(V[i]) + 1; |
99 | V[i] = NIST_HTONL(x); |
100 | if (x) /* There was only a carry if we are zero */ |
101 | return; |
102 | } |
103 | } |
104 | |
105 | /* |
106 | * NIST SP 800-90 March 2007 |
107 | * 10.4.3 BCC Function |
108 | */ |
109 | static void |
110 | nist_ctr_drbg_bcc_update(const NIST_Key *ctx, const unsigned int *data, |
111 | int n, unsigned int *chaining_value) |
112 | { |
113 | int i, j; |
114 | unsigned int input_block[NIST_BLOCK_OUTLEN_INTS]; |
115 | |
116 | /* [4] for i = 1 to n */ |
117 | for (i = 0; i < n; ++i) { |
118 | |
119 | /* [4.1] input_block = chaining_value XOR block_i */ |
120 | for (j = 0; j < NIST_BLOCK_OUTLEN_INTS; ++j) |
121 | input_block[j] = chaining_value[j] ^ *data++; |
122 | |
123 | /* [4.2] chaining_value = Block_Encrypt(Key, input_block) */ |
124 | Block_Encrypt(ctx, &input_block[0], &chaining_value[0]); |
125 | } |
126 | |
127 | /* [5] output_block = chaining_value */ |
128 | /* chaining_value already is output_block, so no copy is required */ |
129 | } |
130 | |
131 | static void |
132 | nist_ctr_drbg_bcc(NIST_Key *ctx, const unsigned int *data, |
133 | int n, unsigned int *output_block) |
134 | { |
135 | unsigned int *chaining_value = output_block; |
136 | |
137 | /* [1] chaining_value = 0^outlen */ |
138 | memset(&chaining_value[0], 0, NIST_BLOCK_OUTLEN_BYTES); |
139 | |
140 | nist_ctr_drbg_bcc_update(ctx, data, n, output_block); |
141 | } |
142 | |
143 | /* |
144 | * NIST SP 800-90 March 2007 |
145 | * 10.4.2 Derivation Function Using a Block Cipher Algorithm |
146 | */ |
147 | |
148 | typedef struct { |
149 | int index; |
150 | unsigned char S[NIST_BLOCK_OUTLEN_BYTES]; |
151 | } NIST_CTR_DRBG_DF_BCC_CTX; |
152 | |
153 | static inline int |
154 | check_int_alignment(const void *p) |
155 | { |
156 | intptr_t ip = (const char *)p - (const char *)0; |
157 | |
158 | if (ip & (sizeof(int) - 1)) |
159 | return 0; |
160 | |
161 | return 1; |
162 | } |
163 | |
164 | static void |
165 | nist_ctr_drbg_df_bcc_init(NIST_CTR_DRBG_DF_BCC_CTX *ctx, int L, int N) |
166 | { |
167 | unsigned int *S = (unsigned int *)ctx->S; |
168 | |
169 | /* [4] S = L || N || input_string || 0x80 */ |
170 | S[0] = NIST_HTONL(L); |
171 | S[1] = NIST_HTONL(N); |
172 | ctx->index = 2 * sizeof(S[0]); |
173 | } |
174 | |
175 | static void |
176 | nist_ctr_drbg_df_bcc_update(NIST_CTR_DRBG_DF_BCC_CTX *ctx, |
177 | const char *input_string, |
178 | int input_string_length, unsigned int *temp) |
179 | { |
180 | int i, len; |
181 | int index = ctx->index; |
182 | unsigned char *S = ctx->S; |
183 | |
184 | if (index) { |
185 | KASSERT(index < NIST_BLOCK_OUTLEN_BYTES); |
186 | len = NIST_BLOCK_OUTLEN_BYTES - index; |
187 | if (input_string_length < len) |
188 | len = input_string_length; |
189 | |
190 | memcpy(&S[index], input_string, len); |
191 | |
192 | index += len; |
193 | input_string += len; |
194 | input_string_length -= len; |
195 | |
196 | if (index < NIST_BLOCK_OUTLEN_BYTES) { |
197 | ctx->index = index; |
198 | |
199 | return; |
200 | } |
201 | |
202 | /* We have a full block in S, so let's process it */ |
203 | /* [9.2] BCC */ |
204 | nist_ctr_drbg_bcc_update(&nist_cipher_df_ctx, |
205 | (unsigned int *)&S[0], 1, temp); |
206 | index = 0; |
207 | } |
208 | |
209 | /* ctx->S is empty, so let's handle as many input blocks as we can */ |
210 | len = input_string_length / NIST_BLOCK_OUTLEN_BYTES; |
211 | if (len > 0) { |
212 | if (check_int_alignment(input_string)) { |
213 | /* [9.2] BCC */ |
214 | nist_ctr_drbg_bcc_update(&nist_cipher_df_ctx, |
215 | (const unsigned int *) |
216 | input_string, len, temp); |
217 | |
218 | input_string += len * NIST_BLOCK_OUTLEN_BYTES; |
219 | input_string_length -= len * NIST_BLOCK_OUTLEN_BYTES; |
220 | } else { |
221 | for (i = 0; i < len; ++i) { |
222 | memcpy(&S[0], input_string, |
223 | NIST_BLOCK_OUTLEN_BYTES); |
224 | |
225 | /* [9.2] BCC */ |
226 | nist_ctr_drbg_bcc_update(&nist_cipher_df_ctx, |
227 | (unsigned int *) |
228 | &S[0], 1, temp); |
229 | |
230 | input_string += NIST_BLOCK_OUTLEN_BYTES; |
231 | input_string_length -= NIST_BLOCK_OUTLEN_BYTES; |
232 | } |
233 | } |
234 | } |
235 | |
236 | KASSERT(input_string_length < NIST_BLOCK_OUTLEN_BYTES); |
237 | |
238 | if (input_string_length) { |
239 | memcpy(&S[0], input_string, input_string_length); |
240 | index = input_string_length; |
241 | } |
242 | |
243 | ctx->index = index; |
244 | } |
245 | |
246 | static void |
247 | nist_ctr_drbg_df_bcc_final(NIST_CTR_DRBG_DF_BCC_CTX *ctx, unsigned int *temp) |
248 | { |
249 | int index; |
250 | unsigned char* S = ctx->S; |
251 | static const char endmark[] = { 0x80 }; |
252 | |
253 | nist_ctr_drbg_df_bcc_update(ctx, endmark, sizeof(endmark), temp); |
254 | |
255 | index = ctx->index; |
256 | if (index) { |
257 | memset(&S[index], 0, NIST_BLOCK_OUTLEN_BYTES - index); |
258 | |
259 | /* [9.2] BCC */ |
260 | nist_ctr_drbg_bcc_update(&nist_cipher_df_ctx, |
261 | (unsigned int *)&S[0], 1, temp); |
262 | } |
263 | } |
264 | |
265 | static int |
266 | nist_ctr_drbg_block_cipher_df(const char *input_string[], unsigned int L[], |
267 | int input_string_count, |
268 | unsigned char *output_string, unsigned int N) |
269 | { |
270 | int j, k, blocks, sum_L; |
271 | unsigned int *temp; |
272 | unsigned int *X; |
273 | NIST_Key ctx; |
274 | NIST_CTR_DRBG_DF_BCC_CTX df_bcc_ctx; |
275 | unsigned int buffer[NIST_BLOCK_SEEDLEN_INTS]; |
276 | /* |
277 | * NIST SP 800-90 March 2007 10.4.2 states that 512 bits is |
278 | * the maximum length for the approved block cipher algorithms. |
279 | */ |
280 | unsigned int output_buffer[512 / 8 / sizeof(unsigned int)]; |
281 | |
282 | if (N > sizeof(output_buffer) || N < 1) |
283 | return 0; |
284 | |
285 | sum_L = 0; |
286 | for (j = 0; j < input_string_count; ++j) |
287 | sum_L += L[j]; |
288 | |
289 | /* [6] temp = Null string */ |
290 | temp = buffer; |
291 | |
292 | /* [9] while len(temp) < keylen + outlen, do */ |
293 | for (j = 0; j < NIST_BLOCK_SEEDLEN / NIST_BLOCK_OUTLEN; ++j) { |
294 | /* [9.2] temp = temp || BCC(K, (IV || S)) */ |
295 | |
296 | /* Since we have precomputed BCC(K, IV), we start with that... */ |
297 | memcpy(&temp[0], &nist_cipher_df_encrypted_iv[j][0], |
298 | NIST_BLOCK_OUTLEN_BYTES); |
299 | |
300 | nist_ctr_drbg_df_bcc_init(&df_bcc_ctx, sum_L, N); |
301 | |
302 | /* Compute the rest of BCC(K, (IV || S)) */ |
303 | for (k = 0; k < input_string_count; ++k) |
304 | nist_ctr_drbg_df_bcc_update(&df_bcc_ctx, |
305 | input_string[k], |
306 | L[k], temp); |
307 | |
308 | nist_ctr_drbg_df_bcc_final(&df_bcc_ctx, temp); |
309 | |
310 | temp += NIST_BLOCK_OUTLEN_INTS; |
311 | } |
312 | |
313 | nist_zeroize(&df_bcc_ctx, sizeof(df_bcc_ctx)); |
314 | |
315 | /* [6] temp = Null string */ |
316 | temp = buffer; |
317 | |
318 | /* [10] K = Leftmost keylen bits of temp */ |
319 | Block_Schedule_Encryption(&ctx, &temp[0]); |
320 | |
321 | /* [11] X = next outlen bits of temp */ |
322 | X = &temp[NIST_BLOCK_KEYLEN_INTS]; |
323 | |
324 | /* [12] temp = Null string */ |
325 | temp = output_buffer; |
326 | |
327 | /* [13] While len(temp) < number_of_bits_to_return, do */ |
328 | blocks = (int)(N / NIST_BLOCK_OUTLEN_BYTES); |
329 | if (N & (NIST_BLOCK_OUTLEN_BYTES - 1)) |
330 | ++blocks; |
331 | for (j = 0; j < blocks; ++j) { |
332 | /* [13.1] X = Block_Encrypt(K, X) */ |
333 | Block_Encrypt(&ctx, X, temp); |
334 | X = temp; |
335 | temp += NIST_BLOCK_OUTLEN_INTS; |
336 | } |
337 | |
338 | /* [14] requested_bits = Leftmost number_of_bits_to_return of temp */ |
339 | memcpy(output_string, output_buffer, N); |
340 | |
341 | nist_zeroize(&ctx, sizeof(ctx)); |
342 | |
343 | return 0; |
344 | } |
345 | |
346 | |
347 | static int |
348 | nist_ctr_drbg_block_cipher_df_initialize(void) |
349 | { |
350 | int i, err; |
351 | unsigned char K[NIST_BLOCK_KEYLEN_BYTES]; |
352 | unsigned int IV[NIST_BLOCK_OUTLEN_INTS]; |
353 | |
354 | /* [8] K = Leftmost keylen bits of 0x00010203 ... 1D1E1F */ |
355 | for (i = 0; i < sizeof(K); ++i) |
356 | K[i] = (unsigned char)i; |
357 | |
358 | err = Block_Schedule_Encryption(&nist_cipher_df_ctx, K); |
359 | if (err) |
360 | return err; |
361 | |
362 | /* |
363 | * Precompute the partial BCC result from encrypting the IVs: |
364 | * nist_cipher_df_encrypted_iv[i] = BCC(K, IV(i)) |
365 | */ |
366 | |
367 | /* [7] i = 0 */ |
368 | /* [9.1] IV = i || 0^(outlen - len(i)) */ |
369 | memset(&IV[0], 0, sizeof(IV)); |
370 | |
371 | /* [9.3] i = i + 1 */ |
372 | for (i = 0; i < NIST_BLOCK_SEEDLEN / NIST_BLOCK_OUTLEN; ++i) { |
373 | |
374 | /* [9.1] IV = i || 0^(outlen - len(i)) */ |
375 | IV[0] = NIST_HTONL(i); |
376 | |
377 | /* |
378 | * [9.2] temp = temp || BCC(K, (IV || S)) |
379 | * (the IV part, at least) |
380 | */ |
381 | nist_ctr_drbg_bcc(&nist_cipher_df_ctx, &IV[0], 1, |
382 | (unsigned int *) |
383 | &nist_cipher_df_encrypted_iv[i][0]); |
384 | } |
385 | |
386 | return 0; |
387 | } |
388 | |
389 | /* |
390 | * NIST SP 800-90 March 2007 |
391 | * 10.2.1.2 The Update Function |
392 | */ |
393 | static void |
394 | nist_ctr_drbg_update(NIST_CTR_DRBG *drbg, const unsigned int *provided_data) |
395 | { |
396 | int i; |
397 | unsigned int temp[NIST_BLOCK_SEEDLEN_INTS]; |
398 | unsigned int* output_block; |
399 | |
400 | /* 2. while (len(temp) < seedlen) do */ |
401 | for (output_block = temp; |
402 | output_block < &temp[NIST_BLOCK_SEEDLEN_INTS]; |
403 | output_block += NIST_BLOCK_OUTLEN_INTS) { |
404 | |
405 | /* 2.1 V = (V + 1) mod 2^outlen */ |
406 | nist_increment_block((unsigned long *)&drbg->V[0]); |
407 | |
408 | /* 2.2 output_block = Block_Encrypt(K, V) */ |
409 | Block_Encrypt(&drbg->ctx, drbg->V, output_block); |
410 | } |
411 | |
412 | /* 3 temp is already of size seedlen (NIST_BLOCK_SEEDLEN_INTS) */ |
413 | |
414 | /* 4 (part 1) temp = temp XOR provided_data */ |
415 | for (i = 0; i < NIST_BLOCK_KEYLEN_INTS; ++i) |
416 | temp[i] ^= *provided_data++; |
417 | |
418 | /* 5 Key = leftmost keylen bits of temp */ |
419 | Block_Schedule_Encryption(&drbg->ctx, &temp[0]); |
420 | |
421 | /* 4 (part 2) combined with 6 V = rightmost outlen bits of temp */ |
422 | for (i = 0; i < NIST_BLOCK_OUTLEN_INTS; ++i) |
423 | drbg->V[i] = |
424 | temp[NIST_BLOCK_KEYLEN_INTS + i] ^ *provided_data++; |
425 | } |
426 | |
427 | /* |
428 | * NIST SP 800-90 March 2007 |
429 | * 10.2.1.3.2 The Process Steps for Instantiation When a Derivation |
430 | * Function is Used |
431 | */ |
432 | int |
433 | nist_ctr_drbg_instantiate(NIST_CTR_DRBG* drbg, |
434 | const void *entropy_input, int entropy_input_length, |
435 | const void *nonce, int nonce_length, |
436 | const void *personalization_string, int personalization_string_length) |
437 | { |
438 | int err, count; |
439 | unsigned int seed_material[NIST_BLOCK_SEEDLEN_INTS]; |
440 | unsigned int length[3]; |
441 | const char *input_string[3]; |
442 | |
443 | /* [1] seed_material = entropy_input || |
444 | * nonce || personalization_string |
445 | */ |
446 | |
447 | input_string[0] = entropy_input; |
448 | length[0] = entropy_input_length; |
449 | |
450 | input_string[1] = nonce; |
451 | length[1] = nonce_length; |
452 | |
453 | count = 2; |
454 | if (personalization_string) { |
455 | input_string[count] = personalization_string; |
456 | length[count] = personalization_string_length; |
457 | ++count; |
458 | } |
459 | /* [2] seed_material = Block_Cipher_df(seed_material, seedlen) */ |
460 | err = nist_ctr_drbg_block_cipher_df(input_string, length, count, |
461 | (unsigned char *)seed_material, |
462 | sizeof(seed_material)); |
463 | if (err) |
464 | return err; |
465 | |
466 | /* [3] Key = 0^keylen */ |
467 | memcpy(&drbg->ctx, &nist_cipher_zero_ctx, sizeof(drbg->ctx)); |
468 | |
469 | /* [4] V = 0^outlen */ |
470 | memset(&drbg->V, 0, sizeof(drbg->V)); |
471 | |
472 | /* [5] (Key, V) = Update(seed_material, Key, V) */ |
473 | nist_ctr_drbg_update(drbg, seed_material); |
474 | |
475 | /* [6] reseed_counter = 1 */ |
476 | drbg->reseed_counter = 1; |
477 | |
478 | return 0; |
479 | } |
480 | |
481 | static int |
482 | nist_ctr_drbg_instantiate_initialize(void) |
483 | { |
484 | int err; |
485 | unsigned char K[NIST_BLOCK_KEYLEN_BYTES]; |
486 | |
487 | memset(&K[0], 0, sizeof(K)); |
488 | |
489 | err = Block_Schedule_Encryption(&nist_cipher_zero_ctx, &K[0]); |
490 | |
491 | return err; |
492 | } |
493 | |
494 | /* |
495 | * NIST SP 800-90 March 2007 |
496 | * 10.2.1.4.2 The Process Steps for Reseeding When a Derivation |
497 | * Function is Used |
498 | */ |
499 | int |
500 | nist_ctr_drbg_reseed(NIST_CTR_DRBG *drbg, |
501 | const void *entropy_input, int entropy_input_length, |
502 | const void *additional_input, |
503 | int additional_input_length) |
504 | { |
505 | int err, count; |
506 | const char *input_string[2]; |
507 | unsigned int length[2]; |
508 | unsigned int seed_material[NIST_BLOCK_SEEDLEN_INTS]; |
509 | |
510 | /* [1] seed_material = entropy_input || additional_input */ |
511 | input_string[0] = entropy_input; |
512 | length[0] = entropy_input_length; |
513 | count = 1; |
514 | |
515 | if (additional_input) { |
516 | input_string[count] = additional_input; |
517 | length[count] = additional_input_length; |
518 | |
519 | ++count; |
520 | } |
521 | /* [2] seed_material = Block_Cipher_df(seed_material, seedlen) */ |
522 | err = nist_ctr_drbg_block_cipher_df(input_string, length, count, |
523 | (unsigned char *)seed_material, |
524 | sizeof(seed_material)); |
525 | if (err) |
526 | return err; |
527 | |
528 | /* [3] (Key, V) = Update(seed_material, Key, V) */ |
529 | nist_ctr_drbg_update(drbg, seed_material); |
530 | |
531 | /* [4] reseed_counter = 1 */ |
532 | drbg->reseed_counter = 1; |
533 | |
534 | return 0; |
535 | } |
536 | |
537 | /* |
538 | * NIST SP 800-90 March 2007 |
539 | * 10.2.1.5.2 The Process Steps for Generating Pseudorandom Bits When a |
540 | * Derivation Function is Used for the DRBG Implementation |
541 | */ |
542 | static void |
543 | nist_ctr_drbg_generate_block(NIST_CTR_DRBG *drbg, unsigned int *output_block) |
544 | { |
545 | |
546 | /* [4.1] V = (V + 1) mod 2^outlen */ |
547 | nist_increment_block((unsigned long *)&drbg->V[0]); |
548 | |
549 | /* [4.2] output_block = Block_Encrypt(Key, V) */ |
550 | Block_Encrypt(&drbg->ctx, &drbg->V[0], output_block); |
551 | |
552 | } |
553 | |
554 | int |
555 | nist_ctr_drbg_generate(NIST_CTR_DRBG * drbg, |
556 | void *output_string, int output_string_length, |
557 | const void *additional_input, |
558 | int additional_input_length) |
559 | { |
560 | int i, len, err; |
561 | int blocks = output_string_length / NIST_BLOCK_OUTLEN_BYTES; |
562 | unsigned char* p; |
563 | unsigned int* temp; |
564 | const char *input_string[1]; |
565 | unsigned int length[1]; |
566 | unsigned int buffer[NIST_BLOCK_OUTLEN_BYTES]; |
567 | unsigned int additional_input_buffer[NIST_BLOCK_SEEDLEN_INTS]; |
568 | int ret = 0; |
569 | |
570 | if (output_string_length < 1) |
571 | return 1; |
572 | |
573 | /* [1] If reseed_counter > reseed_interval ... */ |
574 | if (drbg->reseed_counter >= NIST_CTR_DRBG_RESEED_INTERVAL) { |
575 | ret = 1; |
576 | goto out; |
577 | } |
578 | |
579 | /* [2] If (addional_input != Null), then */ |
580 | if (additional_input) { |
581 | input_string[0] = additional_input; |
582 | length[0] = additional_input_length; |
583 | /* |
584 | * [2.1] additional_input = |
585 | * Block_Cipher_df(additional_input, seedlen) |
586 | */ |
587 | err = nist_ctr_drbg_block_cipher_df(input_string, length, 1, |
588 | (unsigned char *)additional_input_buffer, |
589 | sizeof(additional_input_buffer)); |
590 | if (err) { |
591 | ret = err; |
592 | goto out; |
593 | } |
594 | |
595 | /* [2.2] (Key, V) = Update(additional_input, Key, V) */ |
596 | nist_ctr_drbg_update(drbg, additional_input_buffer); |
597 | } |
598 | |
599 | if (blocks && check_int_alignment(output_string)) { |
600 | /* [3] temp = Null */ |
601 | temp = (unsigned int *)output_string; |
602 | for (i = 0; i < blocks; ++i) { |
603 | nist_ctr_drbg_generate_block(drbg, temp); |
604 | |
605 | temp += NIST_BLOCK_OUTLEN_INTS; |
606 | output_string_length -= NIST_BLOCK_OUTLEN_BYTES; |
607 | } |
608 | |
609 | output_string = (unsigned char *)temp; |
610 | } |
611 | |
612 | /* [3] temp = Null */ |
613 | temp = buffer; |
614 | |
615 | len = NIST_BLOCK_OUTLEN_BYTES; |
616 | |
617 | /* [4] While (len(temp) < requested_number_of_bits) do: */ |
618 | p = output_string; |
619 | while (output_string_length > 0) { |
620 | nist_ctr_drbg_generate_block(drbg, temp); |
621 | |
622 | if (output_string_length < NIST_BLOCK_OUTLEN_BYTES) |
623 | len = output_string_length; |
624 | |
625 | memcpy(p, temp, len); |
626 | |
627 | p += len; |
628 | output_string_length -= len; |
629 | } |
630 | |
631 | /* [6] (Key, V) = Update(additional_input, Key, V) */ |
632 | nist_ctr_drbg_update(drbg, additional_input ? |
633 | &additional_input_buffer[0] : |
634 | &nist_ctr_drgb_generate_null_input[0]); |
635 | |
636 | /* [7] reseed_counter = reseed_counter + 1 */ |
637 | ++drbg->reseed_counter; |
638 | |
639 | out: |
640 | return ret; |
641 | } |
642 | |
643 | int |
644 | nist_ctr_initialize(void) |
645 | { |
646 | int err; |
647 | |
648 | err = nist_ctr_drbg_instantiate_initialize(); |
649 | if (err) |
650 | return err; |
651 | err = nist_ctr_drbg_block_cipher_df_initialize(); |
652 | if (err) |
653 | return err; |
654 | |
655 | return 0; |
656 | } |
657 | |
658 | int |
659 | nist_ctr_drbg_destroy(NIST_CTR_DRBG* drbg) |
660 | { |
661 | nist_zeroize(drbg, sizeof(*drbg)); |
662 | drbg->reseed_counter = ~0U; |
663 | return 1; |
664 | } |
665 | |