1 /********************************************************************** 2 Copyright(c) 2011-2016 Intel Corporation All rights reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions 6 are met: 7 * Redistributions of source code must retain the above copyright 8 notice, this list of conditions and the following disclaimer. 9 * Redistributions in binary form must reproduce the above copyright 10 notice, this list of conditions and the following disclaimer in 11 the documentation and/or other materials provided with the 12 distribution. 13 * Neither the name of Intel Corporation nor the names of its 14 contributors may be used to endorse or promote products derived 15 from this software without specific prior written permission. 16 17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 **********************************************************************/ 29 30 #include <stdlib.h> 31 #include <stdio.h> 32 #include <stdint.h> 33 #include <string.h> 34 #include <aes_cbc.h> 35 #include "types.h" 36 #include "ossl_helper.h" 37 #include "cbc_std_vectors.h" 38 39 // define CBC_VECTORS_VERBOSE 40 // define CBC_VECTORS_EXTRA_VERBOSE 41 42 #ifndef TEST_SEED 43 #define TEST_SEED 0x1234 44 #endif 45 #ifndef RANDOMS 46 #define RANDOMS 100 47 #endif 48 #ifndef TEST_LEN 49 #define TEST_LEN (8 * 1024 * 1024) 50 #endif 51 #ifndef PAGE_LEN 52 #define PAGE_LEN (4 * 1024) 53 #endif 54 #ifndef MAX_UNALINED 55 #define MAX_UNALINED (16) 56 #endif 57 58 static cbc_key_size const Ksize[] = { CBC_128_BITS, CBC_192_BITS, CBC_256_BITS }; 59 60 typedef void (*aes_cbc_generic)(uint8_t *in, uint8_t *IV, uint8_t *keys, uint8_t *out, 61 uint64_t len_bytes); 62 63 int 64 OpenSslEnc(uint8_t k_len, uint8_t *key, uint8_t *in, uint8_t *iv, uint8_t *out, uint64_t len_bytes) 65 { 66 if (CBC_128_BITS == k_len) { 67 #ifdef CBC_VECTORS_EXTRA_VERBOSE 68 printf(" OpenSSL128 "); 69 #endif 70 openssl_aes_128_cbc_enc(key, (uint8_t *) iv, len_bytes, in, out); 71 } else if (CBC_192_BITS == k_len) { 72 #ifdef CBC_VECTORS_EXTRA_VERBOSE 73 printf(" OpenSSL192 "); 74 #endif 75 openssl_aes_192_cbc_enc(key, (uint8_t *) iv, len_bytes, in, out); 76 } else if (CBC_256_BITS == k_len) { 77 #ifdef CBC_VECTORS_EXTRA_VERBOSE 78 printf(" OpenSSL256 "); 79 fflush(0); 80 #endif 81 openssl_aes_256_cbc_enc(key, (uint8_t *) iv, len_bytes, in, out); 82 } else { 83 fprintf(stderr, "Invalid key length: %d\n", k_len); 84 return 1; 85 } 86 return 0; 87 } 88 89 int 90 OpenSslDec(uint8_t k_len, uint8_t *key, uint8_t *in, uint8_t *iv, uint8_t *out, uint64_t len_bytes) 91 { 92 if (CBC_128_BITS == k_len) { 93 #ifdef CBC_VECTORS_EXTRA_VERBOSE 94 printf(" OpenSSL128 "); 95 #endif 96 openssl_aes_128_cbc_dec(key, (uint8_t *) iv, len_bytes, in, out); 97 } else if (CBC_192_BITS == k_len) { 98 #ifdef CBC_VECTORS_EXTRA_VERBOSE 99 printf(" OpenSSL192 "); 100 #endif 101 openssl_aes_192_cbc_dec(key, (uint8_t *) iv, len_bytes, in, out); 102 } else if (CBC_256_BITS == k_len) { 103 #ifdef CBC_VECTORS_EXTRA_VERBOSE 104 printf(" OpenSSL256 "); 105 #endif 106 openssl_aes_256_cbc_dec(key, (uint8_t *) iv, len_bytes, in, out); 107 } else { 108 fprintf(stderr, "Invalid key length: %d\n", k_len); 109 return 1; 110 } 111 return 0; 112 } 113 114 void 115 mk_rand_data(uint8_t *data, uint32_t size) 116 { 117 int i; 118 for (i = 0; i < size; i++) { 119 *data++ = rand(); 120 } 121 } 122 123 int 124 check_data(uint8_t *test, uint8_t *expected, uint64_t len, char *data_name) 125 { 126 int mismatch; 127 int fail = 0; 128 uint64_t a; 129 130 mismatch = memcmp(test, expected, len); 131 if (!mismatch) { 132 return fail; 133 134 } else { 135 fail = 1; 136 printf(" failed %s \t\t", data_name); 137 for (a = 0; a < len; a++) { 138 if (test[a] != expected[a]) { 139 printf(" '%x' != '%x' at %lx of %lx\n", test[a], expected[a], a, 140 len); 141 break; 142 } 143 } 144 } 145 return fail; 146 } 147 148 int 149 check_vector(struct cbc_vector *vector) 150 { 151 uint8_t *pt_test = NULL; 152 uint8_t *o_ct_test = NULL; 153 int fail = 0; 154 aes_cbc_generic enc; 155 aes_cbc_generic dec; 156 157 #ifdef CBC_VECTORS_VERBOSE 158 printf(" Keylen:%d PLen:%d ", (int) vector->K_LEN, (int) vector->P_LEN); 159 #ifdef CBC_VECTORS_EXTRA_VERBOSE 160 printf(" K:%p P:%p C:%p IV:%p expC:%p Keys:%p ", vector->K, vector->P, vector->C, 161 vector->IV, vector->EXP_C, vector->KEYS); 162 #endif 163 fflush(0); 164 #else 165 printf("."); 166 #endif 167 168 if (CBC_128_BITS == vector->K_LEN) { 169 enc = (aes_cbc_generic) &aes_cbc_enc_128; 170 dec = (aes_cbc_generic) &aes_cbc_dec_128; 171 #ifdef CBC_VECTORS_EXTRA_VERBOSE 172 printf(" CBC128 "); 173 #endif 174 } else if (CBC_192_BITS == vector->K_LEN) { 175 enc = (aes_cbc_generic) &aes_cbc_enc_192; 176 dec = (aes_cbc_generic) &aes_cbc_dec_192; 177 #ifdef CBC_VECTORS_EXTRA_VERBOSE 178 printf(" CBC192 "); 179 #endif 180 } else if (CBC_256_BITS == vector->K_LEN) { 181 enc = (aes_cbc_generic) &aes_cbc_enc_256; 182 dec = (aes_cbc_generic) &aes_cbc_dec_256; 183 #ifdef CBC_VECTORS_EXTRA_VERBOSE 184 printf(" CBC256 "); 185 #endif 186 } else { 187 printf("Invalid key length: %d\n", vector->K_LEN); 188 return 1; 189 } 190 191 // Allocate space for the calculated ciphertext 192 pt_test = malloc(vector->P_LEN); 193 o_ct_test = malloc(vector->P_LEN); 194 if ((pt_test == NULL) || (o_ct_test == NULL)) { 195 fprintf(stderr, "Can't allocate ciphertext memory\n"); 196 fail = 1; 197 goto exit; 198 } 199 200 aes_cbc_precomp(vector->K, vector->K_LEN, vector->KEYS); 201 202 #ifdef CBC_VECTORS_VERBOSE 203 fflush(0); 204 #endif 205 //// 206 // ISA-l Encrypt 207 //// 208 enc(vector->P, vector->IV, vector->KEYS->enc_keys, vector->C, vector->P_LEN); 209 if (NULL != vector->EXP_C) { // when the encrypted text is know verify correct 210 fail |= check_data(vector->EXP_C, vector->C, vector->P_LEN, 211 "ISA-L expected cypher text (C)"); 212 } 213 OpenSslEnc(vector->K_LEN, vector->K, vector->P, vector->IV, o_ct_test, vector->P_LEN); 214 fail |= check_data(vector->C, o_ct_test, vector->P_LEN, "OpenSSL vs ISA-L cypher text (C)"); 215 216 memcpy(pt_test, vector->P, vector->P_LEN); 217 memset(vector->P, 0, vector->P_LEN); 218 #ifdef CBC_VECTORS_VERBOSE 219 fflush(0); 220 #endif 221 222 //// 223 // ISA-l Decrypt 224 //// 225 dec(vector->C, vector->IV, vector->KEYS->dec_keys, vector->P, vector->P_LEN); 226 fail |= check_data(vector->P, pt_test, vector->P_LEN, "ISA-L decrypted plain text (P)"); 227 memset(vector->P, 0, vector->P_LEN); 228 dec(o_ct_test, vector->IV, vector->KEYS->dec_keys, vector->P, vector->P_LEN); 229 fail |= check_data(vector->P, pt_test, vector->P_LEN, "ISA-L decrypted OpenSSL (P)"); 230 memset(vector->P, 0, vector->P_LEN); 231 OpenSslDec(vector->K_LEN, vector->K, vector->C, vector->IV, vector->P, vector->P_LEN); 232 fail |= check_data(vector->P, pt_test, vector->P_LEN, "OpenSSL decrypted ISA-L (P)"); 233 234 exit: 235 free(pt_test); 236 free(o_ct_test); 237 238 #ifdef CBC_VECTORS_VERBOSE 239 if (fail) 240 printf("Failed"); 241 else 242 printf("Passed"); 243 244 printf("\n"); 245 #endif 246 247 return fail; 248 } 249 250 int 251 test_std_combinations(void) 252 { 253 int const vectors_cnt = sizeof(cbc_vectors) / sizeof(cbc_vectors[0]); 254 int i, ret; 255 uint8_t *iv = NULL; 256 257 printf("AES CBC standard test vectors:"); 258 #ifdef CBC_VECTORS_VERBOSE 259 printf("\n"); 260 #endif 261 ret = posix_memalign((void **) &iv, 16, (CBC_IV_DATA_LEN)); 262 if ((0 != ret) || (NULL == iv)) 263 return 1; 264 265 for (i = 0; (i < vectors_cnt); i++) { 266 struct cbc_vector vect = cbc_vectors[i]; 267 268 ret = posix_memalign((void **) &vect.KEYS, 16, (sizeof(*vect.KEYS))); 269 if ((0 != ret) || (NULL == vect.KEYS)) 270 return 1; 271 // IV data must be aligned to 16 byte boundary so move data in aligned buffer and 272 // change out the pointer 273 memcpy(iv, vect.IV, CBC_IV_DATA_LEN); 274 vect.IV = iv; 275 vect.C = NULL; 276 vect.C = malloc(vect.P_LEN); 277 if ((NULL == vect.C)) { 278 aligned_free(vect.KEYS); 279 ret = 1; 280 break; 281 } 282 #ifdef CBC_VECTORS_VERBOSE 283 printf("vector[%d of %d] ", i, vectors_cnt); 284 #endif 285 if (0 == (i % 25)) 286 printf("\n"); 287 if (0 == (i % 10)) 288 fflush(0); 289 290 if (0 != check_vector(&vect)) { 291 aligned_free(vect.KEYS); 292 free(vect.C); 293 ret = 1; 294 break; 295 } 296 297 aligned_free(vect.KEYS); 298 free(vect.C); 299 } 300 301 aligned_free(iv); 302 printf("\n"); 303 return ret; 304 } 305 306 int 307 test_random_combinations(void) 308 { 309 struct cbc_vector test; 310 int t, ret; 311 312 printf("AES CBC random test vectors:"); 313 #ifdef CBC_VECTORS_VERBOSE 314 fflush(0); 315 #endif 316 test.IV = NULL; 317 ret = posix_memalign((void **) &test.IV, 16, (CBC_IV_DATA_LEN)); 318 if ((0 != ret) || (NULL == test.IV)) 319 return 1; 320 test.KEYS = NULL; 321 ret = posix_memalign((void **) &test.KEYS, 16, (sizeof(*test.KEYS))); 322 if ((0 != ret) || (NULL == test.KEYS)) { 323 ret = 1; 324 goto exit; 325 } 326 327 for (t = 0; RANDOMS > t; t++) { 328 int Plen = 16 + ((rand() % TEST_LEN) & ~0xf); // must be a 16byte multiple 329 int offset = (rand() % MAX_UNALINED); 330 int Kindex = (rand() % (sizeof(Ksize) / 331 sizeof(Ksize[0]))); // select one of the valid key sizes 332 333 if (0 == (t % 25)) 334 printf("\n"); 335 if (0 == (t % 10)) 336 fflush(0); 337 338 test.C = NULL; 339 test.P = NULL; 340 test.K = NULL; 341 test.EXP_C = NULL; 342 test.P_LEN = Plen; 343 test.K_LEN = Ksize[Kindex]; 344 345 test.P = malloc(test.P_LEN + offset); 346 test.C = malloc(test.P_LEN + offset); 347 test.K = malloc(test.K_LEN + offset); 348 if ((NULL == test.P) || (NULL == test.C) || (NULL == test.K)) { 349 printf("malloc of testsize:0x%x failed\n", Plen); 350 free(test.P); 351 free(test.C); 352 free(test.K); 353 ret = -1; 354 break; 355 } 356 test.P += offset; 357 test.C += offset; 358 test.K += offset; 359 360 mk_rand_data(test.P, test.P_LEN); 361 mk_rand_data(test.K, test.K_LEN); 362 mk_rand_data(test.IV, CBC_IV_DATA_LEN); 363 364 #ifdef CBC_VECTORS_EXTRA_VERBOSE 365 printf(" Offset:0x%x ", offset); 366 #endif 367 if (0 != check_vector(&test)) 368 ret = 1; 369 370 test.C -= offset; 371 free(test.C); 372 test.K -= offset; 373 free(test.K); 374 test.P -= offset; 375 free(test.P); 376 377 if (ret != 0) 378 break; 379 } 380 381 exit: 382 aligned_free(test.IV); 383 aligned_free(test.KEYS); 384 printf("\n"); 385 return ret; 386 } 387 388 int 389 test_efence_combinations(void) 390 { 391 struct cbc_vector test; 392 int offset = 0; 393 int key_idx; 394 uint8_t *P = NULL, *C = NULL, *K = NULL, *IV = NULL; 395 uint8_t *key_data = NULL; 396 int ret = 1; 397 398 P = malloc(PAGE_LEN); 399 C = malloc(PAGE_LEN); 400 K = malloc(PAGE_LEN); 401 IV = malloc(PAGE_LEN); 402 key_data = malloc(PAGE_LEN); 403 404 if ((NULL == P) || (NULL == C) || (NULL == K) || (NULL == IV) || (NULL == key_data)) { 405 printf("malloc of testsize:0x%x failed\n", PAGE_LEN); 406 goto exit; 407 } 408 // place buffers to end at page boundary 409 test.P_LEN = PAGE_LEN / 2; 410 test.EXP_C = NULL; 411 412 printf("AES CBC efence test vectors:"); 413 for (key_idx = 0; key_idx < (sizeof(Ksize) / sizeof(Ksize[0])); key_idx++) { 414 test.K_LEN = Ksize[key_idx]; 415 416 for (offset = 0; MAX_UNALINED > offset; offset++) { 417 if (0 == (offset % 80)) 418 printf("\n"); 419 // move the start and size of the data block towards the end of the page 420 test.P_LEN = ((PAGE_LEN / (1 + (2 * offset))) & 421 ~0xff); // must be a multiple of 16 422 if (16 > test.P_LEN) 423 test.P_LEN = 16; 424 // Place data at end of page 425 test.P = P + PAGE_LEN - test.P_LEN - offset; 426 test.C = C + PAGE_LEN - test.P_LEN - offset; 427 test.K = K + PAGE_LEN - test.K_LEN - offset; 428 test.IV = IV + PAGE_LEN - CBC_IV_DATA_LEN - offset; 429 test.IV = 430 test.IV - ((uint64_t) test.IV & 0xff); // align to 16 byte boundary 431 test.KEYS = (struct cbc_key_data *) (key_data + PAGE_LEN - 432 sizeof(*test.KEYS) - offset); 433 test.KEYS = (struct cbc_key_data *) ((uint8_t *) test.KEYS - 434 ((uint64_t) test.KEYS & 435 0xff)); // align to 16 byte boundary 436 437 mk_rand_data(test.P, test.P_LEN); 438 mk_rand_data(test.K, test.K_LEN); 439 mk_rand_data(test.IV, CBC_IV_DATA_LEN); 440 #ifdef CBC_VECTORS_EXTRA_VERBOSE 441 printf(" Offset:0x%x ", offset); 442 #endif 443 if (0 != check_vector(&test)) 444 goto exit; 445 } 446 } 447 448 ret = 0; 449 450 exit: 451 free(P); 452 free(C); 453 free(K); 454 free(IV); 455 free(key_data); 456 printf("\n"); 457 return ret; 458 } 459 460 int 461 main(void) 462 { 463 uint32_t fail = 0; 464 465 srand(TEST_SEED); 466 fail |= test_std_combinations(); 467 fail |= test_random_combinations(); 468 fail |= test_efence_combinations(); 469 if (0 == fail) { 470 printf("...Pass\n"); 471 } else { 472 printf("...Fail\n"); 473 } 474 return fail; 475 } 476