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
nist_increment_block(unsigned long * V)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
nist_ctr_drbg_bcc_update(const NIST_Key * ctx,const unsigned int * data,int n,unsigned int * chaining_value)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
nist_ctr_drbg_bcc(NIST_Key * ctx,const unsigned int * data,int n,unsigned int * output_block)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
check_int_alignment(const void * p)154 check_int_alignment(const void *p)
155 {
156 intptr_t ip = (intptr_t)p;
157
158 if (ip & (sizeof(int) - 1))
159 return 0;
160
161 return 1;
162 }
163
164 static void
nist_ctr_drbg_df_bcc_init(NIST_CTR_DRBG_DF_BCC_CTX * ctx,int L,int N)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
nist_ctr_drbg_df_bcc_update(NIST_CTR_DRBG_DF_BCC_CTX * ctx,const char * input_string,int input_string_length,unsigned int * temp)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
nist_ctr_drbg_df_bcc_final(NIST_CTR_DRBG_DF_BCC_CTX * ctx,unsigned int * temp)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
nist_ctr_drbg_block_cipher_df(const char * input_string[],unsigned int L[],int input_string_count,unsigned char * output_string,unsigned int N)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
nist_ctr_drbg_block_cipher_df_initialize(void)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
nist_ctr_drbg_update(NIST_CTR_DRBG * drbg,const unsigned int * provided_data)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
nist_ctr_drbg_instantiate(NIST_CTR_DRBG * drbg,const void * entropy_input,int entropy_input_length,const void * nonce,int nonce_length,const void * personalization_string,int personalization_string_length)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
nist_ctr_drbg_instantiate_initialize(void)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
nist_ctr_drbg_reseed(NIST_CTR_DRBG * drbg,const void * entropy_input,int entropy_input_length,const void * additional_input,int additional_input_length)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
nist_ctr_drbg_generate_block(NIST_CTR_DRBG * drbg,unsigned int * output_block)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
nist_ctr_drbg_generate(NIST_CTR_DRBG * drbg,void * output_string,int output_string_length,const void * additional_input,int additional_input_length)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
nist_ctr_initialize(void)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
nist_ctr_drbg_destroy(NIST_CTR_DRBG * drbg)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