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 <aes_keyexp.h> 36 #include "types.h" 37 #include "ossl_helper.h" 38 #include "cbc_std_vectors.h" 39 40 // define CBC_VECTORS_VERBOSE 41 // define CBC_VECTORS_EXTRA_VERBOSE 42 43 #ifndef TEST_SEED 44 #define TEST_SEED 0x1234 45 #endif 46 #ifndef RANDOMS 47 #define RANDOMS 100 48 #endif 49 #ifndef TEST_LEN 50 #define TEST_LEN (8 * 1024 * 1024) 51 #endif 52 #ifndef PAGE_LEN 53 #define PAGE_LEN (4 * 1024) 54 #endif 55 #ifndef MAX_UNALINED 56 #define MAX_UNALINED (16) 57 #endif 58 59 static isal_cbc_key_size const Ksize[] = { ISAL_CBC_128_BITS, ISAL_CBC_192_BITS, 60 ISAL_CBC_256_BITS }; 61 62 typedef void (*aes_cbc_generic)(uint8_t *in, uint8_t *IV, uint8_t *keys, uint8_t *out, 63 uint64_t len_bytes); 64 65 int 66 OpenSslEnc(uint8_t k_len, uint8_t *key, uint8_t *in, uint8_t *iv, uint8_t *out, uint64_t len_bytes) 67 { 68 if (ISAL_CBC_128_BITS == k_len) { 69 #ifdef CBC_VECTORS_EXTRA_VERBOSE 70 printf(" OpenSSL128 "); 71 #endif 72 openssl_aes_128_cbc_enc(key, (uint8_t *) iv, len_bytes, in, out); 73 } else if (ISAL_CBC_192_BITS == k_len) { 74 #ifdef CBC_VECTORS_EXTRA_VERBOSE 75 printf(" OpenSSL192 "); 76 #endif 77 openssl_aes_192_cbc_enc(key, (uint8_t *) iv, len_bytes, in, out); 78 } else if (ISAL_CBC_256_BITS == k_len) { 79 #ifdef CBC_VECTORS_EXTRA_VERBOSE 80 printf(" OpenSSL256 "); 81 fflush(0); 82 #endif 83 openssl_aes_256_cbc_enc(key, (uint8_t *) iv, len_bytes, in, out); 84 } else { 85 fprintf(stderr, "Invalid key length: %d\n", k_len); 86 return 1; 87 } 88 return 0; 89 } 90 91 int 92 OpenSslDec(uint8_t k_len, uint8_t *key, uint8_t *in, uint8_t *iv, uint8_t *out, uint64_t len_bytes) 93 { 94 if (ISAL_CBC_128_BITS == k_len) { 95 #ifdef CBC_VECTORS_EXTRA_VERBOSE 96 printf(" OpenSSL128 "); 97 #endif 98 openssl_aes_128_cbc_dec(key, (uint8_t *) iv, len_bytes, in, out); 99 } else if (ISAL_CBC_192_BITS == k_len) { 100 #ifdef CBC_VECTORS_EXTRA_VERBOSE 101 printf(" OpenSSL192 "); 102 #endif 103 openssl_aes_192_cbc_dec(key, (uint8_t *) iv, len_bytes, in, out); 104 } else if (ISAL_CBC_256_BITS == k_len) { 105 #ifdef CBC_VECTORS_EXTRA_VERBOSE 106 printf(" OpenSSL256 "); 107 #endif 108 openssl_aes_256_cbc_dec(key, (uint8_t *) iv, len_bytes, in, out); 109 } else { 110 fprintf(stderr, "Invalid key length: %d\n", k_len); 111 return 1; 112 } 113 return 0; 114 } 115 116 void 117 mk_rand_data(uint8_t *data, uint32_t size) 118 { 119 int i; 120 for (i = 0; i < size; i++) { 121 *data++ = rand(); 122 } 123 } 124 125 int 126 check_data(uint8_t *test, uint8_t *expected, uint64_t len, char *data_name) 127 { 128 int mismatch; 129 int fail = 0; 130 uint64_t a; 131 132 mismatch = memcmp(test, expected, len); 133 if (!mismatch) { 134 return fail; 135 } else { 136 fail = 1; 137 printf(" failed %s \t\t", data_name); 138 for (a = 0; a < len; a++) { 139 if (test[a] != expected[a]) { 140 printf(" '%x' != '%x' at 0x%llx of 0x%llx\n", test[a], expected[a], 141 (unsigned long long) a, (unsigned long long) len); 142 break; 143 } 144 } 145 } 146 return fail; 147 } 148 149 int 150 check_vector(struct cbc_vector *vector) 151 { 152 uint8_t *pt_test = NULL; 153 uint8_t *o_ct_test = NULL; 154 int fail = 0; 155 aes_cbc_generic enc; 156 aes_cbc_generic dec; 157 158 #ifdef CBC_VECTORS_VERBOSE 159 printf(" Keylen:%d PLen:%d ", (int) vector->K_LEN, (int) vector->P_LEN); 160 #ifdef CBC_VECTORS_EXTRA_VERBOSE 161 printf(" K:%p P:%p C:%p IV:%p expC:%p Keys:%p ", vector->K, vector->P, vector->C, 162 vector->IV, vector->EXP_C, vector->KEYS); 163 #endif 164 fflush(0); 165 #else 166 printf("."); 167 #endif 168 169 if (ISAL_CBC_128_BITS == vector->K_LEN) { 170 enc = (aes_cbc_generic) &isal_aes_cbc_enc_128; 171 dec = (aes_cbc_generic) &isal_aes_cbc_dec_128; 172 isal_aes_keyexp_128(vector->K, vector->KEYS->enc_keys, vector->KEYS->dec_keys); 173 #ifdef CBC_VECTORS_EXTRA_VERBOSE 174 printf(" CBC128 "); 175 #endif 176 } else if (ISAL_CBC_192_BITS == vector->K_LEN) { 177 enc = (aes_cbc_generic) &isal_aes_cbc_enc_192; 178 dec = (aes_cbc_generic) &isal_aes_cbc_dec_192; 179 isal_aes_keyexp_192(vector->K, vector->KEYS->enc_keys, vector->KEYS->dec_keys); 180 #ifdef CBC_VECTORS_EXTRA_VERBOSE 181 printf(" CBC192 "); 182 #endif 183 } else if (ISAL_CBC_256_BITS == vector->K_LEN) { 184 enc = (aes_cbc_generic) &isal_aes_cbc_enc_256; 185 dec = (aes_cbc_generic) &isal_aes_cbc_dec_256; 186 isal_aes_keyexp_256(vector->K, vector->KEYS->enc_keys, vector->KEYS->dec_keys); 187 #ifdef CBC_VECTORS_EXTRA_VERBOSE 188 printf(" CBC256 "); 189 #endif 190 } else { 191 printf("Invalid key length: %d\n", vector->K_LEN); 192 return 1; 193 } 194 195 // Allocate space for the calculated ciphertext 196 pt_test = malloc(vector->P_LEN); 197 o_ct_test = malloc(vector->P_LEN); 198 if ((pt_test == NULL) || (o_ct_test == NULL)) { 199 fprintf(stderr, "Can't allocate ciphertext memory\n"); 200 fail = 1; 201 goto exit; 202 } 203 204 #ifdef CBC_VECTORS_VERBOSE 205 fflush(0); 206 #endif 207 //// 208 // ISA-l Encrypt 209 //// 210 enc(vector->P, vector->IV, vector->KEYS->enc_keys, vector->C, vector->P_LEN); 211 if (NULL != vector->EXP_C) { // when the encrypted text is know verify correct 212 fail |= check_data(vector->EXP_C, vector->C, vector->P_LEN, 213 "ISA-L expected cypher text (C)"); 214 } 215 OpenSslEnc(vector->K_LEN, vector->K, vector->P, vector->IV, o_ct_test, vector->P_LEN); 216 fail |= check_data(vector->C, o_ct_test, vector->P_LEN, "OpenSSL vs ISA-L cypher text (C)"); 217 218 memcpy(pt_test, vector->P, vector->P_LEN); 219 memset(vector->P, 0, vector->P_LEN); 220 #ifdef CBC_VECTORS_VERBOSE 221 fflush(0); 222 #endif 223 224 //// 225 // ISA-l Decrypt 226 //// 227 dec(vector->C, vector->IV, vector->KEYS->dec_keys, vector->P, vector->P_LEN); 228 fail |= check_data(vector->P, pt_test, vector->P_LEN, "ISA-L decrypted plain text (P)"); 229 memset(vector->P, 0, vector->P_LEN); 230 dec(o_ct_test, vector->IV, vector->KEYS->dec_keys, vector->P, vector->P_LEN); 231 fail |= check_data(vector->P, pt_test, vector->P_LEN, "ISA-L decrypted OpenSSL (P)"); 232 memset(vector->P, 0, vector->P_LEN); 233 OpenSslDec(vector->K_LEN, vector->K, vector->C, vector->IV, vector->P, vector->P_LEN); 234 fail |= check_data(vector->P, pt_test, vector->P_LEN, "OpenSSL decrypted ISA-L (P)"); 235 236 exit: 237 free(pt_test); 238 free(o_ct_test); 239 240 #ifdef CBC_VECTORS_VERBOSE 241 if (fail) 242 printf("Failed"); 243 else 244 printf("Passed"); 245 246 printf("\n"); 247 #endif 248 249 return fail; 250 } 251 252 int 253 test_std_combinations(void) 254 { 255 int const vectors_cnt = sizeof(cbc_vectors) / sizeof(cbc_vectors[0]); 256 int i, ret; 257 uint8_t *iv = NULL; 258 259 printf("AES CBC standard test vectors:"); 260 #ifdef CBC_VECTORS_VERBOSE 261 printf("\n"); 262 #endif 263 ret = posix_memalign((void **) &iv, 16, (ISAL_CBC_IV_DATA_LEN)); 264 if ((0 != ret) || (NULL == iv)) 265 return 1; 266 267 for (i = 0; (i < vectors_cnt); i++) { 268 struct cbc_vector vect = cbc_vectors[i]; 269 270 ret = posix_memalign((void **) &vect.KEYS, 16, (sizeof(*vect.KEYS))); 271 if ((0 != ret) || (NULL == vect.KEYS)) { 272 ret = 1; 273 break; 274 } 275 // IV data must be aligned to 16 byte boundary so move data in aligned buffer and 276 // change out the pointer 277 memcpy(iv, vect.IV, ISAL_CBC_IV_DATA_LEN); 278 vect.IV = iv; 279 vect.C = NULL; 280 vect.C = malloc(vect.P_LEN); 281 if ((NULL == vect.C)) { 282 aligned_free(vect.KEYS); 283 ret = 1; 284 break; 285 } 286 #ifdef CBC_VECTORS_VERBOSE 287 printf("vector[%d of %d] ", i, vectors_cnt); 288 #endif 289 if (0 == (i % 25)) 290 printf("\n"); 291 if (0 == (i % 10)) 292 fflush(0); 293 294 if (0 != check_vector(&vect)) { 295 aligned_free(vect.KEYS); 296 free(vect.C); 297 ret = 1; 298 break; 299 } 300 301 aligned_free(vect.KEYS); 302 free(vect.C); 303 } 304 305 aligned_free(iv); 306 printf("\n"); 307 return ret; 308 } 309 310 int 311 test_random_combinations(void) 312 { 313 struct cbc_vector test; 314 int t, ret; 315 316 printf("AES CBC random test vectors:"); 317 #ifdef CBC_VECTORS_VERBOSE 318 fflush(0); 319 #endif 320 test.IV = NULL; 321 ret = posix_memalign((void **) &test.IV, 16, (ISAL_CBC_IV_DATA_LEN)); 322 if ((0 != ret) || (NULL == test.IV)) 323 return 1; 324 test.KEYS = NULL; 325 ret = posix_memalign((void **) &test.KEYS, 16, (sizeof(*test.KEYS))); 326 if ((0 != ret) || (NULL == test.KEYS)) { 327 ret = 1; 328 goto exit; 329 } 330 331 for (t = 0; RANDOMS > t; t++) { 332 int Plen = 16 + ((rand() % TEST_LEN) & ~0xf); // must be a 16byte multiple 333 int offset = (rand() % MAX_UNALINED); 334 int Kindex = (rand() % (sizeof(Ksize) / 335 sizeof(Ksize[0]))); // select one of the valid key sizes 336 337 if (0 == (t % 25)) 338 printf("\n"); 339 if (0 == (t % 10)) 340 fflush(0); 341 342 test.C = NULL; 343 test.P = NULL; 344 test.K = NULL; 345 test.EXP_C = NULL; 346 test.P_LEN = Plen; 347 test.K_LEN = Ksize[Kindex]; 348 349 test.P = malloc(test.P_LEN + offset); 350 test.C = malloc(test.P_LEN + offset); 351 test.K = malloc(test.K_LEN + offset); 352 if ((NULL == test.P) || (NULL == test.C) || (NULL == test.K)) { 353 printf("malloc of testsize:0x%x failed\n", Plen); 354 free(test.P); 355 free(test.C); 356 free(test.K); 357 ret = -1; 358 break; 359 } 360 test.P += offset; 361 test.C += offset; 362 test.K += offset; 363 364 mk_rand_data(test.P, test.P_LEN); 365 mk_rand_data(test.K, test.K_LEN); 366 mk_rand_data(test.IV, ISAL_CBC_IV_DATA_LEN); 367 368 #ifdef CBC_VECTORS_EXTRA_VERBOSE 369 printf(" Offset:0x%x ", offset); 370 #endif 371 if (0 != check_vector(&test)) 372 ret = 1; 373 374 test.C -= offset; 375 free(test.C); 376 test.K -= offset; 377 free(test.K); 378 test.P -= offset; 379 free(test.P); 380 381 if (ret != 0) 382 break; 383 } 384 385 exit: 386 aligned_free(test.IV); 387 aligned_free(test.KEYS); 388 printf("\n"); 389 return ret; 390 } 391 392 int 393 test_efence_combinations(void) 394 { 395 struct cbc_vector test; 396 int offset = 0; 397 int key_idx; 398 uint8_t *P = NULL, *C = NULL, *K = NULL, *IV = NULL; 399 uint8_t *key_data = NULL; 400 int ret = 1; 401 402 P = malloc(PAGE_LEN); 403 C = malloc(PAGE_LEN); 404 K = malloc(PAGE_LEN); 405 IV = malloc(PAGE_LEN); 406 key_data = malloc(PAGE_LEN); 407 408 if ((NULL == P) || (NULL == C) || (NULL == K) || (NULL == IV) || (NULL == key_data)) { 409 printf("malloc of testsize:0x%x failed\n", PAGE_LEN); 410 goto exit; 411 } 412 // place buffers to end at page boundary 413 test.P_LEN = PAGE_LEN / 2; 414 test.EXP_C = NULL; 415 416 printf("AES CBC efence test vectors:"); 417 for (key_idx = 0; key_idx < (sizeof(Ksize) / sizeof(Ksize[0])); key_idx++) { 418 test.K_LEN = Ksize[key_idx]; 419 420 for (offset = 0; MAX_UNALINED > offset; offset++) { 421 if (0 == (offset % 80)) 422 printf("\n"); 423 // move the start and size of the data block towards the end of the page 424 test.P_LEN = ((PAGE_LEN / (1 + (2 * offset))) & 425 ~0xff); // must be a multiple of 16 426 if (16 > test.P_LEN) 427 test.P_LEN = 16; 428 // Place data at end of page 429 test.P = P + PAGE_LEN - test.P_LEN - offset; 430 test.C = C + PAGE_LEN - test.P_LEN - offset; 431 test.K = K + PAGE_LEN - test.K_LEN - offset; 432 test.IV = IV + PAGE_LEN - ISAL_CBC_IV_DATA_LEN - offset; 433 test.IV = 434 test.IV - ((uint64_t) test.IV & 0xff); // align to 16 byte boundary 435 test.KEYS = (struct isal_cbc_key_data *) (key_data + PAGE_LEN - 436 sizeof(*test.KEYS) - offset); 437 test.KEYS = 438 (struct isal_cbc_key_data *) ((uint8_t *) test.KEYS - 439 ((uint64_t) test.KEYS & 440 0xff)); // align to 16 byte boundary 441 442 mk_rand_data(test.P, test.P_LEN); 443 mk_rand_data(test.K, test.K_LEN); 444 mk_rand_data(test.IV, ISAL_CBC_IV_DATA_LEN); 445 #ifdef CBC_VECTORS_EXTRA_VERBOSE 446 printf(" Offset:0x%x ", offset); 447 #endif 448 if (0 != check_vector(&test)) 449 goto exit; 450 } 451 } 452 453 ret = 0; 454 455 exit: 456 free(P); 457 free(C); 458 free(K); 459 free(IV); 460 free(key_data); 461 printf("\n"); 462 return ret; 463 } 464 465 int 466 main(void) 467 { 468 uint32_t fail = 0; 469 470 srand(TEST_SEED); 471 fail |= test_std_combinations(); 472 fail |= test_random_combinations(); 473 fail |= test_efence_combinations(); 474 if (0 == fail) { 475 printf("...Pass\n"); 476 } else { 477 printf("...Fail\n"); 478 } 479 return fail; 480 } 481