Run util/openssl-format-source -v -c .
[openssl.git] / test / igetest.c
1 /* test/igetest.c -*- mode:C; c-file-style: "eay" -*- */
2 /* ====================================================================
3  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in
14  *    the documentation and/or other materials provided with the
15  *    distribution.
16  *
17  * 3. All advertising materials mentioning features or use of this
18  *    software must display the following acknowledgment:
19  *    "This product includes software developed by the OpenSSL Project
20  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21  *
22  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23  *    endorse or promote products derived from this software without
24  *    prior written permission. For written permission, please contact
25  *    openssl-core@openssl.org.
26  *
27  * 5. Products derived from this software may not be called "OpenSSL"
28  *    nor may "OpenSSL" appear in their names without prior written
29  *    permission of the OpenSSL Project.
30  *
31  * 6. Redistributions of any form whatsoever must retain the following
32  *    acknowledgment:
33  *    "This product includes software developed by the OpenSSL Project
34  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35  *
36  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47  * OF THE POSSIBILITY OF SUCH DAMAGE.
48  * ====================================================================
49  *
50  */
51
52 #include <openssl/aes.h>
53 #include <openssl/rand.h>
54 #include <stdio.h>
55 #include <string.h>
56 #include <assert.h>
57
58 #define TEST_SIZE       128
59 #define BIG_TEST_SIZE 10240
60
61 static void hexdump(FILE *f, const char *title, const unsigned char *s, int l)
62 {
63     int n = 0;
64
65     fprintf(f, "%s", title);
66     for (; n < l; ++n) {
67         if ((n % 16) == 0)
68             fprintf(f, "\n%04x", n);
69         fprintf(f, " %02x", s[n]);
70     }
71     fprintf(f, "\n");
72 }
73
74 #define MAX_VECTOR_SIZE 64
75
76 struct ige_test {
77     const unsigned char key[16];
78     const unsigned char iv[32];
79     const unsigned char in[MAX_VECTOR_SIZE];
80     const unsigned char out[MAX_VECTOR_SIZE];
81     const size_t length;
82     const int encrypt;
83 };
84
85 static struct ige_test const ige_test_vectors[] = {
86     {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
87       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, /* key */
88      {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
89       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
90       0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
91       0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}, /* iv */
92      {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* in */
96      {0x1a, 0x85, 0x19, 0xa6, 0x55, 0x7b, 0xe6, 0x52,
97       0xe9, 0xda, 0x8e, 0x43, 0xda, 0x4e, 0xf4, 0x45,
98       0x3c, 0xf4, 0x56, 0xb4, 0xca, 0x48, 0x8a, 0xa3,
99       0x83, 0xc7, 0x9c, 0x98, 0xb3, 0x47, 0x97, 0xcb}, /* out */
100      32, AES_ENCRYPT},          /* test vector 0 */
101
102     {{0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
103       0x61, 0x6e, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65}, /* key */
104      {0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f,
105       0x6e, 0x20, 0x6f, 0x66, 0x20, 0x49, 0x47, 0x45,
106       0x20, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x6f,
107       0x72, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53}, /* iv */
108      {0x4c, 0x2e, 0x20, 0x4c, 0x65, 0x74, 0x27, 0x73,
109       0x20, 0x68, 0x6f, 0x70, 0x65, 0x20, 0x42, 0x65,
110       0x6e, 0x20, 0x67, 0x6f, 0x74, 0x20, 0x69, 0x74,
111       0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x21, 0x0a}, /* in */
112      {0x99, 0x70, 0x64, 0x87, 0xa1, 0xcd, 0xe6, 0x13,
113       0xbc, 0x6d, 0xe0, 0xb6, 0xf2, 0x4b, 0x1c, 0x7a,
114       0xa4, 0x48, 0xc8, 0xb9, 0xc3, 0x40, 0x3e, 0x34,
115       0x67, 0xa8, 0xca, 0xd8, 0x93, 0x40, 0xf5, 0x3b}, /* out */
116      32, AES_DECRYPT},          /* test vector 1 */
117 };
118
119 struct bi_ige_test {
120     const unsigned char key1[32];
121     const unsigned char key2[32];
122     const unsigned char iv[64];
123     const unsigned char in[MAX_VECTOR_SIZE];
124     const unsigned char out[MAX_VECTOR_SIZE];
125     const size_t keysize;
126     const size_t length;
127     const int encrypt;
128 };
129
130 static struct bi_ige_test const bi_ige_test_vectors[] = {
131     {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
132       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, /* key1 */
133      {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
134       0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}, /* key2 */
135      {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
136       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
137       0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
138       0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
139       0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
140       0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
141       0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
142       0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f}, /* iv */
143      {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* in */
147      {0x14, 0x40, 0x6f, 0xae, 0xa2, 0x79, 0xf2, 0x56,
148       0x1f, 0x86, 0xeb, 0x3b, 0x7d, 0xff, 0x53, 0xdc,
149       0x4e, 0x27, 0x0c, 0x03, 0xde, 0x7c, 0xe5, 0x16,
150       0x6a, 0x9c, 0x20, 0x33, 0x9d, 0x33, 0xfe, 0x12}, /* out */
151      16, 32, AES_ENCRYPT},      /* test vector 0 */
152     {{0x58, 0x0a, 0x06, 0xe9, 0x97, 0x07, 0x59, 0x5c,
153       0x9e, 0x19, 0xd2, 0xa7, 0xbb, 0x40, 0x2b, 0x7a,
154       0xc7, 0xd8, 0x11, 0x9e, 0x4c, 0x51, 0x35, 0x75,
155       0x64, 0x28, 0x0f, 0x23, 0xad, 0x74, 0xac, 0x37}, /* key1 */
156      {0xd1, 0x80, 0xa0, 0x31, 0x47, 0xa3, 0x11, 0x13,
157       0x86, 0x26, 0x9e, 0x6d, 0xff, 0xaf, 0x72, 0x74,
158       0x5b, 0xa2, 0x35, 0x81, 0xd2, 0xa6, 0x3d, 0x21,
159       0x67, 0x7b, 0x58, 0xa8, 0x18, 0xf9, 0x72, 0xe4}, /* key2 */
160      {0x80, 0x3d, 0xbd, 0x4c, 0xe6, 0x7b, 0x06, 0xa9,
161       0x53, 0x35, 0xd5, 0x7e, 0x71, 0xc1, 0x70, 0x70,
162       0x74, 0x9a, 0x00, 0x28, 0x0c, 0xbf, 0x6c, 0x42,
163       0x9b, 0xa4, 0xdd, 0x65, 0x11, 0x77, 0x7c, 0x67,
164       0xfe, 0x76, 0x0a, 0xf0, 0xd5, 0xc6, 0x6e, 0x6a,
165       0xe7, 0x5e, 0x4c, 0xf2, 0x7e, 0x9e, 0xf9, 0x20,
166       0x0e, 0x54, 0x6f, 0x2d, 0x8a, 0x8d, 0x7e, 0xbd,
167       0x48, 0x79, 0x37, 0x99, 0xff, 0x27, 0x93, 0xa3}, /* iv */
168      {0xf1, 0x54, 0x3d, 0xca, 0xfe, 0xb5, 0xef, 0x1c,
169       0x4f, 0xa6, 0x43, 0xf6, 0xe6, 0x48, 0x57, 0xf0,
170       0xee, 0x15, 0x7f, 0xe3, 0xe7, 0x2f, 0xd0, 0x2f,
171       0x11, 0x95, 0x7a, 0x17, 0x00, 0xab, 0xa7, 0x0b,
172       0xbe, 0x44, 0x09, 0x9c, 0xcd, 0xac, 0xa8, 0x52,
173       0xa1, 0x8e, 0x7b, 0x75, 0xbc, 0xa4, 0x92, 0x5a,
174       0xab, 0x46, 0xd3, 0x3a, 0xa0, 0xd5, 0x35, 0x1c,
175       0x55, 0xa4, 0xb3, 0xa8, 0x40, 0x81, 0xa5, 0x0b}, /* in */
176      {0x42, 0xe5, 0x28, 0x30, 0x31, 0xc2, 0xa0, 0x23,
177       0x68, 0x49, 0x4e, 0xb3, 0x24, 0x59, 0x92, 0x79,
178       0xc1, 0xa5, 0xcc, 0xe6, 0x76, 0x53, 0xb1, 0xcf,
179       0x20, 0x86, 0x23, 0xe8, 0x72, 0x55, 0x99, 0x92,
180       0x0d, 0x16, 0x1c, 0x5a, 0x2f, 0xce, 0xcb, 0x51,
181       0xe2, 0x67, 0xfa, 0x10, 0xec, 0xcd, 0x3d, 0x67,
182       0xa5, 0xe6, 0xf7, 0x31, 0x26, 0xb0, 0x0d, 0x76,
183       0x5e, 0x28, 0xdc, 0x7f, 0x01, 0xc5, 0xa5, 0x4c}, /* out */
184      32, 64, AES_ENCRYPT},      /* test vector 1 */
185
186 };
187
188 static int run_test_vectors(void)
189 {
190     unsigned int n;
191     int errs = 0;
192
193     for (n = 0; n < sizeof(ige_test_vectors) / sizeof(ige_test_vectors[0]);
194          ++n) {
195         const struct ige_test *const v = &ige_test_vectors[n];
196         AES_KEY key;
197         unsigned char buf[MAX_VECTOR_SIZE];
198         unsigned char iv[AES_BLOCK_SIZE * 2];
199
200         assert(v->length <= MAX_VECTOR_SIZE);
201
202         if (v->encrypt == AES_ENCRYPT)
203             AES_set_encrypt_key(v->key, 8 * sizeof v->key, &key);
204         else
205             AES_set_decrypt_key(v->key, 8 * sizeof v->key, &key);
206         memcpy(iv, v->iv, sizeof iv);
207         AES_ige_encrypt(v->in, buf, v->length, &key, iv, v->encrypt);
208
209         if (memcmp(v->out, buf, v->length)) {
210             printf("IGE test vector %d failed\n", n);
211             hexdump(stdout, "key", v->key, sizeof v->key);
212             hexdump(stdout, "iv", v->iv, sizeof v->iv);
213             hexdump(stdout, "in", v->in, v->length);
214             hexdump(stdout, "expected", v->out, v->length);
215             hexdump(stdout, "got", buf, v->length);
216
217             ++errs;
218         }
219
220         /* try with in == out */
221         memcpy(iv, v->iv, sizeof iv);
222         memcpy(buf, v->in, v->length);
223         AES_ige_encrypt(buf, buf, v->length, &key, iv, v->encrypt);
224
225         if (memcmp(v->out, buf, v->length)) {
226             printf("IGE test vector %d failed (with in == out)\n", n);
227             hexdump(stdout, "key", v->key, sizeof v->key);
228             hexdump(stdout, "iv", v->iv, sizeof v->iv);
229             hexdump(stdout, "in", v->in, v->length);
230             hexdump(stdout, "expected", v->out, v->length);
231             hexdump(stdout, "got", buf, v->length);
232
233             ++errs;
234         }
235     }
236
237     for (n = 0;
238          n < sizeof(bi_ige_test_vectors) / sizeof(bi_ige_test_vectors[0]);
239          ++n) {
240         const struct bi_ige_test *const v = &bi_ige_test_vectors[n];
241         AES_KEY key1;
242         AES_KEY key2;
243         unsigned char buf[MAX_VECTOR_SIZE];
244
245         assert(v->length <= MAX_VECTOR_SIZE);
246
247         if (v->encrypt == AES_ENCRYPT) {
248             AES_set_encrypt_key(v->key1, 8 * v->keysize, &key1);
249             AES_set_encrypt_key(v->key2, 8 * v->keysize, &key2);
250         } else {
251             AES_set_decrypt_key(v->key1, 8 * v->keysize, &key1);
252             AES_set_decrypt_key(v->key2, 8 * v->keysize, &key2);
253         }
254
255         AES_bi_ige_encrypt(v->in, buf, v->length, &key1, &key2, v->iv,
256                            v->encrypt);
257
258         if (memcmp(v->out, buf, v->length)) {
259             printf("Bidirectional IGE test vector %d failed\n", n);
260             hexdump(stdout, "key 1", v->key1, sizeof v->key1);
261             hexdump(stdout, "key 2", v->key2, sizeof v->key2);
262             hexdump(stdout, "iv", v->iv, sizeof v->iv);
263             hexdump(stdout, "in", v->in, v->length);
264             hexdump(stdout, "expected", v->out, v->length);
265             hexdump(stdout, "got", buf, v->length);
266
267             ++errs;
268         }
269     }
270
271     return errs;
272 }
273
274 int main(int argc, char **argv)
275 {
276     unsigned char rkey[16];
277     unsigned char rkey2[16];
278     AES_KEY key;
279     AES_KEY key2;
280     unsigned char plaintext[BIG_TEST_SIZE];
281     unsigned char ciphertext[BIG_TEST_SIZE];
282     unsigned char checktext[BIG_TEST_SIZE];
283     unsigned char iv[AES_BLOCK_SIZE * 4];
284     unsigned char saved_iv[AES_BLOCK_SIZE * 4];
285     int err = 0;
286     unsigned int n;
287     unsigned matches;
288
289     assert(BIG_TEST_SIZE >= TEST_SIZE);
290
291     RAND_pseudo_bytes(rkey, sizeof rkey);
292     RAND_pseudo_bytes(plaintext, sizeof plaintext);
293     RAND_pseudo_bytes(iv, sizeof iv);
294     memcpy(saved_iv, iv, sizeof saved_iv);
295
296     /* Forward IGE only... */
297
298     /* Straight encrypt/decrypt */
299     AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
300     AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, iv, AES_ENCRYPT);
301
302     AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
303     memcpy(iv, saved_iv, sizeof iv);
304     AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv, AES_DECRYPT);
305
306     if (memcmp(checktext, plaintext, TEST_SIZE)) {
307         printf("Encrypt+decrypt doesn't match\n");
308         hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
309         hexdump(stdout, "Checktext", checktext, TEST_SIZE);
310         ++err;
311     }
312
313     /* Now check encrypt chaining works */
314     AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
315     memcpy(iv, saved_iv, sizeof iv);
316     AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE / 2, &key, iv,
317                     AES_ENCRYPT);
318     AES_ige_encrypt(plaintext + TEST_SIZE / 2,
319                     ciphertext + TEST_SIZE / 2, TEST_SIZE / 2,
320                     &key, iv, AES_ENCRYPT);
321
322     AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
323     memcpy(iv, saved_iv, sizeof iv);
324     AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv, AES_DECRYPT);
325
326     if (memcmp(checktext, plaintext, TEST_SIZE)) {
327         printf("Chained encrypt+decrypt doesn't match\n");
328         hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
329         hexdump(stdout, "Checktext", checktext, TEST_SIZE);
330         ++err;
331     }
332
333     /* And check decrypt chaining */
334     AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
335     memcpy(iv, saved_iv, sizeof iv);
336     AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE / 2, &key, iv,
337                     AES_ENCRYPT);
338     AES_ige_encrypt(plaintext + TEST_SIZE / 2,
339                     ciphertext + TEST_SIZE / 2, TEST_SIZE / 2,
340                     &key, iv, AES_ENCRYPT);
341
342     AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
343     memcpy(iv, saved_iv, sizeof iv);
344     AES_ige_encrypt(ciphertext, checktext, TEST_SIZE / 2, &key, iv,
345                     AES_DECRYPT);
346     AES_ige_encrypt(ciphertext + TEST_SIZE / 2,
347                     checktext + TEST_SIZE / 2, TEST_SIZE / 2, &key, iv,
348                     AES_DECRYPT);
349
350     if (memcmp(checktext, plaintext, TEST_SIZE)) {
351         printf("Chained encrypt+chained decrypt doesn't match\n");
352         hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
353         hexdump(stdout, "Checktext", checktext, TEST_SIZE);
354         ++err;
355     }
356
357     /* make sure garble extends forwards only */
358     AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
359     memcpy(iv, saved_iv, sizeof iv);
360     AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
361                     AES_ENCRYPT);
362
363     /* corrupt halfway through */
364     ++ciphertext[sizeof ciphertext / 2];
365     AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
366     memcpy(iv, saved_iv, sizeof iv);
367     AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
368                     AES_DECRYPT);
369
370     matches = 0;
371     for (n = 0; n < sizeof checktext; ++n)
372         if (checktext[n] == plaintext[n])
373             ++matches;
374
375     if (matches > sizeof checktext / 2 + sizeof checktext / 100) {
376         printf("More than 51%% matches after garbling\n");
377         ++err;
378     }
379
380     if (matches < sizeof checktext / 2) {
381         printf("Garble extends backwards!\n");
382         ++err;
383     }
384
385     /* Bi-directional IGE */
386
387     /*
388      * Note that we don't have to recover the IV, because chaining isn't
389      */
390     /* possible with biIGE, so the IV is not updated. */
391
392     RAND_pseudo_bytes(rkey2, sizeof rkey2);
393
394     /* Straight encrypt/decrypt */
395     AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
396     AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
397     AES_bi_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, &key2, iv,
398                        AES_ENCRYPT);
399
400     AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
401     AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
402     AES_bi_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, &key2, iv,
403                        AES_DECRYPT);
404
405     if (memcmp(checktext, plaintext, TEST_SIZE)) {
406         printf("Encrypt+decrypt doesn't match\n");
407         hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
408         hexdump(stdout, "Checktext", checktext, TEST_SIZE);
409         ++err;
410     }
411
412     /* make sure garble extends both ways */
413     AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
414     AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
415     AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
416                     AES_ENCRYPT);
417
418     /* corrupt halfway through */
419     ++ciphertext[sizeof ciphertext / 2];
420     AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
421     AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
422     AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
423                     AES_DECRYPT);
424
425     matches = 0;
426     for (n = 0; n < sizeof checktext; ++n)
427         if (checktext[n] == plaintext[n])
428             ++matches;
429
430     if (matches > sizeof checktext / 100) {
431         printf("More than 1%% matches after bidirectional garbling\n");
432         ++err;
433     }
434
435     /* make sure garble extends both ways (2) */
436     AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
437     AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
438     AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
439                     AES_ENCRYPT);
440
441     /* corrupt right at the end */
442     ++ciphertext[sizeof ciphertext - 1];
443     AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
444     AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
445     AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
446                     AES_DECRYPT);
447
448     matches = 0;
449     for (n = 0; n < sizeof checktext; ++n)
450         if (checktext[n] == plaintext[n])
451             ++matches;
452
453     if (matches > sizeof checktext / 100) {
454         printf("More than 1%% matches after bidirectional garbling (2)\n");
455         ++err;
456     }
457
458     /* make sure garble extends both ways (3) */
459     AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
460     AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
461     AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
462                     AES_ENCRYPT);
463
464     /* corrupt right at the start */
465     ++ciphertext[0];
466     AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
467     AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
468     AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
469                     AES_DECRYPT);
470
471     matches = 0;
472     for (n = 0; n < sizeof checktext; ++n)
473         if (checktext[n] == plaintext[n])
474             ++matches;
475
476     if (matches > sizeof checktext / 100) {
477         printf("More than 1%% matches after bidirectional garbling (3)\n");
478         ++err;
479     }
480
481     err += run_test_vectors();
482
483     return err;
484 }