xref: /openbsd-src/regress/sys/crypto/aesctr/aesctr.c (revision 2b0358df1d88d06ef4139321dd05bd5e05d91eaf)
1 /*      $OpenBSD: aesctr.c,v 1.1 2005/05/25 05:47:53 markus 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 <sys/param.h>
21 #include <sys/ioctl.h>
22 #include <sys/sysctl.h>
23 #include <crypto/cryptodev.h>
24 #include <err.h>
25 #include <fcntl.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <unistd.h>
30 #include <limits.h>
31 #include <errno.h>
32 
33 int debug = 0;
34 
35 enum { TST_KEY, TST_IV, TST_PLAIN, TST_CIPHER, TST_NUM };
36 
37 /* Test vectors from RFC 3686 */
38 struct {
39 	char *data[TST_NUM];
40 } tests[] = {
41 	/* 128 bit key */
42 	{
43 		"AE 68 52 F8 12 10 67 CC 4B F7 A5 76 55 77 F3 9E "
44 		"00 00 00 30",
45 		"00 00 00 00 00 00 00 00",
46 		"53 69 6E 67 6C 65 20 62 6C 6F 63 6B 20 6D 73 67",
47 		"E4 09 5D 4F B7 A7 B3 79 2D 61 75 A3 26 13 11 B8"
48 	},
49 	{
50 		"7E 24 06 78 17 FA E0 D7 43 D6 CE 1F 32 53 91 63 "
51 		"00 6C B6 DB",
52 		"C0 54 3B 59 DA 48 D9 0B",
53 		"00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F "
54 		"10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F",
55 		"51 04 A1 06 16 8A 72 D9 79 0D 41 EE 8E DA D3 88 "
56 		"EB 2E 1E FC 46 DA 57 C8 FC E6 30 DF 91 41 BE 28"
57 	},
58 	{
59 		"76 91 BE 03 5E 50 20 A8 AC 6E 61 85 29 F9 A0 DC "
60 		"00 E0 01 7B",
61 		"27 77 7F 3F 4A 17 86 F0",
62 		"00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F "
63 		"10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F"
64 		/*"20 21 22 23"*/,
65 		"C1 CF 48 A8 9F 2F FD D9 CF 46 52 E9 EF DB 72 D7 "
66 		"45 40 A4 2B DE 6D 78 36 D5 9A 5C EA AE F3 10 53"
67                 /*"25 B2 07 2F"*/
68 	},
69 	/* 192 bit key */
70 	{
71 		"16 AF 5B 14 5F C9 F5 79 C1 75 F9 3E 3B FB 0E ED "
72 		"86 3D 06 CC FD B7 85 15 "
73 		"00 00 00 48",
74 		"36 73 3C 14 7D 6D 93 CB",
75 		"53 69 6E 67 6C 65 20 62 6C 6F 63 6B 20 6D 73 67",
76 		"4B 55 38 4F E2 59 C9 C8 4E 79 35 A0 03 CB E9 28",
77 	},
78 	{
79 		"7C 5C B2 40 1B 3D C3 3C 19 E7 34 08 19 E0 F6 9C "
80 		"67 8C 3D B8 E6 F6 A9 1A "
81 		"00 96 B0 3B",
82 		"02 0C 6E AD C2 CB 50 0D",
83 		"00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F "
84 		"10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F",
85 		"45 32 43 FC 60 9B 23 32 7E DF AA FA 71 31 CD 9F "
86 		"84 90 70 1C 5A D4 A7 9C FC 1F E0 FF 42 F4 FB 00",
87 	},
88 	{
89 		"02 BF 39 1E E8 EC B1 59 B9 59 61 7B 09 65 27 9B "
90 		"F5 9B 60 A7 86 D3 E0 FE "
91 		"00 07 BD FD",
92 		"5C BD 60 27 8D CC 09 12",
93 		"00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F "
94 		"10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F"
95 		/*"20 21 22 23"*/,
96 		"96 89 3F C5 5E 5C 72 2F 54 0B 7D D1 DD F7 E7 58 "
97 		"D2 88 BC 95 C6 91 65 88 45 36 C8 11 66 2F 21 88"
98 		/*"AB EE 09 35"*/,
99 	},
100 	/* 256 bit key */
101 	{
102 		"77 6B EF F2 85 1D B0 6F 4C 8A 05 42 C8 69 6F 6C "
103 		"6A 81 AF 1E EC 96 B4 D3 7F C1 D6 89 E6 C1 C1 04 "
104 		"00 00 00 60",
105 		"DB 56 72 C9 7A A8 F0 B2",
106 		"53 69 6E 67 6C 65 20 62 6C 6F 63 6B 20 6D 73 67",
107 		"14 5A D0 1D BF 82 4E C7 56 08 63 DC 71 E3 E0 C0"
108 	},
109 	{
110 		"F6 D6 6D 6B D5 2D 59 BB 07 96 36 58 79 EF F8 86 "
111 		"C6 6D D5 1A 5B 6A 99 74 4B 50 59 0C 87 A2 38 84 "
112 		"00 FA AC 24",
113 		"C1 58 5E F1 5A 43 D8 75",
114 		"00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F "
115 		"10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F",
116 		"F0 5E 23 1B 38 94 61 2C 49 EE 00 0B 80 4E B2 A9 "
117 		"B8 30 6B 50 8F 83 9D 6A 55 30 83 1D 93 44 AF 1C",
118 	},
119 	{
120 		"FF 7A 61 7C E6 91 48 E4 F1 72 6E 2F 43 58 1D E2 "
121 		"AA 62 D9 F8 05 53 2E DF F1 EE D6 87 FB 54 15 3D "
122 		"00 1C C5 B7",
123 		"51 A5 1D 70 A1 C1 11 48",
124 		"00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F "
125 		"10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F"
126 		/*"20 21 22 23"*/,
127 		"EB 6C 52 82 1D 0B BB F7 CE 75 94 46 2A CA 4F AA "
128 		"B4 07 DF 86 65 69 FD 07 F4 8C C0 B5 83 D6 07 1F"
129 		/*"1E C0 E6 B8"*/,
130 	},
131 };
132 
133 static int
134 syscrypt(const unsigned char *key, size_t klen, const unsigned char *iv,
135     const unsigned char *in, unsigned char *out, size_t len, int encrypt)
136 {
137 	struct session_op session;
138 	struct crypt_op cryp;
139 	int cryptodev_fd = -1, fd = -1;
140 
141 	if ((cryptodev_fd = open("/dev/crypto", O_RDWR, 0)) < 0) {
142 		warn("/dev/crypto");
143 		goto err;
144 	}
145 	if (ioctl(cryptodev_fd, CRIOGET, &fd) == -1) {
146 		warn("CRIOGET failed");
147 		goto err;
148 	}
149 	memset(&session, 0, sizeof(session));
150 	session.cipher = CRYPTO_AES_CTR;
151 	session.key = (caddr_t) key;
152 	session.keylen = klen;
153 	if (ioctl(fd, CIOCGSESSION, &session) == -1) {
154 		warn("CIOCGSESSION");
155 		goto err;
156 	}
157 	memset(&cryp, 0, sizeof(cryp));
158 	cryp.ses = session.ses;
159 	cryp.op = encrypt ? COP_ENCRYPT : COP_DECRYPT;
160 	cryp.flags = 0;
161 	cryp.len = len;
162 	cryp.src = (caddr_t) in;
163 	cryp.dst = (caddr_t) out;
164 	cryp.iv = (caddr_t) iv;
165 	cryp.mac = 0;
166 	if (ioctl(fd, CIOCCRYPT, &cryp) == -1) {
167 		warn("CIOCCRYPT");
168 		goto err;
169 	}
170 	if (ioctl(fd, CIOCFSESSION, &session.ses) == -1) {
171 		warn("CIOCFSESSION");
172 		goto err;
173 	}
174 	close(fd);
175 	close(cryptodev_fd);
176 	return (0);
177 
178 err:
179 	if (fd != -1)
180 		close(fd);
181 	if (cryptodev_fd != -1)
182 		close(cryptodev_fd);
183 	return (-1);
184 }
185 
186 static int
187 getallowsoft(void)
188 {
189 	int mib[2], old;
190 	size_t olen;
191 
192 	olen = sizeof(old);
193 
194 	mib[0] = CTL_KERN;
195 	mib[1] = KERN_CRYPTODEVALLOWSOFT;
196 	if (sysctl(mib, 2, &old, &olen, NULL, 0) < 0)
197 		err(1, "sysctl failed");
198 
199 	return old;
200 }
201 
202 static void
203 setallowsoft(int new)
204 {
205 	int mib[2], old;
206 	size_t olen, nlen;
207 
208 	olen = nlen = sizeof(new);
209 
210 	mib[0] = CTL_KERN;
211 	mib[1] = KERN_CRYPTODEVALLOWSOFT;
212 
213 	if (sysctl(mib, 2, &old, &olen, &new, nlen) < 0)
214 		err(1, "sysctl failed");
215 }
216 
217 static int
218 match(unsigned char *a, unsigned char *b, size_t len)
219 {
220 	int i;
221 
222 	if (memcmp(a, b, len) == 0)
223 		return (1);
224 
225 	warnx("ciphertext mismatch");
226 
227 	for (i = 0; i < len; i++)
228 		printf("%2.2x", a[i]);
229 	printf("\n");
230 	for (i = 0; i < len; i++)
231 		printf("%2.2x", b[i]);
232 	printf("\n");
233 
234 	return (0);
235 }
236 
237 static int
238 run(int num)
239 {
240 	int i, fail = 1, len, j, length[TST_NUM];
241 	u_long val;
242 	char *ep, *from;
243 	u_char *p, *data[TST_NUM];
244 
245 	for (i = 0; i < TST_NUM; i++)
246 		data[i] = NULL;
247 	for (i = 0; i < TST_NUM; i++) {
248 		from = tests[num].data[i];
249 		if (debug)
250 			printf("%s\n", from);
251 		len = strlen(from);
252 		if ((p = malloc(len)) == 0) {
253 			warn("malloc");
254 			goto done;
255 		}
256 		errno = 0;
257 		for (j = 0; j < len; j++) {
258 			val = strtoul(&from[j*3], &ep, 16);
259 			p[j] = (u_char)val;
260 			if (*ep == '\0' || errno)
261 				break;
262 		}
263 		length[i] = j+1;
264 		data[i] = p;
265 	}
266 	len = length[TST_PLAIN];
267 	if ((p = malloc(len)) == 0) {
268 		warn("malloc");
269 		return (1);
270 	}
271 	if (syscrypt(data[TST_KEY], length[TST_KEY],
272 	    data[TST_IV], data[TST_PLAIN], p,
273 	    length[TST_PLAIN], 0) < 0) {
274 		warnx("crypt with /dev/crypto failed");
275 		goto done;
276 	}
277 	fail = !match(data[TST_CIPHER], p, len);
278 	printf("%s test vector %d\n", fail ? "FAILED" : "OK", num);
279 done:
280 	for (i = 0; i < TST_NUM; i++)
281 		free(data[i]);
282 	return (fail);
283 }
284 
285 int
286 main(int argc, char **argv)
287 {
288 	int allowed = 0, fail = 0, i;
289 
290 	if (geteuid() == 0) {
291 		allowed = getallowsoft();
292 		if (allowed == 0)
293 			setallowsoft(1);
294 	}
295 	for (i = 0; i < (sizeof(tests) / sizeof(tests[0])); i++)
296 		fail += run(i);
297 	if (geteuid() == 0 && allowed == 0)
298 		setallowsoft(0);
299 	exit((fail > 0) ? 1 : 0);
300 }
301