Fix issue in 18-dtls-renegotiate.conf.in
[openssl.git] / test / igetest.c
1 /*
2  * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <openssl/crypto.h>
11 #include <openssl/aes.h>
12 #include <openssl/rand.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <assert.h>
16 #include "e_os.h"
17
18 #define TEST_SIZE       128
19 #define BIG_TEST_SIZE 10240
20
21 static void hexdump(FILE *f, const char *title, const unsigned char *s, int l)
22 {
23     int n = 0;
24
25     fprintf(f, "%s", title);
26     for (; n < l; ++n) {
27         if ((n % 16) == 0)
28             fprintf(f, "\n%04x", n);
29         fprintf(f, " %02x", s[n]);
30     }
31     fprintf(f, "\n");
32 }
33
34 #define MAX_VECTOR_SIZE 64
35
36 struct ige_test {
37     const unsigned char key[16];
38     const unsigned char iv[32];
39     const unsigned char in[MAX_VECTOR_SIZE];
40     const unsigned char out[MAX_VECTOR_SIZE];
41     const size_t length;
42     const int encrypt;
43 };
44
45 static struct ige_test const ige_test_vectors[] = {
46     {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
47       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, /* key */
48      {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
49       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
50       0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
51       0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}, /* iv */
52      {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* in */
56      {0x1a, 0x85, 0x19, 0xa6, 0x55, 0x7b, 0xe6, 0x52,
57       0xe9, 0xda, 0x8e, 0x43, 0xda, 0x4e, 0xf4, 0x45,
58       0x3c, 0xf4, 0x56, 0xb4, 0xca, 0x48, 0x8a, 0xa3,
59       0x83, 0xc7, 0x9c, 0x98, 0xb3, 0x47, 0x97, 0xcb}, /* out */
60      32, AES_ENCRYPT},          /* test vector 0 */
61
62     {{0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
63       0x61, 0x6e, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65}, /* key */
64      {0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f,
65       0x6e, 0x20, 0x6f, 0x66, 0x20, 0x49, 0x47, 0x45,
66       0x20, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x6f,
67       0x72, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53}, /* iv */
68      {0x4c, 0x2e, 0x20, 0x4c, 0x65, 0x74, 0x27, 0x73,
69       0x20, 0x68, 0x6f, 0x70, 0x65, 0x20, 0x42, 0x65,
70       0x6e, 0x20, 0x67, 0x6f, 0x74, 0x20, 0x69, 0x74,
71       0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x21, 0x0a}, /* in */
72      {0x99, 0x70, 0x64, 0x87, 0xa1, 0xcd, 0xe6, 0x13,
73       0xbc, 0x6d, 0xe0, 0xb6, 0xf2, 0x4b, 0x1c, 0x7a,
74       0xa4, 0x48, 0xc8, 0xb9, 0xc3, 0x40, 0x3e, 0x34,
75       0x67, 0xa8, 0xca, 0xd8, 0x93, 0x40, 0xf5, 0x3b}, /* out */
76      32, AES_DECRYPT},          /* test vector 1 */
77 };
78
79 struct bi_ige_test {
80     const unsigned char key1[32];
81     const unsigned char key2[32];
82     const unsigned char iv[64];
83     const unsigned char in[MAX_VECTOR_SIZE];
84     const unsigned char out[MAX_VECTOR_SIZE];
85     const size_t keysize;
86     const size_t length;
87     const int encrypt;
88 };
89
90 static struct bi_ige_test const bi_ige_test_vectors[] = {
91     {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
92       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, /* key1 */
93      {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
94       0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}, /* key2 */
95      {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
96       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
97       0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
98       0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
99       0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
100       0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
101       0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
102       0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f}, /* iv */
103      {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* in */
107      {0x14, 0x40, 0x6f, 0xae, 0xa2, 0x79, 0xf2, 0x56,
108       0x1f, 0x86, 0xeb, 0x3b, 0x7d, 0xff, 0x53, 0xdc,
109       0x4e, 0x27, 0x0c, 0x03, 0xde, 0x7c, 0xe5, 0x16,
110       0x6a, 0x9c, 0x20, 0x33, 0x9d, 0x33, 0xfe, 0x12}, /* out */
111      16, 32, AES_ENCRYPT},      /* test vector 0 */
112     {{0x58, 0x0a, 0x06, 0xe9, 0x97, 0x07, 0x59, 0x5c,
113       0x9e, 0x19, 0xd2, 0xa7, 0xbb, 0x40, 0x2b, 0x7a,
114       0xc7, 0xd8, 0x11, 0x9e, 0x4c, 0x51, 0x35, 0x75,
115       0x64, 0x28, 0x0f, 0x23, 0xad, 0x74, 0xac, 0x37}, /* key1 */
116      {0xd1, 0x80, 0xa0, 0x31, 0x47, 0xa3, 0x11, 0x13,
117       0x86, 0x26, 0x9e, 0x6d, 0xff, 0xaf, 0x72, 0x74,
118       0x5b, 0xa2, 0x35, 0x81, 0xd2, 0xa6, 0x3d, 0x21,
119       0x67, 0x7b, 0x58, 0xa8, 0x18, 0xf9, 0x72, 0xe4}, /* key2 */
120      {0x80, 0x3d, 0xbd, 0x4c, 0xe6, 0x7b, 0x06, 0xa9,
121       0x53, 0x35, 0xd5, 0x7e, 0x71, 0xc1, 0x70, 0x70,
122       0x74, 0x9a, 0x00, 0x28, 0x0c, 0xbf, 0x6c, 0x42,
123       0x9b, 0xa4, 0xdd, 0x65, 0x11, 0x77, 0x7c, 0x67,
124       0xfe, 0x76, 0x0a, 0xf0, 0xd5, 0xc6, 0x6e, 0x6a,
125       0xe7, 0x5e, 0x4c, 0xf2, 0x7e, 0x9e, 0xf9, 0x20,
126       0x0e, 0x54, 0x6f, 0x2d, 0x8a, 0x8d, 0x7e, 0xbd,
127       0x48, 0x79, 0x37, 0x99, 0xff, 0x27, 0x93, 0xa3}, /* iv */
128      {0xf1, 0x54, 0x3d, 0xca, 0xfe, 0xb5, 0xef, 0x1c,
129       0x4f, 0xa6, 0x43, 0xf6, 0xe6, 0x48, 0x57, 0xf0,
130       0xee, 0x15, 0x7f, 0xe3, 0xe7, 0x2f, 0xd0, 0x2f,
131       0x11, 0x95, 0x7a, 0x17, 0x00, 0xab, 0xa7, 0x0b,
132       0xbe, 0x44, 0x09, 0x9c, 0xcd, 0xac, 0xa8, 0x52,
133       0xa1, 0x8e, 0x7b, 0x75, 0xbc, 0xa4, 0x92, 0x5a,
134       0xab, 0x46, 0xd3, 0x3a, 0xa0, 0xd5, 0x35, 0x1c,
135       0x55, 0xa4, 0xb3, 0xa8, 0x40, 0x81, 0xa5, 0x0b}, /* in */
136      {0x42, 0xe5, 0x28, 0x30, 0x31, 0xc2, 0xa0, 0x23,
137       0x68, 0x49, 0x4e, 0xb3, 0x24, 0x59, 0x92, 0x79,
138       0xc1, 0xa5, 0xcc, 0xe6, 0x76, 0x53, 0xb1, 0xcf,
139       0x20, 0x86, 0x23, 0xe8, 0x72, 0x55, 0x99, 0x92,
140       0x0d, 0x16, 0x1c, 0x5a, 0x2f, 0xce, 0xcb, 0x51,
141       0xe2, 0x67, 0xfa, 0x10, 0xec, 0xcd, 0x3d, 0x67,
142       0xa5, 0xe6, 0xf7, 0x31, 0x26, 0xb0, 0x0d, 0x76,
143       0x5e, 0x28, 0xdc, 0x7f, 0x01, 0xc5, 0xa5, 0x4c}, /* out */
144      32, 64, AES_ENCRYPT},      /* test vector 1 */
145
146 };
147
148 static int run_test_vectors(void)
149 {
150     unsigned int n;
151     int errs = 0;
152
153     for (n = 0; n < OSSL_NELEM(ige_test_vectors); ++n) {
154         const struct ige_test *const v = &ige_test_vectors[n];
155         AES_KEY key;
156         unsigned char buf[MAX_VECTOR_SIZE];
157         unsigned char iv[AES_BLOCK_SIZE * 2];
158
159         assert(v->length <= MAX_VECTOR_SIZE);
160
161         if (v->encrypt == AES_ENCRYPT)
162             AES_set_encrypt_key(v->key, 8 * sizeof v->key, &key);
163         else
164             AES_set_decrypt_key(v->key, 8 * sizeof v->key, &key);
165         memcpy(iv, v->iv, sizeof iv);
166         AES_ige_encrypt(v->in, buf, v->length, &key, iv, v->encrypt);
167
168         if (memcmp(v->out, buf, v->length)) {
169             printf("IGE test vector %d failed\n", n);
170             hexdump(stdout, "key", v->key, sizeof v->key);
171             hexdump(stdout, "iv", v->iv, sizeof v->iv);
172             hexdump(stdout, "in", v->in, v->length);
173             hexdump(stdout, "expected", v->out, v->length);
174             hexdump(stdout, "got", buf, v->length);
175
176             ++errs;
177         }
178
179         /* try with in == out */
180         memcpy(iv, v->iv, sizeof iv);
181         memcpy(buf, v->in, v->length);
182         AES_ige_encrypt(buf, buf, v->length, &key, iv, v->encrypt);
183
184         if (memcmp(v->out, buf, v->length)) {
185             printf("IGE test vector %d failed (with in == out)\n", n);
186             hexdump(stdout, "key", v->key, sizeof v->key);
187             hexdump(stdout, "iv", v->iv, sizeof v->iv);
188             hexdump(stdout, "in", v->in, v->length);
189             hexdump(stdout, "expected", v->out, v->length);
190             hexdump(stdout, "got", buf, v->length);
191
192             ++errs;
193         }
194     }
195
196     for (n = 0; n < OSSL_NELEM(bi_ige_test_vectors); ++n) {
197         const struct bi_ige_test *const v = &bi_ige_test_vectors[n];
198         AES_KEY key1;
199         AES_KEY key2;
200         unsigned char buf[MAX_VECTOR_SIZE];
201
202         assert(v->length <= MAX_VECTOR_SIZE);
203
204         if (v->encrypt == AES_ENCRYPT) {
205             AES_set_encrypt_key(v->key1, 8 * v->keysize, &key1);
206             AES_set_encrypt_key(v->key2, 8 * v->keysize, &key2);
207         } else {
208             AES_set_decrypt_key(v->key1, 8 * v->keysize, &key1);
209             AES_set_decrypt_key(v->key2, 8 * v->keysize, &key2);
210         }
211
212         AES_bi_ige_encrypt(v->in, buf, v->length, &key1, &key2, v->iv,
213                            v->encrypt);
214
215         if (memcmp(v->out, buf, v->length)) {
216             printf("Bidirectional IGE test vector %d failed\n", n);
217             hexdump(stdout, "key 1", v->key1, sizeof v->key1);
218             hexdump(stdout, "key 2", v->key2, sizeof v->key2);
219             hexdump(stdout, "iv", v->iv, sizeof v->iv);
220             hexdump(stdout, "in", v->in, v->length);
221             hexdump(stdout, "expected", v->out, v->length);
222             hexdump(stdout, "got", buf, v->length);
223
224             ++errs;
225         }
226     }
227
228     return errs;
229 }
230
231 int main(int argc, char **argv)
232 {
233     unsigned char rkey[16];
234     unsigned char rkey2[16];
235     AES_KEY key;
236     AES_KEY key2;
237     unsigned char plaintext[BIG_TEST_SIZE];
238     unsigned char ciphertext[BIG_TEST_SIZE];
239     unsigned char checktext[BIG_TEST_SIZE];
240     unsigned char iv[AES_BLOCK_SIZE * 4];
241     unsigned char saved_iv[AES_BLOCK_SIZE * 4];
242     int err = 0;
243     unsigned int n;
244     unsigned matches;
245
246     assert(BIG_TEST_SIZE >= TEST_SIZE);
247
248     RAND_bytes(rkey, sizeof rkey);
249     RAND_bytes(plaintext, sizeof plaintext);
250     RAND_bytes(iv, sizeof iv);
251     memcpy(saved_iv, iv, sizeof saved_iv);
252
253     /* Forward IGE only... */
254
255     /* Straight encrypt/decrypt */
256     AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
257     AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, iv, AES_ENCRYPT);
258
259     AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
260     memcpy(iv, saved_iv, sizeof iv);
261     AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv, AES_DECRYPT);
262
263     if (memcmp(checktext, plaintext, TEST_SIZE)) {
264         printf("Encrypt+decrypt doesn't match\n");
265         hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
266         hexdump(stdout, "Checktext", checktext, TEST_SIZE);
267         ++err;
268     }
269
270     /* Now check encrypt chaining works */
271     AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
272     memcpy(iv, saved_iv, sizeof iv);
273     AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE / 2, &key, iv,
274                     AES_ENCRYPT);
275     AES_ige_encrypt(plaintext + TEST_SIZE / 2,
276                     ciphertext + TEST_SIZE / 2, TEST_SIZE / 2,
277                     &key, iv, AES_ENCRYPT);
278
279     AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
280     memcpy(iv, saved_iv, sizeof iv);
281     AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv, AES_DECRYPT);
282
283     if (memcmp(checktext, plaintext, TEST_SIZE)) {
284         printf("Chained encrypt+decrypt doesn't match\n");
285         hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
286         hexdump(stdout, "Checktext", checktext, TEST_SIZE);
287         ++err;
288     }
289
290     /* And check decrypt chaining */
291     AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
292     memcpy(iv, saved_iv, sizeof iv);
293     AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE / 2, &key, iv,
294                     AES_ENCRYPT);
295     AES_ige_encrypt(plaintext + TEST_SIZE / 2,
296                     ciphertext + TEST_SIZE / 2, TEST_SIZE / 2,
297                     &key, iv, AES_ENCRYPT);
298
299     AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
300     memcpy(iv, saved_iv, sizeof iv);
301     AES_ige_encrypt(ciphertext, checktext, TEST_SIZE / 2, &key, iv,
302                     AES_DECRYPT);
303     AES_ige_encrypt(ciphertext + TEST_SIZE / 2,
304                     checktext + TEST_SIZE / 2, TEST_SIZE / 2, &key, iv,
305                     AES_DECRYPT);
306
307     if (memcmp(checktext, plaintext, TEST_SIZE)) {
308         printf("Chained encrypt+chained decrypt doesn't match\n");
309         hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
310         hexdump(stdout, "Checktext", checktext, TEST_SIZE);
311         ++err;
312     }
313
314     /* make sure garble extends forwards only */
315     AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
316     memcpy(iv, saved_iv, sizeof iv);
317     AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
318                     AES_ENCRYPT);
319
320     /* corrupt halfway through */
321     ++ciphertext[sizeof ciphertext / 2];
322     AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
323     memcpy(iv, saved_iv, sizeof iv);
324     AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
325                     AES_DECRYPT);
326
327     matches = 0;
328     for (n = 0; n < sizeof checktext; ++n)
329         if (checktext[n] == plaintext[n])
330             ++matches;
331
332     if (matches > sizeof checktext / 2 + sizeof checktext / 100) {
333         printf("More than 51%% matches after garbling\n");
334         ++err;
335     }
336
337     if (matches < sizeof checktext / 2) {
338         printf("Garble extends backwards!\n");
339         ++err;
340     }
341
342     /* Bi-directional IGE */
343
344     /*
345      * Note that we don't have to recover the IV, because chaining isn't
346      */
347     /* possible with biIGE, so the IV is not updated. */
348
349     RAND_bytes(rkey2, sizeof rkey2);
350
351     /* Straight encrypt/decrypt */
352     AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
353     AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
354     AES_bi_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, &key2, iv,
355                        AES_ENCRYPT);
356
357     AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
358     AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
359     AES_bi_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, &key2, iv,
360                        AES_DECRYPT);
361
362     if (memcmp(checktext, plaintext, TEST_SIZE)) {
363         printf("Encrypt+decrypt doesn't match\n");
364         hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
365         hexdump(stdout, "Checktext", checktext, TEST_SIZE);
366         ++err;
367     }
368
369     /* make sure garble extends both ways */
370     AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
371     AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
372     AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
373                     AES_ENCRYPT);
374
375     /* corrupt halfway through */
376     ++ciphertext[sizeof ciphertext / 2];
377     AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
378     AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
379     AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
380                     AES_DECRYPT);
381
382     matches = 0;
383     for (n = 0; n < sizeof checktext; ++n)
384         if (checktext[n] == plaintext[n])
385             ++matches;
386
387     if (matches > sizeof checktext / 100) {
388         printf("More than 1%% matches after bidirectional garbling\n");
389         ++err;
390     }
391
392     /* make sure garble extends both ways (2) */
393     AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
394     AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
395     AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
396                     AES_ENCRYPT);
397
398     /* corrupt right at the end */
399     ++ciphertext[sizeof ciphertext - 1];
400     AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
401     AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
402     AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
403                     AES_DECRYPT);
404
405     matches = 0;
406     for (n = 0; n < sizeof checktext; ++n)
407         if (checktext[n] == plaintext[n])
408             ++matches;
409
410     if (matches > sizeof checktext / 100) {
411         printf("More than 1%% matches after bidirectional garbling (2)\n");
412         ++err;
413     }
414
415     /* make sure garble extends both ways (3) */
416     AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
417     AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
418     AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
419                     AES_ENCRYPT);
420
421     /* corrupt right at the start */
422     ++ciphertext[0];
423     AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
424     AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
425     AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
426                     AES_DECRYPT);
427
428     matches = 0;
429     for (n = 0; n < sizeof checktext; ++n)
430         if (checktext[n] == plaintext[n])
431             ++matches;
432
433     if (matches > sizeof checktext / 100) {
434         printf("More than 1%% matches after bidirectional garbling (3)\n");
435         ++err;
436     }
437
438     err += run_test_vectors();
439
440     return err;
441 }