OpenSSL  1.0.1c
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
igetest.c
Go to the documentation of this file.
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
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 
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  }