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