1/*	$NetBSD: chacha_selftest.c,v 1.1 2020/07/25 22:46:34 riastradh Exp $	*/
2
3/*-
4 * Copyright (c) 2020 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "chacha_impl.h"
30
31#ifdef _KERNEL
32
33#include <lib/libkern/libkern.h>
34
35#else
36
37#include <stdio.h>
38#include <string.h>
39
40static void
41hexdump(int (*prf)(const char *, ...) __printflike(1,2), const char *prefix,
42    const void *buf, size_t len)
43{
44	const uint8_t *p = buf;
45	size_t i;
46
47	(*prf)("%s (%zu bytes @ %p)\n", prefix, len, buf);
48	for (i = 0; i < len; i++) {
49		if (i % 16 == 8)
50			(*prf)("  ");
51		else
52			(*prf)(" ");
53		(*prf)("%02hhx", p[i]);
54		if ((i + 1) % 16 == 0)
55			(*prf)("\n");
56	}
57	if (i % 16)
58		(*prf)("\n");
59}
60
61#endif
62
63/* https://tools.ietf.org/html/draft-strombergson-chacha-test-vectors-00 */
64static int
65chacha_core_selftest(const struct chacha_impl *ci)
66{
67	/* TC1, 32-byte key, rounds=12, keystream block 1 */
68	static const uint8_t zero[32];
69	static const uint8_t expected0[64] = {
70		0x9b,0xf4,0x9a,0x6a, 0x07,0x55,0xf9,0x53,
71		0x81,0x1f,0xce,0x12, 0x5f,0x26,0x83,0xd5,
72		0x04,0x29,0xc3,0xbb, 0x49,0xe0,0x74,0x14,
73		0x7e,0x00,0x89,0xa5, 0x2e,0xae,0x15,0x5f,
74		0x05,0x64,0xf8,0x79, 0xd2,0x7a,0xe3,0xc0,
75		0x2c,0xe8,0x28,0x34, 0xac,0xfa,0x8c,0x79,
76		0x3a,0x62,0x9f,0x2c, 0xa0,0xde,0x69,0x19,
77		0x61,0x0b,0xe8,0x2f, 0x41,0x13,0x26,0xbe,
78	};
79	/* TC7, 32-byte key, rounds=12, keystream block 2 */
80	static const uint8_t k1[32] = {
81		0x00,0x11,0x22,0x33, 0x44,0x55,0x66,0x77,
82		0x88,0x99,0xaa,0xbb, 0xcc,0xdd,0xee,0xff,
83		0xff,0xee,0xdd,0xcc, 0xbb,0xaa,0x99,0x88,
84		0x77,0x66,0x55,0x44, 0x33,0x22,0x11,0x00,
85	};
86	static const uint8_t in1[16] = {
87		0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
88		0x0f,0x1e,0x2d,0x3c, 0x4b,0x59,0x68,0x77,
89	};
90	static const uint8_t expected1[64] = {
91		0xcd,0x9a,0x2a,0xa9, 0xea,0x93,0xc2,0x67,
92		0x5e,0x82,0x88,0x14, 0x08,0xde,0x85,0x2c,
93		0x62,0xfa,0x74,0x6a, 0x30,0xe5,0x2b,0x45,
94		0xa2,0x69,0x62,0xcf, 0x43,0x51,0xe3,0x04,
95		0xd3,0x13,0x20,0xbb, 0xd6,0xaa,0x6c,0xc8,
96		0xf3,0x26,0x37,0xf9, 0x59,0x34,0xe4,0xc1,
97		0x45,0xef,0xd5,0x62, 0x31,0xef,0x31,0x61,
98		0x03,0x28,0x36,0xf4, 0x96,0x71,0x83,0x3e,
99	};
100	uint8_t out[64];
101	int result = 0;
102
103	(*ci->ci_chacha_core)(out, zero, zero, chacha_const32, 12);
104	if (memcmp(out, expected0, 64)) {
105		hexdump(printf, "chacha core 1", out, sizeof out);
106		result = -1;
107	}
108
109	(*ci->ci_chacha_core)(out, in1, k1, chacha_const32, 12);
110	if (memcmp(out, expected1, 64)) {
111		hexdump(printf, "chacha core 2", out, sizeof out);
112		result = -1;
113	}
114
115	return result;
116}
117
118static int
119hchacha_selftest(const struct chacha_impl *ci)
120{
121	/* https://tools.ietf.org/html/draft-irtf-cfrg-xchacha-03, ��2.2.1 */
122	static const uint8_t k[32] = {
123		0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07,
124		0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f,
125		0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17,
126		0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f,
127	};
128	static const uint8_t in[16] = {
129		0x00,0x00,0x00,0x09, 0x00,0x00,0x00,0x4a,
130		0x00,0x00,0x00,0x00, 0x31,0x41,0x59,0x27,
131	};
132	static const uint8_t expected[32] = {
133		0x82,0x41,0x3b,0x42, 0x27,0xb2,0x7b,0xfe,
134		0xd3,0x0e,0x42,0x50, 0x8a,0x87,0x7d,0x73,
135		0xa0,0xf9,0xe4,0xd5, 0x8a,0x74,0xa8,0x53,
136		0xc1,0x2e,0xc4,0x13, 0x26,0xd3,0xec,0xdc,
137	};
138	uint8_t out[32];
139	int result = 0;
140
141	(*ci->ci_hchacha)(out, in, k, chacha_const32, 20);
142	if (memcmp(out, expected, 32)) {
143		hexdump(printf, "hchacha", out, sizeof out);
144		result = -1;
145	}
146
147	return result;
148}
149
150static int
151chacha_stream_selftest(const struct chacha_impl *ci)
152{
153
154	/* XXX */
155	return 0;
156}
157
158static int
159xchacha_stream_selftest(const struct chacha_impl *ci)
160{
161	/* https://tools.ietf.org/html/draft-irtf-cfrg-xchacha-03, A.2.1 */
162	static const uint8_t k[32] = {
163		0x80,0x81,0x82,0x83, 0x84,0x85,0x86,0x87,
164		0x88,0x89,0x8a,0x8b, 0x8c,0x8d,0x8e,0x8f,
165		0x90,0x91,0x92,0x93, 0x94,0x95,0x96,0x97,
166		0x98,0x99,0x9a,0x9b, 0x9c,0x9d,0x9e,0x9f,
167	};
168	static const uint8_t nonce[24] = {
169		0x40,0x41,0x42,0x43, 0x44,0x45,0x46,0x47,
170		0x48,0x49,0x4a,0x4b, 0x4c,0x4d,0x4e,0x4f,
171		0x50,0x51,0x52,0x53, 0x54,0x55,0x56,0x58,
172	};
173	static const uint8_t p[608] = {
174		0x54,0x68,0x65,0x20, 0x64,0x68,0x6f,0x6c,
175		0x65,0x20,0x28,0x70, 0x72,0x6f,0x6e,0x6f,
176		0x75,0x6e,0x63,0x65, 0x64,0x20,0x22,0x64,
177		0x6f,0x6c,0x65,0x22, 0x29,0x20,0x69,0x73,
178		0x20,0x61,0x6c,0x73, 0x6f,0x20,0x6b,0x6e,
179		0x6f,0x77,0x6e,0x20, 0x61,0x73,0x20,0x74,
180		0x68,0x65,0x20,0x41, 0x73,0x69,0x61,0x74,
181		0x69,0x63,0x20,0x77, 0x69,0x6c,0x64,0x20,
182		0x64,0x6f,0x67,0x2c, 0x20,0x72,0x65,0x64,
183		0x20,0x64,0x6f,0x67, 0x2c,0x20,0x61,0x6e,
184		0x64,0x20,0x77,0x68, 0x69,0x73,0x74,0x6c,
185		0x69,0x6e,0x67,0x20, 0x64,0x6f,0x67,0x2e,
186		0x20,0x49,0x74,0x20, 0x69,0x73,0x20,0x61,
187		0x62,0x6f,0x75,0x74, 0x20,0x74,0x68,0x65,
188		0x20,0x73,0x69,0x7a, 0x65,0x20,0x6f,0x66,
189		0x20,0x61,0x20,0x47, 0x65,0x72,0x6d,0x61,
190		0x6e,0x20,0x73,0x68, 0x65,0x70,0x68,0x65,
191		0x72,0x64,0x20,0x62, 0x75,0x74,0x20,0x6c,
192		0x6f,0x6f,0x6b,0x73, 0x20,0x6d,0x6f,0x72,
193		0x65,0x20,0x6c,0x69, 0x6b,0x65,0x20,0x61,
194		0x20,0x6c,0x6f,0x6e, 0x67,0x2d,0x6c,0x65,
195		0x67,0x67,0x65,0x64, 0x20,0x66,0x6f,0x78,
196		0x2e,0x20,0x54,0x68, 0x69,0x73,0x20,0x68,
197		0x69,0x67,0x68,0x6c, 0x79,0x20,0x65,0x6c,
198		0x75,0x73,0x69,0x76, 0x65,0x20,0x61,0x6e,
199		0x64,0x20,0x73,0x6b, 0x69,0x6c,0x6c,0x65,
200		0x64,0x20,0x6a,0x75, 0x6d,0x70,0x65,0x72,
201		0x20,0x69,0x73,0x20, 0x63,0x6c,0x61,0x73,
202		0x73,0x69,0x66,0x69, 0x65,0x64,0x20,0x77,
203		0x69,0x74,0x68,0x20, 0x77,0x6f,0x6c,0x76,
204		0x65,0x73,0x2c,0x20, 0x63,0x6f,0x79,0x6f,
205		0x74,0x65,0x73,0x2c, 0x20,0x6a,0x61,0x63,
206		0x6b,0x61,0x6c,0x73, 0x2c,0x20,0x61,0x6e,
207		0x64,0x20,0x66,0x6f, 0x78,0x65,0x73,0x20,
208		0x69,0x6e,0x20,0x74, 0x68,0x65,0x20,0x74,
209		0x61,0x78,0x6f,0x6e, 0x6f,0x6d,0x69,0x63,
210		0x20,0x66,0x61,0x6d, 0x69,0x6c,0x79,0x20,
211		0x43,0x61,0x6e,0x69, 0x64,0x61,0x65,0x2e,
212
213		0x54,0x68,0x65,0x20, 0x64,0x68,0x6f,0x6c,
214		0x65,0x20,0x28,0x70, 0x72,0x6f,0x6e,0x6f,
215		0x75,0x6e,0x63,0x65, 0x64,0x20,0x22,0x64,
216		0x6f,0x6c,0x65,0x22, 0x29,0x20,0x69,0x73,
217		0x20,0x61,0x6c,0x73, 0x6f,0x20,0x6b,0x6e,
218		0x6f,0x77,0x6e,0x20, 0x61,0x73,0x20,0x74,
219		0x68,0x65,0x20,0x41, 0x73,0x69,0x61,0x74,
220		0x69,0x63,0x20,0x77, 0x69,0x6c,0x64,0x20,
221		0x64,0x6f,0x67,0x2c, 0x20,0x72,0x65,0x64,
222		0x20,0x64,0x6f,0x67, 0x2c,0x20,0x61,0x6e,
223		0x64,0x20,0x77,0x68, 0x69,0x73,0x74,0x6c,
224		0x69,0x6e,0x67,0x20, 0x64,0x6f,0x67,0x2e,
225		0x20,0x49,0x74,0x20, 0x69,0x73,0x20,0x61,
226		0x62,0x6f,0x75,0x74, 0x20,0x74,0x68,0x65,
227		0x20,0x73,0x69,0x7a, 0x65,0x20,0x6f,0x66,
228		0x20,0x61,0x20,0x47, 0x65,0x72,0x6d,0x61,
229		0x6e,0x20,0x73,0x68, 0x65,0x70,0x68,0x65,
230		0x72,0x64,0x20,0x62, 0x75,0x74,0x20,0x6c,
231		0x6f,0x6f,0x6b,0x73, 0x20,0x6d,0x6f,0x72,
232		0x65,0x20,0x6c,0x69, 0x6b,0x65,0x20,0x61,
233		0x20,0x6c,0x6f,0x6e, 0x67,0x2d,0x6c,0x65,
234		0x67,0x67,0x65,0x64, 0x20,0x66,0x6f,0x78,
235		0x2e,0x20,0x54,0x68, 0x69,0x73,0x20,0x68,
236		0x69,0x67,0x68,0x6c, 0x79,0x20,0x65,0x6c,
237		0x75,0x73,0x69,0x76, 0x65,0x20,0x61,0x6e,
238		0x64,0x20,0x73,0x6b, 0x69,0x6c,0x6c,0x65,
239		0x64,0x20,0x6a,0x75, 0x6d,0x70,0x65,0x72,
240		0x20,0x69,0x73,0x20, 0x63,0x6c,0x61,0x73,
241		0x73,0x69,0x66,0x69, 0x65,0x64,0x20,0x77,
242		0x69,0x74,0x68,0x20, 0x77,0x6f,0x6c,0x76,
243		0x65,0x73,0x2c,0x20, 0x63,0x6f,0x79,0x6f,
244		0x74,0x65,0x73,0x2c, 0x20,0x6a,0x61,0x63,
245		0x6b,0x61,0x6c,0x73, 0x2c,0x20,0x61,0x6e,
246		0x64,0x20,0x66,0x6f, 0x78,0x65,0x73,0x20,
247		0x69,0x6e,0x20,0x74, 0x68,0x65,0x20,0x74,
248		0x61,0x78,0x6f,0x6e, 0x6f,0x6d,0x69,0x63,
249		0x20,0x66,0x61,0x6d, 0x69,0x6c,0x79,0x20,
250		0x43,0x61,0x6e,0x69, 0x64,0x61,0x65,0x2e,
251	};
252	static const uint8_t expected[608] = {
253		0x45,0x59,0xab,0xba, 0x4e,0x48,0xc1,0x61,
254		0x02,0xe8,0xbb,0x2c, 0x05,0xe6,0x94,0x7f,
255		0x50,0xa7,0x86,0xde, 0x16,0x2f,0x9b,0x0b,
256		0x7e,0x59,0x2a,0x9b, 0x53,0xd0,0xd4,0xe9,
257		0x8d,0x8d,0x64,0x10, 0xd5,0x40,0xa1,0xa6,
258		0x37,0x5b,0x26,0xd8, 0x0d,0xac,0xe4,0xfa,
259		0xb5,0x23,0x84,0xc7, 0x31,0xac,0xbf,0x16,
260		0xa5,0x92,0x3c,0x0c, 0x48,0xd3,0x57,0x5d,
261		0x4d,0x0d,0x2c,0x67, 0x3b,0x66,0x6f,0xaa,
262		0x73,0x10,0x61,0x27, 0x77,0x01,0x09,0x3a,
263		0x6b,0xf7,0xa1,0x58, 0xa8,0x86,0x42,0x92,
264		0xa4,0x1c,0x48,0xe3, 0xa9,0xb4,0xc0,0xda,
265		0xec,0xe0,0xf8,0xd9, 0x8d,0x0d,0x7e,0x05,
266		0xb3,0x7a,0x30,0x7b, 0xbb,0x66,0x33,0x31,
267		0x64,0xec,0x9e,0x1b, 0x24,0xea,0x0d,0x6c,
268		0x3f,0xfd,0xdc,0xec, 0x4f,0x68,0xe7,0x44,
269		0x30,0x56,0x19,0x3a, 0x03,0xc8,0x10,0xe1,
270		0x13,0x44,0xca,0x06, 0xd8,0xed,0x8a,0x2b,
271		0xfb,0x1e,0x8d,0x48, 0xcf,0xa6,0xbc,0x0e,
272		0xb4,0xe2,0x46,0x4b, 0x74,0x81,0x42,0x40,
273		0x7c,0x9f,0x43,0x1a, 0xee,0x76,0x99,0x60,
274		0xe1,0x5b,0xa8,0xb9, 0x68,0x90,0x46,0x6e,
275		0xf2,0x45,0x75,0x99, 0x85,0x23,0x85,0xc6,
276		0x61,0xf7,0x52,0xce, 0x20,0xf9,0xda,0x0c,
277		0x09,0xab,0x6b,0x19, 0xdf,0x74,0xe7,0x6a,
278		0x95,0x96,0x74,0x46, 0xf8,0xd0,0xfd,0x41,
279		0x5e,0x7b,0xee,0x2a, 0x12,0xa1,0x14,0xc2,
280		0x0e,0xb5,0x29,0x2a, 0xe7,0xa3,0x49,0xae,
281		0x57,0x78,0x20,0xd5, 0x52,0x0a,0x1f,0x3f,
282		0xb6,0x2a,0x17,0xce, 0x6a,0x7e,0x68,0xfa,
283		0x7c,0x79,0x11,0x1d, 0x88,0x60,0x92,0x0b,
284		0xc0,0x48,0xef,0x43, 0xfe,0x84,0x48,0x6c,
285		0xcb,0x87,0xc2,0x5f, 0x0a,0xe0,0x45,0xf0,
286		0xcc,0xe1,0xe7,0x98, 0x9a,0x9a,0xa2,0x20,
287		0xa2,0x8b,0xdd,0x48, 0x27,0xe7,0x51,0xa2,
288		0x4a,0x6d,0x5c,0x62, 0xd7,0x90,0xa6,0x63,
289		0x93,0xb9,0x31,0x11, 0xc1,0xa5,0x5d,0xd7,
290		0x42,0x1a,0x10,0x18, 0x49,0x74,0xc7,0xc5,
291
292		0x08,0x38,0x2d,0x64, 0x35,0x8d,0x21,0x77,
293		0x2e,0xb9,0x73,0xa8, 0x8f,0xb6,0x2b,0xf8,
294		0xce,0xfa,0xb4,0xca, 0x6f,0x0c,0x26,0xbb,
295		0x7f,0xd6,0x6d,0xb2, 0xa0,0xbe,0xb0,0x5a,
296		0x1a,0x6e,0x39,0xcb, 0xd5,0xda,0xf2,0xfc,
297		0x0b,0x74,0x31,0x3d, 0x2e,0xcd,0x5f,0x94,
298		0xc2,0x9f,0x30,0xdb, 0x11,0x5e,0x41,0x53,
299		0x8c,0x6d,0x30,0xba, 0x97,0xa0,0xc5,0x07,
300		0x70,0x78,0x02,0x5a, 0xc1,0x69,0x70,0x8f,
301		0x22,0x85,0xcb,0x98, 0xbc,0x6a,0x51,0xfb,
302		0xc6,0xa7,0xc3,0x3d, 0x76,0xe4,0x93,0x9a,
303		0x21,0xe2,0xc6,0x12, 0xe1,0x3a,0xcc,0xfb,
304		0x6f,0xa6,0x57,0xc0, 0x09,0x8c,0x6f,0xf3,
305		0x8d,0x83,0x21,0x1b, 0x71,0xa9,0xc1,0x93,
306		0x88,0x35,0xfc,0x18, 0x1f,0x94,0xa2,0x57,
307		0x3a,0x4e,0xd0,0xc0, 0xbc,0x92,0xa7,0x9c,
308		0x52,0x8a,0x82,0x9d, 0x44,0x75,0x7b,0xa0,
309		0xcf,0x3d,0x2d,0xbf, 0xf9,0x6f,0x71,0x56,
310		0x38,0xb0,0x63,0x5e, 0x55,0xcd,0x28,0x12,
311		0xc5,0xea,0x52,0xf4, 0xdc,0xf7,0xdc,0x3d,
312		0xd8,0x96,0x09,0xe8, 0x2a,0xcc,0x00,0x16,
313		0x88,0x77,0x82,0x10, 0xed,0x7d,0xd8,0x8b,
314		0xf5,0xd3,0xe1,0xfc, 0x49,0x66,0x36,0x8d,
315		0x55,0xd2,0x33,0xb8, 0x6d,0xff,0xe3,0xd3,
316		0x55,0x80,0x0e,0xd8, 0x95,0x32,0x32,0x55,
317		0x83,0xe7,0x58,0x6f, 0xec,0xc3,0x8c,0xf8,
318		0x52,0x16,0xdc,0x0d, 0x29,0x02,0xe5,0x27,
319		0x35,0xc2,0xbb,0xe2, 0xe2,0x3b,0xf5,0x19,
320		0xcd,0x44,0x83,0xe8, 0x21,0x55,0xd0,0x10,
321		0x15,0x68,0x8e,0x46, 0xa3,0x2f,0xa5,0x7c,
322		0xa8,0x2c,0xc6,0x8f, 0x14,0xcd,0xb3,0x79,
323		0x92,0x32,0x71,0xac, 0xd9,0xaf,0x9c,0x4d,
324		0x00,0x88,0xd1,0x42, 0xd5,0x23,0xfa,0xe6,
325		0x7f,0x38,0xa2,0x56, 0x99,0xbe,0x6f,0xcf,
326		0xe0,0xaa,0x44,0x11, 0x8a,0xc8,0x3a,0x99,
327		0x48,0x6d,0x33,0x0e, 0x94,0xf2,0xb9,0x87,
328		0xed,0x4f,0x6a,0x9c, 0x33,0x93,0x6d,0xe4,
329		0x92,0x76,0xab,0xfa, 0xce,0x5b,0x17,0x14,
330	};
331	uint8_t c[608];
332	unsigned i;
333	int result = 0;
334
335	/*
336	 * 608 = 96 (mod 256)
337	 * 607 = 95 (mod 256), = 7 (mod 8)
338	 * 543 = 31 (mod 256), = 7 (mod 8)
339	 * 511 = 255 (mod 256), = 7 (mod 8)
340	 *
341	 * This exercises several branches when there are special cases
342	 * for integral numbers of 4-byte words, integral numbers of
343	 * 64-byte blocks, and integral numbers of 256-byte chunks.
344	 */
345
346	(*ci->ci_xchacha_stream)(c, 608, 0, nonce, k, 20);
347	for (i = 0; i < 608; i++)
348		c[i] ^= p[i];
349	if (memcmp(c, expected, 608)) {
350		for (i = 0; i < 608; i++)
351			c[i] ^= p[i];
352		hexdump(printf, "xchacha_stream", c, 608);
353		for (i = 0; i < 608; i++)
354			c[i] = expected[i] ^ p[i];
355		hexdump(printf, "expected", c, 608);
356		result = -1;
357	}
358
359	(*ci->ci_xchacha_stream)(c, 607, 0, nonce, k, 20);
360	for (i = 0; i < 607; i++)
361		c[i] ^= p[i];
362	if (memcmp(c, expected, 607)) {
363		for (i = 0; i < 607; i++)
364			c[i] ^= p[i];
365		hexdump(printf, "xchacha_stream", c, 607);
366		for (i = 0; i < 607; i++)
367			c[i] = expected[i] ^ p[i];
368		hexdump(printf, "expected", c, 607);
369		result = -1;
370	}
371
372	(*ci->ci_xchacha_stream)(c, 543, 0, nonce, k, 20);
373	for (i = 0; i < 543; i++)
374		c[i] ^= p[i];
375	if (memcmp(c, expected, 543)) {
376		for (i = 0; i < 543; i++)
377			c[i] ^= p[i];
378		hexdump(printf, "xchacha_stream", c, 543);
379		for (i = 0; i < 543; i++)
380			c[i] = expected[i] ^ p[i];
381		hexdump(printf, "expected", c, 543);
382		result = -1;
383	}
384
385	(*ci->ci_xchacha_stream)(c, 511, 0, nonce, k, 20);
386	for (i = 0; i < 511; i++)
387		c[i] ^= p[i];
388	if (memcmp(c, expected, 511)) {
389		for (i = 0; i < 511; i++)
390			c[i] ^= p[i];
391		hexdump(printf, "xchacha_stream", c, 511);
392		for (i = 0; i < 511; i++)
393			c[i] = expected[i] ^ p[i];
394		hexdump(printf, "expected", c, 511);
395		result = -1;
396	}
397
398	(*ci->ci_xchacha_stream)(c, 63, 0, nonce, k, 20);
399	for (i = 0; i < 63; i++)
400		c[i] ^= p[i];
401	if (memcmp(c, expected, 63)) {
402		for (i = 0; i < 63; i++)
403			c[i] ^= p[i];
404		hexdump(printf, "xchacha_stream", c, 63);
405		for (i = 0; i < 63; i++)
406			c[i] = expected[i] ^ p[i];
407		hexdump(printf, "expected", c, 63);
408		result = -1;
409	}
410
411	(*ci->ci_xchacha_stream_xor)(c, p, 608, 0, nonce, k, 20);
412	if (memcmp(c, expected, 608)) {
413		hexdump(printf, "xchacha_stream_xor", c, 608);
414		hexdump(printf, "expected", expected, 608);
415		result = -1;
416	}
417
418	memset(c, 0, sizeof c);
419	(*ci->ci_xchacha_stream_xor)(c, p, 607, 0, nonce, k, 20);
420	if (memcmp(c, expected, 607)) {
421		hexdump(printf, "xchacha_stream_xor", c, 607);
422		hexdump(printf, "expected", expected, 607);
423		result = -1;
424	}
425
426	memset(c, 0, sizeof c);
427	(*ci->ci_xchacha_stream_xor)(c, p, 543, 0, nonce, k, 20);
428	if (memcmp(c, expected, 543)) {
429		hexdump(printf, "xchacha_stream_xor", c, 543);
430		hexdump(printf, "expected", expected, 543);
431		result = -1;
432	}
433
434	memset(c, 0, sizeof c);
435	(*ci->ci_xchacha_stream_xor)(c, p, 511, 0, nonce, k, 20);
436	if (memcmp(c, expected, 511)) {
437		hexdump(printf, "xchacha_stream_xor", c, 511);
438		hexdump(printf, "expected", expected, 511);
439		result = -1;
440	}
441
442	memset(c, 0, sizeof c);
443	(*ci->ci_xchacha_stream_xor)(c, p, 63, 0, nonce, k, 20);
444	if (memcmp(c, expected, 63)) {
445		hexdump(printf, "xchacha_stream_xor", c, 63);
446		hexdump(printf, "expected", expected, 63);
447		result = -1;
448	}
449
450	return result;
451}
452
453int
454chacha_selftest(const struct chacha_impl *ci)
455{
456	int result = 0;
457
458	result |= chacha_core_selftest(ci);
459	result |= chacha_stream_selftest(ci);
460	result |= hchacha_selftest(ci);
461	result |= xchacha_stream_selftest(ci);
462
463	return result;
464}
465