]> git.proxmox.com Git - ceph.git/blob - ceph/src/crypto/isa-l/isa-l_crypto/aes/cbc_std_vectors_random_test.c
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / crypto / isa-l / isa-l_crypto / aes / cbc_std_vectors_random_test.c
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,
61 uint8_t * IV,
62 uint8_t * keys, uint8_t * out, uint64_t len_bytes);
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]);
248 int i;
249 uint8_t *iv = NULL;
250
251 printf("AES CBC standard test vectors:");
252 #ifdef CBC_VECTORS_VERBOSE
253 printf("\n");
254 #endif
255 posix_memalign((void **)&iv, 16, (CBC_IV_DATA_LEN));
256 if (NULL == iv)
257 return 1;
258
259 for (i = 0; (i < vectors_cnt); i++) {
260 struct cbc_vector vect = cbc_vectors[i];
261
262 posix_memalign((void **)&vect.KEYS, 16, (sizeof(*vect.KEYS)));
263 if (NULL == vect.KEYS)
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;
295 int t;
296
297 printf("AES CBC random test vectors:");
298 #ifdef CBC_VECTORS_VERBOSE
299 fflush(0);
300 #endif
301 test.IV = NULL;
302 posix_memalign((void **)&test.IV, 16, (CBC_IV_DATA_LEN));
303 if (NULL == test.IV)
304 return 1;
305 test.KEYS = NULL;
306 posix_memalign((void **)&test.KEYS, 16, (sizeof(*test.KEYS)));
307 if (NULL == test.KEYS)
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 }