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>
61 #define BIG_TEST_SIZE 10240
63 static void hexdump(FILE *f, const char *title, const unsigned char *s, int l)
67 fprintf(f, "%s", title);
70 fprintf(f, "\n%04x", n);
71 fprintf(f, " %02x", s[n]);
76 #define MAX_VECTOR_SIZE 64
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];
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 */
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 */
122 const unsigned char key1[32];
123 const unsigned char key2[32];
124 const unsigned char iv[64];
125 const unsigned char in[MAX_VECTOR_SIZE];
126 const unsigned char out[MAX_VECTOR_SIZE];
127 const size_t keysize;
132 static struct bi_ige_test const bi_ige_test_vectors[] = {
133 {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
134 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, /* key1 */
135 {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
136 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}, /* key2 */
137 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
138 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
139 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
140 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
141 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
142 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
143 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
144 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f}, /* iv */
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,
148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* in */
149 {0x14, 0x40, 0x6f, 0xae, 0xa2, 0x79, 0xf2, 0x56,
150 0x1f, 0x86, 0xeb, 0x3b, 0x7d, 0xff, 0x53, 0xdc,
151 0x4e, 0x27, 0x0c, 0x03, 0xde, 0x7c, 0xe5, 0x16,
152 0x6a, 0x9c, 0x20, 0x33, 0x9d, 0x33, 0xfe, 0x12}, /* out */
153 16, 32, AES_ENCRYPT}, /* test vector 0 */
154 {{0x58, 0x0a, 0x06, 0xe9, 0x97, 0x07, 0x59, 0x5c,
155 0x9e, 0x19, 0xd2, 0xa7, 0xbb, 0x40, 0x2b, 0x7a,
156 0xc7, 0xd8, 0x11, 0x9e, 0x4c, 0x51, 0x35, 0x75,
157 0x64, 0x28, 0x0f, 0x23, 0xad, 0x74, 0xac, 0x37}, /* key1 */
158 {0xd1, 0x80, 0xa0, 0x31, 0x47, 0xa3, 0x11, 0x13,
159 0x86, 0x26, 0x9e, 0x6d, 0xff, 0xaf, 0x72, 0x74,
160 0x5b, 0xa2, 0x35, 0x81, 0xd2, 0xa6, 0x3d, 0x21,
161 0x67, 0x7b, 0x58, 0xa8, 0x18, 0xf9, 0x72, 0xe4}, /* key2 */
162 {0x80, 0x3d, 0xbd, 0x4c, 0xe6, 0x7b, 0x06, 0xa9,
163 0x53, 0x35, 0xd5, 0x7e, 0x71, 0xc1, 0x70, 0x70,
164 0x74, 0x9a, 0x00, 0x28, 0x0c, 0xbf, 0x6c, 0x42,
165 0x9b, 0xa4, 0xdd, 0x65, 0x11, 0x77, 0x7c, 0x67,
166 0xfe, 0x76, 0x0a, 0xf0, 0xd5, 0xc6, 0x6e, 0x6a,
167 0xe7, 0x5e, 0x4c, 0xf2, 0x7e, 0x9e, 0xf9, 0x20,
168 0x0e, 0x54, 0x6f, 0x2d, 0x8a, 0x8d, 0x7e, 0xbd,
169 0x48, 0x79, 0x37, 0x99, 0xff, 0x27, 0x93, 0xa3}, /* iv */
170 {0xf1, 0x54, 0x3d, 0xca, 0xfe, 0xb5, 0xef, 0x1c,
171 0x4f, 0xa6, 0x43, 0xf6, 0xe6, 0x48, 0x57, 0xf0,
172 0xee, 0x15, 0x7f, 0xe3, 0xe7, 0x2f, 0xd0, 0x2f,
173 0x11, 0x95, 0x7a, 0x17, 0x00, 0xab, 0xa7, 0x0b,
174 0xbe, 0x44, 0x09, 0x9c, 0xcd, 0xac, 0xa8, 0x52,
175 0xa1, 0x8e, 0x7b, 0x75, 0xbc, 0xa4, 0x92, 0x5a,
176 0xab, 0x46, 0xd3, 0x3a, 0xa0, 0xd5, 0x35, 0x1c,
177 0x55, 0xa4, 0xb3, 0xa8, 0x40, 0x81, 0xa5, 0x0b}, /* in */
178 {0x42, 0xe5, 0x28, 0x30, 0x31, 0xc2, 0xa0, 0x23,
179 0x68, 0x49, 0x4e, 0xb3, 0x24, 0x59, 0x92, 0x79,
180 0xc1, 0xa5, 0xcc, 0xe6, 0x76, 0x53, 0xb1, 0xcf,
181 0x20, 0x86, 0x23, 0xe8, 0x72, 0x55, 0x99, 0x92,
182 0x0d, 0x16, 0x1c, 0x5a, 0x2f, 0xce, 0xcb, 0x51,
183 0xe2, 0x67, 0xfa, 0x10, 0xec, 0xcd, 0x3d, 0x67,
184 0xa5, 0xe6, 0xf7, 0x31, 0x26, 0xb0, 0x0d, 0x76,
185 0x5e, 0x28, 0xdc, 0x7f, 0x01, 0xc5, 0xa5, 0x4c}, /* out */
186 32, 64, AES_ENCRYPT}, /* test vector 1 */
190 static int run_test_vectors(void)
195 for (n = 0; n < OSSL_NELEM(ige_test_vectors); ++n) {
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);
238 for (n = 0; n < OSSL_NELEM(bi_ige_test_vectors); ++n) {
239 const struct bi_ige_test *const v = &bi_ige_test_vectors[n];
242 unsigned char buf[MAX_VECTOR_SIZE];
244 assert(v->length <= MAX_VECTOR_SIZE);
246 if (v->encrypt == AES_ENCRYPT) {
247 AES_set_encrypt_key(v->key1, 8 * v->keysize, &key1);
248 AES_set_encrypt_key(v->key2, 8 * v->keysize, &key2);
250 AES_set_decrypt_key(v->key1, 8 * v->keysize, &key1);
251 AES_set_decrypt_key(v->key2, 8 * v->keysize, &key2);
254 AES_bi_ige_encrypt(v->in, buf, v->length, &key1, &key2, v->iv,
257 if (memcmp(v->out, buf, v->length)) {
258 printf("Bidirectional IGE test vector %d failed\n", n);
259 hexdump(stdout, "key 1", v->key1, sizeof v->key1);
260 hexdump(stdout, "key 2", v->key2, sizeof v->key2);
261 hexdump(stdout, "iv", v->iv, sizeof v->iv);
262 hexdump(stdout, "in", v->in, v->length);
263 hexdump(stdout, "expected", v->out, v->length);
264 hexdump(stdout, "got", buf, v->length);
273 int main(int argc, char **argv)
275 unsigned char rkey[16];
276 unsigned char rkey2[16];
279 unsigned char plaintext[BIG_TEST_SIZE];
280 unsigned char ciphertext[BIG_TEST_SIZE];
281 unsigned char checktext[BIG_TEST_SIZE];
282 unsigned char iv[AES_BLOCK_SIZE * 4];
283 unsigned char saved_iv[AES_BLOCK_SIZE * 4];
288 assert(BIG_TEST_SIZE >= TEST_SIZE);
290 RAND_bytes(rkey, sizeof rkey);
291 RAND_bytes(plaintext, sizeof plaintext);
292 RAND_bytes(iv, sizeof iv);
293 memcpy(saved_iv, iv, sizeof saved_iv);
295 /* Forward IGE only... */
297 /* Straight encrypt/decrypt */
298 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
299 AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, iv, AES_ENCRYPT);
301 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
302 memcpy(iv, saved_iv, sizeof iv);
303 AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv, AES_DECRYPT);
305 if (memcmp(checktext, plaintext, TEST_SIZE)) {
306 printf("Encrypt+decrypt doesn't match\n");
307 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
308 hexdump(stdout, "Checktext", checktext, TEST_SIZE);
312 /* Now check encrypt chaining works */
313 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
314 memcpy(iv, saved_iv, sizeof iv);
315 AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE / 2, &key, iv,
317 AES_ige_encrypt(plaintext + TEST_SIZE / 2,
318 ciphertext + TEST_SIZE / 2, TEST_SIZE / 2,
319 &key, iv, AES_ENCRYPT);
321 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
322 memcpy(iv, saved_iv, sizeof iv);
323 AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv, AES_DECRYPT);
325 if (memcmp(checktext, plaintext, TEST_SIZE)) {
326 printf("Chained encrypt+decrypt doesn't match\n");
327 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
328 hexdump(stdout, "Checktext", checktext, TEST_SIZE);
332 /* And check decrypt chaining */
333 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
334 memcpy(iv, saved_iv, sizeof iv);
335 AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE / 2, &key, iv,
337 AES_ige_encrypt(plaintext + TEST_SIZE / 2,
338 ciphertext + TEST_SIZE / 2, TEST_SIZE / 2,
339 &key, iv, AES_ENCRYPT);
341 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
342 memcpy(iv, saved_iv, sizeof iv);
343 AES_ige_encrypt(ciphertext, checktext, TEST_SIZE / 2, &key, iv,
345 AES_ige_encrypt(ciphertext + TEST_SIZE / 2,
346 checktext + TEST_SIZE / 2, TEST_SIZE / 2, &key, iv,
349 if (memcmp(checktext, plaintext, TEST_SIZE)) {
350 printf("Chained encrypt+chained decrypt doesn't match\n");
351 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
352 hexdump(stdout, "Checktext", checktext, TEST_SIZE);
356 /* make sure garble extends forwards only */
357 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
358 memcpy(iv, saved_iv, sizeof iv);
359 AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
362 /* corrupt halfway through */
363 ++ciphertext[sizeof ciphertext / 2];
364 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
365 memcpy(iv, saved_iv, sizeof iv);
366 AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
370 for (n = 0; n < sizeof checktext; ++n)
371 if (checktext[n] == plaintext[n])
374 if (matches > sizeof checktext / 2 + sizeof checktext / 100) {
375 printf("More than 51%% matches after garbling\n");
379 if (matches < sizeof checktext / 2) {
380 printf("Garble extends backwards!\n");
384 /* Bi-directional IGE */
387 * Note that we don't have to recover the IV, because chaining isn't
389 /* possible with biIGE, so the IV is not updated. */
391 RAND_bytes(rkey2, sizeof rkey2);
393 /* Straight encrypt/decrypt */
394 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
395 AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
396 AES_bi_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, &key2, iv,
399 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
400 AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
401 AES_bi_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, &key2, iv,
404 if (memcmp(checktext, plaintext, TEST_SIZE)) {
405 printf("Encrypt+decrypt doesn't match\n");
406 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
407 hexdump(stdout, "Checktext", checktext, TEST_SIZE);
411 /* make sure garble extends both ways */
412 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
413 AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
414 AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
417 /* corrupt halfway through */
418 ++ciphertext[sizeof ciphertext / 2];
419 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
420 AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
421 AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
425 for (n = 0; n < sizeof checktext; ++n)
426 if (checktext[n] == plaintext[n])
429 if (matches > sizeof checktext / 100) {
430 printf("More than 1%% matches after bidirectional garbling\n");
434 /* make sure garble extends both ways (2) */
435 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
436 AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
437 AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
440 /* corrupt right at the end */
441 ++ciphertext[sizeof ciphertext - 1];
442 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
443 AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
444 AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
448 for (n = 0; n < sizeof checktext; ++n)
449 if (checktext[n] == plaintext[n])
452 if (matches > sizeof checktext / 100) {
453 printf("More than 1%% matches after bidirectional garbling (2)\n");
457 /* make sure garble extends both ways (3) */
458 AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
459 AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
460 AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
463 /* corrupt right at the start */
465 AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
466 AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
467 AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
471 for (n = 0; n < sizeof checktext; ++n)
472 if (checktext[n] == plaintext[n])
475 if (matches > sizeof checktext / 100) {
476 printf("More than 1%% matches after bidirectional garbling (3)\n");
480 err += run_test_vectors();