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