Home | History | Annotate | Line # | Download | only in libkern
      1 /*	$NetBSD: entpool.c,v 1.1 2020/04/30 03:28:19 riastradh 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  * Entropy pool (`reseedable pseudorandom number generator') based on a
     34  * sponge duplex, following the design described and analyzed in
     35  *
     36  *	Guido Bertoni, Joan Daemen, Michal Peeters, and Gilles Van
     37  *	Assche, `Sponge-Based Pseudo-Random Number Generators', in
     38  *	Stefan Mangard and Franois-Xavier Standaert, eds.,
     39  *	Cryptographic Hardware and Embedded SystemsCHES 2010, Springer
     40  *	LNCS 6225, pp. 3347.
     41  *	https://link.springer.com/chapter/10.1007/978-3-642-15031-9_3
     42  *	https://keccak.team/files/SpongePRNG.pdf
     43  *
     44  *	Guido Bertoni, Joan Daemen, Michal Peeters, and Gilles Van
     45  *	Assche, `Duplexing the Sponge: Single-Pass Authenticated
     46  *	Encryption and Other Applications', in Ali Miri and Serge
     47  *	Vaudenay, eds., Selected Areas in CryptographySAC 2011,
     48  *	Springer LNCS 7118, pp. 320337.
     49  *	https://link.springer.com/chapter/10.1007/978-3-642-28496-0_19
     50  *	https://keccak.team/files/SpongeDuplex.pdf
     51  *
     52  * We make the following tweaks that don't affect security:
     53  *
     54  *	- Samples are length-delimited 7-bit variable-length encoding.
     55  *	  The encoding is still injective, so the security theorems
     56  *	  continue to apply.
     57  *
     58  *	- Output is not buffered -- callers should draw 32 bytes and
     59  *	  expand with a stream cipher.  In effect, every output draws
     60  *	  the full rate, and we just discard whatever the caller didn't
     61  *	  ask for; the impact is only on performance, not security.
     62  *
     63  * On top of the underlying sponge state, an entropy pool maintains an
     64  * integer i in [0, RATE-1] indicating where to write the next byte in
     65  * the input buffer.  Zeroing an entropy pool initializes it.
     66  */
     67 
     68 #if defined(_KERNEL) || defined(_STANDALONE)
     70 #include <sys/cdefs.h>
     71 __KERNEL_RCSID(0, "$NetBSD: entpool.c,v 1.1 2020/04/30 03:28:19 riastradh Exp $");
     72 #endif
     73 
     74 #include "entpool.h"
     75 #include ENTPOOL_HEADER
     76 
     77 #if defined(_KERNEL) || defined(_STANDALONE)
     78 #include <sys/types.h>
     79 #include <lib/libkern/libkern.h>
     80 #define	ASSERT		KASSERT
     81 #else
     82 #include <sys/cdefs.h>
     83 #include <assert.h>
     84 #include <stdbool.h>
     85 #include <stdint.h>
     86 #include <string.h>
     87 #define	ASSERT		assert
     88 #define	CTASSERT	__CTASSERT
     89 #endif
     90 
     91 #define	secret	/* must not use in variable-time operations; should zero */
     92 #define	arraycount(A)	(sizeof(A)/sizeof((A)[0]))
     93 #define	MIN(X,Y)	((X) < (Y) ? (X) : (Y))
     94 
     95 #define	RATE		ENTPOOL_RATE
     96 
     97 /*
     99  * stir(P)
    100  *
    101  *	Internal subroutine to apply the sponge permutation to the
    102  *	state in P.  Resets P->i to 0 to indicate that the input buffer
    103  *	is empty.
    104  */
    105 static void
    106 stir(struct entpool *P)
    107 {
    108 	size_t i;
    109 
    110 	/*
    111 	 * Switch to the permutation's byte order, if necessary, apply
    112 	 * permutation, and then switch back.  This way we can data in
    113 	 * and out byte by byte, but get the same answers out of test
    114 	 * vectors.
    115 	 */
    116 	for (i = 0; i < arraycount(P->s.w); i++)
    117 		P->s.w[i] = ENTPOOL_WTOH(P->s.w[i]);
    118 	ENTPOOL_PERMUTE(P->s.w);
    119 	for (i = 0; i < arraycount(P->s.w); i++)
    120 		P->s.w[i] = ENTPOOL_HTOW(P->s.w[i]);
    121 
    122 	/* Reset the input buffer.  */
    123 	P->i = 0;
    124 }
    125 
    126 /*
    127  * entpool_enter(P, buf, len)
    128  *
    129  *	Enter len bytes from buf into the entropy pool P, stirring as
    130  *	needed.  Corresponds to P.feed in the paper.
    131  */
    132 void
    133 entpool_enter(struct entpool *P, const void *buf, size_t len)
    134 {
    135 	const uint8_t *p = buf;
    136 	size_t n = len, n1 = n;
    137 
    138 	/* Sanity-check P->i.  */
    139 	ASSERT(P->i <= RATE-1);
    140 
    141 	/* Encode the length, stirring as needed.  */
    142 	while (n1) {
    143 		if (P->i == RATE-1)
    144 			stir(P);
    145 		ASSERT(P->i < RATE-1);
    146 		P->s.u8[P->i++] ^= (n1 >= 0x80 ? 0x80 : 0) | (n1 & 0x7f);
    147 		n1 >>= 7;
    148 	}
    149 
    150 	/* Enter the sample, stirring as needed.  */
    151 	while (n --> 0) {
    152 		if (P->i == RATE-1)
    153 			stir(P);
    154 		ASSERT(P->i < RATE-1);
    155 		P->s.u8[P->i++] ^= *p++;
    156 	}
    157 
    158 	/* If we filled the input buffer exactly, stir once more.  */
    159 	if (P->i == RATE-1)
    160 		stir(P);
    161 	ASSERT(P->i < RATE-1);
    162 }
    163 
    164 /*
    166  * entpool_enter_nostir(P, buf, len)
    167  *
    168  *	Enter as many bytes as possible, up to len, from buf into the
    169  *	entropy pool P.  Roughly corresponds to P.feed in the paper,
    170  *	but we stop if we would have run the permutation.
    171  *
    172  *	Return true if the sample was consumed in its entirety, or true
    173  *	if the sample was truncated so the caller should arrange to
    174  *	call entpool_stir when it is next convenient to do so.
    175  *
    176  *	This function is cheap -- it only xors the input into the
    177  *	state, and never calls the underlying permutation, but it may
    178  *	truncate samples.
    179  */
    180 bool
    181 entpool_enter_nostir(struct entpool *P, const void *buf, size_t len)
    182 {
    183 	const uint8_t *p = buf;
    184 	size_t n0, n;
    185 
    186 	/* Sanity-check P->i.  */
    187 	ASSERT(P->i <= RATE-1);
    188 
    189 	/* If the input buffer is full, fail.  */
    190 	if (P->i == RATE-1)
    191 		return false;
    192 	ASSERT(P->i < RATE-1);
    193 
    194 	/*
    195 	 * Truncate the sample and enter it with 1-byte length encoding
    196 	 * -- don't bother with variable-length encoding, not worth the
    197 	 * trouble.
    198 	 */
    199 	n = n0 = MIN(127, MIN(len, RATE-1 - P->i - 1));
    200 	P->s.u8[P->i++] ^= n;
    201 	while (n --> 0)
    202 		P->s.u8[P->i++] ^= *p++;
    203 
    204 	/* Can't guarantee anything better than 0 <= i <= RATE-1.  */
    205 	ASSERT(P->i <= RATE-1);
    206 
    207 	/* Return true if all done, false if truncated and in need of stir.  */
    208 	return (n0 == len);
    209 }
    210 
    211 /*
    212  * entpool_stir(P)
    213  *
    214  *	Stir the entropy pool after entpool_enter_nostir fails.  If it
    215  *	has already been stirred already, this has no effect.
    216  */
    217 void
    218 entpool_stir(struct entpool *P)
    219 {
    220 
    221 	/* Sanity-check P->i.  */
    222 	ASSERT(P->i <= RATE-1);
    223 
    224 	/* If the input buffer is full, stir.  */
    225 	if (P->i == RATE-1)
    226 		stir(P);
    227 	ASSERT(P->i < RATE-1);
    228 }
    229 
    230 /*
    232  * entpool_extract(P, buf, len)
    233  *
    234  *	Extract len bytes from the entropy pool P into buf.
    235  *	Corresponds to iterating P.fetch/P.forget in the paper.
    236  *	(Feeding the output back in -- as P.forget does -- is the same
    237  *	as zeroing what we just read out.)
    238  */
    239 void
    240 entpool_extract(struct entpool *P, secret void *buf, size_t len)
    241 {
    242 	uint8_t *p = buf;
    243 	size_t n = len;
    244 
    245 	/* Sanity-check P->i.  */
    246 	ASSERT(P->i <= RATE-1);
    247 
    248 	/* If input buffer is not empty, stir.  */
    249 	if (P->i != 0)
    250 		stir(P);
    251 	ASSERT(P->i == 0);
    252 
    253 	/*
    254 	 * Copy out and zero (RATE-1)-sized chunks at a time, stirring
    255 	 * with a bit set to distinguish this from inputs.
    256 	 */
    257 	while (n >= RATE-1) {
    258 		memcpy(p, P->s.u8, RATE-1);
    259 		memset(P->s.u8, 0, RATE-1);
    260 		P->s.u8[RATE-1] ^= 0x80;
    261 		stir(P);
    262 		p += RATE-1;
    263 		n -= RATE-1;
    264 	}
    265 
    266 	/*
    267 	 * If there's anything left, copy out a partial rate's worth
    268 	 * and zero the entire rate's worth, stirring with a bit set to
    269 	 * distinguish this from inputs.
    270 	 */
    271 	if (n) {
    272 		ASSERT(n < RATE-1);
    273 		memcpy(p, P->s.u8, n);		/* Copy part of it.  */
    274 		memset(P->s.u8, 0, RATE-1);	/* Zero all of it. */
    275 		P->s.u8[RATE-1] ^= 0x80;
    276 		stir(P);
    277 	}
    278 }
    279 
    280 /*
    282  * Known-answer tests
    283  */
    284 
    285 #if ENTPOOL_SMALL
    286 
    287 #define	KATLEN	15
    288 
    289 /* Gimli */
    290 static const uint8_t known_answers[][KATLEN] = {
    291 	[0] = {
    292 		0x69,0xb8,0x49,0x0d,0x39,0xfb,0x42,0x61,
    293 		0xf7,0x66,0xdf,0x04,0xb6,0xed,0x11,
    294 	},
    295 	[1] = {
    296 		0x74,0x15,0x16,0x49,0x31,0x07,0x77,0xa1,
    297 		0x3b,0x4d,0x78,0xc6,0x5d,0xef,0x87,
    298 	},
    299 	[2] = {
    300 		0xae,0xfd,0x7d,0xc4,0x3b,0xce,0x09,0x25,
    301 		0xbf,0x60,0x21,0x6e,0x3c,0x3a,0x84,
    302 	},
    303 	[3] = {
    304 		0xae,0xfd,0x7d,0xc4,0x3b,0xce,0x09,0x25,
    305 		0xbf,0x60,0x21,0x6e,0x3c,0x3a,0x84,
    306 	},
    307 	[4] = {
    308 		0x69,0xb8,0x49,0x0d,0x39,0xfb,0x42,0x61,
    309 		0xf7,0x66,0xdf,0x04,0xb6,0xed,0x11,
    310 	},
    311 	[5] = {
    312 		0xa9,0x3c,0x3c,0xac,0x5f,0x6d,0x80,0xdc,
    313 		0x33,0x0c,0xb2,0xe3,0xdd,0x55,0x31,
    314 	},
    315 	[6] = {
    316 		0x2e,0x69,0x1a,0x2a,0x2d,0x09,0xd4,0x5e,
    317 		0x49,0xcc,0x8c,0xb2,0x0b,0xcc,0x42,
    318 	},
    319 	[7] = {
    320 		0xae,0xfd,0x7d,0xc4,0x3b,0xce,0x09,0x25,
    321 		0xbf,0x60,0x21,0x6e,0x3c,0x3a,0x84,
    322 	},
    323 	[8] = {
    324 		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    325 		0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    326 	},
    327 	[9] = {
    328 		0x69,0xb8,0x49,0x0d,0x39,0xfb,0x42,0x61,
    329 		0xf7,0x66,0xdf,0x04,0xb6,0xed,0x11,
    330 	},
    331 	[10] = {
    332 		0x2e,0x69,0x1a,0x2a,0x2d,0x09,0xd4,0x5e,
    333 		0x49,0xcc,0x8c,0xb2,0x0b,0xcc,0x42,
    334 	},
    335 	[11] = {
    336 		0x6f,0xfd,0xd2,0x29,0x78,0x46,0xc0,0x7d,
    337 		0xc7,0xf2,0x0a,0x2b,0x72,0xd6,0xc6,
    338 	},
    339 	[12] = {
    340 		0x86,0xf0,0xc1,0xf9,0x95,0x0f,0xc9,0x12,
    341 		0xde,0x38,0x39,0x10,0x1f,0x8c,0xc4,
    342 	},
    343 };
    344 
    345 #else  /* !ENTPOOL_SMALL */
    347 
    348 #define	KATLEN	16
    349 
    350 /* Keccak-p[1600, 24] */
    351 static const uint8_t known_answers[][KATLEN] = {
    352 	[0] = {
    353 		0x3b,0x20,0xf0,0xe9,0xce,0x94,0x48,0x07,
    354 		0x97,0xb6,0x16,0xb5,0xb5,0x05,0x1a,0xce,
    355 	},
    356 	[1] = {
    357 		0x57,0x49,0x6e,0x28,0x7f,0xaa,0xee,0x6c,
    358 		0xa8,0xb0,0xf5,0x0b,0x87,0xae,0xd6,0xd6,
    359 	},
    360 	[2] = {
    361 		0x51,0x72,0x0f,0x59,0x54,0xe1,0xaf,0xa8,
    362 		0x16,0x67,0xfa,0x3f,0x8a,0x19,0x52,0x50,
    363 	},
    364 	[3] = {
    365 		0x51,0x72,0x0f,0x59,0x54,0xe1,0xaf,0xa8,
    366 		0x16,0x67,0xfa,0x3f,0x8a,0x19,0x52,0x50,
    367 	},
    368 	[4] = {
    369 		0x3b,0x20,0xf0,0xe9,0xce,0x94,0x48,0x07,
    370 		0x97,0xb6,0x16,0xb5,0xb5,0x05,0x1a,0xce,
    371 	},
    372 	[5] = {
    373 		0x95,0x23,0x77,0xe4,0x84,0xeb,0xaa,0x2e,
    374 		0x6a,0x99,0xc2,0x52,0x06,0x6d,0xdf,0xea,
    375 	},
    376 	[6] = {
    377 		0x8c,0xdd,0x1b,0xaf,0x0e,0xf6,0xe9,0x1d,
    378 		0x51,0x33,0x68,0x38,0x8d,0xad,0x55,0x84,
    379 	},
    380 	[7] = {
    381 		0x51,0x72,0x0f,0x59,0x54,0xe1,0xaf,0xa8,
    382 		0x16,0x67,0xfa,0x3f,0x8a,0x19,0x52,0x50,
    383 	},
    384 	[8] = {
    385 		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    386 		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    387 	},
    388 	[9] = {
    389 		0x3b,0x20,0xf0,0xe9,0xce,0x94,0x48,0x07,
    390 		0x97,0xb6,0x16,0xb5,0xb5,0x05,0x1a,0xce,
    391 	},
    392 	[10] = {
    393 		0x8c,0xdd,0x1b,0xaf,0x0e,0xf6,0xe9,0x1d,
    394 		0x51,0x33,0x68,0x38,0x8d,0xad,0x55,0x84,
    395 	},
    396 	[11] = {
    397 		0xf6,0xc1,0x14,0xbb,0x13,0x0a,0xaf,0xed,
    398 		0xca,0x0b,0x35,0x2c,0xf1,0x2b,0x1a,0x85,
    399 	},
    400 	[12] = {
    401 		0xf9,0x4b,0x05,0xd1,0x8b,0xcd,0xb3,0xd0,
    402 		0x77,0x27,0xfe,0x46,0xf9,0x33,0xb2,0xa2,
    403 	},
    404 };
    405 
    406 #endif
    407 
    408 #define	KAT_BEGIN(P, n)	memset(P, 0, sizeof(*(P)))
    410 #define	KAT_ERROR()	return -1
    411 #define	KAT_END(P, n)	do						      \
    412 {									      \
    413 	uint8_t KAT_ACTUAL[KATLEN];					      \
    414 	entpool_extract(P, KAT_ACTUAL, KATLEN);				      \
    415 	if (memcmp(KAT_ACTUAL, known_answers[n], KATLEN))		      \
    416 		return -1;						      \
    417 } while (0)
    418 
    419 int
    420 entpool_selftest(void)
    421 {
    422 	struct entpool pool, *P = &pool;
    423 	uint8_t sample[1] = {0xff};
    424 	uint8_t scratch[RATE];
    425 	const uint8_t zero[RATE] = {0};
    426 
    427 	/* Test entpool_enter with empty buffer.  */
    428 	KAT_BEGIN(P, 0);
    429 	entpool_stir(P);	/* noop */
    430 	entpool_enter(P, sample, 1);
    431 	entpool_stir(P);	/* noop */
    432 	KAT_END(P, 0);
    433 
    434 	/* Test entpool_enter with partial buffer.  */
    435 	KAT_BEGIN(P, 1);
    436 	entpool_stir(P);	/* noop */
    437 #if ENTPOOL_SMALL
    438 	entpool_enter(P, zero, RATE-3);
    439 #else
    440 	entpool_enter(P, zero, RATE-4);
    441 #endif
    442 	entpool_stir(P);	/* noop */
    443 	entpool_enter(P, sample, 1);
    444 	entpool_stir(P);	/* noop */
    445 	KAT_END(P, 1);
    446 
    447 	/* Test entpool_enter with full buffer.  */
    448 	KAT_BEGIN(P, 2);
    449 	entpool_stir(P);	/* noop */
    450 #if ENTPOOL_SMALL
    451 	if (!entpool_enter_nostir(P, zero, RATE-2))
    452 		KAT_ERROR();
    453 #else
    454 	if (!entpool_enter_nostir(P, zero, 127))
    455 		KAT_ERROR();
    456 	if (!entpool_enter_nostir(P, zero, RATE-2 - 127 - 1))
    457 		KAT_ERROR();
    458 #endif
    459 	entpool_enter(P, sample, 1);
    460 	entpool_stir(P);	/* noop */
    461 	KAT_END(P, 2);
    462 
    463 	/* Test entpool_enter with full buffer after stir.  */
    465 	KAT_BEGIN(P, 3);
    466 	entpool_stir(P);	/* noop */
    467 #if ENTPOOL_SMALL
    468 	if (!entpool_enter_nostir(P, zero, RATE-2))
    469 		KAT_ERROR();
    470 #else
    471 	CTASSERT(127 <= RATE-2);
    472 	if (!entpool_enter_nostir(P, zero, 127))
    473 		KAT_ERROR();
    474 	if (!entpool_enter_nostir(P, zero, RATE-2 - 127 - 1))
    475 		KAT_ERROR();
    476 #endif
    477 	entpool_stir(P);
    478 	entpool_enter(P, sample, 1);
    479 	entpool_stir(P);	/* noop */
    480 	KAT_END(P, 3);
    481 
    482 	/* Test entpool_enter_nostir with empty buffer.  */
    483 	KAT_BEGIN(P, 4);
    484 	entpool_stir(P);	/* noop */
    485 	if (!entpool_enter_nostir(P, sample, 1))
    486 		KAT_ERROR();
    487 	entpool_stir(P);	/* noop */
    488 	KAT_END(P, 4);
    489 
    490 	/* Test entpool_enter_nostir with partial buffer.  */
    491 	KAT_BEGIN(P, 5);
    492 	entpool_stir(P);	/* noop */
    493 #if ENTPOOL_SMALL
    494 	entpool_enter(P, zero, RATE-3);
    495 #else
    496 	entpool_enter(P, zero, RATE-4);
    497 #endif
    498 	entpool_stir(P);	/* noop */
    499 	if (entpool_enter_nostir(P, sample, 1))
    500 		KAT_ERROR();
    501 	entpool_stir(P);
    502 	KAT_END(P, 5);
    503 
    504 	/* Test entpool_enter_nostir with full buffer.  */
    505 	KAT_BEGIN(P, 6);
    506 	entpool_stir(P);	/* noop */
    507 #if ENTPOOL_SMALL
    508 	if (!entpool_enter_nostir(P, zero, RATE-2))
    509 		KAT_ERROR();
    510 #else
    511 	CTASSERT(127 <= RATE-2);
    512 	if (!entpool_enter_nostir(P, zero, 127))
    513 		KAT_ERROR();
    514 	if (!entpool_enter_nostir(P, zero, RATE-2 - 127 - 1))
    515 		KAT_ERROR();
    516 #endif
    517 	if (entpool_enter_nostir(P, sample, 1))
    518 		KAT_ERROR();
    519 	entpool_stir(P);
    520 	KAT_END(P, 6);
    521 
    522 	/* Test entpool_enter_nostir with full buffer after stir.  */
    524 	KAT_BEGIN(P, 7);
    525 	entpool_stir(P);	/* noop */
    526 #if ENTPOOL_SMALL
    527 	if (!entpool_enter_nostir(P, zero, RATE-2))
    528 		KAT_ERROR();
    529 #else
    530 	CTASSERT(127 <= RATE-2);
    531 	if (!entpool_enter_nostir(P, zero, 127))
    532 		KAT_ERROR();
    533 	if (!entpool_enter_nostir(P, zero, RATE-2 - 127 - 1))
    534 		KAT_ERROR();
    535 #endif
    536 	entpool_stir(P);
    537 	if (!entpool_enter_nostir(P, sample, 1))
    538 		KAT_ERROR();
    539 	entpool_stir(P);	/* noop */
    540 	KAT_END(P, 7);
    541 
    542 	/* Test entpool_extract with empty input buffer.  */
    543 	KAT_BEGIN(P, 8);
    544 	entpool_stir(P);	/* noop */
    545 	KAT_END(P, 8);
    546 
    547 	/* Test entpool_extract with nonempty input buffer.  */
    548 	KAT_BEGIN(P, 9);
    549 	entpool_stir(P);	/* noop */
    550 	entpool_enter(P, sample, 1);
    551 	entpool_stir(P);	/* noop */
    552 	KAT_END(P, 9);
    553 
    554 	/* Test entpool_extract with full input buffer.  */
    555 	KAT_BEGIN(P, 10);
    556 	entpool_stir(P);	/* noop */
    557 #if ENTPOOL_SMALL
    558 	if (!entpool_enter_nostir(P, zero, RATE-2))
    559 		KAT_ERROR();
    560 #else
    561 	CTASSERT(127 <= RATE-2);
    562 	if (!entpool_enter_nostir(P, zero, 127))
    563 		KAT_ERROR();
    564 	if (!entpool_enter_nostir(P, zero, RATE-2 - 127 - 1))
    565 		KAT_ERROR();
    566 #endif
    567 	KAT_END(P, 10);
    568 
    569 	/* Test entpool_extract with iterated output.  */
    570 	KAT_BEGIN(P, 11);
    571 	entpool_stir(P);	/* noop */
    572 	entpool_extract(P, scratch, RATE-1 + 1);
    573 	entpool_stir(P);	/* noop */
    574 	KAT_END(P, 11);
    575 
    576 	/* Test extract, enter, extract.  */
    577 	KAT_BEGIN(P, 12);
    578 	entpool_stir(P);	/* noop */
    579 	entpool_extract(P, scratch, 1);
    580 	entpool_stir(P);	/* noop */
    581 	entpool_enter(P, sample, 1);
    582 	entpool_stir(P);	/* noop */
    583 	KAT_END(P, 12);
    584 
    585 	return 0;
    586 }
    587 
    588 #if ENTPOOL_TEST
    589 int
    590 main(void)
    591 {
    592 	return entpool_selftest();
    593 }
    594 #endif
    595 
    596 /*
    598  * Known-answer test generation
    599  *
    600  *	This generates the known-answer test vectors from explicitly
    601  *	specified duplex inputs that correspond to what entpool_enter
    602  *	&c. induce, to confirm the encoding of inputs works as
    603  *	intended.
    604  */
    605 
    606 #if ENTPOOL_GENKAT
    607 
    608 #include <stdio.h>
    609 
    610 struct event {
    611 	enum { IN, OUT, STOP } t;
    612 	uint8_t b[RATE-1];
    613 };
    614 
    615 /* Cases correspond to entpool_selftest above.  */
    616 static const struct event *const cases[] = {
    617 	[0] = (const struct event[]) {
    618 		{IN, {1, 0xff}},
    619 		{STOP, {0}},
    620 	},
    621 	[1] = (const struct event[]) {
    622 #if ENTPOOL_SMALL
    623 		{IN, {RATE-3, [RATE-2] = 1}},
    624 #else
    625 		{IN, {0x80|((RATE-4)&0x7f), (RATE-4)>>7, [RATE-2] = 1}},
    626 #endif
    627 		{IN, {0xff}},
    628 		{STOP, {0}},
    629 	},
    630 	[2] = (const struct event[]) {
    631 #if ENTPOOL_SMALL
    632 		{IN, {RATE-2}},
    633 #else
    634 		{IN, {127, [128] = RATE-2 - 127 - 1}},
    635 #endif
    636 		{IN, {1, 0xff}},
    637 		{STOP, {0}},
    638 	},
    639 	[3] = (const struct event[]) {
    640 #if ENTPOOL_SMALL
    641 		{IN, {RATE-2}},
    642 #else
    643 		{IN, {127, [128] = RATE-2 - 127 - 1}},
    644 #endif
    645 		{IN, {1, 0xff}},
    646 		{STOP, {0}},
    647 	},
    648 	[4] = (const struct event[]) {
    649 		{IN, {1, 0xff}},
    650 		{STOP, {0}},
    651 	},
    652 
    653 	[5] = (const struct event[]) {
    655 #if ENTPOOL_SMALL
    656 		{IN, {RATE-3, [RATE-2] = 0 /* truncated length */}},
    657 #else
    658 		{IN, {0x80|((RATE-4)&0x7f), (RATE-4)>>7,
    659 		      [RATE-2] = 0 /* truncated length */}},
    660 #endif
    661 		{STOP, {0}},
    662 	},
    663 	[6] = (const struct event[]) {
    664 #if ENTPOOL_SMALL
    665 		{IN, {RATE-2}},
    666 #else
    667 		{IN, {127, [128] = RATE-2 - 127 - 1}},
    668 #endif
    669 		{STOP, {0}},
    670 	},
    671 	[7] = (const struct event[]) {
    672 #if ENTPOOL_SMALL
    673 		{IN, {RATE-2}},
    674 #else
    675 		{IN, {127, [128] = RATE-2 - 127 - 1}},
    676 #endif
    677 		{IN, {1, 0xff}},
    678 		{STOP, {0}},
    679 	},
    680 	[8] = (const struct event[]) {
    681 		{STOP, {0}},
    682 	},
    683 	[9] = (const struct event[]) {
    684 		{IN, {1, 0xff}},
    685 		{STOP, {0}},
    686 	},
    687 	[10] = (const struct event[]) {
    688 #if ENTPOOL_SMALL
    689 		{IN, {RATE-2}},
    690 #else
    691 		{IN, {127, [128] = RATE-2 - 127 - 1}},
    692 #endif
    693 		{STOP, {0}},
    694 	},
    695 	[11] = (const struct event[]) {
    696 		{OUT, {0}},
    697 		{OUT, {0}},
    698 		{STOP, {0}},
    699 	},
    700 	[12] = (const struct event[]) {
    701 		{OUT, {0}},
    702 		{IN, {1, 0xff}},
    703 		{STOP, {0}},
    704 	},
    705 };
    706 
    707 static void
    709 compute(uint8_t output[KATLEN], const struct event *events)
    710 {
    711 	union {
    712 		uint8_t b[ENTPOOL_SIZE];
    713 		ENTPOOL_WORD w[ENTPOOL_SIZE/sizeof(ENTPOOL_WORD)];
    714 	} u;
    715 	unsigned i, j, k;
    716 
    717 	memset(&u.b, 0, sizeof u.b);
    718 	for (i = 0;; i++) {
    719 		if (events[i].t == STOP)
    720 			break;
    721 		for (j = 0; j < sizeof(events[i].b); j++)
    722 			u.b[j] ^= events[i].b[j];
    723 		if (events[i].t == OUT) {
    724 			memset(u.b, 0, RATE-1);
    725 			u.b[RATE-1] ^= 0x80;
    726 		}
    727 
    728 		for (k = 0; k < arraycount(u.w); k++)
    729 			u.w[k] = ENTPOOL_WTOH(u.w[k]);
    730 		ENTPOOL_PERMUTE(u.w);
    731 		for (k = 0; k < arraycount(u.w); k++)
    732 			u.w[k] = ENTPOOL_HTOW(u.w[k]);
    733 	}
    734 
    735 	for (j = 0; j < KATLEN; j++)
    736 		output[j] = u.b[j];
    737 }
    738 
    739 int
    740 main(void)
    741 {
    742 	uint8_t output[KATLEN];
    743 	unsigned i, j;
    744 
    745 	printf("static const uint8_t known_answers[][KATLEN] = {\n");
    746 	for (i = 0; i < arraycount(cases); i++) {
    747 		printf("\t[%u] = {\n", i);
    748 		compute(output, cases[i]);
    749 		for (j = 0; j < KATLEN; j++) {
    750 			if (j % 8 == 0)
    751 				printf("\t\t");
    752 			printf("0x%02hhx,", output[j]);
    753 			if (j % 8 == 7)
    754 				printf("\n");
    755 		}
    756 		if ((KATLEN % 8) != 0)
    757 			printf("\n");
    758 		printf("\t},\n");
    759 	}
    760 	printf("};\n");
    761 
    762 	fflush(stdout);
    763 	return ferror(stdout);
    764 }
    765 
    766 #endif
    767