nist_hash_drbg.c revision 1.1.2.2 1 /* $NetBSD: nist_hash_drbg.c,v 1.1.2.2 2019/09/03 07:47:59 martin Exp $ */
2
3 /*-
4 * Copyright (c) 2019 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Taylor R. Campbell.
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 * This file implements Hash_DRBG, a `deterministic random bit
34 * generator' (more commonly known in lay terms and in the cryptography
35 * literature as a pseudorandom bit generator or pseudorandom number
36 * generator), described in
37 *
38 * Elaine Barker and John Kelsey, `Recommendation for Random
39 * Number Generation Using Deterministic Random Bit Generators',
40 * NIST SP800-90A, June 2015.
41 *
42 * This code is meant to work in userland or in kernel. For a test
43 * program, compile with -DNIST_HASH_DRBG_MAIN to define a `main'
44 * function; for verbose debugging output, compile with
45 * -DNIST_HASH_DRBG_DEBUG, mainly useful if you need to change
46 * something and have to diagnose what's wrong with the known-answer
47 * tests.
48 */
49
50 #ifdef _KERNEL
52 #include <sys/cdefs.h>
53 __KERNEL_RCSID(0, "$NetBSD: nist_hash_drbg.c,v 1.1.2.2 2019/09/03 07:47:59 martin Exp $");
54 #endif
55
56 #include <sys/param.h>
57 #include <sys/types.h>
58 #include <sys/sha2.h>
59
60 #ifdef _KERNEL
61 #include <sys/systm.h> /* memcpy */
62 #include <lib/libkern/libkern.h> /* KASSERT */
63 #define ASSERT KASSERT
64 #else
65 #include <assert.h>
66 #include <stdbool.h>
67 #include <stdio.h>
68 #include <string.h>
69 #define ASSERT assert
70 #define CTASSERT __CTASSERT
71 #endif
72
73 #include "nist_hash_drbg.h"
74
75 #define secret /* must not use in variable-time operations; should zero */
76 #define arraycount(A) (sizeof(A)/sizeof(A[0]))
77
78 CTASSERT(0 < NIST_HASH_DRBG_RESEED_INTERVAL);
79 CTASSERT(NIST_HASH_DRBG_RESEED_INTERVAL <= INT_MAX);
80 CTASSERT(NIST_HASH_DRBG_RESEED_INTERVAL <= ~(~0ull << 48));
81
82 /* Instantiation: SHA-256 */
83 #define HASH_LENGTH SHA256_DIGEST_LENGTH
84 #define HASH_CTX SHA256_CTX
85 #define hash_init SHA256_Init
86 #define hash_update SHA256_Update
87 #define hash_final SHA256_Final
88
89 #define SEEDLEN_BYTES NIST_HASH_DRBG_SEEDLEN_BYTES
90
91 struct hvec {
92 const void *hv_base;
93 size_t hv_len;
94 };
95
96 static void hashgen(secret uint8_t *, size_t,
97 const secret uint8_t[SEEDLEN_BYTES]);
98 static void add8(secret uint8_t *, size_t, const secret uint8_t *, size_t);
99 static void hash_df(secret void *, size_t, const struct hvec *, size_t);
100 static void hash_df_block(secret void *, uint8_t, uint8_t[4],
101 const struct hvec *, size_t);
102
103 /* 10.1.1 Hash_DRBG */
105
106 int
107 nist_hash_drbg_destroy(struct nist_hash_drbg *D)
108 {
109
110 explicit_memset(D, 0, sizeof(*D));
111 D->reseed_counter = UINT_MAX; /* paranoia: make generate fail */
112
113 /* Always return zero for hysterical raisins. (XXX) */
114 return 0;
115 }
116
117 /* 10.1.1.2 Instantiation of Hash_DRBG */
118
119 int
120 nist_hash_drbg_instantiate(secret struct nist_hash_drbg *D,
121 const secret void *entropy, size_t entropylen,
122 const void *nonce, size_t noncelen,
123 const void *personalization, size_t personalizationlen)
124 {
125 /*
126 * 1. seed_material = entropy_input || nonce || personalization_string
127 */
128 const struct hvec seed_material[] = {
129 { .hv_base = entropy, .hv_len = entropylen },
130 { .hv_base = nonce, .hv_len = noncelen },
131 { .hv_base = personalization, .hv_len = personalizationlen },
132 };
133
134 /*
135 * 2. seed = Hash_df(seed_material, seedlen)
136 * 3. V = seed
137 */
138 CTASSERT(sizeof D->V == SEEDLEN_BYTES);
139 hash_df(D->V, sizeof D->V, seed_material, arraycount(seed_material));
140
141 /* 4. C = Hash_df((0x00 || V), seedlen) */
142 const struct hvec hv[] = {
143 { .hv_base = (const uint8_t[]) {0x00}, .hv_len = 1 },
144 { .hv_base = D->V, .hv_len = sizeof D->V },
145 };
146 CTASSERT(sizeof D->C == SEEDLEN_BYTES);
147 hash_df(D->C, sizeof D->C, hv, arraycount(hv));
148
149 /* 5. reseed_counter = 1 */
150 D->reseed_counter = 1;
151
152 /* Always return zero for hysterical raisins. (XXX) */
153 return 0;
154 }
155
156 /* 10.1.1.3 Reseeding a Hash_DRBG Instantiation */
158
159 int
160 nist_hash_drbg_reseed(secret struct nist_hash_drbg *D,
161 const secret void *entropy, size_t entropylen,
162 const void *additional, size_t additionallen)
163 {
164 /* 1. seed_material = 0x01 || V || entropy_input || additional_input */
165 const struct hvec seed_material[] = {
166 { .hv_base = (const uint8_t[]) {0x01}, .hv_len = 1 },
167 { .hv_base = D->V, .hv_len = sizeof D->V },
168 { .hv_base = entropy, .hv_len = entropylen },
169 { .hv_base = additional, .hv_len = additionallen },
170 };
171 uint8_t seed[SEEDLEN_BYTES];
172
173 /*
174 * 2. seed = Hash_df(seed_material, seedlen)
175 * 3. V = seed
176 */
177 CTASSERT(sizeof D->V == SEEDLEN_BYTES);
178 hash_df(seed, sizeof seed, seed_material, arraycount(seed_material));
179 memcpy(D->V, seed, sizeof D->V);
180
181 /* 3. C = Hash_df((0x00 || V), seedlen) */
182 const struct hvec hv[] = {
183 { .hv_base = (const uint8_t[]) {0x00}, .hv_len = 1 },
184 { .hv_base = D->V, .hv_len = sizeof D->V },
185 };
186 CTASSERT(sizeof D->C == SEEDLEN_BYTES);
187 hash_df(D->C, sizeof D->C, hv, arraycount(hv));
188
189 /* 5. reseed_counter = 1 */
190 D->reseed_counter = 1;
191
192 /* Always return zero for hysterical raisins. (XXX) */
193 return 0;
194 }
195
196 /* 10.1.1.4 Generating Pseudorandom Bits Using Hash_DRBG */
198
199 int
200 nist_hash_drbg_generate(secret struct nist_hash_drbg *D,
201 secret void *output, size_t outputlen,
202 const void *additional, size_t additionallen)
203 {
204 secret HASH_CTX ctx;
205 secret uint8_t H[HASH_LENGTH];
206 uint8_t reseed_counter[4];
207
208 ASSERT(outputlen <= NIST_HASH_DRBG_MAX_REQUEST_BYTES);
209
210 /*
211 * 1. If reseed_counter > reseed_interval, then return an
212 * indication that a reseed is required.
213 */
214 if (D->reseed_counter > NIST_HASH_DRBG_RESEED_INTERVAL)
215 return 1;
216
217 /* 2. If (additional_input != Null), then do: */
218 if (additionallen) {
219 /* 2.1 w = Hash(0x02 || V || additional_input) */
220 secret uint8_t w[HASH_LENGTH];
221
222 hash_init(&ctx);
223 hash_update(&ctx, (const uint8_t[]) {0x02}, 1);
224 hash_update(&ctx, D->V, sizeof D->V);
225 hash_update(&ctx, additional, additionallen);
226 hash_final(w, &ctx);
227
228 /* 2.2 V = (V + w) mod 2^seedlen */
229 add8(D->V, sizeof D->V, w, sizeof w);
230
231 explicit_memset(w, 0, sizeof w);
232 }
233
234 /* 3. (returned_bits) = Hashgen(requested_number_of_bits, V) */
235 hashgen(output, outputlen, D->V);
236
237 /* 4. H = Hash(0x03 || V) */
238 hash_init(&ctx);
239 hash_update(&ctx, (const uint8_t[]) {0x03}, 1);
240 hash_update(&ctx, D->V, sizeof D->V);
241 hash_final(H, &ctx);
242
243 /* 5. V = (V + H + C + reseed_counter) mod 2^seedlen */
244 be32enc(reseed_counter, D->reseed_counter);
245 add8(D->V, sizeof D->V, H, sizeof H);
246 add8(D->V, sizeof D->V, D->C, sizeof D->C);
247 add8(D->V, sizeof D->V, reseed_counter, sizeof reseed_counter);
248
249 /* 6. reseed_counter = reseed_counter + 1 */
250 D->reseed_counter++;
251
252 explicit_memset(&ctx, 0, sizeof ctx);
253 explicit_memset(H, 0, sizeof H);
254
255 /* 7. Return SUCCESS, ... */
256 return 0;
257 }
258
259 /*
261 * p := H(V) || H(V + 1) || H(V + 2) || ...
262 */
263 static void
264 hashgen(secret uint8_t *p, size_t n, const secret uint8_t V[SEEDLEN_BYTES])
265 {
266 secret uint8_t data[SEEDLEN_BYTES];
267 secret HASH_CTX ctx;
268
269 /* Save a copy so that we can increment it. */
270 memcpy(data, V, SEEDLEN_BYTES);
271
272 /* Generate block by block into p directly. */
273 while (HASH_LENGTH <= n) {
274 hash_init(&ctx);
275 hash_update(&ctx, data, SEEDLEN_BYTES);
276 hash_final(p, &ctx);
277
278 p += HASH_LENGTH;
279 n -= HASH_LENGTH;
280 add8(data, sizeof data, (const uint8_t[]) {1}, 1);
281 }
282
283 /*
284 * If any partial block requested, generate a full block and
285 * copy the part we need.
286 */
287 if (n) {
288 secret uint8_t t[HASH_LENGTH];
289
290 hash_init(&ctx);
291 hash_update(&ctx, data, SEEDLEN_BYTES);
292 hash_final(t, &ctx);
293
294 memcpy(p, t, n);
295 explicit_memset(t, 0, sizeof t);
296 }
297
298 explicit_memset(data, 0, sizeof data);
299 explicit_memset(&ctx, 0, sizeof ctx);
300 }
301
302 /*
303 * s := s + a (big-endian, radix-2^8)
304 */
305 static void
306 add8(secret uint8_t *s, size_t slen, const secret uint8_t *a, size_t alen)
307 {
308 const size_t smax = slen - 1, amax = alen - 1;
309 size_t i;
310 secret unsigned c = 0;
311
312 /* 2^8 c + s_i := s_i + a_i + c */
313 for (i = 0; i < MIN(slen, alen); i++) {
314 c += s[smax - i] + a[amax - i];
315 s[smax - i] = c & 0xff;
316 c >>= 8;
317 }
318
319 /* 2^8 c + s_i := s_i + c */
320 for (; i < slen; i++) {
321 c += s[smax - i];
322 s[smax - i] = c & 0xff;
323 c >>= 8;
324 }
325
326 explicit_memset(&c, 0, sizeof c);
327 }
328
329 /* 10.4.1 Derivation Function Using a Hash Function (Hash_df) */
331
332 static void
333 hash_df(void *h, size_t hlen, const struct hvec *input, size_t inputlen)
334 {
335 uint8_t *p = h;
336 size_t n = hlen;
337 uint8_t counter = 1;
338 uint8_t hbits[4];
339
340 ASSERT(hlen <= 255*HASH_LENGTH);
341 ASSERT(hlen <= UINT32_MAX/8);
342 be32enc(hbits, 8*hlen);
343
344 while (HASH_LENGTH <= n) {
345 hash_df_block(p, counter++, hbits, input, inputlen);
346 p += HASH_LENGTH;
347 n -= HASH_LENGTH;
348 }
349
350 if (n) {
351 secret uint8_t t[HASH_LENGTH];
352
353 hash_df_block(t, counter, hbits, input, inputlen);
354 memcpy(p, t, n);
355
356 explicit_memset(t, 0, sizeof t);
357 }
358 }
359
360 static void
361 hash_df_block(secret void *h, uint8_t counter, uint8_t hbits[4],
362 const struct hvec *input, size_t inputlen)
363 {
364 secret HASH_CTX ctx;
365 size_t i;
366
367 /*
368 * Hash_df Process, step 4.1:
369 * Hash(counter || no_of_bits_to_return || input_string)
370 */
371 hash_init(&ctx);
372 hash_update(&ctx, &counter, 1);
373 hash_update(&ctx, hbits, 4);
374 for (i = 0; i < inputlen; i++) {
375 if (input[i].hv_len)
376 hash_update(&ctx, input[i].hv_base, input[i].hv_len);
377 }
378 hash_final(h, &ctx);
379
380 explicit_memset(&ctx, 0, sizeof ctx);
381 }
382
383 /*
385 * Known-answer test vectors for Hash_DRBG with SHA-256
386 */
387
388 /* Hash_DRBG.PDF, p. 190 */
389 static const uint8_t kat_entropy[3][SEEDLEN_BYTES] = {
390 [0] = {
391 0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07,
392 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f,
393 0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17,
394 0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f,
395 0x20,0x21,0x22,0x23, 0x24,0x25,0x26,0x27,
396 0x28,0x29,0x2a,0x2b, 0x2c,0x2d,0x2e,0x2f,
397 0x30,0x31,0x32,0x33, 0x34,0x35,0x36,
398 },
399 [1] = { /* for reseed1 */
400 0x80,0x81,0x82,0x83, 0x84,0x85,0x86,0x87,
401 0x88,0x89,0x8a,0x8b, 0x8c,0x8d,0x8e,0x8f,
402 0x90,0x91,0x92,0x93, 0x94,0x95,0x96,0x97,
403 0x98,0x99,0x9a,0x9b, 0x9c,0x9d,0x9e,0x9f,
404 0xa0,0xa1,0xa2,0xa3, 0xa4,0xa5,0xa6,0xa7,
405 0xa8,0xa9,0xaa,0xab, 0xac,0xad,0xae,0xaf,
406 0xb0,0xb1,0xb2,0xb3, 0xb4,0xb5,0xb6,
407 },
408 [2] = { /* for reseed2 */
409 0xc0,0xc1,0xc2,0xc3, 0xc4,0xc5,0xc6,0xc7,
410 0xc8,0xc9,0xca,0xcb, 0xcc,0xcd,0xce,0xcf,
411 0xd0,0xd1,0xd2,0xd3, 0xd4,0xd5,0xd6,0xd7,
412 0xd8,0xd9,0xda,0xdb, 0xdc,0xdd,0xde,0xdf,
413 0xe0,0xe1,0xe2,0xe3, 0xe4,0xe5,0xe6,0xe7,
414 0xe8,0xe9,0xea,0xeb, 0xec,0xed,0xee,0xef,
415 0xf0,0xf1,0xf2,0xf3, 0xf4,0xf5,0xf6,
416 },
417 };
418
419 static const uint8_t kat_nonce[] = {
420 0x20,0x21,0x22,0x23, 0x24,0x25,0x26,0x27,
421 };
422
423 static const struct hvec kat_zero = { .hv_base = 0, .hv_len = 0 };
424
425 static const struct hvec kat_personalization = {
427 .hv_len = 55,
428 .hv_base = (const void *)(const uint8_t[]) { /* p. 208 */
429 0x40,0x41,0x42,0x43, 0x44,0x45,0x46,0x47,
430 0x48,0x49,0x4a,0x4b, 0x4c,0x4d,0x4e,0x4f,
431 0x50,0x51,0x52,0x53, 0x54,0x55,0x56,0x57,
432 0x58,0x59,0x5a,0x5b, 0x5c,0x5d,0x5e,0x5f,
433 0x60,0x61,0x62,0x63, 0x64,0x65,0x66,0x67,
434 0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f,
435 0x70,0x71,0x72,0x73, 0x74,0x75,0x76,
436 },
437 };
438
439 static const struct hvec *const kat_no_additional[] = {
440 [0] = &kat_zero,
441 [1] = &kat_zero,
442 };
443
444 static const struct hvec *const kat_additional[] = {
445 [0] = &(const struct hvec) {
446 .hv_len = 55,
447 .hv_base = (const void *)(const uint8_t[]) {
448 0x60,0x61,0x62,0x63, 0x64,0x65,0x66,0x67,
449 0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f,
450 0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77,
451 0x78,0x79,0x7a,0x7b, 0x7c,0x7d,0x7e,0x7f,
452 0x80,0x81,0x82,0x83, 0x84,0x85,0x86,0x87,
453 0x88,0x89,0x8a,0x8b, 0x8c,0x8d,0x8e,0x8f,
454 0x90,0x91,0x92,0x93, 0x94,0x95,0x96,
455 },
456 },
457 [1] = &(const struct hvec) {
458 .hv_len = 55,
459 .hv_base = (const void *)(const uint8_t[]) {
460 0xa0,0xa1,0xa2,0xa3, 0xa4,0xa5,0xa6,0xa7,
461 0xa8,0xa9,0xaa,0xab, 0xac,0xad,0xae,0xaf,
462 0xb0,0xb1,0xb2,0xb3, 0xb4,0xb5,0xb6,0xb7,
463 0xb8,0xb9,0xba,0xbb, 0xbc,0xbd,0xbe,0xbf,
464 0xc0,0xc1,0xc2,0xc3, 0xc4,0xc5,0xc6,0xc7,
465 0xc8,0xc9,0xca,0xcb, 0xcc,0xcd,0xce,0xcf,
466 0xd0,0xd1,0xd2,0xd3, 0xd4,0xd5,0xd6,
467 },
468 },
469 };
470
471 static const struct {
473 const struct hvec *personalization;
474 const struct hvec *const *additional;
475 bool reseed;
476 uint8_t C[SEEDLEN_BYTES];
477 uint8_t V[3][SEEDLEN_BYTES];
478 uint8_t rnd_val[2][64];
479 } kat[] = {
480 [0] = { /* Hash_DRBG.pdf, p. 190 */
481 .personalization = &kat_zero,
482 .additional = kat_no_additional,
483 .reseed = false,
484 .C = { /* p. 193 */
485 0xe1,0x5d,0xe4,0xa8, 0xe3,0xb1,0x41,0x9b,
486 0x61,0xd5,0x34,0xf1, 0x5d,0xbd,0x31,0xee,
487 0x19,0xec,0x59,0x5f, 0x8b,0x98,0x11,0x1a,
488 0x94,0xf5,0x22,0x37, 0xad,0x5d,0x66,0xf0,
489 0xcf,0xaa,0xfd,0xdc, 0x90,0x19,0x59,0x02,
490 0xe9,0x79,0xf7,0x9b, 0x65,0x35,0x7f,0xea,
491 0x85,0x99,0x8e,0x4e, 0x37,0xd2,0xc1,
492 },
493 .V = {
494 [0] = { /* p. 192 */
495 0xab,0x41,0xcd,0xe4, 0x37,0xab,0x8b,0x09,
496 0x1c,0xa7,0xc5,0x75, 0x5d,0x10,0xf0,0x11,
497 0x0c,0x1d,0xbd,0x46, 0x2f,0x22,0x6c,0xfd,
498 0xab,0xfb,0xb0,0x4a, 0x8b,0xcd,0xef,0x95,
499 0x16,0x7d,0x84,0xaf, 0x64,0x12,0x8c,0x0d,
500 0x71,0xf4,0xd5,0xb8, 0xc0,0xed,0xfb,0xbe,
501 0x3d,0xf4,0x04,0x48, 0xd2,0xd8,0xe1,
502 },
503 [1] = { /* p. 195 */
504 0x8c,0x9f,0xb2,0x8d, 0x1b,0x5c,0xcc,0xa4,
505 0x7e,0x7c,0xfa,0x66, 0xba,0xce,0x21,0xff,
506 0x26,0x0a,0x16,0xa5, 0xba,0xba,0x7f,0x14,
507 0x4e,0x75,0x79,0x36, 0x8e,0x99,0x55,0xbe,
508 0xfb,0xe7,0x00,0xee, 0xf8,0x72,0x77,0x6b,
509 0x17,0xae,0xff,0xd5, 0x3d,0x76,0xf4,0xe3,
510 0xbe,0x65,0xe8,0xc9, 0x4b,0x70,0x8f,
511 },
512 [2] = { /* p. 197 */
513 0x6d,0xfd,0x97,0x35, 0xff,0x0e,0x0e,0x3f,
514 0xe0,0x52,0x2f,0x58, 0x18,0x8b,0x53,0xed,
515 0x3f,0xf6,0x70,0x05, 0x46,0x52,0x90,0x44,
516 0xb6,0x2b,0xe1,0x7d, 0x1b,0x1c,0x21,0xd0,
517 0x91,0xb0,0x89,0xb1, 0x77,0x47,0x95,0xdb,
518 0x14,0x22,0xa8,0x6c, 0x95,0x46,0x34,0x80,
519 0x76,0xb4,0xb6,0x21, 0xc7,0x2f,0x91,
520 },
521 },
522 .rnd_val = {
523 [0] = {
524 0x77,0xe0,0x5a,0x0e, 0x7d,0xc7,0x8a,0xb5,
525 0xd8,0x93,0x4d,0x5e, 0x93,0xe8,0x2c,0x06,
526 0xa0,0x7c,0x04,0xce, 0xe6,0xc9,0xc5,0x30,
527 0x45,0xee,0xb4,0x85, 0x87,0x27,0x77,0xcf,
528 0x3b,0x3e,0x35,0xc4, 0x74,0xf9,0x76,0xb8,
529 0x94,0xbf,0x30,0x1a, 0x86,0xfa,0x65,0x1f,
530 0x46,0x39,0x70,0xe8, 0x9d,0x4a,0x05,0x34,
531 0xb2,0xec,0xad,0x29, 0xec,0x04,0x4e,0x7e,
532 },
533 {
534 0x5f,0xf4,0xba,0x49, 0x3c,0x40,0xcf,0xff,
535 0x3b,0x01,0xe4,0x72, 0xc5,0x75,0x66,0x8c,
536 0xce,0x38,0x80,0xb9, 0x29,0x0b,0x05,0xbf,
537 0xed,0xe5,0xec,0x96, 0xed,0x5e,0x9b,0x28,
538 0x98,0x50,0x8b,0x09, 0xbc,0x80,0x0e,0xee,
539 0x09,0x9a,0x3c,0x90, 0x60,0x2a,0xbd,0x4b,
540 0x1d,0x4f,0x34,0x3d, 0x49,0x7c,0x60,0x55,
541 0xc8,0x7b,0xb9,0x56, 0xd5,0x3b,0xf3,0x51,
542 },
543 },
544 },
545
546 [1] = { /* Hash_DRBG.pdf, p. 198 */
548 .personalization = &kat_zero,
549 .additional = kat_additional,
550 .reseed = false,
551 .C = { /* p. 201 */
552 0xe1,0x5d,0xe4,0xa8, 0xe3,0xb1,0x41,0x9b,
553 0x61,0xd5,0x34,0xf1, 0x5d,0xbd,0x31,0xee,
554 0x19,0xec,0x59,0x5f, 0x8b,0x98,0x11,0x1a,
555 0x94,0xf5,0x22,0x37, 0xad,0x5d,0x66,0xf0,
556 0xcf,0xaa,0xfd,0xdc, 0x90,0x19,0x59,0x02,
557 0xe9,0x79,0xf7,0x9b, 0x65,0x35,0x7f,0xea,
558 0x85,0x99,0x8e,0x4e, 0x37,0xd2,0xc1,
559 },
560 .V = {
561 [0] = { /* p. 200 */
562 0xab,0x41,0xcd,0xe4, 0x37,0xab,0x8b,0x09,
563 0x1c,0xa7,0xc5,0x75, 0x5d,0x10,0xf0,0x11,
564 0x0c,0x1d,0xbd,0x46, 0x2f,0x22,0x6c,0xfd,
565 0xab,0xfb,0xb0,0x4a, 0x8b,0xcd,0xef,0x95,
566 0x16,0x7d,0x84,0xaf, 0x64,0x12,0x8c,0x0d,
567 0x71,0xf4,0xd5,0xb8, 0xc0,0xed,0xfb,0xbe,
568 0x3d,0xf4,0x04,0x48, 0xd2,0xd8,0xe1,
569 },
570 [1] = { /* p. 204 */
571 0x8c,0x9f,0xb2,0x8d, 0x1b,0x5c,0xcc,0xa4,
572 0x7e,0x7c,0xfa,0x66, 0xba,0xce,0x21,0xff,
573 0x26,0x0a,0x16,0xa5, 0xba,0xba,0x7f,0x1f,
574 0xd3,0x3b,0x30,0x79, 0x8f,0xb2,0x9a,0x0f,
575 0xba,0x66,0x65,0x02, 0x7d,0x7f,0x10,0x58,
576 0x71,0xbf,0xb4,0x40, 0xdf,0xbe,0xde,0x81,
577 0xd0,0x4d,0x22,0xdf, 0xf7,0x89,0xe1,
578 },
579 [2] = { /* p. 207 */
580 0x6d,0xfd,0x97,0x35, 0xff,0x0e,0x0e,0x3f,
581 0xe0,0x52,0x2f,0x58, 0x18,0x8b,0x53,0xed,
582 0x3f,0xf6,0x70,0x05, 0x46,0x52,0x90,0xe1,
583 0x7c,0x5a,0xd8,0x2d, 0xa9,0x2a,0x05,0x01,
584 0xaa,0x66,0x3a,0xa6, 0x9f,0xa5,0xa0,0xb0,
585 0x81,0x2b,0x4b,0x4f, 0xaf,0xf3,0xfe,0xce,
586 0x79,0xcc,0xf6,0xaa, 0xde,0xc1,0xd0,
587 },
588 },
589 .rnd_val = {
590 [0] = { /* p. 203 */
591 0x51,0x07,0x24,0xb9, 0x3a,0xe9,0xa1,0x82,
592 0x70,0xe4,0x84,0x73, 0x71,0x1d,0x88,0x24,
593 0x63,0x1b,0xaa,0x7f, 0x1d,0x9a,0xc9,0x28,
594 0x4e,0x7e,0xc8,0xf3, 0x63,0x7f,0x7a,0x74,
595 0x3b,0x36,0x44,0xeb, 0x96,0xc9,0x86,0x27,
596 0xc8,0xfd,0x40,0x5a, 0x7a,0x46,0x03,0xf3,
597 0x8c,0xff,0x7c,0x89, 0xe9,0xc1,0x33,0xf5,
598 0x85,0x1f,0x40,0xe9, 0x20,0x30,0xfe,0xa2,
599 },
600 [1] = { /* p. 206 */
601 0x62,0x53,0xda,0x3a, 0xae,0x8b,0x88,0xa3,
602 0xb7,0x46,0xe4,0xc8, 0xb2,0x63,0x5c,0x54,
603 0x0f,0x6e,0x9e,0xa7, 0x15,0x7e,0xe6,0x9d,
604 0xd7,0x1e,0xfb,0x2e, 0x8f,0xf7,0xbb,0xe1,
605 0xe3,0x33,0x68,0x88, 0x38,0xdd,0x7d,0xe4,
606 0x9c,0xc8,0x89,0x90, 0x30,0x9c,0x96,0xcd,
607 0xb2,0xab,0x92,0x95, 0x74,0x36,0xbf,0x83,
608 0xd1,0xbd,0x83,0x08, 0x19,0xc7,0x48,0xca,
609 },
610 },
611 },
612
613 [2] = { /* Hash_DRBG.pdf, p. 208 */
615 .personalization = &kat_personalization,
616 .additional = kat_no_additional,
617 .reseed = false,
618 .C = { /* p. 211 */
619 0x44,0x74,0x8a,0x78, 0xb1,0x6e,0x75,0x55,
620 0x9f,0x88,0x1d,0x51, 0xc1,0x5d,0xfe,0x6c,
621 0x52,0xcf,0xb0,0xbb, 0x71,0x62,0x01,0x69,
622 0xc7,0x93,0x34,0x27, 0x67,0xe7,0xf8,0x87,
623 0x5f,0x42,0xcb,0x6a, 0x20,0xc8,0x9d,0x7c,
624 0x6e,0xf3,0xdc,0x61, 0x0d,0x8f,0xf2,0x03,
625 0xd6,0x76,0x6c,0xed, 0x19,0x19,0xd0,
626 },
627 .V = {
628 [0] = { /* p. 210 */
629 0xa3,0xe9,0x4e,0x39, 0x26,0xfd,0xa1,0x69,
630 0xc3,0x03,0xd6,0x64, 0x38,0x39,0x05,0xe0,
631 0xd7,0x99,0x62,0xd1, 0x65,0x44,0x6d,0x63,
632 0xbd,0xa6,0x54,0xd1, 0x32,0xf7,0x2d,0xb4,
633 0x71,0x56,0x4b,0x45, 0x6f,0xf2,0xee,0xc8,
634 0x36,0x42,0x2a,0xcc, 0x5a,0x02,0x99,0x35,
635 0xa7,0x99,0x29,0x90, 0x94,0xa1,0xca,
636 },
637 [1] = { /* p. 213 */
638 0xe8,0x5d,0xd8,0xb1, 0xd8,0x6c,0x16,0xbf,
639 0x62,0x8b,0xf3,0xb5, 0xf9,0x97,0x04,0x4d,
640 0x2a,0x69,0x13,0x8c, 0xd6,0xa6,0x6e,0xe7,
641 0x36,0xdb,0xaa,0x3b, 0xf1,0xd0,0x28,0x3b,
642 0x71,0x7b,0x33,0x6e, 0xb3,0xae,0x5b,0xdd,
643 0x04,0x17,0x2e,0xa2, 0x6e,0x5a,0x48,0xf3,
644 0xb3,0xfb,0xab,0xf8, 0x2f,0x76,0x79,
645 },
646 [2] = { /* p. 215 */
647 0x2c,0xd2,0x63,0x2a, 0x89,0xda,0x8c,0x15,
648 0x02,0x14,0x11,0x07, 0xba,0xf5,0x02,0xb9,
649 0x7d,0x38,0xc4,0x48, 0x48,0x08,0x71,0x0a,
650 0x66,0xf8,0x40,0x11, 0xd7,0x02,0x8d,0x14,
651 0xd3,0x15,0x5a,0x73, 0x79,0xad,0xd5,0x3c,
652 0xc8,0xea,0x84,0xd0, 0xfc,0x64,0x1d,0xfc,
653 0x62,0x9e,0x06,0x19, 0x1f,0x5f,0x6d,
654 },
655 },
656 .rnd_val = {
657 [0] = { /* p. 213 */
658 0x4a,0x62,0x66,0x4f, 0x26,0x6e,0xe5,0x37,
659 0xb9,0x0d,0x64,0xb0, 0x5e,0x1d,0x81,0x3d,
660 0x28,0xb1,0x59,0xa9, 0x79,0xf1,0x50,0x9d,
661 0xde,0x31,0xb7,0x1d, 0xa4,0x3d,0x54,0x6e,
662 0xe8,0xe7,0x86,0x78, 0x20,0x2d,0xc2,0x37,
663 0xad,0x4a,0xfe,0x7d, 0xf3,0x10,0xc9,0xa4,
664 0x13,0xe3,0x8a,0xaf, 0x41,0x7d,0x2d,0x22,
665 0x5a,0xa3,0x65,0xec, 0x4a,0x7d,0x29,0x96,
666 },
667 [1] = { /* p. 215 */
668 0x59,0x58,0x3d,0x3c, 0x0a,0xc3,0x71,0x30,
669 0xc4,0x78,0x9a,0x83, 0x11,0xb8,0xca,0x8f,
670 0x98,0x5e,0xf1,0xe8, 0xf9,0x4d,0x95,0x4e,
671 0x32,0xe3,0x44,0xa6, 0x21,0xc2,0x4b,0x2f,
672 0x37,0x1d,0xa9,0xba, 0x3c,0x33,0x15,0x3f,
673 0x09,0xe5,0x51,0x45, 0xe7,0x62,0x92,0x6b,
674 0x73,0xac,0x14,0x7a, 0x1e,0x86,0x31,0xd1,
675 0xcc,0xd0,0x85,0x67, 0xcf,0x67,0x7c,0x72,
676 },
677 },
678 },
679
680 [3] = { /* Hash_DRBG.pdf, p. 215 */
682 .personalization = &kat_personalization,
683 .additional = kat_additional,
684 .reseed = false,
685 .C = { /* p. 220 */
686 0x44,0x74,0x8a,0x78, 0xb1,0x6e,0x75,0x55,
687 0x9f,0x88,0x1d,0x51, 0xc1,0x5d,0xfe,0x6c,
688 0x52,0xcf,0xb0,0xbb, 0x71,0x62,0x01,0x69,
689 0xc7,0x93,0x34,0x27, 0x67,0xe7,0xf8,0x87,
690 0x5f,0x42,0xcb,0x6a, 0x20,0xc8,0x9d,0x7c,
691 0x6e,0xf3,0xdc,0x61, 0x0d,0x8f,0xf2,0x03,
692 0xd6,0x76,0x6c,0xed, 0x19,0x19,0xd0,
693 },
694 .V = {
695 [0] = { /* p. 218 */
696 0xa3,0xe9,0x4e,0x39, 0x26,0xfd,0xa1,0x69,
697 0xc3,0x03,0xd6,0x64, 0x38,0x39,0x05,0xe0,
698 0xd7,0x99,0x62,0xd1, 0x65,0x44,0x6d,0x63,
699 0xbd,0xa6,0x54,0xd1, 0x32,0xf7,0x2d,0xb4,
700 0x71,0x56,0x4b,0x45, 0x6f,0xf2,0xee,0xc8,
701 0x36,0x42,0x2a,0xcc, 0x5a,0x02,0x99,0x35,
702 0xa7,0x99,0x29,0x90, 0x94,0xa1,0xca,
703 },
704 [1] = { /* p. 222 */
705 0xe8,0x5d,0xd8,0xb1, 0xd8,0x6c,0x16,0xbf,
706 0x62,0x8b,0xf3,0xb5, 0xf9,0x97,0x04,0x4d,
707 0x2a,0x69,0x13,0x8c, 0xd6,0xa6,0x6f,0x8c,
708 0xa8,0x7b,0x87,0x43, 0x50,0x20,0x2e,0x1d,
709 0x8a,0xb0,0xb5,0xad, 0x47,0xac,0xc2,0x75,
710 0x40,0x28,0x9f,0xe3, 0xa8,0xe3,0x1f,0x7b,
711 0x56,0x58,0xdd,0xd1, 0x96,0x94,0x89,
712 },
713 [2] = { /* p. 225 */
714 0x2c,0xd2,0x63,0x2a, 0x89,0xda,0x8c,0x15,
715 0x02,0x14,0x11,0x07, 0xba,0xf5,0x02,0xb9,
716 0x7d,0x38,0xc4,0x48, 0x48,0x08,0x71,0xb2,
717 0x77,0xae,0xc7,0xff, 0x8d,0xa2,0x3c,0x71,
718 0xef,0xf5,0x9d,0xc2, 0x4e,0x5e,0x4c,0x7f,
719 0x58,0x47,0xb0,0xc1, 0x2f,0x6a,0x59,0x9e,
720 0x6b,0x2e,0xda,0xc0, 0x30,0x6b,0xcd,
721 },
722 },
723 .rnd_val = { /* p. 222 */
724 [0] = {
725 0xe0,0xb9,0x7c,0x82, 0x12,0x68,0xfd,0x3b,
726 0xb2,0xca,0xbf,0xd1, 0xf9,0x54,0x84,0x78,
727 0xae,0x8a,0x60,0x41, 0x7f,0x7b,0x09,0x4a,
728 0x26,0x13,0x95,0x46, 0x06,0x2b,0x52,0x1c,
729 0xfd,0x33,0xe4,0xe3, 0x9b,0x9d,0xcd,0x0a,
730 0x3d,0xa1,0x52,0x09, 0xc7,0x2a,0xdb,0xe5,
731 0x8c,0x20,0xab,0x34, 0x07,0x02,0x69,0x51,
732 0x29,0x7a,0xd2,0x54, 0x30,0x75,0x53,0xa5,
733 },
734 [1] = { /* p. 225 */
735 0xc1,0xac,0xd3,0xad, 0xa4,0xc8,0xc4,0x95,
736 0xbf,0x17,0x9d,0xb5, 0x98,0x22,0xc3,0x51,
737 0xbc,0x47,0x9a,0xbe, 0x4e,0xb2,0x8f,0x84,
738 0x39,0x57,0xb1,0x1e, 0x3c,0x2b,0xc0,0x48,
739 0x83,0x96,0x42,0x97, 0x97,0x5b,0xd7,0x2d,
740 0x10,0x24,0xab,0xcf, 0x6f,0x66,0x15,0xd7,
741 0xf5,0xb4,0xfd,0x1e, 0x40,0xa6,0x4e,0xeb,
742 0x45,0xba,0x21,0x81, 0xb8,0x39,0x37,0xed,
743 },
744 },
745 },
746
747 [4] = { /* Hash_DRBG.pdf, p. 225 */
749 .personalization = &kat_zero,
750 .additional = kat_no_additional,
751 .reseed = true,
752 .C = { /* p. 229 */
753 0xe1,0x5d,0xe4,0xa8, 0xe3,0xb1,0x41,0x9b,
754 0x61,0xd5,0x34,0xf1, 0x5d,0xbd,0x31,0xee,
755 0x19,0xec,0x59,0x5f, 0x8b,0x98,0x11,0x1a,
756 0x94,0xf5,0x22,0x37, 0xad,0x5d,0x66,0xf0,
757 0xcf,0xaa,0xfd,0xdc, 0x90,0x19,0x59,0x02,
758 0xe9,0x79,0xf7,0x9b, 0x65,0x35,0x7f,0xea,
759 0x85,0x99,0x8e,0x4e, 0x37,0xd2,0xc1,
760 },
761 .V = {
762 [0] = { /* p. 227 */
763 0xab,0x41,0xcd,0xe4, 0x37,0xab,0x8b,0x09,
764 0x1c,0xa7,0xc5,0x75, 0x5d,0x10,0xf0,0x11,
765 0x0c,0x1d,0xbd,0x46, 0x2f,0x22,0x6c,0xfd,
766 0xab,0xfb,0xb0,0x4a, 0x8b,0xcd,0xef,0x95,
767 0x16,0x7d,0x84,0xaf, 0x64,0x12,0x8c,0x0d,
768 0x71,0xf4,0xd5,0xb8, 0xc0,0xed,0xfb,0xbe,
769 0x3d,0xf4,0x04,0x48, 0xd2,0xd8,0xe1,
770 },
771 [1] = { /* p. 234 */
772 0x23,0x97,0x6c,0x61, 0x63,0xd7,0xe2,0x4a,
773 0x1a,0x03,0x8f,0x2b, 0x2b,0x64,0x67,0x97,
774 0x50,0xca,0x9e,0xd8, 0xd1,0x40,0x69,0x8d,
775 0x64,0x22,0x39,0x7b, 0x02,0x96,0x9e,0x6e,
776 0xcd,0xd2,0x9d,0xac, 0xc5,0x76,0x7e,0x2c,
777 0xc2,0xd0,0xa1,0x56, 0xc8,0x7a,0xd0,0xb3,
778 0x57,0x89,0x05,0x07, 0xe0,0x37,0x77,
779 },
780 [2] = { /* p. 239 */
781 0x92,0xfb,0x0e,0x48, 0x0e,0x86,0x99,0x13,
782 0xc7,0xad,0x45,0xc7, 0xe3,0xfd,0x46,0x10,
783 0x17,0xe5,0xa6,0xb7, 0x70,0xf3,0x3b,0x31,
784 0x3c,0x38,0x83,0xf1, 0xcc,0x56,0x71,0x89,
785 0x45,0x21,0xf5,0xed, 0xe6,0x2e,0xaa,0xb0,
786 0x83,0xb1,0x41,0xa7, 0x5b,0x5c,0xc0,0x22,
787 0x60,0x5a,0x8a,0x3d, 0xc7,0x1b,0xa7,
788 },
789 },
790 .rnd_val = {
791 [0] = { /* p. 234 */
792 0x92,0x27,0x55,0x23, 0xc7,0x0e,0x56,0x7b,
793 0xcf,0x9b,0x35,0xec, 0x50,0xb9,0x33,0xf8,
794 0x12,0x61,0x6d,0xf5, 0x86,0xb7,0xf7,0x2e,
795 0xe1,0xbc,0x77,0x35, 0xa5,0xc2,0x65,0x43,
796 0x73,0xcb,0xbc,0x72, 0x31,0x6d,0xff,0x84,
797 0x20,0xa3,0x3b,0xf0, 0x2b,0x97,0xac,0x8d,
798 0x19,0x52,0x58,0x3f, 0x27,0x0a,0xcd,0x70,
799 0x05,0xcc,0x02,0x7f, 0x4c,0xf1,0x18,0x7e,
800 },
801 [1] = { /* p. 239 */
802 0x68,0x1a,0x46,0xb2, 0xaa,0x86,0x94,0xa0,
803 0xfe,0x4d,0xee,0xa7, 0x20,0x92,0x7a,0x84,
804 0xea,0xaa,0x98,0x5e, 0x59,0xc1,0x9f,0x8b,
805 0xe0,0x98,0x4d,0x8c, 0xbe,0xf8,0xc6,0x9b,
806 0x75,0x41,0x67,0x64, 0x19,0x46,0xe0,0x40,
807 0xee,0x20,0x43,0xe1, 0xcc,0xb2,0x9d,0xcf,
808 0x06,0x3c,0x0a,0x50, 0x83,0x0e,0x42,0x8e,
809 0x6d,0xca,0x26,0x2e, 0xcd,0x77,0xc5,0x42,
810 },
811 },
812 },
813
814 [5] = { /* Hash_DRBG.pdf, p. 239 */
816 .personalization = &kat_zero,
817 .additional = kat_additional,
818 .reseed = true,
819 .C = { /* p. 243 */
820 0xe1,0x5d,0xe4,0xa8, 0xe3,0xb1,0x41,0x9b,
821 0x61,0xd5,0x34,0xf1, 0x5d,0xbd,0x31,0xee,
822 0x19,0xec,0x59,0x5f, 0x8b,0x98,0x11,0x1a,
823 0x94,0xf5,0x22,0x37, 0xad,0x5d,0x66,0xf0,
824 0xcf,0xaa,0xfd,0xdc, 0x90,0x19,0x59,0x02,
825 0xe9,0x79,0xf7,0x9b, 0x65,0x35,0x7f,0xea,
826 0x85,0x99,0x8e,0x4e, 0x37,0xd2,0xc1,
827 },
828 .V = {
829 [0] = { /* p. 242 */
830 0xab,0x41,0xcd,0xe4, 0x37,0xab,0x8b,0x09,
831 0x1c,0xa7,0xc5,0x75, 0x5d,0x10,0xf0,0x11,
832 0x0c,0x1d,0xbd,0x46, 0x2f,0x22,0x6c,0xfd,
833 0xab,0xfb,0xb0,0x4a, 0x8b,0xcd,0xef,0x95,
834 0x16,0x7d,0x84,0xaf, 0x64,0x12,0x8c,0x0d,
835 0x71,0xf4,0xd5,0xb8, 0xc0,0xed,0xfb,0xbe,
836 0x3d,0xf4,0x04,0x48, 0xd2,0xd8,0xe1,
837 },
838 [1] = { /* p. 249 */
839 0xb3,0x74,0x95,0x46, 0x81,0xcf,0xc9,0x5b,
840 0x8d,0xb8,0x39,0x52, 0x8c,0x71,0x08,0x83,
841 0x5e,0xb4,0xf3,0x0a, 0xd9,0x1c,0xbe,0x9e,
842 0xa0,0xd5,0x45,0xcc, 0xfd,0x18,0x13,0x2a,
843 0xf1,0xd3,0x76,0x8f, 0x47,0x02,0x77,0x2b,
844 0x69,0x15,0x9f,0x2c, 0xc0,0x7f,0x48,0x74,
845 0x1e,0xb5,0xb2,0xb1, 0x22,0x11,0x25,
846 },
847 [2] = { /* p. 254 */
848 0xbf,0xe3,0xd6,0x81, 0xa2,0x0f,0xbe,0x39,
849 0x03,0x8f,0x4d,0x66, 0x77,0x7c,0x1b,0xe5,
850 0x79,0xee,0xb4,0x85, 0x7b,0x42,0xf2,0x1c,
851 0x3f,0x59,0x8b,0x59, 0x62,0xb7,0xaa,0x48,
852 0x0e,0xa5,0x65,0xfe, 0xea,0xbd,0xfb,0xd6,
853 0xa7,0xec,0xcb,0x96, 0x02,0xc1,0x4b,0xfa,
854 0x30,0xf0,0xf9,0x81, 0x90,0x0c,0xd0,
855 },
856 },
857 .rnd_val = {
858 [0] = { /* p. 249 */
859 0x11,0x60,0x1b,0x72, 0xca,0x60,0x89,0x73,
860 0x6b,0x20,0x47,0x44, 0xb2,0x9d,0xa1,0xaa,
861 0xaf,0xba,0xca,0xa5, 0x28,0x8f,0x06,0xbe,
862 0x48,0x45,0x69,0xcc, 0xed,0xbe,0xce,0x03,
863 0xe8,0x22,0xea,0xa5, 0xb1,0x4f,0x0e,0x04,
864 0x94,0x8c,0x05,0xcd, 0x3c,0xc2,0xe2,0x88,
865 0x9a,0x89,0xfa,0x03, 0xd6,0x5d,0x4d,0x74,
866 0xac,0x50,0xff,0x6b, 0xd8,0x56,0xe5,0x79,
867 },
868 [1] = { /* p. 255 */
869 0x05,0x5b,0xc1,0x28, 0xcc,0x2d,0x0e,0x25,
870 0x0f,0x47,0xe4,0xe4, 0xf5,0x82,0x37,0x5d,
871 0xe3,0xee,0x5e,0x9f, 0xe8,0x31,0x68,0x74,
872 0x97,0xe5,0xaf,0x1e, 0x7c,0xb6,0x9e,0xfd,
873 0xeb,0xd2,0xfd,0x31, 0xc7,0xce,0x2b,0xba,
874 0x0d,0xbc,0x6c,0x74, 0xc8,0xa2,0x0a,0x7d,
875 0x72,0xf6,0x0e,0x6d, 0x9f,0x63,0xed,0x50,
876 0x9e,0x96,0x3e,0x54, 0xa6,0x9e,0x90,0x48,
877 },
878 },
879 },
880
881 [6] = { /* Hash_DRBG.pdf, p. 255 */
883 .personalization = &kat_personalization,
884 .additional = kat_no_additional,
885 .reseed = true,
886 .C = { /* p. 259 */
887 0x44,0x74,0x8a,0x78, 0xb1,0x6e,0x75,0x55,
888 0x9f,0x88,0x1d,0x51, 0xc1,0x5d,0xfe,0x6c,
889 0x52,0xcf,0xb0,0xbb, 0x71,0x62,0x01,0x69,
890 0xc7,0x93,0x34,0x27, 0x67,0xe7,0xf8,0x87,
891 0x5f,0x42,0xcb,0x6a, 0x20,0xc8,0x9d,0x7c,
892 0x6e,0xf3,0xdc,0x61, 0x0d,0x8f,0xf2,0x03,
893 0xd6,0x76,0x6c,0xed, 0x19,0x19,0xd0,
894 },
895 .V = {
896 [0] = { /* p. 257 */
897 0xa3,0xe9,0x4e,0x39, 0x26,0xfd,0xa1,0x69,
898 0xc3,0x03,0xd6,0x64, 0x38,0x39,0x05,0xe0,
899 0xd7,0x99,0x62,0xd1, 0x65,0x44,0x6d,0x63,
900 0xbd,0xa6,0x54,0xd1, 0x32,0xf7,0x2d,0xb4,
901 0x71,0x56,0x4b,0x45, 0x6f,0xf2,0xee,0xc8,
902 0x36,0x42,0x2a,0xcc, 0x5a,0x02,0x99,0x35,
903 0xa7,0x99,0x29,0x90, 0x94,0xa1,0xca,
904 },
905 [1] = { /* p. 264 */
906 0xaa,0x11,0x1b,0x0e, 0xd5,0x6c,0xf4,0xa6,
907 0xcc,0xe4,0xad,0xe7, 0xf1,0x1b,0x06,0x10,
908 0x45,0xbf,0x10,0x92, 0xcb,0xb3,0x8f,0xf3,
909 0x23,0x95,0xea,0x62, 0xd2,0x6b,0x27,0xc8,
910 0x86,0x89,0x45,0xc5, 0x93,0xba,0x70,0xc3,
911 0x84,0xad,0xad,0x45, 0x77,0x1c,0x93,0xb0,
912 0x9c,0x27,0x69,0x07, 0x52,0xd1,0xd8,
913 },
914 [2] = { /* p. 269 */
915 0x5f,0x0f,0xd4,0x0c, 0x8c,0x82,0xef,0x41,
916 0x03,0x14,0xb8,0x30, 0xc2,0x0f,0xcc,0xea,
917 0x71,0x59,0x18,0x9a, 0xea,0x13,0xe8,0x48,
918 0x75,0x68,0x68,0x18, 0xcd,0x4f,0x12,0xb9,
919 0xde,0xa8,0x82,0x58, 0x16,0xa4,0x13,0xa2,
920 0x95,0x72,0x5e,0xb3, 0x3e,0x33,0xb9,0xad,
921 0xfe,0xe0,0xb1,0xc2, 0x34,0x0a,0xe0,
922 },
923 },
924 .rnd_val = {
925 [0] = { /* p. 264 */
926 0x7a,0x33,0xd3,0x90, 0x33,0xf8,0x60,0x58,
927 0x9f,0x37,0x5e,0x73, 0x35,0x30,0x75,0x52,
928 0x96,0x58,0xbb,0xed, 0x99,0xc8,0xa0,0xef,
929 0x5e,0x28,0xb3,0x51, 0xb2,0xdf,0x33,0x58,
930 0xb3,0xd8,0x9b,0xac, 0x72,0x25,0xdf,0x9e,
931 0x3b,0xcd,0x08,0x36, 0xb9,0x9b,0x5d,0xbf,
932 0x36,0x3a,0x17,0x0c, 0x7b,0xb9,0xbe,0x41,
933 0xa4,0xaa,0x97,0x44, 0x5e,0xce,0xe4,0x1e,
934 },
935 [1] = { /* p. 269 */
936 0x04,0x1a,0xbd,0x94, 0x07,0x9a,0x05,0x71,
937 0x88,0x5f,0x16,0x65, 0x94,0x4e,0x0e,0x7f,
938 0x1b,0xfa,0xcd,0xea, 0xea,0xe9,0xd4,0x4e,
939 0xed,0xc1,0x1f,0xad, 0xd8,0x4c,0x34,0xc7,
940 0xca,0xa7,0x3d,0x09, 0xa0,0x19,0x31,0x93,
941 0xfa,0x40,0xa1,0x9f, 0x64,0x4f,0x04,0x8d,
942 0x2a,0x54,0x17,0x04, 0x25,0x53,0xdf,0x52,
943 0x51,0x74,0x1b,0x40, 0xea,0xcf,0xeb,0x98,
944 },
945 },
946 },
947
948 [7] = { /* Hash_DRBG.pdf, p. 269 */
950 .personalization = &kat_personalization,
951 .additional = kat_additional,
952 .reseed = true,
953 .C = { /* p. 274 */
954 0x44,0x74,0x8a,0x78, 0xb1,0x6e,0x75,0x55,
955 0x9f,0x88,0x1d,0x51, 0xc1,0x5d,0xfe,0x6c,
956 0x52,0xcf,0xb0,0xbb, 0x71,0x62,0x01,0x69,
957 0xc7,0x93,0x34,0x27, 0x67,0xe7,0xf8,0x87,
958 0x5f,0x42,0xcb,0x6a, 0x20,0xc8,0x9d,0x7c,
959 0x6e,0xf3,0xdc,0x61, 0x0d,0x8f,0xf2,0x03,
960 0xd6,0x76,0x6c,0xed, 0x19,0x19,0xd0,
961 },
962 .V = {
963 [0] = { /* p. 272 */
964 0xa3,0xe9,0x4e,0x39, 0x26,0xfd,0xa1,0x69,
965 0xc3,0x03,0xd6,0x64, 0x38,0x39,0x05,0xe0,
966 0xd7,0x99,0x62,0xd1, 0x65,0x44,0x6d,0x63,
967 0xbd,0xa6,0x54,0xd1, 0x32,0xf7,0x2d,0xb4,
968 0x71,0x56,0x4b,0x45, 0x6f,0xf2,0xee,0xc8,
969 0x36,0x42,0x2a,0xcc, 0x5a,0x02,0x99,0x35,
970 0xa7,0x99,0x29,0x90, 0x94,0xa1,0xca,
971 },
972 [1] = { /* p. 279 */
973 0xaa,0xf6,0xb9,0x9b, 0x7f,0x84,0xb0,0x36,
974 0xe1,0xcc,0xbc,0x9d, 0x57,0x3a,0x36,0xb8,
975 0xbd,0xd4,0x7c,0x35, 0x8b,0xb5,0xf3,0xc1,
976 0xd6,0xe7,0x90,0x3a, 0xaa,0x29,0xf1,0xc8,
977 0x7a,0xe6,0x66,0xb8, 0x86,0x93,0xbe,0xf4,
978 0x6c,0x51,0xc2,0x4c, 0x47,0xbe,0xfe,0x4b,
979 0x35,0x75,0x4d,0xcb, 0xfa,0x1e,0x7d,
980 },
981 [2] = { /* p. 285 */
982 0x0c,0x75,0x77,0x4d, 0x61,0x02,0x69,0xad,
983 0x5b,0xb4,0xab,0xbb, 0x14,0x83,0x23,0xc9,
984 0x78,0x9f,0x8f,0x76, 0x25,0xcc,0x34,0x33,
985 0x7c,0x03,0x47,0x2d, 0x9a,0x0c,0x4f,0xac,
986 0x30,0xbe,0xd2,0xdd, 0xde,0x64,0xb8,0x7a,
987 0x2c,0x70,0x67,0x52, 0xc2,0x1a,0xc0,0x11,
988 0x27,0x43,0x59,0x2c, 0x4f,0xdf,0x67,
989 },
990 },
991 .rnd_val = { /* p. 279 */
992 [0] = {
993 0x88,0x97,0x32,0x97, 0x5b,0x36,0xe8,0xe2,
994 0xe7,0xb7,0x40,0x50, 0xae,0xa1,0x71,0x39,
995 0xda,0x2b,0x86,0x34, 0xdc,0xe2,0x13,0x3b,
996 0x06,0x34,0x74,0x3f, 0x47,0x75,0x57,0xab,
997 0x7b,0x84,0x4e,0xd3, 0xf2,0xa4,0x6c,0xc6,
998 0x3e,0xb2,0x32,0x86, 0x46,0x4c,0x51,0xd5,
999 0xd7,0x69,0x71,0xc4, 0x7b,0xc5,0xb5,0x5f,
1000 0xed,0x72,0xa8,0x04, 0x3c,0xbf,0x66,0x4f,
1001 },
1002 [1] = {
1003 0xbf,0x49,0xb8,0x89, 0xba,0x98,0x4d,0x34,
1004 0x63,0x87,0xe8,0x64, 0x7e,0x98,0xbb,0x99,
1005 0xcd,0x41,0xa3,0x2f, 0xbe,0xc1,0xfc,0xb3,
1006 0xb6,0xa1,0xb7,0xd9, 0x93,0x2b,0xa7,0xe1,
1007 0x1e,0xe6,0xbb,0xd9, 0x24,0x40,0x5a,0x2c,
1008 0x7f,0xca,0x89,0x0a, 0x5e,0x9a,0x8d,0xea,
1009 0x66,0xac,0x0c,0xac, 0xa0,0xca,0x7b,0xc1,
1010 0x8d,0x74,0xfb,0xc0, 0x2a,0x11,0xe4,0x53,
1011 },
1012 },
1013 },
1014 };
1015
1016 #ifdef NIST_HASH_DRBG_DEBUG
1018 #define DPRINTF(fmt, ...) \
1019 printf("%s:%d: " fmt, __func__, __LINE__, ##__VA_ARGS__)
1020 #define DUSE(v)
1021 #else
1022 #define DPRINTF(fmt, ...)
1023 #define DUSE(v) (void)(v)
1024 #endif
1025
1026 #define CHECK(i, name, actual, expected, n) do \
1027 { \
1028 CTASSERT(sizeof(actual) == (n)); \
1029 ok &= check(i, name, actual, expected, (n)); \
1030 } while (0)
1031
1032 static bool
1033 check(unsigned katno, const char *name, const uint8_t *actual,
1034 const uint8_t *expected, size_t n)
1035 {
1036 bool ok = true;
1037 size_t i;
1038
1039 DUSE(katno);
1040 DUSE(name);
1041
1042 for (i = 0; i < n; i++) {
1043 if (actual[i] != expected[i]) {
1044 DPRINTF("KAT %u %s[%zu] = %02x, expected %02x\n",
1045 katno, name, i, actual[i], expected[i]);
1046 ok = false;
1047 }
1048 }
1049
1050 return ok;
1051 }
1052
1053 #ifdef NIST_HASH_DRBG_MAIN
1054 int
1055 main(void)
1056 {
1057 int ret;
1058
1059 ret = nist_hash_drbg_initialize();
1060
1061 fflush(stdout);
1062 return ret || ferror(stdout);
1063 }
1064 #endif
1065
1066 int
1068 nist_hash_drbg_initialize(void)
1069 {
1070 const unsigned truncation[] = { 0, 1, 32, 63 };
1071 bool ok = true;
1072 size_t i, j;
1073
1074 for (i = 0; i < arraycount(kat); i++) {
1075 for (j = 0; j < arraycount(truncation); j++) {
1076 const unsigned trunc = truncation[j];
1077 struct nist_hash_drbg drbg, *D = &drbg;
1078 uint8_t rnd_val[64];
1079 unsigned reseed_counter;
1080
1081 nist_hash_drbg_instantiate(D,
1082 kat_entropy[0], sizeof kat_entropy[0],
1083 kat_nonce, sizeof kat_nonce,
1084 kat[i].personalization->hv_base,
1085 kat[i].personalization->hv_len);
1086 reseed_counter = 1;
1087 CHECK(i, "C", D->C, kat[i].C, SEEDLEN_BYTES);
1088 CHECK(i, "V[0]", D->V, kat[i].V[0], SEEDLEN_BYTES);
1089 if (D->reseed_counter != reseed_counter) {
1090 DPRINTF("bad reseed counter: %u, expected %u",
1091 D->reseed_counter, reseed_counter);
1092 ok = false;
1093 }
1094
1095 if (kat[i].reseed) {
1096 nist_hash_drbg_reseed(D,
1097 kat_entropy[1], sizeof kat_entropy[1],
1098 kat[i].additional[0]->hv_base,
1099 kat[i].additional[0]->hv_len);
1100 }
1101
1102 nist_hash_drbg_generate(D, rnd_val,
1103 sizeof(rnd_val) - trunc,
1104 kat[i].reseed ? 0 : kat[i].additional[0]->hv_base,
1105 kat[i].reseed ? 0 : kat[i].additional[0]->hv_len);
1106 reseed_counter++;
1107 CHECK(i, "V[1]", D->V, kat[i].V[1], SEEDLEN_BYTES);
1108 CHECK(i, "rnd_val[0]", rnd_val, kat[i].rnd_val[0],
1109 sizeof(kat[i].rnd_val[0]) - trunc);
1110 if (D->reseed_counter != reseed_counter) {
1111 DPRINTF("bad reseed counter: %u, expected %u",
1112 D->reseed_counter, reseed_counter);
1113 ok = false;
1114 }
1115
1116 if (kat[i].reseed) {
1117 nist_hash_drbg_reseed(D,
1118 kat_entropy[2], sizeof kat_entropy[2],
1119 kat[i].additional[1]->hv_base,
1120 kat[i].additional[1]->hv_len);
1121 reseed_counter = 1;
1122 }
1123
1124 nist_hash_drbg_generate(D, rnd_val,
1125 sizeof(rnd_val) - trunc,
1126 kat[i].reseed ? 0 : kat[i].additional[1]->hv_base,
1127 kat[i].reseed ? 0 : kat[i].additional[1]->hv_len);
1128 reseed_counter++;
1129 CHECK(i, "V[2]", D->V, kat[i].V[2], SEEDLEN_BYTES);
1130 CHECK(i, "rnd_val[1]", rnd_val, kat[i].rnd_val[1],
1131 sizeof(kat[i].rnd_val[1]) - trunc);
1132 if (D->reseed_counter != reseed_counter) {
1133 DPRINTF("bad reseed counter: %u, expected %u",
1134 D->reseed_counter, reseed_counter);
1135 ok = false;
1136 }
1137
1138 nist_hash_drbg_destroy(D);
1139 }
1140 }
1141
1142 if (!ok)
1143 return 1;
1144 return 0;
1145 }
1146