xref: /isa-l_crypto/aes/cbc_std_vectors_random_test.c (revision 38e16e11defa07d24d9d593354096a7ef33c75b7)
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