chachatest.c revision 1.2
1/*
2 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <err.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21
22#include <openssl/chacha.h>
23
24struct chacha_tv {
25	const char *desc;
26	const unsigned char key[32];
27	const unsigned char iv[8];
28	const size_t len;
29	const unsigned char out[512];
30};
31
32/*
33 * Test vectors from:
34 *   http://tools.ietf.org/html/draft-strombergson-chacha-test-vectors-01
35 */
36struct chacha_tv chacha_test_vectors[] = {
37	{
38		"TC1: All zero key and IV",
39		{
40			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44		},
45		{
46			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47		},
48		64,
49		{
50			0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
51			0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
52			0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
53			0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
54			0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
55			0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
56			0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
57			0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86,
58		},
59	},
60	{
61		"TC2: Single bit in key set, all zero IV",
62		{
63			0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67		},
68		{
69			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70		},
71		64,
72		{
73			0xc5, 0xd3, 0x0a, 0x7c, 0xe1, 0xec, 0x11, 0x93,
74			0x78, 0xc8, 0x4f, 0x48, 0x7d, 0x77, 0x5a, 0x85,
75			0x42, 0xf1, 0x3e, 0xce, 0x23, 0x8a, 0x94, 0x55,
76			0xe8, 0x22, 0x9e, 0x88, 0x8d, 0xe8, 0x5b, 0xbd,
77			0x29, 0xeb, 0x63, 0xd0, 0xa1, 0x7a, 0x5b, 0x99,
78			0x9b, 0x52, 0xda, 0x22, 0xbe, 0x40, 0x23, 0xeb,
79			0x07, 0x62, 0x0a, 0x54, 0xf6, 0xfa, 0x6a, 0xd8,
80			0x73, 0x7b, 0x71, 0xeb, 0x04, 0x64, 0xda, 0xc0,
81		},
82	},
83	{
84		"TC3: Single bit in IV set, all zero key",
85		{
86			0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
87			0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
88			0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
89			0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
90		},
91		{
92			0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
93		},
94		64,
95		{
96			0xd9, 0xbf, 0x3f, 0x6b, 0xce, 0x6e, 0xd0, 0xb5,
97			0x42, 0x54, 0x55, 0x77, 0x67, 0xfb, 0x57, 0x44,
98			0x3d, 0xd4, 0x77, 0x89, 0x11, 0xb6, 0x06, 0x05,
99			0x5c, 0x39, 0xcc, 0x25, 0xe6, 0x74, 0xb8, 0x36,
100			0x3f, 0xea, 0xbc, 0x57, 0xfd, 0xe5, 0x4f, 0x79,
101			0x0c, 0x52, 0xc8, 0xae, 0x43, 0x24, 0x0b, 0x79,
102			0xd4, 0x90, 0x42, 0xb7, 0x77, 0xbf, 0xd6, 0xcb,
103			0x80, 0xe9, 0x31, 0x27, 0x0b, 0x7f, 0x50, 0xeb,
104		},
105	},
106	{
107		"TC4: All bits in key and IV are set",
108		{
109			0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
110			0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
111			0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
112			0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
113		},
114		{
115			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
116		},
117		64,
118		{
119			0xaf, 0xf7, 0x41, 0x82, 0x93, 0xf3, 0xa5, 0x53,
120			0x89, 0x4b, 0x1e, 0x74, 0x84, 0xbd, 0x1e, 0x8e,
121			0xde, 0x19, 0x6e, 0xce, 0xd5, 0xa1, 0xd6, 0x81,
122			0x4d, 0xe3, 0x70, 0x91, 0xe0, 0x7e, 0x07, 0x6e,
123			0x34, 0xbb, 0xba, 0x81, 0x07, 0xa6, 0x86, 0xc9,
124			0x82, 0x85, 0x0f, 0x0a, 0x73, 0x53, 0x94, 0x0d,
125			0x40, 0xdb, 0x1a, 0xb0, 0xb5, 0x76, 0x5b, 0x78,
126			0xb4, 0xcf, 0x47, 0x3d, 0x94, 0x85, 0xa3, 0xdd,
127		},
128	},
129	{
130		"TC5: Every even bit set in key and IV",
131		{
132			0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
133			0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
134			0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
135			0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
136		},
137		{
138			0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
139		},
140		64,
141		{
142			0xbe, 0xa9, 0x41, 0x1a, 0xa4, 0x53, 0xc5, 0x43,
143			0x4a, 0x5a, 0xe8, 0xc9, 0x28, 0x62, 0xf5, 0x64,
144			0x39, 0x68, 0x55, 0xa9, 0xea, 0x6e, 0x22, 0xd6,
145			0xd3, 0xb5, 0x0a, 0xe1, 0xb3, 0x66, 0x33, 0x11,
146			0xa4, 0xa3, 0x60, 0x6c, 0x67, 0x1d, 0x60, 0x5c,
147			0xe1, 0x6c, 0x3a, 0xec, 0xe8, 0xe6, 0x1e, 0xa1,
148			0x45, 0xc5, 0x97, 0x75, 0x01, 0x7b, 0xee, 0x2f,
149			0xa6, 0xf8, 0x8a, 0xfc, 0x75, 0x80, 0x69, 0xf7,
150		},
151	},
152	{
153		"TC6: Every odd bit set in key and IV",
154		{
155			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
156			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
157			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
158			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
159		},
160		{
161			0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
162		},
163		64,
164		{
165			0x9a, 0xa2, 0xa9, 0xf6, 0x56, 0xef, 0xde, 0x5a,
166			0xa7, 0x59, 0x1c, 0x5f, 0xed, 0x4b, 0x35, 0xae,
167			0xa2, 0x89, 0x5d, 0xec, 0x7c, 0xb4, 0x54, 0x3b,
168			0x9e, 0x9f, 0x21, 0xf5, 0xe7, 0xbc, 0xbc, 0xf3,
169			0xc4, 0x3c, 0x74, 0x8a, 0x97, 0x08, 0x88, 0xf8,
170			0x24, 0x83, 0x93, 0xa0, 0x9d, 0x43, 0xe0, 0xb7,
171			0xe1, 0x64, 0xbc, 0x4d, 0x0b, 0x0f, 0xb2, 0x40,
172			0xa2, 0xd7, 0x21, 0x15, 0xc4, 0x80, 0x89, 0x06,
173		},
174	},
175	{
176		"TC7: Sequence patterns in key and IV",
177		{
178			0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
179			0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
180			0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88,
181			0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00,
182		},
183		{
184			0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78,
185		},
186		64,
187		{
188			0x9f, 0xad, 0xf4, 0x09, 0xc0, 0x08, 0x11, 0xd0,
189			0x04, 0x31, 0xd6, 0x7e, 0xfb, 0xd8, 0x8f, 0xba,
190			0x59, 0x21, 0x8d, 0x5d, 0x67, 0x08, 0xb1, 0xd6,
191			0x85, 0x86, 0x3f, 0xab, 0xbb, 0x0e, 0x96, 0x1e,
192			0xea, 0x48, 0x0f, 0xd6, 0xfb, 0x53, 0x2b, 0xfd,
193			0x49, 0x4b, 0x21, 0x51, 0x01, 0x50, 0x57, 0x42,
194			0x3a, 0xb6, 0x0a, 0x63, 0xfe, 0x4f, 0x55, 0xf7,
195			0xa2, 0x12, 0xe2, 0x16, 0x7c, 0xca, 0xb9, 0x31,
196		},
197	},
198	{
199		"TC8: key: 'All your base are belong to us!, IV: 'IETF2013'",
200		{
201			0xc4, 0x6e, 0xc1, 0xb1, 0x8c, 0xe8, 0xa8, 0x78,
202			0x72, 0x5a, 0x37, 0xe7, 0x80, 0xdf, 0xb7, 0x35,
203			0x1f, 0x68, 0xed, 0x2e, 0x19, 0x4c, 0x79, 0xfb,
204			0xc6, 0xae, 0xbe, 0xe1, 0xa6, 0x67, 0x97, 0x5d,
205		},
206		{
207			0x1a, 0xda, 0x31, 0xd5, 0xcf, 0x68, 0x82, 0x21,
208		},
209		64,
210		{
211			0xf6, 0x3a, 0x89, 0xb7, 0x5c, 0x22, 0x71, 0xf9,
212			0x36, 0x88, 0x16, 0x54, 0x2b, 0xa5, 0x2f, 0x06,
213			0xed, 0x49, 0x24, 0x17, 0x92, 0x30, 0x2b, 0x00,
214			0xb5, 0xe8, 0xf8, 0x0a, 0xe9, 0xa4, 0x73, 0xaf,
215			0xc2, 0x5b, 0x21, 0x8f, 0x51, 0x9a, 0xf0, 0xfd,
216			0xd4, 0x06, 0x36, 0x2e, 0x8d, 0x69, 0xde, 0x7f,
217			0x54, 0xc6, 0x04, 0xa6, 0xe0, 0x0f, 0x35, 0x3f,
218			0x11, 0x0f, 0x77, 0x1b, 0xdc, 0xa8, 0xab, 0x92,
219		},
220	},
221};
222
223#define N_VECTORS (sizeof(chacha_test_vectors) / sizeof(*chacha_test_vectors))
224
225int
226main(int argc, char **argv)
227{
228	struct chacha_tv *tv;
229	unsigned char *in, *out;
230	size_t i, j;
231
232	for (i = 0; i < N_VECTORS; i++) {
233		tv = &chacha_test_vectors[i];
234
235		in = malloc(tv->len);
236		if (in == NULL)
237			errx(1, "malloc in");
238		out = malloc(tv->len);
239		if (out == NULL)
240			errx(1, "malloc out");
241		memset(in, 0, tv->len);
242
243		CRYPTO_chacha_20(out, in, tv->len, tv->key, tv->iv, 0);
244
245		if (memcmp(out, tv->out, tv->len) != 0) {
246			printf("ChaCha %s failed!\n", tv->desc);
247			for (j = 0; j < tv->len; j++)
248				printf("%2.2x", out[j]);
249			printf("\n");
250			for (j = 0; j < tv->len; j++)
251				printf("%2.2x", tv->out[j]);
252			printf("\n");
253			return 1;
254		}
255
256		free(in);
257		free(out);
258	}
259
260	return 0;
261}
262