xref: /netbsd-src/sys/crypto/chacha/chacha_selftest.c (revision fa79152618fc8fd4c1019d2f19f11c1e3d1b3013)
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 
40 static void
41 hexdump(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 */
64 static int
chacha_core_selftest(const struct chacha_impl * ci)65 chacha_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 
118 static int
hchacha_selftest(const struct chacha_impl * ci)119 hchacha_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 
150 static int
chacha_stream_selftest(const struct chacha_impl * ci)151 chacha_stream_selftest(const struct chacha_impl *ci)
152 {
153 
154 	/* XXX */
155 	return 0;
156 }
157 
158 static int
xchacha_stream_selftest(const struct chacha_impl * ci)159 xchacha_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 
453 int
chacha_selftest(const struct chacha_impl * ci)454 chacha_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