1 /* ====================================================================
2 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
30 * 6. Redistributions of any form whatsoever must retain the following
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
51 #include <openssl/crypto.h>
52 #include <openssl/aes.h>
53 #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 < OSSL_NELEM(ige_test_vectors); ++n) {
195 const struct ige_test *const v = &ige_test_vectors[n];
197 unsigned char buf[MAX_VECTOR_SIZE];
198 unsigned char iv[AES_BLOCK_SIZE * 2];
200 assert(v->length <= MAX_VECTOR_SIZE);
202 if (v->encrypt == AES_ENCRYPT)
203 AES_set_encrypt_key(v->key, 8 * sizeof v->key, &key);
205 AES_set_decrypt_key(v->key, 8 * sizeof v->key, &key);
206 memcpy(iv, v->iv, sizeof iv);
207 AES_ige_encrypt(v->in, buf, v->length, &key, iv, v->encrypt);
209 if (memcmp(v->out, buf, v->length)) {
210 printf("IGE test vector %d failed\n", n);
211 hexdump(stdout, "key", v->key, sizeof v->key);
212 hexdump(stdout, "iv", v->iv, sizeof v->iv);
213 hexdump(stdout, "in", v->in, v->length);
214 hexdump(stdout, "expected", v->out, v->length);
215 hexdump(stdout, "got", buf, v->length);
220 /* try with in == out */
221 memcpy(iv, v->iv, sizeof iv);
222 memcpy(buf, v->in, v->length);
223 AES_ige_encrypt(buf, buf, v->length, &key, iv, v->encrypt);
225 if (memcmp(v->out, buf, v->length)) {
226 printf("IGE test vector %d failed (with in == out)\n", n);
227 hexdump(stdout, "key", v->key, sizeof v->key);
228 hexdump(stdout, "iv", v->iv, sizeof v->iv);
229 hexdump(stdout, "in", v->in, v->length);
230 hexdump(stdout, "expected", v->out, v->length);
231 hexdump(stdout, "got", buf, v->length);
237 for (n = 0; n < OSSL_NELEM(bi_ige_test_vectors); ++n) {
238 const struct bi_ige_test *const v = &bi_ige_test_vectors[n];
241 unsigned char buf[MAX_VECTOR_SIZE];
243 assert(v->length <= MAX_VECTOR_SIZE);
245 if (v->encrypt == AES_ENCRYPT) {
246 AES_set_encrypt_key(v->key1, 8 * v->keysize, &key1);
247 AES_set_encrypt_key(v->key2, 8 * v->keysize, &key2);
249 AES_set_decrypt_key(v->key1, 8 * v->keysize, &key1);
250 AES_set_decrypt_key(v->key2, 8 * v->keysize, &key2);
253 AES_bi_ige_encrypt(v->in, buf, v->length, &key1, &key2, v->iv,
256 if (memcmp(v->out, buf, v->length)) {
257 printf("Bidirectional IGE test vector %d failed\n", n);
258 hexdump(stdout, "key 1", v->key1, sizeof v->key1);
259 hexdump(stdout, "key 2", v->key2, sizeof v->key2);
260 hexdump(stdout, "iv", v->iv, sizeof v->iv);
261 hexdump(stdout, "in", v->in, v->length);
262 hexdump(stdout, "expected", v->out, v->length);
263 hexdump(stdout, "got", buf, v->length);
272 int main(int argc, char **argv)
274 unsigned char rkey[16];
275 unsigned char rkey2[16];
278 unsigned char plaintext[BIG_TEST_SIZE];
279 unsigned char ciphertext[BIG_TEST_SIZE];
280 unsigned char checktext[BIG_TEST_SIZE];
281 unsigned char iv[AES_BLOCK_SIZE * 4];
282 unsigned char saved_iv[AES_BLOCK_SIZE * 4];
287 assert(BIG_TEST_SIZE >= TEST_SIZE);
289 RAND_bytes(rkey, sizeof rkey);
290 RAND_bytes(plaintext, sizeof plaintext);
291 RAND_bytes(iv, sizeof iv);
292 memcpy(saved_iv, iv, sizeof saved_iv);
294 /* Forward IGE only... */
296 /* Straight encrypt/decrypt */
297 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
298 AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, iv, AES_ENCRYPT);
300 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
301 memcpy(iv, saved_iv, sizeof iv);
302 AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv, AES_DECRYPT);
304 if (memcmp(checktext, plaintext, TEST_SIZE)) {
305 printf("Encrypt+decrypt doesn't match\n");
306 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
307 hexdump(stdout, "Checktext", checktext, TEST_SIZE);
311 /* Now check encrypt chaining works */
312 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
313 memcpy(iv, saved_iv, sizeof iv);
314 AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE / 2, &key, iv,
316 AES_ige_encrypt(plaintext + TEST_SIZE / 2,
317 ciphertext + TEST_SIZE / 2, TEST_SIZE / 2,
318 &key, iv, AES_ENCRYPT);
320 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
321 memcpy(iv, saved_iv, sizeof iv);
322 AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv, AES_DECRYPT);
324 if (memcmp(checktext, plaintext, TEST_SIZE)) {
325 printf("Chained encrypt+decrypt doesn't match\n");
326 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
327 hexdump(stdout, "Checktext", checktext, TEST_SIZE);
331 /* And check decrypt chaining */
332 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
333 memcpy(iv, saved_iv, sizeof iv);
334 AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE / 2, &key, iv,
336 AES_ige_encrypt(plaintext + TEST_SIZE / 2,
337 ciphertext + TEST_SIZE / 2, TEST_SIZE / 2,
338 &key, iv, AES_ENCRYPT);
340 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
341 memcpy(iv, saved_iv, sizeof iv);
342 AES_ige_encrypt(ciphertext, checktext, TEST_SIZE / 2, &key, iv,
344 AES_ige_encrypt(ciphertext + TEST_SIZE / 2,
345 checktext + TEST_SIZE / 2, TEST_SIZE / 2, &key, iv,
348 if (memcmp(checktext, plaintext, TEST_SIZE)) {
349 printf("Chained encrypt+chained decrypt doesn't match\n");
350 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
351 hexdump(stdout, "Checktext", checktext, TEST_SIZE);
355 /* make sure garble extends forwards only */
356 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
357 memcpy(iv, saved_iv, sizeof iv);
358 AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
361 /* corrupt halfway through */
362 ++ciphertext[sizeof ciphertext / 2];
363 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
364 memcpy(iv, saved_iv, sizeof iv);
365 AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
369 for (n = 0; n < sizeof checktext; ++n)
370 if (checktext[n] == plaintext[n])
373 if (matches > sizeof checktext / 2 + sizeof checktext / 100) {
374 printf("More than 51%% matches after garbling\n");
378 if (matches < sizeof checktext / 2) {
379 printf("Garble extends backwards!\n");
383 /* Bi-directional IGE */
386 * Note that we don't have to recover the IV, because chaining isn't
388 /* possible with biIGE, so the IV is not updated. */
390 RAND_bytes(rkey2, sizeof rkey2);
392 /* Straight encrypt/decrypt */
393 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
394 AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
395 AES_bi_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, &key2, iv,
398 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
399 AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
400 AES_bi_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, &key2, iv,
403 if (memcmp(checktext, plaintext, TEST_SIZE)) {
404 printf("Encrypt+decrypt doesn't match\n");
405 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
406 hexdump(stdout, "Checktext", checktext, TEST_SIZE);
410 /* make sure garble extends both ways */
411 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
412 AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
413 AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
416 /* corrupt halfway through */
417 ++ciphertext[sizeof ciphertext / 2];
418 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
419 AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
420 AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
424 for (n = 0; n < sizeof checktext; ++n)
425 if (checktext[n] == plaintext[n])
428 if (matches > sizeof checktext / 100) {
429 printf("More than 1%% matches after bidirectional garbling\n");
433 /* make sure garble extends both ways (2) */
434 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
435 AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
436 AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
439 /* corrupt right at the end */
440 ++ciphertext[sizeof ciphertext - 1];
441 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
442 AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
443 AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
447 for (n = 0; n < sizeof checktext; ++n)
448 if (checktext[n] == plaintext[n])
451 if (matches > sizeof checktext / 100) {
452 printf("More than 1%% matches after bidirectional garbling (2)\n");
456 /* make sure garble extends both ways (3) */
457 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
458 AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
459 AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
462 /* corrupt right at the start */
464 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
465 AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
466 AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
470 for (n = 0; n < sizeof checktext; ++n)
471 if (checktext[n] == plaintext[n])
474 if (matches > sizeof checktext / 100) {
475 printf("More than 1%% matches after bidirectional garbling (3)\n");
479 err += run_test_vectors();