1 /* test/igetest.c -*- mode:C; c-file-style: "eay" -*- */
2 /* ====================================================================
3 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
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
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/)"
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.
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.
31 * 6. Redistributions of any form whatsoever must retain the following
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
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 * ====================================================================
52 #include <openssl/crypto.h>
53 #include <openssl/aes.h>
54 #include <openssl/rand.h>
60 #define BIG_TEST_SIZE 10240
62 static void hexdump(FILE *f,const char *title,const unsigned char *s,int l)
66 fprintf(f,"%s",title);
70 fprintf(f,"\n%04x",n);
71 fprintf(f," %02x",s[n]);
76 #define MAX_VECTOR_SIZE 64
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];
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 */
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 */
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;
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 */
192 static int run_test_vectors(void)
197 for(n=0 ; n < sizeof(ige_test_vectors)/sizeof(ige_test_vectors[0]) ; ++n)
199 const struct ige_test * const v = &ige_test_vectors[n];
201 unsigned char buf[MAX_VECTOR_SIZE];
202 unsigned char iv[AES_BLOCK_SIZE*2];
204 assert(v->length <= MAX_VECTOR_SIZE);
206 if(v->encrypt == AES_ENCRYPT)
207 AES_set_encrypt_key(v->key, 8*sizeof v->key, &key);
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);
213 if(memcmp(v->out, buf, v->length))
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);
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);
230 if(memcmp(v->out, buf, v->length))
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);
243 for(n=0 ; n < sizeof(bi_ige_test_vectors)/sizeof(bi_ige_test_vectors[0])
246 const struct bi_ige_test * const v = &bi_ige_test_vectors[n];
249 unsigned char buf[MAX_VECTOR_SIZE];
251 assert(v->length <= MAX_VECTOR_SIZE);
253 if(v->encrypt == AES_ENCRYPT)
255 AES_set_encrypt_key(v->key1, 8*v->keysize, &key1);
256 AES_set_encrypt_key(v->key2, 8*v->keysize, &key2);
260 AES_set_decrypt_key(v->key1, 8*v->keysize, &key1);
261 AES_set_decrypt_key(v->key2, 8*v->keysize, &key2);
264 AES_bi_ige_encrypt(v->in, buf, v->length, &key1, &key2, v->iv,
267 if(memcmp(v->out, buf, v->length))
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);
284 int main(int argc, char **argv)
286 unsigned char rkey[16];
287 unsigned char rkey2[16];
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];
299 assert(BIG_TEST_SIZE >= TEST_SIZE);
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);
306 /* Forward IGE only... */
308 /* Straight encrypt/decrypt */
309 AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
310 AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, iv,
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,
318 if(memcmp(checktext, plaintext, TEST_SIZE))
320 printf("Encrypt+decrypt doesn't match\n");
321 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
322 hexdump(stdout, "Checktext", checktext, TEST_SIZE);
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,
331 AES_ige_encrypt(plaintext+TEST_SIZE/2,
332 ciphertext+TEST_SIZE/2, TEST_SIZE/2,
333 &key, iv, AES_ENCRYPT);
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,
340 if(memcmp(checktext, plaintext, TEST_SIZE))
342 printf("Chained encrypt+decrypt doesn't match\n");
343 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
344 hexdump(stdout, "Checktext", checktext, TEST_SIZE);
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,
353 AES_ige_encrypt(plaintext+TEST_SIZE/2,
354 ciphertext+TEST_SIZE/2, TEST_SIZE/2,
355 &key, iv, AES_ENCRYPT);
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,
361 AES_ige_encrypt(ciphertext+TEST_SIZE/2,
362 checktext+TEST_SIZE/2, TEST_SIZE/2, &key, iv,
365 if(memcmp(checktext, plaintext, TEST_SIZE))
367 printf("Chained encrypt+chained decrypt doesn't match\n");
368 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
369 hexdump(stdout, "Checktext", checktext, TEST_SIZE);
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,
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,
387 for(n=0 ; n < sizeof checktext ; ++n)
388 if(checktext[n] == plaintext[n])
391 if(matches > sizeof checktext/2+sizeof checktext/100)
393 printf("More than 51%% matches after garbling\n");
397 if(matches < sizeof checktext/2)
399 printf("Garble extends backwards!\n");
403 /* Bi-directional IGE */
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. */
408 RAND_pseudo_bytes(rkey2, sizeof rkey2);
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,
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,
421 if(memcmp(checktext, plaintext, TEST_SIZE))
423 printf("Encrypt+decrypt doesn't match\n");
424 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
425 hexdump(stdout, "Checktext", checktext, TEST_SIZE);
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,
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,
443 for(n=0 ; n < sizeof checktext ; ++n)
444 if(checktext[n] == plaintext[n])
447 if(matches > sizeof checktext/100)
449 printf("More than 1%% matches after bidirectional garbling\n");
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,
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,
467 for(n=0 ; n < sizeof checktext ; ++n)
468 if(checktext[n] == plaintext[n])
471 if(matches > sizeof checktext/100)
473 printf("More than 1%% matches after bidirectional garbling (2)\n");
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,
483 /* corrupt right at the start */
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,
491 for(n=0 ; n < sizeof checktext ; ++n)
492 if(checktext[n] == plaintext[n])
495 if(matches > sizeof checktext/100)
497 printf("More than 1%% matches after bidirectional garbling (3)\n");
501 err += run_test_vectors();