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