]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /********************************************************************** |
2 | Copyright(c) 2011-2016 Intel Corporation All rights reserved. | |
3 | ||
4 | Redistribution and use in source and binary forms, with or without | |
1e59de90 | 5 | modification, are permitted provided that the following conditions |
7c673cae FG |
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 | ||
1e59de90 TL |
60 | typedef void (*aes_cbc_generic)(uint8_t * in, |
61 | uint8_t * IV, | |
62 | uint8_t * keys, uint8_t * out, uint64_t len_bytes); | |
7c673cae FG |
63 | |
64 | int OpenSslEnc(uint8_t k_len, | |
65 | uint8_t * key, uint8_t * in, uint8_t * iv, uint8_t * out, uint64_t len_bytes) | |
66 | { | |
67 | if (CBC_128_BITS == k_len) { | |
68 | #ifdef CBC_VECTORS_EXTRA_VERBOSE | |
69 | printf(" OpenSSL128 "); | |
70 | #endif | |
71 | openssl_aes_128_cbc_enc(key, (uint8_t *) iv, len_bytes, in, out); | |
72 | } else if (CBC_192_BITS == k_len) { | |
73 | #ifdef CBC_VECTORS_EXTRA_VERBOSE | |
74 | printf(" OpenSSL192 "); | |
75 | #endif | |
76 | openssl_aes_192_cbc_enc(key, (uint8_t *) iv, len_bytes, in, out); | |
77 | } else if (CBC_256_BITS == k_len) { | |
78 | #ifdef CBC_VECTORS_EXTRA_VERBOSE | |
79 | printf(" OpenSSL256 "); | |
80 | fflush(0); | |
81 | #endif | |
82 | openssl_aes_256_cbc_enc(key, (uint8_t *) iv, len_bytes, in, out); | |
83 | } else { | |
84 | fprintf(stderr, "Invalid key length: %d\n", k_len); | |
85 | return 1; | |
86 | } | |
87 | return 0; | |
88 | } | |
89 | ||
90 | int OpenSslDec(uint8_t k_len, | |
91 | uint8_t * key, uint8_t * in, uint8_t * iv, uint8_t * out, uint64_t len_bytes) | |
92 | { | |
93 | if (CBC_128_BITS == k_len) { | |
94 | #ifdef CBC_VECTORS_EXTRA_VERBOSE | |
95 | printf(" OpenSSL128 "); | |
96 | #endif | |
97 | openssl_aes_128_cbc_dec(key, (uint8_t *) iv, len_bytes, in, out); | |
98 | } else if (CBC_192_BITS == k_len) { | |
99 | #ifdef CBC_VECTORS_EXTRA_VERBOSE | |
100 | printf(" OpenSSL192 "); | |
101 | #endif | |
102 | openssl_aes_192_cbc_dec(key, (uint8_t *) iv, len_bytes, in, out); | |
103 | } else if (CBC_256_BITS == k_len) { | |
104 | #ifdef CBC_VECTORS_EXTRA_VERBOSE | |
105 | printf(" OpenSSL256 "); | |
106 | #endif | |
107 | openssl_aes_256_cbc_dec(key, (uint8_t *) iv, len_bytes, in, out); | |
108 | } else { | |
109 | fprintf(stderr, "Invalid key length: %d\n", k_len); | |
110 | return 1; | |
111 | } | |
112 | return 0; | |
113 | } | |
114 | ||
115 | void 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 check_data(uint8_t * test, uint8_t * expected, uint64_t len, char *data_name) | |
124 | { | |
125 | int mismatch; | |
126 | int OK = 0; | |
127 | uint64_t a; | |
128 | ||
129 | mismatch = memcmp(test, expected, len); | |
130 | if (!mismatch) { | |
131 | return OK; | |
132 | ||
133 | } else { | |
134 | OK = 1; | |
135 | printf(" failed %s \t\t", data_name); | |
136 | for (a = 0; a < len; a++) { | |
137 | if (test[a] != expected[a]) { | |
138 | printf(" '%x' != '%x' at %lx of %lx\n", | |
139 | test[a], expected[a], a, len); | |
140 | break; | |
141 | } | |
142 | } | |
143 | } | |
144 | return OK; | |
145 | } | |
146 | ||
147 | int check_vector(struct cbc_vector *vector) | |
148 | { | |
149 | uint8_t *pt_test = NULL; | |
150 | uint8_t *o_ct_test = NULL; | |
151 | int OK = 0; | |
152 | aes_cbc_generic enc; | |
153 | aes_cbc_generic dec; | |
154 | ||
155 | #ifdef CBC_VECTORS_VERBOSE | |
156 | printf(" Keylen:%d PLen:%d ", (int)vector->K_LEN, (int)vector->P_LEN); | |
157 | #ifdef CBC_VECTORS_EXTRA_VERBOSE | |
158 | printf(" K:%p P:%p C:%p IV:%p expC:%p Keys:%p ", vector->K, vector->P, vector->C, | |
159 | vector->IV, vector->EXP_C, vector->KEYS); | |
160 | #endif | |
161 | fflush(0); | |
162 | #else | |
163 | printf("."); | |
164 | #endif | |
165 | ||
166 | if (CBC_128_BITS == vector->K_LEN) { | |
167 | enc = (aes_cbc_generic) & aes_cbc_enc_128; | |
168 | dec = (aes_cbc_generic) & aes_cbc_dec_128; | |
169 | #ifdef CBC_VECTORS_EXTRA_VERBOSE | |
170 | printf(" CBC128 "); | |
171 | #endif | |
172 | } else if (CBC_192_BITS == vector->K_LEN) { | |
173 | enc = (aes_cbc_generic) & aes_cbc_enc_192; | |
174 | dec = (aes_cbc_generic) & aes_cbc_dec_192; | |
175 | #ifdef CBC_VECTORS_EXTRA_VERBOSE | |
176 | printf(" CBC192 "); | |
177 | #endif | |
178 | } else if (CBC_256_BITS == vector->K_LEN) { | |
179 | enc = (aes_cbc_generic) & aes_cbc_enc_256; | |
180 | dec = (aes_cbc_generic) & aes_cbc_dec_256; | |
181 | #ifdef CBC_VECTORS_EXTRA_VERBOSE | |
182 | printf(" CBC256 "); | |
183 | #endif | |
184 | } else { | |
185 | printf("Invalid key length: %d\n", vector->K_LEN); | |
186 | return 1; | |
187 | } | |
188 | ||
189 | // Allocate space for the calculated ciphertext | |
190 | pt_test = malloc(vector->P_LEN); | |
191 | o_ct_test = malloc(vector->P_LEN); | |
192 | if ((pt_test == NULL) || (o_ct_test == NULL)) { | |
193 | fprintf(stderr, "Can't allocate ciphertext memory\n"); | |
194 | return 1; | |
195 | } | |
196 | ||
197 | aes_cbc_precomp(vector->K, vector->K_LEN, vector->KEYS); | |
198 | ||
199 | #ifdef CBC_VECTORS_VERBOSE | |
200 | fflush(0); | |
201 | #endif | |
202 | //// | |
203 | // ISA-l Encrypt | |
204 | //// | |
205 | enc(vector->P, vector->IV, vector->KEYS->enc_keys, vector->C, vector->P_LEN); | |
206 | if (NULL != vector->EXP_C) { //when the encrypted text is know verify correct | |
207 | OK |= | |
208 | check_data(vector->EXP_C, vector->C, vector->P_LEN, | |
209 | "ISA-L expected cypher text (C)"); | |
210 | } | |
211 | OpenSslEnc(vector->K_LEN, vector->K, vector->P, vector->IV, o_ct_test, vector->P_LEN); | |
212 | OK |= | |
213 | check_data(vector->C, o_ct_test, vector->P_LEN, | |
214 | "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 | OK |= 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 | OK |= 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 | OK |= check_data(vector->P, pt_test, vector->P_LEN, "OpenSSL decrypted ISA-L (P)"); | |
233 | #ifdef CBC_VECTORS_VERBOSE | |
234 | if (OK) | |
235 | printf("Failed"); | |
236 | else | |
237 | printf("Passed"); | |
238 | ||
239 | printf("\n"); | |
240 | #endif | |
241 | ||
242 | return OK; | |
243 | } | |
244 | ||
245 | int test_std_combinations(void) | |
246 | { | |
247 | int const vectors_cnt = sizeof(cbc_vectors) / sizeof(cbc_vectors[0]); | |
1e59de90 | 248 | int i, ret; |
7c673cae FG |
249 | uint8_t *iv = NULL; |
250 | ||
251 | printf("AES CBC standard test vectors:"); | |
252 | #ifdef CBC_VECTORS_VERBOSE | |
253 | printf("\n"); | |
254 | #endif | |
1e59de90 TL |
255 | ret = posix_memalign((void **)&iv, 16, (CBC_IV_DATA_LEN)); |
256 | if ((0 != ret) || (NULL == iv)) | |
7c673cae FG |
257 | return 1; |
258 | ||
259 | for (i = 0; (i < vectors_cnt); i++) { | |
260 | struct cbc_vector vect = cbc_vectors[i]; | |
261 | ||
1e59de90 TL |
262 | ret = posix_memalign((void **)&vect.KEYS, 16, (sizeof(*vect.KEYS))); |
263 | if ((0 != ret) || (NULL == vect.KEYS)) | |
7c673cae FG |
264 | return 1; |
265 | // IV data must be aligned to 16 byte boundary so move data in aligned buffer and change out the pointer | |
266 | memcpy(iv, vect.IV, CBC_IV_DATA_LEN); | |
267 | vect.IV = iv; | |
268 | vect.C = NULL; | |
269 | vect.C = malloc(vect.P_LEN); | |
270 | if ((NULL == vect.C)) | |
271 | return 1; | |
272 | #ifdef CBC_VECTORS_VERBOSE | |
273 | printf("vector[%d of %d] ", i, vectors_cnt); | |
274 | #endif | |
275 | if (0 == (i % 25)) | |
276 | printf("\n"); | |
277 | if (0 == (i % 10)) | |
278 | fflush(0); | |
279 | ||
280 | if (0 != check_vector(&vect)) | |
281 | return 1; | |
282 | ||
283 | aligned_free(vect.KEYS); | |
284 | free(vect.C); | |
285 | } | |
286 | ||
287 | aligned_free(iv); | |
288 | printf("\n"); | |
289 | return 0; | |
290 | } | |
291 | ||
292 | int test_random_combinations(void) | |
293 | { | |
294 | struct cbc_vector test; | |
1e59de90 | 295 | int t, ret; |
7c673cae FG |
296 | |
297 | printf("AES CBC random test vectors:"); | |
298 | #ifdef CBC_VECTORS_VERBOSE | |
299 | fflush(0); | |
300 | #endif | |
301 | test.IV = NULL; | |
1e59de90 TL |
302 | ret = posix_memalign((void **)&test.IV, 16, (CBC_IV_DATA_LEN)); |
303 | if ((0 != ret) || (NULL == test.IV)) | |
7c673cae FG |
304 | return 1; |
305 | test.KEYS = NULL; | |
1e59de90 TL |
306 | ret = posix_memalign((void **)&test.KEYS, 16, (sizeof(*test.KEYS))); |
307 | if ((0 != ret) || (NULL == test.KEYS)) | |
7c673cae FG |
308 | return 1; |
309 | ||
310 | for (t = 0; RANDOMS > t; t++) { | |
311 | int Plen = 16 + ((rand() % TEST_LEN) & ~0xf); //must be a 16byte multiple | |
312 | int offset = (rand() % MAX_UNALINED); | |
313 | int Kindex = (rand() % (sizeof(Ksize) / sizeof(Ksize[0]))); // select one of the valid key sizes | |
314 | ||
315 | if (0 == (t % 25)) | |
316 | printf("\n"); | |
317 | if (0 == (t % 10)) | |
318 | fflush(0); | |
319 | ||
320 | test.C = NULL; | |
321 | test.P = NULL; | |
322 | test.K = NULL; | |
323 | test.EXP_C = NULL; | |
324 | test.P_LEN = Plen; | |
325 | test.K_LEN = Ksize[Kindex]; | |
326 | ||
327 | test.P = malloc(test.P_LEN + offset); | |
328 | test.C = malloc(test.P_LEN + offset); | |
329 | test.K = malloc(test.K_LEN + offset); | |
330 | if ((NULL == test.P) || (NULL == test.C) || (NULL == test.K)) { | |
331 | printf("malloc of testsize:0x%x failed\n", Plen); | |
332 | return -1; | |
333 | } | |
334 | test.P += offset; | |
335 | test.C += offset; | |
336 | test.K += offset; | |
337 | ||
338 | mk_rand_data(test.P, test.P_LEN); | |
339 | mk_rand_data(test.K, test.K_LEN); | |
340 | mk_rand_data(test.IV, CBC_IV_DATA_LEN); | |
341 | ||
342 | #ifdef CBC_VECTORS_EXTRA_VERBOSE | |
343 | printf(" Offset:0x%x ", offset); | |
344 | #endif | |
345 | if (0 != check_vector(&test)) | |
346 | return 1; | |
347 | ||
348 | test.C -= offset; | |
349 | free(test.C); | |
350 | test.K -= offset; | |
351 | free(test.K); | |
352 | test.P -= offset; | |
353 | free(test.P); | |
354 | } | |
355 | ||
356 | aligned_free(test.IV); | |
357 | aligned_free(test.KEYS); | |
358 | printf("\n"); | |
359 | return 0; | |
360 | } | |
361 | ||
362 | int test_efence_combinations(void) | |
363 | { | |
364 | struct cbc_vector test; | |
365 | int offset = 0; | |
366 | int key_idx; | |
367 | uint8_t *P = NULL, *C = NULL, *K = NULL, *IV = NULL; | |
368 | uint8_t *key_data = NULL; | |
369 | ||
370 | P = malloc(PAGE_LEN); | |
371 | C = malloc(PAGE_LEN); | |
372 | K = malloc(PAGE_LEN); | |
373 | IV = malloc(PAGE_LEN); | |
374 | key_data = malloc(PAGE_LEN); | |
375 | ||
376 | if ((NULL == P) || (NULL == C) || (NULL == K) || (NULL == IV) | |
377 | || (NULL == key_data) | |
378 | ) { | |
379 | printf("malloc of testsize:0x%x failed\n", PAGE_LEN); | |
380 | return -1; | |
381 | } | |
382 | // place buffers to end at page boundary | |
383 | test.P_LEN = PAGE_LEN / 2; | |
384 | test.EXP_C = NULL; | |
385 | ||
386 | printf("AES CBC efence test vectors:"); | |
387 | for (key_idx = 0; key_idx < (sizeof(Ksize) / sizeof(Ksize[0])); key_idx++) { | |
388 | test.K_LEN = Ksize[key_idx]; | |
389 | ||
390 | for (offset = 0; MAX_UNALINED > offset; offset++) { | |
391 | if (0 == (offset % 80)) | |
392 | printf("\n"); | |
393 | // move the start and size of the data block towards the end of the page | |
394 | test.P_LEN = ((PAGE_LEN / (1 + (2 * offset))) & ~0xff); // must be a multiple of 16 | |
395 | if (16 > test.P_LEN) | |
396 | test.P_LEN = 16; | |
397 | //Place data at end of page | |
398 | test.P = P + PAGE_LEN - test.P_LEN - offset; | |
399 | test.C = C + PAGE_LEN - test.P_LEN - offset; | |
400 | test.K = K + PAGE_LEN - test.K_LEN - offset; | |
401 | test.IV = IV + PAGE_LEN - CBC_IV_DATA_LEN - offset; | |
402 | test.IV = test.IV - ((uint64_t) test.IV & 0xff); // align to 16 byte boundary | |
403 | test.KEYS = (struct cbc_key_data *) | |
404 | (key_data + PAGE_LEN - sizeof(*test.KEYS) - offset); | |
405 | test.KEYS = (struct cbc_key_data *) | |
406 | ((uint8_t *) test.KEYS - ((uint64_t) test.KEYS & 0xff)); // align to 16 byte boundary | |
407 | ||
408 | mk_rand_data(test.P, test.P_LEN); | |
409 | mk_rand_data(test.K, test.K_LEN); | |
410 | mk_rand_data(test.IV, CBC_IV_DATA_LEN); | |
411 | #ifdef CBC_VECTORS_EXTRA_VERBOSE | |
412 | printf(" Offset:0x%x ", offset); | |
413 | #endif | |
414 | if (0 != check_vector(&test)) | |
415 | return 1; | |
416 | } | |
417 | ||
418 | } | |
419 | ||
420 | free(P); | |
421 | free(C); | |
422 | free(K); | |
423 | free(IV); | |
424 | free(key_data); | |
425 | printf("\n"); | |
426 | return 0; | |
427 | } | |
428 | ||
429 | int main(void) | |
430 | { | |
431 | uint32_t OK = 0; | |
432 | ||
433 | srand(TEST_SEED); | |
434 | OK |= test_std_combinations(); | |
435 | OK |= test_random_combinations(); | |
436 | OK |= test_efence_combinations(); | |
437 | if (0 == OK) { | |
438 | printf("...Pass\n"); | |
439 | } else { | |
440 | printf("...Fail\n"); | |
441 | } | |
442 | return OK; | |
443 | } |