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);
69 fprintf(f, "\n%04x", n);
70 fprintf(f, " %02x", s[n]);
75 #define MAX_VECTOR_SIZE 64
78 const unsigned char key[16];
79 const unsigned char iv[32];
80 const unsigned char in[MAX_VECTOR_SIZE];
81 const unsigned char out[MAX_VECTOR_SIZE];
86 static struct ige_test const ige_test_vectors[] = {
87 {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
88 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, /* key */
89 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
90 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
91 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
92 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}, /* iv */
93 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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}, /* in */
97 {0x1a, 0x85, 0x19, 0xa6, 0x55, 0x7b, 0xe6, 0x52,
98 0xe9, 0xda, 0x8e, 0x43, 0xda, 0x4e, 0xf4, 0x45,
99 0x3c, 0xf4, 0x56, 0xb4, 0xca, 0x48, 0x8a, 0xa3,
100 0x83, 0xc7, 0x9c, 0x98, 0xb3, 0x47, 0x97, 0xcb}, /* out */
101 32, AES_ENCRYPT}, /* test vector 0 */
103 {{0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
104 0x61, 0x6e, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65}, /* key */
105 {0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f,
106 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x49, 0x47, 0x45,
107 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x6f,
108 0x72, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53}, /* iv */
109 {0x4c, 0x2e, 0x20, 0x4c, 0x65, 0x74, 0x27, 0x73,
110 0x20, 0x68, 0x6f, 0x70, 0x65, 0x20, 0x42, 0x65,
111 0x6e, 0x20, 0x67, 0x6f, 0x74, 0x20, 0x69, 0x74,
112 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x21, 0x0a}, /* in */
113 {0x99, 0x70, 0x64, 0x87, 0xa1, 0xcd, 0xe6, 0x13,
114 0xbc, 0x6d, 0xe0, 0xb6, 0xf2, 0x4b, 0x1c, 0x7a,
115 0xa4, 0x48, 0xc8, 0xb9, 0xc3, 0x40, 0x3e, 0x34,
116 0x67, 0xa8, 0xca, 0xd8, 0x93, 0x40, 0xf5, 0x3b}, /* out */
117 32, AES_DECRYPT}, /* test vector 1 */
121 const unsigned char key1[32];
122 const unsigned char key2[32];
123 const unsigned char iv[64];
124 const unsigned char in[MAX_VECTOR_SIZE];
125 const unsigned char out[MAX_VECTOR_SIZE];
126 const size_t keysize;
131 static struct bi_ige_test const bi_ige_test_vectors[] = {
132 {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
133 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, /* key1 */
134 {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
135 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}, /* key2 */
136 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
137 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
138 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
139 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
140 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
141 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
142 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
143 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f}, /* iv */
144 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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}, /* in */
148 {0x14, 0x40, 0x6f, 0xae, 0xa2, 0x79, 0xf2, 0x56,
149 0x1f, 0x86, 0xeb, 0x3b, 0x7d, 0xff, 0x53, 0xdc,
150 0x4e, 0x27, 0x0c, 0x03, 0xde, 0x7c, 0xe5, 0x16,
151 0x6a, 0x9c, 0x20, 0x33, 0x9d, 0x33, 0xfe, 0x12}, /* out */
152 16, 32, AES_ENCRYPT}, /* test vector 0 */
153 {{0x58, 0x0a, 0x06, 0xe9, 0x97, 0x07, 0x59, 0x5c,
154 0x9e, 0x19, 0xd2, 0xa7, 0xbb, 0x40, 0x2b, 0x7a,
155 0xc7, 0xd8, 0x11, 0x9e, 0x4c, 0x51, 0x35, 0x75,
156 0x64, 0x28, 0x0f, 0x23, 0xad, 0x74, 0xac, 0x37}, /* key1 */
157 {0xd1, 0x80, 0xa0, 0x31, 0x47, 0xa3, 0x11, 0x13,
158 0x86, 0x26, 0x9e, 0x6d, 0xff, 0xaf, 0x72, 0x74,
159 0x5b, 0xa2, 0x35, 0x81, 0xd2, 0xa6, 0x3d, 0x21,
160 0x67, 0x7b, 0x58, 0xa8, 0x18, 0xf9, 0x72, 0xe4}, /* key2 */
161 {0x80, 0x3d, 0xbd, 0x4c, 0xe6, 0x7b, 0x06, 0xa9,
162 0x53, 0x35, 0xd5, 0x7e, 0x71, 0xc1, 0x70, 0x70,
163 0x74, 0x9a, 0x00, 0x28, 0x0c, 0xbf, 0x6c, 0x42,
164 0x9b, 0xa4, 0xdd, 0x65, 0x11, 0x77, 0x7c, 0x67,
165 0xfe, 0x76, 0x0a, 0xf0, 0xd5, 0xc6, 0x6e, 0x6a,
166 0xe7, 0x5e, 0x4c, 0xf2, 0x7e, 0x9e, 0xf9, 0x20,
167 0x0e, 0x54, 0x6f, 0x2d, 0x8a, 0x8d, 0x7e, 0xbd,
168 0x48, 0x79, 0x37, 0x99, 0xff, 0x27, 0x93, 0xa3}, /* iv */
169 {0xf1, 0x54, 0x3d, 0xca, 0xfe, 0xb5, 0xef, 0x1c,
170 0x4f, 0xa6, 0x43, 0xf6, 0xe6, 0x48, 0x57, 0xf0,
171 0xee, 0x15, 0x7f, 0xe3, 0xe7, 0x2f, 0xd0, 0x2f,
172 0x11, 0x95, 0x7a, 0x17, 0x00, 0xab, 0xa7, 0x0b,
173 0xbe, 0x44, 0x09, 0x9c, 0xcd, 0xac, 0xa8, 0x52,
174 0xa1, 0x8e, 0x7b, 0x75, 0xbc, 0xa4, 0x92, 0x5a,
175 0xab, 0x46, 0xd3, 0x3a, 0xa0, 0xd5, 0x35, 0x1c,
176 0x55, 0xa4, 0xb3, 0xa8, 0x40, 0x81, 0xa5, 0x0b}, /* in */
177 {0x42, 0xe5, 0x28, 0x30, 0x31, 0xc2, 0xa0, 0x23,
178 0x68, 0x49, 0x4e, 0xb3, 0x24, 0x59, 0x92, 0x79,
179 0xc1, 0xa5, 0xcc, 0xe6, 0x76, 0x53, 0xb1, 0xcf,
180 0x20, 0x86, 0x23, 0xe8, 0x72, 0x55, 0x99, 0x92,
181 0x0d, 0x16, 0x1c, 0x5a, 0x2f, 0xce, 0xcb, 0x51,
182 0xe2, 0x67, 0xfa, 0x10, 0xec, 0xcd, 0x3d, 0x67,
183 0xa5, 0xe6, 0xf7, 0x31, 0x26, 0xb0, 0x0d, 0x76,
184 0x5e, 0x28, 0xdc, 0x7f, 0x01, 0xc5, 0xa5, 0x4c}, /* out */
185 32, 64, AES_ENCRYPT}, /* test vector 1 */
189 static int run_test_vectors(void)
194 for (n = 0; n < sizeof(ige_test_vectors) / sizeof(ige_test_vectors[0]);
196 const struct ige_test *const v = &ige_test_vectors[n];
198 unsigned char buf[MAX_VECTOR_SIZE];
199 unsigned char iv[AES_BLOCK_SIZE * 2];
201 assert(v->length <= MAX_VECTOR_SIZE);
203 if (v->encrypt == AES_ENCRYPT)
204 AES_set_encrypt_key(v->key, 8 * sizeof v->key, &key);
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);
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);
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);
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);
239 n < sizeof(bi_ige_test_vectors) / sizeof(bi_ige_test_vectors[0]);
241 const struct bi_ige_test *const v = &bi_ige_test_vectors[n];
244 unsigned char buf[MAX_VECTOR_SIZE];
246 assert(v->length <= MAX_VECTOR_SIZE);
248 if (v->encrypt == AES_ENCRYPT) {
249 AES_set_encrypt_key(v->key1, 8 * v->keysize, &key1);
250 AES_set_encrypt_key(v->key2, 8 * v->keysize, &key2);
252 AES_set_decrypt_key(v->key1, 8 * v->keysize, &key1);
253 AES_set_decrypt_key(v->key2, 8 * v->keysize, &key2);
256 AES_bi_ige_encrypt(v->in, buf, v->length, &key1, &key2, v->iv,
259 if (memcmp(v->out, buf, v->length)) {
260 printf("Bidirectional IGE test vector %d failed\n", n);
261 hexdump(stdout, "key 1", v->key1, sizeof v->key1);
262 hexdump(stdout, "key 2", v->key2, sizeof v->key2);
263 hexdump(stdout, "iv", v->iv, sizeof v->iv);
264 hexdump(stdout, "in", v->in, v->length);
265 hexdump(stdout, "expected", v->out, v->length);
266 hexdump(stdout, "got", buf, v->length);
275 int main(int argc, char **argv)
277 unsigned char rkey[16];
278 unsigned char rkey2[16];
281 unsigned char plaintext[BIG_TEST_SIZE];
282 unsigned char ciphertext[BIG_TEST_SIZE];
283 unsigned char checktext[BIG_TEST_SIZE];
284 unsigned char iv[AES_BLOCK_SIZE * 4];
285 unsigned char saved_iv[AES_BLOCK_SIZE * 4];
290 assert(BIG_TEST_SIZE >= TEST_SIZE);
292 RAND_pseudo_bytes(rkey, sizeof rkey);
293 RAND_pseudo_bytes(plaintext, sizeof plaintext);
294 RAND_pseudo_bytes(iv, sizeof iv);
295 memcpy(saved_iv, iv, sizeof saved_iv);
297 /* Forward IGE only... */
299 /* Straight encrypt/decrypt */
300 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
301 AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, iv, AES_ENCRYPT);
303 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
304 memcpy(iv, saved_iv, sizeof iv);
305 AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv, AES_DECRYPT);
307 if (memcmp(checktext, plaintext, TEST_SIZE)) {
308 printf("Encrypt+decrypt doesn't match\n");
309 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
310 hexdump(stdout, "Checktext", checktext, TEST_SIZE);
314 /* Now check encrypt chaining works */
315 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
316 memcpy(iv, saved_iv, sizeof iv);
317 AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE / 2, &key, iv,
319 AES_ige_encrypt(plaintext + TEST_SIZE / 2,
320 ciphertext + TEST_SIZE / 2, TEST_SIZE / 2,
321 &key, iv, AES_ENCRYPT);
323 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
324 memcpy(iv, saved_iv, sizeof iv);
325 AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv, AES_DECRYPT);
327 if (memcmp(checktext, plaintext, TEST_SIZE)) {
328 printf("Chained encrypt+decrypt doesn't match\n");
329 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
330 hexdump(stdout, "Checktext", checktext, TEST_SIZE);
334 /* And check decrypt chaining */
335 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
336 memcpy(iv, saved_iv, sizeof iv);
337 AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE / 2, &key, iv,
339 AES_ige_encrypt(plaintext + TEST_SIZE / 2,
340 ciphertext + TEST_SIZE / 2, TEST_SIZE / 2,
341 &key, iv, AES_ENCRYPT);
343 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
344 memcpy(iv, saved_iv, sizeof iv);
345 AES_ige_encrypt(ciphertext, checktext, TEST_SIZE / 2, &key, iv,
347 AES_ige_encrypt(ciphertext + TEST_SIZE / 2,
348 checktext + TEST_SIZE / 2, TEST_SIZE / 2, &key, iv,
351 if (memcmp(checktext, plaintext, TEST_SIZE)) {
352 printf("Chained encrypt+chained decrypt doesn't match\n");
353 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
354 hexdump(stdout, "Checktext", checktext, TEST_SIZE);
358 /* make sure garble extends forwards only */
359 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
360 memcpy(iv, saved_iv, sizeof iv);
361 AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
364 /* corrupt halfway through */
365 ++ciphertext[sizeof ciphertext / 2];
366 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
367 memcpy(iv, saved_iv, sizeof iv);
368 AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
372 for (n = 0; n < sizeof checktext; ++n)
373 if (checktext[n] == plaintext[n])
376 if (matches > sizeof checktext / 2 + sizeof checktext / 100) {
377 printf("More than 51%% matches after garbling\n");
381 if (matches < sizeof checktext / 2) {
382 printf("Garble extends backwards!\n");
386 /* Bi-directional IGE */
389 * Note that we don't have to recover the IV, because chaining isn't
391 /* possible with biIGE, so the IV is not updated. */
393 RAND_pseudo_bytes(rkey2, sizeof rkey2);
395 /* Straight encrypt/decrypt */
396 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
397 AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
398 AES_bi_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, &key2, iv,
401 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
402 AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
403 AES_bi_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, &key2, iv,
406 if (memcmp(checktext, plaintext, TEST_SIZE)) {
407 printf("Encrypt+decrypt doesn't match\n");
408 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
409 hexdump(stdout, "Checktext", checktext, TEST_SIZE);
413 /* make sure garble extends both ways */
414 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
415 AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
416 AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
419 /* corrupt halfway through */
420 ++ciphertext[sizeof ciphertext / 2];
421 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
422 AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
423 AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
427 for (n = 0; n < sizeof checktext; ++n)
428 if (checktext[n] == plaintext[n])
431 if (matches > sizeof checktext / 100) {
432 printf("More than 1%% matches after bidirectional garbling\n");
436 /* make sure garble extends both ways (2) */
437 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
438 AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
439 AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
442 /* corrupt right at the end */
443 ++ciphertext[sizeof ciphertext - 1];
444 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
445 AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
446 AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
450 for (n = 0; n < sizeof checktext; ++n)
451 if (checktext[n] == plaintext[n])
454 if (matches > sizeof checktext / 100) {
455 printf("More than 1%% matches after bidirectional garbling (2)\n");
459 /* make sure garble extends both ways (3) */
460 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
461 AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
462 AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
465 /* corrupt right at the start */
467 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
468 AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
469 AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
473 for (n = 0; n < sizeof checktext; ++n)
474 if (checktext[n] == plaintext[n])
477 if (matches > sizeof checktext / 100) {
478 printf("More than 1%% matches after bidirectional garbling (3)\n");
482 err += run_test_vectors();