xref: /openbsd-src/regress/sys/crypto/aesctr/aesctr.c (revision 49a6e16f2c2c8e509184b1f777366d1a6f337e1c)
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 
29 int debug = 0;
30 
31 enum { TST_KEY, TST_IV, TST_PLAIN, TST_CIPHER, TST_NUM };
32 
33 /* Test vectors from RFC 3686 */
34 struct {
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 
131 u_int32_t deflate_global(u_int8_t *, u_int32_t, int, u_int8_t **);
132 
133 u_int32_t
deflate_global(u_int8_t * data,u_int32_t size,int comp,u_int8_t ** out)134 deflate_global(u_int8_t *data, u_int32_t size, int comp, u_int8_t **out)
135 {
136 	return 0;
137 }
138 
139 void	explicit_bzero(void *, size_t);
140 
141 void
explicit_bzero(void * b,size_t len)142 explicit_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 
153 struct aes_ctr_ctx {
154 	AES_CTX		ac_key;
155 	u_int8_t	ac_block[AESCTR_BLOCKSIZE];
156 };
157 
158 int  aes_ctr_setkey(void *, u_int8_t *, int);
159 void aes_ctr_encrypt(caddr_t, u_int8_t *);
160 void aes_ctr_decrypt(caddr_t, u_int8_t *);
161 void aes_ctr_reinit(caddr_t, u_int8_t *);
162 
163 static int
docrypt(const unsigned char * key,size_t klen,const unsigned char * iv,const unsigned char * in,unsigned char * out,size_t len,int encrypt)164 docrypt(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 
186 static int
match(unsigned char * a,unsigned char * b,size_t len)187 match(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 
206 static int
run(int num)207 run(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);
248 done:
249 	for (i = 0; i < TST_NUM; i++)
250 		free(data[i]);
251 	return (fail);
252 }
253 
254 int
main(int argc,char ** argv)255 main(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