2 * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
10 #include <openssl/crypto.h>
11 #include <openssl/aes.h>
12 #include <openssl/rand.h>
19 #define BIG_TEST_SIZE 10240
21 static void hexdump(FILE *f, const char *title, const unsigned char *s, int l)
25 fprintf(f, "%s", title);
28 fprintf(f, "\n%04x", n);
29 fprintf(f, " %02x", s[n]);
34 #define MAX_VECTOR_SIZE 64
37 const unsigned char key[16];
38 const unsigned char iv[32];
39 const unsigned char in[MAX_VECTOR_SIZE];
40 const unsigned char out[MAX_VECTOR_SIZE];
45 static struct ige_test const ige_test_vectors[] = {
46 {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
47 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, /* key */
48 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
49 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
50 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
51 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}, /* iv */
52 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* in */
56 {0x1a, 0x85, 0x19, 0xa6, 0x55, 0x7b, 0xe6, 0x52,
57 0xe9, 0xda, 0x8e, 0x43, 0xda, 0x4e, 0xf4, 0x45,
58 0x3c, 0xf4, 0x56, 0xb4, 0xca, 0x48, 0x8a, 0xa3,
59 0x83, 0xc7, 0x9c, 0x98, 0xb3, 0x47, 0x97, 0xcb}, /* out */
60 32, AES_ENCRYPT}, /* test vector 0 */
62 {{0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
63 0x61, 0x6e, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65}, /* key */
64 {0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f,
65 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x49, 0x47, 0x45,
66 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x6f,
67 0x72, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53}, /* iv */
68 {0x4c, 0x2e, 0x20, 0x4c, 0x65, 0x74, 0x27, 0x73,
69 0x20, 0x68, 0x6f, 0x70, 0x65, 0x20, 0x42, 0x65,
70 0x6e, 0x20, 0x67, 0x6f, 0x74, 0x20, 0x69, 0x74,
71 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x21, 0x0a}, /* in */
72 {0x99, 0x70, 0x64, 0x87, 0xa1, 0xcd, 0xe6, 0x13,
73 0xbc, 0x6d, 0xe0, 0xb6, 0xf2, 0x4b, 0x1c, 0x7a,
74 0xa4, 0x48, 0xc8, 0xb9, 0xc3, 0x40, 0x3e, 0x34,
75 0x67, 0xa8, 0xca, 0xd8, 0x93, 0x40, 0xf5, 0x3b}, /* out */
76 32, AES_DECRYPT}, /* test vector 1 */
80 const unsigned char key1[32];
81 const unsigned char key2[32];
82 const unsigned char iv[64];
83 const unsigned char in[MAX_VECTOR_SIZE];
84 const unsigned char out[MAX_VECTOR_SIZE];
90 static struct bi_ige_test const bi_ige_test_vectors[] = {
91 {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
92 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, /* key1 */
93 {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
94 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}, /* key2 */
95 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
96 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
97 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
98 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
99 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
100 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
101 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
102 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f}, /* iv */
103 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* in */
107 {0x14, 0x40, 0x6f, 0xae, 0xa2, 0x79, 0xf2, 0x56,
108 0x1f, 0x86, 0xeb, 0x3b, 0x7d, 0xff, 0x53, 0xdc,
109 0x4e, 0x27, 0x0c, 0x03, 0xde, 0x7c, 0xe5, 0x16,
110 0x6a, 0x9c, 0x20, 0x33, 0x9d, 0x33, 0xfe, 0x12}, /* out */
111 16, 32, AES_ENCRYPT}, /* test vector 0 */
112 {{0x58, 0x0a, 0x06, 0xe9, 0x97, 0x07, 0x59, 0x5c,
113 0x9e, 0x19, 0xd2, 0xa7, 0xbb, 0x40, 0x2b, 0x7a,
114 0xc7, 0xd8, 0x11, 0x9e, 0x4c, 0x51, 0x35, 0x75,
115 0x64, 0x28, 0x0f, 0x23, 0xad, 0x74, 0xac, 0x37}, /* key1 */
116 {0xd1, 0x80, 0xa0, 0x31, 0x47, 0xa3, 0x11, 0x13,
117 0x86, 0x26, 0x9e, 0x6d, 0xff, 0xaf, 0x72, 0x74,
118 0x5b, 0xa2, 0x35, 0x81, 0xd2, 0xa6, 0x3d, 0x21,
119 0x67, 0x7b, 0x58, 0xa8, 0x18, 0xf9, 0x72, 0xe4}, /* key2 */
120 {0x80, 0x3d, 0xbd, 0x4c, 0xe6, 0x7b, 0x06, 0xa9,
121 0x53, 0x35, 0xd5, 0x7e, 0x71, 0xc1, 0x70, 0x70,
122 0x74, 0x9a, 0x00, 0x28, 0x0c, 0xbf, 0x6c, 0x42,
123 0x9b, 0xa4, 0xdd, 0x65, 0x11, 0x77, 0x7c, 0x67,
124 0xfe, 0x76, 0x0a, 0xf0, 0xd5, 0xc6, 0x6e, 0x6a,
125 0xe7, 0x5e, 0x4c, 0xf2, 0x7e, 0x9e, 0xf9, 0x20,
126 0x0e, 0x54, 0x6f, 0x2d, 0x8a, 0x8d, 0x7e, 0xbd,
127 0x48, 0x79, 0x37, 0x99, 0xff, 0x27, 0x93, 0xa3}, /* iv */
128 {0xf1, 0x54, 0x3d, 0xca, 0xfe, 0xb5, 0xef, 0x1c,
129 0x4f, 0xa6, 0x43, 0xf6, 0xe6, 0x48, 0x57, 0xf0,
130 0xee, 0x15, 0x7f, 0xe3, 0xe7, 0x2f, 0xd0, 0x2f,
131 0x11, 0x95, 0x7a, 0x17, 0x00, 0xab, 0xa7, 0x0b,
132 0xbe, 0x44, 0x09, 0x9c, 0xcd, 0xac, 0xa8, 0x52,
133 0xa1, 0x8e, 0x7b, 0x75, 0xbc, 0xa4, 0x92, 0x5a,
134 0xab, 0x46, 0xd3, 0x3a, 0xa0, 0xd5, 0x35, 0x1c,
135 0x55, 0xa4, 0xb3, 0xa8, 0x40, 0x81, 0xa5, 0x0b}, /* in */
136 {0x42, 0xe5, 0x28, 0x30, 0x31, 0xc2, 0xa0, 0x23,
137 0x68, 0x49, 0x4e, 0xb3, 0x24, 0x59, 0x92, 0x79,
138 0xc1, 0xa5, 0xcc, 0xe6, 0x76, 0x53, 0xb1, 0xcf,
139 0x20, 0x86, 0x23, 0xe8, 0x72, 0x55, 0x99, 0x92,
140 0x0d, 0x16, 0x1c, 0x5a, 0x2f, 0xce, 0xcb, 0x51,
141 0xe2, 0x67, 0xfa, 0x10, 0xec, 0xcd, 0x3d, 0x67,
142 0xa5, 0xe6, 0xf7, 0x31, 0x26, 0xb0, 0x0d, 0x76,
143 0x5e, 0x28, 0xdc, 0x7f, 0x01, 0xc5, 0xa5, 0x4c}, /* out */
144 32, 64, AES_ENCRYPT}, /* test vector 1 */
148 static int run_test_vectors(void)
153 for (n = 0; n < OSSL_NELEM(ige_test_vectors); ++n) {
154 const struct ige_test *const v = &ige_test_vectors[n];
156 unsigned char buf[MAX_VECTOR_SIZE];
157 unsigned char iv[AES_BLOCK_SIZE * 2];
159 assert(v->length <= MAX_VECTOR_SIZE);
161 if (v->encrypt == AES_ENCRYPT)
162 AES_set_encrypt_key(v->key, 8 * sizeof v->key, &key);
164 AES_set_decrypt_key(v->key, 8 * sizeof v->key, &key);
165 memcpy(iv, v->iv, sizeof iv);
166 AES_ige_encrypt(v->in, buf, v->length, &key, iv, v->encrypt);
168 if (memcmp(v->out, buf, v->length)) {
169 printf("IGE test vector %d failed\n", n);
170 hexdump(stdout, "key", v->key, sizeof v->key);
171 hexdump(stdout, "iv", v->iv, sizeof v->iv);
172 hexdump(stdout, "in", v->in, v->length);
173 hexdump(stdout, "expected", v->out, v->length);
174 hexdump(stdout, "got", buf, v->length);
179 /* try with in == out */
180 memcpy(iv, v->iv, sizeof iv);
181 memcpy(buf, v->in, v->length);
182 AES_ige_encrypt(buf, buf, v->length, &key, iv, v->encrypt);
184 if (memcmp(v->out, buf, v->length)) {
185 printf("IGE test vector %d failed (with in == out)\n", n);
186 hexdump(stdout, "key", v->key, sizeof v->key);
187 hexdump(stdout, "iv", v->iv, sizeof v->iv);
188 hexdump(stdout, "in", v->in, v->length);
189 hexdump(stdout, "expected", v->out, v->length);
190 hexdump(stdout, "got", buf, v->length);
196 for (n = 0; n < OSSL_NELEM(bi_ige_test_vectors); ++n) {
197 const struct bi_ige_test *const v = &bi_ige_test_vectors[n];
200 unsigned char buf[MAX_VECTOR_SIZE];
202 assert(v->length <= MAX_VECTOR_SIZE);
204 if (v->encrypt == AES_ENCRYPT) {
205 AES_set_encrypt_key(v->key1, 8 * v->keysize, &key1);
206 AES_set_encrypt_key(v->key2, 8 * v->keysize, &key2);
208 AES_set_decrypt_key(v->key1, 8 * v->keysize, &key1);
209 AES_set_decrypt_key(v->key2, 8 * v->keysize, &key2);
212 AES_bi_ige_encrypt(v->in, buf, v->length, &key1, &key2, v->iv,
215 if (memcmp(v->out, buf, v->length)) {
216 printf("Bidirectional IGE test vector %d failed\n", n);
217 hexdump(stdout, "key 1", v->key1, sizeof v->key1);
218 hexdump(stdout, "key 2", v->key2, sizeof v->key2);
219 hexdump(stdout, "iv", v->iv, sizeof v->iv);
220 hexdump(stdout, "in", v->in, v->length);
221 hexdump(stdout, "expected", v->out, v->length);
222 hexdump(stdout, "got", buf, v->length);
231 int main(int argc, char **argv)
233 unsigned char rkey[16];
234 unsigned char rkey2[16];
237 unsigned char plaintext[BIG_TEST_SIZE];
238 unsigned char ciphertext[BIG_TEST_SIZE];
239 unsigned char checktext[BIG_TEST_SIZE];
240 unsigned char iv[AES_BLOCK_SIZE * 4];
241 unsigned char saved_iv[AES_BLOCK_SIZE * 4];
246 assert(BIG_TEST_SIZE >= TEST_SIZE);
248 RAND_bytes(rkey, sizeof rkey);
249 RAND_bytes(plaintext, sizeof plaintext);
250 RAND_bytes(iv, sizeof iv);
251 memcpy(saved_iv, iv, sizeof saved_iv);
253 /* Forward IGE only... */
255 /* Straight encrypt/decrypt */
256 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
257 AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, iv, AES_ENCRYPT);
259 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
260 memcpy(iv, saved_iv, sizeof iv);
261 AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv, AES_DECRYPT);
263 if (memcmp(checktext, plaintext, TEST_SIZE)) {
264 printf("Encrypt+decrypt doesn't match\n");
265 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
266 hexdump(stdout, "Checktext", checktext, TEST_SIZE);
270 /* Now check encrypt chaining works */
271 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
272 memcpy(iv, saved_iv, sizeof iv);
273 AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE / 2, &key, iv,
275 AES_ige_encrypt(plaintext + TEST_SIZE / 2,
276 ciphertext + TEST_SIZE / 2, TEST_SIZE / 2,
277 &key, iv, AES_ENCRYPT);
279 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
280 memcpy(iv, saved_iv, sizeof iv);
281 AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv, AES_DECRYPT);
283 if (memcmp(checktext, plaintext, TEST_SIZE)) {
284 printf("Chained encrypt+decrypt doesn't match\n");
285 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
286 hexdump(stdout, "Checktext", checktext, TEST_SIZE);
290 /* And check decrypt chaining */
291 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
292 memcpy(iv, saved_iv, sizeof iv);
293 AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE / 2, &key, iv,
295 AES_ige_encrypt(plaintext + TEST_SIZE / 2,
296 ciphertext + TEST_SIZE / 2, TEST_SIZE / 2,
297 &key, iv, AES_ENCRYPT);
299 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
300 memcpy(iv, saved_iv, sizeof iv);
301 AES_ige_encrypt(ciphertext, checktext, TEST_SIZE / 2, &key, iv,
303 AES_ige_encrypt(ciphertext + TEST_SIZE / 2,
304 checktext + TEST_SIZE / 2, TEST_SIZE / 2, &key, iv,
307 if (memcmp(checktext, plaintext, TEST_SIZE)) {
308 printf("Chained encrypt+chained decrypt doesn't match\n");
309 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
310 hexdump(stdout, "Checktext", checktext, TEST_SIZE);
314 /* make sure garble extends forwards only */
315 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
316 memcpy(iv, saved_iv, sizeof iv);
317 AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
320 /* corrupt halfway through */
321 ++ciphertext[sizeof ciphertext / 2];
322 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
323 memcpy(iv, saved_iv, sizeof iv);
324 AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
328 for (n = 0; n < sizeof checktext; ++n)
329 if (checktext[n] == plaintext[n])
332 if (matches > sizeof checktext / 2 + sizeof checktext / 100) {
333 printf("More than 51%% matches after garbling\n");
337 if (matches < sizeof checktext / 2) {
338 printf("Garble extends backwards!\n");
342 /* Bi-directional IGE */
345 * Note that we don't have to recover the IV, because chaining isn't
347 /* possible with biIGE, so the IV is not updated. */
349 RAND_bytes(rkey2, sizeof rkey2);
351 /* Straight encrypt/decrypt */
352 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
353 AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
354 AES_bi_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, &key2, iv,
357 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
358 AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
359 AES_bi_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, &key2, iv,
362 if (memcmp(checktext, plaintext, TEST_SIZE)) {
363 printf("Encrypt+decrypt doesn't match\n");
364 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
365 hexdump(stdout, "Checktext", checktext, TEST_SIZE);
369 /* make sure garble extends both ways */
370 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
371 AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
372 AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
375 /* corrupt halfway through */
376 ++ciphertext[sizeof ciphertext / 2];
377 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
378 AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
379 AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
383 for (n = 0; n < sizeof checktext; ++n)
384 if (checktext[n] == plaintext[n])
387 if (matches > sizeof checktext / 100) {
388 printf("More than 1%% matches after bidirectional garbling\n");
392 /* make sure garble extends both ways (2) */
393 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
394 AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
395 AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
398 /* corrupt right at the end */
399 ++ciphertext[sizeof ciphertext - 1];
400 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
401 AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
402 AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
406 for (n = 0; n < sizeof checktext; ++n)
407 if (checktext[n] == plaintext[n])
410 if (matches > sizeof checktext / 100) {
411 printf("More than 1%% matches after bidirectional garbling (2)\n");
415 /* make sure garble extends both ways (3) */
416 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
417 AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
418 AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
421 /* corrupt right at the start */
423 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
424 AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
425 AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
429 for (n = 0; n < sizeof checktext; ++n)
430 if (checktext[n] == plaintext[n])
433 if (matches > sizeof checktext / 100) {
434 printf("More than 1%% matches after bidirectional garbling (3)\n");
438 err += run_test_vectors();