1/* 2 * Test program for AES 3 * Copyright (c) 2003-2006, Jouni Malinen <j@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 23static 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 60static 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 104static 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 */ 172 173struct omac1_test_vector { 174 u8 k[16]; 175 u8 msg[64]; 176 int msg_len; 177 u8 tag[16]; 178}; 179 180static struct omac1_test_vector test_vectors[] = 181{ 182 { 183 { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 184 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, 185 { }, 186 0, 187 { 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, 188 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 } 189 }, 190 { 191 { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 192 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, 193 { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 194 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a}, 195 16, 196 { 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, 197 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c } 198 }, 199 { 200 { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 201 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, 202 { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 203 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 204 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 205 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 206 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11 }, 207 40, 208 { 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30, 209 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27 } 210 }, 211 { 212 { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 213 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, 214 { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 215 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 216 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 217 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 218 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 219 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, 220 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 221 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 }, 222 64, 223 { 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, 224 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe } 225 }, 226}; 227 228 229int main(int argc, char *argv[]) 230{ 231 u8 kek[] = { 232 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 233 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f 234 }; 235 u8 plain[] = { 236 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 237 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff 238 }; 239 u8 crypt[] = { 240 0x1F, 0xA6, 0x8B, 0x0A, 0x81, 0x12, 0xB4, 0x47, 241 0xAE, 0xF3, 0x4B, 0xD8, 0xFB, 0x5A, 0x7B, 0x82, 242 0x9D, 0x3E, 0x86, 0x23, 0x71, 0xD2, 0xCF, 0xE5 243 }; 244 u8 result[24]; 245 int ret = 0; 246 unsigned int i; 247 struct omac1_test_vector *tv; 248 249 if (aes_wrap(kek, 2, plain, result)) { 250 printf("AES-WRAP-128-128 reported failure\n"); 251 ret++; 252 } 253 if (memcmp(result, crypt, 24) != 0) { 254 printf("AES-WRAP-128-128 failed\n"); 255 ret++; 256 } 257 if (aes_unwrap(kek, 2, crypt, result)) { 258 printf("AES-UNWRAP-128-128 reported failure\n"); 259 ret++; 260 } 261 if (memcmp(result, plain, 16) != 0) { 262 int i; 263 printf("AES-UNWRAP-128-128 failed\n"); 264 ret++; 265 for (i = 0; i < 16; i++) 266 printf(" %02x", result[i]); 267 printf("\n"); 268 } 269 270 test_aes_perf(); 271 272 for (i = 0; i < sizeof(test_vectors) / sizeof(test_vectors[0]); i++) { 273 tv = &test_vectors[i]; 274 omac1_aes_128(tv->k, tv->msg, tv->msg_len, result); 275 if (memcmp(result, tv->tag, 16) != 0) { 276 printf("OMAC1-AES-128 test vector %d failed\n", i); 277 ret++; 278 } 279 280 if (tv->msg_len > 1) { 281 const u8 *addr[2]; 282 size_t len[2]; 283 284 addr[0] = tv->msg; 285 len[0] = 1; 286 addr[1] = tv->msg + 1; 287 len[1] = tv->msg_len - 1; 288 289 omac1_aes_128_vector(tv->k, 2, addr, len, result); 290 if (memcmp(result, tv->tag, 16) != 0) { 291 printf("OMAC1-AES-128(vector) test vector %d " 292 "failed\n", i); 293 ret++; 294 } 295 } 296 } 297 298 ret += test_eax(); 299 300 ret += test_cbc(); 301 302 if (ret) 303 printf("FAILED!\n"); 304 305 return ret; 306} 307