xref: /OK3568_Linux_fs/kernel/crypto/testmgr.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Algorithm testing framework and tests.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
6*4882a593Smuzhiyun  * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
7*4882a593Smuzhiyun  * Copyright (c) 2007 Nokia Siemens Networks
8*4882a593Smuzhiyun  * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
9*4882a593Smuzhiyun  * Copyright (c) 2019 Google LLC
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  * Updated RFC4106 AES-GCM testing.
12*4882a593Smuzhiyun  *    Authors: Aidan O'Mahony (aidan.o.mahony@intel.com)
13*4882a593Smuzhiyun  *             Adrian Hoban <adrian.hoban@intel.com>
14*4882a593Smuzhiyun  *             Gabriele Paoloni <gabriele.paoloni@intel.com>
15*4882a593Smuzhiyun  *             Tadeusz Struk (tadeusz.struk@intel.com)
16*4882a593Smuzhiyun  *    Copyright (c) 2010, Intel Corporation.
17*4882a593Smuzhiyun  */
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #include <crypto/aead.h>
20*4882a593Smuzhiyun #include <crypto/hash.h>
21*4882a593Smuzhiyun #include <crypto/skcipher.h>
22*4882a593Smuzhiyun #include <linux/err.h>
23*4882a593Smuzhiyun #include <linux/fips.h>
24*4882a593Smuzhiyun #include <linux/module.h>
25*4882a593Smuzhiyun #include <linux/once.h>
26*4882a593Smuzhiyun #include <linux/random.h>
27*4882a593Smuzhiyun #include <linux/scatterlist.h>
28*4882a593Smuzhiyun #include <linux/slab.h>
29*4882a593Smuzhiyun #include <linux/string.h>
30*4882a593Smuzhiyun #include <linux/uio.h>
31*4882a593Smuzhiyun #include <crypto/rng.h>
32*4882a593Smuzhiyun #include <crypto/drbg.h>
33*4882a593Smuzhiyun #include <crypto/akcipher.h>
34*4882a593Smuzhiyun #include <crypto/kpp.h>
35*4882a593Smuzhiyun #include <crypto/acompress.h>
36*4882a593Smuzhiyun #include <crypto/internal/cipher.h>
37*4882a593Smuzhiyun #include <crypto/internal/simd.h>
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #include "internal.h"
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun MODULE_IMPORT_NS(CRYPTO_INTERNAL);
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun static bool notests;
44*4882a593Smuzhiyun module_param(notests, bool, 0644);
45*4882a593Smuzhiyun MODULE_PARM_DESC(notests, "disable crypto self-tests");
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun static bool panic_on_fail;
48*4882a593Smuzhiyun module_param(panic_on_fail, bool, 0444);
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
51*4882a593Smuzhiyun static bool noextratests;
52*4882a593Smuzhiyun module_param(noextratests, bool, 0644);
53*4882a593Smuzhiyun MODULE_PARM_DESC(noextratests, "disable expensive crypto self-tests");
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun static unsigned int fuzz_iterations = 100;
56*4882a593Smuzhiyun module_param(fuzz_iterations, uint, 0644);
57*4882a593Smuzhiyun MODULE_PARM_DESC(fuzz_iterations, "number of fuzz test iterations");
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun DEFINE_PER_CPU(bool, crypto_simd_disabled_for_test);
60*4882a593Smuzhiyun EXPORT_PER_CPU_SYMBOL_GPL(crypto_simd_disabled_for_test);
61*4882a593Smuzhiyun #endif
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun #ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun /* a perfect nop */
alg_test(const char * driver,const char * alg,u32 type,u32 mask)66*4882a593Smuzhiyun int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
67*4882a593Smuzhiyun {
68*4882a593Smuzhiyun 	return 0;
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun #else
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun #include "testmgr.h"
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun /*
76*4882a593Smuzhiyun  * Need slab memory for testing (size in number of pages).
77*4882a593Smuzhiyun  */
78*4882a593Smuzhiyun #define XBUFSIZE	8
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun /*
81*4882a593Smuzhiyun * Used by test_cipher()
82*4882a593Smuzhiyun */
83*4882a593Smuzhiyun #define ENCRYPT 1
84*4882a593Smuzhiyun #define DECRYPT 0
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun struct aead_test_suite {
87*4882a593Smuzhiyun 	const struct aead_testvec *vecs;
88*4882a593Smuzhiyun 	unsigned int count;
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	/*
91*4882a593Smuzhiyun 	 * Set if trying to decrypt an inauthentic ciphertext with this
92*4882a593Smuzhiyun 	 * algorithm might result in EINVAL rather than EBADMSG, due to other
93*4882a593Smuzhiyun 	 * validation the algorithm does on the inputs such as length checks.
94*4882a593Smuzhiyun 	 */
95*4882a593Smuzhiyun 	unsigned int einval_allowed : 1;
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun 	/*
98*4882a593Smuzhiyun 	 * Set if this algorithm requires that the IV be located at the end of
99*4882a593Smuzhiyun 	 * the AAD buffer, in addition to being given in the normal way.  The
100*4882a593Smuzhiyun 	 * behavior when the two IV copies differ is implementation-defined.
101*4882a593Smuzhiyun 	 */
102*4882a593Smuzhiyun 	unsigned int aad_iv : 1;
103*4882a593Smuzhiyun };
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun struct cipher_test_suite {
106*4882a593Smuzhiyun 	const struct cipher_testvec *vecs;
107*4882a593Smuzhiyun 	unsigned int count;
108*4882a593Smuzhiyun };
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun struct comp_test_suite {
111*4882a593Smuzhiyun 	struct {
112*4882a593Smuzhiyun 		const struct comp_testvec *vecs;
113*4882a593Smuzhiyun 		unsigned int count;
114*4882a593Smuzhiyun 	} comp, decomp;
115*4882a593Smuzhiyun };
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun struct hash_test_suite {
118*4882a593Smuzhiyun 	const struct hash_testvec *vecs;
119*4882a593Smuzhiyun 	unsigned int count;
120*4882a593Smuzhiyun };
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun struct cprng_test_suite {
123*4882a593Smuzhiyun 	const struct cprng_testvec *vecs;
124*4882a593Smuzhiyun 	unsigned int count;
125*4882a593Smuzhiyun };
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun struct drbg_test_suite {
128*4882a593Smuzhiyun 	const struct drbg_testvec *vecs;
129*4882a593Smuzhiyun 	unsigned int count;
130*4882a593Smuzhiyun };
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun struct akcipher_test_suite {
133*4882a593Smuzhiyun 	const struct akcipher_testvec *vecs;
134*4882a593Smuzhiyun 	unsigned int count;
135*4882a593Smuzhiyun };
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun struct kpp_test_suite {
138*4882a593Smuzhiyun 	const struct kpp_testvec *vecs;
139*4882a593Smuzhiyun 	unsigned int count;
140*4882a593Smuzhiyun };
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun struct alg_test_desc {
143*4882a593Smuzhiyun 	const char *alg;
144*4882a593Smuzhiyun 	const char *generic_driver;
145*4882a593Smuzhiyun 	int (*test)(const struct alg_test_desc *desc, const char *driver,
146*4882a593Smuzhiyun 		    u32 type, u32 mask);
147*4882a593Smuzhiyun 	int fips_allowed;	/* set if alg is allowed in fips mode */
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	union {
150*4882a593Smuzhiyun 		struct aead_test_suite aead;
151*4882a593Smuzhiyun 		struct cipher_test_suite cipher;
152*4882a593Smuzhiyun 		struct comp_test_suite comp;
153*4882a593Smuzhiyun 		struct hash_test_suite hash;
154*4882a593Smuzhiyun 		struct cprng_test_suite cprng;
155*4882a593Smuzhiyun 		struct drbg_test_suite drbg;
156*4882a593Smuzhiyun 		struct akcipher_test_suite akcipher;
157*4882a593Smuzhiyun 		struct kpp_test_suite kpp;
158*4882a593Smuzhiyun 	} suite;
159*4882a593Smuzhiyun };
160*4882a593Smuzhiyun 
hexdump(unsigned char * buf,unsigned int len)161*4882a593Smuzhiyun static void hexdump(unsigned char *buf, unsigned int len)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun 	print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
164*4882a593Smuzhiyun 			16, 1,
165*4882a593Smuzhiyun 			buf, len, false);
166*4882a593Smuzhiyun }
167*4882a593Smuzhiyun 
__testmgr_alloc_buf(char * buf[XBUFSIZE],int order)168*4882a593Smuzhiyun static int __testmgr_alloc_buf(char *buf[XBUFSIZE], int order)
169*4882a593Smuzhiyun {
170*4882a593Smuzhiyun 	int i;
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	for (i = 0; i < XBUFSIZE; i++) {
173*4882a593Smuzhiyun 		buf[i] = (char *)__get_free_pages(GFP_KERNEL, order);
174*4882a593Smuzhiyun 		if (!buf[i])
175*4882a593Smuzhiyun 			goto err_free_buf;
176*4882a593Smuzhiyun 	}
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun 	return 0;
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun err_free_buf:
181*4882a593Smuzhiyun 	while (i-- > 0)
182*4882a593Smuzhiyun 		free_pages((unsigned long)buf[i], order);
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	return -ENOMEM;
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun 
testmgr_alloc_buf(char * buf[XBUFSIZE])187*4882a593Smuzhiyun static int testmgr_alloc_buf(char *buf[XBUFSIZE])
188*4882a593Smuzhiyun {
189*4882a593Smuzhiyun 	return __testmgr_alloc_buf(buf, 0);
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun 
__testmgr_free_buf(char * buf[XBUFSIZE],int order)192*4882a593Smuzhiyun static void __testmgr_free_buf(char *buf[XBUFSIZE], int order)
193*4882a593Smuzhiyun {
194*4882a593Smuzhiyun 	int i;
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 	for (i = 0; i < XBUFSIZE; i++)
197*4882a593Smuzhiyun 		free_pages((unsigned long)buf[i], order);
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun 
testmgr_free_buf(char * buf[XBUFSIZE])200*4882a593Smuzhiyun static void testmgr_free_buf(char *buf[XBUFSIZE])
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun 	__testmgr_free_buf(buf, 0);
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun #define TESTMGR_POISON_BYTE	0xfe
206*4882a593Smuzhiyun #define TESTMGR_POISON_LEN	16
207*4882a593Smuzhiyun 
testmgr_poison(void * addr,size_t len)208*4882a593Smuzhiyun static inline void testmgr_poison(void *addr, size_t len)
209*4882a593Smuzhiyun {
210*4882a593Smuzhiyun 	memset(addr, TESTMGR_POISON_BYTE, len);
211*4882a593Smuzhiyun }
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun /* Is the memory region still fully poisoned? */
testmgr_is_poison(const void * addr,size_t len)214*4882a593Smuzhiyun static inline bool testmgr_is_poison(const void *addr, size_t len)
215*4882a593Smuzhiyun {
216*4882a593Smuzhiyun 	return memchr_inv(addr, TESTMGR_POISON_BYTE, len) == NULL;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun /* flush type for hash algorithms */
220*4882a593Smuzhiyun enum flush_type {
221*4882a593Smuzhiyun 	/* merge with update of previous buffer(s) */
222*4882a593Smuzhiyun 	FLUSH_TYPE_NONE = 0,
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	/* update with previous buffer(s) before doing this one */
225*4882a593Smuzhiyun 	FLUSH_TYPE_FLUSH,
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	/* likewise, but also export and re-import the intermediate state */
228*4882a593Smuzhiyun 	FLUSH_TYPE_REIMPORT,
229*4882a593Smuzhiyun };
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun /* finalization function for hash algorithms */
232*4882a593Smuzhiyun enum finalization_type {
233*4882a593Smuzhiyun 	FINALIZATION_TYPE_FINAL,	/* use final() */
234*4882a593Smuzhiyun 	FINALIZATION_TYPE_FINUP,	/* use finup() */
235*4882a593Smuzhiyun 	FINALIZATION_TYPE_DIGEST,	/* use digest() */
236*4882a593Smuzhiyun };
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun #define TEST_SG_TOTAL	10000
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun /**
241*4882a593Smuzhiyun  * struct test_sg_division - description of a scatterlist entry
242*4882a593Smuzhiyun  *
243*4882a593Smuzhiyun  * This struct describes one entry of a scatterlist being constructed to check a
244*4882a593Smuzhiyun  * crypto test vector.
245*4882a593Smuzhiyun  *
246*4882a593Smuzhiyun  * @proportion_of_total: length of this chunk relative to the total length,
247*4882a593Smuzhiyun  *			 given as a proportion out of TEST_SG_TOTAL so that it
248*4882a593Smuzhiyun  *			 scales to fit any test vector
249*4882a593Smuzhiyun  * @offset: byte offset into a 2-page buffer at which this chunk will start
250*4882a593Smuzhiyun  * @offset_relative_to_alignmask: if true, add the algorithm's alignmask to the
251*4882a593Smuzhiyun  *				  @offset
252*4882a593Smuzhiyun  * @flush_type: for hashes, whether an update() should be done now vs.
253*4882a593Smuzhiyun  *		continuing to accumulate data
254*4882a593Smuzhiyun  * @nosimd: if doing the pending update(), do it with SIMD disabled?
255*4882a593Smuzhiyun  */
256*4882a593Smuzhiyun struct test_sg_division {
257*4882a593Smuzhiyun 	unsigned int proportion_of_total;
258*4882a593Smuzhiyun 	unsigned int offset;
259*4882a593Smuzhiyun 	bool offset_relative_to_alignmask;
260*4882a593Smuzhiyun 	enum flush_type flush_type;
261*4882a593Smuzhiyun 	bool nosimd;
262*4882a593Smuzhiyun };
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun /**
265*4882a593Smuzhiyun  * struct testvec_config - configuration for testing a crypto test vector
266*4882a593Smuzhiyun  *
267*4882a593Smuzhiyun  * This struct describes the data layout and other parameters with which each
268*4882a593Smuzhiyun  * crypto test vector can be tested.
269*4882a593Smuzhiyun  *
270*4882a593Smuzhiyun  * @name: name of this config, logged for debugging purposes if a test fails
271*4882a593Smuzhiyun  * @inplace: operate on the data in-place, if applicable for the algorithm type?
272*4882a593Smuzhiyun  * @req_flags: extra request_flags, e.g. CRYPTO_TFM_REQ_MAY_SLEEP
273*4882a593Smuzhiyun  * @src_divs: description of how to arrange the source scatterlist
274*4882a593Smuzhiyun  * @dst_divs: description of how to arrange the dst scatterlist, if applicable
275*4882a593Smuzhiyun  *	      for the algorithm type.  Defaults to @src_divs if unset.
276*4882a593Smuzhiyun  * @iv_offset: misalignment of the IV in the range [0..MAX_ALGAPI_ALIGNMASK+1],
277*4882a593Smuzhiyun  *	       where 0 is aligned to a 2*(MAX_ALGAPI_ALIGNMASK+1) byte boundary
278*4882a593Smuzhiyun  * @iv_offset_relative_to_alignmask: if true, add the algorithm's alignmask to
279*4882a593Smuzhiyun  *				     the @iv_offset
280*4882a593Smuzhiyun  * @key_offset: misalignment of the key, where 0 is default alignment
281*4882a593Smuzhiyun  * @key_offset_relative_to_alignmask: if true, add the algorithm's alignmask to
282*4882a593Smuzhiyun  *				      the @key_offset
283*4882a593Smuzhiyun  * @finalization_type: what finalization function to use for hashes
284*4882a593Smuzhiyun  * @nosimd: execute with SIMD disabled?  Requires !CRYPTO_TFM_REQ_MAY_SLEEP.
285*4882a593Smuzhiyun  */
286*4882a593Smuzhiyun struct testvec_config {
287*4882a593Smuzhiyun 	const char *name;
288*4882a593Smuzhiyun 	bool inplace;
289*4882a593Smuzhiyun 	u32 req_flags;
290*4882a593Smuzhiyun 	struct test_sg_division src_divs[XBUFSIZE];
291*4882a593Smuzhiyun 	struct test_sg_division dst_divs[XBUFSIZE];
292*4882a593Smuzhiyun 	unsigned int iv_offset;
293*4882a593Smuzhiyun 	unsigned int key_offset;
294*4882a593Smuzhiyun 	bool iv_offset_relative_to_alignmask;
295*4882a593Smuzhiyun 	bool key_offset_relative_to_alignmask;
296*4882a593Smuzhiyun 	enum finalization_type finalization_type;
297*4882a593Smuzhiyun 	bool nosimd;
298*4882a593Smuzhiyun };
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun #define TESTVEC_CONFIG_NAMELEN	192
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun /*
303*4882a593Smuzhiyun  * The following are the lists of testvec_configs to test for each algorithm
304*4882a593Smuzhiyun  * type when the basic crypto self-tests are enabled, i.e. when
305*4882a593Smuzhiyun  * CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is unset.  They aim to provide good test
306*4882a593Smuzhiyun  * coverage, while keeping the test time much shorter than the full fuzz tests
307*4882a593Smuzhiyun  * so that the basic tests can be enabled in a wider range of circumstances.
308*4882a593Smuzhiyun  */
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun /* Configs for skciphers and aeads */
311*4882a593Smuzhiyun static const struct testvec_config default_cipher_testvec_configs[] = {
312*4882a593Smuzhiyun 	{
313*4882a593Smuzhiyun 		.name = "in-place",
314*4882a593Smuzhiyun 		.inplace = true,
315*4882a593Smuzhiyun 		.src_divs = { { .proportion_of_total = 10000 } },
316*4882a593Smuzhiyun 	}, {
317*4882a593Smuzhiyun 		.name = "out-of-place",
318*4882a593Smuzhiyun 		.src_divs = { { .proportion_of_total = 10000 } },
319*4882a593Smuzhiyun 	}, {
320*4882a593Smuzhiyun 		.name = "unaligned buffer, offset=1",
321*4882a593Smuzhiyun 		.src_divs = { { .proportion_of_total = 10000, .offset = 1 } },
322*4882a593Smuzhiyun 		.iv_offset = 1,
323*4882a593Smuzhiyun 		.key_offset = 1,
324*4882a593Smuzhiyun 	}, {
325*4882a593Smuzhiyun 		.name = "buffer aligned only to alignmask",
326*4882a593Smuzhiyun 		.src_divs = {
327*4882a593Smuzhiyun 			{
328*4882a593Smuzhiyun 				.proportion_of_total = 10000,
329*4882a593Smuzhiyun 				.offset = 1,
330*4882a593Smuzhiyun 				.offset_relative_to_alignmask = true,
331*4882a593Smuzhiyun 			},
332*4882a593Smuzhiyun 		},
333*4882a593Smuzhiyun 		.iv_offset = 1,
334*4882a593Smuzhiyun 		.iv_offset_relative_to_alignmask = true,
335*4882a593Smuzhiyun 		.key_offset = 1,
336*4882a593Smuzhiyun 		.key_offset_relative_to_alignmask = true,
337*4882a593Smuzhiyun 	}, {
338*4882a593Smuzhiyun 		.name = "two even aligned splits",
339*4882a593Smuzhiyun 		.src_divs = {
340*4882a593Smuzhiyun 			{ .proportion_of_total = 5000 },
341*4882a593Smuzhiyun 			{ .proportion_of_total = 5000 },
342*4882a593Smuzhiyun 		},
343*4882a593Smuzhiyun 	}, {
344*4882a593Smuzhiyun 		.name = "uneven misaligned splits, may sleep",
345*4882a593Smuzhiyun 		.req_flags = CRYPTO_TFM_REQ_MAY_SLEEP,
346*4882a593Smuzhiyun 		.src_divs = {
347*4882a593Smuzhiyun 			{ .proportion_of_total = 1900, .offset = 33 },
348*4882a593Smuzhiyun 			{ .proportion_of_total = 3300, .offset = 7  },
349*4882a593Smuzhiyun 			{ .proportion_of_total = 4800, .offset = 18 },
350*4882a593Smuzhiyun 		},
351*4882a593Smuzhiyun 		.iv_offset = 3,
352*4882a593Smuzhiyun 		.key_offset = 3,
353*4882a593Smuzhiyun 	}, {
354*4882a593Smuzhiyun 		.name = "misaligned splits crossing pages, inplace",
355*4882a593Smuzhiyun 		.inplace = true,
356*4882a593Smuzhiyun 		.src_divs = {
357*4882a593Smuzhiyun 			{
358*4882a593Smuzhiyun 				.proportion_of_total = 7500,
359*4882a593Smuzhiyun 				.offset = PAGE_SIZE - 32
360*4882a593Smuzhiyun 			}, {
361*4882a593Smuzhiyun 				.proportion_of_total = 2500,
362*4882a593Smuzhiyun 				.offset = PAGE_SIZE - 7
363*4882a593Smuzhiyun 			},
364*4882a593Smuzhiyun 		},
365*4882a593Smuzhiyun 	}
366*4882a593Smuzhiyun };
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun static const struct testvec_config default_hash_testvec_configs[] = {
369*4882a593Smuzhiyun 	{
370*4882a593Smuzhiyun 		.name = "init+update+final aligned buffer",
371*4882a593Smuzhiyun 		.src_divs = { { .proportion_of_total = 10000 } },
372*4882a593Smuzhiyun 		.finalization_type = FINALIZATION_TYPE_FINAL,
373*4882a593Smuzhiyun 	}, {
374*4882a593Smuzhiyun 		.name = "init+finup aligned buffer",
375*4882a593Smuzhiyun 		.src_divs = { { .proportion_of_total = 10000 } },
376*4882a593Smuzhiyun 		.finalization_type = FINALIZATION_TYPE_FINUP,
377*4882a593Smuzhiyun 	}, {
378*4882a593Smuzhiyun 		.name = "digest aligned buffer",
379*4882a593Smuzhiyun 		.src_divs = { { .proportion_of_total = 10000 } },
380*4882a593Smuzhiyun 		.finalization_type = FINALIZATION_TYPE_DIGEST,
381*4882a593Smuzhiyun 	}, {
382*4882a593Smuzhiyun 		.name = "init+update+final misaligned buffer",
383*4882a593Smuzhiyun 		.src_divs = { { .proportion_of_total = 10000, .offset = 1 } },
384*4882a593Smuzhiyun 		.finalization_type = FINALIZATION_TYPE_FINAL,
385*4882a593Smuzhiyun 		.key_offset = 1,
386*4882a593Smuzhiyun 	}, {
387*4882a593Smuzhiyun 		.name = "digest buffer aligned only to alignmask",
388*4882a593Smuzhiyun 		.src_divs = {
389*4882a593Smuzhiyun 			{
390*4882a593Smuzhiyun 				.proportion_of_total = 10000,
391*4882a593Smuzhiyun 				.offset = 1,
392*4882a593Smuzhiyun 				.offset_relative_to_alignmask = true,
393*4882a593Smuzhiyun 			},
394*4882a593Smuzhiyun 		},
395*4882a593Smuzhiyun 		.finalization_type = FINALIZATION_TYPE_DIGEST,
396*4882a593Smuzhiyun 		.key_offset = 1,
397*4882a593Smuzhiyun 		.key_offset_relative_to_alignmask = true,
398*4882a593Smuzhiyun 	}, {
399*4882a593Smuzhiyun 		.name = "init+update+update+final two even splits",
400*4882a593Smuzhiyun 		.src_divs = {
401*4882a593Smuzhiyun 			{ .proportion_of_total = 5000 },
402*4882a593Smuzhiyun 			{
403*4882a593Smuzhiyun 				.proportion_of_total = 5000,
404*4882a593Smuzhiyun 				.flush_type = FLUSH_TYPE_FLUSH,
405*4882a593Smuzhiyun 			},
406*4882a593Smuzhiyun 		},
407*4882a593Smuzhiyun 		.finalization_type = FINALIZATION_TYPE_FINAL,
408*4882a593Smuzhiyun 	}, {
409*4882a593Smuzhiyun 		.name = "digest uneven misaligned splits, may sleep",
410*4882a593Smuzhiyun 		.req_flags = CRYPTO_TFM_REQ_MAY_SLEEP,
411*4882a593Smuzhiyun 		.src_divs = {
412*4882a593Smuzhiyun 			{ .proportion_of_total = 1900, .offset = 33 },
413*4882a593Smuzhiyun 			{ .proportion_of_total = 3300, .offset = 7  },
414*4882a593Smuzhiyun 			{ .proportion_of_total = 4800, .offset = 18 },
415*4882a593Smuzhiyun 		},
416*4882a593Smuzhiyun 		.finalization_type = FINALIZATION_TYPE_DIGEST,
417*4882a593Smuzhiyun 	}, {
418*4882a593Smuzhiyun 		.name = "digest misaligned splits crossing pages",
419*4882a593Smuzhiyun 		.src_divs = {
420*4882a593Smuzhiyun 			{
421*4882a593Smuzhiyun 				.proportion_of_total = 7500,
422*4882a593Smuzhiyun 				.offset = PAGE_SIZE - 32,
423*4882a593Smuzhiyun 			}, {
424*4882a593Smuzhiyun 				.proportion_of_total = 2500,
425*4882a593Smuzhiyun 				.offset = PAGE_SIZE - 7,
426*4882a593Smuzhiyun 			},
427*4882a593Smuzhiyun 		},
428*4882a593Smuzhiyun 		.finalization_type = FINALIZATION_TYPE_DIGEST,
429*4882a593Smuzhiyun 	}, {
430*4882a593Smuzhiyun 		.name = "import/export",
431*4882a593Smuzhiyun 		.src_divs = {
432*4882a593Smuzhiyun 			{
433*4882a593Smuzhiyun 				.proportion_of_total = 6500,
434*4882a593Smuzhiyun 				.flush_type = FLUSH_TYPE_REIMPORT,
435*4882a593Smuzhiyun 			}, {
436*4882a593Smuzhiyun 				.proportion_of_total = 3500,
437*4882a593Smuzhiyun 				.flush_type = FLUSH_TYPE_REIMPORT,
438*4882a593Smuzhiyun 			},
439*4882a593Smuzhiyun 		},
440*4882a593Smuzhiyun 		.finalization_type = FINALIZATION_TYPE_FINAL,
441*4882a593Smuzhiyun 	}
442*4882a593Smuzhiyun };
443*4882a593Smuzhiyun 
count_test_sg_divisions(const struct test_sg_division * divs)444*4882a593Smuzhiyun static unsigned int count_test_sg_divisions(const struct test_sg_division *divs)
445*4882a593Smuzhiyun {
446*4882a593Smuzhiyun 	unsigned int remaining = TEST_SG_TOTAL;
447*4882a593Smuzhiyun 	unsigned int ndivs = 0;
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun 	do {
450*4882a593Smuzhiyun 		remaining -= divs[ndivs++].proportion_of_total;
451*4882a593Smuzhiyun 	} while (remaining);
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun 	return ndivs;
454*4882a593Smuzhiyun }
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun #define SGDIVS_HAVE_FLUSHES	BIT(0)
457*4882a593Smuzhiyun #define SGDIVS_HAVE_NOSIMD	BIT(1)
458*4882a593Smuzhiyun 
valid_sg_divisions(const struct test_sg_division * divs,unsigned int count,int * flags_ret)459*4882a593Smuzhiyun static bool valid_sg_divisions(const struct test_sg_division *divs,
460*4882a593Smuzhiyun 			       unsigned int count, int *flags_ret)
461*4882a593Smuzhiyun {
462*4882a593Smuzhiyun 	unsigned int total = 0;
463*4882a593Smuzhiyun 	unsigned int i;
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun 	for (i = 0; i < count && total != TEST_SG_TOTAL; i++) {
466*4882a593Smuzhiyun 		if (divs[i].proportion_of_total <= 0 ||
467*4882a593Smuzhiyun 		    divs[i].proportion_of_total > TEST_SG_TOTAL - total)
468*4882a593Smuzhiyun 			return false;
469*4882a593Smuzhiyun 		total += divs[i].proportion_of_total;
470*4882a593Smuzhiyun 		if (divs[i].flush_type != FLUSH_TYPE_NONE)
471*4882a593Smuzhiyun 			*flags_ret |= SGDIVS_HAVE_FLUSHES;
472*4882a593Smuzhiyun 		if (divs[i].nosimd)
473*4882a593Smuzhiyun 			*flags_ret |= SGDIVS_HAVE_NOSIMD;
474*4882a593Smuzhiyun 	}
475*4882a593Smuzhiyun 	return total == TEST_SG_TOTAL &&
476*4882a593Smuzhiyun 		memchr_inv(&divs[i], 0, (count - i) * sizeof(divs[0])) == NULL;
477*4882a593Smuzhiyun }
478*4882a593Smuzhiyun 
479*4882a593Smuzhiyun /*
480*4882a593Smuzhiyun  * Check whether the given testvec_config is valid.  This isn't strictly needed
481*4882a593Smuzhiyun  * since every testvec_config should be valid, but check anyway so that people
482*4882a593Smuzhiyun  * don't unknowingly add broken configs that don't do what they wanted.
483*4882a593Smuzhiyun  */
valid_testvec_config(const struct testvec_config * cfg)484*4882a593Smuzhiyun static bool valid_testvec_config(const struct testvec_config *cfg)
485*4882a593Smuzhiyun {
486*4882a593Smuzhiyun 	int flags = 0;
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun 	if (cfg->name == NULL)
489*4882a593Smuzhiyun 		return false;
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun 	if (!valid_sg_divisions(cfg->src_divs, ARRAY_SIZE(cfg->src_divs),
492*4882a593Smuzhiyun 				&flags))
493*4882a593Smuzhiyun 		return false;
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun 	if (cfg->dst_divs[0].proportion_of_total) {
496*4882a593Smuzhiyun 		if (!valid_sg_divisions(cfg->dst_divs,
497*4882a593Smuzhiyun 					ARRAY_SIZE(cfg->dst_divs), &flags))
498*4882a593Smuzhiyun 			return false;
499*4882a593Smuzhiyun 	} else {
500*4882a593Smuzhiyun 		if (memchr_inv(cfg->dst_divs, 0, sizeof(cfg->dst_divs)))
501*4882a593Smuzhiyun 			return false;
502*4882a593Smuzhiyun 		/* defaults to dst_divs=src_divs */
503*4882a593Smuzhiyun 	}
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun 	if (cfg->iv_offset +
506*4882a593Smuzhiyun 	    (cfg->iv_offset_relative_to_alignmask ? MAX_ALGAPI_ALIGNMASK : 0) >
507*4882a593Smuzhiyun 	    MAX_ALGAPI_ALIGNMASK + 1)
508*4882a593Smuzhiyun 		return false;
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun 	if ((flags & (SGDIVS_HAVE_FLUSHES | SGDIVS_HAVE_NOSIMD)) &&
511*4882a593Smuzhiyun 	    cfg->finalization_type == FINALIZATION_TYPE_DIGEST)
512*4882a593Smuzhiyun 		return false;
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun 	if ((cfg->nosimd || (flags & SGDIVS_HAVE_NOSIMD)) &&
515*4882a593Smuzhiyun 	    (cfg->req_flags & CRYPTO_TFM_REQ_MAY_SLEEP))
516*4882a593Smuzhiyun 		return false;
517*4882a593Smuzhiyun 
518*4882a593Smuzhiyun 	return true;
519*4882a593Smuzhiyun }
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun struct test_sglist {
522*4882a593Smuzhiyun 	char *bufs[XBUFSIZE];
523*4882a593Smuzhiyun 	struct scatterlist sgl[XBUFSIZE];
524*4882a593Smuzhiyun 	struct scatterlist sgl_saved[XBUFSIZE];
525*4882a593Smuzhiyun 	struct scatterlist *sgl_ptr;
526*4882a593Smuzhiyun 	unsigned int nents;
527*4882a593Smuzhiyun };
528*4882a593Smuzhiyun 
init_test_sglist(struct test_sglist * tsgl)529*4882a593Smuzhiyun static int init_test_sglist(struct test_sglist *tsgl)
530*4882a593Smuzhiyun {
531*4882a593Smuzhiyun 	return __testmgr_alloc_buf(tsgl->bufs, 1 /* two pages per buffer */);
532*4882a593Smuzhiyun }
533*4882a593Smuzhiyun 
destroy_test_sglist(struct test_sglist * tsgl)534*4882a593Smuzhiyun static void destroy_test_sglist(struct test_sglist *tsgl)
535*4882a593Smuzhiyun {
536*4882a593Smuzhiyun 	return __testmgr_free_buf(tsgl->bufs, 1 /* two pages per buffer */);
537*4882a593Smuzhiyun }
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun /**
540*4882a593Smuzhiyun  * build_test_sglist() - build a scatterlist for a crypto test
541*4882a593Smuzhiyun  *
542*4882a593Smuzhiyun  * @tsgl: the scatterlist to build.  @tsgl->bufs[] contains an array of 2-page
543*4882a593Smuzhiyun  *	  buffers which the scatterlist @tsgl->sgl[] will be made to point into.
544*4882a593Smuzhiyun  * @divs: the layout specification on which the scatterlist will be based
545*4882a593Smuzhiyun  * @alignmask: the algorithm's alignmask
546*4882a593Smuzhiyun  * @total_len: the total length of the scatterlist to build in bytes
547*4882a593Smuzhiyun  * @data: if non-NULL, the buffers will be filled with this data until it ends.
548*4882a593Smuzhiyun  *	  Otherwise the buffers will be poisoned.  In both cases, some bytes
549*4882a593Smuzhiyun  *	  past the end of each buffer will be poisoned to help detect overruns.
550*4882a593Smuzhiyun  * @out_divs: if non-NULL, the test_sg_division to which each scatterlist entry
551*4882a593Smuzhiyun  *	      corresponds will be returned here.  This will match @divs except
552*4882a593Smuzhiyun  *	      that divisions resolving to a length of 0 are omitted as they are
553*4882a593Smuzhiyun  *	      not included in the scatterlist.
554*4882a593Smuzhiyun  *
555*4882a593Smuzhiyun  * Return: 0 or a -errno value
556*4882a593Smuzhiyun  */
build_test_sglist(struct test_sglist * tsgl,const struct test_sg_division * divs,const unsigned int alignmask,const unsigned int total_len,struct iov_iter * data,const struct test_sg_division * out_divs[XBUFSIZE])557*4882a593Smuzhiyun static int build_test_sglist(struct test_sglist *tsgl,
558*4882a593Smuzhiyun 			     const struct test_sg_division *divs,
559*4882a593Smuzhiyun 			     const unsigned int alignmask,
560*4882a593Smuzhiyun 			     const unsigned int total_len,
561*4882a593Smuzhiyun 			     struct iov_iter *data,
562*4882a593Smuzhiyun 			     const struct test_sg_division *out_divs[XBUFSIZE])
563*4882a593Smuzhiyun {
564*4882a593Smuzhiyun 	struct {
565*4882a593Smuzhiyun 		const struct test_sg_division *div;
566*4882a593Smuzhiyun 		size_t length;
567*4882a593Smuzhiyun 	} partitions[XBUFSIZE];
568*4882a593Smuzhiyun 	const unsigned int ndivs = count_test_sg_divisions(divs);
569*4882a593Smuzhiyun 	unsigned int len_remaining = total_len;
570*4882a593Smuzhiyun 	unsigned int i;
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun 	BUILD_BUG_ON(ARRAY_SIZE(partitions) != ARRAY_SIZE(tsgl->sgl));
573*4882a593Smuzhiyun 	if (WARN_ON(ndivs > ARRAY_SIZE(partitions)))
574*4882a593Smuzhiyun 		return -EINVAL;
575*4882a593Smuzhiyun 
576*4882a593Smuzhiyun 	/* Calculate the (div, length) pairs */
577*4882a593Smuzhiyun 	tsgl->nents = 0;
578*4882a593Smuzhiyun 	for (i = 0; i < ndivs; i++) {
579*4882a593Smuzhiyun 		unsigned int len_this_sg =
580*4882a593Smuzhiyun 			min(len_remaining,
581*4882a593Smuzhiyun 			    (total_len * divs[i].proportion_of_total +
582*4882a593Smuzhiyun 			     TEST_SG_TOTAL / 2) / TEST_SG_TOTAL);
583*4882a593Smuzhiyun 
584*4882a593Smuzhiyun 		if (len_this_sg != 0) {
585*4882a593Smuzhiyun 			partitions[tsgl->nents].div = &divs[i];
586*4882a593Smuzhiyun 			partitions[tsgl->nents].length = len_this_sg;
587*4882a593Smuzhiyun 			tsgl->nents++;
588*4882a593Smuzhiyun 			len_remaining -= len_this_sg;
589*4882a593Smuzhiyun 		}
590*4882a593Smuzhiyun 	}
591*4882a593Smuzhiyun 	if (tsgl->nents == 0) {
592*4882a593Smuzhiyun 		partitions[tsgl->nents].div = &divs[0];
593*4882a593Smuzhiyun 		partitions[tsgl->nents].length = 0;
594*4882a593Smuzhiyun 		tsgl->nents++;
595*4882a593Smuzhiyun 	}
596*4882a593Smuzhiyun 	partitions[tsgl->nents - 1].length += len_remaining;
597*4882a593Smuzhiyun 
598*4882a593Smuzhiyun 	/* Set up the sgl entries and fill the data or poison */
599*4882a593Smuzhiyun 	sg_init_table(tsgl->sgl, tsgl->nents);
600*4882a593Smuzhiyun 	for (i = 0; i < tsgl->nents; i++) {
601*4882a593Smuzhiyun 		unsigned int offset = partitions[i].div->offset;
602*4882a593Smuzhiyun 		void *addr;
603*4882a593Smuzhiyun 
604*4882a593Smuzhiyun 		if (partitions[i].div->offset_relative_to_alignmask)
605*4882a593Smuzhiyun 			offset += alignmask;
606*4882a593Smuzhiyun 
607*4882a593Smuzhiyun 		while (offset + partitions[i].length + TESTMGR_POISON_LEN >
608*4882a593Smuzhiyun 		       2 * PAGE_SIZE) {
609*4882a593Smuzhiyun 			if (WARN_ON(offset <= 0))
610*4882a593Smuzhiyun 				return -EINVAL;
611*4882a593Smuzhiyun 			offset /= 2;
612*4882a593Smuzhiyun 		}
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun 		addr = &tsgl->bufs[i][offset];
615*4882a593Smuzhiyun 		sg_set_buf(&tsgl->sgl[i], addr, partitions[i].length);
616*4882a593Smuzhiyun 
617*4882a593Smuzhiyun 		if (out_divs)
618*4882a593Smuzhiyun 			out_divs[i] = partitions[i].div;
619*4882a593Smuzhiyun 
620*4882a593Smuzhiyun 		if (data) {
621*4882a593Smuzhiyun 			size_t copy_len, copied;
622*4882a593Smuzhiyun 
623*4882a593Smuzhiyun 			copy_len = min(partitions[i].length, data->count);
624*4882a593Smuzhiyun 			copied = copy_from_iter(addr, copy_len, data);
625*4882a593Smuzhiyun 			if (WARN_ON(copied != copy_len))
626*4882a593Smuzhiyun 				return -EINVAL;
627*4882a593Smuzhiyun 			testmgr_poison(addr + copy_len, partitions[i].length +
628*4882a593Smuzhiyun 				       TESTMGR_POISON_LEN - copy_len);
629*4882a593Smuzhiyun 		} else {
630*4882a593Smuzhiyun 			testmgr_poison(addr, partitions[i].length +
631*4882a593Smuzhiyun 				       TESTMGR_POISON_LEN);
632*4882a593Smuzhiyun 		}
633*4882a593Smuzhiyun 	}
634*4882a593Smuzhiyun 
635*4882a593Smuzhiyun 	sg_mark_end(&tsgl->sgl[tsgl->nents - 1]);
636*4882a593Smuzhiyun 	tsgl->sgl_ptr = tsgl->sgl;
637*4882a593Smuzhiyun 	memcpy(tsgl->sgl_saved, tsgl->sgl, tsgl->nents * sizeof(tsgl->sgl[0]));
638*4882a593Smuzhiyun 	return 0;
639*4882a593Smuzhiyun }
640*4882a593Smuzhiyun 
641*4882a593Smuzhiyun /*
642*4882a593Smuzhiyun  * Verify that a scatterlist crypto operation produced the correct output.
643*4882a593Smuzhiyun  *
644*4882a593Smuzhiyun  * @tsgl: scatterlist containing the actual output
645*4882a593Smuzhiyun  * @expected_output: buffer containing the expected output
646*4882a593Smuzhiyun  * @len_to_check: length of @expected_output in bytes
647*4882a593Smuzhiyun  * @unchecked_prefix_len: number of ignored bytes in @tsgl prior to real result
648*4882a593Smuzhiyun  * @check_poison: verify that the poison bytes after each chunk are intact?
649*4882a593Smuzhiyun  *
650*4882a593Smuzhiyun  * Return: 0 if correct, -EINVAL if incorrect, -EOVERFLOW if buffer overrun.
651*4882a593Smuzhiyun  */
verify_correct_output(const struct test_sglist * tsgl,const char * expected_output,unsigned int len_to_check,unsigned int unchecked_prefix_len,bool check_poison)652*4882a593Smuzhiyun static int verify_correct_output(const struct test_sglist *tsgl,
653*4882a593Smuzhiyun 				 const char *expected_output,
654*4882a593Smuzhiyun 				 unsigned int len_to_check,
655*4882a593Smuzhiyun 				 unsigned int unchecked_prefix_len,
656*4882a593Smuzhiyun 				 bool check_poison)
657*4882a593Smuzhiyun {
658*4882a593Smuzhiyun 	unsigned int i;
659*4882a593Smuzhiyun 
660*4882a593Smuzhiyun 	for (i = 0; i < tsgl->nents; i++) {
661*4882a593Smuzhiyun 		struct scatterlist *sg = &tsgl->sgl_ptr[i];
662*4882a593Smuzhiyun 		unsigned int len = sg->length;
663*4882a593Smuzhiyun 		unsigned int offset = sg->offset;
664*4882a593Smuzhiyun 		const char *actual_output;
665*4882a593Smuzhiyun 
666*4882a593Smuzhiyun 		if (unchecked_prefix_len) {
667*4882a593Smuzhiyun 			if (unchecked_prefix_len >= len) {
668*4882a593Smuzhiyun 				unchecked_prefix_len -= len;
669*4882a593Smuzhiyun 				continue;
670*4882a593Smuzhiyun 			}
671*4882a593Smuzhiyun 			offset += unchecked_prefix_len;
672*4882a593Smuzhiyun 			len -= unchecked_prefix_len;
673*4882a593Smuzhiyun 			unchecked_prefix_len = 0;
674*4882a593Smuzhiyun 		}
675*4882a593Smuzhiyun 		len = min(len, len_to_check);
676*4882a593Smuzhiyun 		actual_output = page_address(sg_page(sg)) + offset;
677*4882a593Smuzhiyun 		if (memcmp(expected_output, actual_output, len) != 0)
678*4882a593Smuzhiyun 			return -EINVAL;
679*4882a593Smuzhiyun 		if (check_poison &&
680*4882a593Smuzhiyun 		    !testmgr_is_poison(actual_output + len, TESTMGR_POISON_LEN))
681*4882a593Smuzhiyun 			return -EOVERFLOW;
682*4882a593Smuzhiyun 		len_to_check -= len;
683*4882a593Smuzhiyun 		expected_output += len;
684*4882a593Smuzhiyun 	}
685*4882a593Smuzhiyun 	if (WARN_ON(len_to_check != 0))
686*4882a593Smuzhiyun 		return -EINVAL;
687*4882a593Smuzhiyun 	return 0;
688*4882a593Smuzhiyun }
689*4882a593Smuzhiyun 
is_test_sglist_corrupted(const struct test_sglist * tsgl)690*4882a593Smuzhiyun static bool is_test_sglist_corrupted(const struct test_sglist *tsgl)
691*4882a593Smuzhiyun {
692*4882a593Smuzhiyun 	unsigned int i;
693*4882a593Smuzhiyun 
694*4882a593Smuzhiyun 	for (i = 0; i < tsgl->nents; i++) {
695*4882a593Smuzhiyun 		if (tsgl->sgl[i].page_link != tsgl->sgl_saved[i].page_link)
696*4882a593Smuzhiyun 			return true;
697*4882a593Smuzhiyun 		if (tsgl->sgl[i].offset != tsgl->sgl_saved[i].offset)
698*4882a593Smuzhiyun 			return true;
699*4882a593Smuzhiyun 		if (tsgl->sgl[i].length != tsgl->sgl_saved[i].length)
700*4882a593Smuzhiyun 			return true;
701*4882a593Smuzhiyun 	}
702*4882a593Smuzhiyun 	return false;
703*4882a593Smuzhiyun }
704*4882a593Smuzhiyun 
705*4882a593Smuzhiyun struct cipher_test_sglists {
706*4882a593Smuzhiyun 	struct test_sglist src;
707*4882a593Smuzhiyun 	struct test_sglist dst;
708*4882a593Smuzhiyun };
709*4882a593Smuzhiyun 
alloc_cipher_test_sglists(void)710*4882a593Smuzhiyun static struct cipher_test_sglists *alloc_cipher_test_sglists(void)
711*4882a593Smuzhiyun {
712*4882a593Smuzhiyun 	struct cipher_test_sglists *tsgls;
713*4882a593Smuzhiyun 
714*4882a593Smuzhiyun 	tsgls = kmalloc(sizeof(*tsgls), GFP_KERNEL);
715*4882a593Smuzhiyun 	if (!tsgls)
716*4882a593Smuzhiyun 		return NULL;
717*4882a593Smuzhiyun 
718*4882a593Smuzhiyun 	if (init_test_sglist(&tsgls->src) != 0)
719*4882a593Smuzhiyun 		goto fail_kfree;
720*4882a593Smuzhiyun 	if (init_test_sglist(&tsgls->dst) != 0)
721*4882a593Smuzhiyun 		goto fail_destroy_src;
722*4882a593Smuzhiyun 
723*4882a593Smuzhiyun 	return tsgls;
724*4882a593Smuzhiyun 
725*4882a593Smuzhiyun fail_destroy_src:
726*4882a593Smuzhiyun 	destroy_test_sglist(&tsgls->src);
727*4882a593Smuzhiyun fail_kfree:
728*4882a593Smuzhiyun 	kfree(tsgls);
729*4882a593Smuzhiyun 	return NULL;
730*4882a593Smuzhiyun }
731*4882a593Smuzhiyun 
free_cipher_test_sglists(struct cipher_test_sglists * tsgls)732*4882a593Smuzhiyun static void free_cipher_test_sglists(struct cipher_test_sglists *tsgls)
733*4882a593Smuzhiyun {
734*4882a593Smuzhiyun 	if (tsgls) {
735*4882a593Smuzhiyun 		destroy_test_sglist(&tsgls->src);
736*4882a593Smuzhiyun 		destroy_test_sglist(&tsgls->dst);
737*4882a593Smuzhiyun 		kfree(tsgls);
738*4882a593Smuzhiyun 	}
739*4882a593Smuzhiyun }
740*4882a593Smuzhiyun 
741*4882a593Smuzhiyun /* Build the src and dst scatterlists for an skcipher or AEAD test */
build_cipher_test_sglists(struct cipher_test_sglists * tsgls,const struct testvec_config * cfg,unsigned int alignmask,unsigned int src_total_len,unsigned int dst_total_len,const struct kvec * inputs,unsigned int nr_inputs)742*4882a593Smuzhiyun static int build_cipher_test_sglists(struct cipher_test_sglists *tsgls,
743*4882a593Smuzhiyun 				     const struct testvec_config *cfg,
744*4882a593Smuzhiyun 				     unsigned int alignmask,
745*4882a593Smuzhiyun 				     unsigned int src_total_len,
746*4882a593Smuzhiyun 				     unsigned int dst_total_len,
747*4882a593Smuzhiyun 				     const struct kvec *inputs,
748*4882a593Smuzhiyun 				     unsigned int nr_inputs)
749*4882a593Smuzhiyun {
750*4882a593Smuzhiyun 	struct iov_iter input;
751*4882a593Smuzhiyun 	int err;
752*4882a593Smuzhiyun 
753*4882a593Smuzhiyun 	iov_iter_kvec(&input, WRITE, inputs, nr_inputs, src_total_len);
754*4882a593Smuzhiyun 	err = build_test_sglist(&tsgls->src, cfg->src_divs, alignmask,
755*4882a593Smuzhiyun 				cfg->inplace ?
756*4882a593Smuzhiyun 					max(dst_total_len, src_total_len) :
757*4882a593Smuzhiyun 					src_total_len,
758*4882a593Smuzhiyun 				&input, NULL);
759*4882a593Smuzhiyun 	if (err)
760*4882a593Smuzhiyun 		return err;
761*4882a593Smuzhiyun 
762*4882a593Smuzhiyun 	if (cfg->inplace) {
763*4882a593Smuzhiyun 		tsgls->dst.sgl_ptr = tsgls->src.sgl;
764*4882a593Smuzhiyun 		tsgls->dst.nents = tsgls->src.nents;
765*4882a593Smuzhiyun 		return 0;
766*4882a593Smuzhiyun 	}
767*4882a593Smuzhiyun 	return build_test_sglist(&tsgls->dst,
768*4882a593Smuzhiyun 				 cfg->dst_divs[0].proportion_of_total ?
769*4882a593Smuzhiyun 					cfg->dst_divs : cfg->src_divs,
770*4882a593Smuzhiyun 				 alignmask, dst_total_len, NULL, NULL);
771*4882a593Smuzhiyun }
772*4882a593Smuzhiyun 
773*4882a593Smuzhiyun /*
774*4882a593Smuzhiyun  * Support for testing passing a misaligned key to setkey():
775*4882a593Smuzhiyun  *
776*4882a593Smuzhiyun  * If cfg->key_offset is set, copy the key into a new buffer at that offset,
777*4882a593Smuzhiyun  * optionally adding alignmask.  Else, just use the key directly.
778*4882a593Smuzhiyun  */
prepare_keybuf(const u8 * key,unsigned int ksize,const struct testvec_config * cfg,unsigned int alignmask,const u8 ** keybuf_ret,const u8 ** keyptr_ret)779*4882a593Smuzhiyun static int prepare_keybuf(const u8 *key, unsigned int ksize,
780*4882a593Smuzhiyun 			  const struct testvec_config *cfg,
781*4882a593Smuzhiyun 			  unsigned int alignmask,
782*4882a593Smuzhiyun 			  const u8 **keybuf_ret, const u8 **keyptr_ret)
783*4882a593Smuzhiyun {
784*4882a593Smuzhiyun 	unsigned int key_offset = cfg->key_offset;
785*4882a593Smuzhiyun 	u8 *keybuf = NULL, *keyptr = (u8 *)key;
786*4882a593Smuzhiyun 
787*4882a593Smuzhiyun 	if (key_offset != 0) {
788*4882a593Smuzhiyun 		if (cfg->key_offset_relative_to_alignmask)
789*4882a593Smuzhiyun 			key_offset += alignmask;
790*4882a593Smuzhiyun 		keybuf = kmalloc(key_offset + ksize, GFP_KERNEL);
791*4882a593Smuzhiyun 		if (!keybuf)
792*4882a593Smuzhiyun 			return -ENOMEM;
793*4882a593Smuzhiyun 		keyptr = keybuf + key_offset;
794*4882a593Smuzhiyun 		memcpy(keyptr, key, ksize);
795*4882a593Smuzhiyun 	}
796*4882a593Smuzhiyun 	*keybuf_ret = keybuf;
797*4882a593Smuzhiyun 	*keyptr_ret = keyptr;
798*4882a593Smuzhiyun 	return 0;
799*4882a593Smuzhiyun }
800*4882a593Smuzhiyun 
801*4882a593Smuzhiyun /* Like setkey_f(tfm, key, ksize), but sometimes misalign the key */
802*4882a593Smuzhiyun #define do_setkey(setkey_f, tfm, key, ksize, cfg, alignmask)		\
803*4882a593Smuzhiyun ({									\
804*4882a593Smuzhiyun 	const u8 *keybuf, *keyptr;					\
805*4882a593Smuzhiyun 	int err;							\
806*4882a593Smuzhiyun 									\
807*4882a593Smuzhiyun 	err = prepare_keybuf((key), (ksize), (cfg), (alignmask),	\
808*4882a593Smuzhiyun 			     &keybuf, &keyptr);				\
809*4882a593Smuzhiyun 	if (err == 0) {							\
810*4882a593Smuzhiyun 		err = setkey_f((tfm), keyptr, (ksize));			\
811*4882a593Smuzhiyun 		kfree(keybuf);						\
812*4882a593Smuzhiyun 	}								\
813*4882a593Smuzhiyun 	err;								\
814*4882a593Smuzhiyun })
815*4882a593Smuzhiyun 
816*4882a593Smuzhiyun #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
817*4882a593Smuzhiyun 
818*4882a593Smuzhiyun /* Generate a random length in range [0, max_len], but prefer smaller values */
generate_random_length(unsigned int max_len)819*4882a593Smuzhiyun static unsigned int generate_random_length(unsigned int max_len)
820*4882a593Smuzhiyun {
821*4882a593Smuzhiyun 	unsigned int len = prandom_u32() % (max_len + 1);
822*4882a593Smuzhiyun 
823*4882a593Smuzhiyun 	switch (prandom_u32() % 4) {
824*4882a593Smuzhiyun 	case 0:
825*4882a593Smuzhiyun 		return len % 64;
826*4882a593Smuzhiyun 	case 1:
827*4882a593Smuzhiyun 		return len % 256;
828*4882a593Smuzhiyun 	case 2:
829*4882a593Smuzhiyun 		return len % 1024;
830*4882a593Smuzhiyun 	default:
831*4882a593Smuzhiyun 		return len;
832*4882a593Smuzhiyun 	}
833*4882a593Smuzhiyun }
834*4882a593Smuzhiyun 
835*4882a593Smuzhiyun /* Flip a random bit in the given nonempty data buffer */
flip_random_bit(u8 * buf,size_t size)836*4882a593Smuzhiyun static void flip_random_bit(u8 *buf, size_t size)
837*4882a593Smuzhiyun {
838*4882a593Smuzhiyun 	size_t bitpos;
839*4882a593Smuzhiyun 
840*4882a593Smuzhiyun 	bitpos = prandom_u32() % (size * 8);
841*4882a593Smuzhiyun 	buf[bitpos / 8] ^= 1 << (bitpos % 8);
842*4882a593Smuzhiyun }
843*4882a593Smuzhiyun 
844*4882a593Smuzhiyun /* Flip a random byte in the given nonempty data buffer */
flip_random_byte(u8 * buf,size_t size)845*4882a593Smuzhiyun static void flip_random_byte(u8 *buf, size_t size)
846*4882a593Smuzhiyun {
847*4882a593Smuzhiyun 	buf[prandom_u32() % size] ^= 0xff;
848*4882a593Smuzhiyun }
849*4882a593Smuzhiyun 
850*4882a593Smuzhiyun /* Sometimes make some random changes to the given nonempty data buffer */
mutate_buffer(u8 * buf,size_t size)851*4882a593Smuzhiyun static void mutate_buffer(u8 *buf, size_t size)
852*4882a593Smuzhiyun {
853*4882a593Smuzhiyun 	size_t num_flips;
854*4882a593Smuzhiyun 	size_t i;
855*4882a593Smuzhiyun 
856*4882a593Smuzhiyun 	/* Sometimes flip some bits */
857*4882a593Smuzhiyun 	if (prandom_u32() % 4 == 0) {
858*4882a593Smuzhiyun 		num_flips = min_t(size_t, 1 << (prandom_u32() % 8), size * 8);
859*4882a593Smuzhiyun 		for (i = 0; i < num_flips; i++)
860*4882a593Smuzhiyun 			flip_random_bit(buf, size);
861*4882a593Smuzhiyun 	}
862*4882a593Smuzhiyun 
863*4882a593Smuzhiyun 	/* Sometimes flip some bytes */
864*4882a593Smuzhiyun 	if (prandom_u32() % 4 == 0) {
865*4882a593Smuzhiyun 		num_flips = min_t(size_t, 1 << (prandom_u32() % 8), size);
866*4882a593Smuzhiyun 		for (i = 0; i < num_flips; i++)
867*4882a593Smuzhiyun 			flip_random_byte(buf, size);
868*4882a593Smuzhiyun 	}
869*4882a593Smuzhiyun }
870*4882a593Smuzhiyun 
871*4882a593Smuzhiyun /* Randomly generate 'count' bytes, but sometimes make them "interesting" */
generate_random_bytes(u8 * buf,size_t count)872*4882a593Smuzhiyun static void generate_random_bytes(u8 *buf, size_t count)
873*4882a593Smuzhiyun {
874*4882a593Smuzhiyun 	u8 b;
875*4882a593Smuzhiyun 	u8 increment;
876*4882a593Smuzhiyun 	size_t i;
877*4882a593Smuzhiyun 
878*4882a593Smuzhiyun 	if (count == 0)
879*4882a593Smuzhiyun 		return;
880*4882a593Smuzhiyun 
881*4882a593Smuzhiyun 	switch (prandom_u32() % 8) { /* Choose a generation strategy */
882*4882a593Smuzhiyun 	case 0:
883*4882a593Smuzhiyun 	case 1:
884*4882a593Smuzhiyun 		/* All the same byte, plus optional mutations */
885*4882a593Smuzhiyun 		switch (prandom_u32() % 4) {
886*4882a593Smuzhiyun 		case 0:
887*4882a593Smuzhiyun 			b = 0x00;
888*4882a593Smuzhiyun 			break;
889*4882a593Smuzhiyun 		case 1:
890*4882a593Smuzhiyun 			b = 0xff;
891*4882a593Smuzhiyun 			break;
892*4882a593Smuzhiyun 		default:
893*4882a593Smuzhiyun 			b = (u8)prandom_u32();
894*4882a593Smuzhiyun 			break;
895*4882a593Smuzhiyun 		}
896*4882a593Smuzhiyun 		memset(buf, b, count);
897*4882a593Smuzhiyun 		mutate_buffer(buf, count);
898*4882a593Smuzhiyun 		break;
899*4882a593Smuzhiyun 	case 2:
900*4882a593Smuzhiyun 		/* Ascending or descending bytes, plus optional mutations */
901*4882a593Smuzhiyun 		increment = (u8)prandom_u32();
902*4882a593Smuzhiyun 		b = (u8)prandom_u32();
903*4882a593Smuzhiyun 		for (i = 0; i < count; i++, b += increment)
904*4882a593Smuzhiyun 			buf[i] = b;
905*4882a593Smuzhiyun 		mutate_buffer(buf, count);
906*4882a593Smuzhiyun 		break;
907*4882a593Smuzhiyun 	default:
908*4882a593Smuzhiyun 		/* Fully random bytes */
909*4882a593Smuzhiyun 		for (i = 0; i < count; i++)
910*4882a593Smuzhiyun 			buf[i] = (u8)prandom_u32();
911*4882a593Smuzhiyun 	}
912*4882a593Smuzhiyun }
913*4882a593Smuzhiyun 
generate_random_sgl_divisions(struct test_sg_division * divs,size_t max_divs,char * p,char * end,bool gen_flushes,u32 req_flags)914*4882a593Smuzhiyun static char *generate_random_sgl_divisions(struct test_sg_division *divs,
915*4882a593Smuzhiyun 					   size_t max_divs, char *p, char *end,
916*4882a593Smuzhiyun 					   bool gen_flushes, u32 req_flags)
917*4882a593Smuzhiyun {
918*4882a593Smuzhiyun 	struct test_sg_division *div = divs;
919*4882a593Smuzhiyun 	unsigned int remaining = TEST_SG_TOTAL;
920*4882a593Smuzhiyun 
921*4882a593Smuzhiyun 	do {
922*4882a593Smuzhiyun 		unsigned int this_len;
923*4882a593Smuzhiyun 		const char *flushtype_str;
924*4882a593Smuzhiyun 
925*4882a593Smuzhiyun 		if (div == &divs[max_divs - 1] || prandom_u32() % 2 == 0)
926*4882a593Smuzhiyun 			this_len = remaining;
927*4882a593Smuzhiyun 		else
928*4882a593Smuzhiyun 			this_len = 1 + (prandom_u32() % remaining);
929*4882a593Smuzhiyun 		div->proportion_of_total = this_len;
930*4882a593Smuzhiyun 
931*4882a593Smuzhiyun 		if (prandom_u32() % 4 == 0)
932*4882a593Smuzhiyun 			div->offset = (PAGE_SIZE - 128) + (prandom_u32() % 128);
933*4882a593Smuzhiyun 		else if (prandom_u32() % 2 == 0)
934*4882a593Smuzhiyun 			div->offset = prandom_u32() % 32;
935*4882a593Smuzhiyun 		else
936*4882a593Smuzhiyun 			div->offset = prandom_u32() % PAGE_SIZE;
937*4882a593Smuzhiyun 		if (prandom_u32() % 8 == 0)
938*4882a593Smuzhiyun 			div->offset_relative_to_alignmask = true;
939*4882a593Smuzhiyun 
940*4882a593Smuzhiyun 		div->flush_type = FLUSH_TYPE_NONE;
941*4882a593Smuzhiyun 		if (gen_flushes) {
942*4882a593Smuzhiyun 			switch (prandom_u32() % 4) {
943*4882a593Smuzhiyun 			case 0:
944*4882a593Smuzhiyun 				div->flush_type = FLUSH_TYPE_REIMPORT;
945*4882a593Smuzhiyun 				break;
946*4882a593Smuzhiyun 			case 1:
947*4882a593Smuzhiyun 				div->flush_type = FLUSH_TYPE_FLUSH;
948*4882a593Smuzhiyun 				break;
949*4882a593Smuzhiyun 			}
950*4882a593Smuzhiyun 		}
951*4882a593Smuzhiyun 
952*4882a593Smuzhiyun 		if (div->flush_type != FLUSH_TYPE_NONE &&
953*4882a593Smuzhiyun 		    !(req_flags & CRYPTO_TFM_REQ_MAY_SLEEP) &&
954*4882a593Smuzhiyun 		    prandom_u32() % 2 == 0)
955*4882a593Smuzhiyun 			div->nosimd = true;
956*4882a593Smuzhiyun 
957*4882a593Smuzhiyun 		switch (div->flush_type) {
958*4882a593Smuzhiyun 		case FLUSH_TYPE_FLUSH:
959*4882a593Smuzhiyun 			if (div->nosimd)
960*4882a593Smuzhiyun 				flushtype_str = "<flush,nosimd>";
961*4882a593Smuzhiyun 			else
962*4882a593Smuzhiyun 				flushtype_str = "<flush>";
963*4882a593Smuzhiyun 			break;
964*4882a593Smuzhiyun 		case FLUSH_TYPE_REIMPORT:
965*4882a593Smuzhiyun 			if (div->nosimd)
966*4882a593Smuzhiyun 				flushtype_str = "<reimport,nosimd>";
967*4882a593Smuzhiyun 			else
968*4882a593Smuzhiyun 				flushtype_str = "<reimport>";
969*4882a593Smuzhiyun 			break;
970*4882a593Smuzhiyun 		default:
971*4882a593Smuzhiyun 			flushtype_str = "";
972*4882a593Smuzhiyun 			break;
973*4882a593Smuzhiyun 		}
974*4882a593Smuzhiyun 
975*4882a593Smuzhiyun 		BUILD_BUG_ON(TEST_SG_TOTAL != 10000); /* for "%u.%u%%" */
976*4882a593Smuzhiyun 		p += scnprintf(p, end - p, "%s%u.%u%%@%s+%u%s", flushtype_str,
977*4882a593Smuzhiyun 			       this_len / 100, this_len % 100,
978*4882a593Smuzhiyun 			       div->offset_relative_to_alignmask ?
979*4882a593Smuzhiyun 					"alignmask" : "",
980*4882a593Smuzhiyun 			       div->offset, this_len == remaining ? "" : ", ");
981*4882a593Smuzhiyun 		remaining -= this_len;
982*4882a593Smuzhiyun 		div++;
983*4882a593Smuzhiyun 	} while (remaining);
984*4882a593Smuzhiyun 
985*4882a593Smuzhiyun 	return p;
986*4882a593Smuzhiyun }
987*4882a593Smuzhiyun 
988*4882a593Smuzhiyun /* Generate a random testvec_config for fuzz testing */
generate_random_testvec_config(struct testvec_config * cfg,char * name,size_t max_namelen)989*4882a593Smuzhiyun static void generate_random_testvec_config(struct testvec_config *cfg,
990*4882a593Smuzhiyun 					   char *name, size_t max_namelen)
991*4882a593Smuzhiyun {
992*4882a593Smuzhiyun 	char *p = name;
993*4882a593Smuzhiyun 	char * const end = name + max_namelen;
994*4882a593Smuzhiyun 
995*4882a593Smuzhiyun 	memset(cfg, 0, sizeof(*cfg));
996*4882a593Smuzhiyun 
997*4882a593Smuzhiyun 	cfg->name = name;
998*4882a593Smuzhiyun 
999*4882a593Smuzhiyun 	p += scnprintf(p, end - p, "random:");
1000*4882a593Smuzhiyun 
1001*4882a593Smuzhiyun 	if (prandom_u32() % 2 == 0) {
1002*4882a593Smuzhiyun 		cfg->inplace = true;
1003*4882a593Smuzhiyun 		p += scnprintf(p, end - p, " inplace");
1004*4882a593Smuzhiyun 	}
1005*4882a593Smuzhiyun 
1006*4882a593Smuzhiyun 	if (prandom_u32() % 2 == 0) {
1007*4882a593Smuzhiyun 		cfg->req_flags |= CRYPTO_TFM_REQ_MAY_SLEEP;
1008*4882a593Smuzhiyun 		p += scnprintf(p, end - p, " may_sleep");
1009*4882a593Smuzhiyun 	}
1010*4882a593Smuzhiyun 
1011*4882a593Smuzhiyun 	switch (prandom_u32() % 4) {
1012*4882a593Smuzhiyun 	case 0:
1013*4882a593Smuzhiyun 		cfg->finalization_type = FINALIZATION_TYPE_FINAL;
1014*4882a593Smuzhiyun 		p += scnprintf(p, end - p, " use_final");
1015*4882a593Smuzhiyun 		break;
1016*4882a593Smuzhiyun 	case 1:
1017*4882a593Smuzhiyun 		cfg->finalization_type = FINALIZATION_TYPE_FINUP;
1018*4882a593Smuzhiyun 		p += scnprintf(p, end - p, " use_finup");
1019*4882a593Smuzhiyun 		break;
1020*4882a593Smuzhiyun 	default:
1021*4882a593Smuzhiyun 		cfg->finalization_type = FINALIZATION_TYPE_DIGEST;
1022*4882a593Smuzhiyun 		p += scnprintf(p, end - p, " use_digest");
1023*4882a593Smuzhiyun 		break;
1024*4882a593Smuzhiyun 	}
1025*4882a593Smuzhiyun 
1026*4882a593Smuzhiyun 	if (!(cfg->req_flags & CRYPTO_TFM_REQ_MAY_SLEEP) &&
1027*4882a593Smuzhiyun 	    prandom_u32() % 2 == 0) {
1028*4882a593Smuzhiyun 		cfg->nosimd = true;
1029*4882a593Smuzhiyun 		p += scnprintf(p, end - p, " nosimd");
1030*4882a593Smuzhiyun 	}
1031*4882a593Smuzhiyun 
1032*4882a593Smuzhiyun 	p += scnprintf(p, end - p, " src_divs=[");
1033*4882a593Smuzhiyun 	p = generate_random_sgl_divisions(cfg->src_divs,
1034*4882a593Smuzhiyun 					  ARRAY_SIZE(cfg->src_divs), p, end,
1035*4882a593Smuzhiyun 					  (cfg->finalization_type !=
1036*4882a593Smuzhiyun 					   FINALIZATION_TYPE_DIGEST),
1037*4882a593Smuzhiyun 					  cfg->req_flags);
1038*4882a593Smuzhiyun 	p += scnprintf(p, end - p, "]");
1039*4882a593Smuzhiyun 
1040*4882a593Smuzhiyun 	if (!cfg->inplace && prandom_u32() % 2 == 0) {
1041*4882a593Smuzhiyun 		p += scnprintf(p, end - p, " dst_divs=[");
1042*4882a593Smuzhiyun 		p = generate_random_sgl_divisions(cfg->dst_divs,
1043*4882a593Smuzhiyun 						  ARRAY_SIZE(cfg->dst_divs),
1044*4882a593Smuzhiyun 						  p, end, false,
1045*4882a593Smuzhiyun 						  cfg->req_flags);
1046*4882a593Smuzhiyun 		p += scnprintf(p, end - p, "]");
1047*4882a593Smuzhiyun 	}
1048*4882a593Smuzhiyun 
1049*4882a593Smuzhiyun 	if (prandom_u32() % 2 == 0) {
1050*4882a593Smuzhiyun 		cfg->iv_offset = 1 + (prandom_u32() % MAX_ALGAPI_ALIGNMASK);
1051*4882a593Smuzhiyun 		p += scnprintf(p, end - p, " iv_offset=%u", cfg->iv_offset);
1052*4882a593Smuzhiyun 	}
1053*4882a593Smuzhiyun 
1054*4882a593Smuzhiyun 	if (prandom_u32() % 2 == 0) {
1055*4882a593Smuzhiyun 		cfg->key_offset = 1 + (prandom_u32() % MAX_ALGAPI_ALIGNMASK);
1056*4882a593Smuzhiyun 		p += scnprintf(p, end - p, " key_offset=%u", cfg->key_offset);
1057*4882a593Smuzhiyun 	}
1058*4882a593Smuzhiyun 
1059*4882a593Smuzhiyun 	WARN_ON_ONCE(!valid_testvec_config(cfg));
1060*4882a593Smuzhiyun }
1061*4882a593Smuzhiyun 
crypto_disable_simd_for_test(void)1062*4882a593Smuzhiyun static void crypto_disable_simd_for_test(void)
1063*4882a593Smuzhiyun {
1064*4882a593Smuzhiyun 	preempt_disable();
1065*4882a593Smuzhiyun 	__this_cpu_write(crypto_simd_disabled_for_test, true);
1066*4882a593Smuzhiyun }
1067*4882a593Smuzhiyun 
crypto_reenable_simd_for_test(void)1068*4882a593Smuzhiyun static void crypto_reenable_simd_for_test(void)
1069*4882a593Smuzhiyun {
1070*4882a593Smuzhiyun 	__this_cpu_write(crypto_simd_disabled_for_test, false);
1071*4882a593Smuzhiyun 	preempt_enable();
1072*4882a593Smuzhiyun }
1073*4882a593Smuzhiyun 
1074*4882a593Smuzhiyun /*
1075*4882a593Smuzhiyun  * Given an algorithm name, build the name of the generic implementation of that
1076*4882a593Smuzhiyun  * algorithm, assuming the usual naming convention.  Specifically, this appends
1077*4882a593Smuzhiyun  * "-generic" to every part of the name that is not a template name.  Examples:
1078*4882a593Smuzhiyun  *
1079*4882a593Smuzhiyun  *	aes => aes-generic
1080*4882a593Smuzhiyun  *	cbc(aes) => cbc(aes-generic)
1081*4882a593Smuzhiyun  *	cts(cbc(aes)) => cts(cbc(aes-generic))
1082*4882a593Smuzhiyun  *	rfc7539(chacha20,poly1305) => rfc7539(chacha20-generic,poly1305-generic)
1083*4882a593Smuzhiyun  *
1084*4882a593Smuzhiyun  * Return: 0 on success, or -ENAMETOOLONG if the generic name would be too long
1085*4882a593Smuzhiyun  */
build_generic_driver_name(const char * algname,char driver_name[CRYPTO_MAX_ALG_NAME])1086*4882a593Smuzhiyun static int build_generic_driver_name(const char *algname,
1087*4882a593Smuzhiyun 				     char driver_name[CRYPTO_MAX_ALG_NAME])
1088*4882a593Smuzhiyun {
1089*4882a593Smuzhiyun 	const char *in = algname;
1090*4882a593Smuzhiyun 	char *out = driver_name;
1091*4882a593Smuzhiyun 	size_t len = strlen(algname);
1092*4882a593Smuzhiyun 
1093*4882a593Smuzhiyun 	if (len >= CRYPTO_MAX_ALG_NAME)
1094*4882a593Smuzhiyun 		goto too_long;
1095*4882a593Smuzhiyun 	do {
1096*4882a593Smuzhiyun 		const char *in_saved = in;
1097*4882a593Smuzhiyun 
1098*4882a593Smuzhiyun 		while (*in && *in != '(' && *in != ')' && *in != ',')
1099*4882a593Smuzhiyun 			*out++ = *in++;
1100*4882a593Smuzhiyun 		if (*in != '(' && in > in_saved) {
1101*4882a593Smuzhiyun 			len += 8;
1102*4882a593Smuzhiyun 			if (len >= CRYPTO_MAX_ALG_NAME)
1103*4882a593Smuzhiyun 				goto too_long;
1104*4882a593Smuzhiyun 			memcpy(out, "-generic", 8);
1105*4882a593Smuzhiyun 			out += 8;
1106*4882a593Smuzhiyun 		}
1107*4882a593Smuzhiyun 	} while ((*out++ = *in++) != '\0');
1108*4882a593Smuzhiyun 	return 0;
1109*4882a593Smuzhiyun 
1110*4882a593Smuzhiyun too_long:
1111*4882a593Smuzhiyun 	pr_err("alg: generic driver name for \"%s\" would be too long\n",
1112*4882a593Smuzhiyun 	       algname);
1113*4882a593Smuzhiyun 	return -ENAMETOOLONG;
1114*4882a593Smuzhiyun }
1115*4882a593Smuzhiyun #else /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
crypto_disable_simd_for_test(void)1116*4882a593Smuzhiyun static void crypto_disable_simd_for_test(void)
1117*4882a593Smuzhiyun {
1118*4882a593Smuzhiyun }
1119*4882a593Smuzhiyun 
crypto_reenable_simd_for_test(void)1120*4882a593Smuzhiyun static void crypto_reenable_simd_for_test(void)
1121*4882a593Smuzhiyun {
1122*4882a593Smuzhiyun }
1123*4882a593Smuzhiyun #endif /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
1124*4882a593Smuzhiyun 
build_hash_sglist(struct test_sglist * tsgl,const struct hash_testvec * vec,const struct testvec_config * cfg,unsigned int alignmask,const struct test_sg_division * divs[XBUFSIZE])1125*4882a593Smuzhiyun static int build_hash_sglist(struct test_sglist *tsgl,
1126*4882a593Smuzhiyun 			     const struct hash_testvec *vec,
1127*4882a593Smuzhiyun 			     const struct testvec_config *cfg,
1128*4882a593Smuzhiyun 			     unsigned int alignmask,
1129*4882a593Smuzhiyun 			     const struct test_sg_division *divs[XBUFSIZE])
1130*4882a593Smuzhiyun {
1131*4882a593Smuzhiyun 	struct kvec kv;
1132*4882a593Smuzhiyun 	struct iov_iter input;
1133*4882a593Smuzhiyun 
1134*4882a593Smuzhiyun 	kv.iov_base = (void *)vec->plaintext;
1135*4882a593Smuzhiyun 	kv.iov_len = vec->psize;
1136*4882a593Smuzhiyun 	iov_iter_kvec(&input, WRITE, &kv, 1, vec->psize);
1137*4882a593Smuzhiyun 	return build_test_sglist(tsgl, cfg->src_divs, alignmask, vec->psize,
1138*4882a593Smuzhiyun 				 &input, divs);
1139*4882a593Smuzhiyun }
1140*4882a593Smuzhiyun 
check_hash_result(const char * type,const u8 * result,unsigned int digestsize,const struct hash_testvec * vec,const char * vec_name,const char * driver,const struct testvec_config * cfg)1141*4882a593Smuzhiyun static int check_hash_result(const char *type,
1142*4882a593Smuzhiyun 			     const u8 *result, unsigned int digestsize,
1143*4882a593Smuzhiyun 			     const struct hash_testvec *vec,
1144*4882a593Smuzhiyun 			     const char *vec_name,
1145*4882a593Smuzhiyun 			     const char *driver,
1146*4882a593Smuzhiyun 			     const struct testvec_config *cfg)
1147*4882a593Smuzhiyun {
1148*4882a593Smuzhiyun 	if (memcmp(result, vec->digest, digestsize) != 0) {
1149*4882a593Smuzhiyun 		pr_err("alg: %s: %s test failed (wrong result) on test vector %s, cfg=\"%s\"\n",
1150*4882a593Smuzhiyun 		       type, driver, vec_name, cfg->name);
1151*4882a593Smuzhiyun 		return -EINVAL;
1152*4882a593Smuzhiyun 	}
1153*4882a593Smuzhiyun 	if (!testmgr_is_poison(&result[digestsize], TESTMGR_POISON_LEN)) {
1154*4882a593Smuzhiyun 		pr_err("alg: %s: %s overran result buffer on test vector %s, cfg=\"%s\"\n",
1155*4882a593Smuzhiyun 		       type, driver, vec_name, cfg->name);
1156*4882a593Smuzhiyun 		return -EOVERFLOW;
1157*4882a593Smuzhiyun 	}
1158*4882a593Smuzhiyun 	return 0;
1159*4882a593Smuzhiyun }
1160*4882a593Smuzhiyun 
check_shash_op(const char * op,int err,const char * driver,const char * vec_name,const struct testvec_config * cfg)1161*4882a593Smuzhiyun static inline int check_shash_op(const char *op, int err,
1162*4882a593Smuzhiyun 				 const char *driver, const char *vec_name,
1163*4882a593Smuzhiyun 				 const struct testvec_config *cfg)
1164*4882a593Smuzhiyun {
1165*4882a593Smuzhiyun 	if (err)
1166*4882a593Smuzhiyun 		pr_err("alg: shash: %s %s() failed with err %d on test vector %s, cfg=\"%s\"\n",
1167*4882a593Smuzhiyun 		       driver, op, err, vec_name, cfg->name);
1168*4882a593Smuzhiyun 	return err;
1169*4882a593Smuzhiyun }
1170*4882a593Smuzhiyun 
sg_data(struct scatterlist * sg)1171*4882a593Smuzhiyun static inline const void *sg_data(struct scatterlist *sg)
1172*4882a593Smuzhiyun {
1173*4882a593Smuzhiyun 	return page_address(sg_page(sg)) + sg->offset;
1174*4882a593Smuzhiyun }
1175*4882a593Smuzhiyun 
1176*4882a593Smuzhiyun /* Test one hash test vector in one configuration, using the shash API */
test_shash_vec_cfg(const char * driver,const struct hash_testvec * vec,const char * vec_name,const struct testvec_config * cfg,struct shash_desc * desc,struct test_sglist * tsgl,u8 * hashstate)1177*4882a593Smuzhiyun static int test_shash_vec_cfg(const char *driver,
1178*4882a593Smuzhiyun 			      const struct hash_testvec *vec,
1179*4882a593Smuzhiyun 			      const char *vec_name,
1180*4882a593Smuzhiyun 			      const struct testvec_config *cfg,
1181*4882a593Smuzhiyun 			      struct shash_desc *desc,
1182*4882a593Smuzhiyun 			      struct test_sglist *tsgl,
1183*4882a593Smuzhiyun 			      u8 *hashstate)
1184*4882a593Smuzhiyun {
1185*4882a593Smuzhiyun 	struct crypto_shash *tfm = desc->tfm;
1186*4882a593Smuzhiyun 	const unsigned int alignmask = crypto_shash_alignmask(tfm);
1187*4882a593Smuzhiyun 	const unsigned int digestsize = crypto_shash_digestsize(tfm);
1188*4882a593Smuzhiyun 	const unsigned int statesize = crypto_shash_statesize(tfm);
1189*4882a593Smuzhiyun 	const struct test_sg_division *divs[XBUFSIZE];
1190*4882a593Smuzhiyun 	unsigned int i;
1191*4882a593Smuzhiyun 	u8 result[HASH_MAX_DIGESTSIZE + TESTMGR_POISON_LEN];
1192*4882a593Smuzhiyun 	int err;
1193*4882a593Smuzhiyun 
1194*4882a593Smuzhiyun 	/* Set the key, if specified */
1195*4882a593Smuzhiyun 	if (vec->ksize) {
1196*4882a593Smuzhiyun 		err = do_setkey(crypto_shash_setkey, tfm, vec->key, vec->ksize,
1197*4882a593Smuzhiyun 				cfg, alignmask);
1198*4882a593Smuzhiyun 		if (err) {
1199*4882a593Smuzhiyun 			if (err == vec->setkey_error)
1200*4882a593Smuzhiyun 				return 0;
1201*4882a593Smuzhiyun 			pr_err("alg: shash: %s setkey failed on test vector %s; expected_error=%d, actual_error=%d, flags=%#x\n",
1202*4882a593Smuzhiyun 			       driver, vec_name, vec->setkey_error, err,
1203*4882a593Smuzhiyun 			       crypto_shash_get_flags(tfm));
1204*4882a593Smuzhiyun 			return err;
1205*4882a593Smuzhiyun 		}
1206*4882a593Smuzhiyun 		if (vec->setkey_error) {
1207*4882a593Smuzhiyun 			pr_err("alg: shash: %s setkey unexpectedly succeeded on test vector %s; expected_error=%d\n",
1208*4882a593Smuzhiyun 			       driver, vec_name, vec->setkey_error);
1209*4882a593Smuzhiyun 			return -EINVAL;
1210*4882a593Smuzhiyun 		}
1211*4882a593Smuzhiyun 	}
1212*4882a593Smuzhiyun 
1213*4882a593Smuzhiyun 	/* Build the scatterlist for the source data */
1214*4882a593Smuzhiyun 	err = build_hash_sglist(tsgl, vec, cfg, alignmask, divs);
1215*4882a593Smuzhiyun 	if (err) {
1216*4882a593Smuzhiyun 		pr_err("alg: shash: %s: error preparing scatterlist for test vector %s, cfg=\"%s\"\n",
1217*4882a593Smuzhiyun 		       driver, vec_name, cfg->name);
1218*4882a593Smuzhiyun 		return err;
1219*4882a593Smuzhiyun 	}
1220*4882a593Smuzhiyun 
1221*4882a593Smuzhiyun 	/* Do the actual hashing */
1222*4882a593Smuzhiyun 
1223*4882a593Smuzhiyun 	testmgr_poison(desc->__ctx, crypto_shash_descsize(tfm));
1224*4882a593Smuzhiyun 	testmgr_poison(result, digestsize + TESTMGR_POISON_LEN);
1225*4882a593Smuzhiyun 
1226*4882a593Smuzhiyun 	if (cfg->finalization_type == FINALIZATION_TYPE_DIGEST ||
1227*4882a593Smuzhiyun 	    vec->digest_error) {
1228*4882a593Smuzhiyun 		/* Just using digest() */
1229*4882a593Smuzhiyun 		if (tsgl->nents != 1)
1230*4882a593Smuzhiyun 			return 0;
1231*4882a593Smuzhiyun 		if (cfg->nosimd)
1232*4882a593Smuzhiyun 			crypto_disable_simd_for_test();
1233*4882a593Smuzhiyun 		err = crypto_shash_digest(desc, sg_data(&tsgl->sgl[0]),
1234*4882a593Smuzhiyun 					  tsgl->sgl[0].length, result);
1235*4882a593Smuzhiyun 		if (cfg->nosimd)
1236*4882a593Smuzhiyun 			crypto_reenable_simd_for_test();
1237*4882a593Smuzhiyun 		if (err) {
1238*4882a593Smuzhiyun 			if (err == vec->digest_error)
1239*4882a593Smuzhiyun 				return 0;
1240*4882a593Smuzhiyun 			pr_err("alg: shash: %s digest() failed on test vector %s; expected_error=%d, actual_error=%d, cfg=\"%s\"\n",
1241*4882a593Smuzhiyun 			       driver, vec_name, vec->digest_error, err,
1242*4882a593Smuzhiyun 			       cfg->name);
1243*4882a593Smuzhiyun 			return err;
1244*4882a593Smuzhiyun 		}
1245*4882a593Smuzhiyun 		if (vec->digest_error) {
1246*4882a593Smuzhiyun 			pr_err("alg: shash: %s digest() unexpectedly succeeded on test vector %s; expected_error=%d, cfg=\"%s\"\n",
1247*4882a593Smuzhiyun 			       driver, vec_name, vec->digest_error, cfg->name);
1248*4882a593Smuzhiyun 			return -EINVAL;
1249*4882a593Smuzhiyun 		}
1250*4882a593Smuzhiyun 		goto result_ready;
1251*4882a593Smuzhiyun 	}
1252*4882a593Smuzhiyun 
1253*4882a593Smuzhiyun 	/* Using init(), zero or more update(), then final() or finup() */
1254*4882a593Smuzhiyun 
1255*4882a593Smuzhiyun 	if (cfg->nosimd)
1256*4882a593Smuzhiyun 		crypto_disable_simd_for_test();
1257*4882a593Smuzhiyun 	err = crypto_shash_init(desc);
1258*4882a593Smuzhiyun 	if (cfg->nosimd)
1259*4882a593Smuzhiyun 		crypto_reenable_simd_for_test();
1260*4882a593Smuzhiyun 	err = check_shash_op("init", err, driver, vec_name, cfg);
1261*4882a593Smuzhiyun 	if (err)
1262*4882a593Smuzhiyun 		return err;
1263*4882a593Smuzhiyun 
1264*4882a593Smuzhiyun 	for (i = 0; i < tsgl->nents; i++) {
1265*4882a593Smuzhiyun 		if (i + 1 == tsgl->nents &&
1266*4882a593Smuzhiyun 		    cfg->finalization_type == FINALIZATION_TYPE_FINUP) {
1267*4882a593Smuzhiyun 			if (divs[i]->nosimd)
1268*4882a593Smuzhiyun 				crypto_disable_simd_for_test();
1269*4882a593Smuzhiyun 			err = crypto_shash_finup(desc, sg_data(&tsgl->sgl[i]),
1270*4882a593Smuzhiyun 						 tsgl->sgl[i].length, result);
1271*4882a593Smuzhiyun 			if (divs[i]->nosimd)
1272*4882a593Smuzhiyun 				crypto_reenable_simd_for_test();
1273*4882a593Smuzhiyun 			err = check_shash_op("finup", err, driver, vec_name,
1274*4882a593Smuzhiyun 					     cfg);
1275*4882a593Smuzhiyun 			if (err)
1276*4882a593Smuzhiyun 				return err;
1277*4882a593Smuzhiyun 			goto result_ready;
1278*4882a593Smuzhiyun 		}
1279*4882a593Smuzhiyun 		if (divs[i]->nosimd)
1280*4882a593Smuzhiyun 			crypto_disable_simd_for_test();
1281*4882a593Smuzhiyun 		err = crypto_shash_update(desc, sg_data(&tsgl->sgl[i]),
1282*4882a593Smuzhiyun 					  tsgl->sgl[i].length);
1283*4882a593Smuzhiyun 		if (divs[i]->nosimd)
1284*4882a593Smuzhiyun 			crypto_reenable_simd_for_test();
1285*4882a593Smuzhiyun 		err = check_shash_op("update", err, driver, vec_name, cfg);
1286*4882a593Smuzhiyun 		if (err)
1287*4882a593Smuzhiyun 			return err;
1288*4882a593Smuzhiyun 		if (divs[i]->flush_type == FLUSH_TYPE_REIMPORT) {
1289*4882a593Smuzhiyun 			/* Test ->export() and ->import() */
1290*4882a593Smuzhiyun 			testmgr_poison(hashstate + statesize,
1291*4882a593Smuzhiyun 				       TESTMGR_POISON_LEN);
1292*4882a593Smuzhiyun 			err = crypto_shash_export(desc, hashstate);
1293*4882a593Smuzhiyun 			err = check_shash_op("export", err, driver, vec_name,
1294*4882a593Smuzhiyun 					     cfg);
1295*4882a593Smuzhiyun 			if (err)
1296*4882a593Smuzhiyun 				return err;
1297*4882a593Smuzhiyun 			if (!testmgr_is_poison(hashstate + statesize,
1298*4882a593Smuzhiyun 					       TESTMGR_POISON_LEN)) {
1299*4882a593Smuzhiyun 				pr_err("alg: shash: %s export() overran state buffer on test vector %s, cfg=\"%s\"\n",
1300*4882a593Smuzhiyun 				       driver, vec_name, cfg->name);
1301*4882a593Smuzhiyun 				return -EOVERFLOW;
1302*4882a593Smuzhiyun 			}
1303*4882a593Smuzhiyun 			testmgr_poison(desc->__ctx, crypto_shash_descsize(tfm));
1304*4882a593Smuzhiyun 			err = crypto_shash_import(desc, hashstate);
1305*4882a593Smuzhiyun 			err = check_shash_op("import", err, driver, vec_name,
1306*4882a593Smuzhiyun 					     cfg);
1307*4882a593Smuzhiyun 			if (err)
1308*4882a593Smuzhiyun 				return err;
1309*4882a593Smuzhiyun 		}
1310*4882a593Smuzhiyun 	}
1311*4882a593Smuzhiyun 
1312*4882a593Smuzhiyun 	if (cfg->nosimd)
1313*4882a593Smuzhiyun 		crypto_disable_simd_for_test();
1314*4882a593Smuzhiyun 	err = crypto_shash_final(desc, result);
1315*4882a593Smuzhiyun 	if (cfg->nosimd)
1316*4882a593Smuzhiyun 		crypto_reenable_simd_for_test();
1317*4882a593Smuzhiyun 	err = check_shash_op("final", err, driver, vec_name, cfg);
1318*4882a593Smuzhiyun 	if (err)
1319*4882a593Smuzhiyun 		return err;
1320*4882a593Smuzhiyun result_ready:
1321*4882a593Smuzhiyun 	return check_hash_result("shash", result, digestsize, vec, vec_name,
1322*4882a593Smuzhiyun 				 driver, cfg);
1323*4882a593Smuzhiyun }
1324*4882a593Smuzhiyun 
do_ahash_op(int (* op)(struct ahash_request * req),struct ahash_request * req,struct crypto_wait * wait,bool nosimd)1325*4882a593Smuzhiyun static int do_ahash_op(int (*op)(struct ahash_request *req),
1326*4882a593Smuzhiyun 		       struct ahash_request *req,
1327*4882a593Smuzhiyun 		       struct crypto_wait *wait, bool nosimd)
1328*4882a593Smuzhiyun {
1329*4882a593Smuzhiyun 	int err;
1330*4882a593Smuzhiyun 
1331*4882a593Smuzhiyun 	if (nosimd)
1332*4882a593Smuzhiyun 		crypto_disable_simd_for_test();
1333*4882a593Smuzhiyun 
1334*4882a593Smuzhiyun 	err = op(req);
1335*4882a593Smuzhiyun 
1336*4882a593Smuzhiyun 	if (nosimd)
1337*4882a593Smuzhiyun 		crypto_reenable_simd_for_test();
1338*4882a593Smuzhiyun 
1339*4882a593Smuzhiyun 	return crypto_wait_req(err, wait);
1340*4882a593Smuzhiyun }
1341*4882a593Smuzhiyun 
check_nonfinal_ahash_op(const char * op,int err,u8 * result,unsigned int digestsize,const char * driver,const char * vec_name,const struct testvec_config * cfg)1342*4882a593Smuzhiyun static int check_nonfinal_ahash_op(const char *op, int err,
1343*4882a593Smuzhiyun 				   u8 *result, unsigned int digestsize,
1344*4882a593Smuzhiyun 				   const char *driver, const char *vec_name,
1345*4882a593Smuzhiyun 				   const struct testvec_config *cfg)
1346*4882a593Smuzhiyun {
1347*4882a593Smuzhiyun 	if (err) {
1348*4882a593Smuzhiyun 		pr_err("alg: ahash: %s %s() failed with err %d on test vector %s, cfg=\"%s\"\n",
1349*4882a593Smuzhiyun 		       driver, op, err, vec_name, cfg->name);
1350*4882a593Smuzhiyun 		return err;
1351*4882a593Smuzhiyun 	}
1352*4882a593Smuzhiyun 	if (!testmgr_is_poison(result, digestsize)) {
1353*4882a593Smuzhiyun 		pr_err("alg: ahash: %s %s() used result buffer on test vector %s, cfg=\"%s\"\n",
1354*4882a593Smuzhiyun 		       driver, op, vec_name, cfg->name);
1355*4882a593Smuzhiyun 		return -EINVAL;
1356*4882a593Smuzhiyun 	}
1357*4882a593Smuzhiyun 	return 0;
1358*4882a593Smuzhiyun }
1359*4882a593Smuzhiyun 
1360*4882a593Smuzhiyun /* Test one hash test vector in one configuration, using the ahash API */
test_ahash_vec_cfg(const char * driver,const struct hash_testvec * vec,const char * vec_name,const struct testvec_config * cfg,struct ahash_request * req,struct test_sglist * tsgl,u8 * hashstate)1361*4882a593Smuzhiyun static int test_ahash_vec_cfg(const char *driver,
1362*4882a593Smuzhiyun 			      const struct hash_testvec *vec,
1363*4882a593Smuzhiyun 			      const char *vec_name,
1364*4882a593Smuzhiyun 			      const struct testvec_config *cfg,
1365*4882a593Smuzhiyun 			      struct ahash_request *req,
1366*4882a593Smuzhiyun 			      struct test_sglist *tsgl,
1367*4882a593Smuzhiyun 			      u8 *hashstate)
1368*4882a593Smuzhiyun {
1369*4882a593Smuzhiyun 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
1370*4882a593Smuzhiyun 	const unsigned int alignmask = crypto_ahash_alignmask(tfm);
1371*4882a593Smuzhiyun 	const unsigned int digestsize = crypto_ahash_digestsize(tfm);
1372*4882a593Smuzhiyun 	const unsigned int statesize = crypto_ahash_statesize(tfm);
1373*4882a593Smuzhiyun 	const u32 req_flags = CRYPTO_TFM_REQ_MAY_BACKLOG | cfg->req_flags;
1374*4882a593Smuzhiyun 	const struct test_sg_division *divs[XBUFSIZE];
1375*4882a593Smuzhiyun 	DECLARE_CRYPTO_WAIT(wait);
1376*4882a593Smuzhiyun 	unsigned int i;
1377*4882a593Smuzhiyun 	struct scatterlist *pending_sgl;
1378*4882a593Smuzhiyun 	unsigned int pending_len;
1379*4882a593Smuzhiyun 	u8 result[HASH_MAX_DIGESTSIZE + TESTMGR_POISON_LEN];
1380*4882a593Smuzhiyun 	int err;
1381*4882a593Smuzhiyun 
1382*4882a593Smuzhiyun 	/* Set the key, if specified */
1383*4882a593Smuzhiyun 	if (vec->ksize) {
1384*4882a593Smuzhiyun 		err = do_setkey(crypto_ahash_setkey, tfm, vec->key, vec->ksize,
1385*4882a593Smuzhiyun 				cfg, alignmask);
1386*4882a593Smuzhiyun 		if (err) {
1387*4882a593Smuzhiyun 			if (err == vec->setkey_error)
1388*4882a593Smuzhiyun 				return 0;
1389*4882a593Smuzhiyun 			pr_err("alg: ahash: %s setkey failed on test vector %s; expected_error=%d, actual_error=%d, flags=%#x\n",
1390*4882a593Smuzhiyun 			       driver, vec_name, vec->setkey_error, err,
1391*4882a593Smuzhiyun 			       crypto_ahash_get_flags(tfm));
1392*4882a593Smuzhiyun 			return err;
1393*4882a593Smuzhiyun 		}
1394*4882a593Smuzhiyun 		if (vec->setkey_error) {
1395*4882a593Smuzhiyun 			pr_err("alg: ahash: %s setkey unexpectedly succeeded on test vector %s; expected_error=%d\n",
1396*4882a593Smuzhiyun 			       driver, vec_name, vec->setkey_error);
1397*4882a593Smuzhiyun 			return -EINVAL;
1398*4882a593Smuzhiyun 		}
1399*4882a593Smuzhiyun 	}
1400*4882a593Smuzhiyun 
1401*4882a593Smuzhiyun 	/* Build the scatterlist for the source data */
1402*4882a593Smuzhiyun 	err = build_hash_sglist(tsgl, vec, cfg, alignmask, divs);
1403*4882a593Smuzhiyun 	if (err) {
1404*4882a593Smuzhiyun 		pr_err("alg: ahash: %s: error preparing scatterlist for test vector %s, cfg=\"%s\"\n",
1405*4882a593Smuzhiyun 		       driver, vec_name, cfg->name);
1406*4882a593Smuzhiyun 		return err;
1407*4882a593Smuzhiyun 	}
1408*4882a593Smuzhiyun 
1409*4882a593Smuzhiyun 	/* Do the actual hashing */
1410*4882a593Smuzhiyun 
1411*4882a593Smuzhiyun 	testmgr_poison(req->__ctx, crypto_ahash_reqsize(tfm));
1412*4882a593Smuzhiyun 	testmgr_poison(result, digestsize + TESTMGR_POISON_LEN);
1413*4882a593Smuzhiyun 
1414*4882a593Smuzhiyun 	if (cfg->finalization_type == FINALIZATION_TYPE_DIGEST ||
1415*4882a593Smuzhiyun 	    vec->digest_error) {
1416*4882a593Smuzhiyun 		/* Just using digest() */
1417*4882a593Smuzhiyun 		ahash_request_set_callback(req, req_flags, crypto_req_done,
1418*4882a593Smuzhiyun 					   &wait);
1419*4882a593Smuzhiyun 		ahash_request_set_crypt(req, tsgl->sgl, result, vec->psize);
1420*4882a593Smuzhiyun 		err = do_ahash_op(crypto_ahash_digest, req, &wait, cfg->nosimd);
1421*4882a593Smuzhiyun 		if (err) {
1422*4882a593Smuzhiyun 			if (err == vec->digest_error)
1423*4882a593Smuzhiyun 				return 0;
1424*4882a593Smuzhiyun 			pr_err("alg: ahash: %s digest() failed on test vector %s; expected_error=%d, actual_error=%d, cfg=\"%s\"\n",
1425*4882a593Smuzhiyun 			       driver, vec_name, vec->digest_error, err,
1426*4882a593Smuzhiyun 			       cfg->name);
1427*4882a593Smuzhiyun 			return err;
1428*4882a593Smuzhiyun 		}
1429*4882a593Smuzhiyun 		if (vec->digest_error) {
1430*4882a593Smuzhiyun 			pr_err("alg: ahash: %s digest() unexpectedly succeeded on test vector %s; expected_error=%d, cfg=\"%s\"\n",
1431*4882a593Smuzhiyun 			       driver, vec_name, vec->digest_error, cfg->name);
1432*4882a593Smuzhiyun 			return -EINVAL;
1433*4882a593Smuzhiyun 		}
1434*4882a593Smuzhiyun 		goto result_ready;
1435*4882a593Smuzhiyun 	}
1436*4882a593Smuzhiyun 
1437*4882a593Smuzhiyun 	/* Using init(), zero or more update(), then final() or finup() */
1438*4882a593Smuzhiyun 
1439*4882a593Smuzhiyun 	ahash_request_set_callback(req, req_flags, crypto_req_done, &wait);
1440*4882a593Smuzhiyun 	ahash_request_set_crypt(req, NULL, result, 0);
1441*4882a593Smuzhiyun 	err = do_ahash_op(crypto_ahash_init, req, &wait, cfg->nosimd);
1442*4882a593Smuzhiyun 	err = check_nonfinal_ahash_op("init", err, result, digestsize,
1443*4882a593Smuzhiyun 				      driver, vec_name, cfg);
1444*4882a593Smuzhiyun 	if (err)
1445*4882a593Smuzhiyun 		return err;
1446*4882a593Smuzhiyun 
1447*4882a593Smuzhiyun 	pending_sgl = NULL;
1448*4882a593Smuzhiyun 	pending_len = 0;
1449*4882a593Smuzhiyun 	for (i = 0; i < tsgl->nents; i++) {
1450*4882a593Smuzhiyun 		if (divs[i]->flush_type != FLUSH_TYPE_NONE &&
1451*4882a593Smuzhiyun 		    pending_sgl != NULL) {
1452*4882a593Smuzhiyun 			/* update() with the pending data */
1453*4882a593Smuzhiyun 			ahash_request_set_callback(req, req_flags,
1454*4882a593Smuzhiyun 						   crypto_req_done, &wait);
1455*4882a593Smuzhiyun 			ahash_request_set_crypt(req, pending_sgl, result,
1456*4882a593Smuzhiyun 						pending_len);
1457*4882a593Smuzhiyun 			err = do_ahash_op(crypto_ahash_update, req, &wait,
1458*4882a593Smuzhiyun 					  divs[i]->nosimd);
1459*4882a593Smuzhiyun 			err = check_nonfinal_ahash_op("update", err,
1460*4882a593Smuzhiyun 						      result, digestsize,
1461*4882a593Smuzhiyun 						      driver, vec_name, cfg);
1462*4882a593Smuzhiyun 			if (err)
1463*4882a593Smuzhiyun 				return err;
1464*4882a593Smuzhiyun 			pending_sgl = NULL;
1465*4882a593Smuzhiyun 			pending_len = 0;
1466*4882a593Smuzhiyun 		}
1467*4882a593Smuzhiyun 		if (divs[i]->flush_type == FLUSH_TYPE_REIMPORT) {
1468*4882a593Smuzhiyun 			/* Test ->export() and ->import() */
1469*4882a593Smuzhiyun 			testmgr_poison(hashstate + statesize,
1470*4882a593Smuzhiyun 				       TESTMGR_POISON_LEN);
1471*4882a593Smuzhiyun 			err = crypto_ahash_export(req, hashstate);
1472*4882a593Smuzhiyun 			err = check_nonfinal_ahash_op("export", err,
1473*4882a593Smuzhiyun 						      result, digestsize,
1474*4882a593Smuzhiyun 						      driver, vec_name, cfg);
1475*4882a593Smuzhiyun 			if (err)
1476*4882a593Smuzhiyun 				return err;
1477*4882a593Smuzhiyun 			if (!testmgr_is_poison(hashstate + statesize,
1478*4882a593Smuzhiyun 					       TESTMGR_POISON_LEN)) {
1479*4882a593Smuzhiyun 				pr_err("alg: ahash: %s export() overran state buffer on test vector %s, cfg=\"%s\"\n",
1480*4882a593Smuzhiyun 				       driver, vec_name, cfg->name);
1481*4882a593Smuzhiyun 				return -EOVERFLOW;
1482*4882a593Smuzhiyun 			}
1483*4882a593Smuzhiyun 
1484*4882a593Smuzhiyun 			testmgr_poison(req->__ctx, crypto_ahash_reqsize(tfm));
1485*4882a593Smuzhiyun 			err = crypto_ahash_import(req, hashstate);
1486*4882a593Smuzhiyun 			err = check_nonfinal_ahash_op("import", err,
1487*4882a593Smuzhiyun 						      result, digestsize,
1488*4882a593Smuzhiyun 						      driver, vec_name, cfg);
1489*4882a593Smuzhiyun 			if (err)
1490*4882a593Smuzhiyun 				return err;
1491*4882a593Smuzhiyun 		}
1492*4882a593Smuzhiyun 		if (pending_sgl == NULL)
1493*4882a593Smuzhiyun 			pending_sgl = &tsgl->sgl[i];
1494*4882a593Smuzhiyun 		pending_len += tsgl->sgl[i].length;
1495*4882a593Smuzhiyun 	}
1496*4882a593Smuzhiyun 
1497*4882a593Smuzhiyun 	ahash_request_set_callback(req, req_flags, crypto_req_done, &wait);
1498*4882a593Smuzhiyun 	ahash_request_set_crypt(req, pending_sgl, result, pending_len);
1499*4882a593Smuzhiyun 	if (cfg->finalization_type == FINALIZATION_TYPE_FINAL) {
1500*4882a593Smuzhiyun 		/* finish with update() and final() */
1501*4882a593Smuzhiyun 		err = do_ahash_op(crypto_ahash_update, req, &wait, cfg->nosimd);
1502*4882a593Smuzhiyun 		err = check_nonfinal_ahash_op("update", err, result, digestsize,
1503*4882a593Smuzhiyun 					      driver, vec_name, cfg);
1504*4882a593Smuzhiyun 		if (err)
1505*4882a593Smuzhiyun 			return err;
1506*4882a593Smuzhiyun 		err = do_ahash_op(crypto_ahash_final, req, &wait, cfg->nosimd);
1507*4882a593Smuzhiyun 		if (err) {
1508*4882a593Smuzhiyun 			pr_err("alg: ahash: %s final() failed with err %d on test vector %s, cfg=\"%s\"\n",
1509*4882a593Smuzhiyun 			       driver, err, vec_name, cfg->name);
1510*4882a593Smuzhiyun 			return err;
1511*4882a593Smuzhiyun 		}
1512*4882a593Smuzhiyun 	} else {
1513*4882a593Smuzhiyun 		/* finish with finup() */
1514*4882a593Smuzhiyun 		err = do_ahash_op(crypto_ahash_finup, req, &wait, cfg->nosimd);
1515*4882a593Smuzhiyun 		if (err) {
1516*4882a593Smuzhiyun 			pr_err("alg: ahash: %s finup() failed with err %d on test vector %s, cfg=\"%s\"\n",
1517*4882a593Smuzhiyun 			       driver, err, vec_name, cfg->name);
1518*4882a593Smuzhiyun 			return err;
1519*4882a593Smuzhiyun 		}
1520*4882a593Smuzhiyun 	}
1521*4882a593Smuzhiyun 
1522*4882a593Smuzhiyun result_ready:
1523*4882a593Smuzhiyun 	return check_hash_result("ahash", result, digestsize, vec, vec_name,
1524*4882a593Smuzhiyun 				 driver, cfg);
1525*4882a593Smuzhiyun }
1526*4882a593Smuzhiyun 
test_hash_vec_cfg(const char * driver,const struct hash_testvec * vec,const char * vec_name,const struct testvec_config * cfg,struct ahash_request * req,struct shash_desc * desc,struct test_sglist * tsgl,u8 * hashstate)1527*4882a593Smuzhiyun static int test_hash_vec_cfg(const char *driver,
1528*4882a593Smuzhiyun 			     const struct hash_testvec *vec,
1529*4882a593Smuzhiyun 			     const char *vec_name,
1530*4882a593Smuzhiyun 			     const struct testvec_config *cfg,
1531*4882a593Smuzhiyun 			     struct ahash_request *req,
1532*4882a593Smuzhiyun 			     struct shash_desc *desc,
1533*4882a593Smuzhiyun 			     struct test_sglist *tsgl,
1534*4882a593Smuzhiyun 			     u8 *hashstate)
1535*4882a593Smuzhiyun {
1536*4882a593Smuzhiyun 	int err;
1537*4882a593Smuzhiyun 
1538*4882a593Smuzhiyun 	/*
1539*4882a593Smuzhiyun 	 * For algorithms implemented as "shash", most bugs will be detected by
1540*4882a593Smuzhiyun 	 * both the shash and ahash tests.  Test the shash API first so that the
1541*4882a593Smuzhiyun 	 * failures involve less indirection, so are easier to debug.
1542*4882a593Smuzhiyun 	 */
1543*4882a593Smuzhiyun 
1544*4882a593Smuzhiyun 	if (desc) {
1545*4882a593Smuzhiyun 		err = test_shash_vec_cfg(driver, vec, vec_name, cfg, desc, tsgl,
1546*4882a593Smuzhiyun 					 hashstate);
1547*4882a593Smuzhiyun 		if (err)
1548*4882a593Smuzhiyun 			return err;
1549*4882a593Smuzhiyun 	}
1550*4882a593Smuzhiyun 
1551*4882a593Smuzhiyun 	return test_ahash_vec_cfg(driver, vec, vec_name, cfg, req, tsgl,
1552*4882a593Smuzhiyun 				  hashstate);
1553*4882a593Smuzhiyun }
1554*4882a593Smuzhiyun 
test_hash_vec(const char * driver,const struct hash_testvec * vec,unsigned int vec_num,struct ahash_request * req,struct shash_desc * desc,struct test_sglist * tsgl,u8 * hashstate)1555*4882a593Smuzhiyun static int test_hash_vec(const char *driver, const struct hash_testvec *vec,
1556*4882a593Smuzhiyun 			 unsigned int vec_num, struct ahash_request *req,
1557*4882a593Smuzhiyun 			 struct shash_desc *desc, struct test_sglist *tsgl,
1558*4882a593Smuzhiyun 			 u8 *hashstate)
1559*4882a593Smuzhiyun {
1560*4882a593Smuzhiyun 	char vec_name[16];
1561*4882a593Smuzhiyun 	unsigned int i;
1562*4882a593Smuzhiyun 	int err;
1563*4882a593Smuzhiyun 
1564*4882a593Smuzhiyun 	sprintf(vec_name, "%u", vec_num);
1565*4882a593Smuzhiyun 
1566*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(default_hash_testvec_configs); i++) {
1567*4882a593Smuzhiyun 		err = test_hash_vec_cfg(driver, vec, vec_name,
1568*4882a593Smuzhiyun 					&default_hash_testvec_configs[i],
1569*4882a593Smuzhiyun 					req, desc, tsgl, hashstate);
1570*4882a593Smuzhiyun 		if (err)
1571*4882a593Smuzhiyun 			return err;
1572*4882a593Smuzhiyun 	}
1573*4882a593Smuzhiyun 
1574*4882a593Smuzhiyun #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
1575*4882a593Smuzhiyun 	if (!noextratests) {
1576*4882a593Smuzhiyun 		struct testvec_config cfg;
1577*4882a593Smuzhiyun 		char cfgname[TESTVEC_CONFIG_NAMELEN];
1578*4882a593Smuzhiyun 
1579*4882a593Smuzhiyun 		for (i = 0; i < fuzz_iterations; i++) {
1580*4882a593Smuzhiyun 			generate_random_testvec_config(&cfg, cfgname,
1581*4882a593Smuzhiyun 						       sizeof(cfgname));
1582*4882a593Smuzhiyun 			err = test_hash_vec_cfg(driver, vec, vec_name, &cfg,
1583*4882a593Smuzhiyun 						req, desc, tsgl, hashstate);
1584*4882a593Smuzhiyun 			if (err)
1585*4882a593Smuzhiyun 				return err;
1586*4882a593Smuzhiyun 			cond_resched();
1587*4882a593Smuzhiyun 		}
1588*4882a593Smuzhiyun 	}
1589*4882a593Smuzhiyun #endif
1590*4882a593Smuzhiyun 	return 0;
1591*4882a593Smuzhiyun }
1592*4882a593Smuzhiyun 
1593*4882a593Smuzhiyun #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
1594*4882a593Smuzhiyun /*
1595*4882a593Smuzhiyun  * Generate a hash test vector from the given implementation.
1596*4882a593Smuzhiyun  * Assumes the buffers in 'vec' were already allocated.
1597*4882a593Smuzhiyun  */
generate_random_hash_testvec(struct shash_desc * desc,struct hash_testvec * vec,unsigned int maxkeysize,unsigned int maxdatasize,char * name,size_t max_namelen)1598*4882a593Smuzhiyun static void generate_random_hash_testvec(struct shash_desc *desc,
1599*4882a593Smuzhiyun 					 struct hash_testvec *vec,
1600*4882a593Smuzhiyun 					 unsigned int maxkeysize,
1601*4882a593Smuzhiyun 					 unsigned int maxdatasize,
1602*4882a593Smuzhiyun 					 char *name, size_t max_namelen)
1603*4882a593Smuzhiyun {
1604*4882a593Smuzhiyun 	/* Data */
1605*4882a593Smuzhiyun 	vec->psize = generate_random_length(maxdatasize);
1606*4882a593Smuzhiyun 	generate_random_bytes((u8 *)vec->plaintext, vec->psize);
1607*4882a593Smuzhiyun 
1608*4882a593Smuzhiyun 	/*
1609*4882a593Smuzhiyun 	 * Key: length in range [1, maxkeysize], but usually choose maxkeysize.
1610*4882a593Smuzhiyun 	 * If algorithm is unkeyed, then maxkeysize == 0 and set ksize = 0.
1611*4882a593Smuzhiyun 	 */
1612*4882a593Smuzhiyun 	vec->setkey_error = 0;
1613*4882a593Smuzhiyun 	vec->ksize = 0;
1614*4882a593Smuzhiyun 	if (maxkeysize) {
1615*4882a593Smuzhiyun 		vec->ksize = maxkeysize;
1616*4882a593Smuzhiyun 		if (prandom_u32() % 4 == 0)
1617*4882a593Smuzhiyun 			vec->ksize = 1 + (prandom_u32() % maxkeysize);
1618*4882a593Smuzhiyun 		generate_random_bytes((u8 *)vec->key, vec->ksize);
1619*4882a593Smuzhiyun 
1620*4882a593Smuzhiyun 		vec->setkey_error = crypto_shash_setkey(desc->tfm, vec->key,
1621*4882a593Smuzhiyun 							vec->ksize);
1622*4882a593Smuzhiyun 		/* If the key couldn't be set, no need to continue to digest. */
1623*4882a593Smuzhiyun 		if (vec->setkey_error)
1624*4882a593Smuzhiyun 			goto done;
1625*4882a593Smuzhiyun 	}
1626*4882a593Smuzhiyun 
1627*4882a593Smuzhiyun 	/* Digest */
1628*4882a593Smuzhiyun 	vec->digest_error = crypto_shash_digest(desc, vec->plaintext,
1629*4882a593Smuzhiyun 						vec->psize, (u8 *)vec->digest);
1630*4882a593Smuzhiyun done:
1631*4882a593Smuzhiyun 	snprintf(name, max_namelen, "\"random: psize=%u ksize=%u\"",
1632*4882a593Smuzhiyun 		 vec->psize, vec->ksize);
1633*4882a593Smuzhiyun }
1634*4882a593Smuzhiyun 
1635*4882a593Smuzhiyun /*
1636*4882a593Smuzhiyun  * Test the hash algorithm represented by @req against the corresponding generic
1637*4882a593Smuzhiyun  * implementation, if one is available.
1638*4882a593Smuzhiyun  */
test_hash_vs_generic_impl(const char * driver,const char * generic_driver,unsigned int maxkeysize,struct ahash_request * req,struct shash_desc * desc,struct test_sglist * tsgl,u8 * hashstate)1639*4882a593Smuzhiyun static int test_hash_vs_generic_impl(const char *driver,
1640*4882a593Smuzhiyun 				     const char *generic_driver,
1641*4882a593Smuzhiyun 				     unsigned int maxkeysize,
1642*4882a593Smuzhiyun 				     struct ahash_request *req,
1643*4882a593Smuzhiyun 				     struct shash_desc *desc,
1644*4882a593Smuzhiyun 				     struct test_sglist *tsgl,
1645*4882a593Smuzhiyun 				     u8 *hashstate)
1646*4882a593Smuzhiyun {
1647*4882a593Smuzhiyun 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
1648*4882a593Smuzhiyun 	const unsigned int digestsize = crypto_ahash_digestsize(tfm);
1649*4882a593Smuzhiyun 	const unsigned int blocksize = crypto_ahash_blocksize(tfm);
1650*4882a593Smuzhiyun 	const unsigned int maxdatasize = (2 * PAGE_SIZE) - TESTMGR_POISON_LEN;
1651*4882a593Smuzhiyun 	const char *algname = crypto_hash_alg_common(tfm)->base.cra_name;
1652*4882a593Smuzhiyun 	char _generic_driver[CRYPTO_MAX_ALG_NAME];
1653*4882a593Smuzhiyun 	struct crypto_shash *generic_tfm = NULL;
1654*4882a593Smuzhiyun 	struct shash_desc *generic_desc = NULL;
1655*4882a593Smuzhiyun 	unsigned int i;
1656*4882a593Smuzhiyun 	struct hash_testvec vec = { 0 };
1657*4882a593Smuzhiyun 	char vec_name[64];
1658*4882a593Smuzhiyun 	struct testvec_config *cfg;
1659*4882a593Smuzhiyun 	char cfgname[TESTVEC_CONFIG_NAMELEN];
1660*4882a593Smuzhiyun 	int err;
1661*4882a593Smuzhiyun 
1662*4882a593Smuzhiyun 	if (noextratests)
1663*4882a593Smuzhiyun 		return 0;
1664*4882a593Smuzhiyun 
1665*4882a593Smuzhiyun 	if (!generic_driver) { /* Use default naming convention? */
1666*4882a593Smuzhiyun 		err = build_generic_driver_name(algname, _generic_driver);
1667*4882a593Smuzhiyun 		if (err)
1668*4882a593Smuzhiyun 			return err;
1669*4882a593Smuzhiyun 		generic_driver = _generic_driver;
1670*4882a593Smuzhiyun 	}
1671*4882a593Smuzhiyun 
1672*4882a593Smuzhiyun 	if (strcmp(generic_driver, driver) == 0) /* Already the generic impl? */
1673*4882a593Smuzhiyun 		return 0;
1674*4882a593Smuzhiyun 
1675*4882a593Smuzhiyun 	generic_tfm = crypto_alloc_shash(generic_driver, 0, 0);
1676*4882a593Smuzhiyun 	if (IS_ERR(generic_tfm)) {
1677*4882a593Smuzhiyun 		err = PTR_ERR(generic_tfm);
1678*4882a593Smuzhiyun 		if (err == -ENOENT) {
1679*4882a593Smuzhiyun 			pr_warn("alg: hash: skipping comparison tests for %s because %s is unavailable\n",
1680*4882a593Smuzhiyun 				driver, generic_driver);
1681*4882a593Smuzhiyun 			return 0;
1682*4882a593Smuzhiyun 		}
1683*4882a593Smuzhiyun 		pr_err("alg: hash: error allocating %s (generic impl of %s): %d\n",
1684*4882a593Smuzhiyun 		       generic_driver, algname, err);
1685*4882a593Smuzhiyun 		return err;
1686*4882a593Smuzhiyun 	}
1687*4882a593Smuzhiyun 
1688*4882a593Smuzhiyun 	cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
1689*4882a593Smuzhiyun 	if (!cfg) {
1690*4882a593Smuzhiyun 		err = -ENOMEM;
1691*4882a593Smuzhiyun 		goto out;
1692*4882a593Smuzhiyun 	}
1693*4882a593Smuzhiyun 
1694*4882a593Smuzhiyun 	generic_desc = kzalloc(sizeof(*desc) +
1695*4882a593Smuzhiyun 			       crypto_shash_descsize(generic_tfm), GFP_KERNEL);
1696*4882a593Smuzhiyun 	if (!generic_desc) {
1697*4882a593Smuzhiyun 		err = -ENOMEM;
1698*4882a593Smuzhiyun 		goto out;
1699*4882a593Smuzhiyun 	}
1700*4882a593Smuzhiyun 	generic_desc->tfm = generic_tfm;
1701*4882a593Smuzhiyun 
1702*4882a593Smuzhiyun 	/* Check the algorithm properties for consistency. */
1703*4882a593Smuzhiyun 
1704*4882a593Smuzhiyun 	if (digestsize != crypto_shash_digestsize(generic_tfm)) {
1705*4882a593Smuzhiyun 		pr_err("alg: hash: digestsize for %s (%u) doesn't match generic impl (%u)\n",
1706*4882a593Smuzhiyun 		       driver, digestsize,
1707*4882a593Smuzhiyun 		       crypto_shash_digestsize(generic_tfm));
1708*4882a593Smuzhiyun 		err = -EINVAL;
1709*4882a593Smuzhiyun 		goto out;
1710*4882a593Smuzhiyun 	}
1711*4882a593Smuzhiyun 
1712*4882a593Smuzhiyun 	if (blocksize != crypto_shash_blocksize(generic_tfm)) {
1713*4882a593Smuzhiyun 		pr_err("alg: hash: blocksize for %s (%u) doesn't match generic impl (%u)\n",
1714*4882a593Smuzhiyun 		       driver, blocksize, crypto_shash_blocksize(generic_tfm));
1715*4882a593Smuzhiyun 		err = -EINVAL;
1716*4882a593Smuzhiyun 		goto out;
1717*4882a593Smuzhiyun 	}
1718*4882a593Smuzhiyun 
1719*4882a593Smuzhiyun 	/*
1720*4882a593Smuzhiyun 	 * Now generate test vectors using the generic implementation, and test
1721*4882a593Smuzhiyun 	 * the other implementation against them.
1722*4882a593Smuzhiyun 	 */
1723*4882a593Smuzhiyun 
1724*4882a593Smuzhiyun 	vec.key = kmalloc(maxkeysize, GFP_KERNEL);
1725*4882a593Smuzhiyun 	vec.plaintext = kmalloc(maxdatasize, GFP_KERNEL);
1726*4882a593Smuzhiyun 	vec.digest = kmalloc(digestsize, GFP_KERNEL);
1727*4882a593Smuzhiyun 	if (!vec.key || !vec.plaintext || !vec.digest) {
1728*4882a593Smuzhiyun 		err = -ENOMEM;
1729*4882a593Smuzhiyun 		goto out;
1730*4882a593Smuzhiyun 	}
1731*4882a593Smuzhiyun 
1732*4882a593Smuzhiyun 	for (i = 0; i < fuzz_iterations * 8; i++) {
1733*4882a593Smuzhiyun 		generate_random_hash_testvec(generic_desc, &vec,
1734*4882a593Smuzhiyun 					     maxkeysize, maxdatasize,
1735*4882a593Smuzhiyun 					     vec_name, sizeof(vec_name));
1736*4882a593Smuzhiyun 		generate_random_testvec_config(cfg, cfgname, sizeof(cfgname));
1737*4882a593Smuzhiyun 
1738*4882a593Smuzhiyun 		err = test_hash_vec_cfg(driver, &vec, vec_name, cfg,
1739*4882a593Smuzhiyun 					req, desc, tsgl, hashstate);
1740*4882a593Smuzhiyun 		if (err)
1741*4882a593Smuzhiyun 			goto out;
1742*4882a593Smuzhiyun 		cond_resched();
1743*4882a593Smuzhiyun 	}
1744*4882a593Smuzhiyun 	err = 0;
1745*4882a593Smuzhiyun out:
1746*4882a593Smuzhiyun 	kfree(cfg);
1747*4882a593Smuzhiyun 	kfree(vec.key);
1748*4882a593Smuzhiyun 	kfree(vec.plaintext);
1749*4882a593Smuzhiyun 	kfree(vec.digest);
1750*4882a593Smuzhiyun 	crypto_free_shash(generic_tfm);
1751*4882a593Smuzhiyun 	kfree_sensitive(generic_desc);
1752*4882a593Smuzhiyun 	return err;
1753*4882a593Smuzhiyun }
1754*4882a593Smuzhiyun #else /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
test_hash_vs_generic_impl(const char * driver,const char * generic_driver,unsigned int maxkeysize,struct ahash_request * req,struct shash_desc * desc,struct test_sglist * tsgl,u8 * hashstate)1755*4882a593Smuzhiyun static int test_hash_vs_generic_impl(const char *driver,
1756*4882a593Smuzhiyun 				     const char *generic_driver,
1757*4882a593Smuzhiyun 				     unsigned int maxkeysize,
1758*4882a593Smuzhiyun 				     struct ahash_request *req,
1759*4882a593Smuzhiyun 				     struct shash_desc *desc,
1760*4882a593Smuzhiyun 				     struct test_sglist *tsgl,
1761*4882a593Smuzhiyun 				     u8 *hashstate)
1762*4882a593Smuzhiyun {
1763*4882a593Smuzhiyun 	return 0;
1764*4882a593Smuzhiyun }
1765*4882a593Smuzhiyun #endif /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
1766*4882a593Smuzhiyun 
alloc_shash(const char * driver,u32 type,u32 mask,struct crypto_shash ** tfm_ret,struct shash_desc ** desc_ret)1767*4882a593Smuzhiyun static int alloc_shash(const char *driver, u32 type, u32 mask,
1768*4882a593Smuzhiyun 		       struct crypto_shash **tfm_ret,
1769*4882a593Smuzhiyun 		       struct shash_desc **desc_ret)
1770*4882a593Smuzhiyun {
1771*4882a593Smuzhiyun 	struct crypto_shash *tfm;
1772*4882a593Smuzhiyun 	struct shash_desc *desc;
1773*4882a593Smuzhiyun 
1774*4882a593Smuzhiyun 	tfm = crypto_alloc_shash(driver, type, mask);
1775*4882a593Smuzhiyun 	if (IS_ERR(tfm)) {
1776*4882a593Smuzhiyun 		if (PTR_ERR(tfm) == -ENOENT) {
1777*4882a593Smuzhiyun 			/*
1778*4882a593Smuzhiyun 			 * This algorithm is only available through the ahash
1779*4882a593Smuzhiyun 			 * API, not the shash API, so skip the shash tests.
1780*4882a593Smuzhiyun 			 */
1781*4882a593Smuzhiyun 			return 0;
1782*4882a593Smuzhiyun 		}
1783*4882a593Smuzhiyun 		pr_err("alg: hash: failed to allocate shash transform for %s: %ld\n",
1784*4882a593Smuzhiyun 		       driver, PTR_ERR(tfm));
1785*4882a593Smuzhiyun 		return PTR_ERR(tfm);
1786*4882a593Smuzhiyun 	}
1787*4882a593Smuzhiyun 
1788*4882a593Smuzhiyun 	desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(tfm), GFP_KERNEL);
1789*4882a593Smuzhiyun 	if (!desc) {
1790*4882a593Smuzhiyun 		crypto_free_shash(tfm);
1791*4882a593Smuzhiyun 		return -ENOMEM;
1792*4882a593Smuzhiyun 	}
1793*4882a593Smuzhiyun 	desc->tfm = tfm;
1794*4882a593Smuzhiyun 
1795*4882a593Smuzhiyun 	*tfm_ret = tfm;
1796*4882a593Smuzhiyun 	*desc_ret = desc;
1797*4882a593Smuzhiyun 	return 0;
1798*4882a593Smuzhiyun }
1799*4882a593Smuzhiyun 
__alg_test_hash(const struct hash_testvec * vecs,unsigned int num_vecs,const char * driver,u32 type,u32 mask,const char * generic_driver,unsigned int maxkeysize)1800*4882a593Smuzhiyun static int __alg_test_hash(const struct hash_testvec *vecs,
1801*4882a593Smuzhiyun 			   unsigned int num_vecs, const char *driver,
1802*4882a593Smuzhiyun 			   u32 type, u32 mask,
1803*4882a593Smuzhiyun 			   const char *generic_driver, unsigned int maxkeysize)
1804*4882a593Smuzhiyun {
1805*4882a593Smuzhiyun 	struct crypto_ahash *atfm = NULL;
1806*4882a593Smuzhiyun 	struct ahash_request *req = NULL;
1807*4882a593Smuzhiyun 	struct crypto_shash *stfm = NULL;
1808*4882a593Smuzhiyun 	struct shash_desc *desc = NULL;
1809*4882a593Smuzhiyun 	struct test_sglist *tsgl = NULL;
1810*4882a593Smuzhiyun 	u8 *hashstate = NULL;
1811*4882a593Smuzhiyun 	unsigned int statesize;
1812*4882a593Smuzhiyun 	unsigned int i;
1813*4882a593Smuzhiyun 	int err;
1814*4882a593Smuzhiyun 
1815*4882a593Smuzhiyun 	/*
1816*4882a593Smuzhiyun 	 * Always test the ahash API.  This works regardless of whether the
1817*4882a593Smuzhiyun 	 * algorithm is implemented as ahash or shash.
1818*4882a593Smuzhiyun 	 */
1819*4882a593Smuzhiyun 
1820*4882a593Smuzhiyun 	atfm = crypto_alloc_ahash(driver, type, mask);
1821*4882a593Smuzhiyun 	if (IS_ERR(atfm)) {
1822*4882a593Smuzhiyun 		pr_err("alg: hash: failed to allocate transform for %s: %ld\n",
1823*4882a593Smuzhiyun 		       driver, PTR_ERR(atfm));
1824*4882a593Smuzhiyun 		return PTR_ERR(atfm);
1825*4882a593Smuzhiyun 	}
1826*4882a593Smuzhiyun 
1827*4882a593Smuzhiyun 	req = ahash_request_alloc(atfm, GFP_KERNEL);
1828*4882a593Smuzhiyun 	if (!req) {
1829*4882a593Smuzhiyun 		pr_err("alg: hash: failed to allocate request for %s\n",
1830*4882a593Smuzhiyun 		       driver);
1831*4882a593Smuzhiyun 		err = -ENOMEM;
1832*4882a593Smuzhiyun 		goto out;
1833*4882a593Smuzhiyun 	}
1834*4882a593Smuzhiyun 
1835*4882a593Smuzhiyun 	/*
1836*4882a593Smuzhiyun 	 * If available also test the shash API, to cover corner cases that may
1837*4882a593Smuzhiyun 	 * be missed by testing the ahash API only.
1838*4882a593Smuzhiyun 	 */
1839*4882a593Smuzhiyun 	err = alloc_shash(driver, type, mask, &stfm, &desc);
1840*4882a593Smuzhiyun 	if (err)
1841*4882a593Smuzhiyun 		goto out;
1842*4882a593Smuzhiyun 
1843*4882a593Smuzhiyun 	tsgl = kmalloc(sizeof(*tsgl), GFP_KERNEL);
1844*4882a593Smuzhiyun 	if (!tsgl || init_test_sglist(tsgl) != 0) {
1845*4882a593Smuzhiyun 		pr_err("alg: hash: failed to allocate test buffers for %s\n",
1846*4882a593Smuzhiyun 		       driver);
1847*4882a593Smuzhiyun 		kfree(tsgl);
1848*4882a593Smuzhiyun 		tsgl = NULL;
1849*4882a593Smuzhiyun 		err = -ENOMEM;
1850*4882a593Smuzhiyun 		goto out;
1851*4882a593Smuzhiyun 	}
1852*4882a593Smuzhiyun 
1853*4882a593Smuzhiyun 	statesize = crypto_ahash_statesize(atfm);
1854*4882a593Smuzhiyun 	if (stfm)
1855*4882a593Smuzhiyun 		statesize = max(statesize, crypto_shash_statesize(stfm));
1856*4882a593Smuzhiyun 	hashstate = kmalloc(statesize + TESTMGR_POISON_LEN, GFP_KERNEL);
1857*4882a593Smuzhiyun 	if (!hashstate) {
1858*4882a593Smuzhiyun 		pr_err("alg: hash: failed to allocate hash state buffer for %s\n",
1859*4882a593Smuzhiyun 		       driver);
1860*4882a593Smuzhiyun 		err = -ENOMEM;
1861*4882a593Smuzhiyun 		goto out;
1862*4882a593Smuzhiyun 	}
1863*4882a593Smuzhiyun 
1864*4882a593Smuzhiyun 	for (i = 0; i < num_vecs; i++) {
1865*4882a593Smuzhiyun 		err = test_hash_vec(driver, &vecs[i], i, req, desc, tsgl,
1866*4882a593Smuzhiyun 				    hashstate);
1867*4882a593Smuzhiyun 		if (err)
1868*4882a593Smuzhiyun 			goto out;
1869*4882a593Smuzhiyun 		cond_resched();
1870*4882a593Smuzhiyun 	}
1871*4882a593Smuzhiyun 	err = test_hash_vs_generic_impl(driver, generic_driver, maxkeysize, req,
1872*4882a593Smuzhiyun 					desc, tsgl, hashstate);
1873*4882a593Smuzhiyun out:
1874*4882a593Smuzhiyun 	kfree(hashstate);
1875*4882a593Smuzhiyun 	if (tsgl) {
1876*4882a593Smuzhiyun 		destroy_test_sglist(tsgl);
1877*4882a593Smuzhiyun 		kfree(tsgl);
1878*4882a593Smuzhiyun 	}
1879*4882a593Smuzhiyun 	kfree(desc);
1880*4882a593Smuzhiyun 	crypto_free_shash(stfm);
1881*4882a593Smuzhiyun 	ahash_request_free(req);
1882*4882a593Smuzhiyun 	crypto_free_ahash(atfm);
1883*4882a593Smuzhiyun 	return err;
1884*4882a593Smuzhiyun }
1885*4882a593Smuzhiyun 
alg_test_hash(const struct alg_test_desc * desc,const char * driver,u32 type,u32 mask)1886*4882a593Smuzhiyun static int alg_test_hash(const struct alg_test_desc *desc, const char *driver,
1887*4882a593Smuzhiyun 			 u32 type, u32 mask)
1888*4882a593Smuzhiyun {
1889*4882a593Smuzhiyun 	const struct hash_testvec *template = desc->suite.hash.vecs;
1890*4882a593Smuzhiyun 	unsigned int tcount = desc->suite.hash.count;
1891*4882a593Smuzhiyun 	unsigned int nr_unkeyed, nr_keyed;
1892*4882a593Smuzhiyun 	unsigned int maxkeysize = 0;
1893*4882a593Smuzhiyun 	int err;
1894*4882a593Smuzhiyun 
1895*4882a593Smuzhiyun 	/*
1896*4882a593Smuzhiyun 	 * For OPTIONAL_KEY algorithms, we have to do all the unkeyed tests
1897*4882a593Smuzhiyun 	 * first, before setting a key on the tfm.  To make this easier, we
1898*4882a593Smuzhiyun 	 * require that the unkeyed test vectors (if any) are listed first.
1899*4882a593Smuzhiyun 	 */
1900*4882a593Smuzhiyun 
1901*4882a593Smuzhiyun 	for (nr_unkeyed = 0; nr_unkeyed < tcount; nr_unkeyed++) {
1902*4882a593Smuzhiyun 		if (template[nr_unkeyed].ksize)
1903*4882a593Smuzhiyun 			break;
1904*4882a593Smuzhiyun 	}
1905*4882a593Smuzhiyun 	for (nr_keyed = 0; nr_unkeyed + nr_keyed < tcount; nr_keyed++) {
1906*4882a593Smuzhiyun 		if (!template[nr_unkeyed + nr_keyed].ksize) {
1907*4882a593Smuzhiyun 			pr_err("alg: hash: test vectors for %s out of order, "
1908*4882a593Smuzhiyun 			       "unkeyed ones must come first\n", desc->alg);
1909*4882a593Smuzhiyun 			return -EINVAL;
1910*4882a593Smuzhiyun 		}
1911*4882a593Smuzhiyun 		maxkeysize = max_t(unsigned int, maxkeysize,
1912*4882a593Smuzhiyun 				   template[nr_unkeyed + nr_keyed].ksize);
1913*4882a593Smuzhiyun 	}
1914*4882a593Smuzhiyun 
1915*4882a593Smuzhiyun 	err = 0;
1916*4882a593Smuzhiyun 	if (nr_unkeyed) {
1917*4882a593Smuzhiyun 		err = __alg_test_hash(template, nr_unkeyed, driver, type, mask,
1918*4882a593Smuzhiyun 				      desc->generic_driver, maxkeysize);
1919*4882a593Smuzhiyun 		template += nr_unkeyed;
1920*4882a593Smuzhiyun 	}
1921*4882a593Smuzhiyun 
1922*4882a593Smuzhiyun 	if (!err && nr_keyed)
1923*4882a593Smuzhiyun 		err = __alg_test_hash(template, nr_keyed, driver, type, mask,
1924*4882a593Smuzhiyun 				      desc->generic_driver, maxkeysize);
1925*4882a593Smuzhiyun 
1926*4882a593Smuzhiyun 	return err;
1927*4882a593Smuzhiyun }
1928*4882a593Smuzhiyun 
test_aead_vec_cfg(const char * driver,int enc,const struct aead_testvec * vec,const char * vec_name,const struct testvec_config * cfg,struct aead_request * req,struct cipher_test_sglists * tsgls)1929*4882a593Smuzhiyun static int test_aead_vec_cfg(const char *driver, int enc,
1930*4882a593Smuzhiyun 			     const struct aead_testvec *vec,
1931*4882a593Smuzhiyun 			     const char *vec_name,
1932*4882a593Smuzhiyun 			     const struct testvec_config *cfg,
1933*4882a593Smuzhiyun 			     struct aead_request *req,
1934*4882a593Smuzhiyun 			     struct cipher_test_sglists *tsgls)
1935*4882a593Smuzhiyun {
1936*4882a593Smuzhiyun 	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
1937*4882a593Smuzhiyun 	const unsigned int alignmask = crypto_aead_alignmask(tfm);
1938*4882a593Smuzhiyun 	const unsigned int ivsize = crypto_aead_ivsize(tfm);
1939*4882a593Smuzhiyun 	const unsigned int authsize = vec->clen - vec->plen;
1940*4882a593Smuzhiyun 	const u32 req_flags = CRYPTO_TFM_REQ_MAY_BACKLOG | cfg->req_flags;
1941*4882a593Smuzhiyun 	const char *op = enc ? "encryption" : "decryption";
1942*4882a593Smuzhiyun 	DECLARE_CRYPTO_WAIT(wait);
1943*4882a593Smuzhiyun 	u8 _iv[3 * (MAX_ALGAPI_ALIGNMASK + 1) + MAX_IVLEN];
1944*4882a593Smuzhiyun 	u8 *iv = PTR_ALIGN(&_iv[0], 2 * (MAX_ALGAPI_ALIGNMASK + 1)) +
1945*4882a593Smuzhiyun 		 cfg->iv_offset +
1946*4882a593Smuzhiyun 		 (cfg->iv_offset_relative_to_alignmask ? alignmask : 0);
1947*4882a593Smuzhiyun 	struct kvec input[2];
1948*4882a593Smuzhiyun 	int err;
1949*4882a593Smuzhiyun 
1950*4882a593Smuzhiyun 	/* Set the key */
1951*4882a593Smuzhiyun 	if (vec->wk)
1952*4882a593Smuzhiyun 		crypto_aead_set_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS);
1953*4882a593Smuzhiyun 	else
1954*4882a593Smuzhiyun 		crypto_aead_clear_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS);
1955*4882a593Smuzhiyun 
1956*4882a593Smuzhiyun 	err = do_setkey(crypto_aead_setkey, tfm, vec->key, vec->klen,
1957*4882a593Smuzhiyun 			cfg, alignmask);
1958*4882a593Smuzhiyun 	if (err && err != vec->setkey_error) {
1959*4882a593Smuzhiyun 		pr_err("alg: aead: %s setkey failed on test vector %s; expected_error=%d, actual_error=%d, flags=%#x\n",
1960*4882a593Smuzhiyun 		       driver, vec_name, vec->setkey_error, err,
1961*4882a593Smuzhiyun 		       crypto_aead_get_flags(tfm));
1962*4882a593Smuzhiyun 		return err;
1963*4882a593Smuzhiyun 	}
1964*4882a593Smuzhiyun 	if (!err && vec->setkey_error) {
1965*4882a593Smuzhiyun 		pr_err("alg: aead: %s setkey unexpectedly succeeded on test vector %s; expected_error=%d\n",
1966*4882a593Smuzhiyun 		       driver, vec_name, vec->setkey_error);
1967*4882a593Smuzhiyun 		return -EINVAL;
1968*4882a593Smuzhiyun 	}
1969*4882a593Smuzhiyun 
1970*4882a593Smuzhiyun 	/* Set the authentication tag size */
1971*4882a593Smuzhiyun 	err = crypto_aead_setauthsize(tfm, authsize);
1972*4882a593Smuzhiyun 	if (err && err != vec->setauthsize_error) {
1973*4882a593Smuzhiyun 		pr_err("alg: aead: %s setauthsize failed on test vector %s; expected_error=%d, actual_error=%d\n",
1974*4882a593Smuzhiyun 		       driver, vec_name, vec->setauthsize_error, err);
1975*4882a593Smuzhiyun 		return err;
1976*4882a593Smuzhiyun 	}
1977*4882a593Smuzhiyun 	if (!err && vec->setauthsize_error) {
1978*4882a593Smuzhiyun 		pr_err("alg: aead: %s setauthsize unexpectedly succeeded on test vector %s; expected_error=%d\n",
1979*4882a593Smuzhiyun 		       driver, vec_name, vec->setauthsize_error);
1980*4882a593Smuzhiyun 		return -EINVAL;
1981*4882a593Smuzhiyun 	}
1982*4882a593Smuzhiyun 
1983*4882a593Smuzhiyun 	if (vec->setkey_error || vec->setauthsize_error)
1984*4882a593Smuzhiyun 		return 0;
1985*4882a593Smuzhiyun 
1986*4882a593Smuzhiyun 	/* The IV must be copied to a buffer, as the algorithm may modify it */
1987*4882a593Smuzhiyun 	if (WARN_ON(ivsize > MAX_IVLEN))
1988*4882a593Smuzhiyun 		return -EINVAL;
1989*4882a593Smuzhiyun 	if (vec->iv)
1990*4882a593Smuzhiyun 		memcpy(iv, vec->iv, ivsize);
1991*4882a593Smuzhiyun 	else
1992*4882a593Smuzhiyun 		memset(iv, 0, ivsize);
1993*4882a593Smuzhiyun 
1994*4882a593Smuzhiyun 	/* Build the src/dst scatterlists */
1995*4882a593Smuzhiyun 	input[0].iov_base = (void *)vec->assoc;
1996*4882a593Smuzhiyun 	input[0].iov_len = vec->alen;
1997*4882a593Smuzhiyun 	input[1].iov_base = enc ? (void *)vec->ptext : (void *)vec->ctext;
1998*4882a593Smuzhiyun 	input[1].iov_len = enc ? vec->plen : vec->clen;
1999*4882a593Smuzhiyun 	err = build_cipher_test_sglists(tsgls, cfg, alignmask,
2000*4882a593Smuzhiyun 					vec->alen + (enc ? vec->plen :
2001*4882a593Smuzhiyun 						     vec->clen),
2002*4882a593Smuzhiyun 					vec->alen + (enc ? vec->clen :
2003*4882a593Smuzhiyun 						     vec->plen),
2004*4882a593Smuzhiyun 					input, 2);
2005*4882a593Smuzhiyun 	if (err) {
2006*4882a593Smuzhiyun 		pr_err("alg: aead: %s %s: error preparing scatterlists for test vector %s, cfg=\"%s\"\n",
2007*4882a593Smuzhiyun 		       driver, op, vec_name, cfg->name);
2008*4882a593Smuzhiyun 		return err;
2009*4882a593Smuzhiyun 	}
2010*4882a593Smuzhiyun 
2011*4882a593Smuzhiyun 	/* Do the actual encryption or decryption */
2012*4882a593Smuzhiyun 	testmgr_poison(req->__ctx, crypto_aead_reqsize(tfm));
2013*4882a593Smuzhiyun 	aead_request_set_callback(req, req_flags, crypto_req_done, &wait);
2014*4882a593Smuzhiyun 	aead_request_set_crypt(req, tsgls->src.sgl_ptr, tsgls->dst.sgl_ptr,
2015*4882a593Smuzhiyun 			       enc ? vec->plen : vec->clen, iv);
2016*4882a593Smuzhiyun 	aead_request_set_ad(req, vec->alen);
2017*4882a593Smuzhiyun 	if (cfg->nosimd)
2018*4882a593Smuzhiyun 		crypto_disable_simd_for_test();
2019*4882a593Smuzhiyun 	err = enc ? crypto_aead_encrypt(req) : crypto_aead_decrypt(req);
2020*4882a593Smuzhiyun 	if (cfg->nosimd)
2021*4882a593Smuzhiyun 		crypto_reenable_simd_for_test();
2022*4882a593Smuzhiyun 	err = crypto_wait_req(err, &wait);
2023*4882a593Smuzhiyun 
2024*4882a593Smuzhiyun 	/* Check that the algorithm didn't overwrite things it shouldn't have */
2025*4882a593Smuzhiyun 	if (req->cryptlen != (enc ? vec->plen : vec->clen) ||
2026*4882a593Smuzhiyun 	    req->assoclen != vec->alen ||
2027*4882a593Smuzhiyun 	    req->iv != iv ||
2028*4882a593Smuzhiyun 	    req->src != tsgls->src.sgl_ptr ||
2029*4882a593Smuzhiyun 	    req->dst != tsgls->dst.sgl_ptr ||
2030*4882a593Smuzhiyun 	    crypto_aead_reqtfm(req) != tfm ||
2031*4882a593Smuzhiyun 	    req->base.complete != crypto_req_done ||
2032*4882a593Smuzhiyun 	    req->base.flags != req_flags ||
2033*4882a593Smuzhiyun 	    req->base.data != &wait) {
2034*4882a593Smuzhiyun 		pr_err("alg: aead: %s %s corrupted request struct on test vector %s, cfg=\"%s\"\n",
2035*4882a593Smuzhiyun 		       driver, op, vec_name, cfg->name);
2036*4882a593Smuzhiyun 		if (req->cryptlen != (enc ? vec->plen : vec->clen))
2037*4882a593Smuzhiyun 			pr_err("alg: aead: changed 'req->cryptlen'\n");
2038*4882a593Smuzhiyun 		if (req->assoclen != vec->alen)
2039*4882a593Smuzhiyun 			pr_err("alg: aead: changed 'req->assoclen'\n");
2040*4882a593Smuzhiyun 		if (req->iv != iv)
2041*4882a593Smuzhiyun 			pr_err("alg: aead: changed 'req->iv'\n");
2042*4882a593Smuzhiyun 		if (req->src != tsgls->src.sgl_ptr)
2043*4882a593Smuzhiyun 			pr_err("alg: aead: changed 'req->src'\n");
2044*4882a593Smuzhiyun 		if (req->dst != tsgls->dst.sgl_ptr)
2045*4882a593Smuzhiyun 			pr_err("alg: aead: changed 'req->dst'\n");
2046*4882a593Smuzhiyun 		if (crypto_aead_reqtfm(req) != tfm)
2047*4882a593Smuzhiyun 			pr_err("alg: aead: changed 'req->base.tfm'\n");
2048*4882a593Smuzhiyun 		if (req->base.complete != crypto_req_done)
2049*4882a593Smuzhiyun 			pr_err("alg: aead: changed 'req->base.complete'\n");
2050*4882a593Smuzhiyun 		if (req->base.flags != req_flags)
2051*4882a593Smuzhiyun 			pr_err("alg: aead: changed 'req->base.flags'\n");
2052*4882a593Smuzhiyun 		if (req->base.data != &wait)
2053*4882a593Smuzhiyun 			pr_err("alg: aead: changed 'req->base.data'\n");
2054*4882a593Smuzhiyun 		return -EINVAL;
2055*4882a593Smuzhiyun 	}
2056*4882a593Smuzhiyun 	if (is_test_sglist_corrupted(&tsgls->src)) {
2057*4882a593Smuzhiyun 		pr_err("alg: aead: %s %s corrupted src sgl on test vector %s, cfg=\"%s\"\n",
2058*4882a593Smuzhiyun 		       driver, op, vec_name, cfg->name);
2059*4882a593Smuzhiyun 		return -EINVAL;
2060*4882a593Smuzhiyun 	}
2061*4882a593Smuzhiyun 	if (tsgls->dst.sgl_ptr != tsgls->src.sgl &&
2062*4882a593Smuzhiyun 	    is_test_sglist_corrupted(&tsgls->dst)) {
2063*4882a593Smuzhiyun 		pr_err("alg: aead: %s %s corrupted dst sgl on test vector %s, cfg=\"%s\"\n",
2064*4882a593Smuzhiyun 		       driver, op, vec_name, cfg->name);
2065*4882a593Smuzhiyun 		return -EINVAL;
2066*4882a593Smuzhiyun 	}
2067*4882a593Smuzhiyun 
2068*4882a593Smuzhiyun 	/* Check for unexpected success or failure, or wrong error code */
2069*4882a593Smuzhiyun 	if ((err == 0 && vec->novrfy) ||
2070*4882a593Smuzhiyun 	    (err != vec->crypt_error && !(err == -EBADMSG && vec->novrfy))) {
2071*4882a593Smuzhiyun 		char expected_error[32];
2072*4882a593Smuzhiyun 
2073*4882a593Smuzhiyun 		if (vec->novrfy &&
2074*4882a593Smuzhiyun 		    vec->crypt_error != 0 && vec->crypt_error != -EBADMSG)
2075*4882a593Smuzhiyun 			sprintf(expected_error, "-EBADMSG or %d",
2076*4882a593Smuzhiyun 				vec->crypt_error);
2077*4882a593Smuzhiyun 		else if (vec->novrfy)
2078*4882a593Smuzhiyun 			sprintf(expected_error, "-EBADMSG");
2079*4882a593Smuzhiyun 		else
2080*4882a593Smuzhiyun 			sprintf(expected_error, "%d", vec->crypt_error);
2081*4882a593Smuzhiyun 		if (err) {
2082*4882a593Smuzhiyun 			pr_err("alg: aead: %s %s failed on test vector %s; expected_error=%s, actual_error=%d, cfg=\"%s\"\n",
2083*4882a593Smuzhiyun 			       driver, op, vec_name, expected_error, err,
2084*4882a593Smuzhiyun 			       cfg->name);
2085*4882a593Smuzhiyun 			return err;
2086*4882a593Smuzhiyun 		}
2087*4882a593Smuzhiyun 		pr_err("alg: aead: %s %s unexpectedly succeeded on test vector %s; expected_error=%s, cfg=\"%s\"\n",
2088*4882a593Smuzhiyun 		       driver, op, vec_name, expected_error, cfg->name);
2089*4882a593Smuzhiyun 		return -EINVAL;
2090*4882a593Smuzhiyun 	}
2091*4882a593Smuzhiyun 	if (err) /* Expectedly failed. */
2092*4882a593Smuzhiyun 		return 0;
2093*4882a593Smuzhiyun 
2094*4882a593Smuzhiyun 	/* Check for the correct output (ciphertext or plaintext) */
2095*4882a593Smuzhiyun 	err = verify_correct_output(&tsgls->dst, enc ? vec->ctext : vec->ptext,
2096*4882a593Smuzhiyun 				    enc ? vec->clen : vec->plen,
2097*4882a593Smuzhiyun 				    vec->alen, enc || !cfg->inplace);
2098*4882a593Smuzhiyun 	if (err == -EOVERFLOW) {
2099*4882a593Smuzhiyun 		pr_err("alg: aead: %s %s overran dst buffer on test vector %s, cfg=\"%s\"\n",
2100*4882a593Smuzhiyun 		       driver, op, vec_name, cfg->name);
2101*4882a593Smuzhiyun 		return err;
2102*4882a593Smuzhiyun 	}
2103*4882a593Smuzhiyun 	if (err) {
2104*4882a593Smuzhiyun 		pr_err("alg: aead: %s %s test failed (wrong result) on test vector %s, cfg=\"%s\"\n",
2105*4882a593Smuzhiyun 		       driver, op, vec_name, cfg->name);
2106*4882a593Smuzhiyun 		return err;
2107*4882a593Smuzhiyun 	}
2108*4882a593Smuzhiyun 
2109*4882a593Smuzhiyun 	return 0;
2110*4882a593Smuzhiyun }
2111*4882a593Smuzhiyun 
test_aead_vec(const char * driver,int enc,const struct aead_testvec * vec,unsigned int vec_num,struct aead_request * req,struct cipher_test_sglists * tsgls)2112*4882a593Smuzhiyun static int test_aead_vec(const char *driver, int enc,
2113*4882a593Smuzhiyun 			 const struct aead_testvec *vec, unsigned int vec_num,
2114*4882a593Smuzhiyun 			 struct aead_request *req,
2115*4882a593Smuzhiyun 			 struct cipher_test_sglists *tsgls)
2116*4882a593Smuzhiyun {
2117*4882a593Smuzhiyun 	char vec_name[16];
2118*4882a593Smuzhiyun 	unsigned int i;
2119*4882a593Smuzhiyun 	int err;
2120*4882a593Smuzhiyun 
2121*4882a593Smuzhiyun 	if (enc && vec->novrfy)
2122*4882a593Smuzhiyun 		return 0;
2123*4882a593Smuzhiyun 
2124*4882a593Smuzhiyun 	sprintf(vec_name, "%u", vec_num);
2125*4882a593Smuzhiyun 
2126*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(default_cipher_testvec_configs); i++) {
2127*4882a593Smuzhiyun 		err = test_aead_vec_cfg(driver, enc, vec, vec_name,
2128*4882a593Smuzhiyun 					&default_cipher_testvec_configs[i],
2129*4882a593Smuzhiyun 					req, tsgls);
2130*4882a593Smuzhiyun 		if (err)
2131*4882a593Smuzhiyun 			return err;
2132*4882a593Smuzhiyun 	}
2133*4882a593Smuzhiyun 
2134*4882a593Smuzhiyun #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
2135*4882a593Smuzhiyun 	if (!noextratests) {
2136*4882a593Smuzhiyun 		struct testvec_config cfg;
2137*4882a593Smuzhiyun 		char cfgname[TESTVEC_CONFIG_NAMELEN];
2138*4882a593Smuzhiyun 
2139*4882a593Smuzhiyun 		for (i = 0; i < fuzz_iterations; i++) {
2140*4882a593Smuzhiyun 			generate_random_testvec_config(&cfg, cfgname,
2141*4882a593Smuzhiyun 						       sizeof(cfgname));
2142*4882a593Smuzhiyun 			err = test_aead_vec_cfg(driver, enc, vec, vec_name,
2143*4882a593Smuzhiyun 						&cfg, req, tsgls);
2144*4882a593Smuzhiyun 			if (err)
2145*4882a593Smuzhiyun 				return err;
2146*4882a593Smuzhiyun 			cond_resched();
2147*4882a593Smuzhiyun 		}
2148*4882a593Smuzhiyun 	}
2149*4882a593Smuzhiyun #endif
2150*4882a593Smuzhiyun 	return 0;
2151*4882a593Smuzhiyun }
2152*4882a593Smuzhiyun 
2153*4882a593Smuzhiyun #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
2154*4882a593Smuzhiyun 
2155*4882a593Smuzhiyun struct aead_extra_tests_ctx {
2156*4882a593Smuzhiyun 	struct aead_request *req;
2157*4882a593Smuzhiyun 	struct crypto_aead *tfm;
2158*4882a593Smuzhiyun 	const char *driver;
2159*4882a593Smuzhiyun 	const struct alg_test_desc *test_desc;
2160*4882a593Smuzhiyun 	struct cipher_test_sglists *tsgls;
2161*4882a593Smuzhiyun 	unsigned int maxdatasize;
2162*4882a593Smuzhiyun 	unsigned int maxkeysize;
2163*4882a593Smuzhiyun 
2164*4882a593Smuzhiyun 	struct aead_testvec vec;
2165*4882a593Smuzhiyun 	char vec_name[64];
2166*4882a593Smuzhiyun 	char cfgname[TESTVEC_CONFIG_NAMELEN];
2167*4882a593Smuzhiyun 	struct testvec_config cfg;
2168*4882a593Smuzhiyun };
2169*4882a593Smuzhiyun 
2170*4882a593Smuzhiyun /*
2171*4882a593Smuzhiyun  * Make at least one random change to a (ciphertext, AAD) pair.  "Ciphertext"
2172*4882a593Smuzhiyun  * here means the full ciphertext including the authentication tag.  The
2173*4882a593Smuzhiyun  * authentication tag (and hence also the ciphertext) is assumed to be nonempty.
2174*4882a593Smuzhiyun  */
mutate_aead_message(struct aead_testvec * vec,bool aad_iv,unsigned int ivsize)2175*4882a593Smuzhiyun static void mutate_aead_message(struct aead_testvec *vec, bool aad_iv,
2176*4882a593Smuzhiyun 				unsigned int ivsize)
2177*4882a593Smuzhiyun {
2178*4882a593Smuzhiyun 	const unsigned int aad_tail_size = aad_iv ? ivsize : 0;
2179*4882a593Smuzhiyun 	const unsigned int authsize = vec->clen - vec->plen;
2180*4882a593Smuzhiyun 
2181*4882a593Smuzhiyun 	if (prandom_u32() % 2 == 0 && vec->alen > aad_tail_size) {
2182*4882a593Smuzhiyun 		 /* Mutate the AAD */
2183*4882a593Smuzhiyun 		flip_random_bit((u8 *)vec->assoc, vec->alen - aad_tail_size);
2184*4882a593Smuzhiyun 		if (prandom_u32() % 2 == 0)
2185*4882a593Smuzhiyun 			return;
2186*4882a593Smuzhiyun 	}
2187*4882a593Smuzhiyun 	if (prandom_u32() % 2 == 0) {
2188*4882a593Smuzhiyun 		/* Mutate auth tag (assuming it's at the end of ciphertext) */
2189*4882a593Smuzhiyun 		flip_random_bit((u8 *)vec->ctext + vec->plen, authsize);
2190*4882a593Smuzhiyun 	} else {
2191*4882a593Smuzhiyun 		/* Mutate any part of the ciphertext */
2192*4882a593Smuzhiyun 		flip_random_bit((u8 *)vec->ctext, vec->clen);
2193*4882a593Smuzhiyun 	}
2194*4882a593Smuzhiyun }
2195*4882a593Smuzhiyun 
2196*4882a593Smuzhiyun /*
2197*4882a593Smuzhiyun  * Minimum authentication tag size in bytes at which we assume that we can
2198*4882a593Smuzhiyun  * reliably generate inauthentic messages, i.e. not generate an authentic
2199*4882a593Smuzhiyun  * message by chance.
2200*4882a593Smuzhiyun  */
2201*4882a593Smuzhiyun #define MIN_COLLISION_FREE_AUTHSIZE 8
2202*4882a593Smuzhiyun 
generate_aead_message(struct aead_request * req,const struct aead_test_suite * suite,struct aead_testvec * vec,bool prefer_inauthentic)2203*4882a593Smuzhiyun static void generate_aead_message(struct aead_request *req,
2204*4882a593Smuzhiyun 				  const struct aead_test_suite *suite,
2205*4882a593Smuzhiyun 				  struct aead_testvec *vec,
2206*4882a593Smuzhiyun 				  bool prefer_inauthentic)
2207*4882a593Smuzhiyun {
2208*4882a593Smuzhiyun 	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
2209*4882a593Smuzhiyun 	const unsigned int ivsize = crypto_aead_ivsize(tfm);
2210*4882a593Smuzhiyun 	const unsigned int authsize = vec->clen - vec->plen;
2211*4882a593Smuzhiyun 	const bool inauthentic = (authsize >= MIN_COLLISION_FREE_AUTHSIZE) &&
2212*4882a593Smuzhiyun 				 (prefer_inauthentic || prandom_u32() % 4 == 0);
2213*4882a593Smuzhiyun 
2214*4882a593Smuzhiyun 	/* Generate the AAD. */
2215*4882a593Smuzhiyun 	generate_random_bytes((u8 *)vec->assoc, vec->alen);
2216*4882a593Smuzhiyun 	if (suite->aad_iv && vec->alen >= ivsize)
2217*4882a593Smuzhiyun 		/* Avoid implementation-defined behavior. */
2218*4882a593Smuzhiyun 		memcpy((u8 *)vec->assoc + vec->alen - ivsize, vec->iv, ivsize);
2219*4882a593Smuzhiyun 
2220*4882a593Smuzhiyun 	if (inauthentic && prandom_u32() % 2 == 0) {
2221*4882a593Smuzhiyun 		/* Generate a random ciphertext. */
2222*4882a593Smuzhiyun 		generate_random_bytes((u8 *)vec->ctext, vec->clen);
2223*4882a593Smuzhiyun 	} else {
2224*4882a593Smuzhiyun 		int i = 0;
2225*4882a593Smuzhiyun 		struct scatterlist src[2], dst;
2226*4882a593Smuzhiyun 		u8 iv[MAX_IVLEN];
2227*4882a593Smuzhiyun 		DECLARE_CRYPTO_WAIT(wait);
2228*4882a593Smuzhiyun 
2229*4882a593Smuzhiyun 		/* Generate a random plaintext and encrypt it. */
2230*4882a593Smuzhiyun 		sg_init_table(src, 2);
2231*4882a593Smuzhiyun 		if (vec->alen)
2232*4882a593Smuzhiyun 			sg_set_buf(&src[i++], vec->assoc, vec->alen);
2233*4882a593Smuzhiyun 		if (vec->plen) {
2234*4882a593Smuzhiyun 			generate_random_bytes((u8 *)vec->ptext, vec->plen);
2235*4882a593Smuzhiyun 			sg_set_buf(&src[i++], vec->ptext, vec->plen);
2236*4882a593Smuzhiyun 		}
2237*4882a593Smuzhiyun 		sg_init_one(&dst, vec->ctext, vec->alen + vec->clen);
2238*4882a593Smuzhiyun 		memcpy(iv, vec->iv, ivsize);
2239*4882a593Smuzhiyun 		aead_request_set_callback(req, 0, crypto_req_done, &wait);
2240*4882a593Smuzhiyun 		aead_request_set_crypt(req, src, &dst, vec->plen, iv);
2241*4882a593Smuzhiyun 		aead_request_set_ad(req, vec->alen);
2242*4882a593Smuzhiyun 		vec->crypt_error = crypto_wait_req(crypto_aead_encrypt(req),
2243*4882a593Smuzhiyun 						   &wait);
2244*4882a593Smuzhiyun 		/* If encryption failed, we're done. */
2245*4882a593Smuzhiyun 		if (vec->crypt_error != 0)
2246*4882a593Smuzhiyun 			return;
2247*4882a593Smuzhiyun 		memmove((u8 *)vec->ctext, vec->ctext + vec->alen, vec->clen);
2248*4882a593Smuzhiyun 		if (!inauthentic)
2249*4882a593Smuzhiyun 			return;
2250*4882a593Smuzhiyun 		/*
2251*4882a593Smuzhiyun 		 * Mutate the authentic (ciphertext, AAD) pair to get an
2252*4882a593Smuzhiyun 		 * inauthentic one.
2253*4882a593Smuzhiyun 		 */
2254*4882a593Smuzhiyun 		mutate_aead_message(vec, suite->aad_iv, ivsize);
2255*4882a593Smuzhiyun 	}
2256*4882a593Smuzhiyun 	vec->novrfy = 1;
2257*4882a593Smuzhiyun 	if (suite->einval_allowed)
2258*4882a593Smuzhiyun 		vec->crypt_error = -EINVAL;
2259*4882a593Smuzhiyun }
2260*4882a593Smuzhiyun 
2261*4882a593Smuzhiyun /*
2262*4882a593Smuzhiyun  * Generate an AEAD test vector 'vec' using the implementation specified by
2263*4882a593Smuzhiyun  * 'req'.  The buffers in 'vec' must already be allocated.
2264*4882a593Smuzhiyun  *
2265*4882a593Smuzhiyun  * If 'prefer_inauthentic' is true, then this function will generate inauthentic
2266*4882a593Smuzhiyun  * test vectors (i.e. vectors with 'vec->novrfy=1') more often.
2267*4882a593Smuzhiyun  */
generate_random_aead_testvec(struct aead_request * req,struct aead_testvec * vec,const struct aead_test_suite * suite,unsigned int maxkeysize,unsigned int maxdatasize,char * name,size_t max_namelen,bool prefer_inauthentic)2268*4882a593Smuzhiyun static void generate_random_aead_testvec(struct aead_request *req,
2269*4882a593Smuzhiyun 					 struct aead_testvec *vec,
2270*4882a593Smuzhiyun 					 const struct aead_test_suite *suite,
2271*4882a593Smuzhiyun 					 unsigned int maxkeysize,
2272*4882a593Smuzhiyun 					 unsigned int maxdatasize,
2273*4882a593Smuzhiyun 					 char *name, size_t max_namelen,
2274*4882a593Smuzhiyun 					 bool prefer_inauthentic)
2275*4882a593Smuzhiyun {
2276*4882a593Smuzhiyun 	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
2277*4882a593Smuzhiyun 	const unsigned int ivsize = crypto_aead_ivsize(tfm);
2278*4882a593Smuzhiyun 	const unsigned int maxauthsize = crypto_aead_maxauthsize(tfm);
2279*4882a593Smuzhiyun 	unsigned int authsize;
2280*4882a593Smuzhiyun 	unsigned int total_len;
2281*4882a593Smuzhiyun 
2282*4882a593Smuzhiyun 	/* Key: length in [0, maxkeysize], but usually choose maxkeysize */
2283*4882a593Smuzhiyun 	vec->klen = maxkeysize;
2284*4882a593Smuzhiyun 	if (prandom_u32() % 4 == 0)
2285*4882a593Smuzhiyun 		vec->klen = prandom_u32() % (maxkeysize + 1);
2286*4882a593Smuzhiyun 	generate_random_bytes((u8 *)vec->key, vec->klen);
2287*4882a593Smuzhiyun 	vec->setkey_error = crypto_aead_setkey(tfm, vec->key, vec->klen);
2288*4882a593Smuzhiyun 
2289*4882a593Smuzhiyun 	/* IV */
2290*4882a593Smuzhiyun 	generate_random_bytes((u8 *)vec->iv, ivsize);
2291*4882a593Smuzhiyun 
2292*4882a593Smuzhiyun 	/* Tag length: in [0, maxauthsize], but usually choose maxauthsize */
2293*4882a593Smuzhiyun 	authsize = maxauthsize;
2294*4882a593Smuzhiyun 	if (prandom_u32() % 4 == 0)
2295*4882a593Smuzhiyun 		authsize = prandom_u32() % (maxauthsize + 1);
2296*4882a593Smuzhiyun 	if (prefer_inauthentic && authsize < MIN_COLLISION_FREE_AUTHSIZE)
2297*4882a593Smuzhiyun 		authsize = MIN_COLLISION_FREE_AUTHSIZE;
2298*4882a593Smuzhiyun 	if (WARN_ON(authsize > maxdatasize))
2299*4882a593Smuzhiyun 		authsize = maxdatasize;
2300*4882a593Smuzhiyun 	maxdatasize -= authsize;
2301*4882a593Smuzhiyun 	vec->setauthsize_error = crypto_aead_setauthsize(tfm, authsize);
2302*4882a593Smuzhiyun 
2303*4882a593Smuzhiyun 	/* AAD, plaintext, and ciphertext lengths */
2304*4882a593Smuzhiyun 	total_len = generate_random_length(maxdatasize);
2305*4882a593Smuzhiyun 	if (prandom_u32() % 4 == 0)
2306*4882a593Smuzhiyun 		vec->alen = 0;
2307*4882a593Smuzhiyun 	else
2308*4882a593Smuzhiyun 		vec->alen = generate_random_length(total_len);
2309*4882a593Smuzhiyun 	vec->plen = total_len - vec->alen;
2310*4882a593Smuzhiyun 	vec->clen = vec->plen + authsize;
2311*4882a593Smuzhiyun 
2312*4882a593Smuzhiyun 	/*
2313*4882a593Smuzhiyun 	 * Generate the AAD, plaintext, and ciphertext.  Not applicable if the
2314*4882a593Smuzhiyun 	 * key or the authentication tag size couldn't be set.
2315*4882a593Smuzhiyun 	 */
2316*4882a593Smuzhiyun 	vec->novrfy = 0;
2317*4882a593Smuzhiyun 	vec->crypt_error = 0;
2318*4882a593Smuzhiyun 	if (vec->setkey_error == 0 && vec->setauthsize_error == 0)
2319*4882a593Smuzhiyun 		generate_aead_message(req, suite, vec, prefer_inauthentic);
2320*4882a593Smuzhiyun 	snprintf(name, max_namelen,
2321*4882a593Smuzhiyun 		 "\"random: alen=%u plen=%u authsize=%u klen=%u novrfy=%d\"",
2322*4882a593Smuzhiyun 		 vec->alen, vec->plen, authsize, vec->klen, vec->novrfy);
2323*4882a593Smuzhiyun }
2324*4882a593Smuzhiyun 
try_to_generate_inauthentic_testvec(struct aead_extra_tests_ctx * ctx)2325*4882a593Smuzhiyun static void try_to_generate_inauthentic_testvec(
2326*4882a593Smuzhiyun 					struct aead_extra_tests_ctx *ctx)
2327*4882a593Smuzhiyun {
2328*4882a593Smuzhiyun 	int i;
2329*4882a593Smuzhiyun 
2330*4882a593Smuzhiyun 	for (i = 0; i < 10; i++) {
2331*4882a593Smuzhiyun 		generate_random_aead_testvec(ctx->req, &ctx->vec,
2332*4882a593Smuzhiyun 					     &ctx->test_desc->suite.aead,
2333*4882a593Smuzhiyun 					     ctx->maxkeysize, ctx->maxdatasize,
2334*4882a593Smuzhiyun 					     ctx->vec_name,
2335*4882a593Smuzhiyun 					     sizeof(ctx->vec_name), true);
2336*4882a593Smuzhiyun 		if (ctx->vec.novrfy)
2337*4882a593Smuzhiyun 			return;
2338*4882a593Smuzhiyun 	}
2339*4882a593Smuzhiyun }
2340*4882a593Smuzhiyun 
2341*4882a593Smuzhiyun /*
2342*4882a593Smuzhiyun  * Generate inauthentic test vectors (i.e. ciphertext, AAD pairs that aren't the
2343*4882a593Smuzhiyun  * result of an encryption with the key) and verify that decryption fails.
2344*4882a593Smuzhiyun  */
test_aead_inauthentic_inputs(struct aead_extra_tests_ctx * ctx)2345*4882a593Smuzhiyun static int test_aead_inauthentic_inputs(struct aead_extra_tests_ctx *ctx)
2346*4882a593Smuzhiyun {
2347*4882a593Smuzhiyun 	unsigned int i;
2348*4882a593Smuzhiyun 	int err;
2349*4882a593Smuzhiyun 
2350*4882a593Smuzhiyun 	for (i = 0; i < fuzz_iterations * 8; i++) {
2351*4882a593Smuzhiyun 		/*
2352*4882a593Smuzhiyun 		 * Since this part of the tests isn't comparing the
2353*4882a593Smuzhiyun 		 * implementation to another, there's no point in testing any
2354*4882a593Smuzhiyun 		 * test vectors other than inauthentic ones (vec.novrfy=1) here.
2355*4882a593Smuzhiyun 		 *
2356*4882a593Smuzhiyun 		 * If we're having trouble generating such a test vector, e.g.
2357*4882a593Smuzhiyun 		 * if the algorithm keeps rejecting the generated keys, don't
2358*4882a593Smuzhiyun 		 * retry forever; just continue on.
2359*4882a593Smuzhiyun 		 */
2360*4882a593Smuzhiyun 		try_to_generate_inauthentic_testvec(ctx);
2361*4882a593Smuzhiyun 		if (ctx->vec.novrfy) {
2362*4882a593Smuzhiyun 			generate_random_testvec_config(&ctx->cfg, ctx->cfgname,
2363*4882a593Smuzhiyun 						       sizeof(ctx->cfgname));
2364*4882a593Smuzhiyun 			err = test_aead_vec_cfg(ctx->driver, DECRYPT, &ctx->vec,
2365*4882a593Smuzhiyun 						ctx->vec_name, &ctx->cfg,
2366*4882a593Smuzhiyun 						ctx->req, ctx->tsgls);
2367*4882a593Smuzhiyun 			if (err)
2368*4882a593Smuzhiyun 				return err;
2369*4882a593Smuzhiyun 		}
2370*4882a593Smuzhiyun 		cond_resched();
2371*4882a593Smuzhiyun 	}
2372*4882a593Smuzhiyun 	return 0;
2373*4882a593Smuzhiyun }
2374*4882a593Smuzhiyun 
2375*4882a593Smuzhiyun /*
2376*4882a593Smuzhiyun  * Test the AEAD algorithm against the corresponding generic implementation, if
2377*4882a593Smuzhiyun  * one is available.
2378*4882a593Smuzhiyun  */
test_aead_vs_generic_impl(struct aead_extra_tests_ctx * ctx)2379*4882a593Smuzhiyun static int test_aead_vs_generic_impl(struct aead_extra_tests_ctx *ctx)
2380*4882a593Smuzhiyun {
2381*4882a593Smuzhiyun 	struct crypto_aead *tfm = ctx->tfm;
2382*4882a593Smuzhiyun 	const char *algname = crypto_aead_alg(tfm)->base.cra_name;
2383*4882a593Smuzhiyun 	const char *driver = ctx->driver;
2384*4882a593Smuzhiyun 	const char *generic_driver = ctx->test_desc->generic_driver;
2385*4882a593Smuzhiyun 	char _generic_driver[CRYPTO_MAX_ALG_NAME];
2386*4882a593Smuzhiyun 	struct crypto_aead *generic_tfm = NULL;
2387*4882a593Smuzhiyun 	struct aead_request *generic_req = NULL;
2388*4882a593Smuzhiyun 	unsigned int i;
2389*4882a593Smuzhiyun 	int err;
2390*4882a593Smuzhiyun 
2391*4882a593Smuzhiyun 	if (!generic_driver) { /* Use default naming convention? */
2392*4882a593Smuzhiyun 		err = build_generic_driver_name(algname, _generic_driver);
2393*4882a593Smuzhiyun 		if (err)
2394*4882a593Smuzhiyun 			return err;
2395*4882a593Smuzhiyun 		generic_driver = _generic_driver;
2396*4882a593Smuzhiyun 	}
2397*4882a593Smuzhiyun 
2398*4882a593Smuzhiyun 	if (strcmp(generic_driver, driver) == 0) /* Already the generic impl? */
2399*4882a593Smuzhiyun 		return 0;
2400*4882a593Smuzhiyun 
2401*4882a593Smuzhiyun 	generic_tfm = crypto_alloc_aead(generic_driver, 0, 0);
2402*4882a593Smuzhiyun 	if (IS_ERR(generic_tfm)) {
2403*4882a593Smuzhiyun 		err = PTR_ERR(generic_tfm);
2404*4882a593Smuzhiyun 		if (err == -ENOENT) {
2405*4882a593Smuzhiyun 			pr_warn("alg: aead: skipping comparison tests for %s because %s is unavailable\n",
2406*4882a593Smuzhiyun 				driver, generic_driver);
2407*4882a593Smuzhiyun 			return 0;
2408*4882a593Smuzhiyun 		}
2409*4882a593Smuzhiyun 		pr_err("alg: aead: error allocating %s (generic impl of %s): %d\n",
2410*4882a593Smuzhiyun 		       generic_driver, algname, err);
2411*4882a593Smuzhiyun 		return err;
2412*4882a593Smuzhiyun 	}
2413*4882a593Smuzhiyun 
2414*4882a593Smuzhiyun 	generic_req = aead_request_alloc(generic_tfm, GFP_KERNEL);
2415*4882a593Smuzhiyun 	if (!generic_req) {
2416*4882a593Smuzhiyun 		err = -ENOMEM;
2417*4882a593Smuzhiyun 		goto out;
2418*4882a593Smuzhiyun 	}
2419*4882a593Smuzhiyun 
2420*4882a593Smuzhiyun 	/* Check the algorithm properties for consistency. */
2421*4882a593Smuzhiyun 
2422*4882a593Smuzhiyun 	if (crypto_aead_maxauthsize(tfm) !=
2423*4882a593Smuzhiyun 	    crypto_aead_maxauthsize(generic_tfm)) {
2424*4882a593Smuzhiyun 		pr_err("alg: aead: maxauthsize for %s (%u) doesn't match generic impl (%u)\n",
2425*4882a593Smuzhiyun 		       driver, crypto_aead_maxauthsize(tfm),
2426*4882a593Smuzhiyun 		       crypto_aead_maxauthsize(generic_tfm));
2427*4882a593Smuzhiyun 		err = -EINVAL;
2428*4882a593Smuzhiyun 		goto out;
2429*4882a593Smuzhiyun 	}
2430*4882a593Smuzhiyun 
2431*4882a593Smuzhiyun 	if (crypto_aead_ivsize(tfm) != crypto_aead_ivsize(generic_tfm)) {
2432*4882a593Smuzhiyun 		pr_err("alg: aead: ivsize for %s (%u) doesn't match generic impl (%u)\n",
2433*4882a593Smuzhiyun 		       driver, crypto_aead_ivsize(tfm),
2434*4882a593Smuzhiyun 		       crypto_aead_ivsize(generic_tfm));
2435*4882a593Smuzhiyun 		err = -EINVAL;
2436*4882a593Smuzhiyun 		goto out;
2437*4882a593Smuzhiyun 	}
2438*4882a593Smuzhiyun 
2439*4882a593Smuzhiyun 	if (crypto_aead_blocksize(tfm) != crypto_aead_blocksize(generic_tfm)) {
2440*4882a593Smuzhiyun 		pr_err("alg: aead: blocksize for %s (%u) doesn't match generic impl (%u)\n",
2441*4882a593Smuzhiyun 		       driver, crypto_aead_blocksize(tfm),
2442*4882a593Smuzhiyun 		       crypto_aead_blocksize(generic_tfm));
2443*4882a593Smuzhiyun 		err = -EINVAL;
2444*4882a593Smuzhiyun 		goto out;
2445*4882a593Smuzhiyun 	}
2446*4882a593Smuzhiyun 
2447*4882a593Smuzhiyun 	/*
2448*4882a593Smuzhiyun 	 * Now generate test vectors using the generic implementation, and test
2449*4882a593Smuzhiyun 	 * the other implementation against them.
2450*4882a593Smuzhiyun 	 */
2451*4882a593Smuzhiyun 	for (i = 0; i < fuzz_iterations * 8; i++) {
2452*4882a593Smuzhiyun 		generate_random_aead_testvec(generic_req, &ctx->vec,
2453*4882a593Smuzhiyun 					     &ctx->test_desc->suite.aead,
2454*4882a593Smuzhiyun 					     ctx->maxkeysize, ctx->maxdatasize,
2455*4882a593Smuzhiyun 					     ctx->vec_name,
2456*4882a593Smuzhiyun 					     sizeof(ctx->vec_name), false);
2457*4882a593Smuzhiyun 		generate_random_testvec_config(&ctx->cfg, ctx->cfgname,
2458*4882a593Smuzhiyun 					       sizeof(ctx->cfgname));
2459*4882a593Smuzhiyun 		if (!ctx->vec.novrfy) {
2460*4882a593Smuzhiyun 			err = test_aead_vec_cfg(driver, ENCRYPT, &ctx->vec,
2461*4882a593Smuzhiyun 						ctx->vec_name, &ctx->cfg,
2462*4882a593Smuzhiyun 						ctx->req, ctx->tsgls);
2463*4882a593Smuzhiyun 			if (err)
2464*4882a593Smuzhiyun 				goto out;
2465*4882a593Smuzhiyun 		}
2466*4882a593Smuzhiyun 		if (ctx->vec.crypt_error == 0 || ctx->vec.novrfy) {
2467*4882a593Smuzhiyun 			err = test_aead_vec_cfg(driver, DECRYPT, &ctx->vec,
2468*4882a593Smuzhiyun 						ctx->vec_name, &ctx->cfg,
2469*4882a593Smuzhiyun 						ctx->req, ctx->tsgls);
2470*4882a593Smuzhiyun 			if (err)
2471*4882a593Smuzhiyun 				goto out;
2472*4882a593Smuzhiyun 		}
2473*4882a593Smuzhiyun 		cond_resched();
2474*4882a593Smuzhiyun 	}
2475*4882a593Smuzhiyun 	err = 0;
2476*4882a593Smuzhiyun out:
2477*4882a593Smuzhiyun 	crypto_free_aead(generic_tfm);
2478*4882a593Smuzhiyun 	aead_request_free(generic_req);
2479*4882a593Smuzhiyun 	return err;
2480*4882a593Smuzhiyun }
2481*4882a593Smuzhiyun 
test_aead_extra(const char * driver,const struct alg_test_desc * test_desc,struct aead_request * req,struct cipher_test_sglists * tsgls)2482*4882a593Smuzhiyun static int test_aead_extra(const char *driver,
2483*4882a593Smuzhiyun 			   const struct alg_test_desc *test_desc,
2484*4882a593Smuzhiyun 			   struct aead_request *req,
2485*4882a593Smuzhiyun 			   struct cipher_test_sglists *tsgls)
2486*4882a593Smuzhiyun {
2487*4882a593Smuzhiyun 	struct aead_extra_tests_ctx *ctx;
2488*4882a593Smuzhiyun 	unsigned int i;
2489*4882a593Smuzhiyun 	int err;
2490*4882a593Smuzhiyun 
2491*4882a593Smuzhiyun 	if (noextratests)
2492*4882a593Smuzhiyun 		return 0;
2493*4882a593Smuzhiyun 
2494*4882a593Smuzhiyun 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
2495*4882a593Smuzhiyun 	if (!ctx)
2496*4882a593Smuzhiyun 		return -ENOMEM;
2497*4882a593Smuzhiyun 	ctx->req = req;
2498*4882a593Smuzhiyun 	ctx->tfm = crypto_aead_reqtfm(req);
2499*4882a593Smuzhiyun 	ctx->driver = driver;
2500*4882a593Smuzhiyun 	ctx->test_desc = test_desc;
2501*4882a593Smuzhiyun 	ctx->tsgls = tsgls;
2502*4882a593Smuzhiyun 	ctx->maxdatasize = (2 * PAGE_SIZE) - TESTMGR_POISON_LEN;
2503*4882a593Smuzhiyun 	ctx->maxkeysize = 0;
2504*4882a593Smuzhiyun 	for (i = 0; i < test_desc->suite.aead.count; i++)
2505*4882a593Smuzhiyun 		ctx->maxkeysize = max_t(unsigned int, ctx->maxkeysize,
2506*4882a593Smuzhiyun 					test_desc->suite.aead.vecs[i].klen);
2507*4882a593Smuzhiyun 
2508*4882a593Smuzhiyun 	ctx->vec.key = kmalloc(ctx->maxkeysize, GFP_KERNEL);
2509*4882a593Smuzhiyun 	ctx->vec.iv = kmalloc(crypto_aead_ivsize(ctx->tfm), GFP_KERNEL);
2510*4882a593Smuzhiyun 	ctx->vec.assoc = kmalloc(ctx->maxdatasize, GFP_KERNEL);
2511*4882a593Smuzhiyun 	ctx->vec.ptext = kmalloc(ctx->maxdatasize, GFP_KERNEL);
2512*4882a593Smuzhiyun 	ctx->vec.ctext = kmalloc(ctx->maxdatasize, GFP_KERNEL);
2513*4882a593Smuzhiyun 	if (!ctx->vec.key || !ctx->vec.iv || !ctx->vec.assoc ||
2514*4882a593Smuzhiyun 	    !ctx->vec.ptext || !ctx->vec.ctext) {
2515*4882a593Smuzhiyun 		err = -ENOMEM;
2516*4882a593Smuzhiyun 		goto out;
2517*4882a593Smuzhiyun 	}
2518*4882a593Smuzhiyun 
2519*4882a593Smuzhiyun 	err = test_aead_vs_generic_impl(ctx);
2520*4882a593Smuzhiyun 	if (err)
2521*4882a593Smuzhiyun 		goto out;
2522*4882a593Smuzhiyun 
2523*4882a593Smuzhiyun 	err = test_aead_inauthentic_inputs(ctx);
2524*4882a593Smuzhiyun out:
2525*4882a593Smuzhiyun 	kfree(ctx->vec.key);
2526*4882a593Smuzhiyun 	kfree(ctx->vec.iv);
2527*4882a593Smuzhiyun 	kfree(ctx->vec.assoc);
2528*4882a593Smuzhiyun 	kfree(ctx->vec.ptext);
2529*4882a593Smuzhiyun 	kfree(ctx->vec.ctext);
2530*4882a593Smuzhiyun 	kfree(ctx);
2531*4882a593Smuzhiyun 	return err;
2532*4882a593Smuzhiyun }
2533*4882a593Smuzhiyun #else /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
test_aead_extra(const char * driver,const struct alg_test_desc * test_desc,struct aead_request * req,struct cipher_test_sglists * tsgls)2534*4882a593Smuzhiyun static int test_aead_extra(const char *driver,
2535*4882a593Smuzhiyun 			   const struct alg_test_desc *test_desc,
2536*4882a593Smuzhiyun 			   struct aead_request *req,
2537*4882a593Smuzhiyun 			   struct cipher_test_sglists *tsgls)
2538*4882a593Smuzhiyun {
2539*4882a593Smuzhiyun 	return 0;
2540*4882a593Smuzhiyun }
2541*4882a593Smuzhiyun #endif /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
2542*4882a593Smuzhiyun 
test_aead(const char * driver,int enc,const struct aead_test_suite * suite,struct aead_request * req,struct cipher_test_sglists * tsgls)2543*4882a593Smuzhiyun static int test_aead(const char *driver, int enc,
2544*4882a593Smuzhiyun 		     const struct aead_test_suite *suite,
2545*4882a593Smuzhiyun 		     struct aead_request *req,
2546*4882a593Smuzhiyun 		     struct cipher_test_sglists *tsgls)
2547*4882a593Smuzhiyun {
2548*4882a593Smuzhiyun 	unsigned int i;
2549*4882a593Smuzhiyun 	int err;
2550*4882a593Smuzhiyun 
2551*4882a593Smuzhiyun 	for (i = 0; i < suite->count; i++) {
2552*4882a593Smuzhiyun 		err = test_aead_vec(driver, enc, &suite->vecs[i], i, req,
2553*4882a593Smuzhiyun 				    tsgls);
2554*4882a593Smuzhiyun 		if (err)
2555*4882a593Smuzhiyun 			return err;
2556*4882a593Smuzhiyun 		cond_resched();
2557*4882a593Smuzhiyun 	}
2558*4882a593Smuzhiyun 	return 0;
2559*4882a593Smuzhiyun }
2560*4882a593Smuzhiyun 
alg_test_aead(const struct alg_test_desc * desc,const char * driver,u32 type,u32 mask)2561*4882a593Smuzhiyun static int alg_test_aead(const struct alg_test_desc *desc, const char *driver,
2562*4882a593Smuzhiyun 			 u32 type, u32 mask)
2563*4882a593Smuzhiyun {
2564*4882a593Smuzhiyun 	const struct aead_test_suite *suite = &desc->suite.aead;
2565*4882a593Smuzhiyun 	struct crypto_aead *tfm;
2566*4882a593Smuzhiyun 	struct aead_request *req = NULL;
2567*4882a593Smuzhiyun 	struct cipher_test_sglists *tsgls = NULL;
2568*4882a593Smuzhiyun 	int err;
2569*4882a593Smuzhiyun 
2570*4882a593Smuzhiyun 	if (suite->count <= 0) {
2571*4882a593Smuzhiyun 		pr_err("alg: aead: empty test suite for %s\n", driver);
2572*4882a593Smuzhiyun 		return -EINVAL;
2573*4882a593Smuzhiyun 	}
2574*4882a593Smuzhiyun 
2575*4882a593Smuzhiyun 	tfm = crypto_alloc_aead(driver, type, mask);
2576*4882a593Smuzhiyun 	if (IS_ERR(tfm)) {
2577*4882a593Smuzhiyun 		pr_err("alg: aead: failed to allocate transform for %s: %ld\n",
2578*4882a593Smuzhiyun 		       driver, PTR_ERR(tfm));
2579*4882a593Smuzhiyun 		return PTR_ERR(tfm);
2580*4882a593Smuzhiyun 	}
2581*4882a593Smuzhiyun 
2582*4882a593Smuzhiyun 	req = aead_request_alloc(tfm, GFP_KERNEL);
2583*4882a593Smuzhiyun 	if (!req) {
2584*4882a593Smuzhiyun 		pr_err("alg: aead: failed to allocate request for %s\n",
2585*4882a593Smuzhiyun 		       driver);
2586*4882a593Smuzhiyun 		err = -ENOMEM;
2587*4882a593Smuzhiyun 		goto out;
2588*4882a593Smuzhiyun 	}
2589*4882a593Smuzhiyun 
2590*4882a593Smuzhiyun 	tsgls = alloc_cipher_test_sglists();
2591*4882a593Smuzhiyun 	if (!tsgls) {
2592*4882a593Smuzhiyun 		pr_err("alg: aead: failed to allocate test buffers for %s\n",
2593*4882a593Smuzhiyun 		       driver);
2594*4882a593Smuzhiyun 		err = -ENOMEM;
2595*4882a593Smuzhiyun 		goto out;
2596*4882a593Smuzhiyun 	}
2597*4882a593Smuzhiyun 
2598*4882a593Smuzhiyun 	err = test_aead(driver, ENCRYPT, suite, req, tsgls);
2599*4882a593Smuzhiyun 	if (err)
2600*4882a593Smuzhiyun 		goto out;
2601*4882a593Smuzhiyun 
2602*4882a593Smuzhiyun 	err = test_aead(driver, DECRYPT, suite, req, tsgls);
2603*4882a593Smuzhiyun 	if (err)
2604*4882a593Smuzhiyun 		goto out;
2605*4882a593Smuzhiyun 
2606*4882a593Smuzhiyun 	err = test_aead_extra(driver, desc, req, tsgls);
2607*4882a593Smuzhiyun out:
2608*4882a593Smuzhiyun 	free_cipher_test_sglists(tsgls);
2609*4882a593Smuzhiyun 	aead_request_free(req);
2610*4882a593Smuzhiyun 	crypto_free_aead(tfm);
2611*4882a593Smuzhiyun 	return err;
2612*4882a593Smuzhiyun }
2613*4882a593Smuzhiyun 
test_cipher(struct crypto_cipher * tfm,int enc,const struct cipher_testvec * template,unsigned int tcount)2614*4882a593Smuzhiyun static int test_cipher(struct crypto_cipher *tfm, int enc,
2615*4882a593Smuzhiyun 		       const struct cipher_testvec *template,
2616*4882a593Smuzhiyun 		       unsigned int tcount)
2617*4882a593Smuzhiyun {
2618*4882a593Smuzhiyun 	const char *algo = crypto_tfm_alg_driver_name(crypto_cipher_tfm(tfm));
2619*4882a593Smuzhiyun 	unsigned int i, j, k;
2620*4882a593Smuzhiyun 	char *q;
2621*4882a593Smuzhiyun 	const char *e;
2622*4882a593Smuzhiyun 	const char *input, *result;
2623*4882a593Smuzhiyun 	void *data;
2624*4882a593Smuzhiyun 	char *xbuf[XBUFSIZE];
2625*4882a593Smuzhiyun 	int ret = -ENOMEM;
2626*4882a593Smuzhiyun 
2627*4882a593Smuzhiyun 	if (testmgr_alloc_buf(xbuf))
2628*4882a593Smuzhiyun 		goto out_nobuf;
2629*4882a593Smuzhiyun 
2630*4882a593Smuzhiyun 	if (enc == ENCRYPT)
2631*4882a593Smuzhiyun 	        e = "encryption";
2632*4882a593Smuzhiyun 	else
2633*4882a593Smuzhiyun 		e = "decryption";
2634*4882a593Smuzhiyun 
2635*4882a593Smuzhiyun 	j = 0;
2636*4882a593Smuzhiyun 	for (i = 0; i < tcount; i++) {
2637*4882a593Smuzhiyun 
2638*4882a593Smuzhiyun 		if (fips_enabled && template[i].fips_skip)
2639*4882a593Smuzhiyun 			continue;
2640*4882a593Smuzhiyun 
2641*4882a593Smuzhiyun 		input  = enc ? template[i].ptext : template[i].ctext;
2642*4882a593Smuzhiyun 		result = enc ? template[i].ctext : template[i].ptext;
2643*4882a593Smuzhiyun 		j++;
2644*4882a593Smuzhiyun 
2645*4882a593Smuzhiyun 		ret = -EINVAL;
2646*4882a593Smuzhiyun 		if (WARN_ON(template[i].len > PAGE_SIZE))
2647*4882a593Smuzhiyun 			goto out;
2648*4882a593Smuzhiyun 
2649*4882a593Smuzhiyun 		data = xbuf[0];
2650*4882a593Smuzhiyun 		memcpy(data, input, template[i].len);
2651*4882a593Smuzhiyun 
2652*4882a593Smuzhiyun 		crypto_cipher_clear_flags(tfm, ~0);
2653*4882a593Smuzhiyun 		if (template[i].wk)
2654*4882a593Smuzhiyun 			crypto_cipher_set_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS);
2655*4882a593Smuzhiyun 
2656*4882a593Smuzhiyun 		ret = crypto_cipher_setkey(tfm, template[i].key,
2657*4882a593Smuzhiyun 					   template[i].klen);
2658*4882a593Smuzhiyun 		if (ret) {
2659*4882a593Smuzhiyun 			if (ret == template[i].setkey_error)
2660*4882a593Smuzhiyun 				continue;
2661*4882a593Smuzhiyun 			pr_err("alg: cipher: %s setkey failed on test vector %u; expected_error=%d, actual_error=%d, flags=%#x\n",
2662*4882a593Smuzhiyun 			       algo, j, template[i].setkey_error, ret,
2663*4882a593Smuzhiyun 			       crypto_cipher_get_flags(tfm));
2664*4882a593Smuzhiyun 			goto out;
2665*4882a593Smuzhiyun 		}
2666*4882a593Smuzhiyun 		if (template[i].setkey_error) {
2667*4882a593Smuzhiyun 			pr_err("alg: cipher: %s setkey unexpectedly succeeded on test vector %u; expected_error=%d\n",
2668*4882a593Smuzhiyun 			       algo, j, template[i].setkey_error);
2669*4882a593Smuzhiyun 			ret = -EINVAL;
2670*4882a593Smuzhiyun 			goto out;
2671*4882a593Smuzhiyun 		}
2672*4882a593Smuzhiyun 
2673*4882a593Smuzhiyun 		for (k = 0; k < template[i].len;
2674*4882a593Smuzhiyun 		     k += crypto_cipher_blocksize(tfm)) {
2675*4882a593Smuzhiyun 			if (enc)
2676*4882a593Smuzhiyun 				crypto_cipher_encrypt_one(tfm, data + k,
2677*4882a593Smuzhiyun 							  data + k);
2678*4882a593Smuzhiyun 			else
2679*4882a593Smuzhiyun 				crypto_cipher_decrypt_one(tfm, data + k,
2680*4882a593Smuzhiyun 							  data + k);
2681*4882a593Smuzhiyun 		}
2682*4882a593Smuzhiyun 
2683*4882a593Smuzhiyun 		q = data;
2684*4882a593Smuzhiyun 		if (memcmp(q, result, template[i].len)) {
2685*4882a593Smuzhiyun 			printk(KERN_ERR "alg: cipher: Test %d failed "
2686*4882a593Smuzhiyun 			       "on %s for %s\n", j, e, algo);
2687*4882a593Smuzhiyun 			hexdump(q, template[i].len);
2688*4882a593Smuzhiyun 			ret = -EINVAL;
2689*4882a593Smuzhiyun 			goto out;
2690*4882a593Smuzhiyun 		}
2691*4882a593Smuzhiyun 	}
2692*4882a593Smuzhiyun 
2693*4882a593Smuzhiyun 	ret = 0;
2694*4882a593Smuzhiyun 
2695*4882a593Smuzhiyun out:
2696*4882a593Smuzhiyun 	testmgr_free_buf(xbuf);
2697*4882a593Smuzhiyun out_nobuf:
2698*4882a593Smuzhiyun 	return ret;
2699*4882a593Smuzhiyun }
2700*4882a593Smuzhiyun 
test_skcipher_vec_cfg(const char * driver,int enc,const struct cipher_testvec * vec,const char * vec_name,const struct testvec_config * cfg,struct skcipher_request * req,struct cipher_test_sglists * tsgls)2701*4882a593Smuzhiyun static int test_skcipher_vec_cfg(const char *driver, int enc,
2702*4882a593Smuzhiyun 				 const struct cipher_testvec *vec,
2703*4882a593Smuzhiyun 				 const char *vec_name,
2704*4882a593Smuzhiyun 				 const struct testvec_config *cfg,
2705*4882a593Smuzhiyun 				 struct skcipher_request *req,
2706*4882a593Smuzhiyun 				 struct cipher_test_sglists *tsgls)
2707*4882a593Smuzhiyun {
2708*4882a593Smuzhiyun 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
2709*4882a593Smuzhiyun 	const unsigned int alignmask = crypto_skcipher_alignmask(tfm);
2710*4882a593Smuzhiyun 	const unsigned int ivsize = crypto_skcipher_ivsize(tfm);
2711*4882a593Smuzhiyun 	const u32 req_flags = CRYPTO_TFM_REQ_MAY_BACKLOG | cfg->req_flags;
2712*4882a593Smuzhiyun 	const char *op = enc ? "encryption" : "decryption";
2713*4882a593Smuzhiyun 	DECLARE_CRYPTO_WAIT(wait);
2714*4882a593Smuzhiyun 	u8 _iv[3 * (MAX_ALGAPI_ALIGNMASK + 1) + MAX_IVLEN];
2715*4882a593Smuzhiyun 	u8 *iv = PTR_ALIGN(&_iv[0], 2 * (MAX_ALGAPI_ALIGNMASK + 1)) +
2716*4882a593Smuzhiyun 		 cfg->iv_offset +
2717*4882a593Smuzhiyun 		 (cfg->iv_offset_relative_to_alignmask ? alignmask : 0);
2718*4882a593Smuzhiyun 	struct kvec input;
2719*4882a593Smuzhiyun 	int err;
2720*4882a593Smuzhiyun 
2721*4882a593Smuzhiyun 	/* Set the key */
2722*4882a593Smuzhiyun 	if (vec->wk)
2723*4882a593Smuzhiyun 		crypto_skcipher_set_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS);
2724*4882a593Smuzhiyun 	else
2725*4882a593Smuzhiyun 		crypto_skcipher_clear_flags(tfm,
2726*4882a593Smuzhiyun 					    CRYPTO_TFM_REQ_FORBID_WEAK_KEYS);
2727*4882a593Smuzhiyun 	err = do_setkey(crypto_skcipher_setkey, tfm, vec->key, vec->klen,
2728*4882a593Smuzhiyun 			cfg, alignmask);
2729*4882a593Smuzhiyun 	if (err) {
2730*4882a593Smuzhiyun 		if (err == vec->setkey_error)
2731*4882a593Smuzhiyun 			return 0;
2732*4882a593Smuzhiyun 		pr_err("alg: skcipher: %s setkey failed on test vector %s; expected_error=%d, actual_error=%d, flags=%#x\n",
2733*4882a593Smuzhiyun 		       driver, vec_name, vec->setkey_error, err,
2734*4882a593Smuzhiyun 		       crypto_skcipher_get_flags(tfm));
2735*4882a593Smuzhiyun 		return err;
2736*4882a593Smuzhiyun 	}
2737*4882a593Smuzhiyun 	if (vec->setkey_error) {
2738*4882a593Smuzhiyun 		pr_err("alg: skcipher: %s setkey unexpectedly succeeded on test vector %s; expected_error=%d\n",
2739*4882a593Smuzhiyun 		       driver, vec_name, vec->setkey_error);
2740*4882a593Smuzhiyun 		return -EINVAL;
2741*4882a593Smuzhiyun 	}
2742*4882a593Smuzhiyun 
2743*4882a593Smuzhiyun 	/* The IV must be copied to a buffer, as the algorithm may modify it */
2744*4882a593Smuzhiyun 	if (ivsize) {
2745*4882a593Smuzhiyun 		if (WARN_ON(ivsize > MAX_IVLEN))
2746*4882a593Smuzhiyun 			return -EINVAL;
2747*4882a593Smuzhiyun 		if (vec->generates_iv && !enc)
2748*4882a593Smuzhiyun 			memcpy(iv, vec->iv_out, ivsize);
2749*4882a593Smuzhiyun 		else if (vec->iv)
2750*4882a593Smuzhiyun 			memcpy(iv, vec->iv, ivsize);
2751*4882a593Smuzhiyun 		else
2752*4882a593Smuzhiyun 			memset(iv, 0, ivsize);
2753*4882a593Smuzhiyun 	} else {
2754*4882a593Smuzhiyun 		if (vec->generates_iv) {
2755*4882a593Smuzhiyun 			pr_err("alg: skcipher: %s has ivsize=0 but test vector %s generates IV!\n",
2756*4882a593Smuzhiyun 			       driver, vec_name);
2757*4882a593Smuzhiyun 			return -EINVAL;
2758*4882a593Smuzhiyun 		}
2759*4882a593Smuzhiyun 		iv = NULL;
2760*4882a593Smuzhiyun 	}
2761*4882a593Smuzhiyun 
2762*4882a593Smuzhiyun 	/* Build the src/dst scatterlists */
2763*4882a593Smuzhiyun 	input.iov_base = enc ? (void *)vec->ptext : (void *)vec->ctext;
2764*4882a593Smuzhiyun 	input.iov_len = vec->len;
2765*4882a593Smuzhiyun 	err = build_cipher_test_sglists(tsgls, cfg, alignmask,
2766*4882a593Smuzhiyun 					vec->len, vec->len, &input, 1);
2767*4882a593Smuzhiyun 	if (err) {
2768*4882a593Smuzhiyun 		pr_err("alg: skcipher: %s %s: error preparing scatterlists for test vector %s, cfg=\"%s\"\n",
2769*4882a593Smuzhiyun 		       driver, op, vec_name, cfg->name);
2770*4882a593Smuzhiyun 		return err;
2771*4882a593Smuzhiyun 	}
2772*4882a593Smuzhiyun 
2773*4882a593Smuzhiyun 	/* Do the actual encryption or decryption */
2774*4882a593Smuzhiyun 	testmgr_poison(req->__ctx, crypto_skcipher_reqsize(tfm));
2775*4882a593Smuzhiyun 	skcipher_request_set_callback(req, req_flags, crypto_req_done, &wait);
2776*4882a593Smuzhiyun 	skcipher_request_set_crypt(req, tsgls->src.sgl_ptr, tsgls->dst.sgl_ptr,
2777*4882a593Smuzhiyun 				   vec->len, iv);
2778*4882a593Smuzhiyun 	if (cfg->nosimd)
2779*4882a593Smuzhiyun 		crypto_disable_simd_for_test();
2780*4882a593Smuzhiyun 	err = enc ? crypto_skcipher_encrypt(req) : crypto_skcipher_decrypt(req);
2781*4882a593Smuzhiyun 	if (cfg->nosimd)
2782*4882a593Smuzhiyun 		crypto_reenable_simd_for_test();
2783*4882a593Smuzhiyun 	err = crypto_wait_req(err, &wait);
2784*4882a593Smuzhiyun 
2785*4882a593Smuzhiyun 	/* Check that the algorithm didn't overwrite things it shouldn't have */
2786*4882a593Smuzhiyun 	if (req->cryptlen != vec->len ||
2787*4882a593Smuzhiyun 	    req->iv != iv ||
2788*4882a593Smuzhiyun 	    req->src != tsgls->src.sgl_ptr ||
2789*4882a593Smuzhiyun 	    req->dst != tsgls->dst.sgl_ptr ||
2790*4882a593Smuzhiyun 	    crypto_skcipher_reqtfm(req) != tfm ||
2791*4882a593Smuzhiyun 	    req->base.complete != crypto_req_done ||
2792*4882a593Smuzhiyun 	    req->base.flags != req_flags ||
2793*4882a593Smuzhiyun 	    req->base.data != &wait) {
2794*4882a593Smuzhiyun 		pr_err("alg: skcipher: %s %s corrupted request struct on test vector %s, cfg=\"%s\"\n",
2795*4882a593Smuzhiyun 		       driver, op, vec_name, cfg->name);
2796*4882a593Smuzhiyun 		if (req->cryptlen != vec->len)
2797*4882a593Smuzhiyun 			pr_err("alg: skcipher: changed 'req->cryptlen'\n");
2798*4882a593Smuzhiyun 		if (req->iv != iv)
2799*4882a593Smuzhiyun 			pr_err("alg: skcipher: changed 'req->iv'\n");
2800*4882a593Smuzhiyun 		if (req->src != tsgls->src.sgl_ptr)
2801*4882a593Smuzhiyun 			pr_err("alg: skcipher: changed 'req->src'\n");
2802*4882a593Smuzhiyun 		if (req->dst != tsgls->dst.sgl_ptr)
2803*4882a593Smuzhiyun 			pr_err("alg: skcipher: changed 'req->dst'\n");
2804*4882a593Smuzhiyun 		if (crypto_skcipher_reqtfm(req) != tfm)
2805*4882a593Smuzhiyun 			pr_err("alg: skcipher: changed 'req->base.tfm'\n");
2806*4882a593Smuzhiyun 		if (req->base.complete != crypto_req_done)
2807*4882a593Smuzhiyun 			pr_err("alg: skcipher: changed 'req->base.complete'\n");
2808*4882a593Smuzhiyun 		if (req->base.flags != req_flags)
2809*4882a593Smuzhiyun 			pr_err("alg: skcipher: changed 'req->base.flags'\n");
2810*4882a593Smuzhiyun 		if (req->base.data != &wait)
2811*4882a593Smuzhiyun 			pr_err("alg: skcipher: changed 'req->base.data'\n");
2812*4882a593Smuzhiyun 		return -EINVAL;
2813*4882a593Smuzhiyun 	}
2814*4882a593Smuzhiyun 	if (is_test_sglist_corrupted(&tsgls->src)) {
2815*4882a593Smuzhiyun 		pr_err("alg: skcipher: %s %s corrupted src sgl on test vector %s, cfg=\"%s\"\n",
2816*4882a593Smuzhiyun 		       driver, op, vec_name, cfg->name);
2817*4882a593Smuzhiyun 		return -EINVAL;
2818*4882a593Smuzhiyun 	}
2819*4882a593Smuzhiyun 	if (tsgls->dst.sgl_ptr != tsgls->src.sgl &&
2820*4882a593Smuzhiyun 	    is_test_sglist_corrupted(&tsgls->dst)) {
2821*4882a593Smuzhiyun 		pr_err("alg: skcipher: %s %s corrupted dst sgl on test vector %s, cfg=\"%s\"\n",
2822*4882a593Smuzhiyun 		       driver, op, vec_name, cfg->name);
2823*4882a593Smuzhiyun 		return -EINVAL;
2824*4882a593Smuzhiyun 	}
2825*4882a593Smuzhiyun 
2826*4882a593Smuzhiyun 	/* Check for success or failure */
2827*4882a593Smuzhiyun 	if (err) {
2828*4882a593Smuzhiyun 		if (err == vec->crypt_error)
2829*4882a593Smuzhiyun 			return 0;
2830*4882a593Smuzhiyun 		pr_err("alg: skcipher: %s %s failed on test vector %s; expected_error=%d, actual_error=%d, cfg=\"%s\"\n",
2831*4882a593Smuzhiyun 		       driver, op, vec_name, vec->crypt_error, err, cfg->name);
2832*4882a593Smuzhiyun 		return err;
2833*4882a593Smuzhiyun 	}
2834*4882a593Smuzhiyun 	if (vec->crypt_error) {
2835*4882a593Smuzhiyun 		pr_err("alg: skcipher: %s %s unexpectedly succeeded on test vector %s; expected_error=%d, cfg=\"%s\"\n",
2836*4882a593Smuzhiyun 		       driver, op, vec_name, vec->crypt_error, cfg->name);
2837*4882a593Smuzhiyun 		return -EINVAL;
2838*4882a593Smuzhiyun 	}
2839*4882a593Smuzhiyun 
2840*4882a593Smuzhiyun 	/* Check for the correct output (ciphertext or plaintext) */
2841*4882a593Smuzhiyun 	err = verify_correct_output(&tsgls->dst, enc ? vec->ctext : vec->ptext,
2842*4882a593Smuzhiyun 				    vec->len, 0, true);
2843*4882a593Smuzhiyun 	if (err == -EOVERFLOW) {
2844*4882a593Smuzhiyun 		pr_err("alg: skcipher: %s %s overran dst buffer on test vector %s, cfg=\"%s\"\n",
2845*4882a593Smuzhiyun 		       driver, op, vec_name, cfg->name);
2846*4882a593Smuzhiyun 		return err;
2847*4882a593Smuzhiyun 	}
2848*4882a593Smuzhiyun 	if (err) {
2849*4882a593Smuzhiyun 		pr_err("alg: skcipher: %s %s test failed (wrong result) on test vector %s, cfg=\"%s\"\n",
2850*4882a593Smuzhiyun 		       driver, op, vec_name, cfg->name);
2851*4882a593Smuzhiyun 		return err;
2852*4882a593Smuzhiyun 	}
2853*4882a593Smuzhiyun 
2854*4882a593Smuzhiyun 	/* If applicable, check that the algorithm generated the correct IV */
2855*4882a593Smuzhiyun 	if (vec->iv_out && memcmp(iv, vec->iv_out, ivsize) != 0) {
2856*4882a593Smuzhiyun 		pr_err("alg: skcipher: %s %s test failed (wrong output IV) on test vector %s, cfg=\"%s\"\n",
2857*4882a593Smuzhiyun 		       driver, op, vec_name, cfg->name);
2858*4882a593Smuzhiyun 		hexdump(iv, ivsize);
2859*4882a593Smuzhiyun 		return -EINVAL;
2860*4882a593Smuzhiyun 	}
2861*4882a593Smuzhiyun 
2862*4882a593Smuzhiyun 	return 0;
2863*4882a593Smuzhiyun }
2864*4882a593Smuzhiyun 
test_skcipher_vec(const char * driver,int enc,const struct cipher_testvec * vec,unsigned int vec_num,struct skcipher_request * req,struct cipher_test_sglists * tsgls)2865*4882a593Smuzhiyun static int test_skcipher_vec(const char *driver, int enc,
2866*4882a593Smuzhiyun 			     const struct cipher_testvec *vec,
2867*4882a593Smuzhiyun 			     unsigned int vec_num,
2868*4882a593Smuzhiyun 			     struct skcipher_request *req,
2869*4882a593Smuzhiyun 			     struct cipher_test_sglists *tsgls)
2870*4882a593Smuzhiyun {
2871*4882a593Smuzhiyun 	char vec_name[16];
2872*4882a593Smuzhiyun 	unsigned int i;
2873*4882a593Smuzhiyun 	int err;
2874*4882a593Smuzhiyun 
2875*4882a593Smuzhiyun 	if (fips_enabled && vec->fips_skip)
2876*4882a593Smuzhiyun 		return 0;
2877*4882a593Smuzhiyun 
2878*4882a593Smuzhiyun 	sprintf(vec_name, "%u", vec_num);
2879*4882a593Smuzhiyun 
2880*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(default_cipher_testvec_configs); i++) {
2881*4882a593Smuzhiyun 		err = test_skcipher_vec_cfg(driver, enc, vec, vec_name,
2882*4882a593Smuzhiyun 					    &default_cipher_testvec_configs[i],
2883*4882a593Smuzhiyun 					    req, tsgls);
2884*4882a593Smuzhiyun 		if (err)
2885*4882a593Smuzhiyun 			return err;
2886*4882a593Smuzhiyun 	}
2887*4882a593Smuzhiyun 
2888*4882a593Smuzhiyun #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
2889*4882a593Smuzhiyun 	if (!noextratests) {
2890*4882a593Smuzhiyun 		struct testvec_config cfg;
2891*4882a593Smuzhiyun 		char cfgname[TESTVEC_CONFIG_NAMELEN];
2892*4882a593Smuzhiyun 
2893*4882a593Smuzhiyun 		for (i = 0; i < fuzz_iterations; i++) {
2894*4882a593Smuzhiyun 			generate_random_testvec_config(&cfg, cfgname,
2895*4882a593Smuzhiyun 						       sizeof(cfgname));
2896*4882a593Smuzhiyun 			err = test_skcipher_vec_cfg(driver, enc, vec, vec_name,
2897*4882a593Smuzhiyun 						    &cfg, req, tsgls);
2898*4882a593Smuzhiyun 			if (err)
2899*4882a593Smuzhiyun 				return err;
2900*4882a593Smuzhiyun 			cond_resched();
2901*4882a593Smuzhiyun 		}
2902*4882a593Smuzhiyun 	}
2903*4882a593Smuzhiyun #endif
2904*4882a593Smuzhiyun 	return 0;
2905*4882a593Smuzhiyun }
2906*4882a593Smuzhiyun 
2907*4882a593Smuzhiyun #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
2908*4882a593Smuzhiyun /*
2909*4882a593Smuzhiyun  * Generate a symmetric cipher test vector from the given implementation.
2910*4882a593Smuzhiyun  * Assumes the buffers in 'vec' were already allocated.
2911*4882a593Smuzhiyun  */
generate_random_cipher_testvec(struct skcipher_request * req,struct cipher_testvec * vec,unsigned int maxdatasize,char * name,size_t max_namelen)2912*4882a593Smuzhiyun static void generate_random_cipher_testvec(struct skcipher_request *req,
2913*4882a593Smuzhiyun 					   struct cipher_testvec *vec,
2914*4882a593Smuzhiyun 					   unsigned int maxdatasize,
2915*4882a593Smuzhiyun 					   char *name, size_t max_namelen)
2916*4882a593Smuzhiyun {
2917*4882a593Smuzhiyun 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
2918*4882a593Smuzhiyun 	const unsigned int maxkeysize = crypto_skcipher_max_keysize(tfm);
2919*4882a593Smuzhiyun 	const unsigned int ivsize = crypto_skcipher_ivsize(tfm);
2920*4882a593Smuzhiyun 	struct scatterlist src, dst;
2921*4882a593Smuzhiyun 	u8 iv[MAX_IVLEN];
2922*4882a593Smuzhiyun 	DECLARE_CRYPTO_WAIT(wait);
2923*4882a593Smuzhiyun 
2924*4882a593Smuzhiyun 	/* Key: length in [0, maxkeysize], but usually choose maxkeysize */
2925*4882a593Smuzhiyun 	vec->klen = maxkeysize;
2926*4882a593Smuzhiyun 	if (prandom_u32() % 4 == 0)
2927*4882a593Smuzhiyun 		vec->klen = prandom_u32() % (maxkeysize + 1);
2928*4882a593Smuzhiyun 	generate_random_bytes((u8 *)vec->key, vec->klen);
2929*4882a593Smuzhiyun 	vec->setkey_error = crypto_skcipher_setkey(tfm, vec->key, vec->klen);
2930*4882a593Smuzhiyun 
2931*4882a593Smuzhiyun 	/* IV */
2932*4882a593Smuzhiyun 	generate_random_bytes((u8 *)vec->iv, ivsize);
2933*4882a593Smuzhiyun 
2934*4882a593Smuzhiyun 	/* Plaintext */
2935*4882a593Smuzhiyun 	vec->len = generate_random_length(maxdatasize);
2936*4882a593Smuzhiyun 	generate_random_bytes((u8 *)vec->ptext, vec->len);
2937*4882a593Smuzhiyun 
2938*4882a593Smuzhiyun 	/* If the key couldn't be set, no need to continue to encrypt. */
2939*4882a593Smuzhiyun 	if (vec->setkey_error)
2940*4882a593Smuzhiyun 		goto done;
2941*4882a593Smuzhiyun 
2942*4882a593Smuzhiyun 	/* Ciphertext */
2943*4882a593Smuzhiyun 	sg_init_one(&src, vec->ptext, vec->len);
2944*4882a593Smuzhiyun 	sg_init_one(&dst, vec->ctext, vec->len);
2945*4882a593Smuzhiyun 	memcpy(iv, vec->iv, ivsize);
2946*4882a593Smuzhiyun 	skcipher_request_set_callback(req, 0, crypto_req_done, &wait);
2947*4882a593Smuzhiyun 	skcipher_request_set_crypt(req, &src, &dst, vec->len, iv);
2948*4882a593Smuzhiyun 	vec->crypt_error = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
2949*4882a593Smuzhiyun 	if (vec->crypt_error != 0) {
2950*4882a593Smuzhiyun 		/*
2951*4882a593Smuzhiyun 		 * The only acceptable error here is for an invalid length, so
2952*4882a593Smuzhiyun 		 * skcipher decryption should fail with the same error too.
2953*4882a593Smuzhiyun 		 * We'll test for this.  But to keep the API usage well-defined,
2954*4882a593Smuzhiyun 		 * explicitly initialize the ciphertext buffer too.
2955*4882a593Smuzhiyun 		 */
2956*4882a593Smuzhiyun 		memset((u8 *)vec->ctext, 0, vec->len);
2957*4882a593Smuzhiyun 	}
2958*4882a593Smuzhiyun done:
2959*4882a593Smuzhiyun 	snprintf(name, max_namelen, "\"random: len=%u klen=%u\"",
2960*4882a593Smuzhiyun 		 vec->len, vec->klen);
2961*4882a593Smuzhiyun }
2962*4882a593Smuzhiyun 
2963*4882a593Smuzhiyun /*
2964*4882a593Smuzhiyun  * Test the skcipher algorithm represented by @req against the corresponding
2965*4882a593Smuzhiyun  * generic implementation, if one is available.
2966*4882a593Smuzhiyun  */
test_skcipher_vs_generic_impl(const char * driver,const char * generic_driver,struct skcipher_request * req,struct cipher_test_sglists * tsgls)2967*4882a593Smuzhiyun static int test_skcipher_vs_generic_impl(const char *driver,
2968*4882a593Smuzhiyun 					 const char *generic_driver,
2969*4882a593Smuzhiyun 					 struct skcipher_request *req,
2970*4882a593Smuzhiyun 					 struct cipher_test_sglists *tsgls)
2971*4882a593Smuzhiyun {
2972*4882a593Smuzhiyun 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
2973*4882a593Smuzhiyun 	const unsigned int maxkeysize = crypto_skcipher_max_keysize(tfm);
2974*4882a593Smuzhiyun 	const unsigned int ivsize = crypto_skcipher_ivsize(tfm);
2975*4882a593Smuzhiyun 	const unsigned int blocksize = crypto_skcipher_blocksize(tfm);
2976*4882a593Smuzhiyun 	const unsigned int maxdatasize = (2 * PAGE_SIZE) - TESTMGR_POISON_LEN;
2977*4882a593Smuzhiyun 	const char *algname = crypto_skcipher_alg(tfm)->base.cra_name;
2978*4882a593Smuzhiyun 	char _generic_driver[CRYPTO_MAX_ALG_NAME];
2979*4882a593Smuzhiyun 	struct crypto_skcipher *generic_tfm = NULL;
2980*4882a593Smuzhiyun 	struct skcipher_request *generic_req = NULL;
2981*4882a593Smuzhiyun 	unsigned int i;
2982*4882a593Smuzhiyun 	struct cipher_testvec vec = { 0 };
2983*4882a593Smuzhiyun 	char vec_name[64];
2984*4882a593Smuzhiyun 	struct testvec_config *cfg;
2985*4882a593Smuzhiyun 	char cfgname[TESTVEC_CONFIG_NAMELEN];
2986*4882a593Smuzhiyun 	int err;
2987*4882a593Smuzhiyun 
2988*4882a593Smuzhiyun 	if (noextratests)
2989*4882a593Smuzhiyun 		return 0;
2990*4882a593Smuzhiyun 
2991*4882a593Smuzhiyun 	/* Keywrap isn't supported here yet as it handles its IV differently. */
2992*4882a593Smuzhiyun 	if (strncmp(algname, "kw(", 3) == 0)
2993*4882a593Smuzhiyun 		return 0;
2994*4882a593Smuzhiyun 
2995*4882a593Smuzhiyun 	if (!generic_driver) { /* Use default naming convention? */
2996*4882a593Smuzhiyun 		err = build_generic_driver_name(algname, _generic_driver);
2997*4882a593Smuzhiyun 		if (err)
2998*4882a593Smuzhiyun 			return err;
2999*4882a593Smuzhiyun 		generic_driver = _generic_driver;
3000*4882a593Smuzhiyun 	}
3001*4882a593Smuzhiyun 
3002*4882a593Smuzhiyun 	if (strcmp(generic_driver, driver) == 0) /* Already the generic impl? */
3003*4882a593Smuzhiyun 		return 0;
3004*4882a593Smuzhiyun 
3005*4882a593Smuzhiyun 	generic_tfm = crypto_alloc_skcipher(generic_driver, 0, 0);
3006*4882a593Smuzhiyun 	if (IS_ERR(generic_tfm)) {
3007*4882a593Smuzhiyun 		err = PTR_ERR(generic_tfm);
3008*4882a593Smuzhiyun 		if (err == -ENOENT) {
3009*4882a593Smuzhiyun 			pr_warn("alg: skcipher: skipping comparison tests for %s because %s is unavailable\n",
3010*4882a593Smuzhiyun 				driver, generic_driver);
3011*4882a593Smuzhiyun 			return 0;
3012*4882a593Smuzhiyun 		}
3013*4882a593Smuzhiyun 		pr_err("alg: skcipher: error allocating %s (generic impl of %s): %d\n",
3014*4882a593Smuzhiyun 		       generic_driver, algname, err);
3015*4882a593Smuzhiyun 		return err;
3016*4882a593Smuzhiyun 	}
3017*4882a593Smuzhiyun 
3018*4882a593Smuzhiyun 	cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
3019*4882a593Smuzhiyun 	if (!cfg) {
3020*4882a593Smuzhiyun 		err = -ENOMEM;
3021*4882a593Smuzhiyun 		goto out;
3022*4882a593Smuzhiyun 	}
3023*4882a593Smuzhiyun 
3024*4882a593Smuzhiyun 	generic_req = skcipher_request_alloc(generic_tfm, GFP_KERNEL);
3025*4882a593Smuzhiyun 	if (!generic_req) {
3026*4882a593Smuzhiyun 		err = -ENOMEM;
3027*4882a593Smuzhiyun 		goto out;
3028*4882a593Smuzhiyun 	}
3029*4882a593Smuzhiyun 
3030*4882a593Smuzhiyun 	/* Check the algorithm properties for consistency. */
3031*4882a593Smuzhiyun 
3032*4882a593Smuzhiyun 	if (crypto_skcipher_min_keysize(tfm) !=
3033*4882a593Smuzhiyun 	    crypto_skcipher_min_keysize(generic_tfm)) {
3034*4882a593Smuzhiyun 		pr_err("alg: skcipher: min keysize for %s (%u) doesn't match generic impl (%u)\n",
3035*4882a593Smuzhiyun 		       driver, crypto_skcipher_min_keysize(tfm),
3036*4882a593Smuzhiyun 		       crypto_skcipher_min_keysize(generic_tfm));
3037*4882a593Smuzhiyun 		err = -EINVAL;
3038*4882a593Smuzhiyun 		goto out;
3039*4882a593Smuzhiyun 	}
3040*4882a593Smuzhiyun 
3041*4882a593Smuzhiyun 	if (maxkeysize != crypto_skcipher_max_keysize(generic_tfm)) {
3042*4882a593Smuzhiyun 		pr_err("alg: skcipher: max keysize for %s (%u) doesn't match generic impl (%u)\n",
3043*4882a593Smuzhiyun 		       driver, maxkeysize,
3044*4882a593Smuzhiyun 		       crypto_skcipher_max_keysize(generic_tfm));
3045*4882a593Smuzhiyun 		err = -EINVAL;
3046*4882a593Smuzhiyun 		goto out;
3047*4882a593Smuzhiyun 	}
3048*4882a593Smuzhiyun 
3049*4882a593Smuzhiyun 	if (ivsize != crypto_skcipher_ivsize(generic_tfm)) {
3050*4882a593Smuzhiyun 		pr_err("alg: skcipher: ivsize for %s (%u) doesn't match generic impl (%u)\n",
3051*4882a593Smuzhiyun 		       driver, ivsize, crypto_skcipher_ivsize(generic_tfm));
3052*4882a593Smuzhiyun 		err = -EINVAL;
3053*4882a593Smuzhiyun 		goto out;
3054*4882a593Smuzhiyun 	}
3055*4882a593Smuzhiyun 
3056*4882a593Smuzhiyun 	if (blocksize != crypto_skcipher_blocksize(generic_tfm)) {
3057*4882a593Smuzhiyun 		pr_err("alg: skcipher: blocksize for %s (%u) doesn't match generic impl (%u)\n",
3058*4882a593Smuzhiyun 		       driver, blocksize,
3059*4882a593Smuzhiyun 		       crypto_skcipher_blocksize(generic_tfm));
3060*4882a593Smuzhiyun 		err = -EINVAL;
3061*4882a593Smuzhiyun 		goto out;
3062*4882a593Smuzhiyun 	}
3063*4882a593Smuzhiyun 
3064*4882a593Smuzhiyun 	/*
3065*4882a593Smuzhiyun 	 * Now generate test vectors using the generic implementation, and test
3066*4882a593Smuzhiyun 	 * the other implementation against them.
3067*4882a593Smuzhiyun 	 */
3068*4882a593Smuzhiyun 
3069*4882a593Smuzhiyun 	vec.key = kmalloc(maxkeysize, GFP_KERNEL);
3070*4882a593Smuzhiyun 	vec.iv = kmalloc(ivsize, GFP_KERNEL);
3071*4882a593Smuzhiyun 	vec.ptext = kmalloc(maxdatasize, GFP_KERNEL);
3072*4882a593Smuzhiyun 	vec.ctext = kmalloc(maxdatasize, GFP_KERNEL);
3073*4882a593Smuzhiyun 	if (!vec.key || !vec.iv || !vec.ptext || !vec.ctext) {
3074*4882a593Smuzhiyun 		err = -ENOMEM;
3075*4882a593Smuzhiyun 		goto out;
3076*4882a593Smuzhiyun 	}
3077*4882a593Smuzhiyun 
3078*4882a593Smuzhiyun 	for (i = 0; i < fuzz_iterations * 8; i++) {
3079*4882a593Smuzhiyun 		generate_random_cipher_testvec(generic_req, &vec, maxdatasize,
3080*4882a593Smuzhiyun 					       vec_name, sizeof(vec_name));
3081*4882a593Smuzhiyun 		generate_random_testvec_config(cfg, cfgname, sizeof(cfgname));
3082*4882a593Smuzhiyun 
3083*4882a593Smuzhiyun 		err = test_skcipher_vec_cfg(driver, ENCRYPT, &vec, vec_name,
3084*4882a593Smuzhiyun 					    cfg, req, tsgls);
3085*4882a593Smuzhiyun 		if (err)
3086*4882a593Smuzhiyun 			goto out;
3087*4882a593Smuzhiyun 		err = test_skcipher_vec_cfg(driver, DECRYPT, &vec, vec_name,
3088*4882a593Smuzhiyun 					    cfg, req, tsgls);
3089*4882a593Smuzhiyun 		if (err)
3090*4882a593Smuzhiyun 			goto out;
3091*4882a593Smuzhiyun 		cond_resched();
3092*4882a593Smuzhiyun 	}
3093*4882a593Smuzhiyun 	err = 0;
3094*4882a593Smuzhiyun out:
3095*4882a593Smuzhiyun 	kfree(cfg);
3096*4882a593Smuzhiyun 	kfree(vec.key);
3097*4882a593Smuzhiyun 	kfree(vec.iv);
3098*4882a593Smuzhiyun 	kfree(vec.ptext);
3099*4882a593Smuzhiyun 	kfree(vec.ctext);
3100*4882a593Smuzhiyun 	crypto_free_skcipher(generic_tfm);
3101*4882a593Smuzhiyun 	skcipher_request_free(generic_req);
3102*4882a593Smuzhiyun 	return err;
3103*4882a593Smuzhiyun }
3104*4882a593Smuzhiyun #else /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
test_skcipher_vs_generic_impl(const char * driver,const char * generic_driver,struct skcipher_request * req,struct cipher_test_sglists * tsgls)3105*4882a593Smuzhiyun static int test_skcipher_vs_generic_impl(const char *driver,
3106*4882a593Smuzhiyun 					 const char *generic_driver,
3107*4882a593Smuzhiyun 					 struct skcipher_request *req,
3108*4882a593Smuzhiyun 					 struct cipher_test_sglists *tsgls)
3109*4882a593Smuzhiyun {
3110*4882a593Smuzhiyun 	return 0;
3111*4882a593Smuzhiyun }
3112*4882a593Smuzhiyun #endif /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
3113*4882a593Smuzhiyun 
test_skcipher(const char * driver,int enc,const struct cipher_test_suite * suite,struct skcipher_request * req,struct cipher_test_sglists * tsgls)3114*4882a593Smuzhiyun static int test_skcipher(const char *driver, int enc,
3115*4882a593Smuzhiyun 			 const struct cipher_test_suite *suite,
3116*4882a593Smuzhiyun 			 struct skcipher_request *req,
3117*4882a593Smuzhiyun 			 struct cipher_test_sglists *tsgls)
3118*4882a593Smuzhiyun {
3119*4882a593Smuzhiyun 	unsigned int i;
3120*4882a593Smuzhiyun 	int err;
3121*4882a593Smuzhiyun 
3122*4882a593Smuzhiyun 	for (i = 0; i < suite->count; i++) {
3123*4882a593Smuzhiyun 		err = test_skcipher_vec(driver, enc, &suite->vecs[i], i, req,
3124*4882a593Smuzhiyun 					tsgls);
3125*4882a593Smuzhiyun 		if (err)
3126*4882a593Smuzhiyun 			return err;
3127*4882a593Smuzhiyun 		cond_resched();
3128*4882a593Smuzhiyun 	}
3129*4882a593Smuzhiyun 	return 0;
3130*4882a593Smuzhiyun }
3131*4882a593Smuzhiyun 
alg_test_skcipher(const struct alg_test_desc * desc,const char * driver,u32 type,u32 mask)3132*4882a593Smuzhiyun static int alg_test_skcipher(const struct alg_test_desc *desc,
3133*4882a593Smuzhiyun 			     const char *driver, u32 type, u32 mask)
3134*4882a593Smuzhiyun {
3135*4882a593Smuzhiyun 	const struct cipher_test_suite *suite = &desc->suite.cipher;
3136*4882a593Smuzhiyun 	struct crypto_skcipher *tfm;
3137*4882a593Smuzhiyun 	struct skcipher_request *req = NULL;
3138*4882a593Smuzhiyun 	struct cipher_test_sglists *tsgls = NULL;
3139*4882a593Smuzhiyun 	int err;
3140*4882a593Smuzhiyun 
3141*4882a593Smuzhiyun 	if (suite->count <= 0) {
3142*4882a593Smuzhiyun 		pr_err("alg: skcipher: empty test suite for %s\n", driver);
3143*4882a593Smuzhiyun 		return -EINVAL;
3144*4882a593Smuzhiyun 	}
3145*4882a593Smuzhiyun 
3146*4882a593Smuzhiyun 	tfm = crypto_alloc_skcipher(driver, type, mask);
3147*4882a593Smuzhiyun 	if (IS_ERR(tfm)) {
3148*4882a593Smuzhiyun 		pr_err("alg: skcipher: failed to allocate transform for %s: %ld\n",
3149*4882a593Smuzhiyun 		       driver, PTR_ERR(tfm));
3150*4882a593Smuzhiyun 		return PTR_ERR(tfm);
3151*4882a593Smuzhiyun 	}
3152*4882a593Smuzhiyun 
3153*4882a593Smuzhiyun 	req = skcipher_request_alloc(tfm, GFP_KERNEL);
3154*4882a593Smuzhiyun 	if (!req) {
3155*4882a593Smuzhiyun 		pr_err("alg: skcipher: failed to allocate request for %s\n",
3156*4882a593Smuzhiyun 		       driver);
3157*4882a593Smuzhiyun 		err = -ENOMEM;
3158*4882a593Smuzhiyun 		goto out;
3159*4882a593Smuzhiyun 	}
3160*4882a593Smuzhiyun 
3161*4882a593Smuzhiyun 	tsgls = alloc_cipher_test_sglists();
3162*4882a593Smuzhiyun 	if (!tsgls) {
3163*4882a593Smuzhiyun 		pr_err("alg: skcipher: failed to allocate test buffers for %s\n",
3164*4882a593Smuzhiyun 		       driver);
3165*4882a593Smuzhiyun 		err = -ENOMEM;
3166*4882a593Smuzhiyun 		goto out;
3167*4882a593Smuzhiyun 	}
3168*4882a593Smuzhiyun 
3169*4882a593Smuzhiyun 	err = test_skcipher(driver, ENCRYPT, suite, req, tsgls);
3170*4882a593Smuzhiyun 	if (err)
3171*4882a593Smuzhiyun 		goto out;
3172*4882a593Smuzhiyun 
3173*4882a593Smuzhiyun 	err = test_skcipher(driver, DECRYPT, suite, req, tsgls);
3174*4882a593Smuzhiyun 	if (err)
3175*4882a593Smuzhiyun 		goto out;
3176*4882a593Smuzhiyun 
3177*4882a593Smuzhiyun 	err = test_skcipher_vs_generic_impl(driver, desc->generic_driver, req,
3178*4882a593Smuzhiyun 					    tsgls);
3179*4882a593Smuzhiyun out:
3180*4882a593Smuzhiyun 	free_cipher_test_sglists(tsgls);
3181*4882a593Smuzhiyun 	skcipher_request_free(req);
3182*4882a593Smuzhiyun 	crypto_free_skcipher(tfm);
3183*4882a593Smuzhiyun 	return err;
3184*4882a593Smuzhiyun }
3185*4882a593Smuzhiyun 
test_comp(struct crypto_comp * tfm,const struct comp_testvec * ctemplate,const struct comp_testvec * dtemplate,int ctcount,int dtcount)3186*4882a593Smuzhiyun static int test_comp(struct crypto_comp *tfm,
3187*4882a593Smuzhiyun 		     const struct comp_testvec *ctemplate,
3188*4882a593Smuzhiyun 		     const struct comp_testvec *dtemplate,
3189*4882a593Smuzhiyun 		     int ctcount, int dtcount)
3190*4882a593Smuzhiyun {
3191*4882a593Smuzhiyun 	const char *algo = crypto_tfm_alg_driver_name(crypto_comp_tfm(tfm));
3192*4882a593Smuzhiyun 	char *output, *decomp_output;
3193*4882a593Smuzhiyun 	unsigned int i;
3194*4882a593Smuzhiyun 	int ret;
3195*4882a593Smuzhiyun 
3196*4882a593Smuzhiyun 	output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL);
3197*4882a593Smuzhiyun 	if (!output)
3198*4882a593Smuzhiyun 		return -ENOMEM;
3199*4882a593Smuzhiyun 
3200*4882a593Smuzhiyun 	decomp_output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL);
3201*4882a593Smuzhiyun 	if (!decomp_output) {
3202*4882a593Smuzhiyun 		kfree(output);
3203*4882a593Smuzhiyun 		return -ENOMEM;
3204*4882a593Smuzhiyun 	}
3205*4882a593Smuzhiyun 
3206*4882a593Smuzhiyun 	for (i = 0; i < ctcount; i++) {
3207*4882a593Smuzhiyun 		int ilen;
3208*4882a593Smuzhiyun 		unsigned int dlen = COMP_BUF_SIZE;
3209*4882a593Smuzhiyun 
3210*4882a593Smuzhiyun 		memset(output, 0, COMP_BUF_SIZE);
3211*4882a593Smuzhiyun 		memset(decomp_output, 0, COMP_BUF_SIZE);
3212*4882a593Smuzhiyun 
3213*4882a593Smuzhiyun 		ilen = ctemplate[i].inlen;
3214*4882a593Smuzhiyun 		ret = crypto_comp_compress(tfm, ctemplate[i].input,
3215*4882a593Smuzhiyun 					   ilen, output, &dlen);
3216*4882a593Smuzhiyun 		if (ret) {
3217*4882a593Smuzhiyun 			printk(KERN_ERR "alg: comp: compression failed "
3218*4882a593Smuzhiyun 			       "on test %d for %s: ret=%d\n", i + 1, algo,
3219*4882a593Smuzhiyun 			       -ret);
3220*4882a593Smuzhiyun 			goto out;
3221*4882a593Smuzhiyun 		}
3222*4882a593Smuzhiyun 
3223*4882a593Smuzhiyun 		ilen = dlen;
3224*4882a593Smuzhiyun 		dlen = COMP_BUF_SIZE;
3225*4882a593Smuzhiyun 		ret = crypto_comp_decompress(tfm, output,
3226*4882a593Smuzhiyun 					     ilen, decomp_output, &dlen);
3227*4882a593Smuzhiyun 		if (ret) {
3228*4882a593Smuzhiyun 			pr_err("alg: comp: compression failed: decompress: on test %d for %s failed: ret=%d\n",
3229*4882a593Smuzhiyun 			       i + 1, algo, -ret);
3230*4882a593Smuzhiyun 			goto out;
3231*4882a593Smuzhiyun 		}
3232*4882a593Smuzhiyun 
3233*4882a593Smuzhiyun 		if (dlen != ctemplate[i].inlen) {
3234*4882a593Smuzhiyun 			printk(KERN_ERR "alg: comp: Compression test %d "
3235*4882a593Smuzhiyun 			       "failed for %s: output len = %d\n", i + 1, algo,
3236*4882a593Smuzhiyun 			       dlen);
3237*4882a593Smuzhiyun 			ret = -EINVAL;
3238*4882a593Smuzhiyun 			goto out;
3239*4882a593Smuzhiyun 		}
3240*4882a593Smuzhiyun 
3241*4882a593Smuzhiyun 		if (memcmp(decomp_output, ctemplate[i].input,
3242*4882a593Smuzhiyun 			   ctemplate[i].inlen)) {
3243*4882a593Smuzhiyun 			pr_err("alg: comp: compression failed: output differs: on test %d for %s\n",
3244*4882a593Smuzhiyun 			       i + 1, algo);
3245*4882a593Smuzhiyun 			hexdump(decomp_output, dlen);
3246*4882a593Smuzhiyun 			ret = -EINVAL;
3247*4882a593Smuzhiyun 			goto out;
3248*4882a593Smuzhiyun 		}
3249*4882a593Smuzhiyun 	}
3250*4882a593Smuzhiyun 
3251*4882a593Smuzhiyun 	for (i = 0; i < dtcount; i++) {
3252*4882a593Smuzhiyun 		int ilen;
3253*4882a593Smuzhiyun 		unsigned int dlen = COMP_BUF_SIZE;
3254*4882a593Smuzhiyun 
3255*4882a593Smuzhiyun 		memset(decomp_output, 0, COMP_BUF_SIZE);
3256*4882a593Smuzhiyun 
3257*4882a593Smuzhiyun 		ilen = dtemplate[i].inlen;
3258*4882a593Smuzhiyun 		ret = crypto_comp_decompress(tfm, dtemplate[i].input,
3259*4882a593Smuzhiyun 					     ilen, decomp_output, &dlen);
3260*4882a593Smuzhiyun 		if (ret) {
3261*4882a593Smuzhiyun 			printk(KERN_ERR "alg: comp: decompression failed "
3262*4882a593Smuzhiyun 			       "on test %d for %s: ret=%d\n", i + 1, algo,
3263*4882a593Smuzhiyun 			       -ret);
3264*4882a593Smuzhiyun 			goto out;
3265*4882a593Smuzhiyun 		}
3266*4882a593Smuzhiyun 
3267*4882a593Smuzhiyun 		if (dlen != dtemplate[i].outlen) {
3268*4882a593Smuzhiyun 			printk(KERN_ERR "alg: comp: Decompression test %d "
3269*4882a593Smuzhiyun 			       "failed for %s: output len = %d\n", i + 1, algo,
3270*4882a593Smuzhiyun 			       dlen);
3271*4882a593Smuzhiyun 			ret = -EINVAL;
3272*4882a593Smuzhiyun 			goto out;
3273*4882a593Smuzhiyun 		}
3274*4882a593Smuzhiyun 
3275*4882a593Smuzhiyun 		if (memcmp(decomp_output, dtemplate[i].output, dlen)) {
3276*4882a593Smuzhiyun 			printk(KERN_ERR "alg: comp: Decompression test %d "
3277*4882a593Smuzhiyun 			       "failed for %s\n", i + 1, algo);
3278*4882a593Smuzhiyun 			hexdump(decomp_output, dlen);
3279*4882a593Smuzhiyun 			ret = -EINVAL;
3280*4882a593Smuzhiyun 			goto out;
3281*4882a593Smuzhiyun 		}
3282*4882a593Smuzhiyun 	}
3283*4882a593Smuzhiyun 
3284*4882a593Smuzhiyun 	ret = 0;
3285*4882a593Smuzhiyun 
3286*4882a593Smuzhiyun out:
3287*4882a593Smuzhiyun 	kfree(decomp_output);
3288*4882a593Smuzhiyun 	kfree(output);
3289*4882a593Smuzhiyun 	return ret;
3290*4882a593Smuzhiyun }
3291*4882a593Smuzhiyun 
test_acomp(struct crypto_acomp * tfm,const struct comp_testvec * ctemplate,const struct comp_testvec * dtemplate,int ctcount,int dtcount)3292*4882a593Smuzhiyun static int test_acomp(struct crypto_acomp *tfm,
3293*4882a593Smuzhiyun 			      const struct comp_testvec *ctemplate,
3294*4882a593Smuzhiyun 		      const struct comp_testvec *dtemplate,
3295*4882a593Smuzhiyun 		      int ctcount, int dtcount)
3296*4882a593Smuzhiyun {
3297*4882a593Smuzhiyun 	const char *algo = crypto_tfm_alg_driver_name(crypto_acomp_tfm(tfm));
3298*4882a593Smuzhiyun 	unsigned int i;
3299*4882a593Smuzhiyun 	char *output, *decomp_out;
3300*4882a593Smuzhiyun 	int ret;
3301*4882a593Smuzhiyun 	struct scatterlist src, dst;
3302*4882a593Smuzhiyun 	struct acomp_req *req;
3303*4882a593Smuzhiyun 	struct crypto_wait wait;
3304*4882a593Smuzhiyun 
3305*4882a593Smuzhiyun 	output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL);
3306*4882a593Smuzhiyun 	if (!output)
3307*4882a593Smuzhiyun 		return -ENOMEM;
3308*4882a593Smuzhiyun 
3309*4882a593Smuzhiyun 	decomp_out = kmalloc(COMP_BUF_SIZE, GFP_KERNEL);
3310*4882a593Smuzhiyun 	if (!decomp_out) {
3311*4882a593Smuzhiyun 		kfree(output);
3312*4882a593Smuzhiyun 		return -ENOMEM;
3313*4882a593Smuzhiyun 	}
3314*4882a593Smuzhiyun 
3315*4882a593Smuzhiyun 	for (i = 0; i < ctcount; i++) {
3316*4882a593Smuzhiyun 		unsigned int dlen = COMP_BUF_SIZE;
3317*4882a593Smuzhiyun 		int ilen = ctemplate[i].inlen;
3318*4882a593Smuzhiyun 		void *input_vec;
3319*4882a593Smuzhiyun 
3320*4882a593Smuzhiyun 		input_vec = kmemdup(ctemplate[i].input, ilen, GFP_KERNEL);
3321*4882a593Smuzhiyun 		if (!input_vec) {
3322*4882a593Smuzhiyun 			ret = -ENOMEM;
3323*4882a593Smuzhiyun 			goto out;
3324*4882a593Smuzhiyun 		}
3325*4882a593Smuzhiyun 
3326*4882a593Smuzhiyun 		memset(output, 0, dlen);
3327*4882a593Smuzhiyun 		crypto_init_wait(&wait);
3328*4882a593Smuzhiyun 		sg_init_one(&src, input_vec, ilen);
3329*4882a593Smuzhiyun 		sg_init_one(&dst, output, dlen);
3330*4882a593Smuzhiyun 
3331*4882a593Smuzhiyun 		req = acomp_request_alloc(tfm);
3332*4882a593Smuzhiyun 		if (!req) {
3333*4882a593Smuzhiyun 			pr_err("alg: acomp: request alloc failed for %s\n",
3334*4882a593Smuzhiyun 			       algo);
3335*4882a593Smuzhiyun 			kfree(input_vec);
3336*4882a593Smuzhiyun 			ret = -ENOMEM;
3337*4882a593Smuzhiyun 			goto out;
3338*4882a593Smuzhiyun 		}
3339*4882a593Smuzhiyun 
3340*4882a593Smuzhiyun 		acomp_request_set_params(req, &src, &dst, ilen, dlen);
3341*4882a593Smuzhiyun 		acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
3342*4882a593Smuzhiyun 					   crypto_req_done, &wait);
3343*4882a593Smuzhiyun 
3344*4882a593Smuzhiyun 		ret = crypto_wait_req(crypto_acomp_compress(req), &wait);
3345*4882a593Smuzhiyun 		if (ret) {
3346*4882a593Smuzhiyun 			pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n",
3347*4882a593Smuzhiyun 			       i + 1, algo, -ret);
3348*4882a593Smuzhiyun 			kfree(input_vec);
3349*4882a593Smuzhiyun 			acomp_request_free(req);
3350*4882a593Smuzhiyun 			goto out;
3351*4882a593Smuzhiyun 		}
3352*4882a593Smuzhiyun 
3353*4882a593Smuzhiyun 		ilen = req->dlen;
3354*4882a593Smuzhiyun 		dlen = COMP_BUF_SIZE;
3355*4882a593Smuzhiyun 		sg_init_one(&src, output, ilen);
3356*4882a593Smuzhiyun 		sg_init_one(&dst, decomp_out, dlen);
3357*4882a593Smuzhiyun 		crypto_init_wait(&wait);
3358*4882a593Smuzhiyun 		acomp_request_set_params(req, &src, &dst, ilen, dlen);
3359*4882a593Smuzhiyun 
3360*4882a593Smuzhiyun 		ret = crypto_wait_req(crypto_acomp_decompress(req), &wait);
3361*4882a593Smuzhiyun 		if (ret) {
3362*4882a593Smuzhiyun 			pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n",
3363*4882a593Smuzhiyun 			       i + 1, algo, -ret);
3364*4882a593Smuzhiyun 			kfree(input_vec);
3365*4882a593Smuzhiyun 			acomp_request_free(req);
3366*4882a593Smuzhiyun 			goto out;
3367*4882a593Smuzhiyun 		}
3368*4882a593Smuzhiyun 
3369*4882a593Smuzhiyun 		if (req->dlen != ctemplate[i].inlen) {
3370*4882a593Smuzhiyun 			pr_err("alg: acomp: Compression test %d failed for %s: output len = %d\n",
3371*4882a593Smuzhiyun 			       i + 1, algo, req->dlen);
3372*4882a593Smuzhiyun 			ret = -EINVAL;
3373*4882a593Smuzhiyun 			kfree(input_vec);
3374*4882a593Smuzhiyun 			acomp_request_free(req);
3375*4882a593Smuzhiyun 			goto out;
3376*4882a593Smuzhiyun 		}
3377*4882a593Smuzhiyun 
3378*4882a593Smuzhiyun 		if (memcmp(input_vec, decomp_out, req->dlen)) {
3379*4882a593Smuzhiyun 			pr_err("alg: acomp: Compression test %d failed for %s\n",
3380*4882a593Smuzhiyun 			       i + 1, algo);
3381*4882a593Smuzhiyun 			hexdump(output, req->dlen);
3382*4882a593Smuzhiyun 			ret = -EINVAL;
3383*4882a593Smuzhiyun 			kfree(input_vec);
3384*4882a593Smuzhiyun 			acomp_request_free(req);
3385*4882a593Smuzhiyun 			goto out;
3386*4882a593Smuzhiyun 		}
3387*4882a593Smuzhiyun 
3388*4882a593Smuzhiyun 		kfree(input_vec);
3389*4882a593Smuzhiyun 		acomp_request_free(req);
3390*4882a593Smuzhiyun 	}
3391*4882a593Smuzhiyun 
3392*4882a593Smuzhiyun 	for (i = 0; i < dtcount; i++) {
3393*4882a593Smuzhiyun 		unsigned int dlen = COMP_BUF_SIZE;
3394*4882a593Smuzhiyun 		int ilen = dtemplate[i].inlen;
3395*4882a593Smuzhiyun 		void *input_vec;
3396*4882a593Smuzhiyun 
3397*4882a593Smuzhiyun 		input_vec = kmemdup(dtemplate[i].input, ilen, GFP_KERNEL);
3398*4882a593Smuzhiyun 		if (!input_vec) {
3399*4882a593Smuzhiyun 			ret = -ENOMEM;
3400*4882a593Smuzhiyun 			goto out;
3401*4882a593Smuzhiyun 		}
3402*4882a593Smuzhiyun 
3403*4882a593Smuzhiyun 		memset(output, 0, dlen);
3404*4882a593Smuzhiyun 		crypto_init_wait(&wait);
3405*4882a593Smuzhiyun 		sg_init_one(&src, input_vec, ilen);
3406*4882a593Smuzhiyun 		sg_init_one(&dst, output, dlen);
3407*4882a593Smuzhiyun 
3408*4882a593Smuzhiyun 		req = acomp_request_alloc(tfm);
3409*4882a593Smuzhiyun 		if (!req) {
3410*4882a593Smuzhiyun 			pr_err("alg: acomp: request alloc failed for %s\n",
3411*4882a593Smuzhiyun 			       algo);
3412*4882a593Smuzhiyun 			kfree(input_vec);
3413*4882a593Smuzhiyun 			ret = -ENOMEM;
3414*4882a593Smuzhiyun 			goto out;
3415*4882a593Smuzhiyun 		}
3416*4882a593Smuzhiyun 
3417*4882a593Smuzhiyun 		acomp_request_set_params(req, &src, &dst, ilen, dlen);
3418*4882a593Smuzhiyun 		acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
3419*4882a593Smuzhiyun 					   crypto_req_done, &wait);
3420*4882a593Smuzhiyun 
3421*4882a593Smuzhiyun 		ret = crypto_wait_req(crypto_acomp_decompress(req), &wait);
3422*4882a593Smuzhiyun 		if (ret) {
3423*4882a593Smuzhiyun 			pr_err("alg: acomp: decompression failed on test %d for %s: ret=%d\n",
3424*4882a593Smuzhiyun 			       i + 1, algo, -ret);
3425*4882a593Smuzhiyun 			kfree(input_vec);
3426*4882a593Smuzhiyun 			acomp_request_free(req);
3427*4882a593Smuzhiyun 			goto out;
3428*4882a593Smuzhiyun 		}
3429*4882a593Smuzhiyun 
3430*4882a593Smuzhiyun 		if (req->dlen != dtemplate[i].outlen) {
3431*4882a593Smuzhiyun 			pr_err("alg: acomp: Decompression test %d failed for %s: output len = %d\n",
3432*4882a593Smuzhiyun 			       i + 1, algo, req->dlen);
3433*4882a593Smuzhiyun 			ret = -EINVAL;
3434*4882a593Smuzhiyun 			kfree(input_vec);
3435*4882a593Smuzhiyun 			acomp_request_free(req);
3436*4882a593Smuzhiyun 			goto out;
3437*4882a593Smuzhiyun 		}
3438*4882a593Smuzhiyun 
3439*4882a593Smuzhiyun 		if (memcmp(output, dtemplate[i].output, req->dlen)) {
3440*4882a593Smuzhiyun 			pr_err("alg: acomp: Decompression test %d failed for %s\n",
3441*4882a593Smuzhiyun 			       i + 1, algo);
3442*4882a593Smuzhiyun 			hexdump(output, req->dlen);
3443*4882a593Smuzhiyun 			ret = -EINVAL;
3444*4882a593Smuzhiyun 			kfree(input_vec);
3445*4882a593Smuzhiyun 			acomp_request_free(req);
3446*4882a593Smuzhiyun 			goto out;
3447*4882a593Smuzhiyun 		}
3448*4882a593Smuzhiyun 
3449*4882a593Smuzhiyun 		kfree(input_vec);
3450*4882a593Smuzhiyun 		acomp_request_free(req);
3451*4882a593Smuzhiyun 	}
3452*4882a593Smuzhiyun 
3453*4882a593Smuzhiyun 	ret = 0;
3454*4882a593Smuzhiyun 
3455*4882a593Smuzhiyun out:
3456*4882a593Smuzhiyun 	kfree(decomp_out);
3457*4882a593Smuzhiyun 	kfree(output);
3458*4882a593Smuzhiyun 	return ret;
3459*4882a593Smuzhiyun }
3460*4882a593Smuzhiyun 
test_cprng(struct crypto_rng * tfm,const struct cprng_testvec * template,unsigned int tcount)3461*4882a593Smuzhiyun static int test_cprng(struct crypto_rng *tfm,
3462*4882a593Smuzhiyun 		      const struct cprng_testvec *template,
3463*4882a593Smuzhiyun 		      unsigned int tcount)
3464*4882a593Smuzhiyun {
3465*4882a593Smuzhiyun 	const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm));
3466*4882a593Smuzhiyun 	int err = 0, i, j, seedsize;
3467*4882a593Smuzhiyun 	u8 *seed;
3468*4882a593Smuzhiyun 	char result[32];
3469*4882a593Smuzhiyun 
3470*4882a593Smuzhiyun 	seedsize = crypto_rng_seedsize(tfm);
3471*4882a593Smuzhiyun 
3472*4882a593Smuzhiyun 	seed = kmalloc(seedsize, GFP_KERNEL);
3473*4882a593Smuzhiyun 	if (!seed) {
3474*4882a593Smuzhiyun 		printk(KERN_ERR "alg: cprng: Failed to allocate seed space "
3475*4882a593Smuzhiyun 		       "for %s\n", algo);
3476*4882a593Smuzhiyun 		return -ENOMEM;
3477*4882a593Smuzhiyun 	}
3478*4882a593Smuzhiyun 
3479*4882a593Smuzhiyun 	for (i = 0; i < tcount; i++) {
3480*4882a593Smuzhiyun 		memset(result, 0, 32);
3481*4882a593Smuzhiyun 
3482*4882a593Smuzhiyun 		memcpy(seed, template[i].v, template[i].vlen);
3483*4882a593Smuzhiyun 		memcpy(seed + template[i].vlen, template[i].key,
3484*4882a593Smuzhiyun 		       template[i].klen);
3485*4882a593Smuzhiyun 		memcpy(seed + template[i].vlen + template[i].klen,
3486*4882a593Smuzhiyun 		       template[i].dt, template[i].dtlen);
3487*4882a593Smuzhiyun 
3488*4882a593Smuzhiyun 		err = crypto_rng_reset(tfm, seed, seedsize);
3489*4882a593Smuzhiyun 		if (err) {
3490*4882a593Smuzhiyun 			printk(KERN_ERR "alg: cprng: Failed to reset rng "
3491*4882a593Smuzhiyun 			       "for %s\n", algo);
3492*4882a593Smuzhiyun 			goto out;
3493*4882a593Smuzhiyun 		}
3494*4882a593Smuzhiyun 
3495*4882a593Smuzhiyun 		for (j = 0; j < template[i].loops; j++) {
3496*4882a593Smuzhiyun 			err = crypto_rng_get_bytes(tfm, result,
3497*4882a593Smuzhiyun 						   template[i].rlen);
3498*4882a593Smuzhiyun 			if (err < 0) {
3499*4882a593Smuzhiyun 				printk(KERN_ERR "alg: cprng: Failed to obtain "
3500*4882a593Smuzhiyun 				       "the correct amount of random data for "
3501*4882a593Smuzhiyun 				       "%s (requested %d)\n", algo,
3502*4882a593Smuzhiyun 				       template[i].rlen);
3503*4882a593Smuzhiyun 				goto out;
3504*4882a593Smuzhiyun 			}
3505*4882a593Smuzhiyun 		}
3506*4882a593Smuzhiyun 
3507*4882a593Smuzhiyun 		err = memcmp(result, template[i].result,
3508*4882a593Smuzhiyun 			     template[i].rlen);
3509*4882a593Smuzhiyun 		if (err) {
3510*4882a593Smuzhiyun 			printk(KERN_ERR "alg: cprng: Test %d failed for %s\n",
3511*4882a593Smuzhiyun 			       i, algo);
3512*4882a593Smuzhiyun 			hexdump(result, template[i].rlen);
3513*4882a593Smuzhiyun 			err = -EINVAL;
3514*4882a593Smuzhiyun 			goto out;
3515*4882a593Smuzhiyun 		}
3516*4882a593Smuzhiyun 	}
3517*4882a593Smuzhiyun 
3518*4882a593Smuzhiyun out:
3519*4882a593Smuzhiyun 	kfree(seed);
3520*4882a593Smuzhiyun 	return err;
3521*4882a593Smuzhiyun }
3522*4882a593Smuzhiyun 
alg_test_cipher(const struct alg_test_desc * desc,const char * driver,u32 type,u32 mask)3523*4882a593Smuzhiyun static int alg_test_cipher(const struct alg_test_desc *desc,
3524*4882a593Smuzhiyun 			   const char *driver, u32 type, u32 mask)
3525*4882a593Smuzhiyun {
3526*4882a593Smuzhiyun 	const struct cipher_test_suite *suite = &desc->suite.cipher;
3527*4882a593Smuzhiyun 	struct crypto_cipher *tfm;
3528*4882a593Smuzhiyun 	int err;
3529*4882a593Smuzhiyun 
3530*4882a593Smuzhiyun 	tfm = crypto_alloc_cipher(driver, type, mask);
3531*4882a593Smuzhiyun 	if (IS_ERR(tfm)) {
3532*4882a593Smuzhiyun 		printk(KERN_ERR "alg: cipher: Failed to load transform for "
3533*4882a593Smuzhiyun 		       "%s: %ld\n", driver, PTR_ERR(tfm));
3534*4882a593Smuzhiyun 		return PTR_ERR(tfm);
3535*4882a593Smuzhiyun 	}
3536*4882a593Smuzhiyun 
3537*4882a593Smuzhiyun 	err = test_cipher(tfm, ENCRYPT, suite->vecs, suite->count);
3538*4882a593Smuzhiyun 	if (!err)
3539*4882a593Smuzhiyun 		err = test_cipher(tfm, DECRYPT, suite->vecs, suite->count);
3540*4882a593Smuzhiyun 
3541*4882a593Smuzhiyun 	crypto_free_cipher(tfm);
3542*4882a593Smuzhiyun 	return err;
3543*4882a593Smuzhiyun }
3544*4882a593Smuzhiyun 
alg_test_comp(const struct alg_test_desc * desc,const char * driver,u32 type,u32 mask)3545*4882a593Smuzhiyun static int alg_test_comp(const struct alg_test_desc *desc, const char *driver,
3546*4882a593Smuzhiyun 			 u32 type, u32 mask)
3547*4882a593Smuzhiyun {
3548*4882a593Smuzhiyun 	struct crypto_comp *comp;
3549*4882a593Smuzhiyun 	struct crypto_acomp *acomp;
3550*4882a593Smuzhiyun 	int err;
3551*4882a593Smuzhiyun 	u32 algo_type = type & CRYPTO_ALG_TYPE_ACOMPRESS_MASK;
3552*4882a593Smuzhiyun 
3553*4882a593Smuzhiyun 	if (algo_type == CRYPTO_ALG_TYPE_ACOMPRESS) {
3554*4882a593Smuzhiyun 		acomp = crypto_alloc_acomp(driver, type, mask);
3555*4882a593Smuzhiyun 		if (IS_ERR(acomp)) {
3556*4882a593Smuzhiyun 			pr_err("alg: acomp: Failed to load transform for %s: %ld\n",
3557*4882a593Smuzhiyun 			       driver, PTR_ERR(acomp));
3558*4882a593Smuzhiyun 			return PTR_ERR(acomp);
3559*4882a593Smuzhiyun 		}
3560*4882a593Smuzhiyun 		err = test_acomp(acomp, desc->suite.comp.comp.vecs,
3561*4882a593Smuzhiyun 				 desc->suite.comp.decomp.vecs,
3562*4882a593Smuzhiyun 				 desc->suite.comp.comp.count,
3563*4882a593Smuzhiyun 				 desc->suite.comp.decomp.count);
3564*4882a593Smuzhiyun 		crypto_free_acomp(acomp);
3565*4882a593Smuzhiyun 	} else {
3566*4882a593Smuzhiyun 		comp = crypto_alloc_comp(driver, type, mask);
3567*4882a593Smuzhiyun 		if (IS_ERR(comp)) {
3568*4882a593Smuzhiyun 			pr_err("alg: comp: Failed to load transform for %s: %ld\n",
3569*4882a593Smuzhiyun 			       driver, PTR_ERR(comp));
3570*4882a593Smuzhiyun 			return PTR_ERR(comp);
3571*4882a593Smuzhiyun 		}
3572*4882a593Smuzhiyun 
3573*4882a593Smuzhiyun 		err = test_comp(comp, desc->suite.comp.comp.vecs,
3574*4882a593Smuzhiyun 				desc->suite.comp.decomp.vecs,
3575*4882a593Smuzhiyun 				desc->suite.comp.comp.count,
3576*4882a593Smuzhiyun 				desc->suite.comp.decomp.count);
3577*4882a593Smuzhiyun 
3578*4882a593Smuzhiyun 		crypto_free_comp(comp);
3579*4882a593Smuzhiyun 	}
3580*4882a593Smuzhiyun 	return err;
3581*4882a593Smuzhiyun }
3582*4882a593Smuzhiyun 
alg_test_crc32c(const struct alg_test_desc * desc,const char * driver,u32 type,u32 mask)3583*4882a593Smuzhiyun static int alg_test_crc32c(const struct alg_test_desc *desc,
3584*4882a593Smuzhiyun 			   const char *driver, u32 type, u32 mask)
3585*4882a593Smuzhiyun {
3586*4882a593Smuzhiyun 	struct crypto_shash *tfm;
3587*4882a593Smuzhiyun 	__le32 val;
3588*4882a593Smuzhiyun 	int err;
3589*4882a593Smuzhiyun 
3590*4882a593Smuzhiyun 	err = alg_test_hash(desc, driver, type, mask);
3591*4882a593Smuzhiyun 	if (err)
3592*4882a593Smuzhiyun 		return err;
3593*4882a593Smuzhiyun 
3594*4882a593Smuzhiyun 	tfm = crypto_alloc_shash(driver, type, mask);
3595*4882a593Smuzhiyun 	if (IS_ERR(tfm)) {
3596*4882a593Smuzhiyun 		if (PTR_ERR(tfm) == -ENOENT) {
3597*4882a593Smuzhiyun 			/*
3598*4882a593Smuzhiyun 			 * This crc32c implementation is only available through
3599*4882a593Smuzhiyun 			 * ahash API, not the shash API, so the remaining part
3600*4882a593Smuzhiyun 			 * of the test is not applicable to it.
3601*4882a593Smuzhiyun 			 */
3602*4882a593Smuzhiyun 			return 0;
3603*4882a593Smuzhiyun 		}
3604*4882a593Smuzhiyun 		printk(KERN_ERR "alg: crc32c: Failed to load transform for %s: "
3605*4882a593Smuzhiyun 		       "%ld\n", driver, PTR_ERR(tfm));
3606*4882a593Smuzhiyun 		return PTR_ERR(tfm);
3607*4882a593Smuzhiyun 	}
3608*4882a593Smuzhiyun 
3609*4882a593Smuzhiyun 	do {
3610*4882a593Smuzhiyun 		SHASH_DESC_ON_STACK(shash, tfm);
3611*4882a593Smuzhiyun 		u32 *ctx = (u32 *)shash_desc_ctx(shash);
3612*4882a593Smuzhiyun 
3613*4882a593Smuzhiyun 		shash->tfm = tfm;
3614*4882a593Smuzhiyun 
3615*4882a593Smuzhiyun 		*ctx = 420553207;
3616*4882a593Smuzhiyun 		err = crypto_shash_final(shash, (u8 *)&val);
3617*4882a593Smuzhiyun 		if (err) {
3618*4882a593Smuzhiyun 			printk(KERN_ERR "alg: crc32c: Operation failed for "
3619*4882a593Smuzhiyun 			       "%s: %d\n", driver, err);
3620*4882a593Smuzhiyun 			break;
3621*4882a593Smuzhiyun 		}
3622*4882a593Smuzhiyun 
3623*4882a593Smuzhiyun 		if (val != cpu_to_le32(~420553207)) {
3624*4882a593Smuzhiyun 			pr_err("alg: crc32c: Test failed for %s: %u\n",
3625*4882a593Smuzhiyun 			       driver, le32_to_cpu(val));
3626*4882a593Smuzhiyun 			err = -EINVAL;
3627*4882a593Smuzhiyun 		}
3628*4882a593Smuzhiyun 	} while (0);
3629*4882a593Smuzhiyun 
3630*4882a593Smuzhiyun 	crypto_free_shash(tfm);
3631*4882a593Smuzhiyun 
3632*4882a593Smuzhiyun 	return err;
3633*4882a593Smuzhiyun }
3634*4882a593Smuzhiyun 
alg_test_cprng(const struct alg_test_desc * desc,const char * driver,u32 type,u32 mask)3635*4882a593Smuzhiyun static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver,
3636*4882a593Smuzhiyun 			  u32 type, u32 mask)
3637*4882a593Smuzhiyun {
3638*4882a593Smuzhiyun 	struct crypto_rng *rng;
3639*4882a593Smuzhiyun 	int err;
3640*4882a593Smuzhiyun 
3641*4882a593Smuzhiyun 	rng = crypto_alloc_rng(driver, type, mask);
3642*4882a593Smuzhiyun 	if (IS_ERR(rng)) {
3643*4882a593Smuzhiyun 		printk(KERN_ERR "alg: cprng: Failed to load transform for %s: "
3644*4882a593Smuzhiyun 		       "%ld\n", driver, PTR_ERR(rng));
3645*4882a593Smuzhiyun 		return PTR_ERR(rng);
3646*4882a593Smuzhiyun 	}
3647*4882a593Smuzhiyun 
3648*4882a593Smuzhiyun 	err = test_cprng(rng, desc->suite.cprng.vecs, desc->suite.cprng.count);
3649*4882a593Smuzhiyun 
3650*4882a593Smuzhiyun 	crypto_free_rng(rng);
3651*4882a593Smuzhiyun 
3652*4882a593Smuzhiyun 	return err;
3653*4882a593Smuzhiyun }
3654*4882a593Smuzhiyun 
3655*4882a593Smuzhiyun 
drbg_cavs_test(const struct drbg_testvec * test,int pr,const char * driver,u32 type,u32 mask)3656*4882a593Smuzhiyun static int drbg_cavs_test(const struct drbg_testvec *test, int pr,
3657*4882a593Smuzhiyun 			  const char *driver, u32 type, u32 mask)
3658*4882a593Smuzhiyun {
3659*4882a593Smuzhiyun 	int ret = -EAGAIN;
3660*4882a593Smuzhiyun 	struct crypto_rng *drng;
3661*4882a593Smuzhiyun 	struct drbg_test_data test_data;
3662*4882a593Smuzhiyun 	struct drbg_string addtl, pers, testentropy;
3663*4882a593Smuzhiyun 	unsigned char *buf = kzalloc(test->expectedlen, GFP_KERNEL);
3664*4882a593Smuzhiyun 
3665*4882a593Smuzhiyun 	if (!buf)
3666*4882a593Smuzhiyun 		return -ENOMEM;
3667*4882a593Smuzhiyun 
3668*4882a593Smuzhiyun 	drng = crypto_alloc_rng(driver, type, mask);
3669*4882a593Smuzhiyun 	if (IS_ERR(drng)) {
3670*4882a593Smuzhiyun 		printk(KERN_ERR "alg: drbg: could not allocate DRNG handle for "
3671*4882a593Smuzhiyun 		       "%s\n", driver);
3672*4882a593Smuzhiyun 		kfree_sensitive(buf);
3673*4882a593Smuzhiyun 		return -ENOMEM;
3674*4882a593Smuzhiyun 	}
3675*4882a593Smuzhiyun 
3676*4882a593Smuzhiyun 	test_data.testentropy = &testentropy;
3677*4882a593Smuzhiyun 	drbg_string_fill(&testentropy, test->entropy, test->entropylen);
3678*4882a593Smuzhiyun 	drbg_string_fill(&pers, test->pers, test->perslen);
3679*4882a593Smuzhiyun 	ret = crypto_drbg_reset_test(drng, &pers, &test_data);
3680*4882a593Smuzhiyun 	if (ret) {
3681*4882a593Smuzhiyun 		printk(KERN_ERR "alg: drbg: Failed to reset rng\n");
3682*4882a593Smuzhiyun 		goto outbuf;
3683*4882a593Smuzhiyun 	}
3684*4882a593Smuzhiyun 
3685*4882a593Smuzhiyun 	drbg_string_fill(&addtl, test->addtla, test->addtllen);
3686*4882a593Smuzhiyun 	if (pr) {
3687*4882a593Smuzhiyun 		drbg_string_fill(&testentropy, test->entpra, test->entprlen);
3688*4882a593Smuzhiyun 		ret = crypto_drbg_get_bytes_addtl_test(drng,
3689*4882a593Smuzhiyun 			buf, test->expectedlen, &addtl,	&test_data);
3690*4882a593Smuzhiyun 	} else {
3691*4882a593Smuzhiyun 		ret = crypto_drbg_get_bytes_addtl(drng,
3692*4882a593Smuzhiyun 			buf, test->expectedlen, &addtl);
3693*4882a593Smuzhiyun 	}
3694*4882a593Smuzhiyun 	if (ret < 0) {
3695*4882a593Smuzhiyun 		printk(KERN_ERR "alg: drbg: could not obtain random data for "
3696*4882a593Smuzhiyun 		       "driver %s\n", driver);
3697*4882a593Smuzhiyun 		goto outbuf;
3698*4882a593Smuzhiyun 	}
3699*4882a593Smuzhiyun 
3700*4882a593Smuzhiyun 	drbg_string_fill(&addtl, test->addtlb, test->addtllen);
3701*4882a593Smuzhiyun 	if (pr) {
3702*4882a593Smuzhiyun 		drbg_string_fill(&testentropy, test->entprb, test->entprlen);
3703*4882a593Smuzhiyun 		ret = crypto_drbg_get_bytes_addtl_test(drng,
3704*4882a593Smuzhiyun 			buf, test->expectedlen, &addtl, &test_data);
3705*4882a593Smuzhiyun 	} else {
3706*4882a593Smuzhiyun 		ret = crypto_drbg_get_bytes_addtl(drng,
3707*4882a593Smuzhiyun 			buf, test->expectedlen, &addtl);
3708*4882a593Smuzhiyun 	}
3709*4882a593Smuzhiyun 	if (ret < 0) {
3710*4882a593Smuzhiyun 		printk(KERN_ERR "alg: drbg: could not obtain random data for "
3711*4882a593Smuzhiyun 		       "driver %s\n", driver);
3712*4882a593Smuzhiyun 		goto outbuf;
3713*4882a593Smuzhiyun 	}
3714*4882a593Smuzhiyun 
3715*4882a593Smuzhiyun 	ret = memcmp(test->expected, buf, test->expectedlen);
3716*4882a593Smuzhiyun 
3717*4882a593Smuzhiyun outbuf:
3718*4882a593Smuzhiyun 	crypto_free_rng(drng);
3719*4882a593Smuzhiyun 	kfree_sensitive(buf);
3720*4882a593Smuzhiyun 	return ret;
3721*4882a593Smuzhiyun }
3722*4882a593Smuzhiyun 
3723*4882a593Smuzhiyun 
alg_test_drbg(const struct alg_test_desc * desc,const char * driver,u32 type,u32 mask)3724*4882a593Smuzhiyun static int alg_test_drbg(const struct alg_test_desc *desc, const char *driver,
3725*4882a593Smuzhiyun 			 u32 type, u32 mask)
3726*4882a593Smuzhiyun {
3727*4882a593Smuzhiyun 	int err = 0;
3728*4882a593Smuzhiyun 	int pr = 0;
3729*4882a593Smuzhiyun 	int i = 0;
3730*4882a593Smuzhiyun 	const struct drbg_testvec *template = desc->suite.drbg.vecs;
3731*4882a593Smuzhiyun 	unsigned int tcount = desc->suite.drbg.count;
3732*4882a593Smuzhiyun 
3733*4882a593Smuzhiyun 	if (0 == memcmp(driver, "drbg_pr_", 8))
3734*4882a593Smuzhiyun 		pr = 1;
3735*4882a593Smuzhiyun 
3736*4882a593Smuzhiyun 	for (i = 0; i < tcount; i++) {
3737*4882a593Smuzhiyun 		err = drbg_cavs_test(&template[i], pr, driver, type, mask);
3738*4882a593Smuzhiyun 		if (err) {
3739*4882a593Smuzhiyun 			printk(KERN_ERR "alg: drbg: Test %d failed for %s\n",
3740*4882a593Smuzhiyun 			       i, driver);
3741*4882a593Smuzhiyun 			err = -EINVAL;
3742*4882a593Smuzhiyun 			break;
3743*4882a593Smuzhiyun 		}
3744*4882a593Smuzhiyun 	}
3745*4882a593Smuzhiyun 	return err;
3746*4882a593Smuzhiyun 
3747*4882a593Smuzhiyun }
3748*4882a593Smuzhiyun 
do_test_kpp(struct crypto_kpp * tfm,const struct kpp_testvec * vec,const char * alg)3749*4882a593Smuzhiyun static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec,
3750*4882a593Smuzhiyun 		       const char *alg)
3751*4882a593Smuzhiyun {
3752*4882a593Smuzhiyun 	struct kpp_request *req;
3753*4882a593Smuzhiyun 	void *input_buf = NULL;
3754*4882a593Smuzhiyun 	void *output_buf = NULL;
3755*4882a593Smuzhiyun 	void *a_public = NULL;
3756*4882a593Smuzhiyun 	void *a_ss = NULL;
3757*4882a593Smuzhiyun 	void *shared_secret = NULL;
3758*4882a593Smuzhiyun 	struct crypto_wait wait;
3759*4882a593Smuzhiyun 	unsigned int out_len_max;
3760*4882a593Smuzhiyun 	int err = -ENOMEM;
3761*4882a593Smuzhiyun 	struct scatterlist src, dst;
3762*4882a593Smuzhiyun 
3763*4882a593Smuzhiyun 	req = kpp_request_alloc(tfm, GFP_KERNEL);
3764*4882a593Smuzhiyun 	if (!req)
3765*4882a593Smuzhiyun 		return err;
3766*4882a593Smuzhiyun 
3767*4882a593Smuzhiyun 	crypto_init_wait(&wait);
3768*4882a593Smuzhiyun 
3769*4882a593Smuzhiyun 	err = crypto_kpp_set_secret(tfm, vec->secret, vec->secret_size);
3770*4882a593Smuzhiyun 	if (err < 0)
3771*4882a593Smuzhiyun 		goto free_req;
3772*4882a593Smuzhiyun 
3773*4882a593Smuzhiyun 	out_len_max = crypto_kpp_maxsize(tfm);
3774*4882a593Smuzhiyun 	output_buf = kzalloc(out_len_max, GFP_KERNEL);
3775*4882a593Smuzhiyun 	if (!output_buf) {
3776*4882a593Smuzhiyun 		err = -ENOMEM;
3777*4882a593Smuzhiyun 		goto free_req;
3778*4882a593Smuzhiyun 	}
3779*4882a593Smuzhiyun 
3780*4882a593Smuzhiyun 	/* Use appropriate parameter as base */
3781*4882a593Smuzhiyun 	kpp_request_set_input(req, NULL, 0);
3782*4882a593Smuzhiyun 	sg_init_one(&dst, output_buf, out_len_max);
3783*4882a593Smuzhiyun 	kpp_request_set_output(req, &dst, out_len_max);
3784*4882a593Smuzhiyun 	kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
3785*4882a593Smuzhiyun 				 crypto_req_done, &wait);
3786*4882a593Smuzhiyun 
3787*4882a593Smuzhiyun 	/* Compute party A's public key */
3788*4882a593Smuzhiyun 	err = crypto_wait_req(crypto_kpp_generate_public_key(req), &wait);
3789*4882a593Smuzhiyun 	if (err) {
3790*4882a593Smuzhiyun 		pr_err("alg: %s: Party A: generate public key test failed. err %d\n",
3791*4882a593Smuzhiyun 		       alg, err);
3792*4882a593Smuzhiyun 		goto free_output;
3793*4882a593Smuzhiyun 	}
3794*4882a593Smuzhiyun 
3795*4882a593Smuzhiyun 	if (vec->genkey) {
3796*4882a593Smuzhiyun 		/* Save party A's public key */
3797*4882a593Smuzhiyun 		a_public = kmemdup(sg_virt(req->dst), out_len_max, GFP_KERNEL);
3798*4882a593Smuzhiyun 		if (!a_public) {
3799*4882a593Smuzhiyun 			err = -ENOMEM;
3800*4882a593Smuzhiyun 			goto free_output;
3801*4882a593Smuzhiyun 		}
3802*4882a593Smuzhiyun 	} else {
3803*4882a593Smuzhiyun 		/* Verify calculated public key */
3804*4882a593Smuzhiyun 		if (memcmp(vec->expected_a_public, sg_virt(req->dst),
3805*4882a593Smuzhiyun 			   vec->expected_a_public_size)) {
3806*4882a593Smuzhiyun 			pr_err("alg: %s: Party A: generate public key test failed. Invalid output\n",
3807*4882a593Smuzhiyun 			       alg);
3808*4882a593Smuzhiyun 			err = -EINVAL;
3809*4882a593Smuzhiyun 			goto free_output;
3810*4882a593Smuzhiyun 		}
3811*4882a593Smuzhiyun 	}
3812*4882a593Smuzhiyun 
3813*4882a593Smuzhiyun 	/* Calculate shared secret key by using counter part (b) public key. */
3814*4882a593Smuzhiyun 	input_buf = kmemdup(vec->b_public, vec->b_public_size, GFP_KERNEL);
3815*4882a593Smuzhiyun 	if (!input_buf) {
3816*4882a593Smuzhiyun 		err = -ENOMEM;
3817*4882a593Smuzhiyun 		goto free_output;
3818*4882a593Smuzhiyun 	}
3819*4882a593Smuzhiyun 
3820*4882a593Smuzhiyun 	sg_init_one(&src, input_buf, vec->b_public_size);
3821*4882a593Smuzhiyun 	sg_init_one(&dst, output_buf, out_len_max);
3822*4882a593Smuzhiyun 	kpp_request_set_input(req, &src, vec->b_public_size);
3823*4882a593Smuzhiyun 	kpp_request_set_output(req, &dst, out_len_max);
3824*4882a593Smuzhiyun 	kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
3825*4882a593Smuzhiyun 				 crypto_req_done, &wait);
3826*4882a593Smuzhiyun 	err = crypto_wait_req(crypto_kpp_compute_shared_secret(req), &wait);
3827*4882a593Smuzhiyun 	if (err) {
3828*4882a593Smuzhiyun 		pr_err("alg: %s: Party A: compute shared secret test failed. err %d\n",
3829*4882a593Smuzhiyun 		       alg, err);
3830*4882a593Smuzhiyun 		goto free_all;
3831*4882a593Smuzhiyun 	}
3832*4882a593Smuzhiyun 
3833*4882a593Smuzhiyun 	if (vec->genkey) {
3834*4882a593Smuzhiyun 		/* Save the shared secret obtained by party A */
3835*4882a593Smuzhiyun 		a_ss = kmemdup(sg_virt(req->dst), vec->expected_ss_size, GFP_KERNEL);
3836*4882a593Smuzhiyun 		if (!a_ss) {
3837*4882a593Smuzhiyun 			err = -ENOMEM;
3838*4882a593Smuzhiyun 			goto free_all;
3839*4882a593Smuzhiyun 		}
3840*4882a593Smuzhiyun 
3841*4882a593Smuzhiyun 		/*
3842*4882a593Smuzhiyun 		 * Calculate party B's shared secret by using party A's
3843*4882a593Smuzhiyun 		 * public key.
3844*4882a593Smuzhiyun 		 */
3845*4882a593Smuzhiyun 		err = crypto_kpp_set_secret(tfm, vec->b_secret,
3846*4882a593Smuzhiyun 					    vec->b_secret_size);
3847*4882a593Smuzhiyun 		if (err < 0)
3848*4882a593Smuzhiyun 			goto free_all;
3849*4882a593Smuzhiyun 
3850*4882a593Smuzhiyun 		sg_init_one(&src, a_public, vec->expected_a_public_size);
3851*4882a593Smuzhiyun 		sg_init_one(&dst, output_buf, out_len_max);
3852*4882a593Smuzhiyun 		kpp_request_set_input(req, &src, vec->expected_a_public_size);
3853*4882a593Smuzhiyun 		kpp_request_set_output(req, &dst, out_len_max);
3854*4882a593Smuzhiyun 		kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
3855*4882a593Smuzhiyun 					 crypto_req_done, &wait);
3856*4882a593Smuzhiyun 		err = crypto_wait_req(crypto_kpp_compute_shared_secret(req),
3857*4882a593Smuzhiyun 				      &wait);
3858*4882a593Smuzhiyun 		if (err) {
3859*4882a593Smuzhiyun 			pr_err("alg: %s: Party B: compute shared secret failed. err %d\n",
3860*4882a593Smuzhiyun 			       alg, err);
3861*4882a593Smuzhiyun 			goto free_all;
3862*4882a593Smuzhiyun 		}
3863*4882a593Smuzhiyun 
3864*4882a593Smuzhiyun 		shared_secret = a_ss;
3865*4882a593Smuzhiyun 	} else {
3866*4882a593Smuzhiyun 		shared_secret = (void *)vec->expected_ss;
3867*4882a593Smuzhiyun 	}
3868*4882a593Smuzhiyun 
3869*4882a593Smuzhiyun 	/*
3870*4882a593Smuzhiyun 	 * verify shared secret from which the user will derive
3871*4882a593Smuzhiyun 	 * secret key by executing whatever hash it has chosen
3872*4882a593Smuzhiyun 	 */
3873*4882a593Smuzhiyun 	if (memcmp(shared_secret, sg_virt(req->dst),
3874*4882a593Smuzhiyun 		   vec->expected_ss_size)) {
3875*4882a593Smuzhiyun 		pr_err("alg: %s: compute shared secret test failed. Invalid output\n",
3876*4882a593Smuzhiyun 		       alg);
3877*4882a593Smuzhiyun 		err = -EINVAL;
3878*4882a593Smuzhiyun 	}
3879*4882a593Smuzhiyun 
3880*4882a593Smuzhiyun free_all:
3881*4882a593Smuzhiyun 	kfree(a_ss);
3882*4882a593Smuzhiyun 	kfree(input_buf);
3883*4882a593Smuzhiyun free_output:
3884*4882a593Smuzhiyun 	kfree(a_public);
3885*4882a593Smuzhiyun 	kfree(output_buf);
3886*4882a593Smuzhiyun free_req:
3887*4882a593Smuzhiyun 	kpp_request_free(req);
3888*4882a593Smuzhiyun 	return err;
3889*4882a593Smuzhiyun }
3890*4882a593Smuzhiyun 
test_kpp(struct crypto_kpp * tfm,const char * alg,const struct kpp_testvec * vecs,unsigned int tcount)3891*4882a593Smuzhiyun static int test_kpp(struct crypto_kpp *tfm, const char *alg,
3892*4882a593Smuzhiyun 		    const struct kpp_testvec *vecs, unsigned int tcount)
3893*4882a593Smuzhiyun {
3894*4882a593Smuzhiyun 	int ret, i;
3895*4882a593Smuzhiyun 
3896*4882a593Smuzhiyun 	for (i = 0; i < tcount; i++) {
3897*4882a593Smuzhiyun 		ret = do_test_kpp(tfm, vecs++, alg);
3898*4882a593Smuzhiyun 		if (ret) {
3899*4882a593Smuzhiyun 			pr_err("alg: %s: test failed on vector %d, err=%d\n",
3900*4882a593Smuzhiyun 			       alg, i + 1, ret);
3901*4882a593Smuzhiyun 			return ret;
3902*4882a593Smuzhiyun 		}
3903*4882a593Smuzhiyun 	}
3904*4882a593Smuzhiyun 	return 0;
3905*4882a593Smuzhiyun }
3906*4882a593Smuzhiyun 
alg_test_kpp(const struct alg_test_desc * desc,const char * driver,u32 type,u32 mask)3907*4882a593Smuzhiyun static int alg_test_kpp(const struct alg_test_desc *desc, const char *driver,
3908*4882a593Smuzhiyun 			u32 type, u32 mask)
3909*4882a593Smuzhiyun {
3910*4882a593Smuzhiyun 	struct crypto_kpp *tfm;
3911*4882a593Smuzhiyun 	int err = 0;
3912*4882a593Smuzhiyun 
3913*4882a593Smuzhiyun 	tfm = crypto_alloc_kpp(driver, type, mask);
3914*4882a593Smuzhiyun 	if (IS_ERR(tfm)) {
3915*4882a593Smuzhiyun 		pr_err("alg: kpp: Failed to load tfm for %s: %ld\n",
3916*4882a593Smuzhiyun 		       driver, PTR_ERR(tfm));
3917*4882a593Smuzhiyun 		return PTR_ERR(tfm);
3918*4882a593Smuzhiyun 	}
3919*4882a593Smuzhiyun 	if (desc->suite.kpp.vecs)
3920*4882a593Smuzhiyun 		err = test_kpp(tfm, desc->alg, desc->suite.kpp.vecs,
3921*4882a593Smuzhiyun 			       desc->suite.kpp.count);
3922*4882a593Smuzhiyun 
3923*4882a593Smuzhiyun 	crypto_free_kpp(tfm);
3924*4882a593Smuzhiyun 	return err;
3925*4882a593Smuzhiyun }
3926*4882a593Smuzhiyun 
test_pack_u32(u8 * dst,u32 val)3927*4882a593Smuzhiyun static u8 *test_pack_u32(u8 *dst, u32 val)
3928*4882a593Smuzhiyun {
3929*4882a593Smuzhiyun 	memcpy(dst, &val, sizeof(val));
3930*4882a593Smuzhiyun 	return dst + sizeof(val);
3931*4882a593Smuzhiyun }
3932*4882a593Smuzhiyun 
test_akcipher_one(struct crypto_akcipher * tfm,const struct akcipher_testvec * vecs)3933*4882a593Smuzhiyun static int test_akcipher_one(struct crypto_akcipher *tfm,
3934*4882a593Smuzhiyun 			     const struct akcipher_testvec *vecs)
3935*4882a593Smuzhiyun {
3936*4882a593Smuzhiyun 	char *xbuf[XBUFSIZE];
3937*4882a593Smuzhiyun 	struct akcipher_request *req;
3938*4882a593Smuzhiyun 	void *outbuf_enc = NULL;
3939*4882a593Smuzhiyun 	void *outbuf_dec = NULL;
3940*4882a593Smuzhiyun 	struct crypto_wait wait;
3941*4882a593Smuzhiyun 	unsigned int out_len_max, out_len = 0;
3942*4882a593Smuzhiyun 	int err = -ENOMEM;
3943*4882a593Smuzhiyun 	struct scatterlist src, dst, src_tab[3];
3944*4882a593Smuzhiyun 	const char *m, *c;
3945*4882a593Smuzhiyun 	unsigned int m_size, c_size;
3946*4882a593Smuzhiyun 	const char *op;
3947*4882a593Smuzhiyun 	u8 *key, *ptr;
3948*4882a593Smuzhiyun 
3949*4882a593Smuzhiyun 	if (testmgr_alloc_buf(xbuf))
3950*4882a593Smuzhiyun 		return err;
3951*4882a593Smuzhiyun 
3952*4882a593Smuzhiyun 	req = akcipher_request_alloc(tfm, GFP_KERNEL);
3953*4882a593Smuzhiyun 	if (!req)
3954*4882a593Smuzhiyun 		goto free_xbuf;
3955*4882a593Smuzhiyun 
3956*4882a593Smuzhiyun 	crypto_init_wait(&wait);
3957*4882a593Smuzhiyun 
3958*4882a593Smuzhiyun 	key = kmalloc(vecs->key_len + sizeof(u32) * 2 + vecs->param_len,
3959*4882a593Smuzhiyun 		      GFP_KERNEL);
3960*4882a593Smuzhiyun 	if (!key)
3961*4882a593Smuzhiyun 		goto free_req;
3962*4882a593Smuzhiyun 	memcpy(key, vecs->key, vecs->key_len);
3963*4882a593Smuzhiyun 	ptr = key + vecs->key_len;
3964*4882a593Smuzhiyun 	ptr = test_pack_u32(ptr, vecs->algo);
3965*4882a593Smuzhiyun 	ptr = test_pack_u32(ptr, vecs->param_len);
3966*4882a593Smuzhiyun 	memcpy(ptr, vecs->params, vecs->param_len);
3967*4882a593Smuzhiyun 
3968*4882a593Smuzhiyun 	if (vecs->public_key_vec)
3969*4882a593Smuzhiyun 		err = crypto_akcipher_set_pub_key(tfm, key, vecs->key_len);
3970*4882a593Smuzhiyun 	else
3971*4882a593Smuzhiyun 		err = crypto_akcipher_set_priv_key(tfm, key, vecs->key_len);
3972*4882a593Smuzhiyun 	if (err)
3973*4882a593Smuzhiyun 		goto free_key;
3974*4882a593Smuzhiyun 
3975*4882a593Smuzhiyun 	/*
3976*4882a593Smuzhiyun 	 * First run test which do not require a private key, such as
3977*4882a593Smuzhiyun 	 * encrypt or verify.
3978*4882a593Smuzhiyun 	 */
3979*4882a593Smuzhiyun 	err = -ENOMEM;
3980*4882a593Smuzhiyun 	out_len_max = crypto_akcipher_maxsize(tfm);
3981*4882a593Smuzhiyun 	outbuf_enc = kzalloc(out_len_max, GFP_KERNEL);
3982*4882a593Smuzhiyun 	if (!outbuf_enc)
3983*4882a593Smuzhiyun 		goto free_key;
3984*4882a593Smuzhiyun 
3985*4882a593Smuzhiyun 	if (!vecs->siggen_sigver_test) {
3986*4882a593Smuzhiyun 		m = vecs->m;
3987*4882a593Smuzhiyun 		m_size = vecs->m_size;
3988*4882a593Smuzhiyun 		c = vecs->c;
3989*4882a593Smuzhiyun 		c_size = vecs->c_size;
3990*4882a593Smuzhiyun 		op = "encrypt";
3991*4882a593Smuzhiyun 	} else {
3992*4882a593Smuzhiyun 		/* Swap args so we could keep plaintext (digest)
3993*4882a593Smuzhiyun 		 * in vecs->m, and cooked signature in vecs->c.
3994*4882a593Smuzhiyun 		 */
3995*4882a593Smuzhiyun 		m = vecs->c; /* signature */
3996*4882a593Smuzhiyun 		m_size = vecs->c_size;
3997*4882a593Smuzhiyun 		c = vecs->m; /* digest */
3998*4882a593Smuzhiyun 		c_size = vecs->m_size;
3999*4882a593Smuzhiyun 		op = "verify";
4000*4882a593Smuzhiyun 	}
4001*4882a593Smuzhiyun 
4002*4882a593Smuzhiyun 	err = -E2BIG;
4003*4882a593Smuzhiyun 	if (WARN_ON(m_size > PAGE_SIZE))
4004*4882a593Smuzhiyun 		goto free_all;
4005*4882a593Smuzhiyun 	memcpy(xbuf[0], m, m_size);
4006*4882a593Smuzhiyun 
4007*4882a593Smuzhiyun 	sg_init_table(src_tab, 3);
4008*4882a593Smuzhiyun 	sg_set_buf(&src_tab[0], xbuf[0], 8);
4009*4882a593Smuzhiyun 	sg_set_buf(&src_tab[1], xbuf[0] + 8, m_size - 8);
4010*4882a593Smuzhiyun 	if (vecs->siggen_sigver_test) {
4011*4882a593Smuzhiyun 		if (WARN_ON(c_size > PAGE_SIZE))
4012*4882a593Smuzhiyun 			goto free_all;
4013*4882a593Smuzhiyun 		memcpy(xbuf[1], c, c_size);
4014*4882a593Smuzhiyun 		sg_set_buf(&src_tab[2], xbuf[1], c_size);
4015*4882a593Smuzhiyun 		akcipher_request_set_crypt(req, src_tab, NULL, m_size, c_size);
4016*4882a593Smuzhiyun 	} else {
4017*4882a593Smuzhiyun 		sg_init_one(&dst, outbuf_enc, out_len_max);
4018*4882a593Smuzhiyun 		akcipher_request_set_crypt(req, src_tab, &dst, m_size,
4019*4882a593Smuzhiyun 					   out_len_max);
4020*4882a593Smuzhiyun 	}
4021*4882a593Smuzhiyun 	akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
4022*4882a593Smuzhiyun 				      crypto_req_done, &wait);
4023*4882a593Smuzhiyun 
4024*4882a593Smuzhiyun 	err = crypto_wait_req(vecs->siggen_sigver_test ?
4025*4882a593Smuzhiyun 			      /* Run asymmetric signature verification */
4026*4882a593Smuzhiyun 			      crypto_akcipher_verify(req) :
4027*4882a593Smuzhiyun 			      /* Run asymmetric encrypt */
4028*4882a593Smuzhiyun 			      crypto_akcipher_encrypt(req), &wait);
4029*4882a593Smuzhiyun 	if (err) {
4030*4882a593Smuzhiyun 		pr_err("alg: akcipher: %s test failed. err %d\n", op, err);
4031*4882a593Smuzhiyun 		goto free_all;
4032*4882a593Smuzhiyun 	}
4033*4882a593Smuzhiyun 	if (!vecs->siggen_sigver_test && c) {
4034*4882a593Smuzhiyun 		if (req->dst_len != c_size) {
4035*4882a593Smuzhiyun 			pr_err("alg: akcipher: %s test failed. Invalid output len\n",
4036*4882a593Smuzhiyun 			       op);
4037*4882a593Smuzhiyun 			err = -EINVAL;
4038*4882a593Smuzhiyun 			goto free_all;
4039*4882a593Smuzhiyun 		}
4040*4882a593Smuzhiyun 		/* verify that encrypted message is equal to expected */
4041*4882a593Smuzhiyun 		if (memcmp(c, outbuf_enc, c_size) != 0) {
4042*4882a593Smuzhiyun 			pr_err("alg: akcipher: %s test failed. Invalid output\n",
4043*4882a593Smuzhiyun 			       op);
4044*4882a593Smuzhiyun 			hexdump(outbuf_enc, c_size);
4045*4882a593Smuzhiyun 			err = -EINVAL;
4046*4882a593Smuzhiyun 			goto free_all;
4047*4882a593Smuzhiyun 		}
4048*4882a593Smuzhiyun 	}
4049*4882a593Smuzhiyun 
4050*4882a593Smuzhiyun 	/*
4051*4882a593Smuzhiyun 	 * Don't invoke (decrypt or sign) test which require a private key
4052*4882a593Smuzhiyun 	 * for vectors with only a public key.
4053*4882a593Smuzhiyun 	 */
4054*4882a593Smuzhiyun 	if (vecs->public_key_vec) {
4055*4882a593Smuzhiyun 		err = 0;
4056*4882a593Smuzhiyun 		goto free_all;
4057*4882a593Smuzhiyun 	}
4058*4882a593Smuzhiyun 	outbuf_dec = kzalloc(out_len_max, GFP_KERNEL);
4059*4882a593Smuzhiyun 	if (!outbuf_dec) {
4060*4882a593Smuzhiyun 		err = -ENOMEM;
4061*4882a593Smuzhiyun 		goto free_all;
4062*4882a593Smuzhiyun 	}
4063*4882a593Smuzhiyun 
4064*4882a593Smuzhiyun 	if (!vecs->siggen_sigver_test && !c) {
4065*4882a593Smuzhiyun 		c = outbuf_enc;
4066*4882a593Smuzhiyun 		c_size = req->dst_len;
4067*4882a593Smuzhiyun 	}
4068*4882a593Smuzhiyun 
4069*4882a593Smuzhiyun 	err = -E2BIG;
4070*4882a593Smuzhiyun 	op = vecs->siggen_sigver_test ? "sign" : "decrypt";
4071*4882a593Smuzhiyun 	if (WARN_ON(c_size > PAGE_SIZE))
4072*4882a593Smuzhiyun 		goto free_all;
4073*4882a593Smuzhiyun 	memcpy(xbuf[0], c, c_size);
4074*4882a593Smuzhiyun 
4075*4882a593Smuzhiyun 	sg_init_one(&src, xbuf[0], c_size);
4076*4882a593Smuzhiyun 	sg_init_one(&dst, outbuf_dec, out_len_max);
4077*4882a593Smuzhiyun 	crypto_init_wait(&wait);
4078*4882a593Smuzhiyun 	akcipher_request_set_crypt(req, &src, &dst, c_size, out_len_max);
4079*4882a593Smuzhiyun 
4080*4882a593Smuzhiyun 	err = crypto_wait_req(vecs->siggen_sigver_test ?
4081*4882a593Smuzhiyun 			      /* Run asymmetric signature generation */
4082*4882a593Smuzhiyun 			      crypto_akcipher_sign(req) :
4083*4882a593Smuzhiyun 			      /* Run asymmetric decrypt */
4084*4882a593Smuzhiyun 			      crypto_akcipher_decrypt(req), &wait);
4085*4882a593Smuzhiyun 	if (err) {
4086*4882a593Smuzhiyun 		pr_err("alg: akcipher: %s test failed. err %d\n", op, err);
4087*4882a593Smuzhiyun 		goto free_all;
4088*4882a593Smuzhiyun 	}
4089*4882a593Smuzhiyun 	out_len = req->dst_len;
4090*4882a593Smuzhiyun 	if (out_len < m_size) {
4091*4882a593Smuzhiyun 		pr_err("alg: akcipher: %s test failed. Invalid output len %u\n",
4092*4882a593Smuzhiyun 		       op, out_len);
4093*4882a593Smuzhiyun 		err = -EINVAL;
4094*4882a593Smuzhiyun 		goto free_all;
4095*4882a593Smuzhiyun 	}
4096*4882a593Smuzhiyun 	/* verify that decrypted message is equal to the original msg */
4097*4882a593Smuzhiyun 	if (memchr_inv(outbuf_dec, 0, out_len - m_size) ||
4098*4882a593Smuzhiyun 	    memcmp(m, outbuf_dec + out_len - m_size, m_size)) {
4099*4882a593Smuzhiyun 		pr_err("alg: akcipher: %s test failed. Invalid output\n", op);
4100*4882a593Smuzhiyun 		hexdump(outbuf_dec, out_len);
4101*4882a593Smuzhiyun 		err = -EINVAL;
4102*4882a593Smuzhiyun 	}
4103*4882a593Smuzhiyun free_all:
4104*4882a593Smuzhiyun 	kfree(outbuf_dec);
4105*4882a593Smuzhiyun 	kfree(outbuf_enc);
4106*4882a593Smuzhiyun free_key:
4107*4882a593Smuzhiyun 	kfree(key);
4108*4882a593Smuzhiyun free_req:
4109*4882a593Smuzhiyun 	akcipher_request_free(req);
4110*4882a593Smuzhiyun free_xbuf:
4111*4882a593Smuzhiyun 	testmgr_free_buf(xbuf);
4112*4882a593Smuzhiyun 	return err;
4113*4882a593Smuzhiyun }
4114*4882a593Smuzhiyun 
test_akcipher(struct crypto_akcipher * tfm,const char * alg,const struct akcipher_testvec * vecs,unsigned int tcount)4115*4882a593Smuzhiyun static int test_akcipher(struct crypto_akcipher *tfm, const char *alg,
4116*4882a593Smuzhiyun 			 const struct akcipher_testvec *vecs,
4117*4882a593Smuzhiyun 			 unsigned int tcount)
4118*4882a593Smuzhiyun {
4119*4882a593Smuzhiyun 	const char *algo =
4120*4882a593Smuzhiyun 		crypto_tfm_alg_driver_name(crypto_akcipher_tfm(tfm));
4121*4882a593Smuzhiyun 	int ret, i;
4122*4882a593Smuzhiyun 
4123*4882a593Smuzhiyun 	for (i = 0; i < tcount; i++) {
4124*4882a593Smuzhiyun 		ret = test_akcipher_one(tfm, vecs++);
4125*4882a593Smuzhiyun 		if (!ret)
4126*4882a593Smuzhiyun 			continue;
4127*4882a593Smuzhiyun 
4128*4882a593Smuzhiyun 		pr_err("alg: akcipher: test %d failed for %s, err=%d\n",
4129*4882a593Smuzhiyun 		       i + 1, algo, ret);
4130*4882a593Smuzhiyun 		return ret;
4131*4882a593Smuzhiyun 	}
4132*4882a593Smuzhiyun 	return 0;
4133*4882a593Smuzhiyun }
4134*4882a593Smuzhiyun 
alg_test_akcipher(const struct alg_test_desc * desc,const char * driver,u32 type,u32 mask)4135*4882a593Smuzhiyun static int alg_test_akcipher(const struct alg_test_desc *desc,
4136*4882a593Smuzhiyun 			     const char *driver, u32 type, u32 mask)
4137*4882a593Smuzhiyun {
4138*4882a593Smuzhiyun 	struct crypto_akcipher *tfm;
4139*4882a593Smuzhiyun 	int err = 0;
4140*4882a593Smuzhiyun 
4141*4882a593Smuzhiyun 	tfm = crypto_alloc_akcipher(driver, type, mask);
4142*4882a593Smuzhiyun 	if (IS_ERR(tfm)) {
4143*4882a593Smuzhiyun 		pr_err("alg: akcipher: Failed to load tfm for %s: %ld\n",
4144*4882a593Smuzhiyun 		       driver, PTR_ERR(tfm));
4145*4882a593Smuzhiyun 		return PTR_ERR(tfm);
4146*4882a593Smuzhiyun 	}
4147*4882a593Smuzhiyun 	if (desc->suite.akcipher.vecs)
4148*4882a593Smuzhiyun 		err = test_akcipher(tfm, desc->alg, desc->suite.akcipher.vecs,
4149*4882a593Smuzhiyun 				    desc->suite.akcipher.count);
4150*4882a593Smuzhiyun 
4151*4882a593Smuzhiyun 	crypto_free_akcipher(tfm);
4152*4882a593Smuzhiyun 	return err;
4153*4882a593Smuzhiyun }
4154*4882a593Smuzhiyun 
alg_test_null(const struct alg_test_desc * desc,const char * driver,u32 type,u32 mask)4155*4882a593Smuzhiyun static int alg_test_null(const struct alg_test_desc *desc,
4156*4882a593Smuzhiyun 			     const char *driver, u32 type, u32 mask)
4157*4882a593Smuzhiyun {
4158*4882a593Smuzhiyun 	return 0;
4159*4882a593Smuzhiyun }
4160*4882a593Smuzhiyun 
4161*4882a593Smuzhiyun #define ____VECS(tv)	.vecs = tv, .count = ARRAY_SIZE(tv)
4162*4882a593Smuzhiyun #define __VECS(tv)	{ ____VECS(tv) }
4163*4882a593Smuzhiyun 
4164*4882a593Smuzhiyun /* Please keep this list sorted by algorithm name. */
4165*4882a593Smuzhiyun static const struct alg_test_desc alg_test_descs[] = {
4166*4882a593Smuzhiyun 	{
4167*4882a593Smuzhiyun 		.alg = "adiantum(xchacha12,aes)",
4168*4882a593Smuzhiyun 		.generic_driver = "adiantum(xchacha12-generic,aes-generic,nhpoly1305-generic)",
4169*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4170*4882a593Smuzhiyun 		.suite = {
4171*4882a593Smuzhiyun 			.cipher = __VECS(adiantum_xchacha12_aes_tv_template)
4172*4882a593Smuzhiyun 		},
4173*4882a593Smuzhiyun 	}, {
4174*4882a593Smuzhiyun 		.alg = "adiantum(xchacha20,aes)",
4175*4882a593Smuzhiyun 		.generic_driver = "adiantum(xchacha20-generic,aes-generic,nhpoly1305-generic)",
4176*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4177*4882a593Smuzhiyun 		.suite = {
4178*4882a593Smuzhiyun 			.cipher = __VECS(adiantum_xchacha20_aes_tv_template)
4179*4882a593Smuzhiyun 		},
4180*4882a593Smuzhiyun 	}, {
4181*4882a593Smuzhiyun 		.alg = "aegis128",
4182*4882a593Smuzhiyun 		.test = alg_test_aead,
4183*4882a593Smuzhiyun 		.suite = {
4184*4882a593Smuzhiyun 			.aead = __VECS(aegis128_tv_template)
4185*4882a593Smuzhiyun 		}
4186*4882a593Smuzhiyun 	}, {
4187*4882a593Smuzhiyun 		.alg = "ansi_cprng",
4188*4882a593Smuzhiyun 		.test = alg_test_cprng,
4189*4882a593Smuzhiyun 		.suite = {
4190*4882a593Smuzhiyun 			.cprng = __VECS(ansi_cprng_aes_tv_template)
4191*4882a593Smuzhiyun 		}
4192*4882a593Smuzhiyun 	}, {
4193*4882a593Smuzhiyun 		.alg = "authenc(hmac(md5),ecb(cipher_null))",
4194*4882a593Smuzhiyun 		.test = alg_test_aead,
4195*4882a593Smuzhiyun 		.suite = {
4196*4882a593Smuzhiyun 			.aead = __VECS(hmac_md5_ecb_cipher_null_tv_template)
4197*4882a593Smuzhiyun 		}
4198*4882a593Smuzhiyun 	}, {
4199*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha1),cbc(aes))",
4200*4882a593Smuzhiyun 		.test = alg_test_aead,
4201*4882a593Smuzhiyun 		.fips_allowed = 1,
4202*4882a593Smuzhiyun 		.suite = {
4203*4882a593Smuzhiyun 			.aead = __VECS(hmac_sha1_aes_cbc_tv_temp)
4204*4882a593Smuzhiyun 		}
4205*4882a593Smuzhiyun 	}, {
4206*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha1),cbc(des))",
4207*4882a593Smuzhiyun 		.test = alg_test_aead,
4208*4882a593Smuzhiyun 		.suite = {
4209*4882a593Smuzhiyun 			.aead = __VECS(hmac_sha1_des_cbc_tv_temp)
4210*4882a593Smuzhiyun 		}
4211*4882a593Smuzhiyun 	}, {
4212*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha1),cbc(des3_ede))",
4213*4882a593Smuzhiyun 		.test = alg_test_aead,
4214*4882a593Smuzhiyun 		.fips_allowed = 1,
4215*4882a593Smuzhiyun 		.suite = {
4216*4882a593Smuzhiyun 			.aead = __VECS(hmac_sha1_des3_ede_cbc_tv_temp)
4217*4882a593Smuzhiyun 		}
4218*4882a593Smuzhiyun 	}, {
4219*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha1),ctr(aes))",
4220*4882a593Smuzhiyun 		.test = alg_test_null,
4221*4882a593Smuzhiyun 		.fips_allowed = 1,
4222*4882a593Smuzhiyun 	}, {
4223*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha1),ecb(cipher_null))",
4224*4882a593Smuzhiyun 		.test = alg_test_aead,
4225*4882a593Smuzhiyun 		.suite = {
4226*4882a593Smuzhiyun 			.aead = __VECS(hmac_sha1_ecb_cipher_null_tv_temp)
4227*4882a593Smuzhiyun 		}
4228*4882a593Smuzhiyun 	}, {
4229*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha1),rfc3686(ctr(aes)))",
4230*4882a593Smuzhiyun 		.test = alg_test_null,
4231*4882a593Smuzhiyun 		.fips_allowed = 1,
4232*4882a593Smuzhiyun 	}, {
4233*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha224),cbc(des))",
4234*4882a593Smuzhiyun 		.test = alg_test_aead,
4235*4882a593Smuzhiyun 		.suite = {
4236*4882a593Smuzhiyun 			.aead = __VECS(hmac_sha224_des_cbc_tv_temp)
4237*4882a593Smuzhiyun 		}
4238*4882a593Smuzhiyun 	}, {
4239*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha224),cbc(des3_ede))",
4240*4882a593Smuzhiyun 		.test = alg_test_aead,
4241*4882a593Smuzhiyun 		.fips_allowed = 1,
4242*4882a593Smuzhiyun 		.suite = {
4243*4882a593Smuzhiyun 			.aead = __VECS(hmac_sha224_des3_ede_cbc_tv_temp)
4244*4882a593Smuzhiyun 		}
4245*4882a593Smuzhiyun 	}, {
4246*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha256),cbc(aes))",
4247*4882a593Smuzhiyun 		.test = alg_test_aead,
4248*4882a593Smuzhiyun 		.fips_allowed = 1,
4249*4882a593Smuzhiyun 		.suite = {
4250*4882a593Smuzhiyun 			.aead = __VECS(hmac_sha256_aes_cbc_tv_temp)
4251*4882a593Smuzhiyun 		}
4252*4882a593Smuzhiyun 	}, {
4253*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha256),cbc(des))",
4254*4882a593Smuzhiyun 		.test = alg_test_aead,
4255*4882a593Smuzhiyun 		.suite = {
4256*4882a593Smuzhiyun 			.aead = __VECS(hmac_sha256_des_cbc_tv_temp)
4257*4882a593Smuzhiyun 		}
4258*4882a593Smuzhiyun 	}, {
4259*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha256),cbc(des3_ede))",
4260*4882a593Smuzhiyun 		.test = alg_test_aead,
4261*4882a593Smuzhiyun 		.fips_allowed = 1,
4262*4882a593Smuzhiyun 		.suite = {
4263*4882a593Smuzhiyun 			.aead = __VECS(hmac_sha256_des3_ede_cbc_tv_temp)
4264*4882a593Smuzhiyun 		}
4265*4882a593Smuzhiyun 	}, {
4266*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha256),ctr(aes))",
4267*4882a593Smuzhiyun 		.test = alg_test_null,
4268*4882a593Smuzhiyun 		.fips_allowed = 1,
4269*4882a593Smuzhiyun 	}, {
4270*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha256),rfc3686(ctr(aes)))",
4271*4882a593Smuzhiyun 		.test = alg_test_null,
4272*4882a593Smuzhiyun 		.fips_allowed = 1,
4273*4882a593Smuzhiyun 	}, {
4274*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha384),cbc(des))",
4275*4882a593Smuzhiyun 		.test = alg_test_aead,
4276*4882a593Smuzhiyun 		.suite = {
4277*4882a593Smuzhiyun 			.aead = __VECS(hmac_sha384_des_cbc_tv_temp)
4278*4882a593Smuzhiyun 		}
4279*4882a593Smuzhiyun 	}, {
4280*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha384),cbc(des3_ede))",
4281*4882a593Smuzhiyun 		.test = alg_test_aead,
4282*4882a593Smuzhiyun 		.fips_allowed = 1,
4283*4882a593Smuzhiyun 		.suite = {
4284*4882a593Smuzhiyun 			.aead = __VECS(hmac_sha384_des3_ede_cbc_tv_temp)
4285*4882a593Smuzhiyun 		}
4286*4882a593Smuzhiyun 	}, {
4287*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha384),ctr(aes))",
4288*4882a593Smuzhiyun 		.test = alg_test_null,
4289*4882a593Smuzhiyun 		.fips_allowed = 1,
4290*4882a593Smuzhiyun 	}, {
4291*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha384),rfc3686(ctr(aes)))",
4292*4882a593Smuzhiyun 		.test = alg_test_null,
4293*4882a593Smuzhiyun 		.fips_allowed = 1,
4294*4882a593Smuzhiyun 	}, {
4295*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha512),cbc(aes))",
4296*4882a593Smuzhiyun 		.fips_allowed = 1,
4297*4882a593Smuzhiyun 		.test = alg_test_aead,
4298*4882a593Smuzhiyun 		.suite = {
4299*4882a593Smuzhiyun 			.aead = __VECS(hmac_sha512_aes_cbc_tv_temp)
4300*4882a593Smuzhiyun 		}
4301*4882a593Smuzhiyun 	}, {
4302*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha512),cbc(des))",
4303*4882a593Smuzhiyun 		.test = alg_test_aead,
4304*4882a593Smuzhiyun 		.suite = {
4305*4882a593Smuzhiyun 			.aead = __VECS(hmac_sha512_des_cbc_tv_temp)
4306*4882a593Smuzhiyun 		}
4307*4882a593Smuzhiyun 	}, {
4308*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha512),cbc(des3_ede))",
4309*4882a593Smuzhiyun 		.test = alg_test_aead,
4310*4882a593Smuzhiyun 		.fips_allowed = 1,
4311*4882a593Smuzhiyun 		.suite = {
4312*4882a593Smuzhiyun 			.aead = __VECS(hmac_sha512_des3_ede_cbc_tv_temp)
4313*4882a593Smuzhiyun 		}
4314*4882a593Smuzhiyun 	}, {
4315*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha512),ctr(aes))",
4316*4882a593Smuzhiyun 		.test = alg_test_null,
4317*4882a593Smuzhiyun 		.fips_allowed = 1,
4318*4882a593Smuzhiyun 	}, {
4319*4882a593Smuzhiyun 		.alg = "authenc(hmac(sha512),rfc3686(ctr(aes)))",
4320*4882a593Smuzhiyun 		.test = alg_test_null,
4321*4882a593Smuzhiyun 		.fips_allowed = 1,
4322*4882a593Smuzhiyun 	}, {
4323*4882a593Smuzhiyun 		.alg = "blake2b-160",
4324*4882a593Smuzhiyun 		.test = alg_test_hash,
4325*4882a593Smuzhiyun 		.fips_allowed = 0,
4326*4882a593Smuzhiyun 		.suite = {
4327*4882a593Smuzhiyun 			.hash = __VECS(blake2b_160_tv_template)
4328*4882a593Smuzhiyun 		}
4329*4882a593Smuzhiyun 	}, {
4330*4882a593Smuzhiyun 		.alg = "blake2b-256",
4331*4882a593Smuzhiyun 		.test = alg_test_hash,
4332*4882a593Smuzhiyun 		.fips_allowed = 0,
4333*4882a593Smuzhiyun 		.suite = {
4334*4882a593Smuzhiyun 			.hash = __VECS(blake2b_256_tv_template)
4335*4882a593Smuzhiyun 		}
4336*4882a593Smuzhiyun 	}, {
4337*4882a593Smuzhiyun 		.alg = "blake2b-384",
4338*4882a593Smuzhiyun 		.test = alg_test_hash,
4339*4882a593Smuzhiyun 		.fips_allowed = 0,
4340*4882a593Smuzhiyun 		.suite = {
4341*4882a593Smuzhiyun 			.hash = __VECS(blake2b_384_tv_template)
4342*4882a593Smuzhiyun 		}
4343*4882a593Smuzhiyun 	}, {
4344*4882a593Smuzhiyun 		.alg = "blake2b-512",
4345*4882a593Smuzhiyun 		.test = alg_test_hash,
4346*4882a593Smuzhiyun 		.fips_allowed = 0,
4347*4882a593Smuzhiyun 		.suite = {
4348*4882a593Smuzhiyun 			.hash = __VECS(blake2b_512_tv_template)
4349*4882a593Smuzhiyun 		}
4350*4882a593Smuzhiyun 	}, {
4351*4882a593Smuzhiyun 		.alg = "blake2s-128",
4352*4882a593Smuzhiyun 		.test = alg_test_hash,
4353*4882a593Smuzhiyun 		.suite = {
4354*4882a593Smuzhiyun 			.hash = __VECS(blakes2s_128_tv_template)
4355*4882a593Smuzhiyun 		}
4356*4882a593Smuzhiyun 	}, {
4357*4882a593Smuzhiyun 		.alg = "blake2s-160",
4358*4882a593Smuzhiyun 		.test = alg_test_hash,
4359*4882a593Smuzhiyun 		.suite = {
4360*4882a593Smuzhiyun 			.hash = __VECS(blakes2s_160_tv_template)
4361*4882a593Smuzhiyun 		}
4362*4882a593Smuzhiyun 	}, {
4363*4882a593Smuzhiyun 		.alg = "blake2s-224",
4364*4882a593Smuzhiyun 		.test = alg_test_hash,
4365*4882a593Smuzhiyun 		.suite = {
4366*4882a593Smuzhiyun 			.hash = __VECS(blakes2s_224_tv_template)
4367*4882a593Smuzhiyun 		}
4368*4882a593Smuzhiyun 	}, {
4369*4882a593Smuzhiyun 		.alg = "blake2s-256",
4370*4882a593Smuzhiyun 		.test = alg_test_hash,
4371*4882a593Smuzhiyun 		.suite = {
4372*4882a593Smuzhiyun 			.hash = __VECS(blakes2s_256_tv_template)
4373*4882a593Smuzhiyun 		}
4374*4882a593Smuzhiyun 	}, {
4375*4882a593Smuzhiyun 		.alg = "cbc(aes)",
4376*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4377*4882a593Smuzhiyun 		.fips_allowed = 1,
4378*4882a593Smuzhiyun 		.suite = {
4379*4882a593Smuzhiyun 			.cipher = __VECS(aes_cbc_tv_template)
4380*4882a593Smuzhiyun 		},
4381*4882a593Smuzhiyun 	}, {
4382*4882a593Smuzhiyun 		.alg = "cbc(anubis)",
4383*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4384*4882a593Smuzhiyun 		.suite = {
4385*4882a593Smuzhiyun 			.cipher = __VECS(anubis_cbc_tv_template)
4386*4882a593Smuzhiyun 		},
4387*4882a593Smuzhiyun 	}, {
4388*4882a593Smuzhiyun 		.alg = "cbc(blowfish)",
4389*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4390*4882a593Smuzhiyun 		.suite = {
4391*4882a593Smuzhiyun 			.cipher = __VECS(bf_cbc_tv_template)
4392*4882a593Smuzhiyun 		},
4393*4882a593Smuzhiyun 	}, {
4394*4882a593Smuzhiyun 		.alg = "cbc(camellia)",
4395*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4396*4882a593Smuzhiyun 		.suite = {
4397*4882a593Smuzhiyun 			.cipher = __VECS(camellia_cbc_tv_template)
4398*4882a593Smuzhiyun 		},
4399*4882a593Smuzhiyun 	}, {
4400*4882a593Smuzhiyun 		.alg = "cbc(cast5)",
4401*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4402*4882a593Smuzhiyun 		.suite = {
4403*4882a593Smuzhiyun 			.cipher = __VECS(cast5_cbc_tv_template)
4404*4882a593Smuzhiyun 		},
4405*4882a593Smuzhiyun 	}, {
4406*4882a593Smuzhiyun 		.alg = "cbc(cast6)",
4407*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4408*4882a593Smuzhiyun 		.suite = {
4409*4882a593Smuzhiyun 			.cipher = __VECS(cast6_cbc_tv_template)
4410*4882a593Smuzhiyun 		},
4411*4882a593Smuzhiyun 	}, {
4412*4882a593Smuzhiyun 		.alg = "cbc(des)",
4413*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4414*4882a593Smuzhiyun 		.suite = {
4415*4882a593Smuzhiyun 			.cipher = __VECS(des_cbc_tv_template)
4416*4882a593Smuzhiyun 		},
4417*4882a593Smuzhiyun 	}, {
4418*4882a593Smuzhiyun 		.alg = "cbc(des3_ede)",
4419*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4420*4882a593Smuzhiyun 		.fips_allowed = 1,
4421*4882a593Smuzhiyun 		.suite = {
4422*4882a593Smuzhiyun 			.cipher = __VECS(des3_ede_cbc_tv_template)
4423*4882a593Smuzhiyun 		},
4424*4882a593Smuzhiyun 	}, {
4425*4882a593Smuzhiyun 		/* Same as cbc(aes) except the key is stored in
4426*4882a593Smuzhiyun 		 * hardware secure memory which we reference by index
4427*4882a593Smuzhiyun 		 */
4428*4882a593Smuzhiyun 		.alg = "cbc(paes)",
4429*4882a593Smuzhiyun 		.test = alg_test_null,
4430*4882a593Smuzhiyun 		.fips_allowed = 1,
4431*4882a593Smuzhiyun 	}, {
4432*4882a593Smuzhiyun 		/* Same as cbc(sm4) except the key is stored in
4433*4882a593Smuzhiyun 		 * hardware secure memory which we reference by index
4434*4882a593Smuzhiyun 		 */
4435*4882a593Smuzhiyun 		.alg = "cbc(psm4)",
4436*4882a593Smuzhiyun 		.test = alg_test_null,
4437*4882a593Smuzhiyun 	}, {
4438*4882a593Smuzhiyun 		.alg = "cbc(serpent)",
4439*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4440*4882a593Smuzhiyun 		.suite = {
4441*4882a593Smuzhiyun 			.cipher = __VECS(serpent_cbc_tv_template)
4442*4882a593Smuzhiyun 		},
4443*4882a593Smuzhiyun 	}, {
4444*4882a593Smuzhiyun 		.alg = "cbc(sm4)",
4445*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4446*4882a593Smuzhiyun 		.suite = {
4447*4882a593Smuzhiyun 			.cipher = __VECS(sm4_cbc_tv_template)
4448*4882a593Smuzhiyun 		}
4449*4882a593Smuzhiyun 	}, {
4450*4882a593Smuzhiyun 		.alg = "cbc(twofish)",
4451*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4452*4882a593Smuzhiyun 		.suite = {
4453*4882a593Smuzhiyun 			.cipher = __VECS(tf_cbc_tv_template)
4454*4882a593Smuzhiyun 		},
4455*4882a593Smuzhiyun 	}, {
4456*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_CRYPTO_PAES_S390)
4457*4882a593Smuzhiyun 		.alg = "cbc-paes-s390",
4458*4882a593Smuzhiyun 		.fips_allowed = 1,
4459*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4460*4882a593Smuzhiyun 		.suite = {
4461*4882a593Smuzhiyun 			.cipher = __VECS(aes_cbc_tv_template)
4462*4882a593Smuzhiyun 		}
4463*4882a593Smuzhiyun 	}, {
4464*4882a593Smuzhiyun #endif
4465*4882a593Smuzhiyun 		.alg = "cbcmac(aes)",
4466*4882a593Smuzhiyun 		.fips_allowed = 1,
4467*4882a593Smuzhiyun 		.test = alg_test_hash,
4468*4882a593Smuzhiyun 		.suite = {
4469*4882a593Smuzhiyun 			.hash = __VECS(aes_cbcmac_tv_template)
4470*4882a593Smuzhiyun 		}
4471*4882a593Smuzhiyun 	}, {
4472*4882a593Smuzhiyun 		.alg = "ccm(aes)",
4473*4882a593Smuzhiyun 		.generic_driver = "ccm_base(ctr(aes-generic),cbcmac(aes-generic))",
4474*4882a593Smuzhiyun 		.test = alg_test_aead,
4475*4882a593Smuzhiyun 		.fips_allowed = 1,
4476*4882a593Smuzhiyun 		.suite = {
4477*4882a593Smuzhiyun 			.aead = {
4478*4882a593Smuzhiyun 				____VECS(aes_ccm_tv_template),
4479*4882a593Smuzhiyun 				.einval_allowed = 1,
4480*4882a593Smuzhiyun 			}
4481*4882a593Smuzhiyun 		}
4482*4882a593Smuzhiyun 	}, {
4483*4882a593Smuzhiyun 		.alg = "cfb(aes)",
4484*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4485*4882a593Smuzhiyun 		.fips_allowed = 1,
4486*4882a593Smuzhiyun 		.suite = {
4487*4882a593Smuzhiyun 			.cipher = __VECS(aes_cfb_tv_template)
4488*4882a593Smuzhiyun 		},
4489*4882a593Smuzhiyun 	}, {
4490*4882a593Smuzhiyun 		.alg = "cfb(sm4)",
4491*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4492*4882a593Smuzhiyun 		.suite = {
4493*4882a593Smuzhiyun 			.cipher = __VECS(sm4_cfb_tv_template)
4494*4882a593Smuzhiyun 		}
4495*4882a593Smuzhiyun 	}, {
4496*4882a593Smuzhiyun 		.alg = "chacha20",
4497*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4498*4882a593Smuzhiyun 		.suite = {
4499*4882a593Smuzhiyun 			.cipher = __VECS(chacha20_tv_template)
4500*4882a593Smuzhiyun 		},
4501*4882a593Smuzhiyun 	}, {
4502*4882a593Smuzhiyun 		.alg = "cmac(aes)",
4503*4882a593Smuzhiyun 		.fips_allowed = 1,
4504*4882a593Smuzhiyun 		.test = alg_test_hash,
4505*4882a593Smuzhiyun 		.suite = {
4506*4882a593Smuzhiyun 			.hash = __VECS(aes_cmac128_tv_template)
4507*4882a593Smuzhiyun 		}
4508*4882a593Smuzhiyun 	}, {
4509*4882a593Smuzhiyun 		.alg = "cmac(des3_ede)",
4510*4882a593Smuzhiyun 		.fips_allowed = 1,
4511*4882a593Smuzhiyun 		.test = alg_test_hash,
4512*4882a593Smuzhiyun 		.suite = {
4513*4882a593Smuzhiyun 			.hash = __VECS(des3_ede_cmac64_tv_template)
4514*4882a593Smuzhiyun 		}
4515*4882a593Smuzhiyun 	}, {
4516*4882a593Smuzhiyun 		.alg = "compress_null",
4517*4882a593Smuzhiyun 		.test = alg_test_null,
4518*4882a593Smuzhiyun 	}, {
4519*4882a593Smuzhiyun 		.alg = "crc32",
4520*4882a593Smuzhiyun 		.test = alg_test_hash,
4521*4882a593Smuzhiyun 		.fips_allowed = 1,
4522*4882a593Smuzhiyun 		.suite = {
4523*4882a593Smuzhiyun 			.hash = __VECS(crc32_tv_template)
4524*4882a593Smuzhiyun 		}
4525*4882a593Smuzhiyun 	}, {
4526*4882a593Smuzhiyun 		.alg = "crc32c",
4527*4882a593Smuzhiyun 		.test = alg_test_crc32c,
4528*4882a593Smuzhiyun 		.fips_allowed = 1,
4529*4882a593Smuzhiyun 		.suite = {
4530*4882a593Smuzhiyun 			.hash = __VECS(crc32c_tv_template)
4531*4882a593Smuzhiyun 		}
4532*4882a593Smuzhiyun 	}, {
4533*4882a593Smuzhiyun 		.alg = "crct10dif",
4534*4882a593Smuzhiyun 		.test = alg_test_hash,
4535*4882a593Smuzhiyun 		.fips_allowed = 1,
4536*4882a593Smuzhiyun 		.suite = {
4537*4882a593Smuzhiyun 			.hash = __VECS(crct10dif_tv_template)
4538*4882a593Smuzhiyun 		}
4539*4882a593Smuzhiyun 	}, {
4540*4882a593Smuzhiyun 		.alg = "ctr(aes)",
4541*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4542*4882a593Smuzhiyun 		.fips_allowed = 1,
4543*4882a593Smuzhiyun 		.suite = {
4544*4882a593Smuzhiyun 			.cipher = __VECS(aes_ctr_tv_template)
4545*4882a593Smuzhiyun 		}
4546*4882a593Smuzhiyun 	}, {
4547*4882a593Smuzhiyun 		.alg = "ctr(blowfish)",
4548*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4549*4882a593Smuzhiyun 		.suite = {
4550*4882a593Smuzhiyun 			.cipher = __VECS(bf_ctr_tv_template)
4551*4882a593Smuzhiyun 		}
4552*4882a593Smuzhiyun 	}, {
4553*4882a593Smuzhiyun 		.alg = "ctr(camellia)",
4554*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4555*4882a593Smuzhiyun 		.suite = {
4556*4882a593Smuzhiyun 			.cipher = __VECS(camellia_ctr_tv_template)
4557*4882a593Smuzhiyun 		}
4558*4882a593Smuzhiyun 	}, {
4559*4882a593Smuzhiyun 		.alg = "ctr(cast5)",
4560*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4561*4882a593Smuzhiyun 		.suite = {
4562*4882a593Smuzhiyun 			.cipher = __VECS(cast5_ctr_tv_template)
4563*4882a593Smuzhiyun 		}
4564*4882a593Smuzhiyun 	}, {
4565*4882a593Smuzhiyun 		.alg = "ctr(cast6)",
4566*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4567*4882a593Smuzhiyun 		.suite = {
4568*4882a593Smuzhiyun 			.cipher = __VECS(cast6_ctr_tv_template)
4569*4882a593Smuzhiyun 		}
4570*4882a593Smuzhiyun 	}, {
4571*4882a593Smuzhiyun 		.alg = "ctr(des)",
4572*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4573*4882a593Smuzhiyun 		.suite = {
4574*4882a593Smuzhiyun 			.cipher = __VECS(des_ctr_tv_template)
4575*4882a593Smuzhiyun 		}
4576*4882a593Smuzhiyun 	}, {
4577*4882a593Smuzhiyun 		.alg = "ctr(des3_ede)",
4578*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4579*4882a593Smuzhiyun 		.fips_allowed = 1,
4580*4882a593Smuzhiyun 		.suite = {
4581*4882a593Smuzhiyun 			.cipher = __VECS(des3_ede_ctr_tv_template)
4582*4882a593Smuzhiyun 		}
4583*4882a593Smuzhiyun 	}, {
4584*4882a593Smuzhiyun 		/* Same as ctr(aes) except the key is stored in
4585*4882a593Smuzhiyun 		 * hardware secure memory which we reference by index
4586*4882a593Smuzhiyun 		 */
4587*4882a593Smuzhiyun 		.alg = "ctr(paes)",
4588*4882a593Smuzhiyun 		.test = alg_test_null,
4589*4882a593Smuzhiyun 		.fips_allowed = 1,
4590*4882a593Smuzhiyun 	}, {
4591*4882a593Smuzhiyun 
4592*4882a593Smuzhiyun 		/* Same as ctr(sm4) except the key is stored in
4593*4882a593Smuzhiyun 		 * hardware secure memory which we reference by index
4594*4882a593Smuzhiyun 		 */
4595*4882a593Smuzhiyun 		.alg = "ctr(psm4)",
4596*4882a593Smuzhiyun 		.test = alg_test_null,
4597*4882a593Smuzhiyun 	}, {
4598*4882a593Smuzhiyun 		.alg = "ctr(serpent)",
4599*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4600*4882a593Smuzhiyun 		.suite = {
4601*4882a593Smuzhiyun 			.cipher = __VECS(serpent_ctr_tv_template)
4602*4882a593Smuzhiyun 		}
4603*4882a593Smuzhiyun 	}, {
4604*4882a593Smuzhiyun 		.alg = "ctr(sm4)",
4605*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4606*4882a593Smuzhiyun 		.suite = {
4607*4882a593Smuzhiyun 			.cipher = __VECS(sm4_ctr_tv_template)
4608*4882a593Smuzhiyun 		}
4609*4882a593Smuzhiyun 	}, {
4610*4882a593Smuzhiyun 		.alg = "ctr(twofish)",
4611*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4612*4882a593Smuzhiyun 		.suite = {
4613*4882a593Smuzhiyun 			.cipher = __VECS(tf_ctr_tv_template)
4614*4882a593Smuzhiyun 		}
4615*4882a593Smuzhiyun 	}, {
4616*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_CRYPTO_PAES_S390)
4617*4882a593Smuzhiyun 		.alg = "ctr-paes-s390",
4618*4882a593Smuzhiyun 		.fips_allowed = 1,
4619*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4620*4882a593Smuzhiyun 		.suite = {
4621*4882a593Smuzhiyun 			.cipher = __VECS(aes_ctr_tv_template)
4622*4882a593Smuzhiyun 		}
4623*4882a593Smuzhiyun 	}, {
4624*4882a593Smuzhiyun #endif
4625*4882a593Smuzhiyun 		.alg = "cts(cbc(aes))",
4626*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4627*4882a593Smuzhiyun 		.fips_allowed = 1,
4628*4882a593Smuzhiyun 		.suite = {
4629*4882a593Smuzhiyun 			.cipher = __VECS(cts_mode_tv_template)
4630*4882a593Smuzhiyun 		}
4631*4882a593Smuzhiyun 	}, {
4632*4882a593Smuzhiyun 		/* Same as cts(cbc((aes)) except the key is stored in
4633*4882a593Smuzhiyun 		 * hardware secure memory which we reference by index
4634*4882a593Smuzhiyun 		 */
4635*4882a593Smuzhiyun 		.alg = "cts(cbc(paes))",
4636*4882a593Smuzhiyun 		.test = alg_test_null,
4637*4882a593Smuzhiyun 		.fips_allowed = 1,
4638*4882a593Smuzhiyun 	}, {
4639*4882a593Smuzhiyun 		.alg = "curve25519",
4640*4882a593Smuzhiyun 		.test = alg_test_kpp,
4641*4882a593Smuzhiyun 		.suite = {
4642*4882a593Smuzhiyun 			.kpp = __VECS(curve25519_tv_template)
4643*4882a593Smuzhiyun 		}
4644*4882a593Smuzhiyun 	}, {
4645*4882a593Smuzhiyun 		.alg = "deflate",
4646*4882a593Smuzhiyun 		.test = alg_test_comp,
4647*4882a593Smuzhiyun 		.fips_allowed = 1,
4648*4882a593Smuzhiyun 		.suite = {
4649*4882a593Smuzhiyun 			.comp = {
4650*4882a593Smuzhiyun 				.comp = __VECS(deflate_comp_tv_template),
4651*4882a593Smuzhiyun 				.decomp = __VECS(deflate_decomp_tv_template)
4652*4882a593Smuzhiyun 			}
4653*4882a593Smuzhiyun 		}
4654*4882a593Smuzhiyun 	}, {
4655*4882a593Smuzhiyun 		.alg = "dh",
4656*4882a593Smuzhiyun 		.test = alg_test_kpp,
4657*4882a593Smuzhiyun 		.fips_allowed = 1,
4658*4882a593Smuzhiyun 		.suite = {
4659*4882a593Smuzhiyun 			.kpp = __VECS(dh_tv_template)
4660*4882a593Smuzhiyun 		}
4661*4882a593Smuzhiyun 	}, {
4662*4882a593Smuzhiyun 		.alg = "digest_null",
4663*4882a593Smuzhiyun 		.test = alg_test_null,
4664*4882a593Smuzhiyun 	}, {
4665*4882a593Smuzhiyun 		.alg = "drbg_nopr_ctr_aes128",
4666*4882a593Smuzhiyun 		.test = alg_test_drbg,
4667*4882a593Smuzhiyun 		.fips_allowed = 1,
4668*4882a593Smuzhiyun 		.suite = {
4669*4882a593Smuzhiyun 			.drbg = __VECS(drbg_nopr_ctr_aes128_tv_template)
4670*4882a593Smuzhiyun 		}
4671*4882a593Smuzhiyun 	}, {
4672*4882a593Smuzhiyun 		.alg = "drbg_nopr_ctr_aes192",
4673*4882a593Smuzhiyun 		.test = alg_test_drbg,
4674*4882a593Smuzhiyun 		.fips_allowed = 1,
4675*4882a593Smuzhiyun 		.suite = {
4676*4882a593Smuzhiyun 			.drbg = __VECS(drbg_nopr_ctr_aes192_tv_template)
4677*4882a593Smuzhiyun 		}
4678*4882a593Smuzhiyun 	}, {
4679*4882a593Smuzhiyun 		.alg = "drbg_nopr_ctr_aes256",
4680*4882a593Smuzhiyun 		.test = alg_test_drbg,
4681*4882a593Smuzhiyun 		.fips_allowed = 1,
4682*4882a593Smuzhiyun 		.suite = {
4683*4882a593Smuzhiyun 			.drbg = __VECS(drbg_nopr_ctr_aes256_tv_template)
4684*4882a593Smuzhiyun 		}
4685*4882a593Smuzhiyun 	}, {
4686*4882a593Smuzhiyun 		/*
4687*4882a593Smuzhiyun 		 * There is no need to specifically test the DRBG with every
4688*4882a593Smuzhiyun 		 * backend cipher -- covered by drbg_nopr_hmac_sha256 test
4689*4882a593Smuzhiyun 		 */
4690*4882a593Smuzhiyun 		.alg = "drbg_nopr_hmac_sha1",
4691*4882a593Smuzhiyun 		.fips_allowed = 1,
4692*4882a593Smuzhiyun 		.test = alg_test_null,
4693*4882a593Smuzhiyun 	}, {
4694*4882a593Smuzhiyun 		.alg = "drbg_nopr_hmac_sha256",
4695*4882a593Smuzhiyun 		.test = alg_test_drbg,
4696*4882a593Smuzhiyun 		.fips_allowed = 1,
4697*4882a593Smuzhiyun 		.suite = {
4698*4882a593Smuzhiyun 			.drbg = __VECS(drbg_nopr_hmac_sha256_tv_template)
4699*4882a593Smuzhiyun 		}
4700*4882a593Smuzhiyun 	}, {
4701*4882a593Smuzhiyun 		/* covered by drbg_nopr_hmac_sha256 test */
4702*4882a593Smuzhiyun 		.alg = "drbg_nopr_hmac_sha384",
4703*4882a593Smuzhiyun 		.fips_allowed = 1,
4704*4882a593Smuzhiyun 		.test = alg_test_null,
4705*4882a593Smuzhiyun 	}, {
4706*4882a593Smuzhiyun 		.alg = "drbg_nopr_hmac_sha512",
4707*4882a593Smuzhiyun 		.test = alg_test_null,
4708*4882a593Smuzhiyun 		.fips_allowed = 1,
4709*4882a593Smuzhiyun 	}, {
4710*4882a593Smuzhiyun 		.alg = "drbg_nopr_sha1",
4711*4882a593Smuzhiyun 		.fips_allowed = 1,
4712*4882a593Smuzhiyun 		.test = alg_test_null,
4713*4882a593Smuzhiyun 	}, {
4714*4882a593Smuzhiyun 		.alg = "drbg_nopr_sha256",
4715*4882a593Smuzhiyun 		.test = alg_test_drbg,
4716*4882a593Smuzhiyun 		.fips_allowed = 1,
4717*4882a593Smuzhiyun 		.suite = {
4718*4882a593Smuzhiyun 			.drbg = __VECS(drbg_nopr_sha256_tv_template)
4719*4882a593Smuzhiyun 		}
4720*4882a593Smuzhiyun 	}, {
4721*4882a593Smuzhiyun 		/* covered by drbg_nopr_sha256 test */
4722*4882a593Smuzhiyun 		.alg = "drbg_nopr_sha384",
4723*4882a593Smuzhiyun 		.fips_allowed = 1,
4724*4882a593Smuzhiyun 		.test = alg_test_null,
4725*4882a593Smuzhiyun 	}, {
4726*4882a593Smuzhiyun 		.alg = "drbg_nopr_sha512",
4727*4882a593Smuzhiyun 		.fips_allowed = 1,
4728*4882a593Smuzhiyun 		.test = alg_test_null,
4729*4882a593Smuzhiyun 	}, {
4730*4882a593Smuzhiyun 		.alg = "drbg_pr_ctr_aes128",
4731*4882a593Smuzhiyun 		.test = alg_test_drbg,
4732*4882a593Smuzhiyun 		.fips_allowed = 1,
4733*4882a593Smuzhiyun 		.suite = {
4734*4882a593Smuzhiyun 			.drbg = __VECS(drbg_pr_ctr_aes128_tv_template)
4735*4882a593Smuzhiyun 		}
4736*4882a593Smuzhiyun 	}, {
4737*4882a593Smuzhiyun 		/* covered by drbg_pr_ctr_aes128 test */
4738*4882a593Smuzhiyun 		.alg = "drbg_pr_ctr_aes192",
4739*4882a593Smuzhiyun 		.fips_allowed = 1,
4740*4882a593Smuzhiyun 		.test = alg_test_null,
4741*4882a593Smuzhiyun 	}, {
4742*4882a593Smuzhiyun 		.alg = "drbg_pr_ctr_aes256",
4743*4882a593Smuzhiyun 		.fips_allowed = 1,
4744*4882a593Smuzhiyun 		.test = alg_test_null,
4745*4882a593Smuzhiyun 	}, {
4746*4882a593Smuzhiyun 		.alg = "drbg_pr_hmac_sha1",
4747*4882a593Smuzhiyun 		.fips_allowed = 1,
4748*4882a593Smuzhiyun 		.test = alg_test_null,
4749*4882a593Smuzhiyun 	}, {
4750*4882a593Smuzhiyun 		.alg = "drbg_pr_hmac_sha256",
4751*4882a593Smuzhiyun 		.test = alg_test_drbg,
4752*4882a593Smuzhiyun 		.fips_allowed = 1,
4753*4882a593Smuzhiyun 		.suite = {
4754*4882a593Smuzhiyun 			.drbg = __VECS(drbg_pr_hmac_sha256_tv_template)
4755*4882a593Smuzhiyun 		}
4756*4882a593Smuzhiyun 	}, {
4757*4882a593Smuzhiyun 		/* covered by drbg_pr_hmac_sha256 test */
4758*4882a593Smuzhiyun 		.alg = "drbg_pr_hmac_sha384",
4759*4882a593Smuzhiyun 		.fips_allowed = 1,
4760*4882a593Smuzhiyun 		.test = alg_test_null,
4761*4882a593Smuzhiyun 	}, {
4762*4882a593Smuzhiyun 		.alg = "drbg_pr_hmac_sha512",
4763*4882a593Smuzhiyun 		.test = alg_test_null,
4764*4882a593Smuzhiyun 		.fips_allowed = 1,
4765*4882a593Smuzhiyun 	}, {
4766*4882a593Smuzhiyun 		.alg = "drbg_pr_sha1",
4767*4882a593Smuzhiyun 		.fips_allowed = 1,
4768*4882a593Smuzhiyun 		.test = alg_test_null,
4769*4882a593Smuzhiyun 	}, {
4770*4882a593Smuzhiyun 		.alg = "drbg_pr_sha256",
4771*4882a593Smuzhiyun 		.test = alg_test_drbg,
4772*4882a593Smuzhiyun 		.fips_allowed = 1,
4773*4882a593Smuzhiyun 		.suite = {
4774*4882a593Smuzhiyun 			.drbg = __VECS(drbg_pr_sha256_tv_template)
4775*4882a593Smuzhiyun 		}
4776*4882a593Smuzhiyun 	}, {
4777*4882a593Smuzhiyun 		/* covered by drbg_pr_sha256 test */
4778*4882a593Smuzhiyun 		.alg = "drbg_pr_sha384",
4779*4882a593Smuzhiyun 		.fips_allowed = 1,
4780*4882a593Smuzhiyun 		.test = alg_test_null,
4781*4882a593Smuzhiyun 	}, {
4782*4882a593Smuzhiyun 		.alg = "drbg_pr_sha512",
4783*4882a593Smuzhiyun 		.fips_allowed = 1,
4784*4882a593Smuzhiyun 		.test = alg_test_null,
4785*4882a593Smuzhiyun 	}, {
4786*4882a593Smuzhiyun 		.alg = "ecb(aes)",
4787*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4788*4882a593Smuzhiyun 		.fips_allowed = 1,
4789*4882a593Smuzhiyun 		.suite = {
4790*4882a593Smuzhiyun 			.cipher = __VECS(aes_tv_template)
4791*4882a593Smuzhiyun 		}
4792*4882a593Smuzhiyun 	}, {
4793*4882a593Smuzhiyun 		.alg = "ecb(anubis)",
4794*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4795*4882a593Smuzhiyun 		.suite = {
4796*4882a593Smuzhiyun 			.cipher = __VECS(anubis_tv_template)
4797*4882a593Smuzhiyun 		}
4798*4882a593Smuzhiyun 	}, {
4799*4882a593Smuzhiyun 		.alg = "ecb(arc4)",
4800*4882a593Smuzhiyun 		.generic_driver = "ecb(arc4)-generic",
4801*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4802*4882a593Smuzhiyun 		.suite = {
4803*4882a593Smuzhiyun 			.cipher = __VECS(arc4_tv_template)
4804*4882a593Smuzhiyun 		}
4805*4882a593Smuzhiyun 	}, {
4806*4882a593Smuzhiyun 		.alg = "ecb(blowfish)",
4807*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4808*4882a593Smuzhiyun 		.suite = {
4809*4882a593Smuzhiyun 			.cipher = __VECS(bf_tv_template)
4810*4882a593Smuzhiyun 		}
4811*4882a593Smuzhiyun 	}, {
4812*4882a593Smuzhiyun 		.alg = "ecb(camellia)",
4813*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4814*4882a593Smuzhiyun 		.suite = {
4815*4882a593Smuzhiyun 			.cipher = __VECS(camellia_tv_template)
4816*4882a593Smuzhiyun 		}
4817*4882a593Smuzhiyun 	}, {
4818*4882a593Smuzhiyun 		.alg = "ecb(cast5)",
4819*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4820*4882a593Smuzhiyun 		.suite = {
4821*4882a593Smuzhiyun 			.cipher = __VECS(cast5_tv_template)
4822*4882a593Smuzhiyun 		}
4823*4882a593Smuzhiyun 	}, {
4824*4882a593Smuzhiyun 		.alg = "ecb(cast6)",
4825*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4826*4882a593Smuzhiyun 		.suite = {
4827*4882a593Smuzhiyun 			.cipher = __VECS(cast6_tv_template)
4828*4882a593Smuzhiyun 		}
4829*4882a593Smuzhiyun 	}, {
4830*4882a593Smuzhiyun 		.alg = "ecb(cipher_null)",
4831*4882a593Smuzhiyun 		.test = alg_test_null,
4832*4882a593Smuzhiyun 		.fips_allowed = 1,
4833*4882a593Smuzhiyun 	}, {
4834*4882a593Smuzhiyun 		.alg = "ecb(des)",
4835*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4836*4882a593Smuzhiyun 		.suite = {
4837*4882a593Smuzhiyun 			.cipher = __VECS(des_tv_template)
4838*4882a593Smuzhiyun 		}
4839*4882a593Smuzhiyun 	}, {
4840*4882a593Smuzhiyun 		.alg = "ecb(des3_ede)",
4841*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4842*4882a593Smuzhiyun 		.fips_allowed = 1,
4843*4882a593Smuzhiyun 		.suite = {
4844*4882a593Smuzhiyun 			.cipher = __VECS(des3_ede_tv_template)
4845*4882a593Smuzhiyun 		}
4846*4882a593Smuzhiyun 	}, {
4847*4882a593Smuzhiyun 		.alg = "ecb(fcrypt)",
4848*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4849*4882a593Smuzhiyun 		.suite = {
4850*4882a593Smuzhiyun 			.cipher = {
4851*4882a593Smuzhiyun 				.vecs = fcrypt_pcbc_tv_template,
4852*4882a593Smuzhiyun 				.count = 1
4853*4882a593Smuzhiyun 			}
4854*4882a593Smuzhiyun 		}
4855*4882a593Smuzhiyun 	}, {
4856*4882a593Smuzhiyun 		.alg = "ecb(khazad)",
4857*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4858*4882a593Smuzhiyun 		.suite = {
4859*4882a593Smuzhiyun 			.cipher = __VECS(khazad_tv_template)
4860*4882a593Smuzhiyun 		}
4861*4882a593Smuzhiyun 	}, {
4862*4882a593Smuzhiyun 		/* Same as ecb(aes) except the key is stored in
4863*4882a593Smuzhiyun 		 * hardware secure memory which we reference by index
4864*4882a593Smuzhiyun 		 */
4865*4882a593Smuzhiyun 		.alg = "ecb(paes)",
4866*4882a593Smuzhiyun 		.test = alg_test_null,
4867*4882a593Smuzhiyun 		.fips_allowed = 1,
4868*4882a593Smuzhiyun 	}, {
4869*4882a593Smuzhiyun 		.alg = "ecb(seed)",
4870*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4871*4882a593Smuzhiyun 		.suite = {
4872*4882a593Smuzhiyun 			.cipher = __VECS(seed_tv_template)
4873*4882a593Smuzhiyun 		}
4874*4882a593Smuzhiyun 	}, {
4875*4882a593Smuzhiyun 		.alg = "ecb(serpent)",
4876*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4877*4882a593Smuzhiyun 		.suite = {
4878*4882a593Smuzhiyun 			.cipher = __VECS(serpent_tv_template)
4879*4882a593Smuzhiyun 		}
4880*4882a593Smuzhiyun 	}, {
4881*4882a593Smuzhiyun 		.alg = "ecb(sm4)",
4882*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4883*4882a593Smuzhiyun 		.suite = {
4884*4882a593Smuzhiyun 			.cipher = __VECS(sm4_tv_template)
4885*4882a593Smuzhiyun 		}
4886*4882a593Smuzhiyun 	}, {
4887*4882a593Smuzhiyun 		.alg = "ecb(tea)",
4888*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4889*4882a593Smuzhiyun 		.suite = {
4890*4882a593Smuzhiyun 			.cipher = __VECS(tea_tv_template)
4891*4882a593Smuzhiyun 		}
4892*4882a593Smuzhiyun 	}, {
4893*4882a593Smuzhiyun 		.alg = "ecb(tnepres)",
4894*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4895*4882a593Smuzhiyun 		.suite = {
4896*4882a593Smuzhiyun 			.cipher = __VECS(tnepres_tv_template)
4897*4882a593Smuzhiyun 		}
4898*4882a593Smuzhiyun 	}, {
4899*4882a593Smuzhiyun 		.alg = "ecb(twofish)",
4900*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4901*4882a593Smuzhiyun 		.suite = {
4902*4882a593Smuzhiyun 			.cipher = __VECS(tf_tv_template)
4903*4882a593Smuzhiyun 		}
4904*4882a593Smuzhiyun 	}, {
4905*4882a593Smuzhiyun 		.alg = "ecb(xeta)",
4906*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4907*4882a593Smuzhiyun 		.suite = {
4908*4882a593Smuzhiyun 			.cipher = __VECS(xeta_tv_template)
4909*4882a593Smuzhiyun 		}
4910*4882a593Smuzhiyun 	}, {
4911*4882a593Smuzhiyun 		.alg = "ecb(xtea)",
4912*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4913*4882a593Smuzhiyun 		.suite = {
4914*4882a593Smuzhiyun 			.cipher = __VECS(xtea_tv_template)
4915*4882a593Smuzhiyun 		}
4916*4882a593Smuzhiyun 	}, {
4917*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_CRYPTO_PAES_S390)
4918*4882a593Smuzhiyun 		.alg = "ecb-paes-s390",
4919*4882a593Smuzhiyun 		.fips_allowed = 1,
4920*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4921*4882a593Smuzhiyun 		.suite = {
4922*4882a593Smuzhiyun 			.cipher = __VECS(aes_tv_template)
4923*4882a593Smuzhiyun 		}
4924*4882a593Smuzhiyun 	}, {
4925*4882a593Smuzhiyun #endif
4926*4882a593Smuzhiyun 		.alg = "ecdh",
4927*4882a593Smuzhiyun 		.test = alg_test_kpp,
4928*4882a593Smuzhiyun 		.fips_allowed = 1,
4929*4882a593Smuzhiyun 		.suite = {
4930*4882a593Smuzhiyun 			.kpp = __VECS(ecdh_tv_template)
4931*4882a593Smuzhiyun 		}
4932*4882a593Smuzhiyun 	}, {
4933*4882a593Smuzhiyun 		.alg = "ecrdsa",
4934*4882a593Smuzhiyun 		.test = alg_test_akcipher,
4935*4882a593Smuzhiyun 		.suite = {
4936*4882a593Smuzhiyun 			.akcipher = __VECS(ecrdsa_tv_template)
4937*4882a593Smuzhiyun 		}
4938*4882a593Smuzhiyun 	}, {
4939*4882a593Smuzhiyun 		.alg = "essiv(authenc(hmac(sha256),cbc(aes)),sha256)",
4940*4882a593Smuzhiyun 		.test = alg_test_aead,
4941*4882a593Smuzhiyun 		.fips_allowed = 1,
4942*4882a593Smuzhiyun 		.suite = {
4943*4882a593Smuzhiyun 			.aead = __VECS(essiv_hmac_sha256_aes_cbc_tv_temp)
4944*4882a593Smuzhiyun 		}
4945*4882a593Smuzhiyun 	}, {
4946*4882a593Smuzhiyun 		.alg = "essiv(cbc(aes),sha256)",
4947*4882a593Smuzhiyun 		.test = alg_test_skcipher,
4948*4882a593Smuzhiyun 		.fips_allowed = 1,
4949*4882a593Smuzhiyun 		.suite = {
4950*4882a593Smuzhiyun 			.cipher = __VECS(essiv_aes_cbc_tv_template)
4951*4882a593Smuzhiyun 		}
4952*4882a593Smuzhiyun 	}, {
4953*4882a593Smuzhiyun 		.alg = "gcm(aes)",
4954*4882a593Smuzhiyun 		.generic_driver = "gcm_base(ctr(aes-generic),ghash-generic)",
4955*4882a593Smuzhiyun 		.test = alg_test_aead,
4956*4882a593Smuzhiyun 		.fips_allowed = 1,
4957*4882a593Smuzhiyun 		.suite = {
4958*4882a593Smuzhiyun 			.aead = __VECS(aes_gcm_tv_template)
4959*4882a593Smuzhiyun 		}
4960*4882a593Smuzhiyun 	}, {
4961*4882a593Smuzhiyun 		.alg = "ghash",
4962*4882a593Smuzhiyun 		.test = alg_test_hash,
4963*4882a593Smuzhiyun 		.fips_allowed = 1,
4964*4882a593Smuzhiyun 		.suite = {
4965*4882a593Smuzhiyun 			.hash = __VECS(ghash_tv_template)
4966*4882a593Smuzhiyun 		}
4967*4882a593Smuzhiyun 	}, {
4968*4882a593Smuzhiyun 		.alg = "hmac(md5)",
4969*4882a593Smuzhiyun 		.test = alg_test_hash,
4970*4882a593Smuzhiyun 		.suite = {
4971*4882a593Smuzhiyun 			.hash = __VECS(hmac_md5_tv_template)
4972*4882a593Smuzhiyun 		}
4973*4882a593Smuzhiyun 	}, {
4974*4882a593Smuzhiyun 		.alg = "hmac(rmd128)",
4975*4882a593Smuzhiyun 		.test = alg_test_hash,
4976*4882a593Smuzhiyun 		.suite = {
4977*4882a593Smuzhiyun 			.hash = __VECS(hmac_rmd128_tv_template)
4978*4882a593Smuzhiyun 		}
4979*4882a593Smuzhiyun 	}, {
4980*4882a593Smuzhiyun 		.alg = "hmac(rmd160)",
4981*4882a593Smuzhiyun 		.test = alg_test_hash,
4982*4882a593Smuzhiyun 		.suite = {
4983*4882a593Smuzhiyun 			.hash = __VECS(hmac_rmd160_tv_template)
4984*4882a593Smuzhiyun 		}
4985*4882a593Smuzhiyun 	}, {
4986*4882a593Smuzhiyun 		.alg = "hmac(sha1)",
4987*4882a593Smuzhiyun 		.test = alg_test_hash,
4988*4882a593Smuzhiyun 		.fips_allowed = 1,
4989*4882a593Smuzhiyun 		.suite = {
4990*4882a593Smuzhiyun 			.hash = __VECS(hmac_sha1_tv_template)
4991*4882a593Smuzhiyun 		}
4992*4882a593Smuzhiyun 	}, {
4993*4882a593Smuzhiyun 		.alg = "hmac(sha224)",
4994*4882a593Smuzhiyun 		.test = alg_test_hash,
4995*4882a593Smuzhiyun 		.fips_allowed = 1,
4996*4882a593Smuzhiyun 		.suite = {
4997*4882a593Smuzhiyun 			.hash = __VECS(hmac_sha224_tv_template)
4998*4882a593Smuzhiyun 		}
4999*4882a593Smuzhiyun 	}, {
5000*4882a593Smuzhiyun 		.alg = "hmac(sha256)",
5001*4882a593Smuzhiyun 		.test = alg_test_hash,
5002*4882a593Smuzhiyun 		.fips_allowed = 1,
5003*4882a593Smuzhiyun 		.suite = {
5004*4882a593Smuzhiyun 			.hash = __VECS(hmac_sha256_tv_template)
5005*4882a593Smuzhiyun 		}
5006*4882a593Smuzhiyun 	}, {
5007*4882a593Smuzhiyun 		.alg = "hmac(sha3-224)",
5008*4882a593Smuzhiyun 		.test = alg_test_hash,
5009*4882a593Smuzhiyun 		.fips_allowed = 1,
5010*4882a593Smuzhiyun 		.suite = {
5011*4882a593Smuzhiyun 			.hash = __VECS(hmac_sha3_224_tv_template)
5012*4882a593Smuzhiyun 		}
5013*4882a593Smuzhiyun 	}, {
5014*4882a593Smuzhiyun 		.alg = "hmac(sha3-256)",
5015*4882a593Smuzhiyun 		.test = alg_test_hash,
5016*4882a593Smuzhiyun 		.fips_allowed = 1,
5017*4882a593Smuzhiyun 		.suite = {
5018*4882a593Smuzhiyun 			.hash = __VECS(hmac_sha3_256_tv_template)
5019*4882a593Smuzhiyun 		}
5020*4882a593Smuzhiyun 	}, {
5021*4882a593Smuzhiyun 		.alg = "hmac(sha3-384)",
5022*4882a593Smuzhiyun 		.test = alg_test_hash,
5023*4882a593Smuzhiyun 		.fips_allowed = 1,
5024*4882a593Smuzhiyun 		.suite = {
5025*4882a593Smuzhiyun 			.hash = __VECS(hmac_sha3_384_tv_template)
5026*4882a593Smuzhiyun 		}
5027*4882a593Smuzhiyun 	}, {
5028*4882a593Smuzhiyun 		.alg = "hmac(sha3-512)",
5029*4882a593Smuzhiyun 		.test = alg_test_hash,
5030*4882a593Smuzhiyun 		.fips_allowed = 1,
5031*4882a593Smuzhiyun 		.suite = {
5032*4882a593Smuzhiyun 			.hash = __VECS(hmac_sha3_512_tv_template)
5033*4882a593Smuzhiyun 		}
5034*4882a593Smuzhiyun 	}, {
5035*4882a593Smuzhiyun 		.alg = "hmac(sha384)",
5036*4882a593Smuzhiyun 		.test = alg_test_hash,
5037*4882a593Smuzhiyun 		.fips_allowed = 1,
5038*4882a593Smuzhiyun 		.suite = {
5039*4882a593Smuzhiyun 			.hash = __VECS(hmac_sha384_tv_template)
5040*4882a593Smuzhiyun 		}
5041*4882a593Smuzhiyun 	}, {
5042*4882a593Smuzhiyun 		.alg = "hmac(sha512)",
5043*4882a593Smuzhiyun 		.test = alg_test_hash,
5044*4882a593Smuzhiyun 		.fips_allowed = 1,
5045*4882a593Smuzhiyun 		.suite = {
5046*4882a593Smuzhiyun 			.hash = __VECS(hmac_sha512_tv_template)
5047*4882a593Smuzhiyun 		}
5048*4882a593Smuzhiyun 	}, {
5049*4882a593Smuzhiyun 		.alg = "hmac(sm3)",
5050*4882a593Smuzhiyun 		.test = alg_test_hash,
5051*4882a593Smuzhiyun 		.suite = {
5052*4882a593Smuzhiyun 			.hash = __VECS(hmac_sm3_tv_template)
5053*4882a593Smuzhiyun 		}
5054*4882a593Smuzhiyun 	}, {
5055*4882a593Smuzhiyun 		.alg = "hmac(streebog256)",
5056*4882a593Smuzhiyun 		.test = alg_test_hash,
5057*4882a593Smuzhiyun 		.suite = {
5058*4882a593Smuzhiyun 			.hash = __VECS(hmac_streebog256_tv_template)
5059*4882a593Smuzhiyun 		}
5060*4882a593Smuzhiyun 	}, {
5061*4882a593Smuzhiyun 		.alg = "hmac(streebog512)",
5062*4882a593Smuzhiyun 		.test = alg_test_hash,
5063*4882a593Smuzhiyun 		.suite = {
5064*4882a593Smuzhiyun 			.hash = __VECS(hmac_streebog512_tv_template)
5065*4882a593Smuzhiyun 		}
5066*4882a593Smuzhiyun 	}, {
5067*4882a593Smuzhiyun 		.alg = "jitterentropy_rng",
5068*4882a593Smuzhiyun 		.fips_allowed = 1,
5069*4882a593Smuzhiyun 		.test = alg_test_null,
5070*4882a593Smuzhiyun 	}, {
5071*4882a593Smuzhiyun 		.alg = "kw(aes)",
5072*4882a593Smuzhiyun 		.test = alg_test_skcipher,
5073*4882a593Smuzhiyun 		.fips_allowed = 1,
5074*4882a593Smuzhiyun 		.suite = {
5075*4882a593Smuzhiyun 			.cipher = __VECS(aes_kw_tv_template)
5076*4882a593Smuzhiyun 		}
5077*4882a593Smuzhiyun 	}, {
5078*4882a593Smuzhiyun 		.alg = "lrw(aes)",
5079*4882a593Smuzhiyun 		.generic_driver = "lrw(ecb(aes-generic))",
5080*4882a593Smuzhiyun 		.test = alg_test_skcipher,
5081*4882a593Smuzhiyun 		.suite = {
5082*4882a593Smuzhiyun 			.cipher = __VECS(aes_lrw_tv_template)
5083*4882a593Smuzhiyun 		}
5084*4882a593Smuzhiyun 	}, {
5085*4882a593Smuzhiyun 		.alg = "lrw(camellia)",
5086*4882a593Smuzhiyun 		.generic_driver = "lrw(ecb(camellia-generic))",
5087*4882a593Smuzhiyun 		.test = alg_test_skcipher,
5088*4882a593Smuzhiyun 		.suite = {
5089*4882a593Smuzhiyun 			.cipher = __VECS(camellia_lrw_tv_template)
5090*4882a593Smuzhiyun 		}
5091*4882a593Smuzhiyun 	}, {
5092*4882a593Smuzhiyun 		.alg = "lrw(cast6)",
5093*4882a593Smuzhiyun 		.generic_driver = "lrw(ecb(cast6-generic))",
5094*4882a593Smuzhiyun 		.test = alg_test_skcipher,
5095*4882a593Smuzhiyun 		.suite = {
5096*4882a593Smuzhiyun 			.cipher = __VECS(cast6_lrw_tv_template)
5097*4882a593Smuzhiyun 		}
5098*4882a593Smuzhiyun 	}, {
5099*4882a593Smuzhiyun 		.alg = "lrw(serpent)",
5100*4882a593Smuzhiyun 		.generic_driver = "lrw(ecb(serpent-generic))",
5101*4882a593Smuzhiyun 		.test = alg_test_skcipher,
5102*4882a593Smuzhiyun 		.suite = {
5103*4882a593Smuzhiyun 			.cipher = __VECS(serpent_lrw_tv_template)
5104*4882a593Smuzhiyun 		}
5105*4882a593Smuzhiyun 	}, {
5106*4882a593Smuzhiyun 		.alg = "lrw(twofish)",
5107*4882a593Smuzhiyun 		.generic_driver = "lrw(ecb(twofish-generic))",
5108*4882a593Smuzhiyun 		.test = alg_test_skcipher,
5109*4882a593Smuzhiyun 		.suite = {
5110*4882a593Smuzhiyun 			.cipher = __VECS(tf_lrw_tv_template)
5111*4882a593Smuzhiyun 		}
5112*4882a593Smuzhiyun 	}, {
5113*4882a593Smuzhiyun 		.alg = "lz4",
5114*4882a593Smuzhiyun 		.test = alg_test_comp,
5115*4882a593Smuzhiyun 		.fips_allowed = 1,
5116*4882a593Smuzhiyun 		.suite = {
5117*4882a593Smuzhiyun 			.comp = {
5118*4882a593Smuzhiyun 				.comp = __VECS(lz4_comp_tv_template),
5119*4882a593Smuzhiyun 				.decomp = __VECS(lz4_decomp_tv_template)
5120*4882a593Smuzhiyun 			}
5121*4882a593Smuzhiyun 		}
5122*4882a593Smuzhiyun 	}, {
5123*4882a593Smuzhiyun 		.alg = "lz4hc",
5124*4882a593Smuzhiyun 		.test = alg_test_comp,
5125*4882a593Smuzhiyun 		.fips_allowed = 1,
5126*4882a593Smuzhiyun 		.suite = {
5127*4882a593Smuzhiyun 			.comp = {
5128*4882a593Smuzhiyun 				.comp = __VECS(lz4hc_comp_tv_template),
5129*4882a593Smuzhiyun 				.decomp = __VECS(lz4hc_decomp_tv_template)
5130*4882a593Smuzhiyun 			}
5131*4882a593Smuzhiyun 		}
5132*4882a593Smuzhiyun 	}, {
5133*4882a593Smuzhiyun 		.alg = "lzo",
5134*4882a593Smuzhiyun 		.test = alg_test_comp,
5135*4882a593Smuzhiyun 		.fips_allowed = 1,
5136*4882a593Smuzhiyun 		.suite = {
5137*4882a593Smuzhiyun 			.comp = {
5138*4882a593Smuzhiyun 				.comp = __VECS(lzo_comp_tv_template),
5139*4882a593Smuzhiyun 				.decomp = __VECS(lzo_decomp_tv_template)
5140*4882a593Smuzhiyun 			}
5141*4882a593Smuzhiyun 		}
5142*4882a593Smuzhiyun 	}, {
5143*4882a593Smuzhiyun 		.alg = "lzo-rle",
5144*4882a593Smuzhiyun 		.test = alg_test_comp,
5145*4882a593Smuzhiyun 		.fips_allowed = 1,
5146*4882a593Smuzhiyun 		.suite = {
5147*4882a593Smuzhiyun 			.comp = {
5148*4882a593Smuzhiyun 				.comp = __VECS(lzorle_comp_tv_template),
5149*4882a593Smuzhiyun 				.decomp = __VECS(lzorle_decomp_tv_template)
5150*4882a593Smuzhiyun 			}
5151*4882a593Smuzhiyun 		}
5152*4882a593Smuzhiyun 	}, {
5153*4882a593Smuzhiyun 		.alg = "md4",
5154*4882a593Smuzhiyun 		.test = alg_test_hash,
5155*4882a593Smuzhiyun 		.suite = {
5156*4882a593Smuzhiyun 			.hash = __VECS(md4_tv_template)
5157*4882a593Smuzhiyun 		}
5158*4882a593Smuzhiyun 	}, {
5159*4882a593Smuzhiyun 		.alg = "md5",
5160*4882a593Smuzhiyun 		.test = alg_test_hash,
5161*4882a593Smuzhiyun 		.suite = {
5162*4882a593Smuzhiyun 			.hash = __VECS(md5_tv_template)
5163*4882a593Smuzhiyun 		}
5164*4882a593Smuzhiyun 	}, {
5165*4882a593Smuzhiyun 		.alg = "michael_mic",
5166*4882a593Smuzhiyun 		.test = alg_test_hash,
5167*4882a593Smuzhiyun 		.suite = {
5168*4882a593Smuzhiyun 			.hash = __VECS(michael_mic_tv_template)
5169*4882a593Smuzhiyun 		}
5170*4882a593Smuzhiyun 	}, {
5171*4882a593Smuzhiyun 		.alg = "nhpoly1305",
5172*4882a593Smuzhiyun 		.test = alg_test_hash,
5173*4882a593Smuzhiyun 		.suite = {
5174*4882a593Smuzhiyun 			.hash = __VECS(nhpoly1305_tv_template)
5175*4882a593Smuzhiyun 		}
5176*4882a593Smuzhiyun 	}, {
5177*4882a593Smuzhiyun 		.alg = "ofb(aes)",
5178*4882a593Smuzhiyun 		.test = alg_test_skcipher,
5179*4882a593Smuzhiyun 		.fips_allowed = 1,
5180*4882a593Smuzhiyun 		.suite = {
5181*4882a593Smuzhiyun 			.cipher = __VECS(aes_ofb_tv_template)
5182*4882a593Smuzhiyun 		}
5183*4882a593Smuzhiyun 	}, {
5184*4882a593Smuzhiyun 		/* Same as ofb(aes) except the key is stored in
5185*4882a593Smuzhiyun 		 * hardware secure memory which we reference by index
5186*4882a593Smuzhiyun 		 */
5187*4882a593Smuzhiyun 		.alg = "ofb(paes)",
5188*4882a593Smuzhiyun 		.test = alg_test_null,
5189*4882a593Smuzhiyun 		.fips_allowed = 1,
5190*4882a593Smuzhiyun 	}, {
5191*4882a593Smuzhiyun 		.alg = "ofb(sm4)",
5192*4882a593Smuzhiyun 		.test = alg_test_skcipher,
5193*4882a593Smuzhiyun 		.suite = {
5194*4882a593Smuzhiyun 			.cipher = __VECS(sm4_ofb_tv_template)
5195*4882a593Smuzhiyun 		}
5196*4882a593Smuzhiyun 	}, {
5197*4882a593Smuzhiyun 		.alg = "pcbc(fcrypt)",
5198*4882a593Smuzhiyun 		.test = alg_test_skcipher,
5199*4882a593Smuzhiyun 		.suite = {
5200*4882a593Smuzhiyun 			.cipher = __VECS(fcrypt_pcbc_tv_template)
5201*4882a593Smuzhiyun 		}
5202*4882a593Smuzhiyun 	}, {
5203*4882a593Smuzhiyun 		.alg = "pkcs1pad(rsa,sha224)",
5204*4882a593Smuzhiyun 		.test = alg_test_null,
5205*4882a593Smuzhiyun 		.fips_allowed = 1,
5206*4882a593Smuzhiyun 	}, {
5207*4882a593Smuzhiyun 		.alg = "pkcs1pad(rsa,sha256)",
5208*4882a593Smuzhiyun 		.test = alg_test_akcipher,
5209*4882a593Smuzhiyun 		.fips_allowed = 1,
5210*4882a593Smuzhiyun 		.suite = {
5211*4882a593Smuzhiyun 			.akcipher = __VECS(pkcs1pad_rsa_tv_template)
5212*4882a593Smuzhiyun 		}
5213*4882a593Smuzhiyun 	}, {
5214*4882a593Smuzhiyun 		.alg = "pkcs1pad(rsa,sha384)",
5215*4882a593Smuzhiyun 		.test = alg_test_null,
5216*4882a593Smuzhiyun 		.fips_allowed = 1,
5217*4882a593Smuzhiyun 	}, {
5218*4882a593Smuzhiyun 		.alg = "pkcs1pad(rsa,sha512)",
5219*4882a593Smuzhiyun 		.test = alg_test_null,
5220*4882a593Smuzhiyun 		.fips_allowed = 1,
5221*4882a593Smuzhiyun 	}, {
5222*4882a593Smuzhiyun 		.alg = "poly1305",
5223*4882a593Smuzhiyun 		.test = alg_test_hash,
5224*4882a593Smuzhiyun 		.suite = {
5225*4882a593Smuzhiyun 			.hash = __VECS(poly1305_tv_template)
5226*4882a593Smuzhiyun 		}
5227*4882a593Smuzhiyun 	}, {
5228*4882a593Smuzhiyun 		.alg = "rfc3686(ctr(aes))",
5229*4882a593Smuzhiyun 		.test = alg_test_skcipher,
5230*4882a593Smuzhiyun 		.fips_allowed = 1,
5231*4882a593Smuzhiyun 		.suite = {
5232*4882a593Smuzhiyun 			.cipher = __VECS(aes_ctr_rfc3686_tv_template)
5233*4882a593Smuzhiyun 		}
5234*4882a593Smuzhiyun 	}, {
5235*4882a593Smuzhiyun 		.alg = "rfc3686(ctr(sm4))",
5236*4882a593Smuzhiyun 		.test = alg_test_skcipher,
5237*4882a593Smuzhiyun 		.suite = {
5238*4882a593Smuzhiyun 			.cipher = __VECS(sm4_ctr_rfc3686_tv_template)
5239*4882a593Smuzhiyun 		}
5240*4882a593Smuzhiyun 	}, {
5241*4882a593Smuzhiyun 		.alg = "rfc4106(gcm(aes))",
5242*4882a593Smuzhiyun 		.generic_driver = "rfc4106(gcm_base(ctr(aes-generic),ghash-generic))",
5243*4882a593Smuzhiyun 		.test = alg_test_aead,
5244*4882a593Smuzhiyun 		.fips_allowed = 1,
5245*4882a593Smuzhiyun 		.suite = {
5246*4882a593Smuzhiyun 			.aead = {
5247*4882a593Smuzhiyun 				____VECS(aes_gcm_rfc4106_tv_template),
5248*4882a593Smuzhiyun 				.einval_allowed = 1,
5249*4882a593Smuzhiyun 				.aad_iv = 1,
5250*4882a593Smuzhiyun 			}
5251*4882a593Smuzhiyun 		}
5252*4882a593Smuzhiyun 	}, {
5253*4882a593Smuzhiyun 		.alg = "rfc4309(ccm(aes))",
5254*4882a593Smuzhiyun 		.generic_driver = "rfc4309(ccm_base(ctr(aes-generic),cbcmac(aes-generic)))",
5255*4882a593Smuzhiyun 		.test = alg_test_aead,
5256*4882a593Smuzhiyun 		.fips_allowed = 1,
5257*4882a593Smuzhiyun 		.suite = {
5258*4882a593Smuzhiyun 			.aead = {
5259*4882a593Smuzhiyun 				____VECS(aes_ccm_rfc4309_tv_template),
5260*4882a593Smuzhiyun 				.einval_allowed = 1,
5261*4882a593Smuzhiyun 				.aad_iv = 1,
5262*4882a593Smuzhiyun 			}
5263*4882a593Smuzhiyun 		}
5264*4882a593Smuzhiyun 	}, {
5265*4882a593Smuzhiyun 		.alg = "rfc4543(gcm(aes))",
5266*4882a593Smuzhiyun 		.generic_driver = "rfc4543(gcm_base(ctr(aes-generic),ghash-generic))",
5267*4882a593Smuzhiyun 		.test = alg_test_aead,
5268*4882a593Smuzhiyun 		.suite = {
5269*4882a593Smuzhiyun 			.aead = {
5270*4882a593Smuzhiyun 				____VECS(aes_gcm_rfc4543_tv_template),
5271*4882a593Smuzhiyun 				.einval_allowed = 1,
5272*4882a593Smuzhiyun 				.aad_iv = 1,
5273*4882a593Smuzhiyun 			}
5274*4882a593Smuzhiyun 		}
5275*4882a593Smuzhiyun 	}, {
5276*4882a593Smuzhiyun 		.alg = "rfc7539(chacha20,poly1305)",
5277*4882a593Smuzhiyun 		.test = alg_test_aead,
5278*4882a593Smuzhiyun 		.suite = {
5279*4882a593Smuzhiyun 			.aead = __VECS(rfc7539_tv_template)
5280*4882a593Smuzhiyun 		}
5281*4882a593Smuzhiyun 	}, {
5282*4882a593Smuzhiyun 		.alg = "rfc7539esp(chacha20,poly1305)",
5283*4882a593Smuzhiyun 		.test = alg_test_aead,
5284*4882a593Smuzhiyun 		.suite = {
5285*4882a593Smuzhiyun 			.aead = {
5286*4882a593Smuzhiyun 				____VECS(rfc7539esp_tv_template),
5287*4882a593Smuzhiyun 				.einval_allowed = 1,
5288*4882a593Smuzhiyun 				.aad_iv = 1,
5289*4882a593Smuzhiyun 			}
5290*4882a593Smuzhiyun 		}
5291*4882a593Smuzhiyun 	}, {
5292*4882a593Smuzhiyun 		.alg = "rmd128",
5293*4882a593Smuzhiyun 		.test = alg_test_hash,
5294*4882a593Smuzhiyun 		.suite = {
5295*4882a593Smuzhiyun 			.hash = __VECS(rmd128_tv_template)
5296*4882a593Smuzhiyun 		}
5297*4882a593Smuzhiyun 	}, {
5298*4882a593Smuzhiyun 		.alg = "rmd160",
5299*4882a593Smuzhiyun 		.test = alg_test_hash,
5300*4882a593Smuzhiyun 		.suite = {
5301*4882a593Smuzhiyun 			.hash = __VECS(rmd160_tv_template)
5302*4882a593Smuzhiyun 		}
5303*4882a593Smuzhiyun 	}, {
5304*4882a593Smuzhiyun 		.alg = "rmd256",
5305*4882a593Smuzhiyun 		.test = alg_test_hash,
5306*4882a593Smuzhiyun 		.suite = {
5307*4882a593Smuzhiyun 			.hash = __VECS(rmd256_tv_template)
5308*4882a593Smuzhiyun 		}
5309*4882a593Smuzhiyun 	}, {
5310*4882a593Smuzhiyun 		.alg = "rmd320",
5311*4882a593Smuzhiyun 		.test = alg_test_hash,
5312*4882a593Smuzhiyun 		.suite = {
5313*4882a593Smuzhiyun 			.hash = __VECS(rmd320_tv_template)
5314*4882a593Smuzhiyun 		}
5315*4882a593Smuzhiyun 	}, {
5316*4882a593Smuzhiyun 		.alg = "rsa",
5317*4882a593Smuzhiyun 		.test = alg_test_akcipher,
5318*4882a593Smuzhiyun 		.fips_allowed = 1,
5319*4882a593Smuzhiyun 		.suite = {
5320*4882a593Smuzhiyun 			.akcipher = __VECS(rsa_tv_template)
5321*4882a593Smuzhiyun 		}
5322*4882a593Smuzhiyun 	}, {
5323*4882a593Smuzhiyun 		.alg = "salsa20",
5324*4882a593Smuzhiyun 		.test = alg_test_skcipher,
5325*4882a593Smuzhiyun 		.suite = {
5326*4882a593Smuzhiyun 			.cipher = __VECS(salsa20_stream_tv_template)
5327*4882a593Smuzhiyun 		}
5328*4882a593Smuzhiyun 	}, {
5329*4882a593Smuzhiyun 		.alg = "sha1",
5330*4882a593Smuzhiyun 		.test = alg_test_hash,
5331*4882a593Smuzhiyun 		.fips_allowed = 1,
5332*4882a593Smuzhiyun 		.suite = {
5333*4882a593Smuzhiyun 			.hash = __VECS(sha1_tv_template)
5334*4882a593Smuzhiyun 		}
5335*4882a593Smuzhiyun 	}, {
5336*4882a593Smuzhiyun 		.alg = "sha224",
5337*4882a593Smuzhiyun 		.test = alg_test_hash,
5338*4882a593Smuzhiyun 		.fips_allowed = 1,
5339*4882a593Smuzhiyun 		.suite = {
5340*4882a593Smuzhiyun 			.hash = __VECS(sha224_tv_template)
5341*4882a593Smuzhiyun 		}
5342*4882a593Smuzhiyun 	}, {
5343*4882a593Smuzhiyun 		.alg = "sha256",
5344*4882a593Smuzhiyun 		.test = alg_test_hash,
5345*4882a593Smuzhiyun 		.fips_allowed = 1,
5346*4882a593Smuzhiyun 		.suite = {
5347*4882a593Smuzhiyun 			.hash = __VECS(sha256_tv_template)
5348*4882a593Smuzhiyun 		}
5349*4882a593Smuzhiyun 	}, {
5350*4882a593Smuzhiyun 		.alg = "sha3-224",
5351*4882a593Smuzhiyun 		.test = alg_test_hash,
5352*4882a593Smuzhiyun 		.fips_allowed = 1,
5353*4882a593Smuzhiyun 		.suite = {
5354*4882a593Smuzhiyun 			.hash = __VECS(sha3_224_tv_template)
5355*4882a593Smuzhiyun 		}
5356*4882a593Smuzhiyun 	}, {
5357*4882a593Smuzhiyun 		.alg = "sha3-256",
5358*4882a593Smuzhiyun 		.test = alg_test_hash,
5359*4882a593Smuzhiyun 		.fips_allowed = 1,
5360*4882a593Smuzhiyun 		.suite = {
5361*4882a593Smuzhiyun 			.hash = __VECS(sha3_256_tv_template)
5362*4882a593Smuzhiyun 		}
5363*4882a593Smuzhiyun 	}, {
5364*4882a593Smuzhiyun 		.alg = "sha3-384",
5365*4882a593Smuzhiyun 		.test = alg_test_hash,
5366*4882a593Smuzhiyun 		.fips_allowed = 1,
5367*4882a593Smuzhiyun 		.suite = {
5368*4882a593Smuzhiyun 			.hash = __VECS(sha3_384_tv_template)
5369*4882a593Smuzhiyun 		}
5370*4882a593Smuzhiyun 	}, {
5371*4882a593Smuzhiyun 		.alg = "sha3-512",
5372*4882a593Smuzhiyun 		.test = alg_test_hash,
5373*4882a593Smuzhiyun 		.fips_allowed = 1,
5374*4882a593Smuzhiyun 		.suite = {
5375*4882a593Smuzhiyun 			.hash = __VECS(sha3_512_tv_template)
5376*4882a593Smuzhiyun 		}
5377*4882a593Smuzhiyun 	}, {
5378*4882a593Smuzhiyun 		.alg = "sha384",
5379*4882a593Smuzhiyun 		.test = alg_test_hash,
5380*4882a593Smuzhiyun 		.fips_allowed = 1,
5381*4882a593Smuzhiyun 		.suite = {
5382*4882a593Smuzhiyun 			.hash = __VECS(sha384_tv_template)
5383*4882a593Smuzhiyun 		}
5384*4882a593Smuzhiyun 	}, {
5385*4882a593Smuzhiyun 		.alg = "sha512",
5386*4882a593Smuzhiyun 		.test = alg_test_hash,
5387*4882a593Smuzhiyun 		.fips_allowed = 1,
5388*4882a593Smuzhiyun 		.suite = {
5389*4882a593Smuzhiyun 			.hash = __VECS(sha512_tv_template)
5390*4882a593Smuzhiyun 		}
5391*4882a593Smuzhiyun 	}, {
5392*4882a593Smuzhiyun 		.alg = "sm2",
5393*4882a593Smuzhiyun 		.test = alg_test_akcipher,
5394*4882a593Smuzhiyun 		.suite = {
5395*4882a593Smuzhiyun 			.akcipher = __VECS(sm2_tv_template)
5396*4882a593Smuzhiyun 		}
5397*4882a593Smuzhiyun 	}, {
5398*4882a593Smuzhiyun 		.alg = "sm3",
5399*4882a593Smuzhiyun 		.test = alg_test_hash,
5400*4882a593Smuzhiyun 		.suite = {
5401*4882a593Smuzhiyun 			.hash = __VECS(sm3_tv_template)
5402*4882a593Smuzhiyun 		}
5403*4882a593Smuzhiyun 	}, {
5404*4882a593Smuzhiyun 		.alg = "streebog256",
5405*4882a593Smuzhiyun 		.test = alg_test_hash,
5406*4882a593Smuzhiyun 		.suite = {
5407*4882a593Smuzhiyun 			.hash = __VECS(streebog256_tv_template)
5408*4882a593Smuzhiyun 		}
5409*4882a593Smuzhiyun 	}, {
5410*4882a593Smuzhiyun 		.alg = "streebog512",
5411*4882a593Smuzhiyun 		.test = alg_test_hash,
5412*4882a593Smuzhiyun 		.suite = {
5413*4882a593Smuzhiyun 			.hash = __VECS(streebog512_tv_template)
5414*4882a593Smuzhiyun 		}
5415*4882a593Smuzhiyun 	}, {
5416*4882a593Smuzhiyun 		.alg = "tgr128",
5417*4882a593Smuzhiyun 		.test = alg_test_hash,
5418*4882a593Smuzhiyun 		.suite = {
5419*4882a593Smuzhiyun 			.hash = __VECS(tgr128_tv_template)
5420*4882a593Smuzhiyun 		}
5421*4882a593Smuzhiyun 	}, {
5422*4882a593Smuzhiyun 		.alg = "tgr160",
5423*4882a593Smuzhiyun 		.test = alg_test_hash,
5424*4882a593Smuzhiyun 		.suite = {
5425*4882a593Smuzhiyun 			.hash = __VECS(tgr160_tv_template)
5426*4882a593Smuzhiyun 		}
5427*4882a593Smuzhiyun 	}, {
5428*4882a593Smuzhiyun 		.alg = "tgr192",
5429*4882a593Smuzhiyun 		.test = alg_test_hash,
5430*4882a593Smuzhiyun 		.suite = {
5431*4882a593Smuzhiyun 			.hash = __VECS(tgr192_tv_template)
5432*4882a593Smuzhiyun 		}
5433*4882a593Smuzhiyun 	}, {
5434*4882a593Smuzhiyun 		.alg = "vmac64(aes)",
5435*4882a593Smuzhiyun 		.test = alg_test_hash,
5436*4882a593Smuzhiyun 		.suite = {
5437*4882a593Smuzhiyun 			.hash = __VECS(vmac64_aes_tv_template)
5438*4882a593Smuzhiyun 		}
5439*4882a593Smuzhiyun 	}, {
5440*4882a593Smuzhiyun 		.alg = "wp256",
5441*4882a593Smuzhiyun 		.test = alg_test_hash,
5442*4882a593Smuzhiyun 		.suite = {
5443*4882a593Smuzhiyun 			.hash = __VECS(wp256_tv_template)
5444*4882a593Smuzhiyun 		}
5445*4882a593Smuzhiyun 	}, {
5446*4882a593Smuzhiyun 		.alg = "wp384",
5447*4882a593Smuzhiyun 		.test = alg_test_hash,
5448*4882a593Smuzhiyun 		.suite = {
5449*4882a593Smuzhiyun 			.hash = __VECS(wp384_tv_template)
5450*4882a593Smuzhiyun 		}
5451*4882a593Smuzhiyun 	}, {
5452*4882a593Smuzhiyun 		.alg = "wp512",
5453*4882a593Smuzhiyun 		.test = alg_test_hash,
5454*4882a593Smuzhiyun 		.suite = {
5455*4882a593Smuzhiyun 			.hash = __VECS(wp512_tv_template)
5456*4882a593Smuzhiyun 		}
5457*4882a593Smuzhiyun 	}, {
5458*4882a593Smuzhiyun 		.alg = "xcbc(aes)",
5459*4882a593Smuzhiyun 		.test = alg_test_hash,
5460*4882a593Smuzhiyun 		.suite = {
5461*4882a593Smuzhiyun 			.hash = __VECS(aes_xcbc128_tv_template)
5462*4882a593Smuzhiyun 		}
5463*4882a593Smuzhiyun 	}, {
5464*4882a593Smuzhiyun 		.alg = "xchacha12",
5465*4882a593Smuzhiyun 		.test = alg_test_skcipher,
5466*4882a593Smuzhiyun 		.suite = {
5467*4882a593Smuzhiyun 			.cipher = __VECS(xchacha12_tv_template)
5468*4882a593Smuzhiyun 		},
5469*4882a593Smuzhiyun 	}, {
5470*4882a593Smuzhiyun 		.alg = "xchacha20",
5471*4882a593Smuzhiyun 		.test = alg_test_skcipher,
5472*4882a593Smuzhiyun 		.suite = {
5473*4882a593Smuzhiyun 			.cipher = __VECS(xchacha20_tv_template)
5474*4882a593Smuzhiyun 		},
5475*4882a593Smuzhiyun 	}, {
5476*4882a593Smuzhiyun 		.alg = "xts(aes)",
5477*4882a593Smuzhiyun 		.generic_driver = "xts(ecb(aes-generic))",
5478*4882a593Smuzhiyun 		.test = alg_test_skcipher,
5479*4882a593Smuzhiyun 		.fips_allowed = 1,
5480*4882a593Smuzhiyun 		.suite = {
5481*4882a593Smuzhiyun 			.cipher = __VECS(aes_xts_tv_template)
5482*4882a593Smuzhiyun 		}
5483*4882a593Smuzhiyun 	}, {
5484*4882a593Smuzhiyun 		.alg = "xts(camellia)",
5485*4882a593Smuzhiyun 		.generic_driver = "xts(ecb(camellia-generic))",
5486*4882a593Smuzhiyun 		.test = alg_test_skcipher,
5487*4882a593Smuzhiyun 		.suite = {
5488*4882a593Smuzhiyun 			.cipher = __VECS(camellia_xts_tv_template)
5489*4882a593Smuzhiyun 		}
5490*4882a593Smuzhiyun 	}, {
5491*4882a593Smuzhiyun 		.alg = "xts(cast6)",
5492*4882a593Smuzhiyun 		.generic_driver = "xts(ecb(cast6-generic))",
5493*4882a593Smuzhiyun 		.test = alg_test_skcipher,
5494*4882a593Smuzhiyun 		.suite = {
5495*4882a593Smuzhiyun 			.cipher = __VECS(cast6_xts_tv_template)
5496*4882a593Smuzhiyun 		}
5497*4882a593Smuzhiyun 	}, {
5498*4882a593Smuzhiyun 		/* Same as xts(aes) except the key is stored in
5499*4882a593Smuzhiyun 		 * hardware secure memory which we reference by index
5500*4882a593Smuzhiyun 		 */
5501*4882a593Smuzhiyun 		.alg = "xts(paes)",
5502*4882a593Smuzhiyun 		.test = alg_test_null,
5503*4882a593Smuzhiyun 		.fips_allowed = 1,
5504*4882a593Smuzhiyun 	}, {
5505*4882a593Smuzhiyun 		.alg = "xts(serpent)",
5506*4882a593Smuzhiyun 		.generic_driver = "xts(ecb(serpent-generic))",
5507*4882a593Smuzhiyun 		.test = alg_test_skcipher,
5508*4882a593Smuzhiyun 		.suite = {
5509*4882a593Smuzhiyun 			.cipher = __VECS(serpent_xts_tv_template)
5510*4882a593Smuzhiyun 		}
5511*4882a593Smuzhiyun 	}, {
5512*4882a593Smuzhiyun 		.alg = "xts(twofish)",
5513*4882a593Smuzhiyun 		.generic_driver = "xts(ecb(twofish-generic))",
5514*4882a593Smuzhiyun 		.test = alg_test_skcipher,
5515*4882a593Smuzhiyun 		.suite = {
5516*4882a593Smuzhiyun 			.cipher = __VECS(tf_xts_tv_template)
5517*4882a593Smuzhiyun 		}
5518*4882a593Smuzhiyun 	}, {
5519*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_CRYPTO_PAES_S390)
5520*4882a593Smuzhiyun 		.alg = "xts-paes-s390",
5521*4882a593Smuzhiyun 		.fips_allowed = 1,
5522*4882a593Smuzhiyun 		.test = alg_test_skcipher,
5523*4882a593Smuzhiyun 		.suite = {
5524*4882a593Smuzhiyun 			.cipher = __VECS(aes_xts_tv_template)
5525*4882a593Smuzhiyun 		}
5526*4882a593Smuzhiyun 	}, {
5527*4882a593Smuzhiyun #endif
5528*4882a593Smuzhiyun 		.alg = "xts4096(paes)",
5529*4882a593Smuzhiyun 		.test = alg_test_null,
5530*4882a593Smuzhiyun 		.fips_allowed = 1,
5531*4882a593Smuzhiyun 	}, {
5532*4882a593Smuzhiyun 		.alg = "xts512(paes)",
5533*4882a593Smuzhiyun 		.test = alg_test_null,
5534*4882a593Smuzhiyun 		.fips_allowed = 1,
5535*4882a593Smuzhiyun 	}, {
5536*4882a593Smuzhiyun 		.alg = "xxhash64",
5537*4882a593Smuzhiyun 		.test = alg_test_hash,
5538*4882a593Smuzhiyun 		.fips_allowed = 1,
5539*4882a593Smuzhiyun 		.suite = {
5540*4882a593Smuzhiyun 			.hash = __VECS(xxhash64_tv_template)
5541*4882a593Smuzhiyun 		}
5542*4882a593Smuzhiyun 	}, {
5543*4882a593Smuzhiyun 		.alg = "zlib-deflate",
5544*4882a593Smuzhiyun 		.test = alg_test_comp,
5545*4882a593Smuzhiyun 		.fips_allowed = 1,
5546*4882a593Smuzhiyun 		.suite = {
5547*4882a593Smuzhiyun 			.comp = {
5548*4882a593Smuzhiyun 				.comp = __VECS(zlib_deflate_comp_tv_template),
5549*4882a593Smuzhiyun 				.decomp = __VECS(zlib_deflate_decomp_tv_template)
5550*4882a593Smuzhiyun 			}
5551*4882a593Smuzhiyun 		}
5552*4882a593Smuzhiyun 	}, {
5553*4882a593Smuzhiyun 		.alg = "zstd",
5554*4882a593Smuzhiyun 		.test = alg_test_comp,
5555*4882a593Smuzhiyun 		.fips_allowed = 1,
5556*4882a593Smuzhiyun 		.suite = {
5557*4882a593Smuzhiyun 			.comp = {
5558*4882a593Smuzhiyun 				.comp = __VECS(zstd_comp_tv_template),
5559*4882a593Smuzhiyun 				.decomp = __VECS(zstd_decomp_tv_template)
5560*4882a593Smuzhiyun 			}
5561*4882a593Smuzhiyun 		}
5562*4882a593Smuzhiyun 	}
5563*4882a593Smuzhiyun };
5564*4882a593Smuzhiyun 
alg_check_test_descs_order(void)5565*4882a593Smuzhiyun static void alg_check_test_descs_order(void)
5566*4882a593Smuzhiyun {
5567*4882a593Smuzhiyun 	int i;
5568*4882a593Smuzhiyun 
5569*4882a593Smuzhiyun 	for (i = 1; i < ARRAY_SIZE(alg_test_descs); i++) {
5570*4882a593Smuzhiyun 		int diff = strcmp(alg_test_descs[i - 1].alg,
5571*4882a593Smuzhiyun 				  alg_test_descs[i].alg);
5572*4882a593Smuzhiyun 
5573*4882a593Smuzhiyun 		if (WARN_ON(diff > 0)) {
5574*4882a593Smuzhiyun 			pr_warn("testmgr: alg_test_descs entries in wrong order: '%s' before '%s'\n",
5575*4882a593Smuzhiyun 				alg_test_descs[i - 1].alg,
5576*4882a593Smuzhiyun 				alg_test_descs[i].alg);
5577*4882a593Smuzhiyun 		}
5578*4882a593Smuzhiyun 
5579*4882a593Smuzhiyun 		if (WARN_ON(diff == 0)) {
5580*4882a593Smuzhiyun 			pr_warn("testmgr: duplicate alg_test_descs entry: '%s'\n",
5581*4882a593Smuzhiyun 				alg_test_descs[i].alg);
5582*4882a593Smuzhiyun 		}
5583*4882a593Smuzhiyun 	}
5584*4882a593Smuzhiyun }
5585*4882a593Smuzhiyun 
alg_check_testvec_configs(void)5586*4882a593Smuzhiyun static void alg_check_testvec_configs(void)
5587*4882a593Smuzhiyun {
5588*4882a593Smuzhiyun 	int i;
5589*4882a593Smuzhiyun 
5590*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(default_cipher_testvec_configs); i++)
5591*4882a593Smuzhiyun 		WARN_ON(!valid_testvec_config(
5592*4882a593Smuzhiyun 				&default_cipher_testvec_configs[i]));
5593*4882a593Smuzhiyun 
5594*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(default_hash_testvec_configs); i++)
5595*4882a593Smuzhiyun 		WARN_ON(!valid_testvec_config(
5596*4882a593Smuzhiyun 				&default_hash_testvec_configs[i]));
5597*4882a593Smuzhiyun }
5598*4882a593Smuzhiyun 
testmgr_onetime_init(void)5599*4882a593Smuzhiyun static void testmgr_onetime_init(void)
5600*4882a593Smuzhiyun {
5601*4882a593Smuzhiyun 	alg_check_test_descs_order();
5602*4882a593Smuzhiyun 	alg_check_testvec_configs();
5603*4882a593Smuzhiyun 
5604*4882a593Smuzhiyun #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
5605*4882a593Smuzhiyun 	pr_warn("alg: extra crypto tests enabled.  This is intended for developer use only.\n");
5606*4882a593Smuzhiyun #endif
5607*4882a593Smuzhiyun }
5608*4882a593Smuzhiyun 
alg_find_test(const char * alg)5609*4882a593Smuzhiyun static int alg_find_test(const char *alg)
5610*4882a593Smuzhiyun {
5611*4882a593Smuzhiyun 	int start = 0;
5612*4882a593Smuzhiyun 	int end = ARRAY_SIZE(alg_test_descs);
5613*4882a593Smuzhiyun 
5614*4882a593Smuzhiyun 	while (start < end) {
5615*4882a593Smuzhiyun 		int i = (start + end) / 2;
5616*4882a593Smuzhiyun 		int diff = strcmp(alg_test_descs[i].alg, alg);
5617*4882a593Smuzhiyun 
5618*4882a593Smuzhiyun 		if (diff > 0) {
5619*4882a593Smuzhiyun 			end = i;
5620*4882a593Smuzhiyun 			continue;
5621*4882a593Smuzhiyun 		}
5622*4882a593Smuzhiyun 
5623*4882a593Smuzhiyun 		if (diff < 0) {
5624*4882a593Smuzhiyun 			start = i + 1;
5625*4882a593Smuzhiyun 			continue;
5626*4882a593Smuzhiyun 		}
5627*4882a593Smuzhiyun 
5628*4882a593Smuzhiyun 		return i;
5629*4882a593Smuzhiyun 	}
5630*4882a593Smuzhiyun 
5631*4882a593Smuzhiyun 	return -1;
5632*4882a593Smuzhiyun }
5633*4882a593Smuzhiyun 
alg_test(const char * driver,const char * alg,u32 type,u32 mask)5634*4882a593Smuzhiyun int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
5635*4882a593Smuzhiyun {
5636*4882a593Smuzhiyun 	int i;
5637*4882a593Smuzhiyun 	int j;
5638*4882a593Smuzhiyun 	int rc;
5639*4882a593Smuzhiyun 
5640*4882a593Smuzhiyun 	if (!fips_enabled && notests) {
5641*4882a593Smuzhiyun 		printk_once(KERN_INFO "alg: self-tests disabled\n");
5642*4882a593Smuzhiyun 		return 0;
5643*4882a593Smuzhiyun 	}
5644*4882a593Smuzhiyun 
5645*4882a593Smuzhiyun 	DO_ONCE(testmgr_onetime_init);
5646*4882a593Smuzhiyun 
5647*4882a593Smuzhiyun 	if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) {
5648*4882a593Smuzhiyun 		char nalg[CRYPTO_MAX_ALG_NAME];
5649*4882a593Smuzhiyun 
5650*4882a593Smuzhiyun 		if (snprintf(nalg, sizeof(nalg), "ecb(%s)", alg) >=
5651*4882a593Smuzhiyun 		    sizeof(nalg))
5652*4882a593Smuzhiyun 			return -ENAMETOOLONG;
5653*4882a593Smuzhiyun 
5654*4882a593Smuzhiyun 		i = alg_find_test(nalg);
5655*4882a593Smuzhiyun 		if (i < 0)
5656*4882a593Smuzhiyun 			goto notest;
5657*4882a593Smuzhiyun 
5658*4882a593Smuzhiyun 		if (fips_enabled && !alg_test_descs[i].fips_allowed)
5659*4882a593Smuzhiyun 			goto non_fips_alg;
5660*4882a593Smuzhiyun 
5661*4882a593Smuzhiyun 		rc = alg_test_cipher(alg_test_descs + i, driver, type, mask);
5662*4882a593Smuzhiyun 		goto test_done;
5663*4882a593Smuzhiyun 	}
5664*4882a593Smuzhiyun 
5665*4882a593Smuzhiyun 	i = alg_find_test(alg);
5666*4882a593Smuzhiyun 	j = alg_find_test(driver);
5667*4882a593Smuzhiyun 	if (i < 0 && j < 0)
5668*4882a593Smuzhiyun 		goto notest;
5669*4882a593Smuzhiyun 
5670*4882a593Smuzhiyun 	if (fips_enabled && ((i >= 0 && !alg_test_descs[i].fips_allowed) ||
5671*4882a593Smuzhiyun 			     (j >= 0 && !alg_test_descs[j].fips_allowed)))
5672*4882a593Smuzhiyun 		goto non_fips_alg;
5673*4882a593Smuzhiyun 
5674*4882a593Smuzhiyun 	rc = 0;
5675*4882a593Smuzhiyun 	if (i >= 0)
5676*4882a593Smuzhiyun 		rc |= alg_test_descs[i].test(alg_test_descs + i, driver,
5677*4882a593Smuzhiyun 					     type, mask);
5678*4882a593Smuzhiyun 	if (j >= 0 && j != i)
5679*4882a593Smuzhiyun 		rc |= alg_test_descs[j].test(alg_test_descs + j, driver,
5680*4882a593Smuzhiyun 					     type, mask);
5681*4882a593Smuzhiyun 
5682*4882a593Smuzhiyun test_done:
5683*4882a593Smuzhiyun 	if (rc && (fips_enabled || panic_on_fail)) {
5684*4882a593Smuzhiyun 		fips_fail_notify();
5685*4882a593Smuzhiyun 		panic("alg: self-tests for %s (%s) failed in %s mode!\n",
5686*4882a593Smuzhiyun 		      driver, alg, fips_enabled ? "fips" : "panic_on_fail");
5687*4882a593Smuzhiyun 	}
5688*4882a593Smuzhiyun 
5689*4882a593Smuzhiyun 	if (fips_enabled && !rc)
5690*4882a593Smuzhiyun 		pr_info("alg: self-tests for %s (%s) passed\n", driver, alg);
5691*4882a593Smuzhiyun 
5692*4882a593Smuzhiyun 	return rc;
5693*4882a593Smuzhiyun 
5694*4882a593Smuzhiyun notest:
5695*4882a593Smuzhiyun 	printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver);
5696*4882a593Smuzhiyun 	return 0;
5697*4882a593Smuzhiyun non_fips_alg:
5698*4882a593Smuzhiyun 	return -EINVAL;
5699*4882a593Smuzhiyun }
5700*4882a593Smuzhiyun 
5701*4882a593Smuzhiyun #endif /* CONFIG_CRYPTO_MANAGER_DISABLE_TESTS */
5702*4882a593Smuzhiyun 
5703*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(alg_test);
5704