1/*      $OpenBSD: aesctr.c,v 1.4 2021/12/13 16:56:49 deraadt Exp $  */
2
3/*
4 * Copyright (c) 2005 Markus Friedl <markus@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/types.h>
20#include <crypto/aes.h>
21#include <err.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <unistd.h>
26#include <limits.h>
27#include <errno.h>
28
29int debug = 0;
30
31enum { TST_KEY, TST_IV, TST_PLAIN, TST_CIPHER, TST_NUM };
32
33/* Test vectors from RFC 3686 */
34struct {
35	char *data[TST_NUM];
36} tests[] = {
37	/* 128 bit key */
38	{
39		"AE 68 52 F8 12 10 67 CC 4B F7 A5 76 55 77 F3 9E "
40		"00 00 00 30",
41		"00 00 00 00 00 00 00 00",
42		"53 69 6E 67 6C 65 20 62 6C 6F 63 6B 20 6D 73 67",
43		"E4 09 5D 4F B7 A7 B3 79 2D 61 75 A3 26 13 11 B8"
44	},
45	{
46		"7E 24 06 78 17 FA E0 D7 43 D6 CE 1F 32 53 91 63 "
47		"00 6C B6 DB",
48		"C0 54 3B 59 DA 48 D9 0B",
49		"00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F "
50		"10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F",
51		"51 04 A1 06 16 8A 72 D9 79 0D 41 EE 8E DA D3 88 "
52		"EB 2E 1E FC 46 DA 57 C8 FC E6 30 DF 91 41 BE 28"
53	},
54	{
55		"76 91 BE 03 5E 50 20 A8 AC 6E 61 85 29 F9 A0 DC "
56		"00 E0 01 7B",
57		"27 77 7F 3F 4A 17 86 F0",
58		"00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F "
59		"10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F"
60		/*"20 21 22 23"*/,
61		"C1 CF 48 A8 9F 2F FD D9 CF 46 52 E9 EF DB 72 D7 "
62		"45 40 A4 2B DE 6D 78 36 D5 9A 5C EA AE F3 10 53"
63                /*"25 B2 07 2F"*/
64	},
65	/* 192 bit key */
66	{
67		"16 AF 5B 14 5F C9 F5 79 C1 75 F9 3E 3B FB 0E ED "
68		"86 3D 06 CC FD B7 85 15 "
69		"00 00 00 48",
70		"36 73 3C 14 7D 6D 93 CB",
71		"53 69 6E 67 6C 65 20 62 6C 6F 63 6B 20 6D 73 67",
72		"4B 55 38 4F E2 59 C9 C8 4E 79 35 A0 03 CB E9 28",
73	},
74	{
75		"7C 5C B2 40 1B 3D C3 3C 19 E7 34 08 19 E0 F6 9C "
76		"67 8C 3D B8 E6 F6 A9 1A "
77		"00 96 B0 3B",
78		"02 0C 6E AD C2 CB 50 0D",
79		"00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F "
80		"10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F",
81		"45 32 43 FC 60 9B 23 32 7E DF AA FA 71 31 CD 9F "
82		"84 90 70 1C 5A D4 A7 9C FC 1F E0 FF 42 F4 FB 00",
83	},
84	{
85		"02 BF 39 1E E8 EC B1 59 B9 59 61 7B 09 65 27 9B "
86		"F5 9B 60 A7 86 D3 E0 FE "
87		"00 07 BD FD",
88		"5C BD 60 27 8D CC 09 12",
89		"00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F "
90		"10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F"
91		/*"20 21 22 23"*/,
92		"96 89 3F C5 5E 5C 72 2F 54 0B 7D D1 DD F7 E7 58 "
93		"D2 88 BC 95 C6 91 65 88 45 36 C8 11 66 2F 21 88"
94		/*"AB EE 09 35"*/,
95	},
96	/* 256 bit key */
97	{
98		"77 6B EF F2 85 1D B0 6F 4C 8A 05 42 C8 69 6F 6C "
99		"6A 81 AF 1E EC 96 B4 D3 7F C1 D6 89 E6 C1 C1 04 "
100		"00 00 00 60",
101		"DB 56 72 C9 7A A8 F0 B2",
102		"53 69 6E 67 6C 65 20 62 6C 6F 63 6B 20 6D 73 67",
103		"14 5A D0 1D BF 82 4E C7 56 08 63 DC 71 E3 E0 C0"
104	},
105	{
106		"F6 D6 6D 6B D5 2D 59 BB 07 96 36 58 79 EF F8 86 "
107		"C6 6D D5 1A 5B 6A 99 74 4B 50 59 0C 87 A2 38 84 "
108		"00 FA AC 24",
109		"C1 58 5E F1 5A 43 D8 75",
110		"00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F "
111		"10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F",
112		"F0 5E 23 1B 38 94 61 2C 49 EE 00 0B 80 4E B2 A9 "
113		"B8 30 6B 50 8F 83 9D 6A 55 30 83 1D 93 44 AF 1C",
114	},
115	{
116		"FF 7A 61 7C E6 91 48 E4 F1 72 6E 2F 43 58 1D E2 "
117		"AA 62 D9 F8 05 53 2E DF F1 EE D6 87 FB 54 15 3D "
118		"00 1C C5 B7",
119		"51 A5 1D 70 A1 C1 11 48",
120		"00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F "
121		"10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F"
122		/*"20 21 22 23"*/,
123		"EB 6C 52 82 1D 0B BB F7 CE 75 94 46 2A CA 4F AA "
124		"B4 07 DF 86 65 69 FD 07 F4 8C C0 B5 83 D6 07 1F"
125		/*"1E C0 E6 B8"*/,
126	},
127};
128
129/* Stubs */
130
131u_int32_t deflate_global(u_int8_t *, u_int32_t, int, u_int8_t **);
132
133u_int32_t
134deflate_global(u_int8_t *data, u_int32_t size, int comp, u_int8_t **out)
135{
136	return 0;
137}
138
139void	explicit_bzero(void *, size_t);
140
141void
142explicit_bzero(void *b, size_t len)
143{
144	bzero(b, len);
145}
146
147/* Definitions from /sys/crypto/xform.c */
148
149#define AESCTR_NONCESIZE	4
150#define AESCTR_IVSIZE		8
151#define AESCTR_BLOCKSIZE	16
152
153struct aes_ctr_ctx {
154	AES_CTX		ac_key;
155	u_int8_t	ac_block[AESCTR_BLOCKSIZE];
156};
157
158int  aes_ctr_setkey(void *, u_int8_t *, int);
159void aes_ctr_encrypt(caddr_t, u_int8_t *);
160void aes_ctr_decrypt(caddr_t, u_int8_t *);
161void aes_ctr_reinit(caddr_t, u_int8_t *);
162
163static int
164docrypt(const unsigned char *key, size_t klen, const unsigned char *iv,
165    const unsigned char *in, unsigned char *out, size_t len, int encrypt)
166{
167	u_int8_t block[AESCTR_BLOCKSIZE];
168	struct aes_ctr_ctx ctx;
169	int error = 0;
170	size_t i;
171
172	error = aes_ctr_setkey(&ctx, (u_int8_t *)key, klen);
173	if (error)
174		return -1;
175	aes_ctr_reinit((caddr_t)&ctx, (u_int8_t *)iv);
176	for (i = 0; i < len / AESCTR_BLOCKSIZE; i++) {
177		bcopy(in, block, AESCTR_BLOCKSIZE);
178		in += AESCTR_BLOCKSIZE;
179		aes_ctr_crypt(&ctx, block);
180		bcopy(block, out, AESCTR_BLOCKSIZE);
181		out += AESCTR_BLOCKSIZE;
182	}
183	return 0;
184}
185
186static int
187match(unsigned char *a, unsigned char *b, size_t len)
188{
189	int i;
190
191	if (memcmp(a, b, len) == 0)
192		return (1);
193
194	warnx("ciphertext mismatch");
195
196	for (i = 0; i < len; i++)
197		printf("%2.2x", a[i]);
198	printf("\n");
199	for (i = 0; i < len; i++)
200		printf("%2.2x", b[i]);
201	printf("\n");
202
203	return (0);
204}
205
206static int
207run(int num)
208{
209	int i, fail = 1, len, j, length[TST_NUM];
210	u_long val;
211	char *ep, *from;
212	u_char *p, *data[TST_NUM];
213
214	for (i = 0; i < TST_NUM; i++)
215		data[i] = NULL;
216	for (i = 0; i < TST_NUM; i++) {
217		from = tests[num].data[i];
218		if (debug)
219			printf("%s\n", from);
220		len = strlen(from);
221		if ((p = malloc(len)) == 0) {
222			warn("malloc");
223			goto done;
224		}
225		errno = 0;
226		for (j = 0; j < len; j++) {
227			val = strtoul(&from[j*3], &ep, 16);
228			p[j] = (u_char)val;
229			if (*ep == '\0' || errno)
230				break;
231		}
232		length[i] = j+1;
233		data[i] = p;
234	}
235	len = length[TST_PLAIN];
236	if ((p = malloc(len)) == 0) {
237		warn("malloc");
238		return (1);
239	}
240	if (docrypt(data[TST_KEY], length[TST_KEY],
241	    data[TST_IV], data[TST_PLAIN], p,
242	    length[TST_PLAIN], 0) < 0) {
243		warnx("encryption failed");
244		goto done;
245	}
246	fail = !match(data[TST_CIPHER], p, len);
247	printf("%s test vector %d\n", fail ? "FAILED" : "OK", num);
248done:
249	for (i = 0; i < TST_NUM; i++)
250		free(data[i]);
251	return (fail);
252}
253
254int
255main(int argc, char **argv)
256{
257	int fail = 0, i;
258
259	for (i = 0; i < (sizeof(tests) / sizeof(tests[0])); i++)
260		fail += run(i);
261	exit((fail > 0) ? 1 : 0);
262}
263