]>
Commit | Line | Data |
---|---|---|
da7f033d HX |
1 | /* |
2 | * Algorithm testing framework and tests. | |
3 | * | |
4 | * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> | |
5 | * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org> | |
6 | * Copyright (c) 2007 Nokia Siemens Networks | |
7 | * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au> | |
3f47a03d | 8 | * Copyright (c) 2019 Google LLC |
da7f033d | 9 | * |
69435b94 AH |
10 | * Updated RFC4106 AES-GCM testing. |
11 | * Authors: Aidan O'Mahony (aidan.o.mahony@intel.com) | |
12 | * Adrian Hoban <adrian.hoban@intel.com> | |
13 | * Gabriele Paoloni <gabriele.paoloni@intel.com> | |
14 | * Tadeusz Struk (tadeusz.struk@intel.com) | |
15 | * Copyright (c) 2010, Intel Corporation. | |
16 | * | |
da7f033d HX |
17 | * This program is free software; you can redistribute it and/or modify it |
18 | * under the terms of the GNU General Public License as published by the Free | |
19 | * Software Foundation; either version 2 of the License, or (at your option) | |
20 | * any later version. | |
21 | * | |
22 | */ | |
23 | ||
1ce33115 | 24 | #include <crypto/aead.h> |
da7f033d | 25 | #include <crypto/hash.h> |
12773d93 | 26 | #include <crypto/skcipher.h> |
da7f033d | 27 | #include <linux/err.h> |
1c41b882 | 28 | #include <linux/fips.h> |
da7f033d | 29 | #include <linux/module.h> |
3f47a03d | 30 | #include <linux/once.h> |
25f9dddb | 31 | #include <linux/random.h> |
da7f033d HX |
32 | #include <linux/scatterlist.h> |
33 | #include <linux/slab.h> | |
34 | #include <linux/string.h> | |
7647d6ce | 35 | #include <crypto/rng.h> |
64d1cdfb | 36 | #include <crypto/drbg.h> |
946cc463 | 37 | #include <crypto/akcipher.h> |
802c7f1c | 38 | #include <crypto/kpp.h> |
d7db7a88 | 39 | #include <crypto/acompress.h> |
da7f033d HX |
40 | |
41 | #include "internal.h" | |
0b767f96 | 42 | |
9e5c9fe4 RJ |
43 | static bool notests; |
44 | module_param(notests, bool, 0644); | |
45 | MODULE_PARM_DESC(notests, "disable crypto self-tests"); | |
46 | ||
5b2706a4 EB |
47 | #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS |
48 | static bool noextratests; | |
49 | module_param(noextratests, bool, 0644); | |
50 | MODULE_PARM_DESC(noextratests, "disable expensive crypto self-tests"); | |
51 | ||
52 | static unsigned int fuzz_iterations = 100; | |
53 | module_param(fuzz_iterations, uint, 0644); | |
54 | MODULE_PARM_DESC(fuzz_iterations, "number of fuzz test iterations"); | |
55 | #endif | |
56 | ||
326a6346 | 57 | #ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS |
0b767f96 AS |
58 | |
59 | /* a perfect nop */ | |
60 | int alg_test(const char *driver, const char *alg, u32 type, u32 mask) | |
61 | { | |
62 | return 0; | |
63 | } | |
64 | ||
65 | #else | |
66 | ||
da7f033d HX |
67 | #include "testmgr.h" |
68 | ||
69 | /* | |
70 | * Need slab memory for testing (size in number of pages). | |
71 | */ | |
72 | #define XBUFSIZE 8 | |
73 | ||
74 | /* | |
75 | * Indexes into the xbuf to simulate cross-page access. | |
76 | */ | |
77 | #define IDX1 32 | |
78 | #define IDX2 32400 | |
04b46fbd | 79 | #define IDX3 1511 |
da7f033d HX |
80 | #define IDX4 8193 |
81 | #define IDX5 22222 | |
82 | #define IDX6 17101 | |
83 | #define IDX7 27333 | |
84 | #define IDX8 3000 | |
85 | ||
86 | /* | |
87 | * Used by test_cipher() | |
88 | */ | |
89 | #define ENCRYPT 1 | |
90 | #define DECRYPT 0 | |
91 | ||
da7f033d | 92 | struct aead_test_suite { |
a0d608ee EB |
93 | const struct aead_testvec *vecs; |
94 | unsigned int count; | |
da7f033d HX |
95 | }; |
96 | ||
97 | struct cipher_test_suite { | |
92a4c9fe EB |
98 | const struct cipher_testvec *vecs; |
99 | unsigned int count; | |
da7f033d HX |
100 | }; |
101 | ||
102 | struct comp_test_suite { | |
103 | struct { | |
b13b1e0c | 104 | const struct comp_testvec *vecs; |
da7f033d HX |
105 | unsigned int count; |
106 | } comp, decomp; | |
107 | }; | |
108 | ||
109 | struct hash_test_suite { | |
b13b1e0c | 110 | const struct hash_testvec *vecs; |
da7f033d HX |
111 | unsigned int count; |
112 | }; | |
113 | ||
7647d6ce | 114 | struct cprng_test_suite { |
b13b1e0c | 115 | const struct cprng_testvec *vecs; |
7647d6ce JW |
116 | unsigned int count; |
117 | }; | |
118 | ||
64d1cdfb | 119 | struct drbg_test_suite { |
b13b1e0c | 120 | const struct drbg_testvec *vecs; |
64d1cdfb SM |
121 | unsigned int count; |
122 | }; | |
123 | ||
946cc463 | 124 | struct akcipher_test_suite { |
b13b1e0c | 125 | const struct akcipher_testvec *vecs; |
946cc463 TS |
126 | unsigned int count; |
127 | }; | |
128 | ||
802c7f1c | 129 | struct kpp_test_suite { |
b13b1e0c | 130 | const struct kpp_testvec *vecs; |
802c7f1c SB |
131 | unsigned int count; |
132 | }; | |
133 | ||
da7f033d HX |
134 | struct alg_test_desc { |
135 | const char *alg; | |
136 | int (*test)(const struct alg_test_desc *desc, const char *driver, | |
137 | u32 type, u32 mask); | |
a1915d51 | 138 | int fips_allowed; /* set if alg is allowed in fips mode */ |
da7f033d HX |
139 | |
140 | union { | |
141 | struct aead_test_suite aead; | |
142 | struct cipher_test_suite cipher; | |
143 | struct comp_test_suite comp; | |
144 | struct hash_test_suite hash; | |
7647d6ce | 145 | struct cprng_test_suite cprng; |
64d1cdfb | 146 | struct drbg_test_suite drbg; |
946cc463 | 147 | struct akcipher_test_suite akcipher; |
802c7f1c | 148 | struct kpp_test_suite kpp; |
da7f033d HX |
149 | } suite; |
150 | }; | |
151 | ||
b13b1e0c EB |
152 | static const unsigned int IDX[8] = { |
153 | IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 }; | |
da7f033d | 154 | |
da7f033d HX |
155 | static void hexdump(unsigned char *buf, unsigned int len) |
156 | { | |
157 | print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET, | |
158 | 16, 1, | |
159 | buf, len, false); | |
160 | } | |
161 | ||
3f47a03d | 162 | static int __testmgr_alloc_buf(char *buf[XBUFSIZE], int order) |
f8b0d4d0 HX |
163 | { |
164 | int i; | |
165 | ||
166 | for (i = 0; i < XBUFSIZE; i++) { | |
3f47a03d | 167 | buf[i] = (char *)__get_free_pages(GFP_KERNEL, order); |
f8b0d4d0 HX |
168 | if (!buf[i]) |
169 | goto err_free_buf; | |
170 | } | |
171 | ||
172 | return 0; | |
173 | ||
174 | err_free_buf: | |
175 | while (i-- > 0) | |
3f47a03d | 176 | free_pages((unsigned long)buf[i], order); |
f8b0d4d0 HX |
177 | |
178 | return -ENOMEM; | |
179 | } | |
180 | ||
3f47a03d EB |
181 | static int testmgr_alloc_buf(char *buf[XBUFSIZE]) |
182 | { | |
183 | return __testmgr_alloc_buf(buf, 0); | |
184 | } | |
185 | ||
186 | static void __testmgr_free_buf(char *buf[XBUFSIZE], int order) | |
f8b0d4d0 HX |
187 | { |
188 | int i; | |
189 | ||
190 | for (i = 0; i < XBUFSIZE; i++) | |
3f47a03d EB |
191 | free_pages((unsigned long)buf[i], order); |
192 | } | |
193 | ||
194 | static void testmgr_free_buf(char *buf[XBUFSIZE]) | |
195 | { | |
196 | __testmgr_free_buf(buf, 0); | |
197 | } | |
198 | ||
199 | #define TESTMGR_POISON_BYTE 0xfe | |
200 | #define TESTMGR_POISON_LEN 16 | |
201 | ||
202 | static inline void testmgr_poison(void *addr, size_t len) | |
203 | { | |
204 | memset(addr, TESTMGR_POISON_BYTE, len); | |
205 | } | |
206 | ||
207 | /* Is the memory region still fully poisoned? */ | |
208 | static inline bool testmgr_is_poison(const void *addr, size_t len) | |
209 | { | |
210 | return memchr_inv(addr, TESTMGR_POISON_BYTE, len) == NULL; | |
211 | } | |
212 | ||
213 | /* flush type for hash algorithms */ | |
214 | enum flush_type { | |
215 | /* merge with update of previous buffer(s) */ | |
216 | FLUSH_TYPE_NONE = 0, | |
217 | ||
218 | /* update with previous buffer(s) before doing this one */ | |
219 | FLUSH_TYPE_FLUSH, | |
220 | ||
221 | /* likewise, but also export and re-import the intermediate state */ | |
222 | FLUSH_TYPE_REIMPORT, | |
223 | }; | |
224 | ||
225 | /* finalization function for hash algorithms */ | |
226 | enum finalization_type { | |
227 | FINALIZATION_TYPE_FINAL, /* use final() */ | |
228 | FINALIZATION_TYPE_FINUP, /* use finup() */ | |
229 | FINALIZATION_TYPE_DIGEST, /* use digest() */ | |
230 | }; | |
231 | ||
232 | #define TEST_SG_TOTAL 10000 | |
233 | ||
234 | /** | |
235 | * struct test_sg_division - description of a scatterlist entry | |
236 | * | |
237 | * This struct describes one entry of a scatterlist being constructed to check a | |
238 | * crypto test vector. | |
239 | * | |
240 | * @proportion_of_total: length of this chunk relative to the total length, | |
241 | * given as a proportion out of TEST_SG_TOTAL so that it | |
242 | * scales to fit any test vector | |
243 | * @offset: byte offset into a 2-page buffer at which this chunk will start | |
244 | * @offset_relative_to_alignmask: if true, add the algorithm's alignmask to the | |
245 | * @offset | |
246 | * @flush_type: for hashes, whether an update() should be done now vs. | |
247 | * continuing to accumulate data | |
248 | */ | |
249 | struct test_sg_division { | |
250 | unsigned int proportion_of_total; | |
251 | unsigned int offset; | |
252 | bool offset_relative_to_alignmask; | |
253 | enum flush_type flush_type; | |
254 | }; | |
255 | ||
256 | /** | |
257 | * struct testvec_config - configuration for testing a crypto test vector | |
258 | * | |
259 | * This struct describes the data layout and other parameters with which each | |
260 | * crypto test vector can be tested. | |
261 | * | |
262 | * @name: name of this config, logged for debugging purposes if a test fails | |
263 | * @inplace: operate on the data in-place, if applicable for the algorithm type? | |
264 | * @req_flags: extra request_flags, e.g. CRYPTO_TFM_REQ_MAY_SLEEP | |
265 | * @src_divs: description of how to arrange the source scatterlist | |
266 | * @dst_divs: description of how to arrange the dst scatterlist, if applicable | |
267 | * for the algorithm type. Defaults to @src_divs if unset. | |
268 | * @iv_offset: misalignment of the IV in the range [0..MAX_ALGAPI_ALIGNMASK+1], | |
269 | * where 0 is aligned to a 2*(MAX_ALGAPI_ALIGNMASK+1) byte boundary | |
270 | * @iv_offset_relative_to_alignmask: if true, add the algorithm's alignmask to | |
271 | * the @iv_offset | |
272 | * @finalization_type: what finalization function to use for hashes | |
273 | */ | |
274 | struct testvec_config { | |
275 | const char *name; | |
276 | bool inplace; | |
277 | u32 req_flags; | |
278 | struct test_sg_division src_divs[XBUFSIZE]; | |
279 | struct test_sg_division dst_divs[XBUFSIZE]; | |
280 | unsigned int iv_offset; | |
281 | bool iv_offset_relative_to_alignmask; | |
282 | enum finalization_type finalization_type; | |
283 | }; | |
284 | ||
285 | #define TESTVEC_CONFIG_NAMELEN 192 | |
286 | ||
287 | static unsigned int count_test_sg_divisions(const struct test_sg_division *divs) | |
288 | { | |
289 | unsigned int remaining = TEST_SG_TOTAL; | |
290 | unsigned int ndivs = 0; | |
291 | ||
292 | do { | |
293 | remaining -= divs[ndivs++].proportion_of_total; | |
294 | } while (remaining); | |
295 | ||
296 | return ndivs; | |
297 | } | |
298 | ||
299 | static bool valid_sg_divisions(const struct test_sg_division *divs, | |
300 | unsigned int count, bool *any_flushes_ret) | |
301 | { | |
302 | unsigned int total = 0; | |
303 | unsigned int i; | |
304 | ||
305 | for (i = 0; i < count && total != TEST_SG_TOTAL; i++) { | |
306 | if (divs[i].proportion_of_total <= 0 || | |
307 | divs[i].proportion_of_total > TEST_SG_TOTAL - total) | |
308 | return false; | |
309 | total += divs[i].proportion_of_total; | |
310 | if (divs[i].flush_type != FLUSH_TYPE_NONE) | |
311 | *any_flushes_ret = true; | |
312 | } | |
313 | return total == TEST_SG_TOTAL && | |
314 | memchr_inv(&divs[i], 0, (count - i) * sizeof(divs[0])) == NULL; | |
315 | } | |
316 | ||
317 | /* | |
318 | * Check whether the given testvec_config is valid. This isn't strictly needed | |
319 | * since every testvec_config should be valid, but check anyway so that people | |
320 | * don't unknowingly add broken configs that don't do what they wanted. | |
321 | */ | |
322 | static bool valid_testvec_config(const struct testvec_config *cfg) | |
323 | { | |
324 | bool any_flushes = false; | |
325 | ||
326 | if (cfg->name == NULL) | |
327 | return false; | |
328 | ||
329 | if (!valid_sg_divisions(cfg->src_divs, ARRAY_SIZE(cfg->src_divs), | |
330 | &any_flushes)) | |
331 | return false; | |
332 | ||
333 | if (cfg->dst_divs[0].proportion_of_total) { | |
334 | if (!valid_sg_divisions(cfg->dst_divs, | |
335 | ARRAY_SIZE(cfg->dst_divs), | |
336 | &any_flushes)) | |
337 | return false; | |
338 | } else { | |
339 | if (memchr_inv(cfg->dst_divs, 0, sizeof(cfg->dst_divs))) | |
340 | return false; | |
341 | /* defaults to dst_divs=src_divs */ | |
342 | } | |
343 | ||
344 | if (cfg->iv_offset + | |
345 | (cfg->iv_offset_relative_to_alignmask ? MAX_ALGAPI_ALIGNMASK : 0) > | |
346 | MAX_ALGAPI_ALIGNMASK + 1) | |
347 | return false; | |
348 | ||
349 | if (any_flushes && cfg->finalization_type == FINALIZATION_TYPE_DIGEST) | |
350 | return false; | |
351 | ||
352 | return true; | |
353 | } | |
354 | ||
355 | struct test_sglist { | |
356 | char *bufs[XBUFSIZE]; | |
357 | struct scatterlist sgl[XBUFSIZE]; | |
358 | struct scatterlist sgl_saved[XBUFSIZE]; | |
359 | struct scatterlist *sgl_ptr; | |
360 | unsigned int nents; | |
361 | }; | |
362 | ||
363 | static int init_test_sglist(struct test_sglist *tsgl) | |
364 | { | |
365 | return __testmgr_alloc_buf(tsgl->bufs, 1 /* two pages per buffer */); | |
366 | } | |
367 | ||
368 | static void destroy_test_sglist(struct test_sglist *tsgl) | |
369 | { | |
370 | return __testmgr_free_buf(tsgl->bufs, 1 /* two pages per buffer */); | |
371 | } | |
372 | ||
373 | /** | |
374 | * build_test_sglist() - build a scatterlist for a crypto test | |
375 | * | |
376 | * @tsgl: the scatterlist to build. @tsgl->bufs[] contains an array of 2-page | |
377 | * buffers which the scatterlist @tsgl->sgl[] will be made to point into. | |
378 | * @divs: the layout specification on which the scatterlist will be based | |
379 | * @alignmask: the algorithm's alignmask | |
380 | * @total_len: the total length of the scatterlist to build in bytes | |
381 | * @data: if non-NULL, the buffers will be filled with this data until it ends. | |
382 | * Otherwise the buffers will be poisoned. In both cases, some bytes | |
383 | * past the end of each buffer will be poisoned to help detect overruns. | |
384 | * @out_divs: if non-NULL, the test_sg_division to which each scatterlist entry | |
385 | * corresponds will be returned here. This will match @divs except | |
386 | * that divisions resolving to a length of 0 are omitted as they are | |
387 | * not included in the scatterlist. | |
388 | * | |
389 | * Return: 0 or a -errno value | |
390 | */ | |
391 | static int build_test_sglist(struct test_sglist *tsgl, | |
392 | const struct test_sg_division *divs, | |
393 | const unsigned int alignmask, | |
394 | const unsigned int total_len, | |
395 | struct iov_iter *data, | |
396 | const struct test_sg_division *out_divs[XBUFSIZE]) | |
397 | { | |
398 | struct { | |
399 | const struct test_sg_division *div; | |
400 | size_t length; | |
401 | } partitions[XBUFSIZE]; | |
402 | const unsigned int ndivs = count_test_sg_divisions(divs); | |
403 | unsigned int len_remaining = total_len; | |
404 | unsigned int i; | |
405 | ||
406 | BUILD_BUG_ON(ARRAY_SIZE(partitions) != ARRAY_SIZE(tsgl->sgl)); | |
407 | if (WARN_ON(ndivs > ARRAY_SIZE(partitions))) | |
408 | return -EINVAL; | |
409 | ||
410 | /* Calculate the (div, length) pairs */ | |
411 | tsgl->nents = 0; | |
412 | for (i = 0; i < ndivs; i++) { | |
413 | unsigned int len_this_sg = | |
414 | min(len_remaining, | |
415 | (total_len * divs[i].proportion_of_total + | |
416 | TEST_SG_TOTAL / 2) / TEST_SG_TOTAL); | |
417 | ||
418 | if (len_this_sg != 0) { | |
419 | partitions[tsgl->nents].div = &divs[i]; | |
420 | partitions[tsgl->nents].length = len_this_sg; | |
421 | tsgl->nents++; | |
422 | len_remaining -= len_this_sg; | |
423 | } | |
424 | } | |
425 | if (tsgl->nents == 0) { | |
426 | partitions[tsgl->nents].div = &divs[0]; | |
427 | partitions[tsgl->nents].length = 0; | |
428 | tsgl->nents++; | |
429 | } | |
430 | partitions[tsgl->nents - 1].length += len_remaining; | |
431 | ||
432 | /* Set up the sgl entries and fill the data or poison */ | |
433 | sg_init_table(tsgl->sgl, tsgl->nents); | |
434 | for (i = 0; i < tsgl->nents; i++) { | |
435 | unsigned int offset = partitions[i].div->offset; | |
436 | void *addr; | |
437 | ||
438 | if (partitions[i].div->offset_relative_to_alignmask) | |
439 | offset += alignmask; | |
440 | ||
441 | while (offset + partitions[i].length + TESTMGR_POISON_LEN > | |
442 | 2 * PAGE_SIZE) { | |
443 | if (WARN_ON(offset <= 0)) | |
444 | return -EINVAL; | |
445 | offset /= 2; | |
446 | } | |
447 | ||
448 | addr = &tsgl->bufs[i][offset]; | |
449 | sg_set_buf(&tsgl->sgl[i], addr, partitions[i].length); | |
450 | ||
451 | if (out_divs) | |
452 | out_divs[i] = partitions[i].div; | |
453 | ||
454 | if (data) { | |
455 | size_t copy_len, copied; | |
456 | ||
457 | copy_len = min(partitions[i].length, data->count); | |
458 | copied = copy_from_iter(addr, copy_len, data); | |
459 | if (WARN_ON(copied != copy_len)) | |
460 | return -EINVAL; | |
461 | testmgr_poison(addr + copy_len, partitions[i].length + | |
462 | TESTMGR_POISON_LEN - copy_len); | |
463 | } else { | |
464 | testmgr_poison(addr, partitions[i].length + | |
465 | TESTMGR_POISON_LEN); | |
466 | } | |
467 | } | |
468 | ||
469 | sg_mark_end(&tsgl->sgl[tsgl->nents - 1]); | |
470 | tsgl->sgl_ptr = tsgl->sgl; | |
471 | memcpy(tsgl->sgl_saved, tsgl->sgl, tsgl->nents * sizeof(tsgl->sgl[0])); | |
472 | return 0; | |
473 | } | |
474 | ||
475 | /* | |
476 | * Verify that a scatterlist crypto operation produced the correct output. | |
477 | * | |
478 | * @tsgl: scatterlist containing the actual output | |
479 | * @expected_output: buffer containing the expected output | |
480 | * @len_to_check: length of @expected_output in bytes | |
481 | * @unchecked_prefix_len: number of ignored bytes in @tsgl prior to real result | |
482 | * @check_poison: verify that the poison bytes after each chunk are intact? | |
483 | * | |
484 | * Return: 0 if correct, -EINVAL if incorrect, -EOVERFLOW if buffer overrun. | |
485 | */ | |
486 | static int verify_correct_output(const struct test_sglist *tsgl, | |
487 | const char *expected_output, | |
488 | unsigned int len_to_check, | |
489 | unsigned int unchecked_prefix_len, | |
490 | bool check_poison) | |
491 | { | |
492 | unsigned int i; | |
493 | ||
494 | for (i = 0; i < tsgl->nents; i++) { | |
495 | struct scatterlist *sg = &tsgl->sgl_ptr[i]; | |
496 | unsigned int len = sg->length; | |
497 | unsigned int offset = sg->offset; | |
498 | const char *actual_output; | |
499 | ||
500 | if (unchecked_prefix_len) { | |
501 | if (unchecked_prefix_len >= len) { | |
502 | unchecked_prefix_len -= len; | |
503 | continue; | |
504 | } | |
505 | offset += unchecked_prefix_len; | |
506 | len -= unchecked_prefix_len; | |
507 | unchecked_prefix_len = 0; | |
508 | } | |
509 | len = min(len, len_to_check); | |
510 | actual_output = page_address(sg_page(sg)) + offset; | |
511 | if (memcmp(expected_output, actual_output, len) != 0) | |
512 | return -EINVAL; | |
513 | if (check_poison && | |
514 | !testmgr_is_poison(actual_output + len, TESTMGR_POISON_LEN)) | |
515 | return -EOVERFLOW; | |
516 | len_to_check -= len; | |
517 | expected_output += len; | |
518 | } | |
519 | if (WARN_ON(len_to_check != 0)) | |
520 | return -EINVAL; | |
521 | return 0; | |
522 | } | |
523 | ||
524 | static bool is_test_sglist_corrupted(const struct test_sglist *tsgl) | |
525 | { | |
526 | unsigned int i; | |
527 | ||
528 | for (i = 0; i < tsgl->nents; i++) { | |
529 | if (tsgl->sgl[i].page_link != tsgl->sgl_saved[i].page_link) | |
530 | return true; | |
531 | if (tsgl->sgl[i].offset != tsgl->sgl_saved[i].offset) | |
532 | return true; | |
533 | if (tsgl->sgl[i].length != tsgl->sgl_saved[i].length) | |
534 | return true; | |
535 | } | |
536 | return false; | |
537 | } | |
538 | ||
539 | struct cipher_test_sglists { | |
540 | struct test_sglist src; | |
541 | struct test_sglist dst; | |
542 | }; | |
543 | ||
544 | static struct cipher_test_sglists *alloc_cipher_test_sglists(void) | |
545 | { | |
546 | struct cipher_test_sglists *tsgls; | |
547 | ||
548 | tsgls = kmalloc(sizeof(*tsgls), GFP_KERNEL); | |
549 | if (!tsgls) | |
550 | return NULL; | |
551 | ||
552 | if (init_test_sglist(&tsgls->src) != 0) | |
553 | goto fail_kfree; | |
554 | if (init_test_sglist(&tsgls->dst) != 0) | |
555 | goto fail_destroy_src; | |
556 | ||
557 | return tsgls; | |
558 | ||
559 | fail_destroy_src: | |
560 | destroy_test_sglist(&tsgls->src); | |
561 | fail_kfree: | |
562 | kfree(tsgls); | |
563 | return NULL; | |
564 | } | |
565 | ||
566 | static void free_cipher_test_sglists(struct cipher_test_sglists *tsgls) | |
567 | { | |
568 | if (tsgls) { | |
569 | destroy_test_sglist(&tsgls->src); | |
570 | destroy_test_sglist(&tsgls->dst); | |
571 | kfree(tsgls); | |
572 | } | |
573 | } | |
574 | ||
575 | /* Build the src and dst scatterlists for an skcipher or AEAD test */ | |
576 | static int build_cipher_test_sglists(struct cipher_test_sglists *tsgls, | |
577 | const struct testvec_config *cfg, | |
578 | unsigned int alignmask, | |
579 | unsigned int src_total_len, | |
580 | unsigned int dst_total_len, | |
581 | const struct kvec *inputs, | |
582 | unsigned int nr_inputs) | |
583 | { | |
584 | struct iov_iter input; | |
585 | int err; | |
586 | ||
587 | iov_iter_kvec(&input, WRITE, inputs, nr_inputs, src_total_len); | |
588 | err = build_test_sglist(&tsgls->src, cfg->src_divs, alignmask, | |
589 | cfg->inplace ? | |
590 | max(dst_total_len, src_total_len) : | |
591 | src_total_len, | |
592 | &input, NULL); | |
593 | if (err) | |
594 | return err; | |
595 | ||
596 | if (cfg->inplace) { | |
597 | tsgls->dst.sgl_ptr = tsgls->src.sgl; | |
598 | tsgls->dst.nents = tsgls->src.nents; | |
599 | return 0; | |
600 | } | |
601 | return build_test_sglist(&tsgls->dst, | |
602 | cfg->dst_divs[0].proportion_of_total ? | |
603 | cfg->dst_divs : cfg->src_divs, | |
604 | alignmask, dst_total_len, NULL, NULL); | |
f8b0d4d0 HX |
605 | } |
606 | ||
25f9dddb EB |
607 | #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS |
608 | static char *generate_random_sgl_divisions(struct test_sg_division *divs, | |
609 | size_t max_divs, char *p, char *end, | |
610 | bool gen_flushes) | |
611 | { | |
612 | struct test_sg_division *div = divs; | |
613 | unsigned int remaining = TEST_SG_TOTAL; | |
614 | ||
615 | do { | |
616 | unsigned int this_len; | |
617 | ||
618 | if (div == &divs[max_divs - 1] || prandom_u32() % 2 == 0) | |
619 | this_len = remaining; | |
620 | else | |
621 | this_len = 1 + (prandom_u32() % remaining); | |
622 | div->proportion_of_total = this_len; | |
623 | ||
624 | if (prandom_u32() % 4 == 0) | |
625 | div->offset = (PAGE_SIZE - 128) + (prandom_u32() % 128); | |
626 | else if (prandom_u32() % 2 == 0) | |
627 | div->offset = prandom_u32() % 32; | |
628 | else | |
629 | div->offset = prandom_u32() % PAGE_SIZE; | |
630 | if (prandom_u32() % 8 == 0) | |
631 | div->offset_relative_to_alignmask = true; | |
632 | ||
633 | div->flush_type = FLUSH_TYPE_NONE; | |
634 | if (gen_flushes) { | |
635 | switch (prandom_u32() % 4) { | |
636 | case 0: | |
637 | div->flush_type = FLUSH_TYPE_REIMPORT; | |
638 | break; | |
639 | case 1: | |
640 | div->flush_type = FLUSH_TYPE_FLUSH; | |
641 | break; | |
642 | } | |
643 | } | |
644 | ||
645 | BUILD_BUG_ON(TEST_SG_TOTAL != 10000); /* for "%u.%u%%" */ | |
646 | p += scnprintf(p, end - p, "%s%u.%u%%@%s+%u%s", | |
647 | div->flush_type == FLUSH_TYPE_NONE ? "" : | |
648 | div->flush_type == FLUSH_TYPE_FLUSH ? | |
649 | "<flush> " : "<reimport> ", | |
650 | this_len / 100, this_len % 100, | |
651 | div->offset_relative_to_alignmask ? | |
652 | "alignmask" : "", | |
653 | div->offset, this_len == remaining ? "" : ", "); | |
654 | remaining -= this_len; | |
655 | div++; | |
656 | } while (remaining); | |
657 | ||
658 | return p; | |
659 | } | |
660 | ||
661 | /* Generate a random testvec_config for fuzz testing */ | |
662 | static void generate_random_testvec_config(struct testvec_config *cfg, | |
663 | char *name, size_t max_namelen) | |
664 | { | |
665 | char *p = name; | |
666 | char * const end = name + max_namelen; | |
667 | ||
668 | memset(cfg, 0, sizeof(*cfg)); | |
669 | ||
670 | cfg->name = name; | |
671 | ||
672 | p += scnprintf(p, end - p, "random:"); | |
673 | ||
674 | if (prandom_u32() % 2 == 0) { | |
675 | cfg->inplace = true; | |
676 | p += scnprintf(p, end - p, " inplace"); | |
677 | } | |
678 | ||
679 | if (prandom_u32() % 2 == 0) { | |
680 | cfg->req_flags |= CRYPTO_TFM_REQ_MAY_SLEEP; | |
681 | p += scnprintf(p, end - p, " may_sleep"); | |
682 | } | |
683 | ||
684 | switch (prandom_u32() % 4) { | |
685 | case 0: | |
686 | cfg->finalization_type = FINALIZATION_TYPE_FINAL; | |
687 | p += scnprintf(p, end - p, " use_final"); | |
688 | break; | |
689 | case 1: | |
690 | cfg->finalization_type = FINALIZATION_TYPE_FINUP; | |
691 | p += scnprintf(p, end - p, " use_finup"); | |
692 | break; | |
693 | default: | |
694 | cfg->finalization_type = FINALIZATION_TYPE_DIGEST; | |
695 | p += scnprintf(p, end - p, " use_digest"); | |
696 | break; | |
697 | } | |
698 | ||
699 | p += scnprintf(p, end - p, " src_divs=["); | |
700 | p = generate_random_sgl_divisions(cfg->src_divs, | |
701 | ARRAY_SIZE(cfg->src_divs), p, end, | |
702 | (cfg->finalization_type != | |
703 | FINALIZATION_TYPE_DIGEST)); | |
704 | p += scnprintf(p, end - p, "]"); | |
705 | ||
706 | if (!cfg->inplace && prandom_u32() % 2 == 0) { | |
707 | p += scnprintf(p, end - p, " dst_divs=["); | |
708 | p = generate_random_sgl_divisions(cfg->dst_divs, | |
709 | ARRAY_SIZE(cfg->dst_divs), | |
710 | p, end, false); | |
711 | p += scnprintf(p, end - p, "]"); | |
712 | } | |
713 | ||
714 | if (prandom_u32() % 2 == 0) { | |
715 | cfg->iv_offset = 1 + (prandom_u32() % MAX_ALGAPI_ALIGNMASK); | |
716 | p += scnprintf(p, end - p, " iv_offset=%u", cfg->iv_offset); | |
717 | } | |
718 | ||
719 | WARN_ON_ONCE(!valid_testvec_config(cfg)); | |
720 | } | |
721 | #endif /* CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */ | |
722 | ||
466d7b9f KK |
723 | static int ahash_guard_result(char *result, char c, int size) |
724 | { | |
725 | int i; | |
726 | ||
727 | for (i = 0; i < size; i++) { | |
728 | if (result[i] != c) | |
729 | return -EINVAL; | |
730 | } | |
731 | ||
732 | return 0; | |
733 | } | |
734 | ||
018ba95c | 735 | static int ahash_partial_update(struct ahash_request **preq, |
b13b1e0c | 736 | struct crypto_ahash *tfm, const struct hash_testvec *template, |
018ba95c | 737 | void *hash_buff, int k, int temp, struct scatterlist *sg, |
7f397136 | 738 | const char *algo, char *result, struct crypto_wait *wait) |
018ba95c WR |
739 | { |
740 | char *state; | |
741 | struct ahash_request *req; | |
742 | int statesize, ret = -EINVAL; | |
da1729ce | 743 | static const unsigned char guard[] = { 0x00, 0xba, 0xad, 0x00 }; |
466d7b9f | 744 | int digestsize = crypto_ahash_digestsize(tfm); |
018ba95c WR |
745 | |
746 | req = *preq; | |
747 | statesize = crypto_ahash_statesize( | |
748 | crypto_ahash_reqtfm(req)); | |
7bcb87bc | 749 | state = kmalloc(statesize + sizeof(guard), GFP_KERNEL); |
018ba95c | 750 | if (!state) { |
cf3f9609 | 751 | pr_err("alg: hash: Failed to alloc state for %s\n", algo); |
018ba95c WR |
752 | goto out_nostate; |
753 | } | |
7bcb87bc | 754 | memcpy(state + statesize, guard, sizeof(guard)); |
466d7b9f | 755 | memset(result, 1, digestsize); |
018ba95c | 756 | ret = crypto_ahash_export(req, state); |
7bcb87bc | 757 | WARN_ON(memcmp(state + statesize, guard, sizeof(guard))); |
018ba95c | 758 | if (ret) { |
cf3f9609 | 759 | pr_err("alg: hash: Failed to export() for %s\n", algo); |
018ba95c WR |
760 | goto out; |
761 | } | |
466d7b9f KK |
762 | ret = ahash_guard_result(result, 1, digestsize); |
763 | if (ret) { | |
764 | pr_err("alg: hash: Failed, export used req->result for %s\n", | |
765 | algo); | |
766 | goto out; | |
767 | } | |
018ba95c WR |
768 | ahash_request_free(req); |
769 | req = ahash_request_alloc(tfm, GFP_KERNEL); | |
770 | if (!req) { | |
771 | pr_err("alg: hash: Failed to alloc request for %s\n", algo); | |
772 | goto out_noreq; | |
773 | } | |
774 | ahash_request_set_callback(req, | |
775 | CRYPTO_TFM_REQ_MAY_BACKLOG, | |
7f397136 | 776 | crypto_req_done, wait); |
018ba95c WR |
777 | |
778 | memcpy(hash_buff, template->plaintext + temp, | |
779 | template->tap[k]); | |
780 | sg_init_one(&sg[0], hash_buff, template->tap[k]); | |
781 | ahash_request_set_crypt(req, sg, result, template->tap[k]); | |
782 | ret = crypto_ahash_import(req, state); | |
783 | if (ret) { | |
784 | pr_err("alg: hash: Failed to import() for %s\n", algo); | |
785 | goto out; | |
786 | } | |
466d7b9f KK |
787 | ret = ahash_guard_result(result, 1, digestsize); |
788 | if (ret) { | |
789 | pr_err("alg: hash: Failed, import used req->result for %s\n", | |
790 | algo); | |
791 | goto out; | |
792 | } | |
7f397136 | 793 | ret = crypto_wait_req(crypto_ahash_update(req), wait); |
018ba95c WR |
794 | if (ret) |
795 | goto out; | |
796 | *preq = req; | |
797 | ret = 0; | |
798 | goto out_noreq; | |
799 | out: | |
800 | ahash_request_free(req); | |
801 | out_noreq: | |
802 | kfree(state); | |
803 | out_nostate: | |
804 | return ret; | |
805 | } | |
806 | ||
76715095 GBY |
807 | enum hash_test { |
808 | HASH_TEST_DIGEST, | |
809 | HASH_TEST_FINAL, | |
810 | HASH_TEST_FINUP | |
811 | }; | |
812 | ||
b13b1e0c EB |
813 | static int __test_hash(struct crypto_ahash *tfm, |
814 | const struct hash_testvec *template, unsigned int tcount, | |
76715095 | 815 | enum hash_test test_type, const int align_offset) |
da7f033d HX |
816 | { |
817 | const char *algo = crypto_tfm_alg_driver_name(crypto_ahash_tfm(tfm)); | |
e93acd6f | 818 | size_t digest_size = crypto_ahash_digestsize(tfm); |
da7f033d HX |
819 | unsigned int i, j, k, temp; |
820 | struct scatterlist sg[8]; | |
29b77e5d HG |
821 | char *result; |
822 | char *key; | |
da7f033d | 823 | struct ahash_request *req; |
7f397136 | 824 | struct crypto_wait wait; |
da7f033d | 825 | void *hash_buff; |
f8b0d4d0 HX |
826 | char *xbuf[XBUFSIZE]; |
827 | int ret = -ENOMEM; | |
828 | ||
e93acd6f | 829 | result = kmalloc(digest_size, GFP_KERNEL); |
29b77e5d HG |
830 | if (!result) |
831 | return ret; | |
832 | key = kmalloc(MAX_KEYLEN, GFP_KERNEL); | |
833 | if (!key) | |
834 | goto out_nobuf; | |
f8b0d4d0 HX |
835 | if (testmgr_alloc_buf(xbuf)) |
836 | goto out_nobuf; | |
da7f033d | 837 | |
7f397136 | 838 | crypto_init_wait(&wait); |
da7f033d HX |
839 | |
840 | req = ahash_request_alloc(tfm, GFP_KERNEL); | |
841 | if (!req) { | |
842 | printk(KERN_ERR "alg: hash: Failed to allocate request for " | |
843 | "%s\n", algo); | |
da7f033d HX |
844 | goto out_noreq; |
845 | } | |
846 | ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, | |
7f397136 | 847 | crypto_req_done, &wait); |
da7f033d | 848 | |
a0cfae59 | 849 | j = 0; |
da7f033d | 850 | for (i = 0; i < tcount; i++) { |
a0cfae59 HX |
851 | if (template[i].np) |
852 | continue; | |
853 | ||
da5ffe11 JK |
854 | ret = -EINVAL; |
855 | if (WARN_ON(align_offset + template[i].psize > PAGE_SIZE)) | |
856 | goto out; | |
857 | ||
a0cfae59 | 858 | j++; |
e93acd6f | 859 | memset(result, 0, digest_size); |
da7f033d HX |
860 | |
861 | hash_buff = xbuf[0]; | |
da5ffe11 | 862 | hash_buff += align_offset; |
da7f033d HX |
863 | |
864 | memcpy(hash_buff, template[i].plaintext, template[i].psize); | |
865 | sg_init_one(&sg[0], hash_buff, template[i].psize); | |
866 | ||
867 | if (template[i].ksize) { | |
868 | crypto_ahash_clear_flags(tfm, ~0); | |
29b77e5d HG |
869 | if (template[i].ksize > MAX_KEYLEN) { |
870 | pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n", | |
871 | j, algo, template[i].ksize, MAX_KEYLEN); | |
872 | ret = -EINVAL; | |
873 | goto out; | |
874 | } | |
875 | memcpy(key, template[i].key, template[i].ksize); | |
876 | ret = crypto_ahash_setkey(tfm, key, template[i].ksize); | |
da7f033d HX |
877 | if (ret) { |
878 | printk(KERN_ERR "alg: hash: setkey failed on " | |
a0cfae59 | 879 | "test %d for %s: ret=%d\n", j, algo, |
da7f033d HX |
880 | -ret); |
881 | goto out; | |
882 | } | |
883 | } | |
884 | ||
885 | ahash_request_set_crypt(req, sg, result, template[i].psize); | |
76715095 GBY |
886 | switch (test_type) { |
887 | case HASH_TEST_DIGEST: | |
7f397136 | 888 | ret = crypto_wait_req(crypto_ahash_digest(req), &wait); |
a8f1a052 DM |
889 | if (ret) { |
890 | pr_err("alg: hash: digest failed on test %d " | |
891 | "for %s: ret=%d\n", j, algo, -ret); | |
892 | goto out; | |
893 | } | |
76715095 GBY |
894 | break; |
895 | ||
896 | case HASH_TEST_FINAL: | |
466d7b9f | 897 | memset(result, 1, digest_size); |
7f397136 | 898 | ret = crypto_wait_req(crypto_ahash_init(req), &wait); |
a8f1a052 | 899 | if (ret) { |
cf3f9609 | 900 | pr_err("alg: hash: init failed on test %d " |
a8f1a052 DM |
901 | "for %s: ret=%d\n", j, algo, -ret); |
902 | goto out; | |
903 | } | |
466d7b9f KK |
904 | ret = ahash_guard_result(result, 1, digest_size); |
905 | if (ret) { | |
906 | pr_err("alg: hash: init failed on test %d " | |
907 | "for %s: used req->result\n", j, algo); | |
908 | goto out; | |
909 | } | |
7f397136 | 910 | ret = crypto_wait_req(crypto_ahash_update(req), &wait); |
a8f1a052 | 911 | if (ret) { |
cf3f9609 | 912 | pr_err("alg: hash: update failed on test %d " |
a8f1a052 DM |
913 | "for %s: ret=%d\n", j, algo, -ret); |
914 | goto out; | |
915 | } | |
466d7b9f KK |
916 | ret = ahash_guard_result(result, 1, digest_size); |
917 | if (ret) { | |
918 | pr_err("alg: hash: update failed on test %d " | |
919 | "for %s: used req->result\n", j, algo); | |
920 | goto out; | |
921 | } | |
7f397136 | 922 | ret = crypto_wait_req(crypto_ahash_final(req), &wait); |
a8f1a052 | 923 | if (ret) { |
cf3f9609 | 924 | pr_err("alg: hash: final failed on test %d " |
a8f1a052 DM |
925 | "for %s: ret=%d\n", j, algo, -ret); |
926 | goto out; | |
da7f033d | 927 | } |
76715095 GBY |
928 | break; |
929 | ||
930 | case HASH_TEST_FINUP: | |
931 | memset(result, 1, digest_size); | |
932 | ret = crypto_wait_req(crypto_ahash_init(req), &wait); | |
933 | if (ret) { | |
934 | pr_err("alg: hash: init failed on test %d " | |
935 | "for %s: ret=%d\n", j, algo, -ret); | |
936 | goto out; | |
937 | } | |
938 | ret = ahash_guard_result(result, 1, digest_size); | |
939 | if (ret) { | |
940 | pr_err("alg: hash: init failed on test %d " | |
941 | "for %s: used req->result\n", j, algo); | |
942 | goto out; | |
943 | } | |
944 | ret = crypto_wait_req(crypto_ahash_finup(req), &wait); | |
945 | if (ret) { | |
946 | pr_err("alg: hash: final failed on test %d " | |
947 | "for %s: ret=%d\n", j, algo, -ret); | |
948 | goto out; | |
949 | } | |
950 | break; | |
da7f033d HX |
951 | } |
952 | ||
953 | if (memcmp(result, template[i].digest, | |
954 | crypto_ahash_digestsize(tfm))) { | |
955 | printk(KERN_ERR "alg: hash: Test %d failed for %s\n", | |
a0cfae59 | 956 | j, algo); |
da7f033d HX |
957 | hexdump(result, crypto_ahash_digestsize(tfm)); |
958 | ret = -EINVAL; | |
959 | goto out; | |
960 | } | |
961 | } | |
962 | ||
76715095 GBY |
963 | if (test_type) |
964 | goto out; | |
965 | ||
da7f033d HX |
966 | j = 0; |
967 | for (i = 0; i < tcount; i++) { | |
da5ffe11 JK |
968 | /* alignment tests are only done with continuous buffers */ |
969 | if (align_offset != 0) | |
970 | break; | |
971 | ||
5f2b424e CS |
972 | if (!template[i].np) |
973 | continue; | |
da7f033d | 974 | |
5f2b424e | 975 | j++; |
e93acd6f | 976 | memset(result, 0, digest_size); |
da7f033d | 977 | |
5f2b424e CS |
978 | temp = 0; |
979 | sg_init_table(sg, template[i].np); | |
980 | ret = -EINVAL; | |
981 | for (k = 0; k < template[i].np; k++) { | |
982 | if (WARN_ON(offset_in_page(IDX[k]) + | |
983 | template[i].tap[k] > PAGE_SIZE)) | |
984 | goto out; | |
985 | sg_set_buf(&sg[k], | |
986 | memcpy(xbuf[IDX[k] >> PAGE_SHIFT] + | |
987 | offset_in_page(IDX[k]), | |
988 | template[i].plaintext + temp, | |
989 | template[i].tap[k]), | |
990 | template[i].tap[k]); | |
991 | temp += template[i].tap[k]; | |
992 | } | |
da7f033d | 993 | |
5f2b424e CS |
994 | if (template[i].ksize) { |
995 | if (template[i].ksize > MAX_KEYLEN) { | |
996 | pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n", | |
997 | j, algo, template[i].ksize, MAX_KEYLEN); | |
998 | ret = -EINVAL; | |
da7f033d HX |
999 | goto out; |
1000 | } | |
5f2b424e CS |
1001 | crypto_ahash_clear_flags(tfm, ~0); |
1002 | memcpy(key, template[i].key, template[i].ksize); | |
1003 | ret = crypto_ahash_setkey(tfm, key, template[i].ksize); | |
da7f033d | 1004 | |
5f2b424e CS |
1005 | if (ret) { |
1006 | printk(KERN_ERR "alg: hash: setkey " | |
1007 | "failed on chunking test %d " | |
1008 | "for %s: ret=%d\n", j, algo, -ret); | |
da7f033d HX |
1009 | goto out; |
1010 | } | |
1011 | } | |
5f2b424e CS |
1012 | |
1013 | ahash_request_set_crypt(req, sg, result, template[i].psize); | |
7f397136 GBY |
1014 | ret = crypto_wait_req(crypto_ahash_digest(req), &wait); |
1015 | if (ret) { | |
1016 | pr_err("alg: hash: digest failed on chunking test %d for %s: ret=%d\n", | |
1017 | j, algo, -ret); | |
5f2b424e CS |
1018 | goto out; |
1019 | } | |
1020 | ||
1021 | if (memcmp(result, template[i].digest, | |
1022 | crypto_ahash_digestsize(tfm))) { | |
1023 | printk(KERN_ERR "alg: hash: Chunking test %d " | |
1024 | "failed for %s\n", j, algo); | |
1025 | hexdump(result, crypto_ahash_digestsize(tfm)); | |
1026 | ret = -EINVAL; | |
018ba95c WR |
1027 | goto out; |
1028 | } | |
1029 | } | |
1030 | ||
1031 | /* partial update exercise */ | |
1032 | j = 0; | |
1033 | for (i = 0; i < tcount; i++) { | |
1034 | /* alignment tests are only done with continuous buffers */ | |
1035 | if (align_offset != 0) | |
1036 | break; | |
1037 | ||
1038 | if (template[i].np < 2) | |
1039 | continue; | |
1040 | ||
1041 | j++; | |
e93acd6f | 1042 | memset(result, 0, digest_size); |
018ba95c WR |
1043 | |
1044 | ret = -EINVAL; | |
1045 | hash_buff = xbuf[0]; | |
1046 | memcpy(hash_buff, template[i].plaintext, | |
1047 | template[i].tap[0]); | |
1048 | sg_init_one(&sg[0], hash_buff, template[i].tap[0]); | |
1049 | ||
1050 | if (template[i].ksize) { | |
1051 | crypto_ahash_clear_flags(tfm, ~0); | |
1052 | if (template[i].ksize > MAX_KEYLEN) { | |
1053 | pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n", | |
1054 | j, algo, template[i].ksize, MAX_KEYLEN); | |
1055 | ret = -EINVAL; | |
1056 | goto out; | |
1057 | } | |
1058 | memcpy(key, template[i].key, template[i].ksize); | |
1059 | ret = crypto_ahash_setkey(tfm, key, template[i].ksize); | |
1060 | if (ret) { | |
1061 | pr_err("alg: hash: setkey failed on test %d for %s: ret=%d\n", | |
1062 | j, algo, -ret); | |
1063 | goto out; | |
1064 | } | |
1065 | } | |
1066 | ||
1067 | ahash_request_set_crypt(req, sg, result, template[i].tap[0]); | |
7f397136 | 1068 | ret = crypto_wait_req(crypto_ahash_init(req), &wait); |
018ba95c | 1069 | if (ret) { |
cf3f9609 | 1070 | pr_err("alg: hash: init failed on test %d for %s: ret=%d\n", |
018ba95c WR |
1071 | j, algo, -ret); |
1072 | goto out; | |
1073 | } | |
7f397136 | 1074 | ret = crypto_wait_req(crypto_ahash_update(req), &wait); |
018ba95c | 1075 | if (ret) { |
cf3f9609 | 1076 | pr_err("alg: hash: update failed on test %d for %s: ret=%d\n", |
018ba95c WR |
1077 | j, algo, -ret); |
1078 | goto out; | |
1079 | } | |
1080 | ||
1081 | temp = template[i].tap[0]; | |
1082 | for (k = 1; k < template[i].np; k++) { | |
1083 | ret = ahash_partial_update(&req, tfm, &template[i], | |
1084 | hash_buff, k, temp, &sg[0], algo, result, | |
7f397136 | 1085 | &wait); |
018ba95c | 1086 | if (ret) { |
cf3f9609 | 1087 | pr_err("alg: hash: partial update failed on test %d for %s: ret=%d\n", |
018ba95c WR |
1088 | j, algo, -ret); |
1089 | goto out_noreq; | |
1090 | } | |
1091 | temp += template[i].tap[k]; | |
1092 | } | |
7f397136 | 1093 | ret = crypto_wait_req(crypto_ahash_final(req), &wait); |
018ba95c | 1094 | if (ret) { |
cf3f9609 | 1095 | pr_err("alg: hash: final failed on test %d for %s: ret=%d\n", |
018ba95c WR |
1096 | j, algo, -ret); |
1097 | goto out; | |
1098 | } | |
1099 | if (memcmp(result, template[i].digest, | |
1100 | crypto_ahash_digestsize(tfm))) { | |
1101 | pr_err("alg: hash: Partial Test %d failed for %s\n", | |
1102 | j, algo); | |
1103 | hexdump(result, crypto_ahash_digestsize(tfm)); | |
1104 | ret = -EINVAL; | |
5f2b424e CS |
1105 | goto out; |
1106 | } | |
da7f033d HX |
1107 | } |
1108 | ||
1109 | ret = 0; | |
1110 | ||
1111 | out: | |
1112 | ahash_request_free(req); | |
1113 | out_noreq: | |
f8b0d4d0 HX |
1114 | testmgr_free_buf(xbuf); |
1115 | out_nobuf: | |
29b77e5d HG |
1116 | kfree(key); |
1117 | kfree(result); | |
da7f033d HX |
1118 | return ret; |
1119 | } | |
1120 | ||
b13b1e0c EB |
1121 | static int test_hash(struct crypto_ahash *tfm, |
1122 | const struct hash_testvec *template, | |
76715095 | 1123 | unsigned int tcount, enum hash_test test_type) |
da5ffe11 JK |
1124 | { |
1125 | unsigned int alignmask; | |
1126 | int ret; | |
1127 | ||
76715095 | 1128 | ret = __test_hash(tfm, template, tcount, test_type, 0); |
da5ffe11 JK |
1129 | if (ret) |
1130 | return ret; | |
1131 | ||
1132 | /* test unaligned buffers, check with one byte offset */ | |
76715095 | 1133 | ret = __test_hash(tfm, template, tcount, test_type, 1); |
da5ffe11 JK |
1134 | if (ret) |
1135 | return ret; | |
1136 | ||
1137 | alignmask = crypto_tfm_alg_alignmask(&tfm->base); | |
1138 | if (alignmask) { | |
1139 | /* Check if alignment mask for tfm is correctly set. */ | |
76715095 | 1140 | ret = __test_hash(tfm, template, tcount, test_type, |
da5ffe11 JK |
1141 | alignmask + 1); |
1142 | if (ret) | |
1143 | return ret; | |
1144 | } | |
1145 | ||
1146 | return 0; | |
1147 | } | |
1148 | ||
d8a32ac2 | 1149 | static int __test_aead(struct crypto_aead *tfm, int enc, |
b13b1e0c | 1150 | const struct aead_testvec *template, unsigned int tcount, |
58dcf548 | 1151 | const bool diff_dst, const int align_offset) |
da7f033d HX |
1152 | { |
1153 | const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)); | |
1154 | unsigned int i, j, k, n, temp; | |
f8b0d4d0 | 1155 | int ret = -ENOMEM; |
da7f033d HX |
1156 | char *q; |
1157 | char *key; | |
1158 | struct aead_request *req; | |
d8a32ac2 | 1159 | struct scatterlist *sg; |
d8a32ac2 JK |
1160 | struct scatterlist *sgout; |
1161 | const char *e, *d; | |
7f397136 | 1162 | struct crypto_wait wait; |
424a5da6 | 1163 | unsigned int authsize, iv_len; |
9bac019d | 1164 | char *iv; |
f8b0d4d0 | 1165 | char *xbuf[XBUFSIZE]; |
d8a32ac2 | 1166 | char *xoutbuf[XBUFSIZE]; |
f8b0d4d0 HX |
1167 | char *axbuf[XBUFSIZE]; |
1168 | ||
9bac019d TS |
1169 | iv = kzalloc(MAX_IVLEN, GFP_KERNEL); |
1170 | if (!iv) | |
1171 | return ret; | |
29b77e5d HG |
1172 | key = kmalloc(MAX_KEYLEN, GFP_KERNEL); |
1173 | if (!key) | |
1174 | goto out_noxbuf; | |
f8b0d4d0 HX |
1175 | if (testmgr_alloc_buf(xbuf)) |
1176 | goto out_noxbuf; | |
1177 | if (testmgr_alloc_buf(axbuf)) | |
1178 | goto out_noaxbuf; | |
d8a32ac2 JK |
1179 | if (diff_dst && testmgr_alloc_buf(xoutbuf)) |
1180 | goto out_nooutbuf; | |
1181 | ||
1182 | /* avoid "the frame size is larger than 1024 bytes" compiler warning */ | |
6da2ec56 KC |
1183 | sg = kmalloc(array3_size(sizeof(*sg), 8, (diff_dst ? 4 : 2)), |
1184 | GFP_KERNEL); | |
d8a32ac2 JK |
1185 | if (!sg) |
1186 | goto out_nosg; | |
8a525fcd | 1187 | sgout = &sg[16]; |
d8a32ac2 JK |
1188 | |
1189 | if (diff_dst) | |
1190 | d = "-ddst"; | |
1191 | else | |
1192 | d = ""; | |
1193 | ||
da7f033d HX |
1194 | if (enc == ENCRYPT) |
1195 | e = "encryption"; | |
1196 | else | |
1197 | e = "decryption"; | |
1198 | ||
7f397136 | 1199 | crypto_init_wait(&wait); |
da7f033d HX |
1200 | |
1201 | req = aead_request_alloc(tfm, GFP_KERNEL); | |
1202 | if (!req) { | |
d8a32ac2 JK |
1203 | pr_err("alg: aead%s: Failed to allocate request for %s\n", |
1204 | d, algo); | |
da7f033d HX |
1205 | goto out; |
1206 | } | |
1207 | ||
1208 | aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, | |
7f397136 | 1209 | crypto_req_done, &wait); |
da7f033d | 1210 | |
abfa7f43 JM |
1211 | iv_len = crypto_aead_ivsize(tfm); |
1212 | ||
da7f033d | 1213 | for (i = 0, j = 0; i < tcount; i++) { |
a0d608ee EB |
1214 | const char *input, *expected_output; |
1215 | unsigned int inlen, outlen; | |
1216 | char *inbuf, *outbuf, *assocbuf; | |
1217 | ||
05b1d338 CS |
1218 | if (template[i].np) |
1219 | continue; | |
a0d608ee EB |
1220 | if (enc) { |
1221 | if (template[i].novrfy) | |
1222 | continue; | |
1223 | input = template[i].ptext; | |
1224 | inlen = template[i].plen; | |
1225 | expected_output = template[i].ctext; | |
1226 | outlen = template[i].clen; | |
1227 | } else { | |
1228 | input = template[i].ctext; | |
1229 | inlen = template[i].clen; | |
1230 | expected_output = template[i].ptext; | |
1231 | outlen = template[i].plen; | |
1232 | } | |
da7f033d | 1233 | |
05b1d338 | 1234 | j++; |
fd57f22a | 1235 | |
05b1d338 CS |
1236 | /* some templates have no input data but they will |
1237 | * touch input | |
1238 | */ | |
a0d608ee EB |
1239 | inbuf = xbuf[0] + align_offset; |
1240 | assocbuf = axbuf[0]; | |
da7f033d | 1241 | |
05b1d338 | 1242 | ret = -EINVAL; |
a0d608ee EB |
1243 | if (WARN_ON(align_offset + template[i].clen > PAGE_SIZE || |
1244 | template[i].alen > PAGE_SIZE)) | |
05b1d338 | 1245 | goto out; |
da7f033d | 1246 | |
a0d608ee EB |
1247 | memcpy(inbuf, input, inlen); |
1248 | memcpy(assocbuf, template[i].assoc, template[i].alen); | |
05b1d338 | 1249 | if (template[i].iv) |
424a5da6 | 1250 | memcpy(iv, template[i].iv, iv_len); |
05b1d338 | 1251 | else |
424a5da6 | 1252 | memset(iv, 0, iv_len); |
05b1d338 CS |
1253 | |
1254 | crypto_aead_clear_flags(tfm, ~0); | |
1255 | if (template[i].wk) | |
231baecd EB |
1256 | crypto_aead_set_flags(tfm, |
1257 | CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); | |
05b1d338 CS |
1258 | |
1259 | if (template[i].klen > MAX_KEYLEN) { | |
1260 | pr_err("alg: aead%s: setkey failed on test %d for %s: key size %d > %d\n", | |
1261 | d, j, algo, template[i].klen, | |
1262 | MAX_KEYLEN); | |
1263 | ret = -EINVAL; | |
1264 | goto out; | |
1265 | } | |
1266 | memcpy(key, template[i].key, template[i].klen); | |
da7f033d | 1267 | |
05b1d338 | 1268 | ret = crypto_aead_setkey(tfm, key, template[i].klen); |
0fae0c1e | 1269 | if (template[i].fail == !ret) { |
05b1d338 CS |
1270 | pr_err("alg: aead%s: setkey failed on test %d for %s: flags=%x\n", |
1271 | d, j, algo, crypto_aead_get_flags(tfm)); | |
1272 | goto out; | |
1273 | } else if (ret) | |
1274 | continue; | |
da7f033d | 1275 | |
a0d608ee | 1276 | authsize = template[i].clen - template[i].plen; |
05b1d338 CS |
1277 | ret = crypto_aead_setauthsize(tfm, authsize); |
1278 | if (ret) { | |
1279 | pr_err("alg: aead%s: Failed to set authsize to %u on test %d for %s\n", | |
1280 | d, authsize, j, algo); | |
1281 | goto out; | |
1282 | } | |
da7f033d | 1283 | |
8a525fcd HX |
1284 | k = !!template[i].alen; |
1285 | sg_init_table(sg, k + 1); | |
a0d608ee EB |
1286 | sg_set_buf(&sg[0], assocbuf, template[i].alen); |
1287 | sg_set_buf(&sg[k], inbuf, template[i].clen); | |
1288 | outbuf = inbuf; | |
8a525fcd | 1289 | |
05b1d338 | 1290 | if (diff_dst) { |
8a525fcd | 1291 | sg_init_table(sgout, k + 1); |
a0d608ee | 1292 | sg_set_buf(&sgout[0], assocbuf, template[i].alen); |
8a525fcd | 1293 | |
a0d608ee EB |
1294 | outbuf = xoutbuf[0] + align_offset; |
1295 | sg_set_buf(&sgout[k], outbuf, template[i].clen); | |
05b1d338 | 1296 | } |
d8a32ac2 | 1297 | |
a0d608ee EB |
1298 | aead_request_set_crypt(req, sg, (diff_dst) ? sgout : sg, inlen, |
1299 | iv); | |
da7f033d | 1300 | |
8a525fcd | 1301 | aead_request_set_ad(req, template[i].alen); |
da7f033d | 1302 | |
7f397136 GBY |
1303 | ret = crypto_wait_req(enc ? crypto_aead_encrypt(req) |
1304 | : crypto_aead_decrypt(req), &wait); | |
da7f033d | 1305 | |
05b1d338 CS |
1306 | switch (ret) { |
1307 | case 0: | |
1308 | if (template[i].novrfy) { | |
1309 | /* verification was supposed to fail */ | |
1310 | pr_err("alg: aead%s: %s failed on test %d for %s: ret was 0, expected -EBADMSG\n", | |
1311 | d, e, j, algo); | |
1312 | /* so really, we got a bad message */ | |
1313 | ret = -EBADMSG; | |
da7f033d HX |
1314 | goto out; |
1315 | } | |
05b1d338 | 1316 | break; |
05b1d338 CS |
1317 | case -EBADMSG: |
1318 | if (template[i].novrfy) | |
1319 | /* verification failure was expected */ | |
1320 | continue; | |
1321 | /* fall through */ | |
1322 | default: | |
1323 | pr_err("alg: aead%s: %s failed on test %d for %s: ret=%d\n", | |
1324 | d, e, j, algo, -ret); | |
1325 | goto out; | |
1326 | } | |
1327 | ||
a0d608ee | 1328 | if (memcmp(outbuf, expected_output, outlen)) { |
05b1d338 CS |
1329 | pr_err("alg: aead%s: Test %d failed on %s for %s\n", |
1330 | d, j, e, algo); | |
a0d608ee | 1331 | hexdump(outbuf, outlen); |
05b1d338 CS |
1332 | ret = -EINVAL; |
1333 | goto out; | |
da7f033d HX |
1334 | } |
1335 | } | |
1336 | ||
1337 | for (i = 0, j = 0; i < tcount; i++) { | |
a0d608ee EB |
1338 | const char *input, *expected_output; |
1339 | unsigned int inlen, outlen; | |
1340 | ||
58dcf548 JK |
1341 | /* alignment tests are only done with continuous buffers */ |
1342 | if (align_offset != 0) | |
1343 | break; | |
1344 | ||
05b1d338 CS |
1345 | if (!template[i].np) |
1346 | continue; | |
da7f033d | 1347 | |
a0d608ee EB |
1348 | if (enc) { |
1349 | if (template[i].novrfy) | |
1350 | continue; | |
1351 | input = template[i].ptext; | |
1352 | inlen = template[i].plen; | |
1353 | expected_output = template[i].ctext; | |
1354 | outlen = template[i].clen; | |
1355 | } else { | |
1356 | input = template[i].ctext; | |
1357 | inlen = template[i].clen; | |
1358 | expected_output = template[i].ptext; | |
1359 | outlen = template[i].plen; | |
1360 | } | |
5bc3de58 | 1361 | |
05b1d338 | 1362 | j++; |
da7f033d | 1363 | |
05b1d338 | 1364 | if (template[i].iv) |
abfa7f43 | 1365 | memcpy(iv, template[i].iv, iv_len); |
05b1d338 CS |
1366 | else |
1367 | memset(iv, 0, MAX_IVLEN); | |
1368 | ||
1369 | crypto_aead_clear_flags(tfm, ~0); | |
1370 | if (template[i].wk) | |
231baecd EB |
1371 | crypto_aead_set_flags(tfm, |
1372 | CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); | |
05b1d338 CS |
1373 | if (template[i].klen > MAX_KEYLEN) { |
1374 | pr_err("alg: aead%s: setkey failed on test %d for %s: key size %d > %d\n", | |
1375 | d, j, algo, template[i].klen, MAX_KEYLEN); | |
1376 | ret = -EINVAL; | |
1377 | goto out; | |
1378 | } | |
1379 | memcpy(key, template[i].key, template[i].klen); | |
da7f033d | 1380 | |
05b1d338 | 1381 | ret = crypto_aead_setkey(tfm, key, template[i].klen); |
0fae0c1e | 1382 | if (template[i].fail == !ret) { |
05b1d338 CS |
1383 | pr_err("alg: aead%s: setkey failed on chunk test %d for %s: flags=%x\n", |
1384 | d, j, algo, crypto_aead_get_flags(tfm)); | |
1385 | goto out; | |
1386 | } else if (ret) | |
1387 | continue; | |
da7f033d | 1388 | |
a0d608ee | 1389 | authsize = template[i].clen - template[i].plen; |
da7f033d | 1390 | |
05b1d338 | 1391 | ret = -EINVAL; |
8a525fcd | 1392 | sg_init_table(sg, template[i].anp + template[i].np); |
05b1d338 | 1393 | if (diff_dst) |
8a525fcd HX |
1394 | sg_init_table(sgout, template[i].anp + template[i].np); |
1395 | ||
1396 | ret = -EINVAL; | |
1397 | for (k = 0, temp = 0; k < template[i].anp; k++) { | |
1398 | if (WARN_ON(offset_in_page(IDX[k]) + | |
1399 | template[i].atap[k] > PAGE_SIZE)) | |
1400 | goto out; | |
1401 | sg_set_buf(&sg[k], | |
1402 | memcpy(axbuf[IDX[k] >> PAGE_SHIFT] + | |
1403 | offset_in_page(IDX[k]), | |
1404 | template[i].assoc + temp, | |
1405 | template[i].atap[k]), | |
1406 | template[i].atap[k]); | |
1407 | if (diff_dst) | |
1408 | sg_set_buf(&sgout[k], | |
1409 | axbuf[IDX[k] >> PAGE_SHIFT] + | |
1410 | offset_in_page(IDX[k]), | |
1411 | template[i].atap[k]); | |
1412 | temp += template[i].atap[k]; | |
1413 | } | |
1414 | ||
05b1d338 | 1415 | for (k = 0, temp = 0; k < template[i].np; k++) { |
a0d608ee EB |
1416 | n = template[i].tap[k]; |
1417 | if (k == template[i].np - 1 && !enc) | |
1418 | n += authsize; | |
1419 | ||
1420 | if (WARN_ON(offset_in_page(IDX[k]) + n > PAGE_SIZE)) | |
05b1d338 | 1421 | goto out; |
da7f033d | 1422 | |
05b1d338 | 1423 | q = xbuf[IDX[k] >> PAGE_SHIFT] + offset_in_page(IDX[k]); |
a0d608ee EB |
1424 | memcpy(q, input + temp, n); |
1425 | sg_set_buf(&sg[template[i].anp + k], q, n); | |
da7f033d | 1426 | |
05b1d338 CS |
1427 | if (diff_dst) { |
1428 | q = xoutbuf[IDX[k] >> PAGE_SHIFT] + | |
1429 | offset_in_page(IDX[k]); | |
d8a32ac2 | 1430 | |
a0d608ee | 1431 | memset(q, 0, n); |
d8a32ac2 | 1432 | |
a0d608ee | 1433 | sg_set_buf(&sgout[template[i].anp + k], q, n); |
05b1d338 | 1434 | } |
d8a32ac2 | 1435 | |
05b1d338 CS |
1436 | if (k == template[i].np - 1 && enc) |
1437 | n += authsize; | |
1438 | if (offset_in_page(q) + n < PAGE_SIZE) | |
1439 | q[n] = 0; | |
d8a32ac2 | 1440 | |
a0d608ee | 1441 | temp += n; |
05b1d338 | 1442 | } |
8ec25c51 | 1443 | |
05b1d338 CS |
1444 | ret = crypto_aead_setauthsize(tfm, authsize); |
1445 | if (ret) { | |
1446 | pr_err("alg: aead%s: Failed to set authsize to %u on chunk test %d for %s\n", | |
1447 | d, authsize, j, algo); | |
1448 | goto out; | |
1449 | } | |
da7f033d | 1450 | |
05b1d338 | 1451 | if (enc) { |
8a525fcd HX |
1452 | if (WARN_ON(sg[template[i].anp + k - 1].offset + |
1453 | sg[template[i].anp + k - 1].length + | |
1454 | authsize > PAGE_SIZE)) { | |
05b1d338 | 1455 | ret = -EINVAL; |
da7f033d HX |
1456 | goto out; |
1457 | } | |
1458 | ||
05b1d338 | 1459 | if (diff_dst) |
8a525fcd HX |
1460 | sgout[template[i].anp + k - 1].length += |
1461 | authsize; | |
1462 | sg[template[i].anp + k - 1].length += authsize; | |
05b1d338 | 1463 | } |
da7f033d | 1464 | |
05b1d338 | 1465 | aead_request_set_crypt(req, sg, (diff_dst) ? sgout : sg, |
a0d608ee | 1466 | inlen, iv); |
da7f033d | 1467 | |
8a525fcd | 1468 | aead_request_set_ad(req, template[i].alen); |
da7f033d | 1469 | |
7f397136 GBY |
1470 | ret = crypto_wait_req(enc ? crypto_aead_encrypt(req) |
1471 | : crypto_aead_decrypt(req), &wait); | |
da7f033d | 1472 | |
05b1d338 CS |
1473 | switch (ret) { |
1474 | case 0: | |
1475 | if (template[i].novrfy) { | |
1476 | /* verification was supposed to fail */ | |
1477 | pr_err("alg: aead%s: %s failed on chunk test %d for %s: ret was 0, expected -EBADMSG\n", | |
1478 | d, e, j, algo); | |
1479 | /* so really, we got a bad message */ | |
1480 | ret = -EBADMSG; | |
da7f033d HX |
1481 | goto out; |
1482 | } | |
05b1d338 | 1483 | break; |
05b1d338 CS |
1484 | case -EBADMSG: |
1485 | if (template[i].novrfy) | |
1486 | /* verification failure was expected */ | |
1487 | continue; | |
1488 | /* fall through */ | |
1489 | default: | |
1490 | pr_err("alg: aead%s: %s failed on chunk test %d for %s: ret=%d\n", | |
1491 | d, e, j, algo, -ret); | |
1492 | goto out; | |
1493 | } | |
da7f033d | 1494 | |
05b1d338 CS |
1495 | ret = -EINVAL; |
1496 | for (k = 0, temp = 0; k < template[i].np; k++) { | |
1497 | if (diff_dst) | |
1498 | q = xoutbuf[IDX[k] >> PAGE_SHIFT] + | |
1499 | offset_in_page(IDX[k]); | |
1500 | else | |
1501 | q = xbuf[IDX[k] >> PAGE_SHIFT] + | |
1502 | offset_in_page(IDX[k]); | |
da7f033d | 1503 | |
05b1d338 | 1504 | n = template[i].tap[k]; |
a0d608ee EB |
1505 | if (k == template[i].np - 1 && enc) |
1506 | n += authsize; | |
da7f033d | 1507 | |
a0d608ee | 1508 | if (memcmp(q, expected_output + temp, n)) { |
05b1d338 CS |
1509 | pr_err("alg: aead%s: Chunk test %d failed on %s at page %u for %s\n", |
1510 | d, j, e, k, algo); | |
1511 | hexdump(q, n); | |
1512 | goto out; | |
1513 | } | |
da7f033d | 1514 | |
05b1d338 CS |
1515 | q += n; |
1516 | if (k == template[i].np - 1 && !enc) { | |
a0d608ee EB |
1517 | if (!diff_dst && memcmp(q, input + temp + n, |
1518 | authsize)) | |
05b1d338 CS |
1519 | n = authsize; |
1520 | else | |
1521 | n = 0; | |
1522 | } else { | |
1523 | for (n = 0; offset_in_page(q + n) && q[n]; n++) | |
1524 | ; | |
1525 | } | |
1526 | if (n) { | |
1527 | pr_err("alg: aead%s: Result buffer corruption in chunk test %d on %s at page %u for %s: %u bytes:\n", | |
1528 | d, j, e, k, algo, n); | |
1529 | hexdump(q, n); | |
1530 | goto out; | |
da7f033d | 1531 | } |
05b1d338 CS |
1532 | |
1533 | temp += template[i].tap[k]; | |
da7f033d HX |
1534 | } |
1535 | } | |
1536 | ||
1537 | ret = 0; | |
1538 | ||
1539 | out: | |
1540 | aead_request_free(req); | |
d8a32ac2 JK |
1541 | kfree(sg); |
1542 | out_nosg: | |
1543 | if (diff_dst) | |
1544 | testmgr_free_buf(xoutbuf); | |
1545 | out_nooutbuf: | |
f8b0d4d0 HX |
1546 | testmgr_free_buf(axbuf); |
1547 | out_noaxbuf: | |
1548 | testmgr_free_buf(xbuf); | |
1549 | out_noxbuf: | |
29b77e5d | 1550 | kfree(key); |
9bac019d | 1551 | kfree(iv); |
da7f033d HX |
1552 | return ret; |
1553 | } | |
1554 | ||
d8a32ac2 | 1555 | static int test_aead(struct crypto_aead *tfm, int enc, |
b13b1e0c | 1556 | const struct aead_testvec *template, unsigned int tcount) |
d8a32ac2 | 1557 | { |
58dcf548 | 1558 | unsigned int alignmask; |
d8a32ac2 JK |
1559 | int ret; |
1560 | ||
1561 | /* test 'dst == src' case */ | |
58dcf548 | 1562 | ret = __test_aead(tfm, enc, template, tcount, false, 0); |
d8a32ac2 JK |
1563 | if (ret) |
1564 | return ret; | |
1565 | ||
1566 | /* test 'dst != src' case */ | |
58dcf548 JK |
1567 | ret = __test_aead(tfm, enc, template, tcount, true, 0); |
1568 | if (ret) | |
1569 | return ret; | |
1570 | ||
1571 | /* test unaligned buffers, check with one byte offset */ | |
1572 | ret = __test_aead(tfm, enc, template, tcount, true, 1); | |
1573 | if (ret) | |
1574 | return ret; | |
1575 | ||
1576 | alignmask = crypto_tfm_alg_alignmask(&tfm->base); | |
1577 | if (alignmask) { | |
1578 | /* Check if alignment mask for tfm is correctly set. */ | |
1579 | ret = __test_aead(tfm, enc, template, tcount, true, | |
1580 | alignmask + 1); | |
1581 | if (ret) | |
1582 | return ret; | |
1583 | } | |
1584 | ||
1585 | return 0; | |
d8a32ac2 JK |
1586 | } |
1587 | ||
1aa4ecd9 | 1588 | static int test_cipher(struct crypto_cipher *tfm, int enc, |
b13b1e0c EB |
1589 | const struct cipher_testvec *template, |
1590 | unsigned int tcount) | |
1aa4ecd9 HX |
1591 | { |
1592 | const char *algo = crypto_tfm_alg_driver_name(crypto_cipher_tfm(tfm)); | |
1593 | unsigned int i, j, k; | |
1aa4ecd9 HX |
1594 | char *q; |
1595 | const char *e; | |
92a4c9fe | 1596 | const char *input, *result; |
1aa4ecd9 | 1597 | void *data; |
f8b0d4d0 HX |
1598 | char *xbuf[XBUFSIZE]; |
1599 | int ret = -ENOMEM; | |
1600 | ||
1601 | if (testmgr_alloc_buf(xbuf)) | |
1602 | goto out_nobuf; | |
1aa4ecd9 HX |
1603 | |
1604 | if (enc == ENCRYPT) | |
1605 | e = "encryption"; | |
1606 | else | |
1607 | e = "decryption"; | |
1608 | ||
1609 | j = 0; | |
1610 | for (i = 0; i < tcount; i++) { | |
1611 | if (template[i].np) | |
1612 | continue; | |
1613 | ||
10faa8c0 SM |
1614 | if (fips_enabled && template[i].fips_skip) |
1615 | continue; | |
1616 | ||
92a4c9fe EB |
1617 | input = enc ? template[i].ptext : template[i].ctext; |
1618 | result = enc ? template[i].ctext : template[i].ptext; | |
1aa4ecd9 HX |
1619 | j++; |
1620 | ||
fd57f22a | 1621 | ret = -EINVAL; |
92a4c9fe | 1622 | if (WARN_ON(template[i].len > PAGE_SIZE)) |
fd57f22a HX |
1623 | goto out; |
1624 | ||
1aa4ecd9 | 1625 | data = xbuf[0]; |
92a4c9fe | 1626 | memcpy(data, input, template[i].len); |
1aa4ecd9 HX |
1627 | |
1628 | crypto_cipher_clear_flags(tfm, ~0); | |
1629 | if (template[i].wk) | |
231baecd | 1630 | crypto_cipher_set_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); |
1aa4ecd9 HX |
1631 | |
1632 | ret = crypto_cipher_setkey(tfm, template[i].key, | |
1633 | template[i].klen); | |
0fae0c1e | 1634 | if (template[i].fail == !ret) { |
1aa4ecd9 HX |
1635 | printk(KERN_ERR "alg: cipher: setkey failed " |
1636 | "on test %d for %s: flags=%x\n", j, | |
1637 | algo, crypto_cipher_get_flags(tfm)); | |
1638 | goto out; | |
1639 | } else if (ret) | |
1640 | continue; | |
1641 | ||
92a4c9fe | 1642 | for (k = 0; k < template[i].len; |
1aa4ecd9 HX |
1643 | k += crypto_cipher_blocksize(tfm)) { |
1644 | if (enc) | |
1645 | crypto_cipher_encrypt_one(tfm, data + k, | |
1646 | data + k); | |
1647 | else | |
1648 | crypto_cipher_decrypt_one(tfm, data + k, | |
1649 | data + k); | |
1650 | } | |
1651 | ||
1652 | q = data; | |
92a4c9fe | 1653 | if (memcmp(q, result, template[i].len)) { |
1aa4ecd9 HX |
1654 | printk(KERN_ERR "alg: cipher: Test %d failed " |
1655 | "on %s for %s\n", j, e, algo); | |
92a4c9fe | 1656 | hexdump(q, template[i].len); |
1aa4ecd9 HX |
1657 | ret = -EINVAL; |
1658 | goto out; | |
1659 | } | |
1660 | } | |
1661 | ||
1662 | ret = 0; | |
1663 | ||
1664 | out: | |
f8b0d4d0 HX |
1665 | testmgr_free_buf(xbuf); |
1666 | out_nobuf: | |
1aa4ecd9 HX |
1667 | return ret; |
1668 | } | |
1669 | ||
12773d93 | 1670 | static int __test_skcipher(struct crypto_skcipher *tfm, int enc, |
b13b1e0c EB |
1671 | const struct cipher_testvec *template, |
1672 | unsigned int tcount, | |
3a338f20 | 1673 | const bool diff_dst, const int align_offset) |
da7f033d HX |
1674 | { |
1675 | const char *algo = | |
12773d93 | 1676 | crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)); |
da7f033d | 1677 | unsigned int i, j, k, n, temp; |
da7f033d | 1678 | char *q; |
12773d93 | 1679 | struct skcipher_request *req; |
da7f033d | 1680 | struct scatterlist sg[8]; |
08d6af8c JK |
1681 | struct scatterlist sgout[8]; |
1682 | const char *e, *d; | |
7f397136 | 1683 | struct crypto_wait wait; |
92a4c9fe | 1684 | const char *input, *result; |
da7f033d HX |
1685 | void *data; |
1686 | char iv[MAX_IVLEN]; | |
f8b0d4d0 | 1687 | char *xbuf[XBUFSIZE]; |
08d6af8c | 1688 | char *xoutbuf[XBUFSIZE]; |
f8b0d4d0 | 1689 | int ret = -ENOMEM; |
84cba178 | 1690 | unsigned int ivsize = crypto_skcipher_ivsize(tfm); |
f8b0d4d0 HX |
1691 | |
1692 | if (testmgr_alloc_buf(xbuf)) | |
1693 | goto out_nobuf; | |
da7f033d | 1694 | |
08d6af8c JK |
1695 | if (diff_dst && testmgr_alloc_buf(xoutbuf)) |
1696 | goto out_nooutbuf; | |
1697 | ||
1698 | if (diff_dst) | |
1699 | d = "-ddst"; | |
1700 | else | |
1701 | d = ""; | |
1702 | ||
da7f033d HX |
1703 | if (enc == ENCRYPT) |
1704 | e = "encryption"; | |
1705 | else | |
1706 | e = "decryption"; | |
1707 | ||
7f397136 | 1708 | crypto_init_wait(&wait); |
da7f033d | 1709 | |
12773d93 | 1710 | req = skcipher_request_alloc(tfm, GFP_KERNEL); |
da7f033d | 1711 | if (!req) { |
08d6af8c JK |
1712 | pr_err("alg: skcipher%s: Failed to allocate request for %s\n", |
1713 | d, algo); | |
da7f033d HX |
1714 | goto out; |
1715 | } | |
1716 | ||
12773d93 | 1717 | skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, |
7f397136 | 1718 | crypto_req_done, &wait); |
da7f033d HX |
1719 | |
1720 | j = 0; | |
1721 | for (i = 0; i < tcount; i++) { | |
bbb9a7dd CS |
1722 | if (template[i].np && !template[i].also_non_np) |
1723 | continue; | |
1724 | ||
10faa8c0 SM |
1725 | if (fips_enabled && template[i].fips_skip) |
1726 | continue; | |
1727 | ||
92a4c9fe | 1728 | if (template[i].iv && !(template[i].generates_iv && enc)) |
84cba178 | 1729 | memcpy(iv, template[i].iv, ivsize); |
da7f033d HX |
1730 | else |
1731 | memset(iv, 0, MAX_IVLEN); | |
1732 | ||
92a4c9fe EB |
1733 | input = enc ? template[i].ptext : template[i].ctext; |
1734 | result = enc ? template[i].ctext : template[i].ptext; | |
a1aa44a2 | 1735 | j++; |
a1aa44a2 | 1736 | ret = -EINVAL; |
92a4c9fe | 1737 | if (WARN_ON(align_offset + template[i].len > PAGE_SIZE)) |
a1aa44a2 | 1738 | goto out; |
da7f033d | 1739 | |
a1aa44a2 CS |
1740 | data = xbuf[0]; |
1741 | data += align_offset; | |
92a4c9fe | 1742 | memcpy(data, input, template[i].len); |
a1aa44a2 | 1743 | |
12773d93 | 1744 | crypto_skcipher_clear_flags(tfm, ~0); |
a1aa44a2 | 1745 | if (template[i].wk) |
231baecd | 1746 | crypto_skcipher_set_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); |
da7f033d | 1747 | |
12773d93 HX |
1748 | ret = crypto_skcipher_setkey(tfm, template[i].key, |
1749 | template[i].klen); | |
0fae0c1e | 1750 | if (template[i].fail == !ret) { |
a1aa44a2 | 1751 | pr_err("alg: skcipher%s: setkey failed on test %d for %s: flags=%x\n", |
12773d93 | 1752 | d, j, algo, crypto_skcipher_get_flags(tfm)); |
a1aa44a2 CS |
1753 | goto out; |
1754 | } else if (ret) | |
1755 | continue; | |
1756 | ||
92a4c9fe | 1757 | sg_init_one(&sg[0], data, template[i].len); |
a1aa44a2 CS |
1758 | if (diff_dst) { |
1759 | data = xoutbuf[0]; | |
1760 | data += align_offset; | |
92a4c9fe | 1761 | sg_init_one(&sgout[0], data, template[i].len); |
a1aa44a2 | 1762 | } |
da7f033d | 1763 | |
12773d93 | 1764 | skcipher_request_set_crypt(req, sg, (diff_dst) ? sgout : sg, |
92a4c9fe | 1765 | template[i].len, iv); |
7f397136 GBY |
1766 | ret = crypto_wait_req(enc ? crypto_skcipher_encrypt(req) : |
1767 | crypto_skcipher_decrypt(req), &wait); | |
a1aa44a2 | 1768 | |
7f397136 | 1769 | if (ret) { |
a1aa44a2 CS |
1770 | pr_err("alg: skcipher%s: %s failed on test %d for %s: ret=%d\n", |
1771 | d, e, j, algo, -ret); | |
1772 | goto out; | |
1773 | } | |
da7f033d | 1774 | |
a1aa44a2 | 1775 | q = data; |
92a4c9fe | 1776 | if (memcmp(q, result, template[i].len)) { |
8a826a34 | 1777 | pr_err("alg: skcipher%s: Test %d failed (invalid result) on %s for %s\n", |
a1aa44a2 | 1778 | d, j, e, algo); |
92a4c9fe | 1779 | hexdump(q, template[i].len); |
a1aa44a2 CS |
1780 | ret = -EINVAL; |
1781 | goto out; | |
da7f033d | 1782 | } |
8a826a34 | 1783 | |
92a4c9fe EB |
1784 | if (template[i].generates_iv && enc && |
1785 | memcmp(iv, template[i].iv, crypto_skcipher_ivsize(tfm))) { | |
8a826a34 BB |
1786 | pr_err("alg: skcipher%s: Test %d failed (invalid output IV) on %s for %s\n", |
1787 | d, j, e, algo); | |
1788 | hexdump(iv, crypto_skcipher_ivsize(tfm)); | |
1789 | ret = -EINVAL; | |
1790 | goto out; | |
1791 | } | |
da7f033d HX |
1792 | } |
1793 | ||
1794 | j = 0; | |
1795 | for (i = 0; i < tcount; i++) { | |
3a338f20 JK |
1796 | /* alignment tests are only done with continuous buffers */ |
1797 | if (align_offset != 0) | |
1798 | break; | |
da7f033d | 1799 | |
bbb9a7dd CS |
1800 | if (!template[i].np) |
1801 | continue; | |
1802 | ||
10faa8c0 SM |
1803 | if (fips_enabled && template[i].fips_skip) |
1804 | continue; | |
1805 | ||
92a4c9fe | 1806 | if (template[i].iv && !(template[i].generates_iv && enc)) |
84cba178 | 1807 | memcpy(iv, template[i].iv, ivsize); |
da7f033d HX |
1808 | else |
1809 | memset(iv, 0, MAX_IVLEN); | |
1810 | ||
92a4c9fe EB |
1811 | input = enc ? template[i].ptext : template[i].ctext; |
1812 | result = enc ? template[i].ctext : template[i].ptext; | |
a1aa44a2 | 1813 | j++; |
12773d93 | 1814 | crypto_skcipher_clear_flags(tfm, ~0); |
a1aa44a2 | 1815 | if (template[i].wk) |
231baecd | 1816 | crypto_skcipher_set_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); |
da7f033d | 1817 | |
12773d93 HX |
1818 | ret = crypto_skcipher_setkey(tfm, template[i].key, |
1819 | template[i].klen); | |
0fae0c1e | 1820 | if (template[i].fail == !ret) { |
a1aa44a2 | 1821 | pr_err("alg: skcipher%s: setkey failed on chunk test %d for %s: flags=%x\n", |
12773d93 | 1822 | d, j, algo, crypto_skcipher_get_flags(tfm)); |
a1aa44a2 CS |
1823 | goto out; |
1824 | } else if (ret) | |
1825 | continue; | |
da7f033d | 1826 | |
a1aa44a2 CS |
1827 | temp = 0; |
1828 | ret = -EINVAL; | |
1829 | sg_init_table(sg, template[i].np); | |
1830 | if (diff_dst) | |
1831 | sg_init_table(sgout, template[i].np); | |
1832 | for (k = 0; k < template[i].np; k++) { | |
1833 | if (WARN_ON(offset_in_page(IDX[k]) + | |
1834 | template[i].tap[k] > PAGE_SIZE)) | |
da7f033d | 1835 | goto out; |
da7f033d | 1836 | |
a1aa44a2 | 1837 | q = xbuf[IDX[k] >> PAGE_SHIFT] + offset_in_page(IDX[k]); |
da7f033d | 1838 | |
92a4c9fe | 1839 | memcpy(q, input + temp, template[i].tap[k]); |
a1aa44a2 CS |
1840 | |
1841 | if (offset_in_page(q) + template[i].tap[k] < PAGE_SIZE) | |
1842 | q[template[i].tap[k]] = 0; | |
1843 | ||
1844 | sg_set_buf(&sg[k], q, template[i].tap[k]); | |
1845 | if (diff_dst) { | |
1846 | q = xoutbuf[IDX[k] >> PAGE_SHIFT] + | |
da7f033d HX |
1847 | offset_in_page(IDX[k]); |
1848 | ||
a1aa44a2 | 1849 | sg_set_buf(&sgout[k], q, template[i].tap[k]); |
da7f033d | 1850 | |
a1aa44a2 CS |
1851 | memset(q, 0, template[i].tap[k]); |
1852 | if (offset_in_page(q) + | |
1853 | template[i].tap[k] < PAGE_SIZE) | |
da7f033d | 1854 | q[template[i].tap[k]] = 0; |
a1aa44a2 | 1855 | } |
da7f033d | 1856 | |
a1aa44a2 CS |
1857 | temp += template[i].tap[k]; |
1858 | } | |
08d6af8c | 1859 | |
12773d93 | 1860 | skcipher_request_set_crypt(req, sg, (diff_dst) ? sgout : sg, |
92a4c9fe | 1861 | template[i].len, iv); |
08d6af8c | 1862 | |
7f397136 GBY |
1863 | ret = crypto_wait_req(enc ? crypto_skcipher_encrypt(req) : |
1864 | crypto_skcipher_decrypt(req), &wait); | |
da7f033d | 1865 | |
7f397136 | 1866 | if (ret) { |
a1aa44a2 CS |
1867 | pr_err("alg: skcipher%s: %s failed on chunk test %d for %s: ret=%d\n", |
1868 | d, e, j, algo, -ret); | |
1869 | goto out; | |
1870 | } | |
da7f033d | 1871 | |
a1aa44a2 CS |
1872 | temp = 0; |
1873 | ret = -EINVAL; | |
1874 | for (k = 0; k < template[i].np; k++) { | |
1875 | if (diff_dst) | |
1876 | q = xoutbuf[IDX[k] >> PAGE_SHIFT] + | |
1877 | offset_in_page(IDX[k]); | |
1878 | else | |
1879 | q = xbuf[IDX[k] >> PAGE_SHIFT] + | |
1880 | offset_in_page(IDX[k]); | |
da7f033d | 1881 | |
92a4c9fe | 1882 | if (memcmp(q, result + temp, template[i].tap[k])) { |
a1aa44a2 CS |
1883 | pr_err("alg: skcipher%s: Chunk test %d failed on %s at page %u for %s\n", |
1884 | d, j, e, k, algo); | |
1885 | hexdump(q, template[i].tap[k]); | |
da7f033d HX |
1886 | goto out; |
1887 | } | |
1888 | ||
a1aa44a2 CS |
1889 | q += template[i].tap[k]; |
1890 | for (n = 0; offset_in_page(q + n) && q[n]; n++) | |
1891 | ; | |
1892 | if (n) { | |
1893 | pr_err("alg: skcipher%s: Result buffer corruption in chunk test %d on %s at page %u for %s: %u bytes:\n", | |
1894 | d, j, e, k, algo, n); | |
1895 | hexdump(q, n); | |
1896 | goto out; | |
da7f033d | 1897 | } |
a1aa44a2 | 1898 | temp += template[i].tap[k]; |
da7f033d HX |
1899 | } |
1900 | } | |
1901 | ||
1902 | ret = 0; | |
1903 | ||
1904 | out: | |
12773d93 | 1905 | skcipher_request_free(req); |
08d6af8c JK |
1906 | if (diff_dst) |
1907 | testmgr_free_buf(xoutbuf); | |
1908 | out_nooutbuf: | |
f8b0d4d0 HX |
1909 | testmgr_free_buf(xbuf); |
1910 | out_nobuf: | |
da7f033d HX |
1911 | return ret; |
1912 | } | |
1913 | ||
12773d93 | 1914 | static int test_skcipher(struct crypto_skcipher *tfm, int enc, |
b13b1e0c EB |
1915 | const struct cipher_testvec *template, |
1916 | unsigned int tcount) | |
08d6af8c | 1917 | { |
3a338f20 | 1918 | unsigned int alignmask; |
08d6af8c JK |
1919 | int ret; |
1920 | ||
1921 | /* test 'dst == src' case */ | |
3a338f20 | 1922 | ret = __test_skcipher(tfm, enc, template, tcount, false, 0); |
08d6af8c JK |
1923 | if (ret) |
1924 | return ret; | |
1925 | ||
1926 | /* test 'dst != src' case */ | |
3a338f20 JK |
1927 | ret = __test_skcipher(tfm, enc, template, tcount, true, 0); |
1928 | if (ret) | |
1929 | return ret; | |
1930 | ||
1931 | /* test unaligned buffers, check with one byte offset */ | |
1932 | ret = __test_skcipher(tfm, enc, template, tcount, true, 1); | |
1933 | if (ret) | |
1934 | return ret; | |
1935 | ||
1936 | alignmask = crypto_tfm_alg_alignmask(&tfm->base); | |
1937 | if (alignmask) { | |
1938 | /* Check if alignment mask for tfm is correctly set. */ | |
1939 | ret = __test_skcipher(tfm, enc, template, tcount, true, | |
1940 | alignmask + 1); | |
1941 | if (ret) | |
1942 | return ret; | |
1943 | } | |
1944 | ||
1945 | return 0; | |
08d6af8c JK |
1946 | } |
1947 | ||
b13b1e0c EB |
1948 | static int test_comp(struct crypto_comp *tfm, |
1949 | const struct comp_testvec *ctemplate, | |
1950 | const struct comp_testvec *dtemplate, | |
1951 | int ctcount, int dtcount) | |
da7f033d HX |
1952 | { |
1953 | const char *algo = crypto_tfm_alg_driver_name(crypto_comp_tfm(tfm)); | |
33607384 | 1954 | char *output, *decomp_output; |
da7f033d | 1955 | unsigned int i; |
da7f033d HX |
1956 | int ret; |
1957 | ||
33607384 MC |
1958 | output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); |
1959 | if (!output) | |
1960 | return -ENOMEM; | |
1961 | ||
1962 | decomp_output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); | |
1963 | if (!decomp_output) { | |
1964 | kfree(output); | |
1965 | return -ENOMEM; | |
1966 | } | |
1967 | ||
da7f033d | 1968 | for (i = 0; i < ctcount; i++) { |
c79cf910 GU |
1969 | int ilen; |
1970 | unsigned int dlen = COMP_BUF_SIZE; | |
da7f033d | 1971 | |
22a8118d MS |
1972 | memset(output, 0, COMP_BUF_SIZE); |
1973 | memset(decomp_output, 0, COMP_BUF_SIZE); | |
da7f033d HX |
1974 | |
1975 | ilen = ctemplate[i].inlen; | |
1976 | ret = crypto_comp_compress(tfm, ctemplate[i].input, | |
33607384 | 1977 | ilen, output, &dlen); |
da7f033d HX |
1978 | if (ret) { |
1979 | printk(KERN_ERR "alg: comp: compression failed " | |
1980 | "on test %d for %s: ret=%d\n", i + 1, algo, | |
1981 | -ret); | |
1982 | goto out; | |
1983 | } | |
1984 | ||
33607384 MC |
1985 | ilen = dlen; |
1986 | dlen = COMP_BUF_SIZE; | |
1987 | ret = crypto_comp_decompress(tfm, output, | |
1988 | ilen, decomp_output, &dlen); | |
1989 | if (ret) { | |
1990 | pr_err("alg: comp: compression failed: decompress: on test %d for %s failed: ret=%d\n", | |
1991 | i + 1, algo, -ret); | |
1992 | goto out; | |
1993 | } | |
1994 | ||
1995 | if (dlen != ctemplate[i].inlen) { | |
b812eb00 GU |
1996 | printk(KERN_ERR "alg: comp: Compression test %d " |
1997 | "failed for %s: output len = %d\n", i + 1, algo, | |
1998 | dlen); | |
1999 | ret = -EINVAL; | |
2000 | goto out; | |
2001 | } | |
2002 | ||
33607384 MC |
2003 | if (memcmp(decomp_output, ctemplate[i].input, |
2004 | ctemplate[i].inlen)) { | |
2005 | pr_err("alg: comp: compression failed: output differs: on test %d for %s\n", | |
2006 | i + 1, algo); | |
2007 | hexdump(decomp_output, dlen); | |
da7f033d HX |
2008 | ret = -EINVAL; |
2009 | goto out; | |
2010 | } | |
2011 | } | |
2012 | ||
2013 | for (i = 0; i < dtcount; i++) { | |
c79cf910 GU |
2014 | int ilen; |
2015 | unsigned int dlen = COMP_BUF_SIZE; | |
da7f033d | 2016 | |
22a8118d | 2017 | memset(decomp_output, 0, COMP_BUF_SIZE); |
da7f033d HX |
2018 | |
2019 | ilen = dtemplate[i].inlen; | |
2020 | ret = crypto_comp_decompress(tfm, dtemplate[i].input, | |
33607384 | 2021 | ilen, decomp_output, &dlen); |
da7f033d HX |
2022 | if (ret) { |
2023 | printk(KERN_ERR "alg: comp: decompression failed " | |
2024 | "on test %d for %s: ret=%d\n", i + 1, algo, | |
2025 | -ret); | |
2026 | goto out; | |
2027 | } | |
2028 | ||
b812eb00 GU |
2029 | if (dlen != dtemplate[i].outlen) { |
2030 | printk(KERN_ERR "alg: comp: Decompression test %d " | |
2031 | "failed for %s: output len = %d\n", i + 1, algo, | |
2032 | dlen); | |
2033 | ret = -EINVAL; | |
2034 | goto out; | |
2035 | } | |
2036 | ||
33607384 | 2037 | if (memcmp(decomp_output, dtemplate[i].output, dlen)) { |
da7f033d HX |
2038 | printk(KERN_ERR "alg: comp: Decompression test %d " |
2039 | "failed for %s\n", i + 1, algo); | |
33607384 | 2040 | hexdump(decomp_output, dlen); |
da7f033d HX |
2041 | ret = -EINVAL; |
2042 | goto out; | |
2043 | } | |
2044 | } | |
2045 | ||
2046 | ret = 0; | |
2047 | ||
2048 | out: | |
33607384 MC |
2049 | kfree(decomp_output); |
2050 | kfree(output); | |
da7f033d HX |
2051 | return ret; |
2052 | } | |
2053 | ||
b13b1e0c | 2054 | static int test_acomp(struct crypto_acomp *tfm, |
33607384 | 2055 | const struct comp_testvec *ctemplate, |
b13b1e0c EB |
2056 | const struct comp_testvec *dtemplate, |
2057 | int ctcount, int dtcount) | |
d7db7a88 GC |
2058 | { |
2059 | const char *algo = crypto_tfm_alg_driver_name(crypto_acomp_tfm(tfm)); | |
2060 | unsigned int i; | |
a9943a0a | 2061 | char *output, *decomp_out; |
d7db7a88 GC |
2062 | int ret; |
2063 | struct scatterlist src, dst; | |
2064 | struct acomp_req *req; | |
7f397136 | 2065 | struct crypto_wait wait; |
d7db7a88 | 2066 | |
eb095593 EB |
2067 | output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); |
2068 | if (!output) | |
2069 | return -ENOMEM; | |
2070 | ||
a9943a0a GC |
2071 | decomp_out = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); |
2072 | if (!decomp_out) { | |
2073 | kfree(output); | |
2074 | return -ENOMEM; | |
2075 | } | |
2076 | ||
d7db7a88 GC |
2077 | for (i = 0; i < ctcount; i++) { |
2078 | unsigned int dlen = COMP_BUF_SIZE; | |
2079 | int ilen = ctemplate[i].inlen; | |
02608e02 | 2080 | void *input_vec; |
d7db7a88 | 2081 | |
d2110224 | 2082 | input_vec = kmemdup(ctemplate[i].input, ilen, GFP_KERNEL); |
02608e02 LA |
2083 | if (!input_vec) { |
2084 | ret = -ENOMEM; | |
2085 | goto out; | |
2086 | } | |
2087 | ||
eb095593 | 2088 | memset(output, 0, dlen); |
7f397136 | 2089 | crypto_init_wait(&wait); |
02608e02 | 2090 | sg_init_one(&src, input_vec, ilen); |
d7db7a88 GC |
2091 | sg_init_one(&dst, output, dlen); |
2092 | ||
2093 | req = acomp_request_alloc(tfm); | |
2094 | if (!req) { | |
2095 | pr_err("alg: acomp: request alloc failed for %s\n", | |
2096 | algo); | |
02608e02 | 2097 | kfree(input_vec); |
d7db7a88 GC |
2098 | ret = -ENOMEM; |
2099 | goto out; | |
2100 | } | |
2101 | ||
2102 | acomp_request_set_params(req, &src, &dst, ilen, dlen); | |
2103 | acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, | |
7f397136 | 2104 | crypto_req_done, &wait); |
d7db7a88 | 2105 | |
7f397136 | 2106 | ret = crypto_wait_req(crypto_acomp_compress(req), &wait); |
d7db7a88 GC |
2107 | if (ret) { |
2108 | pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n", | |
2109 | i + 1, algo, -ret); | |
02608e02 | 2110 | kfree(input_vec); |
d7db7a88 GC |
2111 | acomp_request_free(req); |
2112 | goto out; | |
2113 | } | |
2114 | ||
a9943a0a GC |
2115 | ilen = req->dlen; |
2116 | dlen = COMP_BUF_SIZE; | |
2117 | sg_init_one(&src, output, ilen); | |
2118 | sg_init_one(&dst, decomp_out, dlen); | |
7f397136 | 2119 | crypto_init_wait(&wait); |
a9943a0a GC |
2120 | acomp_request_set_params(req, &src, &dst, ilen, dlen); |
2121 | ||
7f397136 | 2122 | ret = crypto_wait_req(crypto_acomp_decompress(req), &wait); |
a9943a0a GC |
2123 | if (ret) { |
2124 | pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n", | |
2125 | i + 1, algo, -ret); | |
2126 | kfree(input_vec); | |
2127 | acomp_request_free(req); | |
2128 | goto out; | |
2129 | } | |
2130 | ||
2131 | if (req->dlen != ctemplate[i].inlen) { | |
d7db7a88 GC |
2132 | pr_err("alg: acomp: Compression test %d failed for %s: output len = %d\n", |
2133 | i + 1, algo, req->dlen); | |
2134 | ret = -EINVAL; | |
02608e02 | 2135 | kfree(input_vec); |
d7db7a88 GC |
2136 | acomp_request_free(req); |
2137 | goto out; | |
2138 | } | |
2139 | ||
a9943a0a | 2140 | if (memcmp(input_vec, decomp_out, req->dlen)) { |
d7db7a88 GC |
2141 | pr_err("alg: acomp: Compression test %d failed for %s\n", |
2142 | i + 1, algo); | |
2143 | hexdump(output, req->dlen); | |
2144 | ret = -EINVAL; | |
02608e02 | 2145 | kfree(input_vec); |
d7db7a88 GC |
2146 | acomp_request_free(req); |
2147 | goto out; | |
2148 | } | |
2149 | ||
02608e02 | 2150 | kfree(input_vec); |
d7db7a88 GC |
2151 | acomp_request_free(req); |
2152 | } | |
2153 | ||
2154 | for (i = 0; i < dtcount; i++) { | |
2155 | unsigned int dlen = COMP_BUF_SIZE; | |
2156 | int ilen = dtemplate[i].inlen; | |
02608e02 LA |
2157 | void *input_vec; |
2158 | ||
d2110224 | 2159 | input_vec = kmemdup(dtemplate[i].input, ilen, GFP_KERNEL); |
02608e02 LA |
2160 | if (!input_vec) { |
2161 | ret = -ENOMEM; | |
2162 | goto out; | |
2163 | } | |
d7db7a88 | 2164 | |
eb095593 | 2165 | memset(output, 0, dlen); |
7f397136 | 2166 | crypto_init_wait(&wait); |
02608e02 | 2167 | sg_init_one(&src, input_vec, ilen); |
d7db7a88 GC |
2168 | sg_init_one(&dst, output, dlen); |
2169 | ||
2170 | req = acomp_request_alloc(tfm); | |
2171 | if (!req) { | |
2172 | pr_err("alg: acomp: request alloc failed for %s\n", | |
2173 | algo); | |
02608e02 | 2174 | kfree(input_vec); |
d7db7a88 GC |
2175 | ret = -ENOMEM; |
2176 | goto out; | |
2177 | } | |
2178 | ||
2179 | acomp_request_set_params(req, &src, &dst, ilen, dlen); | |
2180 | acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, | |
7f397136 | 2181 | crypto_req_done, &wait); |
d7db7a88 | 2182 | |
7f397136 | 2183 | ret = crypto_wait_req(crypto_acomp_decompress(req), &wait); |
d7db7a88 GC |
2184 | if (ret) { |
2185 | pr_err("alg: acomp: decompression failed on test %d for %s: ret=%d\n", | |
2186 | i + 1, algo, -ret); | |
02608e02 | 2187 | kfree(input_vec); |
d7db7a88 GC |
2188 | acomp_request_free(req); |
2189 | goto out; | |
2190 | } | |
2191 | ||
2192 | if (req->dlen != dtemplate[i].outlen) { | |
2193 | pr_err("alg: acomp: Decompression test %d failed for %s: output len = %d\n", | |
2194 | i + 1, algo, req->dlen); | |
2195 | ret = -EINVAL; | |
02608e02 | 2196 | kfree(input_vec); |
d7db7a88 GC |
2197 | acomp_request_free(req); |
2198 | goto out; | |
2199 | } | |
2200 | ||
2201 | if (memcmp(output, dtemplate[i].output, req->dlen)) { | |
2202 | pr_err("alg: acomp: Decompression test %d failed for %s\n", | |
2203 | i + 1, algo); | |
2204 | hexdump(output, req->dlen); | |
2205 | ret = -EINVAL; | |
02608e02 | 2206 | kfree(input_vec); |
d7db7a88 GC |
2207 | acomp_request_free(req); |
2208 | goto out; | |
2209 | } | |
2210 | ||
02608e02 | 2211 | kfree(input_vec); |
d7db7a88 GC |
2212 | acomp_request_free(req); |
2213 | } | |
2214 | ||
2215 | ret = 0; | |
2216 | ||
2217 | out: | |
a9943a0a | 2218 | kfree(decomp_out); |
eb095593 | 2219 | kfree(output); |
d7db7a88 GC |
2220 | return ret; |
2221 | } | |
2222 | ||
b13b1e0c EB |
2223 | static int test_cprng(struct crypto_rng *tfm, |
2224 | const struct cprng_testvec *template, | |
7647d6ce JW |
2225 | unsigned int tcount) |
2226 | { | |
2227 | const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm)); | |
fa4ef8a6 | 2228 | int err = 0, i, j, seedsize; |
7647d6ce JW |
2229 | u8 *seed; |
2230 | char result[32]; | |
2231 | ||
2232 | seedsize = crypto_rng_seedsize(tfm); | |
2233 | ||
2234 | seed = kmalloc(seedsize, GFP_KERNEL); | |
2235 | if (!seed) { | |
2236 | printk(KERN_ERR "alg: cprng: Failed to allocate seed space " | |
2237 | "for %s\n", algo); | |
2238 | return -ENOMEM; | |
2239 | } | |
2240 | ||
2241 | for (i = 0; i < tcount; i++) { | |
2242 | memset(result, 0, 32); | |
2243 | ||
2244 | memcpy(seed, template[i].v, template[i].vlen); | |
2245 | memcpy(seed + template[i].vlen, template[i].key, | |
2246 | template[i].klen); | |
2247 | memcpy(seed + template[i].vlen + template[i].klen, | |
2248 | template[i].dt, template[i].dtlen); | |
2249 | ||
2250 | err = crypto_rng_reset(tfm, seed, seedsize); | |
2251 | if (err) { | |
2252 | printk(KERN_ERR "alg: cprng: Failed to reset rng " | |
2253 | "for %s\n", algo); | |
2254 | goto out; | |
2255 | } | |
2256 | ||
2257 | for (j = 0; j < template[i].loops; j++) { | |
2258 | err = crypto_rng_get_bytes(tfm, result, | |
2259 | template[i].rlen); | |
19e60e13 | 2260 | if (err < 0) { |
7647d6ce JW |
2261 | printk(KERN_ERR "alg: cprng: Failed to obtain " |
2262 | "the correct amount of random data for " | |
19e60e13 SM |
2263 | "%s (requested %d)\n", algo, |
2264 | template[i].rlen); | |
7647d6ce JW |
2265 | goto out; |
2266 | } | |
2267 | } | |
2268 | ||
2269 | err = memcmp(result, template[i].result, | |
2270 | template[i].rlen); | |
2271 | if (err) { | |
2272 | printk(KERN_ERR "alg: cprng: Test %d failed for %s\n", | |
2273 | i, algo); | |
2274 | hexdump(result, template[i].rlen); | |
2275 | err = -EINVAL; | |
2276 | goto out; | |
2277 | } | |
2278 | } | |
2279 | ||
2280 | out: | |
2281 | kfree(seed); | |
2282 | return err; | |
2283 | } | |
2284 | ||
da7f033d HX |
2285 | static int alg_test_aead(const struct alg_test_desc *desc, const char *driver, |
2286 | u32 type, u32 mask) | |
2287 | { | |
a0d608ee | 2288 | const struct aead_test_suite *suite = &desc->suite.aead; |
da7f033d | 2289 | struct crypto_aead *tfm; |
a0d608ee | 2290 | int err; |
da7f033d | 2291 | |
eed93e0c | 2292 | tfm = crypto_alloc_aead(driver, type, mask); |
da7f033d HX |
2293 | if (IS_ERR(tfm)) { |
2294 | printk(KERN_ERR "alg: aead: Failed to load transform for %s: " | |
2295 | "%ld\n", driver, PTR_ERR(tfm)); | |
2296 | return PTR_ERR(tfm); | |
2297 | } | |
2298 | ||
a0d608ee EB |
2299 | err = test_aead(tfm, ENCRYPT, suite->vecs, suite->count); |
2300 | if (!err) | |
2301 | err = test_aead(tfm, DECRYPT, suite->vecs, suite->count); | |
da7f033d | 2302 | |
da7f033d HX |
2303 | crypto_free_aead(tfm); |
2304 | return err; | |
2305 | } | |
2306 | ||
2307 | static int alg_test_cipher(const struct alg_test_desc *desc, | |
2308 | const char *driver, u32 type, u32 mask) | |
2309 | { | |
92a4c9fe | 2310 | const struct cipher_test_suite *suite = &desc->suite.cipher; |
1aa4ecd9 | 2311 | struct crypto_cipher *tfm; |
92a4c9fe | 2312 | int err; |
da7f033d | 2313 | |
eed93e0c | 2314 | tfm = crypto_alloc_cipher(driver, type, mask); |
da7f033d HX |
2315 | if (IS_ERR(tfm)) { |
2316 | printk(KERN_ERR "alg: cipher: Failed to load transform for " | |
2317 | "%s: %ld\n", driver, PTR_ERR(tfm)); | |
2318 | return PTR_ERR(tfm); | |
2319 | } | |
2320 | ||
92a4c9fe EB |
2321 | err = test_cipher(tfm, ENCRYPT, suite->vecs, suite->count); |
2322 | if (!err) | |
2323 | err = test_cipher(tfm, DECRYPT, suite->vecs, suite->count); | |
da7f033d | 2324 | |
1aa4ecd9 HX |
2325 | crypto_free_cipher(tfm); |
2326 | return err; | |
2327 | } | |
2328 | ||
2329 | static int alg_test_skcipher(const struct alg_test_desc *desc, | |
2330 | const char *driver, u32 type, u32 mask) | |
2331 | { | |
92a4c9fe | 2332 | const struct cipher_test_suite *suite = &desc->suite.cipher; |
12773d93 | 2333 | struct crypto_skcipher *tfm; |
92a4c9fe | 2334 | int err; |
1aa4ecd9 | 2335 | |
eed93e0c | 2336 | tfm = crypto_alloc_skcipher(driver, type, mask); |
1aa4ecd9 HX |
2337 | if (IS_ERR(tfm)) { |
2338 | printk(KERN_ERR "alg: skcipher: Failed to load transform for " | |
2339 | "%s: %ld\n", driver, PTR_ERR(tfm)); | |
2340 | return PTR_ERR(tfm); | |
2341 | } | |
2342 | ||
92a4c9fe EB |
2343 | err = test_skcipher(tfm, ENCRYPT, suite->vecs, suite->count); |
2344 | if (!err) | |
2345 | err = test_skcipher(tfm, DECRYPT, suite->vecs, suite->count); | |
1aa4ecd9 | 2346 | |
12773d93 | 2347 | crypto_free_skcipher(tfm); |
da7f033d HX |
2348 | return err; |
2349 | } | |
2350 | ||
2351 | static int alg_test_comp(const struct alg_test_desc *desc, const char *driver, | |
2352 | u32 type, u32 mask) | |
2353 | { | |
d7db7a88 GC |
2354 | struct crypto_comp *comp; |
2355 | struct crypto_acomp *acomp; | |
da7f033d | 2356 | int err; |
d7db7a88 GC |
2357 | u32 algo_type = type & CRYPTO_ALG_TYPE_ACOMPRESS_MASK; |
2358 | ||
2359 | if (algo_type == CRYPTO_ALG_TYPE_ACOMPRESS) { | |
2360 | acomp = crypto_alloc_acomp(driver, type, mask); | |
2361 | if (IS_ERR(acomp)) { | |
2362 | pr_err("alg: acomp: Failed to load transform for %s: %ld\n", | |
2363 | driver, PTR_ERR(acomp)); | |
2364 | return PTR_ERR(acomp); | |
2365 | } | |
2366 | err = test_acomp(acomp, desc->suite.comp.comp.vecs, | |
2367 | desc->suite.comp.decomp.vecs, | |
2368 | desc->suite.comp.comp.count, | |
2369 | desc->suite.comp.decomp.count); | |
2370 | crypto_free_acomp(acomp); | |
2371 | } else { | |
2372 | comp = crypto_alloc_comp(driver, type, mask); | |
2373 | if (IS_ERR(comp)) { | |
2374 | pr_err("alg: comp: Failed to load transform for %s: %ld\n", | |
2375 | driver, PTR_ERR(comp)); | |
2376 | return PTR_ERR(comp); | |
2377 | } | |
da7f033d | 2378 | |
d7db7a88 GC |
2379 | err = test_comp(comp, desc->suite.comp.comp.vecs, |
2380 | desc->suite.comp.decomp.vecs, | |
2381 | desc->suite.comp.comp.count, | |
2382 | desc->suite.comp.decomp.count); | |
da7f033d | 2383 | |
d7db7a88 GC |
2384 | crypto_free_comp(comp); |
2385 | } | |
da7f033d HX |
2386 | return err; |
2387 | } | |
2388 | ||
9b3abc01 EB |
2389 | static int __alg_test_hash(const struct hash_testvec *template, |
2390 | unsigned int tcount, const char *driver, | |
2391 | u32 type, u32 mask) | |
da7f033d HX |
2392 | { |
2393 | struct crypto_ahash *tfm; | |
2394 | int err; | |
2395 | ||
eed93e0c | 2396 | tfm = crypto_alloc_ahash(driver, type, mask); |
da7f033d HX |
2397 | if (IS_ERR(tfm)) { |
2398 | printk(KERN_ERR "alg: hash: Failed to load transform for %s: " | |
2399 | "%ld\n", driver, PTR_ERR(tfm)); | |
2400 | return PTR_ERR(tfm); | |
2401 | } | |
2402 | ||
76715095 GBY |
2403 | err = test_hash(tfm, template, tcount, HASH_TEST_DIGEST); |
2404 | if (!err) | |
2405 | err = test_hash(tfm, template, tcount, HASH_TEST_FINAL); | |
a8f1a052 | 2406 | if (!err) |
76715095 | 2407 | err = test_hash(tfm, template, tcount, HASH_TEST_FINUP); |
da7f033d HX |
2408 | crypto_free_ahash(tfm); |
2409 | return err; | |
2410 | } | |
2411 | ||
9b3abc01 EB |
2412 | static int alg_test_hash(const struct alg_test_desc *desc, const char *driver, |
2413 | u32 type, u32 mask) | |
2414 | { | |
2415 | const struct hash_testvec *template = desc->suite.hash.vecs; | |
2416 | unsigned int tcount = desc->suite.hash.count; | |
2417 | unsigned int nr_unkeyed, nr_keyed; | |
2418 | int err; | |
2419 | ||
2420 | /* | |
2421 | * For OPTIONAL_KEY algorithms, we have to do all the unkeyed tests | |
2422 | * first, before setting a key on the tfm. To make this easier, we | |
2423 | * require that the unkeyed test vectors (if any) are listed first. | |
2424 | */ | |
2425 | ||
2426 | for (nr_unkeyed = 0; nr_unkeyed < tcount; nr_unkeyed++) { | |
2427 | if (template[nr_unkeyed].ksize) | |
2428 | break; | |
2429 | } | |
2430 | for (nr_keyed = 0; nr_unkeyed + nr_keyed < tcount; nr_keyed++) { | |
2431 | if (!template[nr_unkeyed + nr_keyed].ksize) { | |
2432 | pr_err("alg: hash: test vectors for %s out of order, " | |
2433 | "unkeyed ones must come first\n", desc->alg); | |
2434 | return -EINVAL; | |
2435 | } | |
2436 | } | |
2437 | ||
2438 | err = 0; | |
2439 | if (nr_unkeyed) { | |
2440 | err = __alg_test_hash(template, nr_unkeyed, driver, type, mask); | |
2441 | template += nr_unkeyed; | |
2442 | } | |
2443 | ||
2444 | if (!err && nr_keyed) | |
2445 | err = __alg_test_hash(template, nr_keyed, driver, type, mask); | |
2446 | ||
2447 | return err; | |
2448 | } | |
2449 | ||
8e3ee85e HX |
2450 | static int alg_test_crc32c(const struct alg_test_desc *desc, |
2451 | const char *driver, u32 type, u32 mask) | |
2452 | { | |
2453 | struct crypto_shash *tfm; | |
cb9dde88 | 2454 | __le32 val; |
8e3ee85e HX |
2455 | int err; |
2456 | ||
2457 | err = alg_test_hash(desc, driver, type, mask); | |
2458 | if (err) | |
eb5e6730 | 2459 | return err; |
8e3ee85e | 2460 | |
eed93e0c | 2461 | tfm = crypto_alloc_shash(driver, type, mask); |
8e3ee85e | 2462 | if (IS_ERR(tfm)) { |
eb5e6730 EB |
2463 | if (PTR_ERR(tfm) == -ENOENT) { |
2464 | /* | |
2465 | * This crc32c implementation is only available through | |
2466 | * ahash API, not the shash API, so the remaining part | |
2467 | * of the test is not applicable to it. | |
2468 | */ | |
2469 | return 0; | |
2470 | } | |
8e3ee85e HX |
2471 | printk(KERN_ERR "alg: crc32c: Failed to load transform for %s: " |
2472 | "%ld\n", driver, PTR_ERR(tfm)); | |
eb5e6730 | 2473 | return PTR_ERR(tfm); |
8e3ee85e HX |
2474 | } |
2475 | ||
2476 | do { | |
4c5c3024 JSM |
2477 | SHASH_DESC_ON_STACK(shash, tfm); |
2478 | u32 *ctx = (u32 *)shash_desc_ctx(shash); | |
8e3ee85e | 2479 | |
4c5c3024 JSM |
2480 | shash->tfm = tfm; |
2481 | shash->flags = 0; | |
8e3ee85e | 2482 | |
cb9dde88 | 2483 | *ctx = 420553207; |
4c5c3024 | 2484 | err = crypto_shash_final(shash, (u8 *)&val); |
8e3ee85e HX |
2485 | if (err) { |
2486 | printk(KERN_ERR "alg: crc32c: Operation failed for " | |
2487 | "%s: %d\n", driver, err); | |
2488 | break; | |
2489 | } | |
2490 | ||
cb9dde88 EB |
2491 | if (val != cpu_to_le32(~420553207)) { |
2492 | pr_err("alg: crc32c: Test failed for %s: %u\n", | |
2493 | driver, le32_to_cpu(val)); | |
8e3ee85e HX |
2494 | err = -EINVAL; |
2495 | } | |
2496 | } while (0); | |
2497 | ||
2498 | crypto_free_shash(tfm); | |
2499 | ||
8e3ee85e HX |
2500 | return err; |
2501 | } | |
2502 | ||
7647d6ce JW |
2503 | static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver, |
2504 | u32 type, u32 mask) | |
2505 | { | |
2506 | struct crypto_rng *rng; | |
2507 | int err; | |
2508 | ||
eed93e0c | 2509 | rng = crypto_alloc_rng(driver, type, mask); |
7647d6ce JW |
2510 | if (IS_ERR(rng)) { |
2511 | printk(KERN_ERR "alg: cprng: Failed to load transform for %s: " | |
2512 | "%ld\n", driver, PTR_ERR(rng)); | |
2513 | return PTR_ERR(rng); | |
2514 | } | |
2515 | ||
2516 | err = test_cprng(rng, desc->suite.cprng.vecs, desc->suite.cprng.count); | |
2517 | ||
2518 | crypto_free_rng(rng); | |
2519 | ||
2520 | return err; | |
2521 | } | |
2522 | ||
64d1cdfb | 2523 | |
b13b1e0c | 2524 | static int drbg_cavs_test(const struct drbg_testvec *test, int pr, |
64d1cdfb SM |
2525 | const char *driver, u32 type, u32 mask) |
2526 | { | |
2527 | int ret = -EAGAIN; | |
2528 | struct crypto_rng *drng; | |
2529 | struct drbg_test_data test_data; | |
2530 | struct drbg_string addtl, pers, testentropy; | |
2531 | unsigned char *buf = kzalloc(test->expectedlen, GFP_KERNEL); | |
2532 | ||
2533 | if (!buf) | |
2534 | return -ENOMEM; | |
2535 | ||
eed93e0c | 2536 | drng = crypto_alloc_rng(driver, type, mask); |
64d1cdfb | 2537 | if (IS_ERR(drng)) { |
2fc0d258 | 2538 | printk(KERN_ERR "alg: drbg: could not allocate DRNG handle for " |
64d1cdfb SM |
2539 | "%s\n", driver); |
2540 | kzfree(buf); | |
2541 | return -ENOMEM; | |
2542 | } | |
2543 | ||
2544 | test_data.testentropy = &testentropy; | |
2545 | drbg_string_fill(&testentropy, test->entropy, test->entropylen); | |
2546 | drbg_string_fill(&pers, test->pers, test->perslen); | |
2547 | ret = crypto_drbg_reset_test(drng, &pers, &test_data); | |
2548 | if (ret) { | |
2549 | printk(KERN_ERR "alg: drbg: Failed to reset rng\n"); | |
2550 | goto outbuf; | |
2551 | } | |
2552 | ||
2553 | drbg_string_fill(&addtl, test->addtla, test->addtllen); | |
2554 | if (pr) { | |
2555 | drbg_string_fill(&testentropy, test->entpra, test->entprlen); | |
2556 | ret = crypto_drbg_get_bytes_addtl_test(drng, | |
2557 | buf, test->expectedlen, &addtl, &test_data); | |
2558 | } else { | |
2559 | ret = crypto_drbg_get_bytes_addtl(drng, | |
2560 | buf, test->expectedlen, &addtl); | |
2561 | } | |
19e60e13 | 2562 | if (ret < 0) { |
2fc0d258 | 2563 | printk(KERN_ERR "alg: drbg: could not obtain random data for " |
64d1cdfb SM |
2564 | "driver %s\n", driver); |
2565 | goto outbuf; | |
2566 | } | |
2567 | ||
2568 | drbg_string_fill(&addtl, test->addtlb, test->addtllen); | |
2569 | if (pr) { | |
2570 | drbg_string_fill(&testentropy, test->entprb, test->entprlen); | |
2571 | ret = crypto_drbg_get_bytes_addtl_test(drng, | |
2572 | buf, test->expectedlen, &addtl, &test_data); | |
2573 | } else { | |
2574 | ret = crypto_drbg_get_bytes_addtl(drng, | |
2575 | buf, test->expectedlen, &addtl); | |
2576 | } | |
19e60e13 | 2577 | if (ret < 0) { |
2fc0d258 | 2578 | printk(KERN_ERR "alg: drbg: could not obtain random data for " |
64d1cdfb SM |
2579 | "driver %s\n", driver); |
2580 | goto outbuf; | |
2581 | } | |
2582 | ||
2583 | ret = memcmp(test->expected, buf, test->expectedlen); | |
2584 | ||
2585 | outbuf: | |
2586 | crypto_free_rng(drng); | |
2587 | kzfree(buf); | |
2588 | return ret; | |
2589 | } | |
2590 | ||
2591 | ||
2592 | static int alg_test_drbg(const struct alg_test_desc *desc, const char *driver, | |
2593 | u32 type, u32 mask) | |
2594 | { | |
2595 | int err = 0; | |
2596 | int pr = 0; | |
2597 | int i = 0; | |
b13b1e0c | 2598 | const struct drbg_testvec *template = desc->suite.drbg.vecs; |
64d1cdfb SM |
2599 | unsigned int tcount = desc->suite.drbg.count; |
2600 | ||
2601 | if (0 == memcmp(driver, "drbg_pr_", 8)) | |
2602 | pr = 1; | |
2603 | ||
2604 | for (i = 0; i < tcount; i++) { | |
2605 | err = drbg_cavs_test(&template[i], pr, driver, type, mask); | |
2606 | if (err) { | |
2607 | printk(KERN_ERR "alg: drbg: Test %d failed for %s\n", | |
2608 | i, driver); | |
2609 | err = -EINVAL; | |
2610 | break; | |
2611 | } | |
2612 | } | |
2613 | return err; | |
2614 | ||
2615 | } | |
2616 | ||
b13b1e0c | 2617 | static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec, |
802c7f1c SB |
2618 | const char *alg) |
2619 | { | |
2620 | struct kpp_request *req; | |
2621 | void *input_buf = NULL; | |
2622 | void *output_buf = NULL; | |
47d3fd39 TDA |
2623 | void *a_public = NULL; |
2624 | void *a_ss = NULL; | |
2625 | void *shared_secret = NULL; | |
7f397136 | 2626 | struct crypto_wait wait; |
802c7f1c SB |
2627 | unsigned int out_len_max; |
2628 | int err = -ENOMEM; | |
2629 | struct scatterlist src, dst; | |
2630 | ||
2631 | req = kpp_request_alloc(tfm, GFP_KERNEL); | |
2632 | if (!req) | |
2633 | return err; | |
2634 | ||
7f397136 | 2635 | crypto_init_wait(&wait); |
802c7f1c SB |
2636 | |
2637 | err = crypto_kpp_set_secret(tfm, vec->secret, vec->secret_size); | |
2638 | if (err < 0) | |
2639 | goto free_req; | |
2640 | ||
2641 | out_len_max = crypto_kpp_maxsize(tfm); | |
2642 | output_buf = kzalloc(out_len_max, GFP_KERNEL); | |
2643 | if (!output_buf) { | |
2644 | err = -ENOMEM; | |
2645 | goto free_req; | |
2646 | } | |
2647 | ||
2648 | /* Use appropriate parameter as base */ | |
2649 | kpp_request_set_input(req, NULL, 0); | |
2650 | sg_init_one(&dst, output_buf, out_len_max); | |
2651 | kpp_request_set_output(req, &dst, out_len_max); | |
2652 | kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, | |
7f397136 | 2653 | crypto_req_done, &wait); |
802c7f1c | 2654 | |
47d3fd39 | 2655 | /* Compute party A's public key */ |
7f397136 | 2656 | err = crypto_wait_req(crypto_kpp_generate_public_key(req), &wait); |
802c7f1c | 2657 | if (err) { |
47d3fd39 | 2658 | pr_err("alg: %s: Party A: generate public key test failed. err %d\n", |
802c7f1c SB |
2659 | alg, err); |
2660 | goto free_output; | |
2661 | } | |
47d3fd39 TDA |
2662 | |
2663 | if (vec->genkey) { | |
2664 | /* Save party A's public key */ | |
e3d90e52 | 2665 | a_public = kmemdup(sg_virt(req->dst), out_len_max, GFP_KERNEL); |
47d3fd39 TDA |
2666 | if (!a_public) { |
2667 | err = -ENOMEM; | |
2668 | goto free_output; | |
2669 | } | |
47d3fd39 TDA |
2670 | } else { |
2671 | /* Verify calculated public key */ | |
2672 | if (memcmp(vec->expected_a_public, sg_virt(req->dst), | |
2673 | vec->expected_a_public_size)) { | |
2674 | pr_err("alg: %s: Party A: generate public key test failed. Invalid output\n", | |
2675 | alg); | |
2676 | err = -EINVAL; | |
2677 | goto free_output; | |
2678 | } | |
802c7f1c SB |
2679 | } |
2680 | ||
2681 | /* Calculate shared secret key by using counter part (b) public key. */ | |
e3d90e52 | 2682 | input_buf = kmemdup(vec->b_public, vec->b_public_size, GFP_KERNEL); |
802c7f1c SB |
2683 | if (!input_buf) { |
2684 | err = -ENOMEM; | |
2685 | goto free_output; | |
2686 | } | |
2687 | ||
802c7f1c SB |
2688 | sg_init_one(&src, input_buf, vec->b_public_size); |
2689 | sg_init_one(&dst, output_buf, out_len_max); | |
2690 | kpp_request_set_input(req, &src, vec->b_public_size); | |
2691 | kpp_request_set_output(req, &dst, out_len_max); | |
2692 | kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, | |
7f397136 GBY |
2693 | crypto_req_done, &wait); |
2694 | err = crypto_wait_req(crypto_kpp_compute_shared_secret(req), &wait); | |
802c7f1c | 2695 | if (err) { |
47d3fd39 | 2696 | pr_err("alg: %s: Party A: compute shared secret test failed. err %d\n", |
802c7f1c SB |
2697 | alg, err); |
2698 | goto free_all; | |
2699 | } | |
47d3fd39 TDA |
2700 | |
2701 | if (vec->genkey) { | |
2702 | /* Save the shared secret obtained by party A */ | |
e3d90e52 | 2703 | a_ss = kmemdup(sg_virt(req->dst), vec->expected_ss_size, GFP_KERNEL); |
47d3fd39 TDA |
2704 | if (!a_ss) { |
2705 | err = -ENOMEM; | |
2706 | goto free_all; | |
2707 | } | |
47d3fd39 TDA |
2708 | |
2709 | /* | |
2710 | * Calculate party B's shared secret by using party A's | |
2711 | * public key. | |
2712 | */ | |
2713 | err = crypto_kpp_set_secret(tfm, vec->b_secret, | |
2714 | vec->b_secret_size); | |
2715 | if (err < 0) | |
2716 | goto free_all; | |
2717 | ||
2718 | sg_init_one(&src, a_public, vec->expected_a_public_size); | |
2719 | sg_init_one(&dst, output_buf, out_len_max); | |
2720 | kpp_request_set_input(req, &src, vec->expected_a_public_size); | |
2721 | kpp_request_set_output(req, &dst, out_len_max); | |
2722 | kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, | |
7f397136 GBY |
2723 | crypto_req_done, &wait); |
2724 | err = crypto_wait_req(crypto_kpp_compute_shared_secret(req), | |
2725 | &wait); | |
47d3fd39 TDA |
2726 | if (err) { |
2727 | pr_err("alg: %s: Party B: compute shared secret failed. err %d\n", | |
2728 | alg, err); | |
2729 | goto free_all; | |
2730 | } | |
2731 | ||
2732 | shared_secret = a_ss; | |
2733 | } else { | |
2734 | shared_secret = (void *)vec->expected_ss; | |
2735 | } | |
2736 | ||
802c7f1c SB |
2737 | /* |
2738 | * verify shared secret from which the user will derive | |
2739 | * secret key by executing whatever hash it has chosen | |
2740 | */ | |
47d3fd39 | 2741 | if (memcmp(shared_secret, sg_virt(req->dst), |
802c7f1c SB |
2742 | vec->expected_ss_size)) { |
2743 | pr_err("alg: %s: compute shared secret test failed. Invalid output\n", | |
2744 | alg); | |
2745 | err = -EINVAL; | |
2746 | } | |
2747 | ||
2748 | free_all: | |
47d3fd39 | 2749 | kfree(a_ss); |
802c7f1c SB |
2750 | kfree(input_buf); |
2751 | free_output: | |
47d3fd39 | 2752 | kfree(a_public); |
802c7f1c SB |
2753 | kfree(output_buf); |
2754 | free_req: | |
2755 | kpp_request_free(req); | |
2756 | return err; | |
2757 | } | |
2758 | ||
2759 | static int test_kpp(struct crypto_kpp *tfm, const char *alg, | |
b13b1e0c | 2760 | const struct kpp_testvec *vecs, unsigned int tcount) |
802c7f1c SB |
2761 | { |
2762 | int ret, i; | |
2763 | ||
2764 | for (i = 0; i < tcount; i++) { | |
2765 | ret = do_test_kpp(tfm, vecs++, alg); | |
2766 | if (ret) { | |
2767 | pr_err("alg: %s: test failed on vector %d, err=%d\n", | |
2768 | alg, i + 1, ret); | |
2769 | return ret; | |
2770 | } | |
2771 | } | |
2772 | return 0; | |
2773 | } | |
2774 | ||
2775 | static int alg_test_kpp(const struct alg_test_desc *desc, const char *driver, | |
2776 | u32 type, u32 mask) | |
2777 | { | |
2778 | struct crypto_kpp *tfm; | |
2779 | int err = 0; | |
2780 | ||
eed93e0c | 2781 | tfm = crypto_alloc_kpp(driver, type, mask); |
802c7f1c SB |
2782 | if (IS_ERR(tfm)) { |
2783 | pr_err("alg: kpp: Failed to load tfm for %s: %ld\n", | |
2784 | driver, PTR_ERR(tfm)); | |
2785 | return PTR_ERR(tfm); | |
2786 | } | |
2787 | if (desc->suite.kpp.vecs) | |
2788 | err = test_kpp(tfm, desc->alg, desc->suite.kpp.vecs, | |
2789 | desc->suite.kpp.count); | |
2790 | ||
2791 | crypto_free_kpp(tfm); | |
2792 | return err; | |
2793 | } | |
2794 | ||
50d2b643 | 2795 | static int test_akcipher_one(struct crypto_akcipher *tfm, |
b13b1e0c | 2796 | const struct akcipher_testvec *vecs) |
946cc463 | 2797 | { |
df27b26f | 2798 | char *xbuf[XBUFSIZE]; |
946cc463 TS |
2799 | struct akcipher_request *req; |
2800 | void *outbuf_enc = NULL; | |
2801 | void *outbuf_dec = NULL; | |
7f397136 | 2802 | struct crypto_wait wait; |
946cc463 TS |
2803 | unsigned int out_len_max, out_len = 0; |
2804 | int err = -ENOMEM; | |
22287b0b | 2805 | struct scatterlist src, dst, src_tab[2]; |
0507de94 VC |
2806 | const char *m, *c; |
2807 | unsigned int m_size, c_size; | |
2808 | const char *op; | |
946cc463 | 2809 | |
df27b26f HX |
2810 | if (testmgr_alloc_buf(xbuf)) |
2811 | return err; | |
2812 | ||
946cc463 TS |
2813 | req = akcipher_request_alloc(tfm, GFP_KERNEL); |
2814 | if (!req) | |
df27b26f | 2815 | goto free_xbuf; |
946cc463 | 2816 | |
7f397136 | 2817 | crypto_init_wait(&wait); |
946cc463 | 2818 | |
22287b0b TS |
2819 | if (vecs->public_key_vec) |
2820 | err = crypto_akcipher_set_pub_key(tfm, vecs->key, | |
2821 | vecs->key_len); | |
2822 | else | |
2823 | err = crypto_akcipher_set_priv_key(tfm, vecs->key, | |
2824 | vecs->key_len); | |
2825 | if (err) | |
946cc463 | 2826 | goto free_req; |
946cc463 | 2827 | |
57763f5e | 2828 | err = -ENOMEM; |
22287b0b | 2829 | out_len_max = crypto_akcipher_maxsize(tfm); |
0507de94 VC |
2830 | |
2831 | /* | |
2832 | * First run test which do not require a private key, such as | |
2833 | * encrypt or verify. | |
2834 | */ | |
946cc463 TS |
2835 | outbuf_enc = kzalloc(out_len_max, GFP_KERNEL); |
2836 | if (!outbuf_enc) | |
2837 | goto free_req; | |
2838 | ||
0507de94 VC |
2839 | if (!vecs->siggen_sigver_test) { |
2840 | m = vecs->m; | |
2841 | m_size = vecs->m_size; | |
2842 | c = vecs->c; | |
2843 | c_size = vecs->c_size; | |
2844 | op = "encrypt"; | |
2845 | } else { | |
2846 | /* Swap args so we could keep plaintext (digest) | |
2847 | * in vecs->m, and cooked signature in vecs->c. | |
2848 | */ | |
2849 | m = vecs->c; /* signature */ | |
2850 | m_size = vecs->c_size; | |
2851 | c = vecs->m; /* digest */ | |
2852 | c_size = vecs->m_size; | |
2853 | op = "verify"; | |
2854 | } | |
df27b26f | 2855 | |
0507de94 VC |
2856 | if (WARN_ON(m_size > PAGE_SIZE)) |
2857 | goto free_all; | |
2858 | memcpy(xbuf[0], m, m_size); | |
df27b26f | 2859 | |
22287b0b | 2860 | sg_init_table(src_tab, 2); |
df27b26f | 2861 | sg_set_buf(&src_tab[0], xbuf[0], 8); |
0507de94 | 2862 | sg_set_buf(&src_tab[1], xbuf[0] + 8, m_size - 8); |
22287b0b | 2863 | sg_init_one(&dst, outbuf_enc, out_len_max); |
0507de94 | 2864 | akcipher_request_set_crypt(req, src_tab, &dst, m_size, |
22287b0b | 2865 | out_len_max); |
946cc463 | 2866 | akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, |
7f397136 | 2867 | crypto_req_done, &wait); |
946cc463 | 2868 | |
7f397136 | 2869 | err = crypto_wait_req(vecs->siggen_sigver_test ? |
0507de94 VC |
2870 | /* Run asymmetric signature verification */ |
2871 | crypto_akcipher_verify(req) : | |
7f397136 GBY |
2872 | /* Run asymmetric encrypt */ |
2873 | crypto_akcipher_encrypt(req), &wait); | |
946cc463 | 2874 | if (err) { |
0507de94 | 2875 | pr_err("alg: akcipher: %s test failed. err %d\n", op, err); |
946cc463 TS |
2876 | goto free_all; |
2877 | } | |
0507de94 VC |
2878 | if (req->dst_len != c_size) { |
2879 | pr_err("alg: akcipher: %s test failed. Invalid output len\n", | |
2880 | op); | |
946cc463 TS |
2881 | err = -EINVAL; |
2882 | goto free_all; | |
2883 | } | |
2884 | /* verify that encrypted message is equal to expected */ | |
0507de94 VC |
2885 | if (memcmp(c, outbuf_enc, c_size)) { |
2886 | pr_err("alg: akcipher: %s test failed. Invalid output\n", op); | |
2887 | hexdump(outbuf_enc, c_size); | |
946cc463 TS |
2888 | err = -EINVAL; |
2889 | goto free_all; | |
2890 | } | |
0507de94 VC |
2891 | |
2892 | /* | |
2893 | * Don't invoke (decrypt or sign) test which require a private key | |
2894 | * for vectors with only a public key. | |
2895 | */ | |
946cc463 TS |
2896 | if (vecs->public_key_vec) { |
2897 | err = 0; | |
2898 | goto free_all; | |
2899 | } | |
2900 | outbuf_dec = kzalloc(out_len_max, GFP_KERNEL); | |
2901 | if (!outbuf_dec) { | |
2902 | err = -ENOMEM; | |
2903 | goto free_all; | |
2904 | } | |
df27b26f | 2905 | |
0507de94 VC |
2906 | op = vecs->siggen_sigver_test ? "sign" : "decrypt"; |
2907 | if (WARN_ON(c_size > PAGE_SIZE)) | |
df27b26f | 2908 | goto free_all; |
0507de94 | 2909 | memcpy(xbuf[0], c, c_size); |
df27b26f | 2910 | |
0507de94 | 2911 | sg_init_one(&src, xbuf[0], c_size); |
22287b0b | 2912 | sg_init_one(&dst, outbuf_dec, out_len_max); |
7f397136 | 2913 | crypto_init_wait(&wait); |
0507de94 | 2914 | akcipher_request_set_crypt(req, &src, &dst, c_size, out_len_max); |
946cc463 | 2915 | |
7f397136 | 2916 | err = crypto_wait_req(vecs->siggen_sigver_test ? |
0507de94 VC |
2917 | /* Run asymmetric signature generation */ |
2918 | crypto_akcipher_sign(req) : | |
7f397136 GBY |
2919 | /* Run asymmetric decrypt */ |
2920 | crypto_akcipher_decrypt(req), &wait); | |
946cc463 | 2921 | if (err) { |
0507de94 | 2922 | pr_err("alg: akcipher: %s test failed. err %d\n", op, err); |
946cc463 TS |
2923 | goto free_all; |
2924 | } | |
2925 | out_len = req->dst_len; | |
0507de94 VC |
2926 | if (out_len < m_size) { |
2927 | pr_err("alg: akcipher: %s test failed. Invalid output len %u\n", | |
2928 | op, out_len); | |
946cc463 TS |
2929 | err = -EINVAL; |
2930 | goto free_all; | |
2931 | } | |
2932 | /* verify that decrypted message is equal to the original msg */ | |
0507de94 VC |
2933 | if (memchr_inv(outbuf_dec, 0, out_len - m_size) || |
2934 | memcmp(m, outbuf_dec + out_len - m_size, m_size)) { | |
2935 | pr_err("alg: akcipher: %s test failed. Invalid output\n", op); | |
50d2b643 | 2936 | hexdump(outbuf_dec, out_len); |
946cc463 TS |
2937 | err = -EINVAL; |
2938 | } | |
2939 | free_all: | |
2940 | kfree(outbuf_dec); | |
2941 | kfree(outbuf_enc); | |
2942 | free_req: | |
2943 | akcipher_request_free(req); | |
df27b26f HX |
2944 | free_xbuf: |
2945 | testmgr_free_buf(xbuf); | |
946cc463 TS |
2946 | return err; |
2947 | } | |
2948 | ||
50d2b643 | 2949 | static int test_akcipher(struct crypto_akcipher *tfm, const char *alg, |
b13b1e0c EB |
2950 | const struct akcipher_testvec *vecs, |
2951 | unsigned int tcount) | |
946cc463 | 2952 | { |
15226e48 HX |
2953 | const char *algo = |
2954 | crypto_tfm_alg_driver_name(crypto_akcipher_tfm(tfm)); | |
946cc463 TS |
2955 | int ret, i; |
2956 | ||
2957 | for (i = 0; i < tcount; i++) { | |
50d2b643 HX |
2958 | ret = test_akcipher_one(tfm, vecs++); |
2959 | if (!ret) | |
2960 | continue; | |
946cc463 | 2961 | |
15226e48 HX |
2962 | pr_err("alg: akcipher: test %d failed for %s, err=%d\n", |
2963 | i + 1, algo, ret); | |
50d2b643 HX |
2964 | return ret; |
2965 | } | |
946cc463 TS |
2966 | return 0; |
2967 | } | |
2968 | ||
2969 | static int alg_test_akcipher(const struct alg_test_desc *desc, | |
2970 | const char *driver, u32 type, u32 mask) | |
2971 | { | |
2972 | struct crypto_akcipher *tfm; | |
2973 | int err = 0; | |
2974 | ||
eed93e0c | 2975 | tfm = crypto_alloc_akcipher(driver, type, mask); |
946cc463 TS |
2976 | if (IS_ERR(tfm)) { |
2977 | pr_err("alg: akcipher: Failed to load tfm for %s: %ld\n", | |
2978 | driver, PTR_ERR(tfm)); | |
2979 | return PTR_ERR(tfm); | |
2980 | } | |
2981 | if (desc->suite.akcipher.vecs) | |
2982 | err = test_akcipher(tfm, desc->alg, desc->suite.akcipher.vecs, | |
2983 | desc->suite.akcipher.count); | |
2984 | ||
2985 | crypto_free_akcipher(tfm); | |
2986 | return err; | |
2987 | } | |
2988 | ||
863b557a YS |
2989 | static int alg_test_null(const struct alg_test_desc *desc, |
2990 | const char *driver, u32 type, u32 mask) | |
2991 | { | |
2992 | return 0; | |
2993 | } | |
2994 | ||
21c8e720 AB |
2995 | #define __VECS(tv) { .vecs = tv, .count = ARRAY_SIZE(tv) } |
2996 | ||
da7f033d HX |
2997 | /* Please keep this list sorted by algorithm name. */ |
2998 | static const struct alg_test_desc alg_test_descs[] = { | |
2999 | { | |
059c2a4d EB |
3000 | .alg = "adiantum(xchacha12,aes)", |
3001 | .test = alg_test_skcipher, | |
3002 | .suite = { | |
3003 | .cipher = __VECS(adiantum_xchacha12_aes_tv_template) | |
3004 | }, | |
3005 | }, { | |
3006 | .alg = "adiantum(xchacha20,aes)", | |
3007 | .test = alg_test_skcipher, | |
3008 | .suite = { | |
3009 | .cipher = __VECS(adiantum_xchacha20_aes_tv_template) | |
3010 | }, | |
3011 | }, { | |
b87dc203 OM |
3012 | .alg = "aegis128", |
3013 | .test = alg_test_aead, | |
3014 | .suite = { | |
a0d608ee | 3015 | .aead = __VECS(aegis128_tv_template) |
b87dc203 OM |
3016 | } |
3017 | }, { | |
3018 | .alg = "aegis128l", | |
3019 | .test = alg_test_aead, | |
3020 | .suite = { | |
a0d608ee | 3021 | .aead = __VECS(aegis128l_tv_template) |
b87dc203 OM |
3022 | } |
3023 | }, { | |
3024 | .alg = "aegis256", | |
3025 | .test = alg_test_aead, | |
3026 | .suite = { | |
a0d608ee | 3027 | .aead = __VECS(aegis256_tv_template) |
b87dc203 OM |
3028 | } |
3029 | }, { | |
e08ca2da JW |
3030 | .alg = "ansi_cprng", |
3031 | .test = alg_test_cprng, | |
3032 | .suite = { | |
21c8e720 | 3033 | .cprng = __VECS(ansi_cprng_aes_tv_template) |
e08ca2da | 3034 | } |
bca4feb0 HG |
3035 | }, { |
3036 | .alg = "authenc(hmac(md5),ecb(cipher_null))", | |
3037 | .test = alg_test_aead, | |
bca4feb0 | 3038 | .suite = { |
a0d608ee | 3039 | .aead = __VECS(hmac_md5_ecb_cipher_null_tv_template) |
bca4feb0 | 3040 | } |
e46e9a46 | 3041 | }, { |
a4198fd4 | 3042 | .alg = "authenc(hmac(sha1),cbc(aes))", |
e46e9a46 | 3043 | .test = alg_test_aead, |
bcf741cb | 3044 | .fips_allowed = 1, |
e46e9a46 | 3045 | .suite = { |
a0d608ee | 3046 | .aead = __VECS(hmac_sha1_aes_cbc_tv_temp) |
5208ed2c NL |
3047 | } |
3048 | }, { | |
a4198fd4 | 3049 | .alg = "authenc(hmac(sha1),cbc(des))", |
5208ed2c | 3050 | .test = alg_test_aead, |
5208ed2c | 3051 | .suite = { |
a0d608ee | 3052 | .aead = __VECS(hmac_sha1_des_cbc_tv_temp) |
5208ed2c NL |
3053 | } |
3054 | }, { | |
a4198fd4 | 3055 | .alg = "authenc(hmac(sha1),cbc(des3_ede))", |
5208ed2c | 3056 | .test = alg_test_aead, |
ed1afac9 | 3057 | .fips_allowed = 1, |
5208ed2c | 3058 | .suite = { |
a0d608ee | 3059 | .aead = __VECS(hmac_sha1_des3_ede_cbc_tv_temp) |
e46e9a46 | 3060 | } |
fb16abc2 MM |
3061 | }, { |
3062 | .alg = "authenc(hmac(sha1),ctr(aes))", | |
3063 | .test = alg_test_null, | |
3064 | .fips_allowed = 1, | |
bca4feb0 HG |
3065 | }, { |
3066 | .alg = "authenc(hmac(sha1),ecb(cipher_null))", | |
3067 | .test = alg_test_aead, | |
bca4feb0 | 3068 | .suite = { |
a0d608ee | 3069 | .aead = __VECS(hmac_sha1_ecb_cipher_null_tv_temp) |
5208ed2c | 3070 | } |
8888690e MM |
3071 | }, { |
3072 | .alg = "authenc(hmac(sha1),rfc3686(ctr(aes)))", | |
3073 | .test = alg_test_null, | |
3074 | .fips_allowed = 1, | |
5208ed2c | 3075 | }, { |
a4198fd4 | 3076 | .alg = "authenc(hmac(sha224),cbc(des))", |
5208ed2c | 3077 | .test = alg_test_aead, |
5208ed2c | 3078 | .suite = { |
a0d608ee | 3079 | .aead = __VECS(hmac_sha224_des_cbc_tv_temp) |
5208ed2c NL |
3080 | } |
3081 | }, { | |
a4198fd4 | 3082 | .alg = "authenc(hmac(sha224),cbc(des3_ede))", |
5208ed2c | 3083 | .test = alg_test_aead, |
ed1afac9 | 3084 | .fips_allowed = 1, |
5208ed2c | 3085 | .suite = { |
a0d608ee | 3086 | .aead = __VECS(hmac_sha224_des3_ede_cbc_tv_temp) |
bca4feb0 | 3087 | } |
e46e9a46 | 3088 | }, { |
a4198fd4 | 3089 | .alg = "authenc(hmac(sha256),cbc(aes))", |
e46e9a46 | 3090 | .test = alg_test_aead, |
ed1afac9 | 3091 | .fips_allowed = 1, |
e46e9a46 | 3092 | .suite = { |
a0d608ee | 3093 | .aead = __VECS(hmac_sha256_aes_cbc_tv_temp) |
5208ed2c NL |
3094 | } |
3095 | }, { | |
a4198fd4 | 3096 | .alg = "authenc(hmac(sha256),cbc(des))", |
5208ed2c | 3097 | .test = alg_test_aead, |
5208ed2c | 3098 | .suite = { |
a0d608ee | 3099 | .aead = __VECS(hmac_sha256_des_cbc_tv_temp) |
5208ed2c NL |
3100 | } |
3101 | }, { | |
a4198fd4 | 3102 | .alg = "authenc(hmac(sha256),cbc(des3_ede))", |
5208ed2c | 3103 | .test = alg_test_aead, |
ed1afac9 | 3104 | .fips_allowed = 1, |
5208ed2c | 3105 | .suite = { |
a0d608ee | 3106 | .aead = __VECS(hmac_sha256_des3_ede_cbc_tv_temp) |
5208ed2c | 3107 | } |
fb16abc2 MM |
3108 | }, { |
3109 | .alg = "authenc(hmac(sha256),ctr(aes))", | |
3110 | .test = alg_test_null, | |
3111 | .fips_allowed = 1, | |
8888690e MM |
3112 | }, { |
3113 | .alg = "authenc(hmac(sha256),rfc3686(ctr(aes)))", | |
3114 | .test = alg_test_null, | |
3115 | .fips_allowed = 1, | |
5208ed2c | 3116 | }, { |
a4198fd4 | 3117 | .alg = "authenc(hmac(sha384),cbc(des))", |
5208ed2c | 3118 | .test = alg_test_aead, |
5208ed2c | 3119 | .suite = { |
a0d608ee | 3120 | .aead = __VECS(hmac_sha384_des_cbc_tv_temp) |
5208ed2c NL |
3121 | } |
3122 | }, { | |
a4198fd4 | 3123 | .alg = "authenc(hmac(sha384),cbc(des3_ede))", |
5208ed2c | 3124 | .test = alg_test_aead, |
ed1afac9 | 3125 | .fips_allowed = 1, |
5208ed2c | 3126 | .suite = { |
a0d608ee | 3127 | .aead = __VECS(hmac_sha384_des3_ede_cbc_tv_temp) |
e46e9a46 | 3128 | } |
fb16abc2 MM |
3129 | }, { |
3130 | .alg = "authenc(hmac(sha384),ctr(aes))", | |
3131 | .test = alg_test_null, | |
3132 | .fips_allowed = 1, | |
8888690e MM |
3133 | }, { |
3134 | .alg = "authenc(hmac(sha384),rfc3686(ctr(aes)))", | |
3135 | .test = alg_test_null, | |
3136 | .fips_allowed = 1, | |
e46e9a46 | 3137 | }, { |
a4198fd4 | 3138 | .alg = "authenc(hmac(sha512),cbc(aes))", |
ed1afac9 | 3139 | .fips_allowed = 1, |
e46e9a46 | 3140 | .test = alg_test_aead, |
e46e9a46 | 3141 | .suite = { |
a0d608ee | 3142 | .aead = __VECS(hmac_sha512_aes_cbc_tv_temp) |
5208ed2c NL |
3143 | } |
3144 | }, { | |
a4198fd4 | 3145 | .alg = "authenc(hmac(sha512),cbc(des))", |
5208ed2c | 3146 | .test = alg_test_aead, |
5208ed2c | 3147 | .suite = { |
a0d608ee | 3148 | .aead = __VECS(hmac_sha512_des_cbc_tv_temp) |
5208ed2c NL |
3149 | } |
3150 | }, { | |
a4198fd4 | 3151 | .alg = "authenc(hmac(sha512),cbc(des3_ede))", |
5208ed2c | 3152 | .test = alg_test_aead, |
ed1afac9 | 3153 | .fips_allowed = 1, |
5208ed2c | 3154 | .suite = { |
a0d608ee | 3155 | .aead = __VECS(hmac_sha512_des3_ede_cbc_tv_temp) |
e46e9a46 | 3156 | } |
fb16abc2 MM |
3157 | }, { |
3158 | .alg = "authenc(hmac(sha512),ctr(aes))", | |
3159 | .test = alg_test_null, | |
3160 | .fips_allowed = 1, | |
8888690e MM |
3161 | }, { |
3162 | .alg = "authenc(hmac(sha512),rfc3686(ctr(aes)))", | |
3163 | .test = alg_test_null, | |
3164 | .fips_allowed = 1, | |
e08ca2da | 3165 | }, { |
da7f033d | 3166 | .alg = "cbc(aes)", |
1aa4ecd9 | 3167 | .test = alg_test_skcipher, |
a1915d51 | 3168 | .fips_allowed = 1, |
da7f033d | 3169 | .suite = { |
92a4c9fe EB |
3170 | .cipher = __VECS(aes_cbc_tv_template) |
3171 | }, | |
da7f033d HX |
3172 | }, { |
3173 | .alg = "cbc(anubis)", | |
1aa4ecd9 | 3174 | .test = alg_test_skcipher, |
da7f033d | 3175 | .suite = { |
92a4c9fe EB |
3176 | .cipher = __VECS(anubis_cbc_tv_template) |
3177 | }, | |
da7f033d HX |
3178 | }, { |
3179 | .alg = "cbc(blowfish)", | |
1aa4ecd9 | 3180 | .test = alg_test_skcipher, |
da7f033d | 3181 | .suite = { |
92a4c9fe EB |
3182 | .cipher = __VECS(bf_cbc_tv_template) |
3183 | }, | |
da7f033d HX |
3184 | }, { |
3185 | .alg = "cbc(camellia)", | |
1aa4ecd9 | 3186 | .test = alg_test_skcipher, |
da7f033d | 3187 | .suite = { |
92a4c9fe EB |
3188 | .cipher = __VECS(camellia_cbc_tv_template) |
3189 | }, | |
a2c58260 JG |
3190 | }, { |
3191 | .alg = "cbc(cast5)", | |
3192 | .test = alg_test_skcipher, | |
3193 | .suite = { | |
92a4c9fe EB |
3194 | .cipher = __VECS(cast5_cbc_tv_template) |
3195 | }, | |
9b8b0405 JG |
3196 | }, { |
3197 | .alg = "cbc(cast6)", | |
3198 | .test = alg_test_skcipher, | |
3199 | .suite = { | |
92a4c9fe EB |
3200 | .cipher = __VECS(cast6_cbc_tv_template) |
3201 | }, | |
da7f033d HX |
3202 | }, { |
3203 | .alg = "cbc(des)", | |
1aa4ecd9 | 3204 | .test = alg_test_skcipher, |
da7f033d | 3205 | .suite = { |
92a4c9fe EB |
3206 | .cipher = __VECS(des_cbc_tv_template) |
3207 | }, | |
da7f033d HX |
3208 | }, { |
3209 | .alg = "cbc(des3_ede)", | |
1aa4ecd9 | 3210 | .test = alg_test_skcipher, |
a1915d51 | 3211 | .fips_allowed = 1, |
da7f033d | 3212 | .suite = { |
92a4c9fe EB |
3213 | .cipher = __VECS(des3_ede_cbc_tv_template) |
3214 | }, | |
a794d8d8 GBY |
3215 | }, { |
3216 | /* Same as cbc(aes) except the key is stored in | |
3217 | * hardware secure memory which we reference by index | |
3218 | */ | |
3219 | .alg = "cbc(paes)", | |
3220 | .test = alg_test_null, | |
3221 | .fips_allowed = 1, | |
9d25917d JK |
3222 | }, { |
3223 | .alg = "cbc(serpent)", | |
3224 | .test = alg_test_skcipher, | |
3225 | .suite = { | |
92a4c9fe EB |
3226 | .cipher = __VECS(serpent_cbc_tv_template) |
3227 | }, | |
95ba5973 GBY |
3228 | }, { |
3229 | .alg = "cbc(sm4)", | |
3230 | .test = alg_test_skcipher, | |
3231 | .suite = { | |
3232 | .cipher = __VECS(sm4_cbc_tv_template) | |
3233 | } | |
da7f033d HX |
3234 | }, { |
3235 | .alg = "cbc(twofish)", | |
1aa4ecd9 | 3236 | .test = alg_test_skcipher, |
da7f033d | 3237 | .suite = { |
92a4c9fe EB |
3238 | .cipher = __VECS(tf_cbc_tv_template) |
3239 | }, | |
092acf06 AB |
3240 | }, { |
3241 | .alg = "cbcmac(aes)", | |
3242 | .fips_allowed = 1, | |
3243 | .test = alg_test_hash, | |
3244 | .suite = { | |
3245 | .hash = __VECS(aes_cbcmac_tv_template) | |
3246 | } | |
da7f033d HX |
3247 | }, { |
3248 | .alg = "ccm(aes)", | |
3249 | .test = alg_test_aead, | |
a1915d51 | 3250 | .fips_allowed = 1, |
da7f033d | 3251 | .suite = { |
a0d608ee | 3252 | .aead = __VECS(aes_ccm_tv_template) |
da7f033d | 3253 | } |
7da66670 DB |
3254 | }, { |
3255 | .alg = "cfb(aes)", | |
3256 | .test = alg_test_skcipher, | |
3257 | .fips_allowed = 1, | |
3258 | .suite = { | |
3259 | .cipher = __VECS(aes_cfb_tv_template) | |
3260 | }, | |
3590ebf2 MW |
3261 | }, { |
3262 | .alg = "chacha20", | |
3263 | .test = alg_test_skcipher, | |
3264 | .suite = { | |
92a4c9fe EB |
3265 | .cipher = __VECS(chacha20_tv_template) |
3266 | }, | |
93b5e86a JK |
3267 | }, { |
3268 | .alg = "cmac(aes)", | |
8f183751 | 3269 | .fips_allowed = 1, |
93b5e86a JK |
3270 | .test = alg_test_hash, |
3271 | .suite = { | |
21c8e720 | 3272 | .hash = __VECS(aes_cmac128_tv_template) |
93b5e86a JK |
3273 | } |
3274 | }, { | |
3275 | .alg = "cmac(des3_ede)", | |
8f183751 | 3276 | .fips_allowed = 1, |
93b5e86a JK |
3277 | .test = alg_test_hash, |
3278 | .suite = { | |
21c8e720 | 3279 | .hash = __VECS(des3_ede_cmac64_tv_template) |
93b5e86a | 3280 | } |
e448370d JK |
3281 | }, { |
3282 | .alg = "compress_null", | |
3283 | .test = alg_test_null, | |
ebb3472f AB |
3284 | }, { |
3285 | .alg = "crc32", | |
3286 | .test = alg_test_hash, | |
a8a34416 | 3287 | .fips_allowed = 1, |
ebb3472f | 3288 | .suite = { |
21c8e720 | 3289 | .hash = __VECS(crc32_tv_template) |
ebb3472f | 3290 | } |
da7f033d HX |
3291 | }, { |
3292 | .alg = "crc32c", | |
8e3ee85e | 3293 | .test = alg_test_crc32c, |
a1915d51 | 3294 | .fips_allowed = 1, |
da7f033d | 3295 | .suite = { |
21c8e720 | 3296 | .hash = __VECS(crc32c_tv_template) |
da7f033d | 3297 | } |
68411521 HX |
3298 | }, { |
3299 | .alg = "crct10dif", | |
3300 | .test = alg_test_hash, | |
3301 | .fips_allowed = 1, | |
3302 | .suite = { | |
21c8e720 | 3303 | .hash = __VECS(crct10dif_tv_template) |
68411521 | 3304 | } |
f7cb80f2 JW |
3305 | }, { |
3306 | .alg = "ctr(aes)", | |
3307 | .test = alg_test_skcipher, | |
a1915d51 | 3308 | .fips_allowed = 1, |
f7cb80f2 | 3309 | .suite = { |
92a4c9fe | 3310 | .cipher = __VECS(aes_ctr_tv_template) |
f7cb80f2 | 3311 | } |
85b63e34 JK |
3312 | }, { |
3313 | .alg = "ctr(blowfish)", | |
3314 | .test = alg_test_skcipher, | |
3315 | .suite = { | |
92a4c9fe | 3316 | .cipher = __VECS(bf_ctr_tv_template) |
85b63e34 | 3317 | } |
0840605e JK |
3318 | }, { |
3319 | .alg = "ctr(camellia)", | |
3320 | .test = alg_test_skcipher, | |
3321 | .suite = { | |
92a4c9fe | 3322 | .cipher = __VECS(camellia_ctr_tv_template) |
0840605e | 3323 | } |
a2c58260 JG |
3324 | }, { |
3325 | .alg = "ctr(cast5)", | |
3326 | .test = alg_test_skcipher, | |
3327 | .suite = { | |
92a4c9fe | 3328 | .cipher = __VECS(cast5_ctr_tv_template) |
a2c58260 | 3329 | } |
9b8b0405 JG |
3330 | }, { |
3331 | .alg = "ctr(cast6)", | |
3332 | .test = alg_test_skcipher, | |
3333 | .suite = { | |
92a4c9fe | 3334 | .cipher = __VECS(cast6_ctr_tv_template) |
9b8b0405 | 3335 | } |
8163fc30 JK |
3336 | }, { |
3337 | .alg = "ctr(des)", | |
3338 | .test = alg_test_skcipher, | |
3339 | .suite = { | |
92a4c9fe | 3340 | .cipher = __VECS(des_ctr_tv_template) |
8163fc30 | 3341 | } |
e080b17a JK |
3342 | }, { |
3343 | .alg = "ctr(des3_ede)", | |
3344 | .test = alg_test_skcipher, | |
0d8da104 | 3345 | .fips_allowed = 1, |
e080b17a | 3346 | .suite = { |
92a4c9fe | 3347 | .cipher = __VECS(des3_ede_ctr_tv_template) |
e080b17a | 3348 | } |
a794d8d8 GBY |
3349 | }, { |
3350 | /* Same as ctr(aes) except the key is stored in | |
3351 | * hardware secure memory which we reference by index | |
3352 | */ | |
3353 | .alg = "ctr(paes)", | |
3354 | .test = alg_test_null, | |
3355 | .fips_allowed = 1, | |
9d25917d JK |
3356 | }, { |
3357 | .alg = "ctr(serpent)", | |
3358 | .test = alg_test_skcipher, | |
3359 | .suite = { | |
92a4c9fe | 3360 | .cipher = __VECS(serpent_ctr_tv_template) |
9d25917d | 3361 | } |
95ba5973 GBY |
3362 | }, { |
3363 | .alg = "ctr(sm4)", | |
3364 | .test = alg_test_skcipher, | |
3365 | .suite = { | |
3366 | .cipher = __VECS(sm4_ctr_tv_template) | |
3367 | } | |
573da620 JK |
3368 | }, { |
3369 | .alg = "ctr(twofish)", | |
3370 | .test = alg_test_skcipher, | |
3371 | .suite = { | |
92a4c9fe | 3372 | .cipher = __VECS(tf_ctr_tv_template) |
573da620 | 3373 | } |
da7f033d HX |
3374 | }, { |
3375 | .alg = "cts(cbc(aes))", | |
1aa4ecd9 | 3376 | .test = alg_test_skcipher, |
196ad604 | 3377 | .fips_allowed = 1, |
da7f033d | 3378 | .suite = { |
92a4c9fe | 3379 | .cipher = __VECS(cts_mode_tv_template) |
da7f033d HX |
3380 | } |
3381 | }, { | |
3382 | .alg = "deflate", | |
3383 | .test = alg_test_comp, | |
0818904d | 3384 | .fips_allowed = 1, |
da7f033d HX |
3385 | .suite = { |
3386 | .comp = { | |
21c8e720 AB |
3387 | .comp = __VECS(deflate_comp_tv_template), |
3388 | .decomp = __VECS(deflate_decomp_tv_template) | |
da7f033d HX |
3389 | } |
3390 | } | |
802c7f1c SB |
3391 | }, { |
3392 | .alg = "dh", | |
3393 | .test = alg_test_kpp, | |
3394 | .fips_allowed = 1, | |
3395 | .suite = { | |
21c8e720 | 3396 | .kpp = __VECS(dh_tv_template) |
802c7f1c | 3397 | } |
e448370d JK |
3398 | }, { |
3399 | .alg = "digest_null", | |
3400 | .test = alg_test_null, | |
64d1cdfb SM |
3401 | }, { |
3402 | .alg = "drbg_nopr_ctr_aes128", | |
3403 | .test = alg_test_drbg, | |
3404 | .fips_allowed = 1, | |
3405 | .suite = { | |
21c8e720 | 3406 | .drbg = __VECS(drbg_nopr_ctr_aes128_tv_template) |
64d1cdfb SM |
3407 | } |
3408 | }, { | |
3409 | .alg = "drbg_nopr_ctr_aes192", | |
3410 | .test = alg_test_drbg, | |
3411 | .fips_allowed = 1, | |
3412 | .suite = { | |
21c8e720 | 3413 | .drbg = __VECS(drbg_nopr_ctr_aes192_tv_template) |
64d1cdfb SM |
3414 | } |
3415 | }, { | |
3416 | .alg = "drbg_nopr_ctr_aes256", | |
3417 | .test = alg_test_drbg, | |
3418 | .fips_allowed = 1, | |
3419 | .suite = { | |
21c8e720 | 3420 | .drbg = __VECS(drbg_nopr_ctr_aes256_tv_template) |
64d1cdfb SM |
3421 | } |
3422 | }, { | |
3423 | /* | |
3424 | * There is no need to specifically test the DRBG with every | |
3425 | * backend cipher -- covered by drbg_nopr_hmac_sha256 test | |
3426 | */ | |
3427 | .alg = "drbg_nopr_hmac_sha1", | |
3428 | .fips_allowed = 1, | |
3429 | .test = alg_test_null, | |
3430 | }, { | |
3431 | .alg = "drbg_nopr_hmac_sha256", | |
3432 | .test = alg_test_drbg, | |
3433 | .fips_allowed = 1, | |
3434 | .suite = { | |
21c8e720 | 3435 | .drbg = __VECS(drbg_nopr_hmac_sha256_tv_template) |
64d1cdfb SM |
3436 | } |
3437 | }, { | |
3438 | /* covered by drbg_nopr_hmac_sha256 test */ | |
3439 | .alg = "drbg_nopr_hmac_sha384", | |
3440 | .fips_allowed = 1, | |
3441 | .test = alg_test_null, | |
3442 | }, { | |
3443 | .alg = "drbg_nopr_hmac_sha512", | |
3444 | .test = alg_test_null, | |
3445 | .fips_allowed = 1, | |
3446 | }, { | |
3447 | .alg = "drbg_nopr_sha1", | |
3448 | .fips_allowed = 1, | |
3449 | .test = alg_test_null, | |
3450 | }, { | |
3451 | .alg = "drbg_nopr_sha256", | |
3452 | .test = alg_test_drbg, | |
3453 | .fips_allowed = 1, | |
3454 | .suite = { | |
21c8e720 | 3455 | .drbg = __VECS(drbg_nopr_sha256_tv_template) |
64d1cdfb SM |
3456 | } |
3457 | }, { | |
3458 | /* covered by drbg_nopr_sha256 test */ | |
3459 | .alg = "drbg_nopr_sha384", | |
3460 | .fips_allowed = 1, | |
3461 | .test = alg_test_null, | |
3462 | }, { | |
3463 | .alg = "drbg_nopr_sha512", | |
3464 | .fips_allowed = 1, | |
3465 | .test = alg_test_null, | |
3466 | }, { | |
3467 | .alg = "drbg_pr_ctr_aes128", | |
3468 | .test = alg_test_drbg, | |
3469 | .fips_allowed = 1, | |
3470 | .suite = { | |
21c8e720 | 3471 | .drbg = __VECS(drbg_pr_ctr_aes128_tv_template) |
64d1cdfb SM |
3472 | } |
3473 | }, { | |
3474 | /* covered by drbg_pr_ctr_aes128 test */ | |
3475 | .alg = "drbg_pr_ctr_aes192", | |
3476 | .fips_allowed = 1, | |
3477 | .test = alg_test_null, | |
3478 | }, { | |
3479 | .alg = "drbg_pr_ctr_aes256", | |
3480 | .fips_allowed = 1, | |
3481 | .test = alg_test_null, | |
3482 | }, { | |
3483 | .alg = "drbg_pr_hmac_sha1", | |
3484 | .fips_allowed = 1, | |
3485 | .test = alg_test_null, | |
3486 | }, { | |
3487 | .alg = "drbg_pr_hmac_sha256", | |
3488 | .test = alg_test_drbg, | |
3489 | .fips_allowed = 1, | |
3490 | .suite = { | |
21c8e720 | 3491 | .drbg = __VECS(drbg_pr_hmac_sha256_tv_template) |
64d1cdfb SM |
3492 | } |
3493 | }, { | |
3494 | /* covered by drbg_pr_hmac_sha256 test */ | |
3495 | .alg = "drbg_pr_hmac_sha384", | |
3496 | .fips_allowed = 1, | |
3497 | .test = alg_test_null, | |
3498 | }, { | |
3499 | .alg = "drbg_pr_hmac_sha512", | |
3500 | .test = alg_test_null, | |
3501 | .fips_allowed = 1, | |
3502 | }, { | |
3503 | .alg = "drbg_pr_sha1", | |
3504 | .fips_allowed = 1, | |
3505 | .test = alg_test_null, | |
3506 | }, { | |
3507 | .alg = "drbg_pr_sha256", | |
3508 | .test = alg_test_drbg, | |
3509 | .fips_allowed = 1, | |
3510 | .suite = { | |
21c8e720 | 3511 | .drbg = __VECS(drbg_pr_sha256_tv_template) |
64d1cdfb SM |
3512 | } |
3513 | }, { | |
3514 | /* covered by drbg_pr_sha256 test */ | |
3515 | .alg = "drbg_pr_sha384", | |
3516 | .fips_allowed = 1, | |
3517 | .test = alg_test_null, | |
3518 | }, { | |
3519 | .alg = "drbg_pr_sha512", | |
3520 | .fips_allowed = 1, | |
3521 | .test = alg_test_null, | |
da7f033d HX |
3522 | }, { |
3523 | .alg = "ecb(aes)", | |
1aa4ecd9 | 3524 | .test = alg_test_skcipher, |
a1915d51 | 3525 | .fips_allowed = 1, |
da7f033d | 3526 | .suite = { |
92a4c9fe | 3527 | .cipher = __VECS(aes_tv_template) |
da7f033d HX |
3528 | } |
3529 | }, { | |
3530 | .alg = "ecb(anubis)", | |
1aa4ecd9 | 3531 | .test = alg_test_skcipher, |
da7f033d | 3532 | .suite = { |
92a4c9fe | 3533 | .cipher = __VECS(anubis_tv_template) |
da7f033d HX |
3534 | } |
3535 | }, { | |
3536 | .alg = "ecb(arc4)", | |
1aa4ecd9 | 3537 | .test = alg_test_skcipher, |
da7f033d | 3538 | .suite = { |
92a4c9fe | 3539 | .cipher = __VECS(arc4_tv_template) |
da7f033d HX |
3540 | } |
3541 | }, { | |
3542 | .alg = "ecb(blowfish)", | |
1aa4ecd9 | 3543 | .test = alg_test_skcipher, |
da7f033d | 3544 | .suite = { |
92a4c9fe | 3545 | .cipher = __VECS(bf_tv_template) |
da7f033d HX |
3546 | } |
3547 | }, { | |
3548 | .alg = "ecb(camellia)", | |
1aa4ecd9 | 3549 | .test = alg_test_skcipher, |
da7f033d | 3550 | .suite = { |
92a4c9fe | 3551 | .cipher = __VECS(camellia_tv_template) |
da7f033d HX |
3552 | } |
3553 | }, { | |
3554 | .alg = "ecb(cast5)", | |
1aa4ecd9 | 3555 | .test = alg_test_skcipher, |
da7f033d | 3556 | .suite = { |
92a4c9fe | 3557 | .cipher = __VECS(cast5_tv_template) |
da7f033d HX |
3558 | } |
3559 | }, { | |
3560 | .alg = "ecb(cast6)", | |
1aa4ecd9 | 3561 | .test = alg_test_skcipher, |
da7f033d | 3562 | .suite = { |
92a4c9fe | 3563 | .cipher = __VECS(cast6_tv_template) |
da7f033d | 3564 | } |
e448370d JK |
3565 | }, { |
3566 | .alg = "ecb(cipher_null)", | |
3567 | .test = alg_test_null, | |
6175ca2b | 3568 | .fips_allowed = 1, |
da7f033d HX |
3569 | }, { |
3570 | .alg = "ecb(des)", | |
1aa4ecd9 | 3571 | .test = alg_test_skcipher, |
da7f033d | 3572 | .suite = { |
92a4c9fe | 3573 | .cipher = __VECS(des_tv_template) |
da7f033d HX |
3574 | } |
3575 | }, { | |
3576 | .alg = "ecb(des3_ede)", | |
1aa4ecd9 | 3577 | .test = alg_test_skcipher, |
a1915d51 | 3578 | .fips_allowed = 1, |
da7f033d | 3579 | .suite = { |
92a4c9fe | 3580 | .cipher = __VECS(des3_ede_tv_template) |
da7f033d | 3581 | } |
66e5bd00 JK |
3582 | }, { |
3583 | .alg = "ecb(fcrypt)", | |
3584 | .test = alg_test_skcipher, | |
3585 | .suite = { | |
3586 | .cipher = { | |
92a4c9fe EB |
3587 | .vecs = fcrypt_pcbc_tv_template, |
3588 | .count = 1 | |
66e5bd00 JK |
3589 | } |
3590 | } | |
da7f033d HX |
3591 | }, { |
3592 | .alg = "ecb(khazad)", | |
1aa4ecd9 | 3593 | .test = alg_test_skcipher, |
da7f033d | 3594 | .suite = { |
92a4c9fe | 3595 | .cipher = __VECS(khazad_tv_template) |
da7f033d | 3596 | } |
15f47ce5 GBY |
3597 | }, { |
3598 | /* Same as ecb(aes) except the key is stored in | |
3599 | * hardware secure memory which we reference by index | |
3600 | */ | |
3601 | .alg = "ecb(paes)", | |
3602 | .test = alg_test_null, | |
3603 | .fips_allowed = 1, | |
da7f033d HX |
3604 | }, { |
3605 | .alg = "ecb(seed)", | |
1aa4ecd9 | 3606 | .test = alg_test_skcipher, |
da7f033d | 3607 | .suite = { |
92a4c9fe | 3608 | .cipher = __VECS(seed_tv_template) |
da7f033d HX |
3609 | } |
3610 | }, { | |
3611 | .alg = "ecb(serpent)", | |
1aa4ecd9 | 3612 | .test = alg_test_skcipher, |
da7f033d | 3613 | .suite = { |
92a4c9fe | 3614 | .cipher = __VECS(serpent_tv_template) |
da7f033d | 3615 | } |
cd83a8a7 GBY |
3616 | }, { |
3617 | .alg = "ecb(sm4)", | |
3618 | .test = alg_test_skcipher, | |
3619 | .suite = { | |
92a4c9fe | 3620 | .cipher = __VECS(sm4_tv_template) |
cd83a8a7 | 3621 | } |
da7f033d HX |
3622 | }, { |
3623 | .alg = "ecb(tea)", | |
1aa4ecd9 | 3624 | .test = alg_test_skcipher, |
da7f033d | 3625 | .suite = { |
92a4c9fe | 3626 | .cipher = __VECS(tea_tv_template) |
da7f033d HX |
3627 | } |
3628 | }, { | |
3629 | .alg = "ecb(tnepres)", | |
1aa4ecd9 | 3630 | .test = alg_test_skcipher, |
da7f033d | 3631 | .suite = { |
92a4c9fe | 3632 | .cipher = __VECS(tnepres_tv_template) |
da7f033d HX |
3633 | } |
3634 | }, { | |
3635 | .alg = "ecb(twofish)", | |
1aa4ecd9 | 3636 | .test = alg_test_skcipher, |
da7f033d | 3637 | .suite = { |
92a4c9fe | 3638 | .cipher = __VECS(tf_tv_template) |
da7f033d HX |
3639 | } |
3640 | }, { | |
3641 | .alg = "ecb(xeta)", | |
1aa4ecd9 | 3642 | .test = alg_test_skcipher, |
da7f033d | 3643 | .suite = { |
92a4c9fe | 3644 | .cipher = __VECS(xeta_tv_template) |
da7f033d HX |
3645 | } |
3646 | }, { | |
3647 | .alg = "ecb(xtea)", | |
1aa4ecd9 | 3648 | .test = alg_test_skcipher, |
da7f033d | 3649 | .suite = { |
92a4c9fe | 3650 | .cipher = __VECS(xtea_tv_template) |
da7f033d | 3651 | } |
3c4b2390 SB |
3652 | }, { |
3653 | .alg = "ecdh", | |
3654 | .test = alg_test_kpp, | |
3655 | .fips_allowed = 1, | |
3656 | .suite = { | |
21c8e720 | 3657 | .kpp = __VECS(ecdh_tv_template) |
3c4b2390 | 3658 | } |
da7f033d HX |
3659 | }, { |
3660 | .alg = "gcm(aes)", | |
3661 | .test = alg_test_aead, | |
a1915d51 | 3662 | .fips_allowed = 1, |
da7f033d | 3663 | .suite = { |
a0d608ee | 3664 | .aead = __VECS(aes_gcm_tv_template) |
da7f033d | 3665 | } |
507069c9 YS |
3666 | }, { |
3667 | .alg = "ghash", | |
3668 | .test = alg_test_hash, | |
18c0ebd2 | 3669 | .fips_allowed = 1, |
507069c9 | 3670 | .suite = { |
21c8e720 | 3671 | .hash = __VECS(ghash_tv_template) |
507069c9 | 3672 | } |
da7f033d HX |
3673 | }, { |
3674 | .alg = "hmac(md5)", | |
3675 | .test = alg_test_hash, | |
3676 | .suite = { | |
21c8e720 | 3677 | .hash = __VECS(hmac_md5_tv_template) |
da7f033d HX |
3678 | } |
3679 | }, { | |
3680 | .alg = "hmac(rmd128)", | |
3681 | .test = alg_test_hash, | |
3682 | .suite = { | |
21c8e720 | 3683 | .hash = __VECS(hmac_rmd128_tv_template) |
da7f033d HX |
3684 | } |
3685 | }, { | |
3686 | .alg = "hmac(rmd160)", | |
3687 | .test = alg_test_hash, | |
3688 | .suite = { | |
21c8e720 | 3689 | .hash = __VECS(hmac_rmd160_tv_template) |
da7f033d HX |
3690 | } |
3691 | }, { | |
3692 | .alg = "hmac(sha1)", | |
3693 | .test = alg_test_hash, | |
a1915d51 | 3694 | .fips_allowed = 1, |
da7f033d | 3695 | .suite = { |
21c8e720 | 3696 | .hash = __VECS(hmac_sha1_tv_template) |
da7f033d HX |
3697 | } |
3698 | }, { | |
3699 | .alg = "hmac(sha224)", | |
3700 | .test = alg_test_hash, | |
a1915d51 | 3701 | .fips_allowed = 1, |
da7f033d | 3702 | .suite = { |
21c8e720 | 3703 | .hash = __VECS(hmac_sha224_tv_template) |
da7f033d HX |
3704 | } |
3705 | }, { | |
3706 | .alg = "hmac(sha256)", | |
3707 | .test = alg_test_hash, | |
a1915d51 | 3708 | .fips_allowed = 1, |
da7f033d | 3709 | .suite = { |
21c8e720 | 3710 | .hash = __VECS(hmac_sha256_tv_template) |
da7f033d | 3711 | } |
98eca72f | 3712 | }, { |
3713 | .alg = "hmac(sha3-224)", | |
3714 | .test = alg_test_hash, | |
3715 | .fips_allowed = 1, | |
3716 | .suite = { | |
21c8e720 | 3717 | .hash = __VECS(hmac_sha3_224_tv_template) |
98eca72f | 3718 | } |
3719 | }, { | |
3720 | .alg = "hmac(sha3-256)", | |
3721 | .test = alg_test_hash, | |
3722 | .fips_allowed = 1, | |
3723 | .suite = { | |
21c8e720 | 3724 | .hash = __VECS(hmac_sha3_256_tv_template) |
98eca72f | 3725 | } |
3726 | }, { | |
3727 | .alg = "hmac(sha3-384)", | |
3728 | .test = alg_test_hash, | |
3729 | .fips_allowed = 1, | |
3730 | .suite = { | |
21c8e720 | 3731 | .hash = __VECS(hmac_sha3_384_tv_template) |
98eca72f | 3732 | } |
3733 | }, { | |
3734 | .alg = "hmac(sha3-512)", | |
3735 | .test = alg_test_hash, | |
3736 | .fips_allowed = 1, | |
3737 | .suite = { | |
21c8e720 | 3738 | .hash = __VECS(hmac_sha3_512_tv_template) |
98eca72f | 3739 | } |
da7f033d HX |
3740 | }, { |
3741 | .alg = "hmac(sha384)", | |
3742 | .test = alg_test_hash, | |
a1915d51 | 3743 | .fips_allowed = 1, |
da7f033d | 3744 | .suite = { |
21c8e720 | 3745 | .hash = __VECS(hmac_sha384_tv_template) |
da7f033d HX |
3746 | } |
3747 | }, { | |
3748 | .alg = "hmac(sha512)", | |
3749 | .test = alg_test_hash, | |
a1915d51 | 3750 | .fips_allowed = 1, |
da7f033d | 3751 | .suite = { |
21c8e720 | 3752 | .hash = __VECS(hmac_sha512_tv_template) |
da7f033d | 3753 | } |
25a0b9d4 VC |
3754 | }, { |
3755 | .alg = "hmac(streebog256)", | |
3756 | .test = alg_test_hash, | |
3757 | .suite = { | |
3758 | .hash = __VECS(hmac_streebog256_tv_template) | |
3759 | } | |
3760 | }, { | |
3761 | .alg = "hmac(streebog512)", | |
3762 | .test = alg_test_hash, | |
3763 | .suite = { | |
3764 | .hash = __VECS(hmac_streebog512_tv_template) | |
3765 | } | |
bb5530e4 SM |
3766 | }, { |
3767 | .alg = "jitterentropy_rng", | |
3768 | .fips_allowed = 1, | |
3769 | .test = alg_test_null, | |
35351988 SM |
3770 | }, { |
3771 | .alg = "kw(aes)", | |
3772 | .test = alg_test_skcipher, | |
3773 | .fips_allowed = 1, | |
3774 | .suite = { | |
92a4c9fe | 3775 | .cipher = __VECS(aes_kw_tv_template) |
35351988 | 3776 | } |
da7f033d HX |
3777 | }, { |
3778 | .alg = "lrw(aes)", | |
1aa4ecd9 | 3779 | .test = alg_test_skcipher, |
da7f033d | 3780 | .suite = { |
92a4c9fe | 3781 | .cipher = __VECS(aes_lrw_tv_template) |
da7f033d | 3782 | } |
0840605e JK |
3783 | }, { |
3784 | .alg = "lrw(camellia)", | |
3785 | .test = alg_test_skcipher, | |
3786 | .suite = { | |
92a4c9fe | 3787 | .cipher = __VECS(camellia_lrw_tv_template) |
0840605e | 3788 | } |
9b8b0405 JG |
3789 | }, { |
3790 | .alg = "lrw(cast6)", | |
3791 | .test = alg_test_skcipher, | |
3792 | .suite = { | |
92a4c9fe | 3793 | .cipher = __VECS(cast6_lrw_tv_template) |
9b8b0405 | 3794 | } |
d7bfc0fa JK |
3795 | }, { |
3796 | .alg = "lrw(serpent)", | |
3797 | .test = alg_test_skcipher, | |
3798 | .suite = { | |
92a4c9fe | 3799 | .cipher = __VECS(serpent_lrw_tv_template) |
d7bfc0fa | 3800 | } |
0b2a1551 JK |
3801 | }, { |
3802 | .alg = "lrw(twofish)", | |
3803 | .test = alg_test_skcipher, | |
3804 | .suite = { | |
92a4c9fe | 3805 | .cipher = __VECS(tf_lrw_tv_template) |
0b2a1551 | 3806 | } |
1443cc9b KK |
3807 | }, { |
3808 | .alg = "lz4", | |
3809 | .test = alg_test_comp, | |
3810 | .fips_allowed = 1, | |
3811 | .suite = { | |
3812 | .comp = { | |
21c8e720 AB |
3813 | .comp = __VECS(lz4_comp_tv_template), |
3814 | .decomp = __VECS(lz4_decomp_tv_template) | |
1443cc9b KK |
3815 | } |
3816 | } | |
3817 | }, { | |
3818 | .alg = "lz4hc", | |
3819 | .test = alg_test_comp, | |
3820 | .fips_allowed = 1, | |
3821 | .suite = { | |
3822 | .comp = { | |
21c8e720 AB |
3823 | .comp = __VECS(lz4hc_comp_tv_template), |
3824 | .decomp = __VECS(lz4hc_decomp_tv_template) | |
1443cc9b KK |
3825 | } |
3826 | } | |
da7f033d HX |
3827 | }, { |
3828 | .alg = "lzo", | |
3829 | .test = alg_test_comp, | |
0818904d | 3830 | .fips_allowed = 1, |
da7f033d HX |
3831 | .suite = { |
3832 | .comp = { | |
21c8e720 AB |
3833 | .comp = __VECS(lzo_comp_tv_template), |
3834 | .decomp = __VECS(lzo_decomp_tv_template) | |
da7f033d HX |
3835 | } |
3836 | } | |
3837 | }, { | |
3838 | .alg = "md4", | |
3839 | .test = alg_test_hash, | |
3840 | .suite = { | |
21c8e720 | 3841 | .hash = __VECS(md4_tv_template) |
da7f033d HX |
3842 | } |
3843 | }, { | |
3844 | .alg = "md5", | |
3845 | .test = alg_test_hash, | |
3846 | .suite = { | |
21c8e720 | 3847 | .hash = __VECS(md5_tv_template) |
da7f033d HX |
3848 | } |
3849 | }, { | |
3850 | .alg = "michael_mic", | |
3851 | .test = alg_test_hash, | |
3852 | .suite = { | |
21c8e720 | 3853 | .hash = __VECS(michael_mic_tv_template) |
da7f033d | 3854 | } |
4feb4c59 OM |
3855 | }, { |
3856 | .alg = "morus1280", | |
3857 | .test = alg_test_aead, | |
3858 | .suite = { | |
a0d608ee | 3859 | .aead = __VECS(morus1280_tv_template) |
4feb4c59 OM |
3860 | } |
3861 | }, { | |
3862 | .alg = "morus640", | |
3863 | .test = alg_test_aead, | |
3864 | .suite = { | |
a0d608ee | 3865 | .aead = __VECS(morus640_tv_template) |
4feb4c59 | 3866 | } |
26609a21 EB |
3867 | }, { |
3868 | .alg = "nhpoly1305", | |
3869 | .test = alg_test_hash, | |
3870 | .suite = { | |
3871 | .hash = __VECS(nhpoly1305_tv_template) | |
3872 | } | |
ba0e14ac PS |
3873 | }, { |
3874 | .alg = "ofb(aes)", | |
3875 | .test = alg_test_skcipher, | |
3876 | .fips_allowed = 1, | |
3877 | .suite = { | |
92a4c9fe | 3878 | .cipher = __VECS(aes_ofb_tv_template) |
ba0e14ac | 3879 | } |
a794d8d8 GBY |
3880 | }, { |
3881 | /* Same as ofb(aes) except the key is stored in | |
3882 | * hardware secure memory which we reference by index | |
3883 | */ | |
3884 | .alg = "ofb(paes)", | |
3885 | .test = alg_test_null, | |
3886 | .fips_allowed = 1, | |
da7f033d HX |
3887 | }, { |
3888 | .alg = "pcbc(fcrypt)", | |
1aa4ecd9 | 3889 | .test = alg_test_skcipher, |
da7f033d | 3890 | .suite = { |
92a4c9fe | 3891 | .cipher = __VECS(fcrypt_pcbc_tv_template) |
da7f033d | 3892 | } |
1207107c SM |
3893 | }, { |
3894 | .alg = "pkcs1pad(rsa,sha224)", | |
3895 | .test = alg_test_null, | |
3896 | .fips_allowed = 1, | |
3897 | }, { | |
3898 | .alg = "pkcs1pad(rsa,sha256)", | |
3899 | .test = alg_test_akcipher, | |
3900 | .fips_allowed = 1, | |
3901 | .suite = { | |
3902 | .akcipher = __VECS(pkcs1pad_rsa_tv_template) | |
3903 | } | |
3904 | }, { | |
3905 | .alg = "pkcs1pad(rsa,sha384)", | |
3906 | .test = alg_test_null, | |
3907 | .fips_allowed = 1, | |
3908 | }, { | |
3909 | .alg = "pkcs1pad(rsa,sha512)", | |
3910 | .test = alg_test_null, | |
3911 | .fips_allowed = 1, | |
eee9dc61 MW |
3912 | }, { |
3913 | .alg = "poly1305", | |
3914 | .test = alg_test_hash, | |
3915 | .suite = { | |
21c8e720 | 3916 | .hash = __VECS(poly1305_tv_template) |
eee9dc61 | 3917 | } |
da7f033d HX |
3918 | }, { |
3919 | .alg = "rfc3686(ctr(aes))", | |
1aa4ecd9 | 3920 | .test = alg_test_skcipher, |
a1915d51 | 3921 | .fips_allowed = 1, |
da7f033d | 3922 | .suite = { |
92a4c9fe | 3923 | .cipher = __VECS(aes_ctr_rfc3686_tv_template) |
da7f033d | 3924 | } |
5d667322 | 3925 | }, { |
3f31a740 | 3926 | .alg = "rfc4106(gcm(aes))", |
69435b94 | 3927 | .test = alg_test_aead, |
db71f29a | 3928 | .fips_allowed = 1, |
69435b94 | 3929 | .suite = { |
a0d608ee | 3930 | .aead = __VECS(aes_gcm_rfc4106_tv_template) |
69435b94 AH |
3931 | } |
3932 | }, { | |
544c436a | 3933 | .alg = "rfc4309(ccm(aes))", |
5d667322 | 3934 | .test = alg_test_aead, |
a1915d51 | 3935 | .fips_allowed = 1, |
5d667322 | 3936 | .suite = { |
a0d608ee | 3937 | .aead = __VECS(aes_ccm_rfc4309_tv_template) |
5d667322 | 3938 | } |
e9b7441a | 3939 | }, { |
bb68745e | 3940 | .alg = "rfc4543(gcm(aes))", |
e9b7441a JK |
3941 | .test = alg_test_aead, |
3942 | .suite = { | |
a0d608ee | 3943 | .aead = __VECS(aes_gcm_rfc4543_tv_template) |
e9b7441a | 3944 | } |
af2b76b5 MW |
3945 | }, { |
3946 | .alg = "rfc7539(chacha20,poly1305)", | |
3947 | .test = alg_test_aead, | |
3948 | .suite = { | |
a0d608ee | 3949 | .aead = __VECS(rfc7539_tv_template) |
af2b76b5 | 3950 | } |
5900758d MW |
3951 | }, { |
3952 | .alg = "rfc7539esp(chacha20,poly1305)", | |
3953 | .test = alg_test_aead, | |
3954 | .suite = { | |
a0d608ee | 3955 | .aead = __VECS(rfc7539esp_tv_template) |
5900758d | 3956 | } |
da7f033d HX |
3957 | }, { |
3958 | .alg = "rmd128", | |
3959 | .test = alg_test_hash, | |
3960 | .suite = { | |
21c8e720 | 3961 | .hash = __VECS(rmd128_tv_template) |
da7f033d HX |
3962 | } |
3963 | }, { | |
3964 | .alg = "rmd160", | |
3965 | .test = alg_test_hash, | |
3966 | .suite = { | |
21c8e720 | 3967 | .hash = __VECS(rmd160_tv_template) |
da7f033d HX |
3968 | } |
3969 | }, { | |
3970 | .alg = "rmd256", | |
3971 | .test = alg_test_hash, | |
3972 | .suite = { | |
21c8e720 | 3973 | .hash = __VECS(rmd256_tv_template) |
da7f033d HX |
3974 | } |
3975 | }, { | |
3976 | .alg = "rmd320", | |
3977 | .test = alg_test_hash, | |
3978 | .suite = { | |
21c8e720 | 3979 | .hash = __VECS(rmd320_tv_template) |
da7f033d | 3980 | } |
946cc463 TS |
3981 | }, { |
3982 | .alg = "rsa", | |
3983 | .test = alg_test_akcipher, | |
3984 | .fips_allowed = 1, | |
3985 | .suite = { | |
21c8e720 | 3986 | .akcipher = __VECS(rsa_tv_template) |
946cc463 | 3987 | } |
da7f033d HX |
3988 | }, { |
3989 | .alg = "salsa20", | |
1aa4ecd9 | 3990 | .test = alg_test_skcipher, |
da7f033d | 3991 | .suite = { |
92a4c9fe | 3992 | .cipher = __VECS(salsa20_stream_tv_template) |
da7f033d HX |
3993 | } |
3994 | }, { | |
3995 | .alg = "sha1", | |
3996 | .test = alg_test_hash, | |
a1915d51 | 3997 | .fips_allowed = 1, |
da7f033d | 3998 | .suite = { |
21c8e720 | 3999 | .hash = __VECS(sha1_tv_template) |
da7f033d HX |
4000 | } |
4001 | }, { | |
4002 | .alg = "sha224", | |
4003 | .test = alg_test_hash, | |
a1915d51 | 4004 | .fips_allowed = 1, |
da7f033d | 4005 | .suite = { |
21c8e720 | 4006 | .hash = __VECS(sha224_tv_template) |
da7f033d HX |
4007 | } |
4008 | }, { | |
4009 | .alg = "sha256", | |
4010 | .test = alg_test_hash, | |
a1915d51 | 4011 | .fips_allowed = 1, |
da7f033d | 4012 | .suite = { |
21c8e720 | 4013 | .hash = __VECS(sha256_tv_template) |
da7f033d | 4014 | } |
79cc6ab8 | 4015 | }, { |
4016 | .alg = "sha3-224", | |
4017 | .test = alg_test_hash, | |
4018 | .fips_allowed = 1, | |
4019 | .suite = { | |
21c8e720 | 4020 | .hash = __VECS(sha3_224_tv_template) |
79cc6ab8 | 4021 | } |
4022 | }, { | |
4023 | .alg = "sha3-256", | |
4024 | .test = alg_test_hash, | |
4025 | .fips_allowed = 1, | |
4026 | .suite = { | |
21c8e720 | 4027 | .hash = __VECS(sha3_256_tv_template) |
79cc6ab8 | 4028 | } |
4029 | }, { | |
4030 | .alg = "sha3-384", | |
4031 | .test = alg_test_hash, | |
4032 | .fips_allowed = 1, | |
4033 | .suite = { | |
21c8e720 | 4034 | .hash = __VECS(sha3_384_tv_template) |
79cc6ab8 | 4035 | } |
4036 | }, { | |
4037 | .alg = "sha3-512", | |
4038 | .test = alg_test_hash, | |
4039 | .fips_allowed = 1, | |
4040 | .suite = { | |
21c8e720 | 4041 | .hash = __VECS(sha3_512_tv_template) |
79cc6ab8 | 4042 | } |
da7f033d HX |
4043 | }, { |
4044 | .alg = "sha384", | |
4045 | .test = alg_test_hash, | |
a1915d51 | 4046 | .fips_allowed = 1, |
da7f033d | 4047 | .suite = { |
21c8e720 | 4048 | .hash = __VECS(sha384_tv_template) |
da7f033d HX |
4049 | } |
4050 | }, { | |
4051 | .alg = "sha512", | |
4052 | .test = alg_test_hash, | |
a1915d51 | 4053 | .fips_allowed = 1, |
da7f033d | 4054 | .suite = { |
21c8e720 | 4055 | .hash = __VECS(sha512_tv_template) |
da7f033d | 4056 | } |
b7e27530 GBY |
4057 | }, { |
4058 | .alg = "sm3", | |
4059 | .test = alg_test_hash, | |
4060 | .suite = { | |
4061 | .hash = __VECS(sm3_tv_template) | |
4062 | } | |
25a0b9d4 VC |
4063 | }, { |
4064 | .alg = "streebog256", | |
4065 | .test = alg_test_hash, | |
4066 | .suite = { | |
4067 | .hash = __VECS(streebog256_tv_template) | |
4068 | } | |
4069 | }, { | |
4070 | .alg = "streebog512", | |
4071 | .test = alg_test_hash, | |
4072 | .suite = { | |
4073 | .hash = __VECS(streebog512_tv_template) | |
4074 | } | |
da7f033d HX |
4075 | }, { |
4076 | .alg = "tgr128", | |
4077 | .test = alg_test_hash, | |
4078 | .suite = { | |
21c8e720 | 4079 | .hash = __VECS(tgr128_tv_template) |
da7f033d HX |
4080 | } |
4081 | }, { | |
4082 | .alg = "tgr160", | |
4083 | .test = alg_test_hash, | |
4084 | .suite = { | |
21c8e720 | 4085 | .hash = __VECS(tgr160_tv_template) |
da7f033d HX |
4086 | } |
4087 | }, { | |
4088 | .alg = "tgr192", | |
4089 | .test = alg_test_hash, | |
4090 | .suite = { | |
21c8e720 | 4091 | .hash = __VECS(tgr192_tv_template) |
da7f033d | 4092 | } |
ed331ada EB |
4093 | }, { |
4094 | .alg = "vmac64(aes)", | |
4095 | .test = alg_test_hash, | |
4096 | .suite = { | |
4097 | .hash = __VECS(vmac64_aes_tv_template) | |
4098 | } | |
da7f033d HX |
4099 | }, { |
4100 | .alg = "wp256", | |
4101 | .test = alg_test_hash, | |
4102 | .suite = { | |
21c8e720 | 4103 | .hash = __VECS(wp256_tv_template) |
da7f033d HX |
4104 | } |
4105 | }, { | |
4106 | .alg = "wp384", | |
4107 | .test = alg_test_hash, | |
4108 | .suite = { | |
21c8e720 | 4109 | .hash = __VECS(wp384_tv_template) |
da7f033d HX |
4110 | } |
4111 | }, { | |
4112 | .alg = "wp512", | |
4113 | .test = alg_test_hash, | |
4114 | .suite = { | |
21c8e720 | 4115 | .hash = __VECS(wp512_tv_template) |
da7f033d HX |
4116 | } |
4117 | }, { | |
4118 | .alg = "xcbc(aes)", | |
4119 | .test = alg_test_hash, | |
4120 | .suite = { | |
21c8e720 | 4121 | .hash = __VECS(aes_xcbc128_tv_template) |
da7f033d | 4122 | } |
aa762409 EB |
4123 | }, { |
4124 | .alg = "xchacha12", | |
4125 | .test = alg_test_skcipher, | |
4126 | .suite = { | |
4127 | .cipher = __VECS(xchacha12_tv_template) | |
4128 | }, | |
de61d7ae EB |
4129 | }, { |
4130 | .alg = "xchacha20", | |
4131 | .test = alg_test_skcipher, | |
4132 | .suite = { | |
4133 | .cipher = __VECS(xchacha20_tv_template) | |
4134 | }, | |
da7f033d HX |
4135 | }, { |
4136 | .alg = "xts(aes)", | |
1aa4ecd9 | 4137 | .test = alg_test_skcipher, |
2918aa8d | 4138 | .fips_allowed = 1, |
da7f033d | 4139 | .suite = { |
92a4c9fe | 4140 | .cipher = __VECS(aes_xts_tv_template) |
da7f033d | 4141 | } |
0840605e JK |
4142 | }, { |
4143 | .alg = "xts(camellia)", | |
4144 | .test = alg_test_skcipher, | |
4145 | .suite = { | |
92a4c9fe | 4146 | .cipher = __VECS(camellia_xts_tv_template) |
0840605e | 4147 | } |
9b8b0405 JG |
4148 | }, { |
4149 | .alg = "xts(cast6)", | |
4150 | .test = alg_test_skcipher, | |
4151 | .suite = { | |
92a4c9fe | 4152 | .cipher = __VECS(cast6_xts_tv_template) |
9b8b0405 | 4153 | } |
15f47ce5 GBY |
4154 | }, { |
4155 | /* Same as xts(aes) except the key is stored in | |
4156 | * hardware secure memory which we reference by index | |
4157 | */ | |
4158 | .alg = "xts(paes)", | |
4159 | .test = alg_test_null, | |
4160 | .fips_allowed = 1, | |
18be20b9 JK |
4161 | }, { |
4162 | .alg = "xts(serpent)", | |
4163 | .test = alg_test_skcipher, | |
4164 | .suite = { | |
92a4c9fe | 4165 | .cipher = __VECS(serpent_xts_tv_template) |
18be20b9 | 4166 | } |
aed265b9 JK |
4167 | }, { |
4168 | .alg = "xts(twofish)", | |
4169 | .test = alg_test_skcipher, | |
4170 | .suite = { | |
92a4c9fe | 4171 | .cipher = __VECS(tf_xts_tv_template) |
aed265b9 | 4172 | } |
15f47ce5 GBY |
4173 | }, { |
4174 | .alg = "xts4096(paes)", | |
4175 | .test = alg_test_null, | |
4176 | .fips_allowed = 1, | |
4177 | }, { | |
4178 | .alg = "xts512(paes)", | |
4179 | .test = alg_test_null, | |
4180 | .fips_allowed = 1, | |
a368f43d GC |
4181 | }, { |
4182 | .alg = "zlib-deflate", | |
4183 | .test = alg_test_comp, | |
4184 | .fips_allowed = 1, | |
4185 | .suite = { | |
4186 | .comp = { | |
4187 | .comp = __VECS(zlib_deflate_comp_tv_template), | |
4188 | .decomp = __VECS(zlib_deflate_decomp_tv_template) | |
4189 | } | |
4190 | } | |
d28fc3db NT |
4191 | }, { |
4192 | .alg = "zstd", | |
4193 | .test = alg_test_comp, | |
4194 | .fips_allowed = 1, | |
4195 | .suite = { | |
4196 | .comp = { | |
4197 | .comp = __VECS(zstd_comp_tv_template), | |
4198 | .decomp = __VECS(zstd_decomp_tv_template) | |
4199 | } | |
4200 | } | |
da7f033d HX |
4201 | } |
4202 | }; | |
4203 | ||
3f47a03d | 4204 | static void alg_check_test_descs_order(void) |
5714758b JK |
4205 | { |
4206 | int i; | |
4207 | ||
5714758b JK |
4208 | for (i = 1; i < ARRAY_SIZE(alg_test_descs); i++) { |
4209 | int diff = strcmp(alg_test_descs[i - 1].alg, | |
4210 | alg_test_descs[i].alg); | |
4211 | ||
4212 | if (WARN_ON(diff > 0)) { | |
4213 | pr_warn("testmgr: alg_test_descs entries in wrong order: '%s' before '%s'\n", | |
4214 | alg_test_descs[i - 1].alg, | |
4215 | alg_test_descs[i].alg); | |
4216 | } | |
4217 | ||
4218 | if (WARN_ON(diff == 0)) { | |
4219 | pr_warn("testmgr: duplicate alg_test_descs entry: '%s'\n", | |
4220 | alg_test_descs[i].alg); | |
4221 | } | |
4222 | } | |
4223 | } | |
4224 | ||
3f47a03d EB |
4225 | static void alg_check_testvec_configs(void) |
4226 | { | |
4227 | } | |
4228 | ||
4229 | static void testmgr_onetime_init(void) | |
4230 | { | |
4231 | alg_check_test_descs_order(); | |
4232 | alg_check_testvec_configs(); | |
5b2706a4 EB |
4233 | |
4234 | #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS | |
4235 | pr_warn("alg: extra crypto tests enabled. This is intended for developer use only.\n"); | |
4236 | #endif | |
3f47a03d EB |
4237 | } |
4238 | ||
1aa4ecd9 | 4239 | static int alg_find_test(const char *alg) |
da7f033d HX |
4240 | { |
4241 | int start = 0; | |
4242 | int end = ARRAY_SIZE(alg_test_descs); | |
4243 | ||
4244 | while (start < end) { | |
4245 | int i = (start + end) / 2; | |
4246 | int diff = strcmp(alg_test_descs[i].alg, alg); | |
4247 | ||
4248 | if (diff > 0) { | |
4249 | end = i; | |
4250 | continue; | |
4251 | } | |
4252 | ||
4253 | if (diff < 0) { | |
4254 | start = i + 1; | |
4255 | continue; | |
4256 | } | |
4257 | ||
1aa4ecd9 HX |
4258 | return i; |
4259 | } | |
4260 | ||
4261 | return -1; | |
4262 | } | |
4263 | ||
4264 | int alg_test(const char *driver, const char *alg, u32 type, u32 mask) | |
4265 | { | |
4266 | int i; | |
a68f6610 | 4267 | int j; |
d12d6b6d | 4268 | int rc; |
1aa4ecd9 | 4269 | |
9e5c9fe4 RJ |
4270 | if (!fips_enabled && notests) { |
4271 | printk_once(KERN_INFO "alg: self-tests disabled\n"); | |
4272 | return 0; | |
4273 | } | |
4274 | ||
3f47a03d | 4275 | DO_ONCE(testmgr_onetime_init); |
5714758b | 4276 | |
1aa4ecd9 HX |
4277 | if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) { |
4278 | char nalg[CRYPTO_MAX_ALG_NAME]; | |
4279 | ||
4280 | if (snprintf(nalg, sizeof(nalg), "ecb(%s)", alg) >= | |
4281 | sizeof(nalg)) | |
4282 | return -ENAMETOOLONG; | |
4283 | ||
4284 | i = alg_find_test(nalg); | |
4285 | if (i < 0) | |
4286 | goto notest; | |
4287 | ||
a3bef3a3 JW |
4288 | if (fips_enabled && !alg_test_descs[i].fips_allowed) |
4289 | goto non_fips_alg; | |
4290 | ||
941fb328 JW |
4291 | rc = alg_test_cipher(alg_test_descs + i, driver, type, mask); |
4292 | goto test_done; | |
da7f033d HX |
4293 | } |
4294 | ||
1aa4ecd9 | 4295 | i = alg_find_test(alg); |
a68f6610 HX |
4296 | j = alg_find_test(driver); |
4297 | if (i < 0 && j < 0) | |
1aa4ecd9 HX |
4298 | goto notest; |
4299 | ||
a68f6610 HX |
4300 | if (fips_enabled && ((i >= 0 && !alg_test_descs[i].fips_allowed) || |
4301 | (j >= 0 && !alg_test_descs[j].fips_allowed))) | |
a3bef3a3 JW |
4302 | goto non_fips_alg; |
4303 | ||
a68f6610 HX |
4304 | rc = 0; |
4305 | if (i >= 0) | |
4306 | rc |= alg_test_descs[i].test(alg_test_descs + i, driver, | |
4307 | type, mask); | |
032c8cac | 4308 | if (j >= 0 && j != i) |
a68f6610 HX |
4309 | rc |= alg_test_descs[j].test(alg_test_descs + j, driver, |
4310 | type, mask); | |
4311 | ||
941fb328 | 4312 | test_done: |
d12d6b6d NH |
4313 | if (fips_enabled && rc) |
4314 | panic("%s: %s alg self test failed in fips mode!\n", driver, alg); | |
4315 | ||
29ecd4ab | 4316 | if (fips_enabled && !rc) |
3e8cffd4 | 4317 | pr_info("alg: self-tests for %s (%s) passed\n", driver, alg); |
29ecd4ab | 4318 | |
d12d6b6d | 4319 | return rc; |
1aa4ecd9 HX |
4320 | |
4321 | notest: | |
da7f033d HX |
4322 | printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver); |
4323 | return 0; | |
a3bef3a3 JW |
4324 | non_fips_alg: |
4325 | return -EINVAL; | |
da7f033d | 4326 | } |
0b767f96 | 4327 | |
326a6346 | 4328 | #endif /* CONFIG_CRYPTO_MANAGER_DISABLE_TESTS */ |
0b767f96 | 4329 | |
da7f033d | 4330 | EXPORT_SYMBOL_GPL(alg_test); |