1 /*
2 * To be compiled against the AES code from:
3 * https://github.com/BrianGladman/AES
4 */
5 #include <stdio.h>
6 #include <string.h>
7 #include <stdlib.h>
8 #include <unistd.h>
9 #include "aes.h"
10
11 #define B 16U
12 uint8_t key[16] = { 0x46, 0x64, 0x31, 0x29, 0x64, 0x86, 0xED, 0x9C,
13 0xD7, 0x1F, 0xC2, 0x07, 0x25, 0x48, 0x20, 0xA2 };
14 size_t test_case_len[] = { B+1, 2*B-1, 2*B, 2*B+1, 3*B-1, 3*B, 4*B, };
15 #define NTESTS (sizeof(test_case_len) / sizeof(*test_case_len))
16 uint8_t test_case[NTESTS][4 * B] = {
17 { 0xC4, 0xA8, 0x5A, 0xEB, 0x0B, 0x20, 0x41, 0x49,
18 0x4F, 0x8B, 0xF1, 0xF8, 0xCD, 0x30, 0xF1, 0x13,
19 0x94 },
20 { 0x22, 0x3C, 0xF8, 0xA8, 0x29, 0x95, 0x80, 0x49,
21 0x57, 0x87, 0x6E, 0x9F, 0xA7, 0x11, 0x63, 0x50,
22 0x6B, 0x4E, 0x5B, 0x8C, 0x8F, 0xA4, 0xDB, 0x1B,
23 0x95, 0xD3, 0xE8, 0xC5, 0xC5, 0xFB, 0x5A },
24 { 0xE7, 0x37, 0x52, 0x90, 0x60, 0xE7, 0x10, 0xA9,
25 0x3E, 0x97, 0x18, 0xDD, 0x3E, 0x29, 0x41, 0x8E,
26 0x94, 0x8F, 0xE9, 0x20, 0x1F, 0x8D, 0xFB, 0x3A,
27 0x22, 0xCF, 0x22, 0xE8, 0x94, 0x1D, 0x42, 0x7B },
28 { 0x54, 0x94, 0x0B, 0xB4, 0x7C, 0x1B, 0x5E, 0xBA,
29 0xB2, 0x76, 0x98, 0xF1, 0x9F, 0xD9, 0x7F, 0x33,
30 0x68, 0x69, 0x54, 0x87, 0xF6, 0x4F, 0xC1, 0x19,
31 0x1E, 0xE3, 0x01, 0xB2, 0x00, 0x43, 0x2E, 0x54,
32 0xD7 },
33 { 0x39, 0x09, 0x53, 0x55, 0x67, 0x0E, 0x07, 0xDD,
34 0xA6, 0xF8, 0x7C, 0x7F, 0x78, 0xAF, 0xE7, 0xE1,
35 0x03, 0x6F, 0xD7, 0x53, 0x30, 0xF0, 0x71, 0x14,
36 0xF1, 0x24, 0x14, 0x34, 0x52, 0x69, 0x0C, 0x8B,
37 0x72, 0x5F, 0xE0, 0xD9, 0x6D, 0xE8, 0xB6, 0x13,
38 0xE0, 0x32, 0x92, 0x58, 0xE1, 0x7A, 0x39 },
39 { 0xE5, 0xE9, 0x11, 0x38, 0x19, 0x01, 0xA9, 0x2D,
40 0xF3, 0xCD, 0x42, 0x27, 0x1F, 0xAB, 0x33, 0xAB,
41 0x1D, 0x93, 0x8B, 0xF6, 0x00, 0x73, 0xAC, 0x14,
42 0x54, 0xDE, 0xA6, 0xAC, 0xBF, 0x20, 0xE6, 0xA4,
43 0x09, 0xF7, 0xDC, 0x23, 0xF8, 0x86, 0x50, 0xEB,
44 0x53, 0x92, 0x13, 0x73, 0x3D, 0x46, 0x1E, 0x5A },
45 { 0xD9, 0xA9, 0x50, 0xDA, 0x1D, 0xFC, 0xEE, 0x71,
46 0xDA, 0x94, 0x1D, 0x9A, 0xB5, 0x03, 0x3E, 0xBE,
47 0xFA, 0x1B, 0xE1, 0xF3, 0xA1, 0x32, 0xDE, 0xF4,
48 0xC4, 0xF1, 0x67, 0x02, 0x38, 0x85, 0x5C, 0x11,
49 0x2F, 0xAD, 0xEB, 0x4C, 0xA9, 0xD9, 0xBD, 0x84,
50 0x6E, 0xDA, 0x1E, 0x23, 0xDE, 0x5C, 0xE1, 0xD8,
51 0x77, 0xC3, 0xCB, 0x18, 0xF5, 0xAA, 0x0D, 0xB9,
52 0x9B, 0x74, 0xBB, 0xD3, 0xFA, 0x18, 0xE5, 0x29 }
53 };
54 aes_encrypt_ctx ctx;
55 aes_decrypt_ctx dctx;
56
57 static void
init(void)58 init (void)
59 {
60 AES_RETURN r;
61
62 r = aes_encrypt_key128(key, &ctx);
63 if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
64 r = aes_decrypt_key128(key, &dctx);
65 if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
66 }
67
hexdump(const unsigned char * ptr,size_t len)68 static void hexdump(const unsigned char *ptr, size_t len)
69 {
70 size_t i;
71 for (i = 0; i < len; i++)
72 printf ("%s%02X", (i % 16 == 0) ? "\n " : " ", ptr[i]);
73 }
74
75 static void
fips_test(void)76 fips_test (void)
77 {
78 static const unsigned char fipskey[16] = {
79 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
80 };
81 static const unsigned char input[16] = {
82 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
83 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
84 };
85 static const unsigned char expected[16] = {
86 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
87 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a,
88 };
89 unsigned char output[16];
90 unsigned char tmp[16];
91 aes_crypt_ctx fipsctx;
92 int r;
93
94 printf ("FIPS test:\nkey:");
95 hexdump (fipskey, 16);
96 printf ("\ninput:");
97 hexdump (input, 16);
98 r = aes_encrypt_key128(fipskey, &fipsctx);
99 if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
100 r = aes_encrypt(input, output, &fipsctx);
101 if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
102 printf ("\noutput:");
103 hexdump (output, 16);
104 printf ("\n");
105 if (memcmp(expected, output, 16))
106 fprintf(stderr, "wrong results!!!\n"), exit (1);
107 r = aes_decrypt_key128(fipskey, &fipsctx);
108 if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
109 r = aes_decrypt(output, tmp, &fipsctx);
110 if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
111 if (memcmp(input, tmp, 16))
112 fprintf(stderr, "decryption failed!!\n"), exit(1);
113 printf ("ok.\n\n");
114 }
115
116 static void
xor(unsigned char * out,const unsigned char * a,const unsigned char * b)117 xor (unsigned char *out, const unsigned char *a, const unsigned char *b)
118 {
119 unsigned int i;
120 for (i = 0; i < B; i++)
121 out[i] = a[i] ^ b[i];
122 }
123
124 static void
ecb_enc(unsigned char * out,unsigned char * in,unsigned int len)125 ecb_enc (unsigned char *out, unsigned char *in, unsigned int len)
126 {
127 unsigned int i, r;
128 for (i = 0; i < len; i += 16) {
129 r = aes_encrypt(in + i, out + i, &ctx);
130 if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
131 }
132 if (i != len) abort ();
133 }
134
135 static void
ecb_dec(unsigned char * out,unsigned char * in,unsigned int len)136 ecb_dec (unsigned char *out, unsigned char *in, unsigned int len)
137 {
138 unsigned int i, r;
139 for (i = 0; i < len; i += 16) {
140 r = aes_decrypt(in + i, out + i, &dctx);
141 if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
142 }
143 if (i != len) abort ();
144 }
145
146 #define D(X) (printf("%s %d: %s=",__FUNCTION__,__LINE__, #X),hexdump(X,B),printf("\n"))
147
148 #undef D
149 #define D(X)
150
151 static void
cbc_enc(unsigned char * out,unsigned char * in,unsigned char * iv,unsigned int len)152 cbc_enc (unsigned char *out, unsigned char *in, unsigned char *iv,
153 unsigned int len)
154 {
155 unsigned int i, r;
156 unsigned char tmp[B];
157 D(iv);
158 memcpy (tmp, iv, B);
159 for (i = 0; i < len; i += B) {
160 D(in+i);
161 xor (tmp, tmp, in + i);
162 D(tmp);
163 r = aes_encrypt(tmp, out + i, &ctx);
164 if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
165 memcpy (tmp, out + i, B);
166 D(out+i);
167 }
168 if (i != len) abort ();
169 }
170
171 static void
cbc_dec(unsigned char * out,unsigned char * in,unsigned char * iv,unsigned int len)172 cbc_dec (unsigned char *out, unsigned char *in, unsigned char *iv,
173 unsigned int len)
174 {
175 unsigned int i, r;
176 unsigned char tmp[B];
177 memcpy (tmp, iv, B);
178 for (i = 0; i < len; i += B) {
179 r = aes_decrypt(in + i, tmp, &dctx);
180 if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
181 xor (tmp, tmp, iv);
182 iv = in + i;
183 memcpy (out + i, tmp, B);
184 }
185 if (i != len) abort ();
186 }
187
188 static void
cts_enc(unsigned char * out,unsigned char * in,unsigned char * iv,unsigned int len)189 cts_enc (unsigned char *out, unsigned char *in, unsigned char *iv,
190 unsigned int len)
191 {
192 int r;
193 unsigned int len2;
194 unsigned char pn1[B], pn[B], cn[B], cn1[B];
195
196 if (len < B + 1) abort ();
197 len2 = (len - B - 1) & ~(B-1);
198 cbc_enc (out, in, iv, len2);
199 out += len2;
200 in += len2;
201 len -= len2;
202 if (len2)
203 iv = out - B;
204 if (len <= B || len > 2 * B)
205 abort ();
206 printf ("(did CBC mode for %d)\n", len2);
207
208 D(in);
209 xor (pn1, in, iv);
210 D(pn1);
211 r = aes_encrypt(pn1, cn, &ctx);
212 if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
213 D(cn);
214 memset (pn, 0, sizeof(pn));
215 memcpy (pn, in+B, len-B);
216 D(pn);
217 xor (pn, pn, cn);
218 D(pn);
219 r = aes_encrypt(pn, cn1, &ctx);
220 if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
221 D(cn1);
222 memcpy(out, cn1, B);
223 memcpy(out+B, cn, len-B);
224 }
225
226 static void
cts_dec(unsigned char * out,unsigned char * in,unsigned char * iv,unsigned int len)227 cts_dec (unsigned char *out, unsigned char *in, unsigned char *iv,
228 unsigned int len)
229 {
230 int r;
231 unsigned int len2;
232 unsigned char pn1[B], pn[B], cn[B], cn1[B];
233
234 if (len < B + 1) abort ();
235 len2 = (len - B - 1) & ~(B-1);
236 cbc_dec (out, in, iv, len2);
237 out += len2;
238 in += len2;
239 len -= len2;
240 if (len2)
241 iv = in - B;
242 if (len <= B || len > 2 * B)
243 abort ();
244
245 memcpy (cn1, in, B);
246 r = aes_decrypt(cn1, pn, &dctx);
247 if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
248 memset (cn, 0, sizeof(cn));
249 memcpy (cn, in+B, len-B);
250 xor (pn, pn, cn);
251 memcpy (cn+len-B, pn+len-B, 2*B-len);
252 r = aes_decrypt(cn, pn1, &dctx);
253 if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
254 xor (pn1, pn1, iv);
255 memcpy(out, pn1, B);
256 memcpy(out+B, pn, len-B);
257 }
258
259 static void
ecb_test(void)260 ecb_test (void)
261 {
262 unsigned int testno;
263 uint8_t output[4 * B], tmp[4 * B];
264
265 printf ("ECB tests:\n");
266 printf ("key:");
267 hexdump (key, sizeof(key));
268 for (testno = 0; testno < NTESTS; testno++) {
269 unsigned len = (test_case_len[testno] + 15) & ~15;
270 printf ("\ntest %d - %d bytes\n", testno, len);
271 printf ("input:");
272 hexdump (test_case[testno], len);
273 printf ("\n");
274 ecb_enc (output, test_case[testno], len);
275 printf ("output:");
276 hexdump (output, len);
277 printf ("\n");
278 ecb_dec (tmp, output, len);
279 if (memcmp (tmp, test_case[testno], len)) {
280 printf ("ecb decrypt failed!!");
281 hexdump (tmp, len);
282 printf ("\n");
283 exit (1);
284 }
285 }
286 printf ("\n");
287 }
288
289 unsigned char ivec[16] = { 0 };
290
291 static void
cbc_test(void)292 cbc_test (void)
293 {
294 unsigned int testno;
295 uint8_t output[4 * B], tmp[4 * B];
296
297 printf ("CBC tests:\n");
298 printf ("initial vector:");
299 hexdump (ivec, sizeof(ivec));
300 for (testno = 0; testno < NTESTS; testno++) {
301 unsigned len = (test_case_len[testno] + 15) & ~15;
302 printf ("\ntest %d - %d bytes\n", testno, len);
303 printf ("input:");
304 hexdump (test_case[testno], len);
305 printf ("\n");
306 cbc_enc (output, test_case[testno], ivec, len);
307 printf ("output:");
308 hexdump (output, len);
309 printf ("\n");
310 cbc_dec (tmp, output, ivec, len);
311 if (memcmp (tmp, test_case[testno], len)) {
312 printf("cbc decrypt failed!!");
313 hexdump (tmp, len);
314 printf ("\n");
315 exit(1);
316 }
317 }
318 printf ("\n");
319 }
320
321 static void
cts_test(void)322 cts_test (void)
323 {
324 unsigned int testno;
325 uint8_t output[4 * B], tmp[4 * B];
326
327 printf ("CTS tests:\n");
328 printf ("initial vector:");
329 hexdump (ivec, sizeof(ivec));
330 for (testno = 0; testno < NTESTS; testno++) {
331 unsigned int len = test_case_len[testno];
332 printf ("\ntest %d - %d bytes\n", testno, len);
333 printf ("input:");
334 hexdump (test_case[testno], len);
335 printf ("\n");
336 cts_enc (output, test_case[testno], ivec, len);
337 printf ("output:");
338 hexdump (output, len);
339 printf ("\n");
340 cts_dec (tmp, output, ivec, len);
341 if (memcmp (tmp, test_case[testno], len))
342 fprintf (stderr, "cts decrypt failed!!\n"), exit(1);
343 }
344 printf ("\n");
345 }
346
347 int
main(void)348 main (void)
349 {
350 init ();
351 fips_test ();
352
353 ecb_test();
354 cbc_test();
355 cts_test();
356
357 return 0;
358 }
359