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 /* 31 * Run list of standard CBC test vectors through encode and decode checks. 32 */ 33 34 #include <stdlib.h> 35 #include <stdio.h> 36 #include <stdint.h> 37 #include <string.h> 38 #include <aes_cbc.h> 39 #include <aes_keyexp.h> 40 #include "types.h" 41 #include "cbc_std_vectors.h" 42 43 typedef void (*aes_cbc_generic)(uint8_t *in, uint8_t *IV, uint8_t *keys, uint8_t *out, 44 uint64_t len_bytes); 45 46 int 47 check_data(uint8_t *test, uint8_t *expected, uint64_t len, char *data_name) 48 { 49 int mismatch; 50 int OK = 0; 51 uint64_t a; 52 53 mismatch = memcmp(test, expected, len); 54 if (!mismatch) { 55 return OK; 56 } else { 57 OK = 1; 58 printf(" failed %s \t\t", data_name); 59 for (a = 0; a < len; a++) { 60 if (test[a] != expected[a]) { 61 printf(" '%x' != '%x' at %llx of %llx\n", test[a], expected[a], 62 (unsigned long long) a, (unsigned long long) len); 63 break; 64 } 65 } 66 } 67 return OK; 68 } 69 70 int 71 check_vector(struct cbc_vector *vector) 72 { 73 uint8_t *pt_test = NULL; 74 int OK = 0; 75 aes_cbc_generic enc; 76 aes_cbc_generic dec; 77 78 DEBUG_PRINT((" Keylen:%d PLen:%d ", (int) vector->K_LEN, (int) vector->P_LEN)); 79 DEBUG_PRINT((" K:%p P:%p C:%p IV:%p expC:%p Keys:%p ", vector->K, vector->P, vector->C, 80 vector->IV, vector->EXP_C, vector->KEYS)); 81 printf("."); 82 83 switch (vector->K_LEN) { 84 case CBC_128_BITS: 85 enc = (aes_cbc_generic) &isal_aes_cbc_enc_128; 86 dec = (aes_cbc_generic) &isal_aes_cbc_dec_128; 87 isal_aes_keyexp_128(vector->K, vector->KEYS->enc_keys, vector->KEYS->dec_keys); 88 DEBUG_PRINT((" CBC128 ")); 89 break; 90 case CBC_192_BITS: 91 enc = (aes_cbc_generic) &isal_aes_cbc_enc_192; 92 dec = (aes_cbc_generic) &isal_aes_cbc_dec_192; 93 isal_aes_keyexp_192(vector->K, vector->KEYS->enc_keys, vector->KEYS->dec_keys); 94 DEBUG_PRINT((" CBC192 ")); 95 break; 96 case CBC_256_BITS: 97 enc = (aes_cbc_generic) &isal_aes_cbc_enc_256; 98 dec = (aes_cbc_generic) &isal_aes_cbc_dec_256; 99 isal_aes_keyexp_256(vector->K, vector->KEYS->enc_keys, vector->KEYS->dec_keys); 100 DEBUG_PRINT((" CBC256 ")); 101 break; 102 default: 103 printf("Invalid key length: %d\n", vector->K_LEN); 104 return 1; 105 } 106 107 // Allocate space for the calculated ciphertext 108 pt_test = malloc(vector->P_LEN); 109 110 if (pt_test == NULL) { 111 fprintf(stderr, "Can't allocate ciphertext memory\n"); 112 return 1; 113 } 114 115 //// 116 // ISA-L CBC Encrypt (out-of-place) 117 //// 118 enc(vector->P, vector->IV, vector->KEYS->enc_keys, vector->C, vector->P_LEN); 119 120 if (NULL != vector->EXP_C) { // when the encrypted text is known verify correct 121 OK |= check_data(vector->EXP_C, vector->C, vector->P_LEN, 122 "AES-CBC out-of-place encryption"); 123 } 124 125 //// 126 // ISA-L CBC Encrypt (in-place) 127 //// 128 memcpy(vector->C, vector->P, vector->P_LEN); 129 enc(vector->C, vector->IV, vector->KEYS->enc_keys, vector->C, vector->P_LEN); 130 131 if (NULL != vector->EXP_C) { // when the encrypted text is known verify correct 132 OK |= check_data(vector->EXP_C, vector->C, vector->P_LEN, 133 "AES-CBC in-place encryption"); 134 } 135 memcpy(pt_test, vector->P, vector->P_LEN); 136 memset(vector->P, 0, vector->P_LEN); 137 138 //// 139 // ISA-L CBC Decrypt (out-of-place) 140 //// 141 dec(vector->C, vector->IV, vector->KEYS->dec_keys, vector->P, vector->P_LEN); 142 OK |= check_data(vector->P, pt_test, vector->P_LEN, "AES-CBC in-place decryption"); 143 144 //// 145 // ISA-L CBC Decrypt (in-place) 146 //// 147 memcpy(vector->P, vector->C, vector->P_LEN); 148 dec(vector->P, vector->IV, vector->KEYS->dec_keys, vector->P, vector->P_LEN); 149 OK |= check_data(vector->P, pt_test, vector->P_LEN, "AES-CBC in-place decryption"); 150 DEBUG_PRINT((OK ? "Failed\n" : "Passed\n")); 151 152 free(pt_test); 153 return OK; 154 } 155 156 int 157 test_std_combinations(void) 158 { 159 int const vectors_cnt = sizeof(cbc_vectors) / sizeof(cbc_vectors[0]); 160 int i, ret; 161 uint8_t *iv = NULL; 162 163 printf("AES CBC standard test vectors: "); 164 165 ret = posix_memalign((void **) &iv, 16, (CBC_IV_DATA_LEN)); 166 if ((0 != ret) || (NULL == iv)) 167 return 1; 168 169 for (i = 0; (i < vectors_cnt); i++) { 170 struct cbc_vector vect = cbc_vectors[i]; 171 172 ret = posix_memalign((void **) &(vect.KEYS), 16, sizeof(*vect.KEYS)); 173 if ((0 != ret) || (NULL == vect.KEYS)) { 174 ret = 1; 175 break; 176 } 177 // IV data must be aligned to 16 byte boundary so move data in 178 // aligned buffer and change out the pointer 179 memcpy(iv, vect.IV, CBC_IV_DATA_LEN); 180 vect.IV = iv; 181 vect.C = malloc(vect.P_LEN); 182 if (NULL == vect.C) { 183 ret = 1; 184 aligned_free(vect.KEYS); 185 vect.KEYS = NULL; 186 break; 187 } 188 189 DEBUG_PRINT(("vector[%d of %d] ", i, vectors_cnt)); 190 191 if (0 != check_vector(&vect)) 192 ret = 1; 193 194 aligned_free(vect.KEYS); 195 vect.KEYS = NULL; 196 free(vect.C); 197 vect.C = NULL; 198 199 if (ret != 0) 200 break; 201 } 202 203 aligned_free(iv); 204 return ret; 205 } 206 207 int 208 main(void) 209 { 210 uint32_t OK = 0; 211 212 OK = test_std_combinations(); 213 214 printf(0 == OK ? "Pass\n" : "Fail\n"); 215 return OK; 216 } 217