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