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