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