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