Home | History | Annotate | Download | only in tests
      1 /*
      2  * Test program for AES
      3  * Copyright (c) 2003-2006, Jouni Malinen <j (at) w1.fi>
      4  *
      5  * This program is free software; you can redistribute it and/or modify
      6  * it under the terms of the GNU General Public License version 2 as
      7  * published by the Free Software Foundation.
      8  *
      9  * Alternatively, this software may be distributed under the terms of BSD
     10  * license.
     11  *
     12  * See README and COPYING for more details.
     13  */
     14 
     15 #include "includes.h"
     16 
     17 #include "common.h"
     18 #include "crypto.h"
     19 #include "aes_wrap.h"
     20 
     21 #define BLOCK_SIZE 16
     22 
     23 static void test_aes_perf(void)
     24 {
     25 #if 0 /* this did not seem to work with new compiler?! */
     26 #ifdef __i386__
     27 #define rdtscll(val) \
     28      __asm__ __volatile__("rdtsc" : "=A" (val))
     29 	const int num_iters = 10;
     30 	int i;
     31 	unsigned int start, end;
     32 	u8 key[16], pt[16], ct[16];
     33 	void *ctx;
     34 
     35 	printf("keySetupEnc:");
     36 	for (i = 0; i < num_iters; i++) {
     37 		rdtscll(start);
     38 		ctx = aes_encrypt_init(key, 16);
     39 		rdtscll(end);
     40 		aes_encrypt_deinit(ctx);
     41 		printf(" %d", end - start);
     42 	}
     43 	printf("\n");
     44 
     45 	printf("Encrypt:");
     46 	ctx = aes_encrypt_init(key, 16);
     47 	for (i = 0; i < num_iters; i++) {
     48 		rdtscll(start);
     49 		aes_encrypt(ctx, pt, ct);
     50 		rdtscll(end);
     51 		printf(" %d", end - start);
     52 	}
     53 	aes_encrypt_deinit(ctx);
     54 	printf("\n");
     55 #endif /* __i386__ */
     56 #endif
     57 }
     58 
     59 
     60 static int test_eax(void)
     61 {
     62 	u8 msg[] = { 0xF7, 0xFB };
     63 	u8 key[] = { 0x91, 0x94, 0x5D, 0x3F, 0x4D, 0xCB, 0xEE, 0x0B,
     64 		     0xF4, 0x5E, 0xF5, 0x22, 0x55, 0xF0, 0x95, 0xA4 };
     65 	u8 nonce[] = { 0xBE, 0xCA, 0xF0, 0x43, 0xB0, 0xA2, 0x3D, 0x84,
     66 		       0x31, 0x94, 0xBA, 0x97, 0x2C, 0x66, 0xDE, 0xBD };
     67 	u8 hdr[] = { 0xFA, 0x3B, 0xFD, 0x48, 0x06, 0xEB, 0x53, 0xFA };
     68 	u8 cipher[] = { 0x19, 0xDD, 0x5C, 0x4C, 0x93, 0x31, 0x04, 0x9D,
     69 			0x0B, 0xDA, 0xB0, 0x27, 0x74, 0x08, 0xF6, 0x79,
     70 			0x67, 0xE5 };
     71 	u8 data[sizeof(msg)], tag[BLOCK_SIZE];
     72 
     73 	memcpy(data, msg, sizeof(msg));
     74 	if (aes_128_eax_encrypt(key, nonce, sizeof(nonce), hdr, sizeof(hdr),
     75 				data, sizeof(data), tag)) {
     76 		printf("AES-128 EAX mode encryption failed\n");
     77 		return 1;
     78 	}
     79 	if (memcmp(data, cipher, sizeof(data)) != 0) {
     80 		printf("AES-128 EAX mode encryption returned invalid cipher "
     81 		       "text\n");
     82 		return 1;
     83 	}
     84 	if (memcmp(tag, cipher + sizeof(data), BLOCK_SIZE) != 0) {
     85 		printf("AES-128 EAX mode encryption returned invalid tag\n");
     86 		return 1;
     87 	}
     88 
     89 	if (aes_128_eax_decrypt(key, nonce, sizeof(nonce), hdr, sizeof(hdr),
     90 				data, sizeof(data), tag)) {
     91 		printf("AES-128 EAX mode decryption failed\n");
     92 		return 1;
     93 	}
     94 	if (memcmp(data, msg, sizeof(data)) != 0) {
     95 		printf("AES-128 EAX mode decryption returned invalid plain "
     96 		       "text\n");
     97 		return 1;
     98 	}
     99 
    100 	return 0;
    101 }
    102 
    103 
    104 static int test_cbc(void)
    105 {
    106 	struct cbc_test_vector {
    107 		u8 key[16];
    108 		u8 iv[16];
    109 		u8 plain[32];
    110 		u8 cipher[32];
    111 		size_t len;
    112 	} vectors[] = {
    113 		{
    114 			{ 0x06, 0xa9, 0x21, 0x40, 0x36, 0xb8, 0xa1, 0x5b,
    115 			  0x51, 0x2e, 0x03, 0xd5, 0x34, 0x12, 0x00, 0x06 },
    116 			{ 0x3d, 0xaf, 0xba, 0x42, 0x9d, 0x9e, 0xb4, 0x30,
    117 			  0xb4, 0x22, 0xda, 0x80, 0x2c, 0x9f, 0xac, 0x41 },
    118 			"Single block msg",
    119 			{ 0xe3, 0x53, 0x77, 0x9c, 0x10, 0x79, 0xae, 0xb8,
    120 			  0x27, 0x08, 0x94, 0x2d, 0xbe, 0x77, 0x18, 0x1a },
    121 			16
    122 		},
    123 		{
    124 			{ 0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0,
    125 			  0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a },
    126 			{ 0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28,
    127 			  0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58 },
    128 			{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    129 			  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    130 			  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    131 			  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
    132 			{ 0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a,
    133 			  0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a,
    134 			  0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9,
    135 			  0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1 },
    136 			32
    137 		}
    138 	};
    139 	int ret = 0;
    140 	u8 *buf;
    141 	unsigned int i;
    142 
    143 	for (i = 0; i < sizeof(vectors) / sizeof(vectors[0]); i++) {
    144 		struct cbc_test_vector *tv = &vectors[i];
    145 		buf = malloc(tv->len);
    146 		if (buf == NULL) {
    147 			ret++;
    148 			break;
    149 		}
    150 		memcpy(buf, tv->plain, tv->len);
    151 		aes_128_cbc_encrypt(tv->key, tv->iv, buf, tv->len);
    152 		if (memcmp(buf, tv->cipher, tv->len) != 0) {
    153 			printf("AES-CBC encrypt %d failed\n", i);
    154 			ret++;
    155 		}
    156 		memcpy(buf, tv->cipher, tv->len);
    157 		aes_128_cbc_decrypt(tv->key, tv->iv, buf, tv->len);
    158 		if (memcmp(buf, tv->plain, tv->len) != 0) {
    159 			printf("AES-CBC decrypt %d failed\n", i);
    160 			ret++;
    161 		}
    162 		free(buf);
    163 	}
    164 
    165 	return ret;
    166 }
    167 
    168 
    169 /* OMAC1 AES-128 test vectors from
    170  * http://csrc.nist.gov/CryptoToolkit/modes/proposedmodes/omac/omac-ad.pdf
    171  * which are same as the examples from NIST SP800-38B
    172  * http://csrc.nist.gov/CryptoToolkit/modes/800-38_Series_Publications/SP800-38B.pdf
    173  */
    174 
    175 struct omac1_test_vector {
    176 	u8 k[16];
    177 	u8 msg[64];
    178 	int msg_len;
    179 	u8 tag[16];
    180 };
    181 
    182 static struct omac1_test_vector test_vectors[] =
    183 {
    184 	{
    185 		{ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
    186 		  0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
    187 		{ },
    188 		0,
    189 		{ 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
    190 		  0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 }
    191 	},
    192 	{
    193 		{ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
    194 		  0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
    195 		{ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
    196 		  0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a},
    197 		16,
    198 		{ 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
    199 		  0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c }
    200 	},
    201 	{
    202 		{ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
    203 		  0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
    204 		{ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
    205 		  0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
    206 		  0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
    207 		  0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
    208 		  0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11 },
    209 		40,
    210 		{ 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
    211 		  0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27 }
    212 	},
    213 	{
    214 		{ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
    215 		  0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
    216 		{ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
    217 		  0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
    218 		  0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
    219 		  0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
    220 		  0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
    221 		  0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
    222 		  0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
    223 		  0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 },
    224 		64,
    225 		{ 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
    226 		  0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe }
    227 	},
    228 };
    229 
    230 
    231 int main(int argc, char *argv[])
    232 {
    233 	u8 kek[] = {
    234 		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    235 		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
    236 	};
    237 	u8 plain[] = {
    238 		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
    239 		0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
    240 	};
    241 	u8 crypt[] = {
    242 		0x1F, 0xA6, 0x8B, 0x0A, 0x81, 0x12, 0xB4, 0x47,
    243 		0xAE, 0xF3, 0x4B, 0xD8, 0xFB, 0x5A, 0x7B, 0x82,
    244 		0x9D, 0x3E, 0x86, 0x23, 0x71, 0xD2, 0xCF, 0xE5
    245 	};
    246 	u8 result[24];
    247 	int ret = 0;
    248 	unsigned int i;
    249 	struct omac1_test_vector *tv;
    250 
    251 	if (aes_wrap(kek, 2, plain, result)) {
    252 		printf("AES-WRAP-128-128 reported failure\n");
    253 		ret++;
    254 	}
    255 	if (memcmp(result, crypt, 24) != 0) {
    256 		printf("AES-WRAP-128-128 failed\n");
    257 		ret++;
    258 	}
    259 	if (aes_unwrap(kek, 2, crypt, result)) {
    260 		printf("AES-UNWRAP-128-128 reported failure\n");
    261 		ret++;
    262 	}
    263 	if (memcmp(result, plain, 16) != 0) {
    264 		printf("AES-UNWRAP-128-128 failed\n");
    265 		ret++;
    266 		for (i = 0; i < 16; i++)
    267 			printf(" %02x", result[i]);
    268 		printf("\n");
    269 	}
    270 
    271 	test_aes_perf();
    272 
    273 	for (i = 0; i < sizeof(test_vectors) / sizeof(test_vectors[0]); i++) {
    274 		tv = &test_vectors[i];
    275 		omac1_aes_128(tv->k, tv->msg, tv->msg_len, result);
    276 		if (memcmp(result, tv->tag, 16) != 0) {
    277 			printf("OMAC1-AES-128 test vector %d failed\n", i);
    278 			ret++;
    279 		}
    280 
    281 		if (tv->msg_len > 1) {
    282 			const u8 *addr[2];
    283 			size_t len[2];
    284 
    285 			addr[0] = tv->msg;
    286 			len[0] = 1;
    287 			addr[1] = tv->msg + 1;
    288 			len[1] = tv->msg_len - 1;
    289 
    290 			omac1_aes_128_vector(tv->k, 2, addr, len, result);
    291 			if (memcmp(result, tv->tag, 16) != 0) {
    292 				printf("OMAC1-AES-128(vector) test vector %d "
    293 				       "failed\n", i);
    294 				ret++;
    295 			}
    296 		}
    297 	}
    298 
    299 	ret += test_eax();
    300 
    301 	ret += test_cbc();
    302 
    303 	if (ret)
    304 		printf("FAILED!\n");
    305 
    306 	return ret;
    307 }
    308