xref: /openbmc/linux/crypto/testmgr.c (revision 092acf06)
1da7f033dSHerbert Xu /*
2da7f033dSHerbert Xu  * Algorithm testing framework and tests.
3da7f033dSHerbert Xu  *
4da7f033dSHerbert Xu  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
5da7f033dSHerbert Xu  * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
6da7f033dSHerbert Xu  * Copyright (c) 2007 Nokia Siemens Networks
7da7f033dSHerbert Xu  * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
8da7f033dSHerbert Xu  *
969435b94SAdrian Hoban  * Updated RFC4106 AES-GCM testing.
1069435b94SAdrian Hoban  *    Authors: Aidan O'Mahony (aidan.o.mahony@intel.com)
1169435b94SAdrian Hoban  *             Adrian Hoban <adrian.hoban@intel.com>
1269435b94SAdrian Hoban  *             Gabriele Paoloni <gabriele.paoloni@intel.com>
1369435b94SAdrian Hoban  *             Tadeusz Struk (tadeusz.struk@intel.com)
1469435b94SAdrian Hoban  *    Copyright (c) 2010, Intel Corporation.
1569435b94SAdrian Hoban  *
16da7f033dSHerbert Xu  * This program is free software; you can redistribute it and/or modify it
17da7f033dSHerbert Xu  * under the terms of the GNU General Public License as published by the Free
18da7f033dSHerbert Xu  * Software Foundation; either version 2 of the License, or (at your option)
19da7f033dSHerbert Xu  * any later version.
20da7f033dSHerbert Xu  *
21da7f033dSHerbert Xu  */
22da7f033dSHerbert Xu 
231ce33115SHerbert Xu #include <crypto/aead.h>
24da7f033dSHerbert Xu #include <crypto/hash.h>
2512773d93SHerbert Xu #include <crypto/skcipher.h>
26da7f033dSHerbert Xu #include <linux/err.h>
271c41b882SHerbert Xu #include <linux/fips.h>
28da7f033dSHerbert Xu #include <linux/module.h>
29da7f033dSHerbert Xu #include <linux/scatterlist.h>
30da7f033dSHerbert Xu #include <linux/slab.h>
31da7f033dSHerbert Xu #include <linux/string.h>
327647d6ceSJarod Wilson #include <crypto/rng.h>
3364d1cdfbSStephan Mueller #include <crypto/drbg.h>
34946cc463STadeusz Struk #include <crypto/akcipher.h>
35802c7f1cSSalvatore Benedetto #include <crypto/kpp.h>
36d7db7a88SGiovanni Cabiddu #include <crypto/acompress.h>
37da7f033dSHerbert Xu 
38da7f033dSHerbert Xu #include "internal.h"
390b767f96SAlexander Shishkin 
409e5c9fe4SRichard W.M. Jones static bool notests;
419e5c9fe4SRichard W.M. Jones module_param(notests, bool, 0644);
429e5c9fe4SRichard W.M. Jones MODULE_PARM_DESC(notests, "disable crypto self-tests");
439e5c9fe4SRichard W.M. Jones 
44326a6346SHerbert Xu #ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS
450b767f96SAlexander Shishkin 
460b767f96SAlexander Shishkin /* a perfect nop */
470b767f96SAlexander Shishkin int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
480b767f96SAlexander Shishkin {
490b767f96SAlexander Shishkin 	return 0;
500b767f96SAlexander Shishkin }
510b767f96SAlexander Shishkin 
520b767f96SAlexander Shishkin #else
530b767f96SAlexander Shishkin 
54da7f033dSHerbert Xu #include "testmgr.h"
55da7f033dSHerbert Xu 
56da7f033dSHerbert Xu /*
57da7f033dSHerbert Xu  * Need slab memory for testing (size in number of pages).
58da7f033dSHerbert Xu  */
59da7f033dSHerbert Xu #define XBUFSIZE	8
60da7f033dSHerbert Xu 
61da7f033dSHerbert Xu /*
62da7f033dSHerbert Xu  * Indexes into the xbuf to simulate cross-page access.
63da7f033dSHerbert Xu  */
64da7f033dSHerbert Xu #define IDX1		32
65da7f033dSHerbert Xu #define IDX2		32400
6604b46fbdSArd Biesheuvel #define IDX3		1511
67da7f033dSHerbert Xu #define IDX4		8193
68da7f033dSHerbert Xu #define IDX5		22222
69da7f033dSHerbert Xu #define IDX6		17101
70da7f033dSHerbert Xu #define IDX7		27333
71da7f033dSHerbert Xu #define IDX8		3000
72da7f033dSHerbert Xu 
73da7f033dSHerbert Xu /*
74da7f033dSHerbert Xu * Used by test_cipher()
75da7f033dSHerbert Xu */
76da7f033dSHerbert Xu #define ENCRYPT 1
77da7f033dSHerbert Xu #define DECRYPT 0
78da7f033dSHerbert Xu 
79da7f033dSHerbert Xu struct tcrypt_result {
80da7f033dSHerbert Xu 	struct completion completion;
81da7f033dSHerbert Xu 	int err;
82da7f033dSHerbert Xu };
83da7f033dSHerbert Xu 
84da7f033dSHerbert Xu struct aead_test_suite {
85da7f033dSHerbert Xu 	struct {
86da7f033dSHerbert Xu 		struct aead_testvec *vecs;
87da7f033dSHerbert Xu 		unsigned int count;
88da7f033dSHerbert Xu 	} enc, dec;
89da7f033dSHerbert Xu };
90da7f033dSHerbert Xu 
91da7f033dSHerbert Xu struct cipher_test_suite {
92da7f033dSHerbert Xu 	struct {
93da7f033dSHerbert Xu 		struct cipher_testvec *vecs;
94da7f033dSHerbert Xu 		unsigned int count;
95da7f033dSHerbert Xu 	} enc, dec;
96da7f033dSHerbert Xu };
97da7f033dSHerbert Xu 
98da7f033dSHerbert Xu struct comp_test_suite {
99da7f033dSHerbert Xu 	struct {
100da7f033dSHerbert Xu 		struct comp_testvec *vecs;
101da7f033dSHerbert Xu 		unsigned int count;
102da7f033dSHerbert Xu 	} comp, decomp;
103da7f033dSHerbert Xu };
104da7f033dSHerbert Xu 
105da7f033dSHerbert Xu struct hash_test_suite {
106da7f033dSHerbert Xu 	struct hash_testvec *vecs;
107da7f033dSHerbert Xu 	unsigned int count;
108da7f033dSHerbert Xu };
109da7f033dSHerbert Xu 
1107647d6ceSJarod Wilson struct cprng_test_suite {
1117647d6ceSJarod Wilson 	struct cprng_testvec *vecs;
1127647d6ceSJarod Wilson 	unsigned int count;
1137647d6ceSJarod Wilson };
1147647d6ceSJarod Wilson 
11564d1cdfbSStephan Mueller struct drbg_test_suite {
11664d1cdfbSStephan Mueller 	struct drbg_testvec *vecs;
11764d1cdfbSStephan Mueller 	unsigned int count;
11864d1cdfbSStephan Mueller };
11964d1cdfbSStephan Mueller 
120946cc463STadeusz Struk struct akcipher_test_suite {
121946cc463STadeusz Struk 	struct akcipher_testvec *vecs;
122946cc463STadeusz Struk 	unsigned int count;
123946cc463STadeusz Struk };
124946cc463STadeusz Struk 
125802c7f1cSSalvatore Benedetto struct kpp_test_suite {
126802c7f1cSSalvatore Benedetto 	struct kpp_testvec *vecs;
127802c7f1cSSalvatore Benedetto 	unsigned int count;
128802c7f1cSSalvatore Benedetto };
129802c7f1cSSalvatore Benedetto 
130da7f033dSHerbert Xu struct alg_test_desc {
131da7f033dSHerbert Xu 	const char *alg;
132da7f033dSHerbert Xu 	int (*test)(const struct alg_test_desc *desc, const char *driver,
133da7f033dSHerbert Xu 		    u32 type, u32 mask);
134a1915d51SJarod Wilson 	int fips_allowed;	/* set if alg is allowed in fips mode */
135da7f033dSHerbert Xu 
136da7f033dSHerbert Xu 	union {
137da7f033dSHerbert Xu 		struct aead_test_suite aead;
138da7f033dSHerbert Xu 		struct cipher_test_suite cipher;
139da7f033dSHerbert Xu 		struct comp_test_suite comp;
140da7f033dSHerbert Xu 		struct hash_test_suite hash;
1417647d6ceSJarod Wilson 		struct cprng_test_suite cprng;
14264d1cdfbSStephan Mueller 		struct drbg_test_suite drbg;
143946cc463STadeusz Struk 		struct akcipher_test_suite akcipher;
144802c7f1cSSalvatore Benedetto 		struct kpp_test_suite kpp;
145da7f033dSHerbert Xu 	} suite;
146da7f033dSHerbert Xu };
147da7f033dSHerbert Xu 
148da7f033dSHerbert Xu static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 };
149da7f033dSHerbert Xu 
150da7f033dSHerbert Xu static void hexdump(unsigned char *buf, unsigned int len)
151da7f033dSHerbert Xu {
152da7f033dSHerbert Xu 	print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
153da7f033dSHerbert Xu 			16, 1,
154da7f033dSHerbert Xu 			buf, len, false);
155da7f033dSHerbert Xu }
156da7f033dSHerbert Xu 
157da7f033dSHerbert Xu static void tcrypt_complete(struct crypto_async_request *req, int err)
158da7f033dSHerbert Xu {
159da7f033dSHerbert Xu 	struct tcrypt_result *res = req->data;
160da7f033dSHerbert Xu 
161da7f033dSHerbert Xu 	if (err == -EINPROGRESS)
162da7f033dSHerbert Xu 		return;
163da7f033dSHerbert Xu 
164da7f033dSHerbert Xu 	res->err = err;
165da7f033dSHerbert Xu 	complete(&res->completion);
166da7f033dSHerbert Xu }
167da7f033dSHerbert Xu 
168f8b0d4d0SHerbert Xu static int testmgr_alloc_buf(char *buf[XBUFSIZE])
169f8b0d4d0SHerbert Xu {
170f8b0d4d0SHerbert Xu 	int i;
171f8b0d4d0SHerbert Xu 
172f8b0d4d0SHerbert Xu 	for (i = 0; i < XBUFSIZE; i++) {
173f8b0d4d0SHerbert Xu 		buf[i] = (void *)__get_free_page(GFP_KERNEL);
174f8b0d4d0SHerbert Xu 		if (!buf[i])
175f8b0d4d0SHerbert Xu 			goto err_free_buf;
176f8b0d4d0SHerbert Xu 	}
177f8b0d4d0SHerbert Xu 
178f8b0d4d0SHerbert Xu 	return 0;
179f8b0d4d0SHerbert Xu 
180f8b0d4d0SHerbert Xu err_free_buf:
181f8b0d4d0SHerbert Xu 	while (i-- > 0)
182f8b0d4d0SHerbert Xu 		free_page((unsigned long)buf[i]);
183f8b0d4d0SHerbert Xu 
184f8b0d4d0SHerbert Xu 	return -ENOMEM;
185f8b0d4d0SHerbert Xu }
186f8b0d4d0SHerbert Xu 
187f8b0d4d0SHerbert Xu static void testmgr_free_buf(char *buf[XBUFSIZE])
188f8b0d4d0SHerbert Xu {
189f8b0d4d0SHerbert Xu 	int i;
190f8b0d4d0SHerbert Xu 
191f8b0d4d0SHerbert Xu 	for (i = 0; i < XBUFSIZE; i++)
192f8b0d4d0SHerbert Xu 		free_page((unsigned long)buf[i]);
193f8b0d4d0SHerbert Xu }
194f8b0d4d0SHerbert Xu 
195d4c85f9bSCristian Stoica static int wait_async_op(struct tcrypt_result *tr, int ret)
196a8f1a052SDavid S. Miller {
197a8f1a052SDavid S. Miller 	if (ret == -EINPROGRESS || ret == -EBUSY) {
1988a45ac12SRabin Vincent 		wait_for_completion(&tr->completion);
19916735d02SWolfram Sang 		reinit_completion(&tr->completion);
2008a45ac12SRabin Vincent 		ret = tr->err;
201a8f1a052SDavid S. Miller 	}
202a8f1a052SDavid S. Miller 	return ret;
203a8f1a052SDavid S. Miller }
204a8f1a052SDavid S. Miller 
205018ba95cSWang, Rui Y static int ahash_partial_update(struct ahash_request **preq,
206018ba95cSWang, Rui Y 	struct crypto_ahash *tfm, struct hash_testvec *template,
207018ba95cSWang, Rui Y 	void *hash_buff, int k, int temp, struct scatterlist *sg,
208018ba95cSWang, Rui Y 	const char *algo, char *result, struct tcrypt_result *tresult)
209018ba95cSWang, Rui Y {
210018ba95cSWang, Rui Y 	char *state;
211018ba95cSWang, Rui Y 	struct ahash_request *req;
212018ba95cSWang, Rui Y 	int statesize, ret = -EINVAL;
2137bcb87bcSJan Stancek 	const char guard[] = { 0x00, 0xba, 0xad, 0x00 };
214018ba95cSWang, Rui Y 
215018ba95cSWang, Rui Y 	req = *preq;
216018ba95cSWang, Rui Y 	statesize = crypto_ahash_statesize(
217018ba95cSWang, Rui Y 			crypto_ahash_reqtfm(req));
2187bcb87bcSJan Stancek 	state = kmalloc(statesize + sizeof(guard), GFP_KERNEL);
219018ba95cSWang, Rui Y 	if (!state) {
220018ba95cSWang, Rui Y 		pr_err("alt: hash: Failed to alloc state for %s\n", algo);
221018ba95cSWang, Rui Y 		goto out_nostate;
222018ba95cSWang, Rui Y 	}
2237bcb87bcSJan Stancek 	memcpy(state + statesize, guard, sizeof(guard));
224018ba95cSWang, Rui Y 	ret = crypto_ahash_export(req, state);
2257bcb87bcSJan Stancek 	WARN_ON(memcmp(state + statesize, guard, sizeof(guard)));
226018ba95cSWang, Rui Y 	if (ret) {
227018ba95cSWang, Rui Y 		pr_err("alt: hash: Failed to export() for %s\n", algo);
228018ba95cSWang, Rui Y 		goto out;
229018ba95cSWang, Rui Y 	}
230018ba95cSWang, Rui Y 	ahash_request_free(req);
231018ba95cSWang, Rui Y 	req = ahash_request_alloc(tfm, GFP_KERNEL);
232018ba95cSWang, Rui Y 	if (!req) {
233018ba95cSWang, Rui Y 		pr_err("alg: hash: Failed to alloc request for %s\n", algo);
234018ba95cSWang, Rui Y 		goto out_noreq;
235018ba95cSWang, Rui Y 	}
236018ba95cSWang, Rui Y 	ahash_request_set_callback(req,
237018ba95cSWang, Rui Y 		CRYPTO_TFM_REQ_MAY_BACKLOG,
238018ba95cSWang, Rui Y 		tcrypt_complete, tresult);
239018ba95cSWang, Rui Y 
240018ba95cSWang, Rui Y 	memcpy(hash_buff, template->plaintext + temp,
241018ba95cSWang, Rui Y 		template->tap[k]);
242018ba95cSWang, Rui Y 	sg_init_one(&sg[0], hash_buff, template->tap[k]);
243018ba95cSWang, Rui Y 	ahash_request_set_crypt(req, sg, result, template->tap[k]);
244018ba95cSWang, Rui Y 	ret = crypto_ahash_import(req, state);
245018ba95cSWang, Rui Y 	if (ret) {
246018ba95cSWang, Rui Y 		pr_err("alg: hash: Failed to import() for %s\n", algo);
247018ba95cSWang, Rui Y 		goto out;
248018ba95cSWang, Rui Y 	}
249018ba95cSWang, Rui Y 	ret = wait_async_op(tresult, crypto_ahash_update(req));
250018ba95cSWang, Rui Y 	if (ret)
251018ba95cSWang, Rui Y 		goto out;
252018ba95cSWang, Rui Y 	*preq = req;
253018ba95cSWang, Rui Y 	ret = 0;
254018ba95cSWang, Rui Y 	goto out_noreq;
255018ba95cSWang, Rui Y out:
256018ba95cSWang, Rui Y 	ahash_request_free(req);
257018ba95cSWang, Rui Y out_noreq:
258018ba95cSWang, Rui Y 	kfree(state);
259018ba95cSWang, Rui Y out_nostate:
260018ba95cSWang, Rui Y 	return ret;
261018ba95cSWang, Rui Y }
262018ba95cSWang, Rui Y 
263da5ffe11SJussi Kivilinna static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
264da5ffe11SJussi Kivilinna 		       unsigned int tcount, bool use_digest,
265da5ffe11SJussi Kivilinna 		       const int align_offset)
266da7f033dSHerbert Xu {
267da7f033dSHerbert Xu 	const char *algo = crypto_tfm_alg_driver_name(crypto_ahash_tfm(tfm));
268e93acd6fSAndrew Lutomirski 	size_t digest_size = crypto_ahash_digestsize(tfm);
269da7f033dSHerbert Xu 	unsigned int i, j, k, temp;
270da7f033dSHerbert Xu 	struct scatterlist sg[8];
27129b77e5dSHoria Geanta 	char *result;
27229b77e5dSHoria Geanta 	char *key;
273da7f033dSHerbert Xu 	struct ahash_request *req;
274da7f033dSHerbert Xu 	struct tcrypt_result tresult;
275da7f033dSHerbert Xu 	void *hash_buff;
276f8b0d4d0SHerbert Xu 	char *xbuf[XBUFSIZE];
277f8b0d4d0SHerbert Xu 	int ret = -ENOMEM;
278f8b0d4d0SHerbert Xu 
279e93acd6fSAndrew Lutomirski 	result = kmalloc(digest_size, GFP_KERNEL);
28029b77e5dSHoria Geanta 	if (!result)
28129b77e5dSHoria Geanta 		return ret;
28229b77e5dSHoria Geanta 	key = kmalloc(MAX_KEYLEN, GFP_KERNEL);
28329b77e5dSHoria Geanta 	if (!key)
28429b77e5dSHoria Geanta 		goto out_nobuf;
285f8b0d4d0SHerbert Xu 	if (testmgr_alloc_buf(xbuf))
286f8b0d4d0SHerbert Xu 		goto out_nobuf;
287da7f033dSHerbert Xu 
288da7f033dSHerbert Xu 	init_completion(&tresult.completion);
289da7f033dSHerbert Xu 
290da7f033dSHerbert Xu 	req = ahash_request_alloc(tfm, GFP_KERNEL);
291da7f033dSHerbert Xu 	if (!req) {
292da7f033dSHerbert Xu 		printk(KERN_ERR "alg: hash: Failed to allocate request for "
293da7f033dSHerbert Xu 		       "%s\n", algo);
294da7f033dSHerbert Xu 		goto out_noreq;
295da7f033dSHerbert Xu 	}
296da7f033dSHerbert Xu 	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
297da7f033dSHerbert Xu 				   tcrypt_complete, &tresult);
298da7f033dSHerbert Xu 
299a0cfae59SHerbert Xu 	j = 0;
300da7f033dSHerbert Xu 	for (i = 0; i < tcount; i++) {
301a0cfae59SHerbert Xu 		if (template[i].np)
302a0cfae59SHerbert Xu 			continue;
303a0cfae59SHerbert Xu 
304da5ffe11SJussi Kivilinna 		ret = -EINVAL;
305da5ffe11SJussi Kivilinna 		if (WARN_ON(align_offset + template[i].psize > PAGE_SIZE))
306da5ffe11SJussi Kivilinna 			goto out;
307da5ffe11SJussi Kivilinna 
308a0cfae59SHerbert Xu 		j++;
309e93acd6fSAndrew Lutomirski 		memset(result, 0, digest_size);
310da7f033dSHerbert Xu 
311da7f033dSHerbert Xu 		hash_buff = xbuf[0];
312da5ffe11SJussi Kivilinna 		hash_buff += align_offset;
313da7f033dSHerbert Xu 
314da7f033dSHerbert Xu 		memcpy(hash_buff, template[i].plaintext, template[i].psize);
315da7f033dSHerbert Xu 		sg_init_one(&sg[0], hash_buff, template[i].psize);
316da7f033dSHerbert Xu 
317da7f033dSHerbert Xu 		if (template[i].ksize) {
318da7f033dSHerbert Xu 			crypto_ahash_clear_flags(tfm, ~0);
31929b77e5dSHoria Geanta 			if (template[i].ksize > MAX_KEYLEN) {
32029b77e5dSHoria Geanta 				pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n",
32129b77e5dSHoria Geanta 				       j, algo, template[i].ksize, MAX_KEYLEN);
32229b77e5dSHoria Geanta 				ret = -EINVAL;
32329b77e5dSHoria Geanta 				goto out;
32429b77e5dSHoria Geanta 			}
32529b77e5dSHoria Geanta 			memcpy(key, template[i].key, template[i].ksize);
32629b77e5dSHoria Geanta 			ret = crypto_ahash_setkey(tfm, key, template[i].ksize);
327da7f033dSHerbert Xu 			if (ret) {
328da7f033dSHerbert Xu 				printk(KERN_ERR "alg: hash: setkey failed on "
329a0cfae59SHerbert Xu 				       "test %d for %s: ret=%d\n", j, algo,
330da7f033dSHerbert Xu 				       -ret);
331da7f033dSHerbert Xu 				goto out;
332da7f033dSHerbert Xu 			}
333da7f033dSHerbert Xu 		}
334da7f033dSHerbert Xu 
335da7f033dSHerbert Xu 		ahash_request_set_crypt(req, sg, result, template[i].psize);
336a8f1a052SDavid S. Miller 		if (use_digest) {
337d4c85f9bSCristian Stoica 			ret = wait_async_op(&tresult, crypto_ahash_digest(req));
338a8f1a052SDavid S. Miller 			if (ret) {
339a8f1a052SDavid S. Miller 				pr_err("alg: hash: digest failed on test %d "
340a0cfae59SHerbert Xu 				       "for %s: ret=%d\n", j, algo, -ret);
341da7f033dSHerbert Xu 				goto out;
342da7f033dSHerbert Xu 			}
343a8f1a052SDavid S. Miller 		} else {
344d4c85f9bSCristian Stoica 			ret = wait_async_op(&tresult, crypto_ahash_init(req));
345a8f1a052SDavid S. Miller 			if (ret) {
346a8f1a052SDavid S. Miller 				pr_err("alt: hash: init failed on test %d "
347a8f1a052SDavid S. Miller 				       "for %s: ret=%d\n", j, algo, -ret);
348a8f1a052SDavid S. Miller 				goto out;
349a8f1a052SDavid S. Miller 			}
350d4c85f9bSCristian Stoica 			ret = wait_async_op(&tresult, crypto_ahash_update(req));
351a8f1a052SDavid S. Miller 			if (ret) {
352a8f1a052SDavid S. Miller 				pr_err("alt: hash: update failed on test %d "
353a8f1a052SDavid S. Miller 				       "for %s: ret=%d\n", j, algo, -ret);
354a8f1a052SDavid S. Miller 				goto out;
355a8f1a052SDavid S. Miller 			}
356d4c85f9bSCristian Stoica 			ret = wait_async_op(&tresult, crypto_ahash_final(req));
357a8f1a052SDavid S. Miller 			if (ret) {
358a8f1a052SDavid S. Miller 				pr_err("alt: hash: final failed on test %d "
359a8f1a052SDavid S. Miller 				       "for %s: ret=%d\n", j, algo, -ret);
360a8f1a052SDavid S. Miller 				goto out;
361a8f1a052SDavid S. Miller 			}
362a8f1a052SDavid S. Miller 		}
363da7f033dSHerbert Xu 
364da7f033dSHerbert Xu 		if (memcmp(result, template[i].digest,
365da7f033dSHerbert Xu 			   crypto_ahash_digestsize(tfm))) {
366da7f033dSHerbert Xu 			printk(KERN_ERR "alg: hash: Test %d failed for %s\n",
367a0cfae59SHerbert Xu 			       j, algo);
368da7f033dSHerbert Xu 			hexdump(result, crypto_ahash_digestsize(tfm));
369da7f033dSHerbert Xu 			ret = -EINVAL;
370da7f033dSHerbert Xu 			goto out;
371da7f033dSHerbert Xu 		}
372da7f033dSHerbert Xu 	}
373da7f033dSHerbert Xu 
374da7f033dSHerbert Xu 	j = 0;
375da7f033dSHerbert Xu 	for (i = 0; i < tcount; i++) {
376da5ffe11SJussi Kivilinna 		/* alignment tests are only done with continuous buffers */
377da5ffe11SJussi Kivilinna 		if (align_offset != 0)
378da5ffe11SJussi Kivilinna 			break;
379da5ffe11SJussi Kivilinna 
3805f2b424eSCristian Stoica 		if (!template[i].np)
3815f2b424eSCristian Stoica 			continue;
3825f2b424eSCristian Stoica 
383da7f033dSHerbert Xu 		j++;
384e93acd6fSAndrew Lutomirski 		memset(result, 0, digest_size);
385da7f033dSHerbert Xu 
386da7f033dSHerbert Xu 		temp = 0;
387da7f033dSHerbert Xu 		sg_init_table(sg, template[i].np);
388fd57f22aSHerbert Xu 		ret = -EINVAL;
389da7f033dSHerbert Xu 		for (k = 0; k < template[i].np; k++) {
390fd57f22aSHerbert Xu 			if (WARN_ON(offset_in_page(IDX[k]) +
391fd57f22aSHerbert Xu 				    template[i].tap[k] > PAGE_SIZE))
392fd57f22aSHerbert Xu 				goto out;
393da7f033dSHerbert Xu 			sg_set_buf(&sg[k],
394da7f033dSHerbert Xu 				   memcpy(xbuf[IDX[k] >> PAGE_SHIFT] +
395da7f033dSHerbert Xu 					  offset_in_page(IDX[k]),
396da7f033dSHerbert Xu 					  template[i].plaintext + temp,
397da7f033dSHerbert Xu 					  template[i].tap[k]),
398da7f033dSHerbert Xu 				   template[i].tap[k]);
399da7f033dSHerbert Xu 			temp += template[i].tap[k];
400da7f033dSHerbert Xu 		}
401da7f033dSHerbert Xu 
402da7f033dSHerbert Xu 		if (template[i].ksize) {
40329b77e5dSHoria Geanta 			if (template[i].ksize > MAX_KEYLEN) {
40429b77e5dSHoria Geanta 				pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n",
4055f2b424eSCristian Stoica 				       j, algo, template[i].ksize, MAX_KEYLEN);
40629b77e5dSHoria Geanta 				ret = -EINVAL;
40729b77e5dSHoria Geanta 				goto out;
40829b77e5dSHoria Geanta 			}
409da7f033dSHerbert Xu 			crypto_ahash_clear_flags(tfm, ~0);
41029b77e5dSHoria Geanta 			memcpy(key, template[i].key, template[i].ksize);
4115f2b424eSCristian Stoica 			ret = crypto_ahash_setkey(tfm, key, template[i].ksize);
412da7f033dSHerbert Xu 
413da7f033dSHerbert Xu 			if (ret) {
414da7f033dSHerbert Xu 				printk(KERN_ERR "alg: hash: setkey "
415da7f033dSHerbert Xu 				       "failed on chunking test %d "
4165f2b424eSCristian Stoica 				       "for %s: ret=%d\n", j, algo, -ret);
417da7f033dSHerbert Xu 				goto out;
418da7f033dSHerbert Xu 			}
419da7f033dSHerbert Xu 		}
420da7f033dSHerbert Xu 
4215f2b424eSCristian Stoica 		ahash_request_set_crypt(req, sg, result, template[i].psize);
422da7f033dSHerbert Xu 		ret = crypto_ahash_digest(req);
423da7f033dSHerbert Xu 		switch (ret) {
424da7f033dSHerbert Xu 		case 0:
425da7f033dSHerbert Xu 			break;
426da7f033dSHerbert Xu 		case -EINPROGRESS:
427da7f033dSHerbert Xu 		case -EBUSY:
4288a45ac12SRabin Vincent 			wait_for_completion(&tresult.completion);
42916735d02SWolfram Sang 			reinit_completion(&tresult.completion);
4308a45ac12SRabin Vincent 			ret = tresult.err;
4318a45ac12SRabin Vincent 			if (!ret)
432da7f033dSHerbert Xu 				break;
433da7f033dSHerbert Xu 			/* fall through */
434da7f033dSHerbert Xu 		default:
435da7f033dSHerbert Xu 			printk(KERN_ERR "alg: hash: digest failed "
436da7f033dSHerbert Xu 			       "on chunking test %d for %s: "
437da7f033dSHerbert Xu 			       "ret=%d\n", j, algo, -ret);
438da7f033dSHerbert Xu 			goto out;
439da7f033dSHerbert Xu 		}
440da7f033dSHerbert Xu 
441da7f033dSHerbert Xu 		if (memcmp(result, template[i].digest,
442da7f033dSHerbert Xu 			   crypto_ahash_digestsize(tfm))) {
443da7f033dSHerbert Xu 			printk(KERN_ERR "alg: hash: Chunking test %d "
444da7f033dSHerbert Xu 			       "failed for %s\n", j, algo);
445da7f033dSHerbert Xu 			hexdump(result, crypto_ahash_digestsize(tfm));
446da7f033dSHerbert Xu 			ret = -EINVAL;
447da7f033dSHerbert Xu 			goto out;
448da7f033dSHerbert Xu 		}
449da7f033dSHerbert Xu 	}
450da7f033dSHerbert Xu 
451018ba95cSWang, Rui Y 	/* partial update exercise */
452018ba95cSWang, Rui Y 	j = 0;
453018ba95cSWang, Rui Y 	for (i = 0; i < tcount; i++) {
454018ba95cSWang, Rui Y 		/* alignment tests are only done with continuous buffers */
455018ba95cSWang, Rui Y 		if (align_offset != 0)
456018ba95cSWang, Rui Y 			break;
457018ba95cSWang, Rui Y 
458018ba95cSWang, Rui Y 		if (template[i].np < 2)
459018ba95cSWang, Rui Y 			continue;
460018ba95cSWang, Rui Y 
461018ba95cSWang, Rui Y 		j++;
462e93acd6fSAndrew Lutomirski 		memset(result, 0, digest_size);
463018ba95cSWang, Rui Y 
464018ba95cSWang, Rui Y 		ret = -EINVAL;
465018ba95cSWang, Rui Y 		hash_buff = xbuf[0];
466018ba95cSWang, Rui Y 		memcpy(hash_buff, template[i].plaintext,
467018ba95cSWang, Rui Y 			template[i].tap[0]);
468018ba95cSWang, Rui Y 		sg_init_one(&sg[0], hash_buff, template[i].tap[0]);
469018ba95cSWang, Rui Y 
470018ba95cSWang, Rui Y 		if (template[i].ksize) {
471018ba95cSWang, Rui Y 			crypto_ahash_clear_flags(tfm, ~0);
472018ba95cSWang, Rui Y 			if (template[i].ksize > MAX_KEYLEN) {
473018ba95cSWang, Rui Y 				pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n",
474018ba95cSWang, Rui Y 					j, algo, template[i].ksize, MAX_KEYLEN);
475018ba95cSWang, Rui Y 				ret = -EINVAL;
476018ba95cSWang, Rui Y 				goto out;
477018ba95cSWang, Rui Y 			}
478018ba95cSWang, Rui Y 			memcpy(key, template[i].key, template[i].ksize);
479018ba95cSWang, Rui Y 			ret = crypto_ahash_setkey(tfm, key, template[i].ksize);
480018ba95cSWang, Rui Y 			if (ret) {
481018ba95cSWang, Rui Y 				pr_err("alg: hash: setkey failed on test %d for %s: ret=%d\n",
482018ba95cSWang, Rui Y 					j, algo, -ret);
483018ba95cSWang, Rui Y 				goto out;
484018ba95cSWang, Rui Y 			}
485018ba95cSWang, Rui Y 		}
486018ba95cSWang, Rui Y 
487018ba95cSWang, Rui Y 		ahash_request_set_crypt(req, sg, result, template[i].tap[0]);
488018ba95cSWang, Rui Y 		ret = wait_async_op(&tresult, crypto_ahash_init(req));
489018ba95cSWang, Rui Y 		if (ret) {
490018ba95cSWang, Rui Y 			pr_err("alt: hash: init failed on test %d for %s: ret=%d\n",
491018ba95cSWang, Rui Y 				j, algo, -ret);
492018ba95cSWang, Rui Y 			goto out;
493018ba95cSWang, Rui Y 		}
494018ba95cSWang, Rui Y 		ret = wait_async_op(&tresult, crypto_ahash_update(req));
495018ba95cSWang, Rui Y 		if (ret) {
496018ba95cSWang, Rui Y 			pr_err("alt: hash: update failed on test %d for %s: ret=%d\n",
497018ba95cSWang, Rui Y 				j, algo, -ret);
498018ba95cSWang, Rui Y 			goto out;
499018ba95cSWang, Rui Y 		}
500018ba95cSWang, Rui Y 
501018ba95cSWang, Rui Y 		temp = template[i].tap[0];
502018ba95cSWang, Rui Y 		for (k = 1; k < template[i].np; k++) {
503018ba95cSWang, Rui Y 			ret = ahash_partial_update(&req, tfm, &template[i],
504018ba95cSWang, Rui Y 				hash_buff, k, temp, &sg[0], algo, result,
505018ba95cSWang, Rui Y 				&tresult);
506018ba95cSWang, Rui Y 			if (ret) {
507018ba95cSWang, Rui Y 				pr_err("hash: partial update failed on test %d for %s: ret=%d\n",
508018ba95cSWang, Rui Y 					j, algo, -ret);
509018ba95cSWang, Rui Y 				goto out_noreq;
510018ba95cSWang, Rui Y 			}
511018ba95cSWang, Rui Y 			temp += template[i].tap[k];
512018ba95cSWang, Rui Y 		}
513018ba95cSWang, Rui Y 		ret = wait_async_op(&tresult, crypto_ahash_final(req));
514018ba95cSWang, Rui Y 		if (ret) {
515018ba95cSWang, Rui Y 			pr_err("alt: hash: final failed on test %d for %s: ret=%d\n",
516018ba95cSWang, Rui Y 				j, algo, -ret);
517018ba95cSWang, Rui Y 			goto out;
518018ba95cSWang, Rui Y 		}
519018ba95cSWang, Rui Y 		if (memcmp(result, template[i].digest,
520018ba95cSWang, Rui Y 			   crypto_ahash_digestsize(tfm))) {
521018ba95cSWang, Rui Y 			pr_err("alg: hash: Partial Test %d failed for %s\n",
522018ba95cSWang, Rui Y 			       j, algo);
523018ba95cSWang, Rui Y 			hexdump(result, crypto_ahash_digestsize(tfm));
524018ba95cSWang, Rui Y 			ret = -EINVAL;
525018ba95cSWang, Rui Y 			goto out;
526018ba95cSWang, Rui Y 		}
527018ba95cSWang, Rui Y 	}
528018ba95cSWang, Rui Y 
529da7f033dSHerbert Xu 	ret = 0;
530da7f033dSHerbert Xu 
531da7f033dSHerbert Xu out:
532da7f033dSHerbert Xu 	ahash_request_free(req);
533da7f033dSHerbert Xu out_noreq:
534f8b0d4d0SHerbert Xu 	testmgr_free_buf(xbuf);
535f8b0d4d0SHerbert Xu out_nobuf:
53629b77e5dSHoria Geanta 	kfree(key);
53729b77e5dSHoria Geanta 	kfree(result);
538da7f033dSHerbert Xu 	return ret;
539da7f033dSHerbert Xu }
540da7f033dSHerbert Xu 
541da5ffe11SJussi Kivilinna static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
542da5ffe11SJussi Kivilinna 		     unsigned int tcount, bool use_digest)
543da5ffe11SJussi Kivilinna {
544da5ffe11SJussi Kivilinna 	unsigned int alignmask;
545da5ffe11SJussi Kivilinna 	int ret;
546da5ffe11SJussi Kivilinna 
547da5ffe11SJussi Kivilinna 	ret = __test_hash(tfm, template, tcount, use_digest, 0);
548da5ffe11SJussi Kivilinna 	if (ret)
549da5ffe11SJussi Kivilinna 		return ret;
550da5ffe11SJussi Kivilinna 
551da5ffe11SJussi Kivilinna 	/* test unaligned buffers, check with one byte offset */
552da5ffe11SJussi Kivilinna 	ret = __test_hash(tfm, template, tcount, use_digest, 1);
553da5ffe11SJussi Kivilinna 	if (ret)
554da5ffe11SJussi Kivilinna 		return ret;
555da5ffe11SJussi Kivilinna 
556da5ffe11SJussi Kivilinna 	alignmask = crypto_tfm_alg_alignmask(&tfm->base);
557da5ffe11SJussi Kivilinna 	if (alignmask) {
558da5ffe11SJussi Kivilinna 		/* Check if alignment mask for tfm is correctly set. */
559da5ffe11SJussi Kivilinna 		ret = __test_hash(tfm, template, tcount, use_digest,
560da5ffe11SJussi Kivilinna 				  alignmask + 1);
561da5ffe11SJussi Kivilinna 		if (ret)
562da5ffe11SJussi Kivilinna 			return ret;
563da5ffe11SJussi Kivilinna 	}
564da5ffe11SJussi Kivilinna 
565da5ffe11SJussi Kivilinna 	return 0;
566da5ffe11SJussi Kivilinna }
567da5ffe11SJussi Kivilinna 
568d8a32ac2SJussi Kivilinna static int __test_aead(struct crypto_aead *tfm, int enc,
569d8a32ac2SJussi Kivilinna 		       struct aead_testvec *template, unsigned int tcount,
57058dcf548SJussi Kivilinna 		       const bool diff_dst, const int align_offset)
571da7f033dSHerbert Xu {
572da7f033dSHerbert Xu 	const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm));
573da7f033dSHerbert Xu 	unsigned int i, j, k, n, temp;
574f8b0d4d0SHerbert Xu 	int ret = -ENOMEM;
575da7f033dSHerbert Xu 	char *q;
576da7f033dSHerbert Xu 	char *key;
577da7f033dSHerbert Xu 	struct aead_request *req;
578d8a32ac2SJussi Kivilinna 	struct scatterlist *sg;
579d8a32ac2SJussi Kivilinna 	struct scatterlist *sgout;
580d8a32ac2SJussi Kivilinna 	const char *e, *d;
581da7f033dSHerbert Xu 	struct tcrypt_result result;
582424a5da6SCristian Stoica 	unsigned int authsize, iv_len;
583da7f033dSHerbert Xu 	void *input;
584d8a32ac2SJussi Kivilinna 	void *output;
585da7f033dSHerbert Xu 	void *assoc;
5869bac019dSTadeusz Struk 	char *iv;
587f8b0d4d0SHerbert Xu 	char *xbuf[XBUFSIZE];
588d8a32ac2SJussi Kivilinna 	char *xoutbuf[XBUFSIZE];
589f8b0d4d0SHerbert Xu 	char *axbuf[XBUFSIZE];
590f8b0d4d0SHerbert Xu 
5919bac019dSTadeusz Struk 	iv = kzalloc(MAX_IVLEN, GFP_KERNEL);
5929bac019dSTadeusz Struk 	if (!iv)
5939bac019dSTadeusz Struk 		return ret;
59429b77e5dSHoria Geanta 	key = kmalloc(MAX_KEYLEN, GFP_KERNEL);
59529b77e5dSHoria Geanta 	if (!key)
59629b77e5dSHoria Geanta 		goto out_noxbuf;
597f8b0d4d0SHerbert Xu 	if (testmgr_alloc_buf(xbuf))
598f8b0d4d0SHerbert Xu 		goto out_noxbuf;
599f8b0d4d0SHerbert Xu 	if (testmgr_alloc_buf(axbuf))
600f8b0d4d0SHerbert Xu 		goto out_noaxbuf;
601d8a32ac2SJussi Kivilinna 	if (diff_dst && testmgr_alloc_buf(xoutbuf))
602d8a32ac2SJussi Kivilinna 		goto out_nooutbuf;
603d8a32ac2SJussi Kivilinna 
604d8a32ac2SJussi Kivilinna 	/* avoid "the frame size is larger than 1024 bytes" compiler warning */
6058a525fcdSHerbert Xu 	sg = kmalloc(sizeof(*sg) * 8 * (diff_dst ? 4 : 2), GFP_KERNEL);
606d8a32ac2SJussi Kivilinna 	if (!sg)
607d8a32ac2SJussi Kivilinna 		goto out_nosg;
6088a525fcdSHerbert Xu 	sgout = &sg[16];
609d8a32ac2SJussi Kivilinna 
610d8a32ac2SJussi Kivilinna 	if (diff_dst)
611d8a32ac2SJussi Kivilinna 		d = "-ddst";
612d8a32ac2SJussi Kivilinna 	else
613d8a32ac2SJussi Kivilinna 		d = "";
614d8a32ac2SJussi Kivilinna 
615da7f033dSHerbert Xu 	if (enc == ENCRYPT)
616da7f033dSHerbert Xu 		e = "encryption";
617da7f033dSHerbert Xu 	else
618da7f033dSHerbert Xu 		e = "decryption";
619da7f033dSHerbert Xu 
620da7f033dSHerbert Xu 	init_completion(&result.completion);
621da7f033dSHerbert Xu 
622da7f033dSHerbert Xu 	req = aead_request_alloc(tfm, GFP_KERNEL);
623da7f033dSHerbert Xu 	if (!req) {
624d8a32ac2SJussi Kivilinna 		pr_err("alg: aead%s: Failed to allocate request for %s\n",
625d8a32ac2SJussi Kivilinna 		       d, algo);
626da7f033dSHerbert Xu 		goto out;
627da7f033dSHerbert Xu 	}
628da7f033dSHerbert Xu 
629da7f033dSHerbert Xu 	aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
630da7f033dSHerbert Xu 				  tcrypt_complete, &result);
631da7f033dSHerbert Xu 
632abfa7f43SJerome Marchand 	iv_len = crypto_aead_ivsize(tfm);
633abfa7f43SJerome Marchand 
634da7f033dSHerbert Xu 	for (i = 0, j = 0; i < tcount; i++) {
63505b1d338SCristian Stoica 		if (template[i].np)
63605b1d338SCristian Stoica 			continue;
63705b1d338SCristian Stoica 
638da7f033dSHerbert Xu 		j++;
639da7f033dSHerbert Xu 
64058dcf548SJussi Kivilinna 		/* some templates have no input data but they will
641da7f033dSHerbert Xu 		 * touch input
642da7f033dSHerbert Xu 		 */
643da7f033dSHerbert Xu 		input = xbuf[0];
64458dcf548SJussi Kivilinna 		input += align_offset;
645da7f033dSHerbert Xu 		assoc = axbuf[0];
646da7f033dSHerbert Xu 
647fd57f22aSHerbert Xu 		ret = -EINVAL;
64858dcf548SJussi Kivilinna 		if (WARN_ON(align_offset + template[i].ilen >
64958dcf548SJussi Kivilinna 			    PAGE_SIZE || template[i].alen > PAGE_SIZE))
650fd57f22aSHerbert Xu 			goto out;
651fd57f22aSHerbert Xu 
652da7f033dSHerbert Xu 		memcpy(input, template[i].input, template[i].ilen);
653da7f033dSHerbert Xu 		memcpy(assoc, template[i].assoc, template[i].alen);
654da7f033dSHerbert Xu 		if (template[i].iv)
655424a5da6SCristian Stoica 			memcpy(iv, template[i].iv, iv_len);
656da7f033dSHerbert Xu 		else
657424a5da6SCristian Stoica 			memset(iv, 0, iv_len);
658da7f033dSHerbert Xu 
659da7f033dSHerbert Xu 		crypto_aead_clear_flags(tfm, ~0);
660da7f033dSHerbert Xu 		if (template[i].wk)
66105b1d338SCristian Stoica 			crypto_aead_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY);
662da7f033dSHerbert Xu 
66329b77e5dSHoria Geanta 		if (template[i].klen > MAX_KEYLEN) {
66429b77e5dSHoria Geanta 			pr_err("alg: aead%s: setkey failed on test %d for %s: key size %d > %d\n",
66529b77e5dSHoria Geanta 			       d, j, algo, template[i].klen,
66629b77e5dSHoria Geanta 			       MAX_KEYLEN);
66729b77e5dSHoria Geanta 			ret = -EINVAL;
66829b77e5dSHoria Geanta 			goto out;
66929b77e5dSHoria Geanta 		}
67029b77e5dSHoria Geanta 		memcpy(key, template[i].key, template[i].klen);
671da7f033dSHerbert Xu 
67205b1d338SCristian Stoica 		ret = crypto_aead_setkey(tfm, key, template[i].klen);
6730fae0c1eSYanjiang Jin 		if (template[i].fail == !ret) {
674d8a32ac2SJussi Kivilinna 			pr_err("alg: aead%s: setkey failed on test %d for %s: flags=%x\n",
675d8a32ac2SJussi Kivilinna 			       d, j, algo, crypto_aead_get_flags(tfm));
676da7f033dSHerbert Xu 			goto out;
677da7f033dSHerbert Xu 		} else if (ret)
678da7f033dSHerbert Xu 			continue;
679da7f033dSHerbert Xu 
680da7f033dSHerbert Xu 		authsize = abs(template[i].rlen - template[i].ilen);
681da7f033dSHerbert Xu 		ret = crypto_aead_setauthsize(tfm, authsize);
682da7f033dSHerbert Xu 		if (ret) {
683d8a32ac2SJussi Kivilinna 			pr_err("alg: aead%s: Failed to set authsize to %u on test %d for %s\n",
684d8a32ac2SJussi Kivilinna 			       d, authsize, j, algo);
685da7f033dSHerbert Xu 			goto out;
686da7f033dSHerbert Xu 		}
687da7f033dSHerbert Xu 
6888a525fcdSHerbert Xu 		k = !!template[i].alen;
6898a525fcdSHerbert Xu 		sg_init_table(sg, k + 1);
6908a525fcdSHerbert Xu 		sg_set_buf(&sg[0], assoc, template[i].alen);
6918a525fcdSHerbert Xu 		sg_set_buf(&sg[k], input,
69205b1d338SCristian Stoica 			   template[i].ilen + (enc ? authsize : 0));
693d8a32ac2SJussi Kivilinna 		output = input;
694d8a32ac2SJussi Kivilinna 
6958a525fcdSHerbert Xu 		if (diff_dst) {
6968a525fcdSHerbert Xu 			sg_init_table(sgout, k + 1);
6978a525fcdSHerbert Xu 			sg_set_buf(&sgout[0], assoc, template[i].alen);
6988a525fcdSHerbert Xu 
6998a525fcdSHerbert Xu 			output = xoutbuf[0];
7008a525fcdSHerbert Xu 			output += align_offset;
7018a525fcdSHerbert Xu 			sg_set_buf(&sgout[k], output,
7028a525fcdSHerbert Xu 				   template[i].rlen + (enc ? 0 : authsize));
7038a525fcdSHerbert Xu 		}
704da7f033dSHerbert Xu 
705d8a32ac2SJussi Kivilinna 		aead_request_set_crypt(req, sg, (diff_dst) ? sgout : sg,
706da7f033dSHerbert Xu 				       template[i].ilen, iv);
707da7f033dSHerbert Xu 
7088a525fcdSHerbert Xu 		aead_request_set_ad(req, template[i].alen);
709da7f033dSHerbert Xu 
71005b1d338SCristian Stoica 		ret = enc ? crypto_aead_encrypt(req) : crypto_aead_decrypt(req);
711da7f033dSHerbert Xu 
712da7f033dSHerbert Xu 		switch (ret) {
713da7f033dSHerbert Xu 		case 0:
714e44a1b44SJarod Wilson 			if (template[i].novrfy) {
715e44a1b44SJarod Wilson 				/* verification was supposed to fail */
716d8a32ac2SJussi Kivilinna 				pr_err("alg: aead%s: %s failed on test %d for %s: ret was 0, expected -EBADMSG\n",
717d8a32ac2SJussi Kivilinna 				       d, e, j, algo);
718e44a1b44SJarod Wilson 				/* so really, we got a bad message */
719e44a1b44SJarod Wilson 				ret = -EBADMSG;
720e44a1b44SJarod Wilson 				goto out;
721e44a1b44SJarod Wilson 			}
722da7f033dSHerbert Xu 			break;
723da7f033dSHerbert Xu 		case -EINPROGRESS:
724da7f033dSHerbert Xu 		case -EBUSY:
7258a45ac12SRabin Vincent 			wait_for_completion(&result.completion);
72616735d02SWolfram Sang 			reinit_completion(&result.completion);
7278a45ac12SRabin Vincent 			ret = result.err;
7288a45ac12SRabin Vincent 			if (!ret)
729da7f033dSHerbert Xu 				break;
730e44a1b44SJarod Wilson 		case -EBADMSG:
731e44a1b44SJarod Wilson 			if (template[i].novrfy)
732e44a1b44SJarod Wilson 				/* verification failure was expected */
733e44a1b44SJarod Wilson 				continue;
734da7f033dSHerbert Xu 			/* fall through */
735da7f033dSHerbert Xu 		default:
736d8a32ac2SJussi Kivilinna 			pr_err("alg: aead%s: %s failed on test %d for %s: ret=%d\n",
737d8a32ac2SJussi Kivilinna 			       d, e, j, algo, -ret);
738da7f033dSHerbert Xu 			goto out;
739da7f033dSHerbert Xu 		}
740da7f033dSHerbert Xu 
741d8a32ac2SJussi Kivilinna 		q = output;
742da7f033dSHerbert Xu 		if (memcmp(q, template[i].result, template[i].rlen)) {
743d8a32ac2SJussi Kivilinna 			pr_err("alg: aead%s: Test %d failed on %s for %s\n",
744d8a32ac2SJussi Kivilinna 			       d, j, e, algo);
745da7f033dSHerbert Xu 			hexdump(q, template[i].rlen);
746da7f033dSHerbert Xu 			ret = -EINVAL;
747da7f033dSHerbert Xu 			goto out;
748da7f033dSHerbert Xu 		}
749da7f033dSHerbert Xu 	}
750da7f033dSHerbert Xu 
751da7f033dSHerbert Xu 	for (i = 0, j = 0; i < tcount; i++) {
75258dcf548SJussi Kivilinna 		/* alignment tests are only done with continuous buffers */
75358dcf548SJussi Kivilinna 		if (align_offset != 0)
75458dcf548SJussi Kivilinna 			break;
75558dcf548SJussi Kivilinna 
75605b1d338SCristian Stoica 		if (!template[i].np)
75705b1d338SCristian Stoica 			continue;
75805b1d338SCristian Stoica 
759da7f033dSHerbert Xu 		j++;
760da7f033dSHerbert Xu 
761da7f033dSHerbert Xu 		if (template[i].iv)
762abfa7f43SJerome Marchand 			memcpy(iv, template[i].iv, iv_len);
763da7f033dSHerbert Xu 		else
764da7f033dSHerbert Xu 			memset(iv, 0, MAX_IVLEN);
765da7f033dSHerbert Xu 
766da7f033dSHerbert Xu 		crypto_aead_clear_flags(tfm, ~0);
767da7f033dSHerbert Xu 		if (template[i].wk)
76805b1d338SCristian Stoica 			crypto_aead_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY);
76929b77e5dSHoria Geanta 		if (template[i].klen > MAX_KEYLEN) {
77029b77e5dSHoria Geanta 			pr_err("alg: aead%s: setkey failed on test %d for %s: key size %d > %d\n",
77105b1d338SCristian Stoica 			       d, j, algo, template[i].klen, MAX_KEYLEN);
77229b77e5dSHoria Geanta 			ret = -EINVAL;
77329b77e5dSHoria Geanta 			goto out;
77429b77e5dSHoria Geanta 		}
77529b77e5dSHoria Geanta 		memcpy(key, template[i].key, template[i].klen);
776da7f033dSHerbert Xu 
777da7f033dSHerbert Xu 		ret = crypto_aead_setkey(tfm, key, template[i].klen);
7780fae0c1eSYanjiang Jin 		if (template[i].fail == !ret) {
779d8a32ac2SJussi Kivilinna 			pr_err("alg: aead%s: setkey failed on chunk test %d for %s: flags=%x\n",
780d8a32ac2SJussi Kivilinna 			       d, j, algo, crypto_aead_get_flags(tfm));
781da7f033dSHerbert Xu 			goto out;
782da7f033dSHerbert Xu 		} else if (ret)
783da7f033dSHerbert Xu 			continue;
784da7f033dSHerbert Xu 
785da7f033dSHerbert Xu 		authsize = abs(template[i].rlen - template[i].ilen);
786da7f033dSHerbert Xu 
787da7f033dSHerbert Xu 		ret = -EINVAL;
7888a525fcdSHerbert Xu 		sg_init_table(sg, template[i].anp + template[i].np);
789d8a32ac2SJussi Kivilinna 		if (diff_dst)
7908a525fcdSHerbert Xu 			sg_init_table(sgout, template[i].anp + template[i].np);
7918a525fcdSHerbert Xu 
7928a525fcdSHerbert Xu 		ret = -EINVAL;
7938a525fcdSHerbert Xu 		for (k = 0, temp = 0; k < template[i].anp; k++) {
7948a525fcdSHerbert Xu 			if (WARN_ON(offset_in_page(IDX[k]) +
7958a525fcdSHerbert Xu 				    template[i].atap[k] > PAGE_SIZE))
7968a525fcdSHerbert Xu 				goto out;
7978a525fcdSHerbert Xu 			sg_set_buf(&sg[k],
7988a525fcdSHerbert Xu 				   memcpy(axbuf[IDX[k] >> PAGE_SHIFT] +
7998a525fcdSHerbert Xu 					  offset_in_page(IDX[k]),
8008a525fcdSHerbert Xu 					  template[i].assoc + temp,
8018a525fcdSHerbert Xu 					  template[i].atap[k]),
8028a525fcdSHerbert Xu 				   template[i].atap[k]);
8038a525fcdSHerbert Xu 			if (diff_dst)
8048a525fcdSHerbert Xu 				sg_set_buf(&sgout[k],
8058a525fcdSHerbert Xu 					   axbuf[IDX[k] >> PAGE_SHIFT] +
8068a525fcdSHerbert Xu 					   offset_in_page(IDX[k]),
8078a525fcdSHerbert Xu 					   template[i].atap[k]);
8088a525fcdSHerbert Xu 			temp += template[i].atap[k];
8098a525fcdSHerbert Xu 		}
8108a525fcdSHerbert Xu 
811da7f033dSHerbert Xu 		for (k = 0, temp = 0; k < template[i].np; k++) {
812da7f033dSHerbert Xu 			if (WARN_ON(offset_in_page(IDX[k]) +
813da7f033dSHerbert Xu 				    template[i].tap[k] > PAGE_SIZE))
814da7f033dSHerbert Xu 				goto out;
815da7f033dSHerbert Xu 
81605b1d338SCristian Stoica 			q = xbuf[IDX[k] >> PAGE_SHIFT] + offset_in_page(IDX[k]);
81705b1d338SCristian Stoica 			memcpy(q, template[i].input + temp, template[i].tap[k]);
8188a525fcdSHerbert Xu 			sg_set_buf(&sg[template[i].anp + k],
8198a525fcdSHerbert Xu 				   q, template[i].tap[k]);
820d8a32ac2SJussi Kivilinna 
821d8a32ac2SJussi Kivilinna 			if (diff_dst) {
822d8a32ac2SJussi Kivilinna 				q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
823d8a32ac2SJussi Kivilinna 				    offset_in_page(IDX[k]);
824d8a32ac2SJussi Kivilinna 
825d8a32ac2SJussi Kivilinna 				memset(q, 0, template[i].tap[k]);
826d8a32ac2SJussi Kivilinna 
8278a525fcdSHerbert Xu 				sg_set_buf(&sgout[template[i].anp + k],
8288a525fcdSHerbert Xu 					   q, template[i].tap[k]);
829d8a32ac2SJussi Kivilinna 			}
830d8a32ac2SJussi Kivilinna 
8318ec25c51SHoria Geanta 			n = template[i].tap[k];
8328ec25c51SHoria Geanta 			if (k == template[i].np - 1 && enc)
8338ec25c51SHoria Geanta 				n += authsize;
8348ec25c51SHoria Geanta 			if (offset_in_page(q) + n < PAGE_SIZE)
8358ec25c51SHoria Geanta 				q[n] = 0;
8368ec25c51SHoria Geanta 
837da7f033dSHerbert Xu 			temp += template[i].tap[k];
838da7f033dSHerbert Xu 		}
839da7f033dSHerbert Xu 
840da7f033dSHerbert Xu 		ret = crypto_aead_setauthsize(tfm, authsize);
841da7f033dSHerbert Xu 		if (ret) {
842d8a32ac2SJussi Kivilinna 			pr_err("alg: aead%s: Failed to set authsize to %u on chunk test %d for %s\n",
843d8a32ac2SJussi Kivilinna 			       d, authsize, j, algo);
844da7f033dSHerbert Xu 			goto out;
845da7f033dSHerbert Xu 		}
846da7f033dSHerbert Xu 
847da7f033dSHerbert Xu 		if (enc) {
8488a525fcdSHerbert Xu 			if (WARN_ON(sg[template[i].anp + k - 1].offset +
8498a525fcdSHerbert Xu 				    sg[template[i].anp + k - 1].length +
8508a525fcdSHerbert Xu 				    authsize > PAGE_SIZE)) {
851da7f033dSHerbert Xu 				ret = -EINVAL;
852da7f033dSHerbert Xu 				goto out;
853da7f033dSHerbert Xu 			}
854da7f033dSHerbert Xu 
855d8a32ac2SJussi Kivilinna 			if (diff_dst)
8568a525fcdSHerbert Xu 				sgout[template[i].anp + k - 1].length +=
8578a525fcdSHerbert Xu 					authsize;
8588a525fcdSHerbert Xu 			sg[template[i].anp + k - 1].length += authsize;
859da7f033dSHerbert Xu 		}
860da7f033dSHerbert Xu 
861d8a32ac2SJussi Kivilinna 		aead_request_set_crypt(req, sg, (diff_dst) ? sgout : sg,
862da7f033dSHerbert Xu 				       template[i].ilen,
863da7f033dSHerbert Xu 				       iv);
864da7f033dSHerbert Xu 
8658a525fcdSHerbert Xu 		aead_request_set_ad(req, template[i].alen);
866da7f033dSHerbert Xu 
86705b1d338SCristian Stoica 		ret = enc ? crypto_aead_encrypt(req) : crypto_aead_decrypt(req);
868da7f033dSHerbert Xu 
869da7f033dSHerbert Xu 		switch (ret) {
870da7f033dSHerbert Xu 		case 0:
871e44a1b44SJarod Wilson 			if (template[i].novrfy) {
872e44a1b44SJarod Wilson 				/* verification was supposed to fail */
873d8a32ac2SJussi Kivilinna 				pr_err("alg: aead%s: %s failed on chunk test %d for %s: ret was 0, expected -EBADMSG\n",
874d8a32ac2SJussi Kivilinna 				       d, e, j, algo);
875e44a1b44SJarod Wilson 				/* so really, we got a bad message */
876e44a1b44SJarod Wilson 				ret = -EBADMSG;
877e44a1b44SJarod Wilson 				goto out;
878e44a1b44SJarod Wilson 			}
879da7f033dSHerbert Xu 			break;
880da7f033dSHerbert Xu 		case -EINPROGRESS:
881da7f033dSHerbert Xu 		case -EBUSY:
8828a45ac12SRabin Vincent 			wait_for_completion(&result.completion);
88316735d02SWolfram Sang 			reinit_completion(&result.completion);
8848a45ac12SRabin Vincent 			ret = result.err;
8858a45ac12SRabin Vincent 			if (!ret)
886da7f033dSHerbert Xu 				break;
887e44a1b44SJarod Wilson 		case -EBADMSG:
888e44a1b44SJarod Wilson 			if (template[i].novrfy)
889e44a1b44SJarod Wilson 				/* verification failure was expected */
890e44a1b44SJarod Wilson 				continue;
891da7f033dSHerbert Xu 			/* fall through */
892da7f033dSHerbert Xu 		default:
893d8a32ac2SJussi Kivilinna 			pr_err("alg: aead%s: %s failed on chunk test %d for %s: ret=%d\n",
894d8a32ac2SJussi Kivilinna 			       d, e, j, algo, -ret);
895da7f033dSHerbert Xu 			goto out;
896da7f033dSHerbert Xu 		}
897da7f033dSHerbert Xu 
898da7f033dSHerbert Xu 		ret = -EINVAL;
899da7f033dSHerbert Xu 		for (k = 0, temp = 0; k < template[i].np; k++) {
900d8a32ac2SJussi Kivilinna 			if (diff_dst)
901d8a32ac2SJussi Kivilinna 				q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
902d8a32ac2SJussi Kivilinna 				    offset_in_page(IDX[k]);
903d8a32ac2SJussi Kivilinna 			else
904da7f033dSHerbert Xu 				q = xbuf[IDX[k] >> PAGE_SHIFT] +
905da7f033dSHerbert Xu 				    offset_in_page(IDX[k]);
906da7f033dSHerbert Xu 
907da7f033dSHerbert Xu 			n = template[i].tap[k];
908da7f033dSHerbert Xu 			if (k == template[i].np - 1)
909da7f033dSHerbert Xu 				n += enc ? authsize : -authsize;
910da7f033dSHerbert Xu 
911da7f033dSHerbert Xu 			if (memcmp(q, template[i].result + temp, n)) {
912d8a32ac2SJussi Kivilinna 				pr_err("alg: aead%s: Chunk test %d failed on %s at page %u for %s\n",
913d8a32ac2SJussi Kivilinna 				       d, j, e, k, algo);
914da7f033dSHerbert Xu 				hexdump(q, n);
915da7f033dSHerbert Xu 				goto out;
916da7f033dSHerbert Xu 			}
917da7f033dSHerbert Xu 
918da7f033dSHerbert Xu 			q += n;
919da7f033dSHerbert Xu 			if (k == template[i].np - 1 && !enc) {
920d8a32ac2SJussi Kivilinna 				if (!diff_dst &&
921d8a32ac2SJussi Kivilinna 					memcmp(q, template[i].input +
922da7f033dSHerbert Xu 					      temp + n, authsize))
923da7f033dSHerbert Xu 					n = authsize;
924da7f033dSHerbert Xu 				else
925da7f033dSHerbert Xu 					n = 0;
926da7f033dSHerbert Xu 			} else {
92705b1d338SCristian Stoica 				for (n = 0; offset_in_page(q + n) && q[n]; n++)
928da7f033dSHerbert Xu 					;
929da7f033dSHerbert Xu 			}
930da7f033dSHerbert Xu 			if (n) {
931d8a32ac2SJussi Kivilinna 				pr_err("alg: aead%s: Result buffer corruption in chunk test %d on %s at page %u for %s: %u bytes:\n",
932d8a32ac2SJussi Kivilinna 				       d, j, e, k, algo, n);
933da7f033dSHerbert Xu 				hexdump(q, n);
934da7f033dSHerbert Xu 				goto out;
935da7f033dSHerbert Xu 			}
936da7f033dSHerbert Xu 
937da7f033dSHerbert Xu 			temp += template[i].tap[k];
938da7f033dSHerbert Xu 		}
939da7f033dSHerbert Xu 	}
940da7f033dSHerbert Xu 
941da7f033dSHerbert Xu 	ret = 0;
942da7f033dSHerbert Xu 
943da7f033dSHerbert Xu out:
944da7f033dSHerbert Xu 	aead_request_free(req);
945d8a32ac2SJussi Kivilinna 	kfree(sg);
946d8a32ac2SJussi Kivilinna out_nosg:
947d8a32ac2SJussi Kivilinna 	if (diff_dst)
948d8a32ac2SJussi Kivilinna 		testmgr_free_buf(xoutbuf);
949d8a32ac2SJussi Kivilinna out_nooutbuf:
950f8b0d4d0SHerbert Xu 	testmgr_free_buf(axbuf);
951f8b0d4d0SHerbert Xu out_noaxbuf:
952f8b0d4d0SHerbert Xu 	testmgr_free_buf(xbuf);
953f8b0d4d0SHerbert Xu out_noxbuf:
95429b77e5dSHoria Geanta 	kfree(key);
9559bac019dSTadeusz Struk 	kfree(iv);
956da7f033dSHerbert Xu 	return ret;
957da7f033dSHerbert Xu }
958da7f033dSHerbert Xu 
959d8a32ac2SJussi Kivilinna static int test_aead(struct crypto_aead *tfm, int enc,
960d8a32ac2SJussi Kivilinna 		     struct aead_testvec *template, unsigned int tcount)
961d8a32ac2SJussi Kivilinna {
96258dcf548SJussi Kivilinna 	unsigned int alignmask;
963d8a32ac2SJussi Kivilinna 	int ret;
964d8a32ac2SJussi Kivilinna 
965d8a32ac2SJussi Kivilinna 	/* test 'dst == src' case */
96658dcf548SJussi Kivilinna 	ret = __test_aead(tfm, enc, template, tcount, false, 0);
967d8a32ac2SJussi Kivilinna 	if (ret)
968d8a32ac2SJussi Kivilinna 		return ret;
969d8a32ac2SJussi Kivilinna 
970d8a32ac2SJussi Kivilinna 	/* test 'dst != src' case */
97158dcf548SJussi Kivilinna 	ret = __test_aead(tfm, enc, template, tcount, true, 0);
97258dcf548SJussi Kivilinna 	if (ret)
97358dcf548SJussi Kivilinna 		return ret;
97458dcf548SJussi Kivilinna 
97558dcf548SJussi Kivilinna 	/* test unaligned buffers, check with one byte offset */
97658dcf548SJussi Kivilinna 	ret = __test_aead(tfm, enc, template, tcount, true, 1);
97758dcf548SJussi Kivilinna 	if (ret)
97858dcf548SJussi Kivilinna 		return ret;
97958dcf548SJussi Kivilinna 
98058dcf548SJussi Kivilinna 	alignmask = crypto_tfm_alg_alignmask(&tfm->base);
98158dcf548SJussi Kivilinna 	if (alignmask) {
98258dcf548SJussi Kivilinna 		/* Check if alignment mask for tfm is correctly set. */
98358dcf548SJussi Kivilinna 		ret = __test_aead(tfm, enc, template, tcount, true,
98458dcf548SJussi Kivilinna 				  alignmask + 1);
98558dcf548SJussi Kivilinna 		if (ret)
98658dcf548SJussi Kivilinna 			return ret;
98758dcf548SJussi Kivilinna 	}
98858dcf548SJussi Kivilinna 
98958dcf548SJussi Kivilinna 	return 0;
990d8a32ac2SJussi Kivilinna }
991d8a32ac2SJussi Kivilinna 
9921aa4ecd9SHerbert Xu static int test_cipher(struct crypto_cipher *tfm, int enc,
9931aa4ecd9SHerbert Xu 		       struct cipher_testvec *template, unsigned int tcount)
9941aa4ecd9SHerbert Xu {
9951aa4ecd9SHerbert Xu 	const char *algo = crypto_tfm_alg_driver_name(crypto_cipher_tfm(tfm));
9961aa4ecd9SHerbert Xu 	unsigned int i, j, k;
9971aa4ecd9SHerbert Xu 	char *q;
9981aa4ecd9SHerbert Xu 	const char *e;
9991aa4ecd9SHerbert Xu 	void *data;
1000f8b0d4d0SHerbert Xu 	char *xbuf[XBUFSIZE];
1001f8b0d4d0SHerbert Xu 	int ret = -ENOMEM;
1002f8b0d4d0SHerbert Xu 
1003f8b0d4d0SHerbert Xu 	if (testmgr_alloc_buf(xbuf))
1004f8b0d4d0SHerbert Xu 		goto out_nobuf;
10051aa4ecd9SHerbert Xu 
10061aa4ecd9SHerbert Xu 	if (enc == ENCRYPT)
10071aa4ecd9SHerbert Xu 	        e = "encryption";
10081aa4ecd9SHerbert Xu 	else
10091aa4ecd9SHerbert Xu 		e = "decryption";
10101aa4ecd9SHerbert Xu 
10111aa4ecd9SHerbert Xu 	j = 0;
10121aa4ecd9SHerbert Xu 	for (i = 0; i < tcount; i++) {
10131aa4ecd9SHerbert Xu 		if (template[i].np)
10141aa4ecd9SHerbert Xu 			continue;
10151aa4ecd9SHerbert Xu 
101610faa8c0SStephan Mueller 		if (fips_enabled && template[i].fips_skip)
101710faa8c0SStephan Mueller 			continue;
101810faa8c0SStephan Mueller 
10191aa4ecd9SHerbert Xu 		j++;
10201aa4ecd9SHerbert Xu 
1021fd57f22aSHerbert Xu 		ret = -EINVAL;
1022fd57f22aSHerbert Xu 		if (WARN_ON(template[i].ilen > PAGE_SIZE))
1023fd57f22aSHerbert Xu 			goto out;
1024fd57f22aSHerbert Xu 
10251aa4ecd9SHerbert Xu 		data = xbuf[0];
10261aa4ecd9SHerbert Xu 		memcpy(data, template[i].input, template[i].ilen);
10271aa4ecd9SHerbert Xu 
10281aa4ecd9SHerbert Xu 		crypto_cipher_clear_flags(tfm, ~0);
10291aa4ecd9SHerbert Xu 		if (template[i].wk)
10301aa4ecd9SHerbert Xu 			crypto_cipher_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY);
10311aa4ecd9SHerbert Xu 
10321aa4ecd9SHerbert Xu 		ret = crypto_cipher_setkey(tfm, template[i].key,
10331aa4ecd9SHerbert Xu 					   template[i].klen);
10340fae0c1eSYanjiang Jin 		if (template[i].fail == !ret) {
10351aa4ecd9SHerbert Xu 			printk(KERN_ERR "alg: cipher: setkey failed "
10361aa4ecd9SHerbert Xu 			       "on test %d for %s: flags=%x\n", j,
10371aa4ecd9SHerbert Xu 			       algo, crypto_cipher_get_flags(tfm));
10381aa4ecd9SHerbert Xu 			goto out;
10391aa4ecd9SHerbert Xu 		} else if (ret)
10401aa4ecd9SHerbert Xu 			continue;
10411aa4ecd9SHerbert Xu 
10421aa4ecd9SHerbert Xu 		for (k = 0; k < template[i].ilen;
10431aa4ecd9SHerbert Xu 		     k += crypto_cipher_blocksize(tfm)) {
10441aa4ecd9SHerbert Xu 			if (enc)
10451aa4ecd9SHerbert Xu 				crypto_cipher_encrypt_one(tfm, data + k,
10461aa4ecd9SHerbert Xu 							  data + k);
10471aa4ecd9SHerbert Xu 			else
10481aa4ecd9SHerbert Xu 				crypto_cipher_decrypt_one(tfm, data + k,
10491aa4ecd9SHerbert Xu 							  data + k);
10501aa4ecd9SHerbert Xu 		}
10511aa4ecd9SHerbert Xu 
10521aa4ecd9SHerbert Xu 		q = data;
10531aa4ecd9SHerbert Xu 		if (memcmp(q, template[i].result, template[i].rlen)) {
10541aa4ecd9SHerbert Xu 			printk(KERN_ERR "alg: cipher: Test %d failed "
10551aa4ecd9SHerbert Xu 			       "on %s for %s\n", j, e, algo);
10561aa4ecd9SHerbert Xu 			hexdump(q, template[i].rlen);
10571aa4ecd9SHerbert Xu 			ret = -EINVAL;
10581aa4ecd9SHerbert Xu 			goto out;
10591aa4ecd9SHerbert Xu 		}
10601aa4ecd9SHerbert Xu 	}
10611aa4ecd9SHerbert Xu 
10621aa4ecd9SHerbert Xu 	ret = 0;
10631aa4ecd9SHerbert Xu 
10641aa4ecd9SHerbert Xu out:
1065f8b0d4d0SHerbert Xu 	testmgr_free_buf(xbuf);
1066f8b0d4d0SHerbert Xu out_nobuf:
10671aa4ecd9SHerbert Xu 	return ret;
10681aa4ecd9SHerbert Xu }
10691aa4ecd9SHerbert Xu 
107012773d93SHerbert Xu static int __test_skcipher(struct crypto_skcipher *tfm, int enc,
107108d6af8cSJussi Kivilinna 			   struct cipher_testvec *template, unsigned int tcount,
10723a338f20SJussi Kivilinna 			   const bool diff_dst, const int align_offset)
1073da7f033dSHerbert Xu {
1074da7f033dSHerbert Xu 	const char *algo =
107512773d93SHerbert Xu 		crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm));
1076da7f033dSHerbert Xu 	unsigned int i, j, k, n, temp;
1077da7f033dSHerbert Xu 	char *q;
107812773d93SHerbert Xu 	struct skcipher_request *req;
1079da7f033dSHerbert Xu 	struct scatterlist sg[8];
108008d6af8cSJussi Kivilinna 	struct scatterlist sgout[8];
108108d6af8cSJussi Kivilinna 	const char *e, *d;
1082da7f033dSHerbert Xu 	struct tcrypt_result result;
1083da7f033dSHerbert Xu 	void *data;
1084da7f033dSHerbert Xu 	char iv[MAX_IVLEN];
1085f8b0d4d0SHerbert Xu 	char *xbuf[XBUFSIZE];
108608d6af8cSJussi Kivilinna 	char *xoutbuf[XBUFSIZE];
1087f8b0d4d0SHerbert Xu 	int ret = -ENOMEM;
108884cba178SAndrey Ryabinin 	unsigned int ivsize = crypto_skcipher_ivsize(tfm);
1089f8b0d4d0SHerbert Xu 
1090f8b0d4d0SHerbert Xu 	if (testmgr_alloc_buf(xbuf))
1091f8b0d4d0SHerbert Xu 		goto out_nobuf;
1092da7f033dSHerbert Xu 
109308d6af8cSJussi Kivilinna 	if (diff_dst && testmgr_alloc_buf(xoutbuf))
109408d6af8cSJussi Kivilinna 		goto out_nooutbuf;
109508d6af8cSJussi Kivilinna 
109608d6af8cSJussi Kivilinna 	if (diff_dst)
109708d6af8cSJussi Kivilinna 		d = "-ddst";
109808d6af8cSJussi Kivilinna 	else
109908d6af8cSJussi Kivilinna 		d = "";
110008d6af8cSJussi Kivilinna 
1101da7f033dSHerbert Xu 	if (enc == ENCRYPT)
1102da7f033dSHerbert Xu 	        e = "encryption";
1103da7f033dSHerbert Xu 	else
1104da7f033dSHerbert Xu 		e = "decryption";
1105da7f033dSHerbert Xu 
1106da7f033dSHerbert Xu 	init_completion(&result.completion);
1107da7f033dSHerbert Xu 
110812773d93SHerbert Xu 	req = skcipher_request_alloc(tfm, GFP_KERNEL);
1109da7f033dSHerbert Xu 	if (!req) {
111008d6af8cSJussi Kivilinna 		pr_err("alg: skcipher%s: Failed to allocate request for %s\n",
111108d6af8cSJussi Kivilinna 		       d, algo);
1112da7f033dSHerbert Xu 		goto out;
1113da7f033dSHerbert Xu 	}
1114da7f033dSHerbert Xu 
111512773d93SHerbert Xu 	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
1116da7f033dSHerbert Xu 				      tcrypt_complete, &result);
1117da7f033dSHerbert Xu 
1118da7f033dSHerbert Xu 	j = 0;
1119da7f033dSHerbert Xu 	for (i = 0; i < tcount; i++) {
1120bbb9a7ddSCristian Stoica 		if (template[i].np && !template[i].also_non_np)
1121bbb9a7ddSCristian Stoica 			continue;
1122bbb9a7ddSCristian Stoica 
112310faa8c0SStephan Mueller 		if (fips_enabled && template[i].fips_skip)
112410faa8c0SStephan Mueller 			continue;
112510faa8c0SStephan Mueller 
1126da7f033dSHerbert Xu 		if (template[i].iv)
112784cba178SAndrey Ryabinin 			memcpy(iv, template[i].iv, ivsize);
1128da7f033dSHerbert Xu 		else
1129da7f033dSHerbert Xu 			memset(iv, 0, MAX_IVLEN);
1130da7f033dSHerbert Xu 
1131da7f033dSHerbert Xu 		j++;
1132fd57f22aSHerbert Xu 		ret = -EINVAL;
1133a1aa44a2SCristian Stoica 		if (WARN_ON(align_offset + template[i].ilen > PAGE_SIZE))
1134fd57f22aSHerbert Xu 			goto out;
1135fd57f22aSHerbert Xu 
1136da7f033dSHerbert Xu 		data = xbuf[0];
11373a338f20SJussi Kivilinna 		data += align_offset;
1138da7f033dSHerbert Xu 		memcpy(data, template[i].input, template[i].ilen);
1139da7f033dSHerbert Xu 
114012773d93SHerbert Xu 		crypto_skcipher_clear_flags(tfm, ~0);
1141da7f033dSHerbert Xu 		if (template[i].wk)
114212773d93SHerbert Xu 			crypto_skcipher_set_flags(tfm,
114312773d93SHerbert Xu 						  CRYPTO_TFM_REQ_WEAK_KEY);
1144da7f033dSHerbert Xu 
114512773d93SHerbert Xu 		ret = crypto_skcipher_setkey(tfm, template[i].key,
1146da7f033dSHerbert Xu 					     template[i].klen);
11470fae0c1eSYanjiang Jin 		if (template[i].fail == !ret) {
114808d6af8cSJussi Kivilinna 			pr_err("alg: skcipher%s: setkey failed on test %d for %s: flags=%x\n",
114912773d93SHerbert Xu 			       d, j, algo, crypto_skcipher_get_flags(tfm));
1150da7f033dSHerbert Xu 			goto out;
1151da7f033dSHerbert Xu 		} else if (ret)
1152da7f033dSHerbert Xu 			continue;
1153da7f033dSHerbert Xu 
1154da7f033dSHerbert Xu 		sg_init_one(&sg[0], data, template[i].ilen);
115508d6af8cSJussi Kivilinna 		if (diff_dst) {
115608d6af8cSJussi Kivilinna 			data = xoutbuf[0];
11573a338f20SJussi Kivilinna 			data += align_offset;
115808d6af8cSJussi Kivilinna 			sg_init_one(&sgout[0], data, template[i].ilen);
115908d6af8cSJussi Kivilinna 		}
1160da7f033dSHerbert Xu 
116112773d93SHerbert Xu 		skcipher_request_set_crypt(req, sg, (diff_dst) ? sgout : sg,
1162da7f033dSHerbert Xu 					   template[i].ilen, iv);
116312773d93SHerbert Xu 		ret = enc ? crypto_skcipher_encrypt(req) :
116412773d93SHerbert Xu 			    crypto_skcipher_decrypt(req);
1165da7f033dSHerbert Xu 
1166da7f033dSHerbert Xu 		switch (ret) {
1167da7f033dSHerbert Xu 		case 0:
1168da7f033dSHerbert Xu 			break;
1169da7f033dSHerbert Xu 		case -EINPROGRESS:
1170da7f033dSHerbert Xu 		case -EBUSY:
11718a45ac12SRabin Vincent 			wait_for_completion(&result.completion);
117216735d02SWolfram Sang 			reinit_completion(&result.completion);
11738a45ac12SRabin Vincent 			ret = result.err;
11748a45ac12SRabin Vincent 			if (!ret)
1175da7f033dSHerbert Xu 				break;
1176da7f033dSHerbert Xu 			/* fall through */
1177da7f033dSHerbert Xu 		default:
117808d6af8cSJussi Kivilinna 			pr_err("alg: skcipher%s: %s failed on test %d for %s: ret=%d\n",
117908d6af8cSJussi Kivilinna 			       d, e, j, algo, -ret);
1180da7f033dSHerbert Xu 			goto out;
1181da7f033dSHerbert Xu 		}
1182da7f033dSHerbert Xu 
1183da7f033dSHerbert Xu 		q = data;
1184da7f033dSHerbert Xu 		if (memcmp(q, template[i].result, template[i].rlen)) {
11858a826a34SBoris BREZILLON 			pr_err("alg: skcipher%s: Test %d failed (invalid result) on %s for %s\n",
118608d6af8cSJussi Kivilinna 			       d, j, e, algo);
1187da7f033dSHerbert Xu 			hexdump(q, template[i].rlen);
1188da7f033dSHerbert Xu 			ret = -EINVAL;
1189da7f033dSHerbert Xu 			goto out;
1190da7f033dSHerbert Xu 		}
11918a826a34SBoris BREZILLON 
11928a826a34SBoris BREZILLON 		if (template[i].iv_out &&
11938a826a34SBoris BREZILLON 		    memcmp(iv, template[i].iv_out,
11948a826a34SBoris BREZILLON 			   crypto_skcipher_ivsize(tfm))) {
11958a826a34SBoris BREZILLON 			pr_err("alg: skcipher%s: Test %d failed (invalid output IV) on %s for %s\n",
11968a826a34SBoris BREZILLON 			       d, j, e, algo);
11978a826a34SBoris BREZILLON 			hexdump(iv, crypto_skcipher_ivsize(tfm));
11988a826a34SBoris BREZILLON 			ret = -EINVAL;
11998a826a34SBoris BREZILLON 			goto out;
12008a826a34SBoris BREZILLON 		}
1201da7f033dSHerbert Xu 	}
1202da7f033dSHerbert Xu 
1203da7f033dSHerbert Xu 	j = 0;
1204da7f033dSHerbert Xu 	for (i = 0; i < tcount; i++) {
12053a338f20SJussi Kivilinna 		/* alignment tests are only done with continuous buffers */
12063a338f20SJussi Kivilinna 		if (align_offset != 0)
12073a338f20SJussi Kivilinna 			break;
1208da7f033dSHerbert Xu 
1209bbb9a7ddSCristian Stoica 		if (!template[i].np)
1210bbb9a7ddSCristian Stoica 			continue;
1211bbb9a7ddSCristian Stoica 
121210faa8c0SStephan Mueller 		if (fips_enabled && template[i].fips_skip)
121310faa8c0SStephan Mueller 			continue;
121410faa8c0SStephan Mueller 
1215da7f033dSHerbert Xu 		if (template[i].iv)
121684cba178SAndrey Ryabinin 			memcpy(iv, template[i].iv, ivsize);
1217da7f033dSHerbert Xu 		else
1218da7f033dSHerbert Xu 			memset(iv, 0, MAX_IVLEN);
1219da7f033dSHerbert Xu 
1220da7f033dSHerbert Xu 		j++;
122112773d93SHerbert Xu 		crypto_skcipher_clear_flags(tfm, ~0);
1222da7f033dSHerbert Xu 		if (template[i].wk)
122312773d93SHerbert Xu 			crypto_skcipher_set_flags(tfm,
122412773d93SHerbert Xu 						  CRYPTO_TFM_REQ_WEAK_KEY);
1225da7f033dSHerbert Xu 
122612773d93SHerbert Xu 		ret = crypto_skcipher_setkey(tfm, template[i].key,
1227da7f033dSHerbert Xu 					     template[i].klen);
12280fae0c1eSYanjiang Jin 		if (template[i].fail == !ret) {
122908d6af8cSJussi Kivilinna 			pr_err("alg: skcipher%s: setkey failed on chunk test %d for %s: flags=%x\n",
123012773d93SHerbert Xu 			       d, j, algo, crypto_skcipher_get_flags(tfm));
1231da7f033dSHerbert Xu 			goto out;
1232da7f033dSHerbert Xu 		} else if (ret)
1233da7f033dSHerbert Xu 			continue;
1234da7f033dSHerbert Xu 
1235da7f033dSHerbert Xu 		temp = 0;
1236da7f033dSHerbert Xu 		ret = -EINVAL;
1237da7f033dSHerbert Xu 		sg_init_table(sg, template[i].np);
123808d6af8cSJussi Kivilinna 		if (diff_dst)
123908d6af8cSJussi Kivilinna 			sg_init_table(sgout, template[i].np);
1240da7f033dSHerbert Xu 		for (k = 0; k < template[i].np; k++) {
1241da7f033dSHerbert Xu 			if (WARN_ON(offset_in_page(IDX[k]) +
1242da7f033dSHerbert Xu 				    template[i].tap[k] > PAGE_SIZE))
1243da7f033dSHerbert Xu 				goto out;
1244da7f033dSHerbert Xu 
1245a1aa44a2SCristian Stoica 			q = xbuf[IDX[k] >> PAGE_SHIFT] + offset_in_page(IDX[k]);
1246da7f033dSHerbert Xu 
1247a1aa44a2SCristian Stoica 			memcpy(q, template[i].input + temp, template[i].tap[k]);
1248da7f033dSHerbert Xu 
1249a1aa44a2SCristian Stoica 			if (offset_in_page(q) + template[i].tap[k] < PAGE_SIZE)
1250da7f033dSHerbert Xu 				q[template[i].tap[k]] = 0;
1251da7f033dSHerbert Xu 
1252da7f033dSHerbert Xu 			sg_set_buf(&sg[k], q, template[i].tap[k]);
125308d6af8cSJussi Kivilinna 			if (diff_dst) {
125408d6af8cSJussi Kivilinna 				q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
125508d6af8cSJussi Kivilinna 				    offset_in_page(IDX[k]);
125608d6af8cSJussi Kivilinna 
1257a1aa44a2SCristian Stoica 				sg_set_buf(&sgout[k], q, template[i].tap[k]);
125808d6af8cSJussi Kivilinna 
125908d6af8cSJussi Kivilinna 				memset(q, 0, template[i].tap[k]);
126008d6af8cSJussi Kivilinna 				if (offset_in_page(q) +
126108d6af8cSJussi Kivilinna 				    template[i].tap[k] < PAGE_SIZE)
126208d6af8cSJussi Kivilinna 					q[template[i].tap[k]] = 0;
126308d6af8cSJussi Kivilinna 			}
1264da7f033dSHerbert Xu 
1265da7f033dSHerbert Xu 			temp += template[i].tap[k];
1266da7f033dSHerbert Xu 		}
1267da7f033dSHerbert Xu 
126812773d93SHerbert Xu 		skcipher_request_set_crypt(req, sg, (diff_dst) ? sgout : sg,
1269da7f033dSHerbert Xu 					   template[i].ilen, iv);
1270da7f033dSHerbert Xu 
127112773d93SHerbert Xu 		ret = enc ? crypto_skcipher_encrypt(req) :
127212773d93SHerbert Xu 			    crypto_skcipher_decrypt(req);
1273da7f033dSHerbert Xu 
1274da7f033dSHerbert Xu 		switch (ret) {
1275da7f033dSHerbert Xu 		case 0:
1276da7f033dSHerbert Xu 			break;
1277da7f033dSHerbert Xu 		case -EINPROGRESS:
1278da7f033dSHerbert Xu 		case -EBUSY:
12798a45ac12SRabin Vincent 			wait_for_completion(&result.completion);
128016735d02SWolfram Sang 			reinit_completion(&result.completion);
12818a45ac12SRabin Vincent 			ret = result.err;
12828a45ac12SRabin Vincent 			if (!ret)
1283da7f033dSHerbert Xu 				break;
1284da7f033dSHerbert Xu 			/* fall through */
1285da7f033dSHerbert Xu 		default:
128608d6af8cSJussi Kivilinna 			pr_err("alg: skcipher%s: %s failed on chunk test %d for %s: ret=%d\n",
128708d6af8cSJussi Kivilinna 			       d, e, j, algo, -ret);
1288da7f033dSHerbert Xu 			goto out;
1289da7f033dSHerbert Xu 		}
1290da7f033dSHerbert Xu 
1291da7f033dSHerbert Xu 		temp = 0;
1292da7f033dSHerbert Xu 		ret = -EINVAL;
1293da7f033dSHerbert Xu 		for (k = 0; k < template[i].np; k++) {
129408d6af8cSJussi Kivilinna 			if (diff_dst)
129508d6af8cSJussi Kivilinna 				q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
129608d6af8cSJussi Kivilinna 				    offset_in_page(IDX[k]);
129708d6af8cSJussi Kivilinna 			else
1298da7f033dSHerbert Xu 				q = xbuf[IDX[k] >> PAGE_SHIFT] +
1299da7f033dSHerbert Xu 				    offset_in_page(IDX[k]);
1300da7f033dSHerbert Xu 
1301da7f033dSHerbert Xu 			if (memcmp(q, template[i].result + temp,
1302da7f033dSHerbert Xu 				   template[i].tap[k])) {
130308d6af8cSJussi Kivilinna 				pr_err("alg: skcipher%s: Chunk test %d failed on %s at page %u for %s\n",
130408d6af8cSJussi Kivilinna 				       d, j, e, k, algo);
1305da7f033dSHerbert Xu 				hexdump(q, template[i].tap[k]);
1306da7f033dSHerbert Xu 				goto out;
1307da7f033dSHerbert Xu 			}
1308da7f033dSHerbert Xu 
1309da7f033dSHerbert Xu 			q += template[i].tap[k];
1310da7f033dSHerbert Xu 			for (n = 0; offset_in_page(q + n) && q[n]; n++)
1311da7f033dSHerbert Xu 				;
1312da7f033dSHerbert Xu 			if (n) {
131308d6af8cSJussi Kivilinna 				pr_err("alg: skcipher%s: Result buffer corruption in chunk test %d on %s at page %u for %s: %u bytes:\n",
131408d6af8cSJussi Kivilinna 				       d, j, e, k, algo, n);
1315da7f033dSHerbert Xu 				hexdump(q, n);
1316da7f033dSHerbert Xu 				goto out;
1317da7f033dSHerbert Xu 			}
1318da7f033dSHerbert Xu 			temp += template[i].tap[k];
1319da7f033dSHerbert Xu 		}
1320da7f033dSHerbert Xu 	}
1321da7f033dSHerbert Xu 
1322da7f033dSHerbert Xu 	ret = 0;
1323da7f033dSHerbert Xu 
1324da7f033dSHerbert Xu out:
132512773d93SHerbert Xu 	skcipher_request_free(req);
132608d6af8cSJussi Kivilinna 	if (diff_dst)
132708d6af8cSJussi Kivilinna 		testmgr_free_buf(xoutbuf);
132808d6af8cSJussi Kivilinna out_nooutbuf:
1329f8b0d4d0SHerbert Xu 	testmgr_free_buf(xbuf);
1330f8b0d4d0SHerbert Xu out_nobuf:
1331da7f033dSHerbert Xu 	return ret;
1332da7f033dSHerbert Xu }
1333da7f033dSHerbert Xu 
133412773d93SHerbert Xu static int test_skcipher(struct crypto_skcipher *tfm, int enc,
133508d6af8cSJussi Kivilinna 			 struct cipher_testvec *template, unsigned int tcount)
133608d6af8cSJussi Kivilinna {
13373a338f20SJussi Kivilinna 	unsigned int alignmask;
133808d6af8cSJussi Kivilinna 	int ret;
133908d6af8cSJussi Kivilinna 
134008d6af8cSJussi Kivilinna 	/* test 'dst == src' case */
13413a338f20SJussi Kivilinna 	ret = __test_skcipher(tfm, enc, template, tcount, false, 0);
134208d6af8cSJussi Kivilinna 	if (ret)
134308d6af8cSJussi Kivilinna 		return ret;
134408d6af8cSJussi Kivilinna 
134508d6af8cSJussi Kivilinna 	/* test 'dst != src' case */
13463a338f20SJussi Kivilinna 	ret = __test_skcipher(tfm, enc, template, tcount, true, 0);
13473a338f20SJussi Kivilinna 	if (ret)
13483a338f20SJussi Kivilinna 		return ret;
13493a338f20SJussi Kivilinna 
13503a338f20SJussi Kivilinna 	/* test unaligned buffers, check with one byte offset */
13513a338f20SJussi Kivilinna 	ret = __test_skcipher(tfm, enc, template, tcount, true, 1);
13523a338f20SJussi Kivilinna 	if (ret)
13533a338f20SJussi Kivilinna 		return ret;
13543a338f20SJussi Kivilinna 
13553a338f20SJussi Kivilinna 	alignmask = crypto_tfm_alg_alignmask(&tfm->base);
13563a338f20SJussi Kivilinna 	if (alignmask) {
13573a338f20SJussi Kivilinna 		/* Check if alignment mask for tfm is correctly set. */
13583a338f20SJussi Kivilinna 		ret = __test_skcipher(tfm, enc, template, tcount, true,
13593a338f20SJussi Kivilinna 				      alignmask + 1);
13603a338f20SJussi Kivilinna 		if (ret)
13613a338f20SJussi Kivilinna 			return ret;
13623a338f20SJussi Kivilinna 	}
13633a338f20SJussi Kivilinna 
13643a338f20SJussi Kivilinna 	return 0;
136508d6af8cSJussi Kivilinna }
136608d6af8cSJussi Kivilinna 
1367da7f033dSHerbert Xu static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate,
1368da7f033dSHerbert Xu 		     struct comp_testvec *dtemplate, int ctcount, int dtcount)
1369da7f033dSHerbert Xu {
1370da7f033dSHerbert Xu 	const char *algo = crypto_tfm_alg_driver_name(crypto_comp_tfm(tfm));
1371da7f033dSHerbert Xu 	unsigned int i;
1372da7f033dSHerbert Xu 	char result[COMP_BUF_SIZE];
1373da7f033dSHerbert Xu 	int ret;
1374da7f033dSHerbert Xu 
1375da7f033dSHerbert Xu 	for (i = 0; i < ctcount; i++) {
1376c79cf910SGeert Uytterhoeven 		int ilen;
1377c79cf910SGeert Uytterhoeven 		unsigned int dlen = COMP_BUF_SIZE;
1378da7f033dSHerbert Xu 
1379da7f033dSHerbert Xu 		memset(result, 0, sizeof (result));
1380da7f033dSHerbert Xu 
1381da7f033dSHerbert Xu 		ilen = ctemplate[i].inlen;
1382da7f033dSHerbert Xu 		ret = crypto_comp_compress(tfm, ctemplate[i].input,
1383da7f033dSHerbert Xu 		                           ilen, result, &dlen);
1384da7f033dSHerbert Xu 		if (ret) {
1385da7f033dSHerbert Xu 			printk(KERN_ERR "alg: comp: compression failed "
1386da7f033dSHerbert Xu 			       "on test %d for %s: ret=%d\n", i + 1, algo,
1387da7f033dSHerbert Xu 			       -ret);
1388da7f033dSHerbert Xu 			goto out;
1389da7f033dSHerbert Xu 		}
1390da7f033dSHerbert Xu 
1391b812eb00SGeert Uytterhoeven 		if (dlen != ctemplate[i].outlen) {
1392b812eb00SGeert Uytterhoeven 			printk(KERN_ERR "alg: comp: Compression test %d "
1393b812eb00SGeert Uytterhoeven 			       "failed for %s: output len = %d\n", i + 1, algo,
1394b812eb00SGeert Uytterhoeven 			       dlen);
1395b812eb00SGeert Uytterhoeven 			ret = -EINVAL;
1396b812eb00SGeert Uytterhoeven 			goto out;
1397b812eb00SGeert Uytterhoeven 		}
1398b812eb00SGeert Uytterhoeven 
1399da7f033dSHerbert Xu 		if (memcmp(result, ctemplate[i].output, dlen)) {
1400da7f033dSHerbert Xu 			printk(KERN_ERR "alg: comp: Compression test %d "
1401da7f033dSHerbert Xu 			       "failed for %s\n", i + 1, algo);
1402da7f033dSHerbert Xu 			hexdump(result, dlen);
1403da7f033dSHerbert Xu 			ret = -EINVAL;
1404da7f033dSHerbert Xu 			goto out;
1405da7f033dSHerbert Xu 		}
1406da7f033dSHerbert Xu 	}
1407da7f033dSHerbert Xu 
1408da7f033dSHerbert Xu 	for (i = 0; i < dtcount; i++) {
1409c79cf910SGeert Uytterhoeven 		int ilen;
1410c79cf910SGeert Uytterhoeven 		unsigned int dlen = COMP_BUF_SIZE;
1411da7f033dSHerbert Xu 
1412da7f033dSHerbert Xu 		memset(result, 0, sizeof (result));
1413da7f033dSHerbert Xu 
1414da7f033dSHerbert Xu 		ilen = dtemplate[i].inlen;
1415da7f033dSHerbert Xu 		ret = crypto_comp_decompress(tfm, dtemplate[i].input,
1416da7f033dSHerbert Xu 		                             ilen, result, &dlen);
1417da7f033dSHerbert Xu 		if (ret) {
1418da7f033dSHerbert Xu 			printk(KERN_ERR "alg: comp: decompression failed "
1419da7f033dSHerbert Xu 			       "on test %d for %s: ret=%d\n", i + 1, algo,
1420da7f033dSHerbert Xu 			       -ret);
1421da7f033dSHerbert Xu 			goto out;
1422da7f033dSHerbert Xu 		}
1423da7f033dSHerbert Xu 
1424b812eb00SGeert Uytterhoeven 		if (dlen != dtemplate[i].outlen) {
1425b812eb00SGeert Uytterhoeven 			printk(KERN_ERR "alg: comp: Decompression test %d "
1426b812eb00SGeert Uytterhoeven 			       "failed for %s: output len = %d\n", i + 1, algo,
1427b812eb00SGeert Uytterhoeven 			       dlen);
1428b812eb00SGeert Uytterhoeven 			ret = -EINVAL;
1429b812eb00SGeert Uytterhoeven 			goto out;
1430b812eb00SGeert Uytterhoeven 		}
1431b812eb00SGeert Uytterhoeven 
1432da7f033dSHerbert Xu 		if (memcmp(result, dtemplate[i].output, dlen)) {
1433da7f033dSHerbert Xu 			printk(KERN_ERR "alg: comp: Decompression test %d "
1434da7f033dSHerbert Xu 			       "failed for %s\n", i + 1, algo);
1435da7f033dSHerbert Xu 			hexdump(result, dlen);
1436da7f033dSHerbert Xu 			ret = -EINVAL;
1437da7f033dSHerbert Xu 			goto out;
1438da7f033dSHerbert Xu 		}
1439da7f033dSHerbert Xu 	}
1440da7f033dSHerbert Xu 
1441da7f033dSHerbert Xu 	ret = 0;
1442da7f033dSHerbert Xu 
1443da7f033dSHerbert Xu out:
1444da7f033dSHerbert Xu 	return ret;
1445da7f033dSHerbert Xu }
1446da7f033dSHerbert Xu 
1447d7db7a88SGiovanni Cabiddu static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
1448d7db7a88SGiovanni Cabiddu 		      struct comp_testvec *dtemplate, int ctcount, int dtcount)
1449d7db7a88SGiovanni Cabiddu {
1450d7db7a88SGiovanni Cabiddu 	const char *algo = crypto_tfm_alg_driver_name(crypto_acomp_tfm(tfm));
1451d7db7a88SGiovanni Cabiddu 	unsigned int i;
1452eb095593SEric Biggers 	char *output;
1453d7db7a88SGiovanni Cabiddu 	int ret;
1454d7db7a88SGiovanni Cabiddu 	struct scatterlist src, dst;
1455d7db7a88SGiovanni Cabiddu 	struct acomp_req *req;
1456d7db7a88SGiovanni Cabiddu 	struct tcrypt_result result;
1457d7db7a88SGiovanni Cabiddu 
1458eb095593SEric Biggers 	output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL);
1459eb095593SEric Biggers 	if (!output)
1460eb095593SEric Biggers 		return -ENOMEM;
1461eb095593SEric Biggers 
1462d7db7a88SGiovanni Cabiddu 	for (i = 0; i < ctcount; i++) {
1463d7db7a88SGiovanni Cabiddu 		unsigned int dlen = COMP_BUF_SIZE;
1464d7db7a88SGiovanni Cabiddu 		int ilen = ctemplate[i].inlen;
146502608e02SLaura Abbott 		void *input_vec;
1466d7db7a88SGiovanni Cabiddu 
1467d2110224SEric Biggers 		input_vec = kmemdup(ctemplate[i].input, ilen, GFP_KERNEL);
146802608e02SLaura Abbott 		if (!input_vec) {
146902608e02SLaura Abbott 			ret = -ENOMEM;
147002608e02SLaura Abbott 			goto out;
147102608e02SLaura Abbott 		}
147202608e02SLaura Abbott 
1473eb095593SEric Biggers 		memset(output, 0, dlen);
1474d7db7a88SGiovanni Cabiddu 		init_completion(&result.completion);
147502608e02SLaura Abbott 		sg_init_one(&src, input_vec, ilen);
1476d7db7a88SGiovanni Cabiddu 		sg_init_one(&dst, output, dlen);
1477d7db7a88SGiovanni Cabiddu 
1478d7db7a88SGiovanni Cabiddu 		req = acomp_request_alloc(tfm);
1479d7db7a88SGiovanni Cabiddu 		if (!req) {
1480d7db7a88SGiovanni Cabiddu 			pr_err("alg: acomp: request alloc failed for %s\n",
1481d7db7a88SGiovanni Cabiddu 			       algo);
148202608e02SLaura Abbott 			kfree(input_vec);
1483d7db7a88SGiovanni Cabiddu 			ret = -ENOMEM;
1484d7db7a88SGiovanni Cabiddu 			goto out;
1485d7db7a88SGiovanni Cabiddu 		}
1486d7db7a88SGiovanni Cabiddu 
1487d7db7a88SGiovanni Cabiddu 		acomp_request_set_params(req, &src, &dst, ilen, dlen);
1488d7db7a88SGiovanni Cabiddu 		acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
1489d7db7a88SGiovanni Cabiddu 					   tcrypt_complete, &result);
1490d7db7a88SGiovanni Cabiddu 
1491d7db7a88SGiovanni Cabiddu 		ret = wait_async_op(&result, crypto_acomp_compress(req));
1492d7db7a88SGiovanni Cabiddu 		if (ret) {
1493d7db7a88SGiovanni Cabiddu 			pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n",
1494d7db7a88SGiovanni Cabiddu 			       i + 1, algo, -ret);
149502608e02SLaura Abbott 			kfree(input_vec);
1496d7db7a88SGiovanni Cabiddu 			acomp_request_free(req);
1497d7db7a88SGiovanni Cabiddu 			goto out;
1498d7db7a88SGiovanni Cabiddu 		}
1499d7db7a88SGiovanni Cabiddu 
1500d7db7a88SGiovanni Cabiddu 		if (req->dlen != ctemplate[i].outlen) {
1501d7db7a88SGiovanni Cabiddu 			pr_err("alg: acomp: Compression test %d failed for %s: output len = %d\n",
1502d7db7a88SGiovanni Cabiddu 			       i + 1, algo, req->dlen);
1503d7db7a88SGiovanni Cabiddu 			ret = -EINVAL;
150402608e02SLaura Abbott 			kfree(input_vec);
1505d7db7a88SGiovanni Cabiddu 			acomp_request_free(req);
1506d7db7a88SGiovanni Cabiddu 			goto out;
1507d7db7a88SGiovanni Cabiddu 		}
1508d7db7a88SGiovanni Cabiddu 
1509d7db7a88SGiovanni Cabiddu 		if (memcmp(output, ctemplate[i].output, req->dlen)) {
1510d7db7a88SGiovanni Cabiddu 			pr_err("alg: acomp: Compression test %d failed for %s\n",
1511d7db7a88SGiovanni Cabiddu 			       i + 1, algo);
1512d7db7a88SGiovanni Cabiddu 			hexdump(output, req->dlen);
1513d7db7a88SGiovanni Cabiddu 			ret = -EINVAL;
151402608e02SLaura Abbott 			kfree(input_vec);
1515d7db7a88SGiovanni Cabiddu 			acomp_request_free(req);
1516d7db7a88SGiovanni Cabiddu 			goto out;
1517d7db7a88SGiovanni Cabiddu 		}
1518d7db7a88SGiovanni Cabiddu 
151902608e02SLaura Abbott 		kfree(input_vec);
1520d7db7a88SGiovanni Cabiddu 		acomp_request_free(req);
1521d7db7a88SGiovanni Cabiddu 	}
1522d7db7a88SGiovanni Cabiddu 
1523d7db7a88SGiovanni Cabiddu 	for (i = 0; i < dtcount; i++) {
1524d7db7a88SGiovanni Cabiddu 		unsigned int dlen = COMP_BUF_SIZE;
1525d7db7a88SGiovanni Cabiddu 		int ilen = dtemplate[i].inlen;
152602608e02SLaura Abbott 		void *input_vec;
1527d7db7a88SGiovanni Cabiddu 
1528d2110224SEric Biggers 		input_vec = kmemdup(dtemplate[i].input, ilen, GFP_KERNEL);
152902608e02SLaura Abbott 		if (!input_vec) {
153002608e02SLaura Abbott 			ret = -ENOMEM;
153102608e02SLaura Abbott 			goto out;
153202608e02SLaura Abbott 		}
153302608e02SLaura Abbott 
1534eb095593SEric Biggers 		memset(output, 0, dlen);
1535d7db7a88SGiovanni Cabiddu 		init_completion(&result.completion);
153602608e02SLaura Abbott 		sg_init_one(&src, input_vec, ilen);
1537d7db7a88SGiovanni Cabiddu 		sg_init_one(&dst, output, dlen);
1538d7db7a88SGiovanni Cabiddu 
1539d7db7a88SGiovanni Cabiddu 		req = acomp_request_alloc(tfm);
1540d7db7a88SGiovanni Cabiddu 		if (!req) {
1541d7db7a88SGiovanni Cabiddu 			pr_err("alg: acomp: request alloc failed for %s\n",
1542d7db7a88SGiovanni Cabiddu 			       algo);
154302608e02SLaura Abbott 			kfree(input_vec);
1544d7db7a88SGiovanni Cabiddu 			ret = -ENOMEM;
1545d7db7a88SGiovanni Cabiddu 			goto out;
1546d7db7a88SGiovanni Cabiddu 		}
1547d7db7a88SGiovanni Cabiddu 
1548d7db7a88SGiovanni Cabiddu 		acomp_request_set_params(req, &src, &dst, ilen, dlen);
1549d7db7a88SGiovanni Cabiddu 		acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
1550d7db7a88SGiovanni Cabiddu 					   tcrypt_complete, &result);
1551d7db7a88SGiovanni Cabiddu 
1552d7db7a88SGiovanni Cabiddu 		ret = wait_async_op(&result, crypto_acomp_decompress(req));
1553d7db7a88SGiovanni Cabiddu 		if (ret) {
1554d7db7a88SGiovanni Cabiddu 			pr_err("alg: acomp: decompression failed on test %d for %s: ret=%d\n",
1555d7db7a88SGiovanni Cabiddu 			       i + 1, algo, -ret);
155602608e02SLaura Abbott 			kfree(input_vec);
1557d7db7a88SGiovanni Cabiddu 			acomp_request_free(req);
1558d7db7a88SGiovanni Cabiddu 			goto out;
1559d7db7a88SGiovanni Cabiddu 		}
1560d7db7a88SGiovanni Cabiddu 
1561d7db7a88SGiovanni Cabiddu 		if (req->dlen != dtemplate[i].outlen) {
1562d7db7a88SGiovanni Cabiddu 			pr_err("alg: acomp: Decompression test %d failed for %s: output len = %d\n",
1563d7db7a88SGiovanni Cabiddu 			       i + 1, algo, req->dlen);
1564d7db7a88SGiovanni Cabiddu 			ret = -EINVAL;
156502608e02SLaura Abbott 			kfree(input_vec);
1566d7db7a88SGiovanni Cabiddu 			acomp_request_free(req);
1567d7db7a88SGiovanni Cabiddu 			goto out;
1568d7db7a88SGiovanni Cabiddu 		}
1569d7db7a88SGiovanni Cabiddu 
1570d7db7a88SGiovanni Cabiddu 		if (memcmp(output, dtemplate[i].output, req->dlen)) {
1571d7db7a88SGiovanni Cabiddu 			pr_err("alg: acomp: Decompression test %d failed for %s\n",
1572d7db7a88SGiovanni Cabiddu 			       i + 1, algo);
1573d7db7a88SGiovanni Cabiddu 			hexdump(output, req->dlen);
1574d7db7a88SGiovanni Cabiddu 			ret = -EINVAL;
157502608e02SLaura Abbott 			kfree(input_vec);
1576d7db7a88SGiovanni Cabiddu 			acomp_request_free(req);
1577d7db7a88SGiovanni Cabiddu 			goto out;
1578d7db7a88SGiovanni Cabiddu 		}
1579d7db7a88SGiovanni Cabiddu 
158002608e02SLaura Abbott 		kfree(input_vec);
1581d7db7a88SGiovanni Cabiddu 		acomp_request_free(req);
1582d7db7a88SGiovanni Cabiddu 	}
1583d7db7a88SGiovanni Cabiddu 
1584d7db7a88SGiovanni Cabiddu 	ret = 0;
1585d7db7a88SGiovanni Cabiddu 
1586d7db7a88SGiovanni Cabiddu out:
1587eb095593SEric Biggers 	kfree(output);
1588d7db7a88SGiovanni Cabiddu 	return ret;
1589d7db7a88SGiovanni Cabiddu }
1590d7db7a88SGiovanni Cabiddu 
15917647d6ceSJarod Wilson static int test_cprng(struct crypto_rng *tfm, struct cprng_testvec *template,
15927647d6ceSJarod Wilson 		      unsigned int tcount)
15937647d6ceSJarod Wilson {
15947647d6ceSJarod Wilson 	const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm));
1595fa4ef8a6SFelipe Contreras 	int err = 0, i, j, seedsize;
15967647d6ceSJarod Wilson 	u8 *seed;
15977647d6ceSJarod Wilson 	char result[32];
15987647d6ceSJarod Wilson 
15997647d6ceSJarod Wilson 	seedsize = crypto_rng_seedsize(tfm);
16007647d6ceSJarod Wilson 
16017647d6ceSJarod Wilson 	seed = kmalloc(seedsize, GFP_KERNEL);
16027647d6ceSJarod Wilson 	if (!seed) {
16037647d6ceSJarod Wilson 		printk(KERN_ERR "alg: cprng: Failed to allocate seed space "
16047647d6ceSJarod Wilson 		       "for %s\n", algo);
16057647d6ceSJarod Wilson 		return -ENOMEM;
16067647d6ceSJarod Wilson 	}
16077647d6ceSJarod Wilson 
16087647d6ceSJarod Wilson 	for (i = 0; i < tcount; i++) {
16097647d6ceSJarod Wilson 		memset(result, 0, 32);
16107647d6ceSJarod Wilson 
16117647d6ceSJarod Wilson 		memcpy(seed, template[i].v, template[i].vlen);
16127647d6ceSJarod Wilson 		memcpy(seed + template[i].vlen, template[i].key,
16137647d6ceSJarod Wilson 		       template[i].klen);
16147647d6ceSJarod Wilson 		memcpy(seed + template[i].vlen + template[i].klen,
16157647d6ceSJarod Wilson 		       template[i].dt, template[i].dtlen);
16167647d6ceSJarod Wilson 
16177647d6ceSJarod Wilson 		err = crypto_rng_reset(tfm, seed, seedsize);
16187647d6ceSJarod Wilson 		if (err) {
16197647d6ceSJarod Wilson 			printk(KERN_ERR "alg: cprng: Failed to reset rng "
16207647d6ceSJarod Wilson 			       "for %s\n", algo);
16217647d6ceSJarod Wilson 			goto out;
16227647d6ceSJarod Wilson 		}
16237647d6ceSJarod Wilson 
16247647d6ceSJarod Wilson 		for (j = 0; j < template[i].loops; j++) {
16257647d6ceSJarod Wilson 			err = crypto_rng_get_bytes(tfm, result,
16267647d6ceSJarod Wilson 						   template[i].rlen);
162719e60e13SStephan Mueller 			if (err < 0) {
16287647d6ceSJarod Wilson 				printk(KERN_ERR "alg: cprng: Failed to obtain "
16297647d6ceSJarod Wilson 				       "the correct amount of random data for "
163019e60e13SStephan Mueller 				       "%s (requested %d)\n", algo,
163119e60e13SStephan Mueller 				       template[i].rlen);
16327647d6ceSJarod Wilson 				goto out;
16337647d6ceSJarod Wilson 			}
16347647d6ceSJarod Wilson 		}
16357647d6ceSJarod Wilson 
16367647d6ceSJarod Wilson 		err = memcmp(result, template[i].result,
16377647d6ceSJarod Wilson 			     template[i].rlen);
16387647d6ceSJarod Wilson 		if (err) {
16397647d6ceSJarod Wilson 			printk(KERN_ERR "alg: cprng: Test %d failed for %s\n",
16407647d6ceSJarod Wilson 			       i, algo);
16417647d6ceSJarod Wilson 			hexdump(result, template[i].rlen);
16427647d6ceSJarod Wilson 			err = -EINVAL;
16437647d6ceSJarod Wilson 			goto out;
16447647d6ceSJarod Wilson 		}
16457647d6ceSJarod Wilson 	}
16467647d6ceSJarod Wilson 
16477647d6ceSJarod Wilson out:
16487647d6ceSJarod Wilson 	kfree(seed);
16497647d6ceSJarod Wilson 	return err;
16507647d6ceSJarod Wilson }
16517647d6ceSJarod Wilson 
1652da7f033dSHerbert Xu static int alg_test_aead(const struct alg_test_desc *desc, const char *driver,
1653da7f033dSHerbert Xu 			 u32 type, u32 mask)
1654da7f033dSHerbert Xu {
1655da7f033dSHerbert Xu 	struct crypto_aead *tfm;
1656da7f033dSHerbert Xu 	int err = 0;
1657da7f033dSHerbert Xu 
1658eed93e0cSHerbert Xu 	tfm = crypto_alloc_aead(driver, type, mask);
1659da7f033dSHerbert Xu 	if (IS_ERR(tfm)) {
1660da7f033dSHerbert Xu 		printk(KERN_ERR "alg: aead: Failed to load transform for %s: "
1661da7f033dSHerbert Xu 		       "%ld\n", driver, PTR_ERR(tfm));
1662da7f033dSHerbert Xu 		return PTR_ERR(tfm);
1663da7f033dSHerbert Xu 	}
1664da7f033dSHerbert Xu 
1665da7f033dSHerbert Xu 	if (desc->suite.aead.enc.vecs) {
1666da7f033dSHerbert Xu 		err = test_aead(tfm, ENCRYPT, desc->suite.aead.enc.vecs,
1667da7f033dSHerbert Xu 				desc->suite.aead.enc.count);
1668da7f033dSHerbert Xu 		if (err)
1669da7f033dSHerbert Xu 			goto out;
1670da7f033dSHerbert Xu 	}
1671da7f033dSHerbert Xu 
1672da7f033dSHerbert Xu 	if (!err && desc->suite.aead.dec.vecs)
1673da7f033dSHerbert Xu 		err = test_aead(tfm, DECRYPT, desc->suite.aead.dec.vecs,
1674da7f033dSHerbert Xu 				desc->suite.aead.dec.count);
1675da7f033dSHerbert Xu 
1676da7f033dSHerbert Xu out:
1677da7f033dSHerbert Xu 	crypto_free_aead(tfm);
1678da7f033dSHerbert Xu 	return err;
1679da7f033dSHerbert Xu }
1680da7f033dSHerbert Xu 
1681da7f033dSHerbert Xu static int alg_test_cipher(const struct alg_test_desc *desc,
1682da7f033dSHerbert Xu 			   const char *driver, u32 type, u32 mask)
1683da7f033dSHerbert Xu {
16841aa4ecd9SHerbert Xu 	struct crypto_cipher *tfm;
1685da7f033dSHerbert Xu 	int err = 0;
1686da7f033dSHerbert Xu 
1687eed93e0cSHerbert Xu 	tfm = crypto_alloc_cipher(driver, type, mask);
1688da7f033dSHerbert Xu 	if (IS_ERR(tfm)) {
1689da7f033dSHerbert Xu 		printk(KERN_ERR "alg: cipher: Failed to load transform for "
1690da7f033dSHerbert Xu 		       "%s: %ld\n", driver, PTR_ERR(tfm));
1691da7f033dSHerbert Xu 		return PTR_ERR(tfm);
1692da7f033dSHerbert Xu 	}
1693da7f033dSHerbert Xu 
1694da7f033dSHerbert Xu 	if (desc->suite.cipher.enc.vecs) {
1695da7f033dSHerbert Xu 		err = test_cipher(tfm, ENCRYPT, desc->suite.cipher.enc.vecs,
1696da7f033dSHerbert Xu 				  desc->suite.cipher.enc.count);
1697da7f033dSHerbert Xu 		if (err)
1698da7f033dSHerbert Xu 			goto out;
1699da7f033dSHerbert Xu 	}
1700da7f033dSHerbert Xu 
1701da7f033dSHerbert Xu 	if (desc->suite.cipher.dec.vecs)
1702da7f033dSHerbert Xu 		err = test_cipher(tfm, DECRYPT, desc->suite.cipher.dec.vecs,
1703da7f033dSHerbert Xu 				  desc->suite.cipher.dec.count);
1704da7f033dSHerbert Xu 
1705da7f033dSHerbert Xu out:
17061aa4ecd9SHerbert Xu 	crypto_free_cipher(tfm);
17071aa4ecd9SHerbert Xu 	return err;
17081aa4ecd9SHerbert Xu }
17091aa4ecd9SHerbert Xu 
17101aa4ecd9SHerbert Xu static int alg_test_skcipher(const struct alg_test_desc *desc,
17111aa4ecd9SHerbert Xu 			     const char *driver, u32 type, u32 mask)
17121aa4ecd9SHerbert Xu {
171312773d93SHerbert Xu 	struct crypto_skcipher *tfm;
17141aa4ecd9SHerbert Xu 	int err = 0;
17151aa4ecd9SHerbert Xu 
1716eed93e0cSHerbert Xu 	tfm = crypto_alloc_skcipher(driver, type, mask);
17171aa4ecd9SHerbert Xu 	if (IS_ERR(tfm)) {
17181aa4ecd9SHerbert Xu 		printk(KERN_ERR "alg: skcipher: Failed to load transform for "
17191aa4ecd9SHerbert Xu 		       "%s: %ld\n", driver, PTR_ERR(tfm));
17201aa4ecd9SHerbert Xu 		return PTR_ERR(tfm);
17211aa4ecd9SHerbert Xu 	}
17221aa4ecd9SHerbert Xu 
17231aa4ecd9SHerbert Xu 	if (desc->suite.cipher.enc.vecs) {
17241aa4ecd9SHerbert Xu 		err = test_skcipher(tfm, ENCRYPT, desc->suite.cipher.enc.vecs,
17251aa4ecd9SHerbert Xu 				    desc->suite.cipher.enc.count);
17261aa4ecd9SHerbert Xu 		if (err)
17271aa4ecd9SHerbert Xu 			goto out;
17281aa4ecd9SHerbert Xu 	}
17291aa4ecd9SHerbert Xu 
17301aa4ecd9SHerbert Xu 	if (desc->suite.cipher.dec.vecs)
17311aa4ecd9SHerbert Xu 		err = test_skcipher(tfm, DECRYPT, desc->suite.cipher.dec.vecs,
17321aa4ecd9SHerbert Xu 				    desc->suite.cipher.dec.count);
17331aa4ecd9SHerbert Xu 
17341aa4ecd9SHerbert Xu out:
173512773d93SHerbert Xu 	crypto_free_skcipher(tfm);
1736da7f033dSHerbert Xu 	return err;
1737da7f033dSHerbert Xu }
1738da7f033dSHerbert Xu 
1739da7f033dSHerbert Xu static int alg_test_comp(const struct alg_test_desc *desc, const char *driver,
1740da7f033dSHerbert Xu 			 u32 type, u32 mask)
1741da7f033dSHerbert Xu {
1742d7db7a88SGiovanni Cabiddu 	struct crypto_comp *comp;
1743d7db7a88SGiovanni Cabiddu 	struct crypto_acomp *acomp;
1744da7f033dSHerbert Xu 	int err;
1745d7db7a88SGiovanni Cabiddu 	u32 algo_type = type & CRYPTO_ALG_TYPE_ACOMPRESS_MASK;
1746da7f033dSHerbert Xu 
1747d7db7a88SGiovanni Cabiddu 	if (algo_type == CRYPTO_ALG_TYPE_ACOMPRESS) {
1748d7db7a88SGiovanni Cabiddu 		acomp = crypto_alloc_acomp(driver, type, mask);
1749d7db7a88SGiovanni Cabiddu 		if (IS_ERR(acomp)) {
1750d7db7a88SGiovanni Cabiddu 			pr_err("alg: acomp: Failed to load transform for %s: %ld\n",
1751d7db7a88SGiovanni Cabiddu 			       driver, PTR_ERR(acomp));
1752d7db7a88SGiovanni Cabiddu 			return PTR_ERR(acomp);
1753d7db7a88SGiovanni Cabiddu 		}
1754d7db7a88SGiovanni Cabiddu 		err = test_acomp(acomp, desc->suite.comp.comp.vecs,
1755d7db7a88SGiovanni Cabiddu 				 desc->suite.comp.decomp.vecs,
1756d7db7a88SGiovanni Cabiddu 				 desc->suite.comp.comp.count,
1757d7db7a88SGiovanni Cabiddu 				 desc->suite.comp.decomp.count);
1758d7db7a88SGiovanni Cabiddu 		crypto_free_acomp(acomp);
1759d7db7a88SGiovanni Cabiddu 	} else {
1760d7db7a88SGiovanni Cabiddu 		comp = crypto_alloc_comp(driver, type, mask);
1761d7db7a88SGiovanni Cabiddu 		if (IS_ERR(comp)) {
1762d7db7a88SGiovanni Cabiddu 			pr_err("alg: comp: Failed to load transform for %s: %ld\n",
1763d7db7a88SGiovanni Cabiddu 			       driver, PTR_ERR(comp));
1764d7db7a88SGiovanni Cabiddu 			return PTR_ERR(comp);
1765da7f033dSHerbert Xu 		}
1766da7f033dSHerbert Xu 
1767d7db7a88SGiovanni Cabiddu 		err = test_comp(comp, desc->suite.comp.comp.vecs,
1768da7f033dSHerbert Xu 				desc->suite.comp.decomp.vecs,
1769da7f033dSHerbert Xu 				desc->suite.comp.comp.count,
1770da7f033dSHerbert Xu 				desc->suite.comp.decomp.count);
1771da7f033dSHerbert Xu 
1772d7db7a88SGiovanni Cabiddu 		crypto_free_comp(comp);
1773d7db7a88SGiovanni Cabiddu 	}
1774da7f033dSHerbert Xu 	return err;
1775da7f033dSHerbert Xu }
1776da7f033dSHerbert Xu 
1777da7f033dSHerbert Xu static int alg_test_hash(const struct alg_test_desc *desc, const char *driver,
1778da7f033dSHerbert Xu 			 u32 type, u32 mask)
1779da7f033dSHerbert Xu {
1780da7f033dSHerbert Xu 	struct crypto_ahash *tfm;
1781da7f033dSHerbert Xu 	int err;
1782da7f033dSHerbert Xu 
1783eed93e0cSHerbert Xu 	tfm = crypto_alloc_ahash(driver, type, mask);
1784da7f033dSHerbert Xu 	if (IS_ERR(tfm)) {
1785da7f033dSHerbert Xu 		printk(KERN_ERR "alg: hash: Failed to load transform for %s: "
1786da7f033dSHerbert Xu 		       "%ld\n", driver, PTR_ERR(tfm));
1787da7f033dSHerbert Xu 		return PTR_ERR(tfm);
1788da7f033dSHerbert Xu 	}
1789da7f033dSHerbert Xu 
1790a8f1a052SDavid S. Miller 	err = test_hash(tfm, desc->suite.hash.vecs,
1791a8f1a052SDavid S. Miller 			desc->suite.hash.count, true);
1792a8f1a052SDavid S. Miller 	if (!err)
1793a8f1a052SDavid S. Miller 		err = test_hash(tfm, desc->suite.hash.vecs,
1794a8f1a052SDavid S. Miller 				desc->suite.hash.count, false);
1795da7f033dSHerbert Xu 
1796da7f033dSHerbert Xu 	crypto_free_ahash(tfm);
1797da7f033dSHerbert Xu 	return err;
1798da7f033dSHerbert Xu }
1799da7f033dSHerbert Xu 
18008e3ee85eSHerbert Xu static int alg_test_crc32c(const struct alg_test_desc *desc,
18018e3ee85eSHerbert Xu 			   const char *driver, u32 type, u32 mask)
18028e3ee85eSHerbert Xu {
18038e3ee85eSHerbert Xu 	struct crypto_shash *tfm;
18048e3ee85eSHerbert Xu 	u32 val;
18058e3ee85eSHerbert Xu 	int err;
18068e3ee85eSHerbert Xu 
18078e3ee85eSHerbert Xu 	err = alg_test_hash(desc, driver, type, mask);
18088e3ee85eSHerbert Xu 	if (err)
18098e3ee85eSHerbert Xu 		goto out;
18108e3ee85eSHerbert Xu 
1811eed93e0cSHerbert Xu 	tfm = crypto_alloc_shash(driver, type, mask);
18128e3ee85eSHerbert Xu 	if (IS_ERR(tfm)) {
18138e3ee85eSHerbert Xu 		printk(KERN_ERR "alg: crc32c: Failed to load transform for %s: "
18148e3ee85eSHerbert Xu 		       "%ld\n", driver, PTR_ERR(tfm));
18158e3ee85eSHerbert Xu 		err = PTR_ERR(tfm);
18168e3ee85eSHerbert Xu 		goto out;
18178e3ee85eSHerbert Xu 	}
18188e3ee85eSHerbert Xu 
18198e3ee85eSHerbert Xu 	do {
18204c5c3024SJan-Simon Möller 		SHASH_DESC_ON_STACK(shash, tfm);
18214c5c3024SJan-Simon Möller 		u32 *ctx = (u32 *)shash_desc_ctx(shash);
18228e3ee85eSHerbert Xu 
18234c5c3024SJan-Simon Möller 		shash->tfm = tfm;
18244c5c3024SJan-Simon Möller 		shash->flags = 0;
18258e3ee85eSHerbert Xu 
18264c5c3024SJan-Simon Möller 		*ctx = le32_to_cpu(420553207);
18274c5c3024SJan-Simon Möller 		err = crypto_shash_final(shash, (u8 *)&val);
18288e3ee85eSHerbert Xu 		if (err) {
18298e3ee85eSHerbert Xu 			printk(KERN_ERR "alg: crc32c: Operation failed for "
18308e3ee85eSHerbert Xu 			       "%s: %d\n", driver, err);
18318e3ee85eSHerbert Xu 			break;
18328e3ee85eSHerbert Xu 		}
18338e3ee85eSHerbert Xu 
18348e3ee85eSHerbert Xu 		if (val != ~420553207) {
18358e3ee85eSHerbert Xu 			printk(KERN_ERR "alg: crc32c: Test failed for %s: "
18368e3ee85eSHerbert Xu 			       "%d\n", driver, val);
18378e3ee85eSHerbert Xu 			err = -EINVAL;
18388e3ee85eSHerbert Xu 		}
18398e3ee85eSHerbert Xu 	} while (0);
18408e3ee85eSHerbert Xu 
18418e3ee85eSHerbert Xu 	crypto_free_shash(tfm);
18428e3ee85eSHerbert Xu 
18438e3ee85eSHerbert Xu out:
18448e3ee85eSHerbert Xu 	return err;
18458e3ee85eSHerbert Xu }
18468e3ee85eSHerbert Xu 
18477647d6ceSJarod Wilson static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver,
18487647d6ceSJarod Wilson 			  u32 type, u32 mask)
18497647d6ceSJarod Wilson {
18507647d6ceSJarod Wilson 	struct crypto_rng *rng;
18517647d6ceSJarod Wilson 	int err;
18527647d6ceSJarod Wilson 
1853eed93e0cSHerbert Xu 	rng = crypto_alloc_rng(driver, type, mask);
18547647d6ceSJarod Wilson 	if (IS_ERR(rng)) {
18557647d6ceSJarod Wilson 		printk(KERN_ERR "alg: cprng: Failed to load transform for %s: "
18567647d6ceSJarod Wilson 		       "%ld\n", driver, PTR_ERR(rng));
18577647d6ceSJarod Wilson 		return PTR_ERR(rng);
18587647d6ceSJarod Wilson 	}
18597647d6ceSJarod Wilson 
18607647d6ceSJarod Wilson 	err = test_cprng(rng, desc->suite.cprng.vecs, desc->suite.cprng.count);
18617647d6ceSJarod Wilson 
18627647d6ceSJarod Wilson 	crypto_free_rng(rng);
18637647d6ceSJarod Wilson 
18647647d6ceSJarod Wilson 	return err;
18657647d6ceSJarod Wilson }
18667647d6ceSJarod Wilson 
186764d1cdfbSStephan Mueller 
186864d1cdfbSStephan Mueller static int drbg_cavs_test(struct drbg_testvec *test, int pr,
186964d1cdfbSStephan Mueller 			  const char *driver, u32 type, u32 mask)
187064d1cdfbSStephan Mueller {
187164d1cdfbSStephan Mueller 	int ret = -EAGAIN;
187264d1cdfbSStephan Mueller 	struct crypto_rng *drng;
187364d1cdfbSStephan Mueller 	struct drbg_test_data test_data;
187464d1cdfbSStephan Mueller 	struct drbg_string addtl, pers, testentropy;
187564d1cdfbSStephan Mueller 	unsigned char *buf = kzalloc(test->expectedlen, GFP_KERNEL);
187664d1cdfbSStephan Mueller 
187764d1cdfbSStephan Mueller 	if (!buf)
187864d1cdfbSStephan Mueller 		return -ENOMEM;
187964d1cdfbSStephan Mueller 
1880eed93e0cSHerbert Xu 	drng = crypto_alloc_rng(driver, type, mask);
188164d1cdfbSStephan Mueller 	if (IS_ERR(drng)) {
188264d1cdfbSStephan Mueller 		printk(KERN_ERR "alg: drbg: could not allocate DRNG handle for "
188364d1cdfbSStephan Mueller 		       "%s\n", driver);
188464d1cdfbSStephan Mueller 		kzfree(buf);
188564d1cdfbSStephan Mueller 		return -ENOMEM;
188664d1cdfbSStephan Mueller 	}
188764d1cdfbSStephan Mueller 
188864d1cdfbSStephan Mueller 	test_data.testentropy = &testentropy;
188964d1cdfbSStephan Mueller 	drbg_string_fill(&testentropy, test->entropy, test->entropylen);
189064d1cdfbSStephan Mueller 	drbg_string_fill(&pers, test->pers, test->perslen);
189164d1cdfbSStephan Mueller 	ret = crypto_drbg_reset_test(drng, &pers, &test_data);
189264d1cdfbSStephan Mueller 	if (ret) {
189364d1cdfbSStephan Mueller 		printk(KERN_ERR "alg: drbg: Failed to reset rng\n");
189464d1cdfbSStephan Mueller 		goto outbuf;
189564d1cdfbSStephan Mueller 	}
189664d1cdfbSStephan Mueller 
189764d1cdfbSStephan Mueller 	drbg_string_fill(&addtl, test->addtla, test->addtllen);
189864d1cdfbSStephan Mueller 	if (pr) {
189964d1cdfbSStephan Mueller 		drbg_string_fill(&testentropy, test->entpra, test->entprlen);
190064d1cdfbSStephan Mueller 		ret = crypto_drbg_get_bytes_addtl_test(drng,
190164d1cdfbSStephan Mueller 			buf, test->expectedlen, &addtl,	&test_data);
190264d1cdfbSStephan Mueller 	} else {
190364d1cdfbSStephan Mueller 		ret = crypto_drbg_get_bytes_addtl(drng,
190464d1cdfbSStephan Mueller 			buf, test->expectedlen, &addtl);
190564d1cdfbSStephan Mueller 	}
190619e60e13SStephan Mueller 	if (ret < 0) {
190764d1cdfbSStephan Mueller 		printk(KERN_ERR "alg: drbg: could not obtain random data for "
190864d1cdfbSStephan Mueller 		       "driver %s\n", driver);
190964d1cdfbSStephan Mueller 		goto outbuf;
191064d1cdfbSStephan Mueller 	}
191164d1cdfbSStephan Mueller 
191264d1cdfbSStephan Mueller 	drbg_string_fill(&addtl, test->addtlb, test->addtllen);
191364d1cdfbSStephan Mueller 	if (pr) {
191464d1cdfbSStephan Mueller 		drbg_string_fill(&testentropy, test->entprb, test->entprlen);
191564d1cdfbSStephan Mueller 		ret = crypto_drbg_get_bytes_addtl_test(drng,
191664d1cdfbSStephan Mueller 			buf, test->expectedlen, &addtl, &test_data);
191764d1cdfbSStephan Mueller 	} else {
191864d1cdfbSStephan Mueller 		ret = crypto_drbg_get_bytes_addtl(drng,
191964d1cdfbSStephan Mueller 			buf, test->expectedlen, &addtl);
192064d1cdfbSStephan Mueller 	}
192119e60e13SStephan Mueller 	if (ret < 0) {
192264d1cdfbSStephan Mueller 		printk(KERN_ERR "alg: drbg: could not obtain random data for "
192364d1cdfbSStephan Mueller 		       "driver %s\n", driver);
192464d1cdfbSStephan Mueller 		goto outbuf;
192564d1cdfbSStephan Mueller 	}
192664d1cdfbSStephan Mueller 
192764d1cdfbSStephan Mueller 	ret = memcmp(test->expected, buf, test->expectedlen);
192864d1cdfbSStephan Mueller 
192964d1cdfbSStephan Mueller outbuf:
193064d1cdfbSStephan Mueller 	crypto_free_rng(drng);
193164d1cdfbSStephan Mueller 	kzfree(buf);
193264d1cdfbSStephan Mueller 	return ret;
193364d1cdfbSStephan Mueller }
193464d1cdfbSStephan Mueller 
193564d1cdfbSStephan Mueller 
193664d1cdfbSStephan Mueller static int alg_test_drbg(const struct alg_test_desc *desc, const char *driver,
193764d1cdfbSStephan Mueller 			 u32 type, u32 mask)
193864d1cdfbSStephan Mueller {
193964d1cdfbSStephan Mueller 	int err = 0;
194064d1cdfbSStephan Mueller 	int pr = 0;
194164d1cdfbSStephan Mueller 	int i = 0;
194264d1cdfbSStephan Mueller 	struct drbg_testvec *template = desc->suite.drbg.vecs;
194364d1cdfbSStephan Mueller 	unsigned int tcount = desc->suite.drbg.count;
194464d1cdfbSStephan Mueller 
194564d1cdfbSStephan Mueller 	if (0 == memcmp(driver, "drbg_pr_", 8))
194664d1cdfbSStephan Mueller 		pr = 1;
194764d1cdfbSStephan Mueller 
194864d1cdfbSStephan Mueller 	for (i = 0; i < tcount; i++) {
194964d1cdfbSStephan Mueller 		err = drbg_cavs_test(&template[i], pr, driver, type, mask);
195064d1cdfbSStephan Mueller 		if (err) {
195164d1cdfbSStephan Mueller 			printk(KERN_ERR "alg: drbg: Test %d failed for %s\n",
195264d1cdfbSStephan Mueller 			       i, driver);
195364d1cdfbSStephan Mueller 			err = -EINVAL;
195464d1cdfbSStephan Mueller 			break;
195564d1cdfbSStephan Mueller 		}
195664d1cdfbSStephan Mueller 	}
195764d1cdfbSStephan Mueller 	return err;
195864d1cdfbSStephan Mueller 
195964d1cdfbSStephan Mueller }
196064d1cdfbSStephan Mueller 
1961802c7f1cSSalvatore Benedetto static int do_test_kpp(struct crypto_kpp *tfm, struct kpp_testvec *vec,
1962802c7f1cSSalvatore Benedetto 		       const char *alg)
1963802c7f1cSSalvatore Benedetto {
1964802c7f1cSSalvatore Benedetto 	struct kpp_request *req;
1965802c7f1cSSalvatore Benedetto 	void *input_buf = NULL;
1966802c7f1cSSalvatore Benedetto 	void *output_buf = NULL;
1967802c7f1cSSalvatore Benedetto 	struct tcrypt_result result;
1968802c7f1cSSalvatore Benedetto 	unsigned int out_len_max;
1969802c7f1cSSalvatore Benedetto 	int err = -ENOMEM;
1970802c7f1cSSalvatore Benedetto 	struct scatterlist src, dst;
1971802c7f1cSSalvatore Benedetto 
1972802c7f1cSSalvatore Benedetto 	req = kpp_request_alloc(tfm, GFP_KERNEL);
1973802c7f1cSSalvatore Benedetto 	if (!req)
1974802c7f1cSSalvatore Benedetto 		return err;
1975802c7f1cSSalvatore Benedetto 
1976802c7f1cSSalvatore Benedetto 	init_completion(&result.completion);
1977802c7f1cSSalvatore Benedetto 
1978802c7f1cSSalvatore Benedetto 	err = crypto_kpp_set_secret(tfm, vec->secret, vec->secret_size);
1979802c7f1cSSalvatore Benedetto 	if (err < 0)
1980802c7f1cSSalvatore Benedetto 		goto free_req;
1981802c7f1cSSalvatore Benedetto 
1982802c7f1cSSalvatore Benedetto 	out_len_max = crypto_kpp_maxsize(tfm);
1983802c7f1cSSalvatore Benedetto 	output_buf = kzalloc(out_len_max, GFP_KERNEL);
1984802c7f1cSSalvatore Benedetto 	if (!output_buf) {
1985802c7f1cSSalvatore Benedetto 		err = -ENOMEM;
1986802c7f1cSSalvatore Benedetto 		goto free_req;
1987802c7f1cSSalvatore Benedetto 	}
1988802c7f1cSSalvatore Benedetto 
1989802c7f1cSSalvatore Benedetto 	/* Use appropriate parameter as base */
1990802c7f1cSSalvatore Benedetto 	kpp_request_set_input(req, NULL, 0);
1991802c7f1cSSalvatore Benedetto 	sg_init_one(&dst, output_buf, out_len_max);
1992802c7f1cSSalvatore Benedetto 	kpp_request_set_output(req, &dst, out_len_max);
1993802c7f1cSSalvatore Benedetto 	kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
1994802c7f1cSSalvatore Benedetto 				 tcrypt_complete, &result);
1995802c7f1cSSalvatore Benedetto 
1996802c7f1cSSalvatore Benedetto 	/* Compute public key */
1997802c7f1cSSalvatore Benedetto 	err = wait_async_op(&result, crypto_kpp_generate_public_key(req));
1998802c7f1cSSalvatore Benedetto 	if (err) {
1999802c7f1cSSalvatore Benedetto 		pr_err("alg: %s: generate public key test failed. err %d\n",
2000802c7f1cSSalvatore Benedetto 		       alg, err);
2001802c7f1cSSalvatore Benedetto 		goto free_output;
2002802c7f1cSSalvatore Benedetto 	}
2003802c7f1cSSalvatore Benedetto 	/* Verify calculated public key */
2004802c7f1cSSalvatore Benedetto 	if (memcmp(vec->expected_a_public, sg_virt(req->dst),
2005802c7f1cSSalvatore Benedetto 		   vec->expected_a_public_size)) {
2006802c7f1cSSalvatore Benedetto 		pr_err("alg: %s: generate public key test failed. Invalid output\n",
2007802c7f1cSSalvatore Benedetto 		       alg);
2008802c7f1cSSalvatore Benedetto 		err = -EINVAL;
2009802c7f1cSSalvatore Benedetto 		goto free_output;
2010802c7f1cSSalvatore Benedetto 	}
2011802c7f1cSSalvatore Benedetto 
2012802c7f1cSSalvatore Benedetto 	/* Calculate shared secret key by using counter part (b) public key. */
2013802c7f1cSSalvatore Benedetto 	input_buf = kzalloc(vec->b_public_size, GFP_KERNEL);
2014802c7f1cSSalvatore Benedetto 	if (!input_buf) {
2015802c7f1cSSalvatore Benedetto 		err = -ENOMEM;
2016802c7f1cSSalvatore Benedetto 		goto free_output;
2017802c7f1cSSalvatore Benedetto 	}
2018802c7f1cSSalvatore Benedetto 
2019802c7f1cSSalvatore Benedetto 	memcpy(input_buf, vec->b_public, vec->b_public_size);
2020802c7f1cSSalvatore Benedetto 	sg_init_one(&src, input_buf, vec->b_public_size);
2021802c7f1cSSalvatore Benedetto 	sg_init_one(&dst, output_buf, out_len_max);
2022802c7f1cSSalvatore Benedetto 	kpp_request_set_input(req, &src, vec->b_public_size);
2023802c7f1cSSalvatore Benedetto 	kpp_request_set_output(req, &dst, out_len_max);
2024802c7f1cSSalvatore Benedetto 	kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
2025802c7f1cSSalvatore Benedetto 				 tcrypt_complete, &result);
2026802c7f1cSSalvatore Benedetto 	err = wait_async_op(&result, crypto_kpp_compute_shared_secret(req));
2027802c7f1cSSalvatore Benedetto 	if (err) {
2028802c7f1cSSalvatore Benedetto 		pr_err("alg: %s: compute shard secret test failed. err %d\n",
2029802c7f1cSSalvatore Benedetto 		       alg, err);
2030802c7f1cSSalvatore Benedetto 		goto free_all;
2031802c7f1cSSalvatore Benedetto 	}
2032802c7f1cSSalvatore Benedetto 	/*
2033802c7f1cSSalvatore Benedetto 	 * verify shared secret from which the user will derive
2034802c7f1cSSalvatore Benedetto 	 * secret key by executing whatever hash it has chosen
2035802c7f1cSSalvatore Benedetto 	 */
2036802c7f1cSSalvatore Benedetto 	if (memcmp(vec->expected_ss, sg_virt(req->dst),
2037802c7f1cSSalvatore Benedetto 		   vec->expected_ss_size)) {
2038802c7f1cSSalvatore Benedetto 		pr_err("alg: %s: compute shared secret test failed. Invalid output\n",
2039802c7f1cSSalvatore Benedetto 		       alg);
2040802c7f1cSSalvatore Benedetto 		err = -EINVAL;
2041802c7f1cSSalvatore Benedetto 	}
2042802c7f1cSSalvatore Benedetto 
2043802c7f1cSSalvatore Benedetto free_all:
2044802c7f1cSSalvatore Benedetto 	kfree(input_buf);
2045802c7f1cSSalvatore Benedetto free_output:
2046802c7f1cSSalvatore Benedetto 	kfree(output_buf);
2047802c7f1cSSalvatore Benedetto free_req:
2048802c7f1cSSalvatore Benedetto 	kpp_request_free(req);
2049802c7f1cSSalvatore Benedetto 	return err;
2050802c7f1cSSalvatore Benedetto }
2051802c7f1cSSalvatore Benedetto 
2052802c7f1cSSalvatore Benedetto static int test_kpp(struct crypto_kpp *tfm, const char *alg,
2053802c7f1cSSalvatore Benedetto 		    struct kpp_testvec *vecs, unsigned int tcount)
2054802c7f1cSSalvatore Benedetto {
2055802c7f1cSSalvatore Benedetto 	int ret, i;
2056802c7f1cSSalvatore Benedetto 
2057802c7f1cSSalvatore Benedetto 	for (i = 0; i < tcount; i++) {
2058802c7f1cSSalvatore Benedetto 		ret = do_test_kpp(tfm, vecs++, alg);
2059802c7f1cSSalvatore Benedetto 		if (ret) {
2060802c7f1cSSalvatore Benedetto 			pr_err("alg: %s: test failed on vector %d, err=%d\n",
2061802c7f1cSSalvatore Benedetto 			       alg, i + 1, ret);
2062802c7f1cSSalvatore Benedetto 			return ret;
2063802c7f1cSSalvatore Benedetto 		}
2064802c7f1cSSalvatore Benedetto 	}
2065802c7f1cSSalvatore Benedetto 	return 0;
2066802c7f1cSSalvatore Benedetto }
2067802c7f1cSSalvatore Benedetto 
2068802c7f1cSSalvatore Benedetto static int alg_test_kpp(const struct alg_test_desc *desc, const char *driver,
2069802c7f1cSSalvatore Benedetto 			u32 type, u32 mask)
2070802c7f1cSSalvatore Benedetto {
2071802c7f1cSSalvatore Benedetto 	struct crypto_kpp *tfm;
2072802c7f1cSSalvatore Benedetto 	int err = 0;
2073802c7f1cSSalvatore Benedetto 
2074eed93e0cSHerbert Xu 	tfm = crypto_alloc_kpp(driver, type, mask);
2075802c7f1cSSalvatore Benedetto 	if (IS_ERR(tfm)) {
2076802c7f1cSSalvatore Benedetto 		pr_err("alg: kpp: Failed to load tfm for %s: %ld\n",
2077802c7f1cSSalvatore Benedetto 		       driver, PTR_ERR(tfm));
2078802c7f1cSSalvatore Benedetto 		return PTR_ERR(tfm);
2079802c7f1cSSalvatore Benedetto 	}
2080802c7f1cSSalvatore Benedetto 	if (desc->suite.kpp.vecs)
2081802c7f1cSSalvatore Benedetto 		err = test_kpp(tfm, desc->alg, desc->suite.kpp.vecs,
2082802c7f1cSSalvatore Benedetto 			       desc->suite.kpp.count);
2083802c7f1cSSalvatore Benedetto 
2084802c7f1cSSalvatore Benedetto 	crypto_free_kpp(tfm);
2085802c7f1cSSalvatore Benedetto 	return err;
2086802c7f1cSSalvatore Benedetto }
2087802c7f1cSSalvatore Benedetto 
208850d2b643SHerbert Xu static int test_akcipher_one(struct crypto_akcipher *tfm,
2089946cc463STadeusz Struk 			     struct akcipher_testvec *vecs)
2090946cc463STadeusz Struk {
2091df27b26fSHerbert Xu 	char *xbuf[XBUFSIZE];
2092946cc463STadeusz Struk 	struct akcipher_request *req;
2093946cc463STadeusz Struk 	void *outbuf_enc = NULL;
2094946cc463STadeusz Struk 	void *outbuf_dec = NULL;
2095946cc463STadeusz Struk 	struct tcrypt_result result;
2096946cc463STadeusz Struk 	unsigned int out_len_max, out_len = 0;
2097946cc463STadeusz Struk 	int err = -ENOMEM;
209822287b0bSTadeusz Struk 	struct scatterlist src, dst, src_tab[2];
2099946cc463STadeusz Struk 
2100df27b26fSHerbert Xu 	if (testmgr_alloc_buf(xbuf))
2101df27b26fSHerbert Xu 		return err;
2102df27b26fSHerbert Xu 
2103946cc463STadeusz Struk 	req = akcipher_request_alloc(tfm, GFP_KERNEL);
2104946cc463STadeusz Struk 	if (!req)
2105df27b26fSHerbert Xu 		goto free_xbuf;
2106946cc463STadeusz Struk 
2107946cc463STadeusz Struk 	init_completion(&result.completion);
210822287b0bSTadeusz Struk 
210922287b0bSTadeusz Struk 	if (vecs->public_key_vec)
211022287b0bSTadeusz Struk 		err = crypto_akcipher_set_pub_key(tfm, vecs->key,
211122287b0bSTadeusz Struk 						  vecs->key_len);
211222287b0bSTadeusz Struk 	else
211322287b0bSTadeusz Struk 		err = crypto_akcipher_set_priv_key(tfm, vecs->key,
211422287b0bSTadeusz Struk 						   vecs->key_len);
2115946cc463STadeusz Struk 	if (err)
2116946cc463STadeusz Struk 		goto free_req;
2117946cc463STadeusz Struk 
211857763f5eSSalvatore Benedetto 	err = -ENOMEM;
211922287b0bSTadeusz Struk 	out_len_max = crypto_akcipher_maxsize(tfm);
2120946cc463STadeusz Struk 	outbuf_enc = kzalloc(out_len_max, GFP_KERNEL);
2121946cc463STadeusz Struk 	if (!outbuf_enc)
2122946cc463STadeusz Struk 		goto free_req;
2123946cc463STadeusz Struk 
2124df27b26fSHerbert Xu 	if (WARN_ON(vecs->m_size > PAGE_SIZE))
2125df27b26fSHerbert Xu 		goto free_all;
2126df27b26fSHerbert Xu 
2127df27b26fSHerbert Xu 	memcpy(xbuf[0], vecs->m, vecs->m_size);
2128df27b26fSHerbert Xu 
212922287b0bSTadeusz Struk 	sg_init_table(src_tab, 2);
2130df27b26fSHerbert Xu 	sg_set_buf(&src_tab[0], xbuf[0], 8);
2131df27b26fSHerbert Xu 	sg_set_buf(&src_tab[1], xbuf[0] + 8, vecs->m_size - 8);
213222287b0bSTadeusz Struk 	sg_init_one(&dst, outbuf_enc, out_len_max);
213322287b0bSTadeusz Struk 	akcipher_request_set_crypt(req, src_tab, &dst, vecs->m_size,
213422287b0bSTadeusz Struk 				   out_len_max);
2135946cc463STadeusz Struk 	akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
2136946cc463STadeusz Struk 				      tcrypt_complete, &result);
2137946cc463STadeusz Struk 
2138946cc463STadeusz Struk 	/* Run RSA encrypt - c = m^e mod n;*/
2139946cc463STadeusz Struk 	err = wait_async_op(&result, crypto_akcipher_encrypt(req));
2140946cc463STadeusz Struk 	if (err) {
214150d2b643SHerbert Xu 		pr_err("alg: akcipher: encrypt test failed. err %d\n", err);
2142946cc463STadeusz Struk 		goto free_all;
2143946cc463STadeusz Struk 	}
214422287b0bSTadeusz Struk 	if (req->dst_len != vecs->c_size) {
214550d2b643SHerbert Xu 		pr_err("alg: akcipher: encrypt test failed. Invalid output len\n");
2146946cc463STadeusz Struk 		err = -EINVAL;
2147946cc463STadeusz Struk 		goto free_all;
2148946cc463STadeusz Struk 	}
2149946cc463STadeusz Struk 	/* verify that encrypted message is equal to expected */
2150df27b26fSHerbert Xu 	if (memcmp(vecs->c, outbuf_enc, vecs->c_size)) {
215150d2b643SHerbert Xu 		pr_err("alg: akcipher: encrypt test failed. Invalid output\n");
215250d2b643SHerbert Xu 		hexdump(outbuf_enc, vecs->c_size);
2153946cc463STadeusz Struk 		err = -EINVAL;
2154946cc463STadeusz Struk 		goto free_all;
2155946cc463STadeusz Struk 	}
2156946cc463STadeusz Struk 	/* Don't invoke decrypt for vectors with public key */
2157946cc463STadeusz Struk 	if (vecs->public_key_vec) {
2158946cc463STadeusz Struk 		err = 0;
2159946cc463STadeusz Struk 		goto free_all;
2160946cc463STadeusz Struk 	}
2161946cc463STadeusz Struk 	outbuf_dec = kzalloc(out_len_max, GFP_KERNEL);
2162946cc463STadeusz Struk 	if (!outbuf_dec) {
2163946cc463STadeusz Struk 		err = -ENOMEM;
2164946cc463STadeusz Struk 		goto free_all;
2165946cc463STadeusz Struk 	}
2166df27b26fSHerbert Xu 
2167df27b26fSHerbert Xu 	if (WARN_ON(vecs->c_size > PAGE_SIZE))
2168df27b26fSHerbert Xu 		goto free_all;
2169df27b26fSHerbert Xu 
2170df27b26fSHerbert Xu 	memcpy(xbuf[0], vecs->c, vecs->c_size);
2171df27b26fSHerbert Xu 
2172df27b26fSHerbert Xu 	sg_init_one(&src, xbuf[0], vecs->c_size);
217322287b0bSTadeusz Struk 	sg_init_one(&dst, outbuf_dec, out_len_max);
2174946cc463STadeusz Struk 	init_completion(&result.completion);
217522287b0bSTadeusz Struk 	akcipher_request_set_crypt(req, &src, &dst, vecs->c_size, out_len_max);
2176946cc463STadeusz Struk 
2177946cc463STadeusz Struk 	/* Run RSA decrypt - m = c^d mod n;*/
2178946cc463STadeusz Struk 	err = wait_async_op(&result, crypto_akcipher_decrypt(req));
2179946cc463STadeusz Struk 	if (err) {
218050d2b643SHerbert Xu 		pr_err("alg: akcipher: decrypt test failed. err %d\n", err);
2181946cc463STadeusz Struk 		goto free_all;
2182946cc463STadeusz Struk 	}
2183946cc463STadeusz Struk 	out_len = req->dst_len;
218450d2b643SHerbert Xu 	if (out_len < vecs->m_size) {
218550d2b643SHerbert Xu 		pr_err("alg: akcipher: decrypt test failed. "
218650d2b643SHerbert Xu 		       "Invalid output len %u\n", out_len);
2187946cc463STadeusz Struk 		err = -EINVAL;
2188946cc463STadeusz Struk 		goto free_all;
2189946cc463STadeusz Struk 	}
2190946cc463STadeusz Struk 	/* verify that decrypted message is equal to the original msg */
219150d2b643SHerbert Xu 	if (memchr_inv(outbuf_dec, 0, out_len - vecs->m_size) ||
219250d2b643SHerbert Xu 	    memcmp(vecs->m, outbuf_dec + out_len - vecs->m_size,
219350d2b643SHerbert Xu 		   vecs->m_size)) {
219450d2b643SHerbert Xu 		pr_err("alg: akcipher: decrypt test failed. Invalid output\n");
219550d2b643SHerbert Xu 		hexdump(outbuf_dec, out_len);
2196946cc463STadeusz Struk 		err = -EINVAL;
2197946cc463STadeusz Struk 	}
2198946cc463STadeusz Struk free_all:
2199946cc463STadeusz Struk 	kfree(outbuf_dec);
2200946cc463STadeusz Struk 	kfree(outbuf_enc);
2201946cc463STadeusz Struk free_req:
2202946cc463STadeusz Struk 	akcipher_request_free(req);
2203df27b26fSHerbert Xu free_xbuf:
2204df27b26fSHerbert Xu 	testmgr_free_buf(xbuf);
2205946cc463STadeusz Struk 	return err;
2206946cc463STadeusz Struk }
2207946cc463STadeusz Struk 
220850d2b643SHerbert Xu static int test_akcipher(struct crypto_akcipher *tfm, const char *alg,
220950d2b643SHerbert Xu 			 struct akcipher_testvec *vecs, unsigned int tcount)
2210946cc463STadeusz Struk {
221115226e48SHerbert Xu 	const char *algo =
221215226e48SHerbert Xu 		crypto_tfm_alg_driver_name(crypto_akcipher_tfm(tfm));
2213946cc463STadeusz Struk 	int ret, i;
2214946cc463STadeusz Struk 
2215946cc463STadeusz Struk 	for (i = 0; i < tcount; i++) {
221650d2b643SHerbert Xu 		ret = test_akcipher_one(tfm, vecs++);
221750d2b643SHerbert Xu 		if (!ret)
221850d2b643SHerbert Xu 			continue;
221950d2b643SHerbert Xu 
222015226e48SHerbert Xu 		pr_err("alg: akcipher: test %d failed for %s, err=%d\n",
222115226e48SHerbert Xu 		       i + 1, algo, ret);
2222946cc463STadeusz Struk 		return ret;
2223946cc463STadeusz Struk 	}
2224946cc463STadeusz Struk 	return 0;
2225946cc463STadeusz Struk }
2226946cc463STadeusz Struk 
2227946cc463STadeusz Struk static int alg_test_akcipher(const struct alg_test_desc *desc,
2228946cc463STadeusz Struk 			     const char *driver, u32 type, u32 mask)
2229946cc463STadeusz Struk {
2230946cc463STadeusz Struk 	struct crypto_akcipher *tfm;
2231946cc463STadeusz Struk 	int err = 0;
2232946cc463STadeusz Struk 
2233eed93e0cSHerbert Xu 	tfm = crypto_alloc_akcipher(driver, type, mask);
2234946cc463STadeusz Struk 	if (IS_ERR(tfm)) {
2235946cc463STadeusz Struk 		pr_err("alg: akcipher: Failed to load tfm for %s: %ld\n",
2236946cc463STadeusz Struk 		       driver, PTR_ERR(tfm));
2237946cc463STadeusz Struk 		return PTR_ERR(tfm);
2238946cc463STadeusz Struk 	}
2239946cc463STadeusz Struk 	if (desc->suite.akcipher.vecs)
2240946cc463STadeusz Struk 		err = test_akcipher(tfm, desc->alg, desc->suite.akcipher.vecs,
2241946cc463STadeusz Struk 				    desc->suite.akcipher.count);
2242946cc463STadeusz Struk 
2243946cc463STadeusz Struk 	crypto_free_akcipher(tfm);
2244946cc463STadeusz Struk 	return err;
2245946cc463STadeusz Struk }
2246946cc463STadeusz Struk 
2247863b557aSYouquan, Song static int alg_test_null(const struct alg_test_desc *desc,
2248863b557aSYouquan, Song 			     const char *driver, u32 type, u32 mask)
2249863b557aSYouquan, Song {
2250863b557aSYouquan, Song 	return 0;
2251863b557aSYouquan, Song }
2252863b557aSYouquan, Song 
225321c8e720SArd Biesheuvel #define __VECS(tv)	{ .vecs = tv, .count = ARRAY_SIZE(tv) }
225421c8e720SArd Biesheuvel 
2255da7f033dSHerbert Xu /* Please keep this list sorted by algorithm name. */
2256da7f033dSHerbert Xu static const struct alg_test_desc alg_test_descs[] = {
2257da7f033dSHerbert Xu 	{
2258e08ca2daSJarod Wilson 		.alg = "ansi_cprng",
2259e08ca2daSJarod Wilson 		.test = alg_test_cprng,
2260e08ca2daSJarod Wilson 		.suite = {
226121c8e720SArd Biesheuvel 			.cprng = __VECS(ansi_cprng_aes_tv_template)
2262e08ca2daSJarod Wilson 		}
2263e08ca2daSJarod Wilson 	}, {
2264bca4feb0SHoria Geanta 		.alg = "authenc(hmac(md5),ecb(cipher_null))",
2265bca4feb0SHoria Geanta 		.test = alg_test_aead,
2266bca4feb0SHoria Geanta 		.suite = {
2267bca4feb0SHoria Geanta 			.aead = {
226821c8e720SArd Biesheuvel 				.enc = __VECS(hmac_md5_ecb_cipher_null_enc_tv_template),
226921c8e720SArd Biesheuvel 				.dec = __VECS(hmac_md5_ecb_cipher_null_dec_tv_template)
2270bca4feb0SHoria Geanta 			}
2271bca4feb0SHoria Geanta 		}
2272bca4feb0SHoria Geanta 	}, {
2273a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha1),cbc(aes))",
2274e46e9a46SHoria Geanta 		.test = alg_test_aead,
2275e46e9a46SHoria Geanta 		.suite = {
2276e46e9a46SHoria Geanta 			.aead = {
227721c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha1_aes_cbc_enc_tv_temp)
22785208ed2cSNitesh Lal 			}
22795208ed2cSNitesh Lal 		}
22805208ed2cSNitesh Lal 	}, {
2281a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha1),cbc(des))",
22825208ed2cSNitesh Lal 		.test = alg_test_aead,
22835208ed2cSNitesh Lal 		.suite = {
22845208ed2cSNitesh Lal 			.aead = {
228521c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha1_des_cbc_enc_tv_temp)
22865208ed2cSNitesh Lal 			}
22875208ed2cSNitesh Lal 		}
22885208ed2cSNitesh Lal 	}, {
2289a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha1),cbc(des3_ede))",
22905208ed2cSNitesh Lal 		.test = alg_test_aead,
2291ed1afac9SMarcus Meissner 		.fips_allowed = 1,
22925208ed2cSNitesh Lal 		.suite = {
22935208ed2cSNitesh Lal 			.aead = {
229421c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha1_des3_ede_cbc_enc_tv_temp)
2295e46e9a46SHoria Geanta 			}
2296e46e9a46SHoria Geanta 		}
2297e46e9a46SHoria Geanta 	}, {
2298fb16abc2SMarcus Meissner 		.alg = "authenc(hmac(sha1),ctr(aes))",
2299fb16abc2SMarcus Meissner 		.test = alg_test_null,
2300fb16abc2SMarcus Meissner 		.fips_allowed = 1,
2301fb16abc2SMarcus Meissner 	}, {
2302bca4feb0SHoria Geanta 		.alg = "authenc(hmac(sha1),ecb(cipher_null))",
2303bca4feb0SHoria Geanta 		.test = alg_test_aead,
2304bca4feb0SHoria Geanta 		.suite = {
2305bca4feb0SHoria Geanta 			.aead = {
230621c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha1_ecb_cipher_null_enc_tv_temp),
230721c8e720SArd Biesheuvel 				.dec = __VECS(hmac_sha1_ecb_cipher_null_dec_tv_temp)
23085208ed2cSNitesh Lal 			}
23095208ed2cSNitesh Lal 		}
23105208ed2cSNitesh Lal 	}, {
23118888690eSMarcus Meissner 		.alg = "authenc(hmac(sha1),rfc3686(ctr(aes)))",
23128888690eSMarcus Meissner 		.test = alg_test_null,
23138888690eSMarcus Meissner 		.fips_allowed = 1,
23148888690eSMarcus Meissner 	}, {
2315a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha224),cbc(des))",
23165208ed2cSNitesh Lal 		.test = alg_test_aead,
23175208ed2cSNitesh Lal 		.suite = {
23185208ed2cSNitesh Lal 			.aead = {
231921c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha224_des_cbc_enc_tv_temp)
23205208ed2cSNitesh Lal 			}
23215208ed2cSNitesh Lal 		}
23225208ed2cSNitesh Lal 	}, {
2323a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha224),cbc(des3_ede))",
23245208ed2cSNitesh Lal 		.test = alg_test_aead,
2325ed1afac9SMarcus Meissner 		.fips_allowed = 1,
23265208ed2cSNitesh Lal 		.suite = {
23275208ed2cSNitesh Lal 			.aead = {
232821c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha224_des3_ede_cbc_enc_tv_temp)
2329bca4feb0SHoria Geanta 			}
2330bca4feb0SHoria Geanta 		}
2331bca4feb0SHoria Geanta 	}, {
2332a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha256),cbc(aes))",
2333e46e9a46SHoria Geanta 		.test = alg_test_aead,
2334ed1afac9SMarcus Meissner 		.fips_allowed = 1,
2335e46e9a46SHoria Geanta 		.suite = {
2336e46e9a46SHoria Geanta 			.aead = {
233721c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha256_aes_cbc_enc_tv_temp)
23385208ed2cSNitesh Lal 			}
23395208ed2cSNitesh Lal 		}
23405208ed2cSNitesh Lal 	}, {
2341a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha256),cbc(des))",
23425208ed2cSNitesh Lal 		.test = alg_test_aead,
23435208ed2cSNitesh Lal 		.suite = {
23445208ed2cSNitesh Lal 			.aead = {
234521c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha256_des_cbc_enc_tv_temp)
23465208ed2cSNitesh Lal 			}
23475208ed2cSNitesh Lal 		}
23485208ed2cSNitesh Lal 	}, {
2349a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha256),cbc(des3_ede))",
23505208ed2cSNitesh Lal 		.test = alg_test_aead,
2351ed1afac9SMarcus Meissner 		.fips_allowed = 1,
23525208ed2cSNitesh Lal 		.suite = {
23535208ed2cSNitesh Lal 			.aead = {
235421c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha256_des3_ede_cbc_enc_tv_temp)
23555208ed2cSNitesh Lal 			}
23565208ed2cSNitesh Lal 		}
23575208ed2cSNitesh Lal 	}, {
2358fb16abc2SMarcus Meissner 		.alg = "authenc(hmac(sha256),ctr(aes))",
2359fb16abc2SMarcus Meissner 		.test = alg_test_null,
2360fb16abc2SMarcus Meissner 		.fips_allowed = 1,
2361fb16abc2SMarcus Meissner 	}, {
23628888690eSMarcus Meissner 		.alg = "authenc(hmac(sha256),rfc3686(ctr(aes)))",
23638888690eSMarcus Meissner 		.test = alg_test_null,
23648888690eSMarcus Meissner 		.fips_allowed = 1,
23658888690eSMarcus Meissner 	}, {
2366a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha384),cbc(des))",
23675208ed2cSNitesh Lal 		.test = alg_test_aead,
23685208ed2cSNitesh Lal 		.suite = {
23695208ed2cSNitesh Lal 			.aead = {
237021c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha384_des_cbc_enc_tv_temp)
23715208ed2cSNitesh Lal 			}
23725208ed2cSNitesh Lal 		}
23735208ed2cSNitesh Lal 	}, {
2374a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha384),cbc(des3_ede))",
23755208ed2cSNitesh Lal 		.test = alg_test_aead,
2376ed1afac9SMarcus Meissner 		.fips_allowed = 1,
23775208ed2cSNitesh Lal 		.suite = {
23785208ed2cSNitesh Lal 			.aead = {
237921c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha384_des3_ede_cbc_enc_tv_temp)
2380e46e9a46SHoria Geanta 			}
2381e46e9a46SHoria Geanta 		}
2382e46e9a46SHoria Geanta 	}, {
2383fb16abc2SMarcus Meissner 		.alg = "authenc(hmac(sha384),ctr(aes))",
2384fb16abc2SMarcus Meissner 		.test = alg_test_null,
2385fb16abc2SMarcus Meissner 		.fips_allowed = 1,
2386fb16abc2SMarcus Meissner 	}, {
23878888690eSMarcus Meissner 		.alg = "authenc(hmac(sha384),rfc3686(ctr(aes)))",
23888888690eSMarcus Meissner 		.test = alg_test_null,
23898888690eSMarcus Meissner 		.fips_allowed = 1,
23908888690eSMarcus Meissner 	}, {
2391a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha512),cbc(aes))",
2392ed1afac9SMarcus Meissner 		.fips_allowed = 1,
2393e46e9a46SHoria Geanta 		.test = alg_test_aead,
2394e46e9a46SHoria Geanta 		.suite = {
2395e46e9a46SHoria Geanta 			.aead = {
239621c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha512_aes_cbc_enc_tv_temp)
23975208ed2cSNitesh Lal 			}
23985208ed2cSNitesh Lal 		}
23995208ed2cSNitesh Lal 	}, {
2400a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha512),cbc(des))",
24015208ed2cSNitesh Lal 		.test = alg_test_aead,
24025208ed2cSNitesh Lal 		.suite = {
24035208ed2cSNitesh Lal 			.aead = {
240421c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha512_des_cbc_enc_tv_temp)
24055208ed2cSNitesh Lal 			}
24065208ed2cSNitesh Lal 		}
24075208ed2cSNitesh Lal 	}, {
2408a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha512),cbc(des3_ede))",
24095208ed2cSNitesh Lal 		.test = alg_test_aead,
2410ed1afac9SMarcus Meissner 		.fips_allowed = 1,
24115208ed2cSNitesh Lal 		.suite = {
24125208ed2cSNitesh Lal 			.aead = {
241321c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha512_des3_ede_cbc_enc_tv_temp)
2414e46e9a46SHoria Geanta 			}
2415e46e9a46SHoria Geanta 		}
2416e46e9a46SHoria Geanta 	}, {
2417fb16abc2SMarcus Meissner 		.alg = "authenc(hmac(sha512),ctr(aes))",
2418fb16abc2SMarcus Meissner 		.test = alg_test_null,
2419fb16abc2SMarcus Meissner 		.fips_allowed = 1,
2420fb16abc2SMarcus Meissner 	}, {
24218888690eSMarcus Meissner 		.alg = "authenc(hmac(sha512),rfc3686(ctr(aes)))",
24228888690eSMarcus Meissner 		.test = alg_test_null,
24238888690eSMarcus Meissner 		.fips_allowed = 1,
24248888690eSMarcus Meissner 	}, {
2425da7f033dSHerbert Xu 		.alg = "cbc(aes)",
24261aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2427a1915d51SJarod Wilson 		.fips_allowed = 1,
2428da7f033dSHerbert Xu 		.suite = {
2429da7f033dSHerbert Xu 			.cipher = {
243021c8e720SArd Biesheuvel 				.enc = __VECS(aes_cbc_enc_tv_template),
243121c8e720SArd Biesheuvel 				.dec = __VECS(aes_cbc_dec_tv_template)
2432da7f033dSHerbert Xu 			}
2433da7f033dSHerbert Xu 		}
2434da7f033dSHerbert Xu 	}, {
2435da7f033dSHerbert Xu 		.alg = "cbc(anubis)",
24361aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2437da7f033dSHerbert Xu 		.suite = {
2438da7f033dSHerbert Xu 			.cipher = {
243921c8e720SArd Biesheuvel 				.enc = __VECS(anubis_cbc_enc_tv_template),
244021c8e720SArd Biesheuvel 				.dec = __VECS(anubis_cbc_dec_tv_template)
2441da7f033dSHerbert Xu 			}
2442da7f033dSHerbert Xu 		}
2443da7f033dSHerbert Xu 	}, {
2444da7f033dSHerbert Xu 		.alg = "cbc(blowfish)",
24451aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2446da7f033dSHerbert Xu 		.suite = {
2447da7f033dSHerbert Xu 			.cipher = {
244821c8e720SArd Biesheuvel 				.enc = __VECS(bf_cbc_enc_tv_template),
244921c8e720SArd Biesheuvel 				.dec = __VECS(bf_cbc_dec_tv_template)
2450da7f033dSHerbert Xu 			}
2451da7f033dSHerbert Xu 		}
2452da7f033dSHerbert Xu 	}, {
2453da7f033dSHerbert Xu 		.alg = "cbc(camellia)",
24541aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2455da7f033dSHerbert Xu 		.suite = {
2456da7f033dSHerbert Xu 			.cipher = {
245721c8e720SArd Biesheuvel 				.enc = __VECS(camellia_cbc_enc_tv_template),
245821c8e720SArd Biesheuvel 				.dec = __VECS(camellia_cbc_dec_tv_template)
2459da7f033dSHerbert Xu 			}
2460da7f033dSHerbert Xu 		}
2461da7f033dSHerbert Xu 	}, {
2462a2c58260SJohannes Goetzfried 		.alg = "cbc(cast5)",
2463a2c58260SJohannes Goetzfried 		.test = alg_test_skcipher,
2464a2c58260SJohannes Goetzfried 		.suite = {
2465a2c58260SJohannes Goetzfried 			.cipher = {
246621c8e720SArd Biesheuvel 				.enc = __VECS(cast5_cbc_enc_tv_template),
246721c8e720SArd Biesheuvel 				.dec = __VECS(cast5_cbc_dec_tv_template)
2468a2c58260SJohannes Goetzfried 			}
2469a2c58260SJohannes Goetzfried 		}
2470a2c58260SJohannes Goetzfried 	}, {
24719b8b0405SJohannes Goetzfried 		.alg = "cbc(cast6)",
24729b8b0405SJohannes Goetzfried 		.test = alg_test_skcipher,
24739b8b0405SJohannes Goetzfried 		.suite = {
24749b8b0405SJohannes Goetzfried 			.cipher = {
247521c8e720SArd Biesheuvel 				.enc = __VECS(cast6_cbc_enc_tv_template),
247621c8e720SArd Biesheuvel 				.dec = __VECS(cast6_cbc_dec_tv_template)
24779b8b0405SJohannes Goetzfried 			}
24789b8b0405SJohannes Goetzfried 		}
24799b8b0405SJohannes Goetzfried 	}, {
2480da7f033dSHerbert Xu 		.alg = "cbc(des)",
24811aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2482da7f033dSHerbert Xu 		.suite = {
2483da7f033dSHerbert Xu 			.cipher = {
248421c8e720SArd Biesheuvel 				.enc = __VECS(des_cbc_enc_tv_template),
248521c8e720SArd Biesheuvel 				.dec = __VECS(des_cbc_dec_tv_template)
2486da7f033dSHerbert Xu 			}
2487da7f033dSHerbert Xu 		}
2488da7f033dSHerbert Xu 	}, {
2489da7f033dSHerbert Xu 		.alg = "cbc(des3_ede)",
24901aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2491a1915d51SJarod Wilson 		.fips_allowed = 1,
2492da7f033dSHerbert Xu 		.suite = {
2493da7f033dSHerbert Xu 			.cipher = {
249421c8e720SArd Biesheuvel 				.enc = __VECS(des3_ede_cbc_enc_tv_template),
249521c8e720SArd Biesheuvel 				.dec = __VECS(des3_ede_cbc_dec_tv_template)
2496da7f033dSHerbert Xu 			}
2497da7f033dSHerbert Xu 		}
2498da7f033dSHerbert Xu 	}, {
24999d25917dSJussi Kivilinna 		.alg = "cbc(serpent)",
25009d25917dSJussi Kivilinna 		.test = alg_test_skcipher,
25019d25917dSJussi Kivilinna 		.suite = {
25029d25917dSJussi Kivilinna 			.cipher = {
250321c8e720SArd Biesheuvel 				.enc = __VECS(serpent_cbc_enc_tv_template),
250421c8e720SArd Biesheuvel 				.dec = __VECS(serpent_cbc_dec_tv_template)
25059d25917dSJussi Kivilinna 			}
25069d25917dSJussi Kivilinna 		}
25079d25917dSJussi Kivilinna 	}, {
2508da7f033dSHerbert Xu 		.alg = "cbc(twofish)",
25091aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2510da7f033dSHerbert Xu 		.suite = {
2511da7f033dSHerbert Xu 			.cipher = {
251221c8e720SArd Biesheuvel 				.enc = __VECS(tf_cbc_enc_tv_template),
251321c8e720SArd Biesheuvel 				.dec = __VECS(tf_cbc_dec_tv_template)
2514da7f033dSHerbert Xu 			}
2515da7f033dSHerbert Xu 		}
2516da7f033dSHerbert Xu 	}, {
2517092acf06SArd Biesheuvel 		.alg = "cbcmac(aes)",
2518092acf06SArd Biesheuvel 		.fips_allowed = 1,
2519092acf06SArd Biesheuvel 		.test = alg_test_hash,
2520092acf06SArd Biesheuvel 		.suite = {
2521092acf06SArd Biesheuvel 			.hash = __VECS(aes_cbcmac_tv_template)
2522092acf06SArd Biesheuvel 		}
2523092acf06SArd Biesheuvel 	}, {
2524da7f033dSHerbert Xu 		.alg = "ccm(aes)",
2525da7f033dSHerbert Xu 		.test = alg_test_aead,
2526a1915d51SJarod Wilson 		.fips_allowed = 1,
2527da7f033dSHerbert Xu 		.suite = {
2528da7f033dSHerbert Xu 			.aead = {
252921c8e720SArd Biesheuvel 				.enc = __VECS(aes_ccm_enc_tv_template),
253021c8e720SArd Biesheuvel 				.dec = __VECS(aes_ccm_dec_tv_template)
2531da7f033dSHerbert Xu 			}
2532da7f033dSHerbert Xu 		}
2533da7f033dSHerbert Xu 	}, {
25343590ebf2SMartin Willi 		.alg = "chacha20",
25353590ebf2SMartin Willi 		.test = alg_test_skcipher,
25363590ebf2SMartin Willi 		.suite = {
25373590ebf2SMartin Willi 			.cipher = {
253821c8e720SArd Biesheuvel 				.enc = __VECS(chacha20_enc_tv_template),
253921c8e720SArd Biesheuvel 				.dec = __VECS(chacha20_enc_tv_template),
25403590ebf2SMartin Willi 			}
25413590ebf2SMartin Willi 		}
25423590ebf2SMartin Willi 	}, {
254393b5e86aSJussi Kivilinna 		.alg = "cmac(aes)",
25448f183751SStephan Mueller 		.fips_allowed = 1,
254593b5e86aSJussi Kivilinna 		.test = alg_test_hash,
254693b5e86aSJussi Kivilinna 		.suite = {
254721c8e720SArd Biesheuvel 			.hash = __VECS(aes_cmac128_tv_template)
254893b5e86aSJussi Kivilinna 		}
254993b5e86aSJussi Kivilinna 	}, {
255093b5e86aSJussi Kivilinna 		.alg = "cmac(des3_ede)",
25518f183751SStephan Mueller 		.fips_allowed = 1,
255293b5e86aSJussi Kivilinna 		.test = alg_test_hash,
255393b5e86aSJussi Kivilinna 		.suite = {
255421c8e720SArd Biesheuvel 			.hash = __VECS(des3_ede_cmac64_tv_template)
255593b5e86aSJussi Kivilinna 		}
255693b5e86aSJussi Kivilinna 	}, {
2557e448370dSJussi Kivilinna 		.alg = "compress_null",
2558e448370dSJussi Kivilinna 		.test = alg_test_null,
2559e448370dSJussi Kivilinna 	}, {
2560ebb3472fSArd Biesheuvel 		.alg = "crc32",
2561ebb3472fSArd Biesheuvel 		.test = alg_test_hash,
2562ebb3472fSArd Biesheuvel 		.suite = {
256321c8e720SArd Biesheuvel 			.hash = __VECS(crc32_tv_template)
2564ebb3472fSArd Biesheuvel 		}
2565ebb3472fSArd Biesheuvel 	}, {
2566da7f033dSHerbert Xu 		.alg = "crc32c",
25678e3ee85eSHerbert Xu 		.test = alg_test_crc32c,
2568a1915d51SJarod Wilson 		.fips_allowed = 1,
2569da7f033dSHerbert Xu 		.suite = {
257021c8e720SArd Biesheuvel 			.hash = __VECS(crc32c_tv_template)
2571da7f033dSHerbert Xu 		}
2572da7f033dSHerbert Xu 	}, {
257368411521SHerbert Xu 		.alg = "crct10dif",
257468411521SHerbert Xu 		.test = alg_test_hash,
257568411521SHerbert Xu 		.fips_allowed = 1,
257668411521SHerbert Xu 		.suite = {
257721c8e720SArd Biesheuvel 			.hash = __VECS(crct10dif_tv_template)
257868411521SHerbert Xu 		}
257968411521SHerbert Xu 	}, {
2580f7cb80f2SJarod Wilson 		.alg = "ctr(aes)",
2581f7cb80f2SJarod Wilson 		.test = alg_test_skcipher,
2582a1915d51SJarod Wilson 		.fips_allowed = 1,
2583f7cb80f2SJarod Wilson 		.suite = {
2584f7cb80f2SJarod Wilson 			.cipher = {
258521c8e720SArd Biesheuvel 				.enc = __VECS(aes_ctr_enc_tv_template),
258621c8e720SArd Biesheuvel 				.dec = __VECS(aes_ctr_dec_tv_template)
2587f7cb80f2SJarod Wilson 			}
2588f7cb80f2SJarod Wilson 		}
2589f7cb80f2SJarod Wilson 	}, {
259085b63e34SJussi Kivilinna 		.alg = "ctr(blowfish)",
259185b63e34SJussi Kivilinna 		.test = alg_test_skcipher,
259285b63e34SJussi Kivilinna 		.suite = {
259385b63e34SJussi Kivilinna 			.cipher = {
259421c8e720SArd Biesheuvel 				.enc = __VECS(bf_ctr_enc_tv_template),
259521c8e720SArd Biesheuvel 				.dec = __VECS(bf_ctr_dec_tv_template)
259685b63e34SJussi Kivilinna 			}
259785b63e34SJussi Kivilinna 		}
259885b63e34SJussi Kivilinna 	}, {
25990840605eSJussi Kivilinna 		.alg = "ctr(camellia)",
26000840605eSJussi Kivilinna 		.test = alg_test_skcipher,
26010840605eSJussi Kivilinna 		.suite = {
26020840605eSJussi Kivilinna 			.cipher = {
260321c8e720SArd Biesheuvel 				.enc = __VECS(camellia_ctr_enc_tv_template),
260421c8e720SArd Biesheuvel 				.dec = __VECS(camellia_ctr_dec_tv_template)
26050840605eSJussi Kivilinna 			}
26060840605eSJussi Kivilinna 		}
26070840605eSJussi Kivilinna 	}, {
2608a2c58260SJohannes Goetzfried 		.alg = "ctr(cast5)",
2609a2c58260SJohannes Goetzfried 		.test = alg_test_skcipher,
2610a2c58260SJohannes Goetzfried 		.suite = {
2611a2c58260SJohannes Goetzfried 			.cipher = {
261221c8e720SArd Biesheuvel 				.enc = __VECS(cast5_ctr_enc_tv_template),
261321c8e720SArd Biesheuvel 				.dec = __VECS(cast5_ctr_dec_tv_template)
2614a2c58260SJohannes Goetzfried 			}
2615a2c58260SJohannes Goetzfried 		}
2616a2c58260SJohannes Goetzfried 	}, {
26179b8b0405SJohannes Goetzfried 		.alg = "ctr(cast6)",
26189b8b0405SJohannes Goetzfried 		.test = alg_test_skcipher,
26199b8b0405SJohannes Goetzfried 		.suite = {
26209b8b0405SJohannes Goetzfried 			.cipher = {
262121c8e720SArd Biesheuvel 				.enc = __VECS(cast6_ctr_enc_tv_template),
262221c8e720SArd Biesheuvel 				.dec = __VECS(cast6_ctr_dec_tv_template)
26239b8b0405SJohannes Goetzfried 			}
26249b8b0405SJohannes Goetzfried 		}
26259b8b0405SJohannes Goetzfried 	}, {
26268163fc30SJussi Kivilinna 		.alg = "ctr(des)",
26278163fc30SJussi Kivilinna 		.test = alg_test_skcipher,
26288163fc30SJussi Kivilinna 		.suite = {
26298163fc30SJussi Kivilinna 			.cipher = {
263021c8e720SArd Biesheuvel 				.enc = __VECS(des_ctr_enc_tv_template),
263121c8e720SArd Biesheuvel 				.dec = __VECS(des_ctr_dec_tv_template)
26328163fc30SJussi Kivilinna 			}
26338163fc30SJussi Kivilinna 		}
26348163fc30SJussi Kivilinna 	}, {
2635e080b17aSJussi Kivilinna 		.alg = "ctr(des3_ede)",
2636e080b17aSJussi Kivilinna 		.test = alg_test_skcipher,
2637e080b17aSJussi Kivilinna 		.suite = {
2638e080b17aSJussi Kivilinna 			.cipher = {
263921c8e720SArd Biesheuvel 				.enc = __VECS(des3_ede_ctr_enc_tv_template),
264021c8e720SArd Biesheuvel 				.dec = __VECS(des3_ede_ctr_dec_tv_template)
2641e080b17aSJussi Kivilinna 			}
2642e080b17aSJussi Kivilinna 		}
2643e080b17aSJussi Kivilinna 	}, {
26449d25917dSJussi Kivilinna 		.alg = "ctr(serpent)",
26459d25917dSJussi Kivilinna 		.test = alg_test_skcipher,
26469d25917dSJussi Kivilinna 		.suite = {
26479d25917dSJussi Kivilinna 			.cipher = {
264821c8e720SArd Biesheuvel 				.enc = __VECS(serpent_ctr_enc_tv_template),
264921c8e720SArd Biesheuvel 				.dec = __VECS(serpent_ctr_dec_tv_template)
26509d25917dSJussi Kivilinna 			}
26519d25917dSJussi Kivilinna 		}
26529d25917dSJussi Kivilinna 	}, {
2653573da620SJussi Kivilinna 		.alg = "ctr(twofish)",
2654573da620SJussi Kivilinna 		.test = alg_test_skcipher,
2655573da620SJussi Kivilinna 		.suite = {
2656573da620SJussi Kivilinna 			.cipher = {
265721c8e720SArd Biesheuvel 				.enc = __VECS(tf_ctr_enc_tv_template),
265821c8e720SArd Biesheuvel 				.dec = __VECS(tf_ctr_dec_tv_template)
2659573da620SJussi Kivilinna 			}
2660573da620SJussi Kivilinna 		}
2661573da620SJussi Kivilinna 	}, {
2662da7f033dSHerbert Xu 		.alg = "cts(cbc(aes))",
26631aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2664da7f033dSHerbert Xu 		.suite = {
2665da7f033dSHerbert Xu 			.cipher = {
266621c8e720SArd Biesheuvel 				.enc = __VECS(cts_mode_enc_tv_template),
266721c8e720SArd Biesheuvel 				.dec = __VECS(cts_mode_dec_tv_template)
2668da7f033dSHerbert Xu 			}
2669da7f033dSHerbert Xu 		}
2670da7f033dSHerbert Xu 	}, {
2671da7f033dSHerbert Xu 		.alg = "deflate",
2672da7f033dSHerbert Xu 		.test = alg_test_comp,
26730818904dSMilan Broz 		.fips_allowed = 1,
2674da7f033dSHerbert Xu 		.suite = {
2675da7f033dSHerbert Xu 			.comp = {
267621c8e720SArd Biesheuvel 				.comp = __VECS(deflate_comp_tv_template),
267721c8e720SArd Biesheuvel 				.decomp = __VECS(deflate_decomp_tv_template)
2678da7f033dSHerbert Xu 			}
2679da7f033dSHerbert Xu 		}
2680da7f033dSHerbert Xu 	}, {
2681802c7f1cSSalvatore Benedetto 		.alg = "dh",
2682802c7f1cSSalvatore Benedetto 		.test = alg_test_kpp,
2683802c7f1cSSalvatore Benedetto 		.fips_allowed = 1,
2684802c7f1cSSalvatore Benedetto 		.suite = {
268521c8e720SArd Biesheuvel 			.kpp = __VECS(dh_tv_template)
2686802c7f1cSSalvatore Benedetto 		}
2687802c7f1cSSalvatore Benedetto 	}, {
2688e448370dSJussi Kivilinna 		.alg = "digest_null",
2689e448370dSJussi Kivilinna 		.test = alg_test_null,
2690e448370dSJussi Kivilinna 	}, {
269164d1cdfbSStephan Mueller 		.alg = "drbg_nopr_ctr_aes128",
269264d1cdfbSStephan Mueller 		.test = alg_test_drbg,
269364d1cdfbSStephan Mueller 		.fips_allowed = 1,
269464d1cdfbSStephan Mueller 		.suite = {
269521c8e720SArd Biesheuvel 			.drbg = __VECS(drbg_nopr_ctr_aes128_tv_template)
269664d1cdfbSStephan Mueller 		}
269764d1cdfbSStephan Mueller 	}, {
269864d1cdfbSStephan Mueller 		.alg = "drbg_nopr_ctr_aes192",
269964d1cdfbSStephan Mueller 		.test = alg_test_drbg,
270064d1cdfbSStephan Mueller 		.fips_allowed = 1,
270164d1cdfbSStephan Mueller 		.suite = {
270221c8e720SArd Biesheuvel 			.drbg = __VECS(drbg_nopr_ctr_aes192_tv_template)
270364d1cdfbSStephan Mueller 		}
270464d1cdfbSStephan Mueller 	}, {
270564d1cdfbSStephan Mueller 		.alg = "drbg_nopr_ctr_aes256",
270664d1cdfbSStephan Mueller 		.test = alg_test_drbg,
270764d1cdfbSStephan Mueller 		.fips_allowed = 1,
270864d1cdfbSStephan Mueller 		.suite = {
270921c8e720SArd Biesheuvel 			.drbg = __VECS(drbg_nopr_ctr_aes256_tv_template)
271064d1cdfbSStephan Mueller 		}
271164d1cdfbSStephan Mueller 	}, {
271264d1cdfbSStephan Mueller 		/*
271364d1cdfbSStephan Mueller 		 * There is no need to specifically test the DRBG with every
271464d1cdfbSStephan Mueller 		 * backend cipher -- covered by drbg_nopr_hmac_sha256 test
271564d1cdfbSStephan Mueller 		 */
271664d1cdfbSStephan Mueller 		.alg = "drbg_nopr_hmac_sha1",
271764d1cdfbSStephan Mueller 		.fips_allowed = 1,
271864d1cdfbSStephan Mueller 		.test = alg_test_null,
271964d1cdfbSStephan Mueller 	}, {
272064d1cdfbSStephan Mueller 		.alg = "drbg_nopr_hmac_sha256",
272164d1cdfbSStephan Mueller 		.test = alg_test_drbg,
272264d1cdfbSStephan Mueller 		.fips_allowed = 1,
272364d1cdfbSStephan Mueller 		.suite = {
272421c8e720SArd Biesheuvel 			.drbg = __VECS(drbg_nopr_hmac_sha256_tv_template)
272564d1cdfbSStephan Mueller 		}
272664d1cdfbSStephan Mueller 	}, {
272764d1cdfbSStephan Mueller 		/* covered by drbg_nopr_hmac_sha256 test */
272864d1cdfbSStephan Mueller 		.alg = "drbg_nopr_hmac_sha384",
272964d1cdfbSStephan Mueller 		.fips_allowed = 1,
273064d1cdfbSStephan Mueller 		.test = alg_test_null,
273164d1cdfbSStephan Mueller 	}, {
273264d1cdfbSStephan Mueller 		.alg = "drbg_nopr_hmac_sha512",
273364d1cdfbSStephan Mueller 		.test = alg_test_null,
273464d1cdfbSStephan Mueller 		.fips_allowed = 1,
273564d1cdfbSStephan Mueller 	}, {
273664d1cdfbSStephan Mueller 		.alg = "drbg_nopr_sha1",
273764d1cdfbSStephan Mueller 		.fips_allowed = 1,
273864d1cdfbSStephan Mueller 		.test = alg_test_null,
273964d1cdfbSStephan Mueller 	}, {
274064d1cdfbSStephan Mueller 		.alg = "drbg_nopr_sha256",
274164d1cdfbSStephan Mueller 		.test = alg_test_drbg,
274264d1cdfbSStephan Mueller 		.fips_allowed = 1,
274364d1cdfbSStephan Mueller 		.suite = {
274421c8e720SArd Biesheuvel 			.drbg = __VECS(drbg_nopr_sha256_tv_template)
274564d1cdfbSStephan Mueller 		}
274664d1cdfbSStephan Mueller 	}, {
274764d1cdfbSStephan Mueller 		/* covered by drbg_nopr_sha256 test */
274864d1cdfbSStephan Mueller 		.alg = "drbg_nopr_sha384",
274964d1cdfbSStephan Mueller 		.fips_allowed = 1,
275064d1cdfbSStephan Mueller 		.test = alg_test_null,
275164d1cdfbSStephan Mueller 	}, {
275264d1cdfbSStephan Mueller 		.alg = "drbg_nopr_sha512",
275364d1cdfbSStephan Mueller 		.fips_allowed = 1,
275464d1cdfbSStephan Mueller 		.test = alg_test_null,
275564d1cdfbSStephan Mueller 	}, {
275664d1cdfbSStephan Mueller 		.alg = "drbg_pr_ctr_aes128",
275764d1cdfbSStephan Mueller 		.test = alg_test_drbg,
275864d1cdfbSStephan Mueller 		.fips_allowed = 1,
275964d1cdfbSStephan Mueller 		.suite = {
276021c8e720SArd Biesheuvel 			.drbg = __VECS(drbg_pr_ctr_aes128_tv_template)
276164d1cdfbSStephan Mueller 		}
276264d1cdfbSStephan Mueller 	}, {
276364d1cdfbSStephan Mueller 		/* covered by drbg_pr_ctr_aes128 test */
276464d1cdfbSStephan Mueller 		.alg = "drbg_pr_ctr_aes192",
276564d1cdfbSStephan Mueller 		.fips_allowed = 1,
276664d1cdfbSStephan Mueller 		.test = alg_test_null,
276764d1cdfbSStephan Mueller 	}, {
276864d1cdfbSStephan Mueller 		.alg = "drbg_pr_ctr_aes256",
276964d1cdfbSStephan Mueller 		.fips_allowed = 1,
277064d1cdfbSStephan Mueller 		.test = alg_test_null,
277164d1cdfbSStephan Mueller 	}, {
277264d1cdfbSStephan Mueller 		.alg = "drbg_pr_hmac_sha1",
277364d1cdfbSStephan Mueller 		.fips_allowed = 1,
277464d1cdfbSStephan Mueller 		.test = alg_test_null,
277564d1cdfbSStephan Mueller 	}, {
277664d1cdfbSStephan Mueller 		.alg = "drbg_pr_hmac_sha256",
277764d1cdfbSStephan Mueller 		.test = alg_test_drbg,
277864d1cdfbSStephan Mueller 		.fips_allowed = 1,
277964d1cdfbSStephan Mueller 		.suite = {
278021c8e720SArd Biesheuvel 			.drbg = __VECS(drbg_pr_hmac_sha256_tv_template)
278164d1cdfbSStephan Mueller 		}
278264d1cdfbSStephan Mueller 	}, {
278364d1cdfbSStephan Mueller 		/* covered by drbg_pr_hmac_sha256 test */
278464d1cdfbSStephan Mueller 		.alg = "drbg_pr_hmac_sha384",
278564d1cdfbSStephan Mueller 		.fips_allowed = 1,
278664d1cdfbSStephan Mueller 		.test = alg_test_null,
278764d1cdfbSStephan Mueller 	}, {
278864d1cdfbSStephan Mueller 		.alg = "drbg_pr_hmac_sha512",
278964d1cdfbSStephan Mueller 		.test = alg_test_null,
279064d1cdfbSStephan Mueller 		.fips_allowed = 1,
279164d1cdfbSStephan Mueller 	}, {
279264d1cdfbSStephan Mueller 		.alg = "drbg_pr_sha1",
279364d1cdfbSStephan Mueller 		.fips_allowed = 1,
279464d1cdfbSStephan Mueller 		.test = alg_test_null,
279564d1cdfbSStephan Mueller 	}, {
279664d1cdfbSStephan Mueller 		.alg = "drbg_pr_sha256",
279764d1cdfbSStephan Mueller 		.test = alg_test_drbg,
279864d1cdfbSStephan Mueller 		.fips_allowed = 1,
279964d1cdfbSStephan Mueller 		.suite = {
280021c8e720SArd Biesheuvel 			.drbg = __VECS(drbg_pr_sha256_tv_template)
280164d1cdfbSStephan Mueller 		}
280264d1cdfbSStephan Mueller 	}, {
280364d1cdfbSStephan Mueller 		/* covered by drbg_pr_sha256 test */
280464d1cdfbSStephan Mueller 		.alg = "drbg_pr_sha384",
280564d1cdfbSStephan Mueller 		.fips_allowed = 1,
280664d1cdfbSStephan Mueller 		.test = alg_test_null,
280764d1cdfbSStephan Mueller 	}, {
280864d1cdfbSStephan Mueller 		.alg = "drbg_pr_sha512",
280964d1cdfbSStephan Mueller 		.fips_allowed = 1,
281064d1cdfbSStephan Mueller 		.test = alg_test_null,
281164d1cdfbSStephan Mueller 	}, {
2812da7f033dSHerbert Xu 		.alg = "ecb(aes)",
28131aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2814a1915d51SJarod Wilson 		.fips_allowed = 1,
2815da7f033dSHerbert Xu 		.suite = {
2816da7f033dSHerbert Xu 			.cipher = {
281721c8e720SArd Biesheuvel 				.enc = __VECS(aes_enc_tv_template),
281821c8e720SArd Biesheuvel 				.dec = __VECS(aes_dec_tv_template)
2819da7f033dSHerbert Xu 			}
2820da7f033dSHerbert Xu 		}
2821da7f033dSHerbert Xu 	}, {
2822da7f033dSHerbert Xu 		.alg = "ecb(anubis)",
28231aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2824da7f033dSHerbert Xu 		.suite = {
2825da7f033dSHerbert Xu 			.cipher = {
282621c8e720SArd Biesheuvel 				.enc = __VECS(anubis_enc_tv_template),
282721c8e720SArd Biesheuvel 				.dec = __VECS(anubis_dec_tv_template)
2828da7f033dSHerbert Xu 			}
2829da7f033dSHerbert Xu 		}
2830da7f033dSHerbert Xu 	}, {
2831da7f033dSHerbert Xu 		.alg = "ecb(arc4)",
28321aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2833da7f033dSHerbert Xu 		.suite = {
2834da7f033dSHerbert Xu 			.cipher = {
283521c8e720SArd Biesheuvel 				.enc = __VECS(arc4_enc_tv_template),
283621c8e720SArd Biesheuvel 				.dec = __VECS(arc4_dec_tv_template)
2837da7f033dSHerbert Xu 			}
2838da7f033dSHerbert Xu 		}
2839da7f033dSHerbert Xu 	}, {
2840da7f033dSHerbert Xu 		.alg = "ecb(blowfish)",
28411aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2842da7f033dSHerbert Xu 		.suite = {
2843da7f033dSHerbert Xu 			.cipher = {
284421c8e720SArd Biesheuvel 				.enc = __VECS(bf_enc_tv_template),
284521c8e720SArd Biesheuvel 				.dec = __VECS(bf_dec_tv_template)
2846da7f033dSHerbert Xu 			}
2847da7f033dSHerbert Xu 		}
2848da7f033dSHerbert Xu 	}, {
2849da7f033dSHerbert Xu 		.alg = "ecb(camellia)",
28501aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2851da7f033dSHerbert Xu 		.suite = {
2852da7f033dSHerbert Xu 			.cipher = {
285321c8e720SArd Biesheuvel 				.enc = __VECS(camellia_enc_tv_template),
285421c8e720SArd Biesheuvel 				.dec = __VECS(camellia_dec_tv_template)
2855da7f033dSHerbert Xu 			}
2856da7f033dSHerbert Xu 		}
2857da7f033dSHerbert Xu 	}, {
2858da7f033dSHerbert Xu 		.alg = "ecb(cast5)",
28591aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2860da7f033dSHerbert Xu 		.suite = {
2861da7f033dSHerbert Xu 			.cipher = {
286221c8e720SArd Biesheuvel 				.enc = __VECS(cast5_enc_tv_template),
286321c8e720SArd Biesheuvel 				.dec = __VECS(cast5_dec_tv_template)
2864da7f033dSHerbert Xu 			}
2865da7f033dSHerbert Xu 		}
2866da7f033dSHerbert Xu 	}, {
2867da7f033dSHerbert Xu 		.alg = "ecb(cast6)",
28681aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2869da7f033dSHerbert Xu 		.suite = {
2870da7f033dSHerbert Xu 			.cipher = {
287121c8e720SArd Biesheuvel 				.enc = __VECS(cast6_enc_tv_template),
287221c8e720SArd Biesheuvel 				.dec = __VECS(cast6_dec_tv_template)
2873da7f033dSHerbert Xu 			}
2874da7f033dSHerbert Xu 		}
2875da7f033dSHerbert Xu 	}, {
2876e448370dSJussi Kivilinna 		.alg = "ecb(cipher_null)",
2877e448370dSJussi Kivilinna 		.test = alg_test_null,
2878e448370dSJussi Kivilinna 	}, {
2879da7f033dSHerbert Xu 		.alg = "ecb(des)",
28801aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2881da7f033dSHerbert Xu 		.suite = {
2882da7f033dSHerbert Xu 			.cipher = {
288321c8e720SArd Biesheuvel 				.enc = __VECS(des_enc_tv_template),
288421c8e720SArd Biesheuvel 				.dec = __VECS(des_dec_tv_template)
2885da7f033dSHerbert Xu 			}
2886da7f033dSHerbert Xu 		}
2887da7f033dSHerbert Xu 	}, {
2888da7f033dSHerbert Xu 		.alg = "ecb(des3_ede)",
28891aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2890a1915d51SJarod Wilson 		.fips_allowed = 1,
2891da7f033dSHerbert Xu 		.suite = {
2892da7f033dSHerbert Xu 			.cipher = {
289321c8e720SArd Biesheuvel 				.enc = __VECS(des3_ede_enc_tv_template),
289421c8e720SArd Biesheuvel 				.dec = __VECS(des3_ede_dec_tv_template)
2895da7f033dSHerbert Xu 			}
2896da7f033dSHerbert Xu 		}
2897da7f033dSHerbert Xu 	}, {
289866e5bd00SJussi Kivilinna 		.alg = "ecb(fcrypt)",
289966e5bd00SJussi Kivilinna 		.test = alg_test_skcipher,
290066e5bd00SJussi Kivilinna 		.suite = {
290166e5bd00SJussi Kivilinna 			.cipher = {
290266e5bd00SJussi Kivilinna 				.enc = {
290366e5bd00SJussi Kivilinna 					.vecs = fcrypt_pcbc_enc_tv_template,
290466e5bd00SJussi Kivilinna 					.count = 1
290566e5bd00SJussi Kivilinna 				},
290666e5bd00SJussi Kivilinna 				.dec = {
290766e5bd00SJussi Kivilinna 					.vecs = fcrypt_pcbc_dec_tv_template,
290866e5bd00SJussi Kivilinna 					.count = 1
290966e5bd00SJussi Kivilinna 				}
291066e5bd00SJussi Kivilinna 			}
291166e5bd00SJussi Kivilinna 		}
291266e5bd00SJussi Kivilinna 	}, {
2913da7f033dSHerbert Xu 		.alg = "ecb(khazad)",
29141aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2915da7f033dSHerbert Xu 		.suite = {
2916da7f033dSHerbert Xu 			.cipher = {
291721c8e720SArd Biesheuvel 				.enc = __VECS(khazad_enc_tv_template),
291821c8e720SArd Biesheuvel 				.dec = __VECS(khazad_dec_tv_template)
2919da7f033dSHerbert Xu 			}
2920da7f033dSHerbert Xu 		}
2921da7f033dSHerbert Xu 	}, {
2922da7f033dSHerbert Xu 		.alg = "ecb(seed)",
29231aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2924da7f033dSHerbert Xu 		.suite = {
2925da7f033dSHerbert Xu 			.cipher = {
292621c8e720SArd Biesheuvel 				.enc = __VECS(seed_enc_tv_template),
292721c8e720SArd Biesheuvel 				.dec = __VECS(seed_dec_tv_template)
2928da7f033dSHerbert Xu 			}
2929da7f033dSHerbert Xu 		}
2930da7f033dSHerbert Xu 	}, {
2931da7f033dSHerbert Xu 		.alg = "ecb(serpent)",
29321aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2933da7f033dSHerbert Xu 		.suite = {
2934da7f033dSHerbert Xu 			.cipher = {
293521c8e720SArd Biesheuvel 				.enc = __VECS(serpent_enc_tv_template),
293621c8e720SArd Biesheuvel 				.dec = __VECS(serpent_dec_tv_template)
2937da7f033dSHerbert Xu 			}
2938da7f033dSHerbert Xu 		}
2939da7f033dSHerbert Xu 	}, {
2940da7f033dSHerbert Xu 		.alg = "ecb(tea)",
29411aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2942da7f033dSHerbert Xu 		.suite = {
2943da7f033dSHerbert Xu 			.cipher = {
294421c8e720SArd Biesheuvel 				.enc = __VECS(tea_enc_tv_template),
294521c8e720SArd Biesheuvel 				.dec = __VECS(tea_dec_tv_template)
2946da7f033dSHerbert Xu 			}
2947da7f033dSHerbert Xu 		}
2948da7f033dSHerbert Xu 	}, {
2949da7f033dSHerbert Xu 		.alg = "ecb(tnepres)",
29501aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2951da7f033dSHerbert Xu 		.suite = {
2952da7f033dSHerbert Xu 			.cipher = {
295321c8e720SArd Biesheuvel 				.enc = __VECS(tnepres_enc_tv_template),
295421c8e720SArd Biesheuvel 				.dec = __VECS(tnepres_dec_tv_template)
2955da7f033dSHerbert Xu 			}
2956da7f033dSHerbert Xu 		}
2957da7f033dSHerbert Xu 	}, {
2958da7f033dSHerbert Xu 		.alg = "ecb(twofish)",
29591aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2960da7f033dSHerbert Xu 		.suite = {
2961da7f033dSHerbert Xu 			.cipher = {
296221c8e720SArd Biesheuvel 				.enc = __VECS(tf_enc_tv_template),
296321c8e720SArd Biesheuvel 				.dec = __VECS(tf_dec_tv_template)
2964da7f033dSHerbert Xu 			}
2965da7f033dSHerbert Xu 		}
2966da7f033dSHerbert Xu 	}, {
2967da7f033dSHerbert Xu 		.alg = "ecb(xeta)",
29681aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2969da7f033dSHerbert Xu 		.suite = {
2970da7f033dSHerbert Xu 			.cipher = {
297121c8e720SArd Biesheuvel 				.enc = __VECS(xeta_enc_tv_template),
297221c8e720SArd Biesheuvel 				.dec = __VECS(xeta_dec_tv_template)
2973da7f033dSHerbert Xu 			}
2974da7f033dSHerbert Xu 		}
2975da7f033dSHerbert Xu 	}, {
2976da7f033dSHerbert Xu 		.alg = "ecb(xtea)",
29771aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2978da7f033dSHerbert Xu 		.suite = {
2979da7f033dSHerbert Xu 			.cipher = {
298021c8e720SArd Biesheuvel 				.enc = __VECS(xtea_enc_tv_template),
298121c8e720SArd Biesheuvel 				.dec = __VECS(xtea_dec_tv_template)
2982da7f033dSHerbert Xu 			}
2983da7f033dSHerbert Xu 		}
2984da7f033dSHerbert Xu 	}, {
29853c4b2390SSalvatore Benedetto 		.alg = "ecdh",
29863c4b2390SSalvatore Benedetto 		.test = alg_test_kpp,
29873c4b2390SSalvatore Benedetto 		.fips_allowed = 1,
29883c4b2390SSalvatore Benedetto 		.suite = {
298921c8e720SArd Biesheuvel 			.kpp = __VECS(ecdh_tv_template)
29903c4b2390SSalvatore Benedetto 		}
29913c4b2390SSalvatore Benedetto 	}, {
2992da7f033dSHerbert Xu 		.alg = "gcm(aes)",
2993da7f033dSHerbert Xu 		.test = alg_test_aead,
2994a1915d51SJarod Wilson 		.fips_allowed = 1,
2995da7f033dSHerbert Xu 		.suite = {
2996da7f033dSHerbert Xu 			.aead = {
299721c8e720SArd Biesheuvel 				.enc = __VECS(aes_gcm_enc_tv_template),
299821c8e720SArd Biesheuvel 				.dec = __VECS(aes_gcm_dec_tv_template)
2999da7f033dSHerbert Xu 			}
3000da7f033dSHerbert Xu 		}
3001da7f033dSHerbert Xu 	}, {
3002507069c9SYouquan, Song 		.alg = "ghash",
3003507069c9SYouquan, Song 		.test = alg_test_hash,
300418c0ebd2SJarod Wilson 		.fips_allowed = 1,
3005507069c9SYouquan, Song 		.suite = {
300621c8e720SArd Biesheuvel 			.hash = __VECS(ghash_tv_template)
3007507069c9SYouquan, Song 		}
3008507069c9SYouquan, Song 	}, {
3009a482b081SSonic Zhang 		.alg = "hmac(crc32)",
3010a482b081SSonic Zhang 		.test = alg_test_hash,
3011a482b081SSonic Zhang 		.suite = {
301221c8e720SArd Biesheuvel 			.hash = __VECS(bfin_crc_tv_template)
3013a482b081SSonic Zhang 		}
3014a482b081SSonic Zhang 	}, {
3015da7f033dSHerbert Xu 		.alg = "hmac(md5)",
3016da7f033dSHerbert Xu 		.test = alg_test_hash,
3017da7f033dSHerbert Xu 		.suite = {
301821c8e720SArd Biesheuvel 			.hash = __VECS(hmac_md5_tv_template)
3019da7f033dSHerbert Xu 		}
3020da7f033dSHerbert Xu 	}, {
3021da7f033dSHerbert Xu 		.alg = "hmac(rmd128)",
3022da7f033dSHerbert Xu 		.test = alg_test_hash,
3023da7f033dSHerbert Xu 		.suite = {
302421c8e720SArd Biesheuvel 			.hash = __VECS(hmac_rmd128_tv_template)
3025da7f033dSHerbert Xu 		}
3026da7f033dSHerbert Xu 	}, {
3027da7f033dSHerbert Xu 		.alg = "hmac(rmd160)",
3028da7f033dSHerbert Xu 		.test = alg_test_hash,
3029da7f033dSHerbert Xu 		.suite = {
303021c8e720SArd Biesheuvel 			.hash = __VECS(hmac_rmd160_tv_template)
3031da7f033dSHerbert Xu 		}
3032da7f033dSHerbert Xu 	}, {
3033da7f033dSHerbert Xu 		.alg = "hmac(sha1)",
3034da7f033dSHerbert Xu 		.test = alg_test_hash,
3035a1915d51SJarod Wilson 		.fips_allowed = 1,
3036da7f033dSHerbert Xu 		.suite = {
303721c8e720SArd Biesheuvel 			.hash = __VECS(hmac_sha1_tv_template)
3038da7f033dSHerbert Xu 		}
3039da7f033dSHerbert Xu 	}, {
3040da7f033dSHerbert Xu 		.alg = "hmac(sha224)",
3041da7f033dSHerbert Xu 		.test = alg_test_hash,
3042a1915d51SJarod Wilson 		.fips_allowed = 1,
3043da7f033dSHerbert Xu 		.suite = {
304421c8e720SArd Biesheuvel 			.hash = __VECS(hmac_sha224_tv_template)
3045da7f033dSHerbert Xu 		}
3046da7f033dSHerbert Xu 	}, {
3047da7f033dSHerbert Xu 		.alg = "hmac(sha256)",
3048da7f033dSHerbert Xu 		.test = alg_test_hash,
3049a1915d51SJarod Wilson 		.fips_allowed = 1,
3050da7f033dSHerbert Xu 		.suite = {
305121c8e720SArd Biesheuvel 			.hash = __VECS(hmac_sha256_tv_template)
3052da7f033dSHerbert Xu 		}
3053da7f033dSHerbert Xu 	}, {
305498eca72fSraveendra padasalagi 		.alg = "hmac(sha3-224)",
305598eca72fSraveendra padasalagi 		.test = alg_test_hash,
305698eca72fSraveendra padasalagi 		.fips_allowed = 1,
305798eca72fSraveendra padasalagi 		.suite = {
305821c8e720SArd Biesheuvel 			.hash = __VECS(hmac_sha3_224_tv_template)
305998eca72fSraveendra padasalagi 		}
306098eca72fSraveendra padasalagi 	}, {
306198eca72fSraveendra padasalagi 		.alg = "hmac(sha3-256)",
306298eca72fSraveendra padasalagi 		.test = alg_test_hash,
306398eca72fSraveendra padasalagi 		.fips_allowed = 1,
306498eca72fSraveendra padasalagi 		.suite = {
306521c8e720SArd Biesheuvel 			.hash = __VECS(hmac_sha3_256_tv_template)
306698eca72fSraveendra padasalagi 		}
306798eca72fSraveendra padasalagi 	}, {
306898eca72fSraveendra padasalagi 		.alg = "hmac(sha3-384)",
306998eca72fSraveendra padasalagi 		.test = alg_test_hash,
307098eca72fSraveendra padasalagi 		.fips_allowed = 1,
307198eca72fSraveendra padasalagi 		.suite = {
307221c8e720SArd Biesheuvel 			.hash = __VECS(hmac_sha3_384_tv_template)
307398eca72fSraveendra padasalagi 		}
307498eca72fSraveendra padasalagi 	}, {
307598eca72fSraveendra padasalagi 		.alg = "hmac(sha3-512)",
307698eca72fSraveendra padasalagi 		.test = alg_test_hash,
307798eca72fSraveendra padasalagi 		.fips_allowed = 1,
307898eca72fSraveendra padasalagi 		.suite = {
307921c8e720SArd Biesheuvel 			.hash = __VECS(hmac_sha3_512_tv_template)
308098eca72fSraveendra padasalagi 		}
308198eca72fSraveendra padasalagi 	}, {
3082da7f033dSHerbert Xu 		.alg = "hmac(sha384)",
3083da7f033dSHerbert Xu 		.test = alg_test_hash,
3084a1915d51SJarod Wilson 		.fips_allowed = 1,
3085da7f033dSHerbert Xu 		.suite = {
308621c8e720SArd Biesheuvel 			.hash = __VECS(hmac_sha384_tv_template)
3087da7f033dSHerbert Xu 		}
3088da7f033dSHerbert Xu 	}, {
3089da7f033dSHerbert Xu 		.alg = "hmac(sha512)",
3090da7f033dSHerbert Xu 		.test = alg_test_hash,
3091a1915d51SJarod Wilson 		.fips_allowed = 1,
3092da7f033dSHerbert Xu 		.suite = {
309321c8e720SArd Biesheuvel 			.hash = __VECS(hmac_sha512_tv_template)
3094da7f033dSHerbert Xu 		}
3095da7f033dSHerbert Xu 	}, {
3096bb5530e4SStephan Mueller 		.alg = "jitterentropy_rng",
3097bb5530e4SStephan Mueller 		.fips_allowed = 1,
3098bb5530e4SStephan Mueller 		.test = alg_test_null,
3099bb5530e4SStephan Mueller 	}, {
310035351988SStephan Mueller 		.alg = "kw(aes)",
310135351988SStephan Mueller 		.test = alg_test_skcipher,
310235351988SStephan Mueller 		.fips_allowed = 1,
310335351988SStephan Mueller 		.suite = {
310435351988SStephan Mueller 			.cipher = {
310521c8e720SArd Biesheuvel 				.enc = __VECS(aes_kw_enc_tv_template),
310621c8e720SArd Biesheuvel 				.dec = __VECS(aes_kw_dec_tv_template)
310735351988SStephan Mueller 			}
310835351988SStephan Mueller 		}
310935351988SStephan Mueller 	}, {
3110da7f033dSHerbert Xu 		.alg = "lrw(aes)",
31111aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3112da7f033dSHerbert Xu 		.suite = {
3113da7f033dSHerbert Xu 			.cipher = {
311421c8e720SArd Biesheuvel 				.enc = __VECS(aes_lrw_enc_tv_template),
311521c8e720SArd Biesheuvel 				.dec = __VECS(aes_lrw_dec_tv_template)
3116da7f033dSHerbert Xu 			}
3117da7f033dSHerbert Xu 		}
3118da7f033dSHerbert Xu 	}, {
31190840605eSJussi Kivilinna 		.alg = "lrw(camellia)",
31200840605eSJussi Kivilinna 		.test = alg_test_skcipher,
31210840605eSJussi Kivilinna 		.suite = {
31220840605eSJussi Kivilinna 			.cipher = {
312321c8e720SArd Biesheuvel 				.enc = __VECS(camellia_lrw_enc_tv_template),
312421c8e720SArd Biesheuvel 				.dec = __VECS(camellia_lrw_dec_tv_template)
31250840605eSJussi Kivilinna 			}
31260840605eSJussi Kivilinna 		}
31270840605eSJussi Kivilinna 	}, {
31289b8b0405SJohannes Goetzfried 		.alg = "lrw(cast6)",
31299b8b0405SJohannes Goetzfried 		.test = alg_test_skcipher,
31309b8b0405SJohannes Goetzfried 		.suite = {
31319b8b0405SJohannes Goetzfried 			.cipher = {
313221c8e720SArd Biesheuvel 				.enc = __VECS(cast6_lrw_enc_tv_template),
313321c8e720SArd Biesheuvel 				.dec = __VECS(cast6_lrw_dec_tv_template)
31349b8b0405SJohannes Goetzfried 			}
31359b8b0405SJohannes Goetzfried 		}
31369b8b0405SJohannes Goetzfried 	}, {
3137d7bfc0faSJussi Kivilinna 		.alg = "lrw(serpent)",
3138d7bfc0faSJussi Kivilinna 		.test = alg_test_skcipher,
3139d7bfc0faSJussi Kivilinna 		.suite = {
3140d7bfc0faSJussi Kivilinna 			.cipher = {
314121c8e720SArd Biesheuvel 				.enc = __VECS(serpent_lrw_enc_tv_template),
314221c8e720SArd Biesheuvel 				.dec = __VECS(serpent_lrw_dec_tv_template)
3143d7bfc0faSJussi Kivilinna 			}
3144d7bfc0faSJussi Kivilinna 		}
3145d7bfc0faSJussi Kivilinna 	}, {
31460b2a1551SJussi Kivilinna 		.alg = "lrw(twofish)",
31470b2a1551SJussi Kivilinna 		.test = alg_test_skcipher,
31480b2a1551SJussi Kivilinna 		.suite = {
31490b2a1551SJussi Kivilinna 			.cipher = {
315021c8e720SArd Biesheuvel 				.enc = __VECS(tf_lrw_enc_tv_template),
315121c8e720SArd Biesheuvel 				.dec = __VECS(tf_lrw_dec_tv_template)
31520b2a1551SJussi Kivilinna 			}
31530b2a1551SJussi Kivilinna 		}
31540b2a1551SJussi Kivilinna 	}, {
31551443cc9bSKOVACS Krisztian 		.alg = "lz4",
31561443cc9bSKOVACS Krisztian 		.test = alg_test_comp,
31571443cc9bSKOVACS Krisztian 		.fips_allowed = 1,
31581443cc9bSKOVACS Krisztian 		.suite = {
31591443cc9bSKOVACS Krisztian 			.comp = {
316021c8e720SArd Biesheuvel 				.comp = __VECS(lz4_comp_tv_template),
316121c8e720SArd Biesheuvel 				.decomp = __VECS(lz4_decomp_tv_template)
31621443cc9bSKOVACS Krisztian 			}
31631443cc9bSKOVACS Krisztian 		}
31641443cc9bSKOVACS Krisztian 	}, {
31651443cc9bSKOVACS Krisztian 		.alg = "lz4hc",
31661443cc9bSKOVACS Krisztian 		.test = alg_test_comp,
31671443cc9bSKOVACS Krisztian 		.fips_allowed = 1,
31681443cc9bSKOVACS Krisztian 		.suite = {
31691443cc9bSKOVACS Krisztian 			.comp = {
317021c8e720SArd Biesheuvel 				.comp = __VECS(lz4hc_comp_tv_template),
317121c8e720SArd Biesheuvel 				.decomp = __VECS(lz4hc_decomp_tv_template)
31721443cc9bSKOVACS Krisztian 			}
31731443cc9bSKOVACS Krisztian 		}
31741443cc9bSKOVACS Krisztian 	}, {
3175da7f033dSHerbert Xu 		.alg = "lzo",
3176da7f033dSHerbert Xu 		.test = alg_test_comp,
31770818904dSMilan Broz 		.fips_allowed = 1,
3178da7f033dSHerbert Xu 		.suite = {
3179da7f033dSHerbert Xu 			.comp = {
318021c8e720SArd Biesheuvel 				.comp = __VECS(lzo_comp_tv_template),
318121c8e720SArd Biesheuvel 				.decomp = __VECS(lzo_decomp_tv_template)
3182da7f033dSHerbert Xu 			}
3183da7f033dSHerbert Xu 		}
3184da7f033dSHerbert Xu 	}, {
3185da7f033dSHerbert Xu 		.alg = "md4",
3186da7f033dSHerbert Xu 		.test = alg_test_hash,
3187da7f033dSHerbert Xu 		.suite = {
318821c8e720SArd Biesheuvel 			.hash = __VECS(md4_tv_template)
3189da7f033dSHerbert Xu 		}
3190da7f033dSHerbert Xu 	}, {
3191da7f033dSHerbert Xu 		.alg = "md5",
3192da7f033dSHerbert Xu 		.test = alg_test_hash,
3193da7f033dSHerbert Xu 		.suite = {
319421c8e720SArd Biesheuvel 			.hash = __VECS(md5_tv_template)
3195da7f033dSHerbert Xu 		}
3196da7f033dSHerbert Xu 	}, {
3197da7f033dSHerbert Xu 		.alg = "michael_mic",
3198da7f033dSHerbert Xu 		.test = alg_test_hash,
3199da7f033dSHerbert Xu 		.suite = {
320021c8e720SArd Biesheuvel 			.hash = __VECS(michael_mic_tv_template)
3201da7f033dSHerbert Xu 		}
3202da7f033dSHerbert Xu 	}, {
3203ba0e14acSPuneet Saxena 		.alg = "ofb(aes)",
3204ba0e14acSPuneet Saxena 		.test = alg_test_skcipher,
3205ba0e14acSPuneet Saxena 		.fips_allowed = 1,
3206ba0e14acSPuneet Saxena 		.suite = {
3207ba0e14acSPuneet Saxena 			.cipher = {
320821c8e720SArd Biesheuvel 				.enc = __VECS(aes_ofb_enc_tv_template),
320921c8e720SArd Biesheuvel 				.dec = __VECS(aes_ofb_dec_tv_template)
3210ba0e14acSPuneet Saxena 			}
3211ba0e14acSPuneet Saxena 		}
3212ba0e14acSPuneet Saxena 	}, {
3213da7f033dSHerbert Xu 		.alg = "pcbc(fcrypt)",
32141aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3215da7f033dSHerbert Xu 		.suite = {
3216da7f033dSHerbert Xu 			.cipher = {
321721c8e720SArd Biesheuvel 				.enc = __VECS(fcrypt_pcbc_enc_tv_template),
321821c8e720SArd Biesheuvel 				.dec = __VECS(fcrypt_pcbc_dec_tv_template)
3219da7f033dSHerbert Xu 			}
3220da7f033dSHerbert Xu 		}
3221da7f033dSHerbert Xu 	}, {
3222eee9dc61SMartin Willi 		.alg = "poly1305",
3223eee9dc61SMartin Willi 		.test = alg_test_hash,
3224eee9dc61SMartin Willi 		.suite = {
322521c8e720SArd Biesheuvel 			.hash = __VECS(poly1305_tv_template)
3226eee9dc61SMartin Willi 		}
3227eee9dc61SMartin Willi 	}, {
3228da7f033dSHerbert Xu 		.alg = "rfc3686(ctr(aes))",
32291aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3230a1915d51SJarod Wilson 		.fips_allowed = 1,
3231da7f033dSHerbert Xu 		.suite = {
3232da7f033dSHerbert Xu 			.cipher = {
323321c8e720SArd Biesheuvel 				.enc = __VECS(aes_ctr_rfc3686_enc_tv_template),
323421c8e720SArd Biesheuvel 				.dec = __VECS(aes_ctr_rfc3686_dec_tv_template)
3235da7f033dSHerbert Xu 			}
3236da7f033dSHerbert Xu 		}
3237da7f033dSHerbert Xu 	}, {
32383f31a740SHerbert Xu 		.alg = "rfc4106(gcm(aes))",
323969435b94SAdrian Hoban 		.test = alg_test_aead,
3240db71f29aSJarod Wilson 		.fips_allowed = 1,
324169435b94SAdrian Hoban 		.suite = {
324269435b94SAdrian Hoban 			.aead = {
324321c8e720SArd Biesheuvel 				.enc = __VECS(aes_gcm_rfc4106_enc_tv_template),
324421c8e720SArd Biesheuvel 				.dec = __VECS(aes_gcm_rfc4106_dec_tv_template)
324569435b94SAdrian Hoban 			}
324669435b94SAdrian Hoban 		}
324769435b94SAdrian Hoban 	}, {
3248544c436aSHerbert Xu 		.alg = "rfc4309(ccm(aes))",
32495d667322SJarod Wilson 		.test = alg_test_aead,
3250a1915d51SJarod Wilson 		.fips_allowed = 1,
32515d667322SJarod Wilson 		.suite = {
32525d667322SJarod Wilson 			.aead = {
325321c8e720SArd Biesheuvel 				.enc = __VECS(aes_ccm_rfc4309_enc_tv_template),
325421c8e720SArd Biesheuvel 				.dec = __VECS(aes_ccm_rfc4309_dec_tv_template)
32555d667322SJarod Wilson 			}
32565d667322SJarod Wilson 		}
32575d667322SJarod Wilson 	}, {
3258bb68745eSHerbert Xu 		.alg = "rfc4543(gcm(aes))",
3259e9b7441aSJussi Kivilinna 		.test = alg_test_aead,
3260e9b7441aSJussi Kivilinna 		.suite = {
3261e9b7441aSJussi Kivilinna 			.aead = {
326221c8e720SArd Biesheuvel 				.enc = __VECS(aes_gcm_rfc4543_enc_tv_template),
326321c8e720SArd Biesheuvel 				.dec = __VECS(aes_gcm_rfc4543_dec_tv_template),
3264e9b7441aSJussi Kivilinna 			}
3265e9b7441aSJussi Kivilinna 		}
3266e9b7441aSJussi Kivilinna 	}, {
3267af2b76b5SMartin Willi 		.alg = "rfc7539(chacha20,poly1305)",
3268af2b76b5SMartin Willi 		.test = alg_test_aead,
3269af2b76b5SMartin Willi 		.suite = {
3270af2b76b5SMartin Willi 			.aead = {
327121c8e720SArd Biesheuvel 				.enc = __VECS(rfc7539_enc_tv_template),
327221c8e720SArd Biesheuvel 				.dec = __VECS(rfc7539_dec_tv_template),
3273af2b76b5SMartin Willi 			}
3274af2b76b5SMartin Willi 		}
3275af2b76b5SMartin Willi 	}, {
32765900758dSMartin Willi 		.alg = "rfc7539esp(chacha20,poly1305)",
32775900758dSMartin Willi 		.test = alg_test_aead,
32785900758dSMartin Willi 		.suite = {
32795900758dSMartin Willi 			.aead = {
328021c8e720SArd Biesheuvel 				.enc = __VECS(rfc7539esp_enc_tv_template),
328121c8e720SArd Biesheuvel 				.dec = __VECS(rfc7539esp_dec_tv_template),
32825900758dSMartin Willi 			}
32835900758dSMartin Willi 		}
32845900758dSMartin Willi 	}, {
3285da7f033dSHerbert Xu 		.alg = "rmd128",
3286da7f033dSHerbert Xu 		.test = alg_test_hash,
3287da7f033dSHerbert Xu 		.suite = {
328821c8e720SArd Biesheuvel 			.hash = __VECS(rmd128_tv_template)
3289da7f033dSHerbert Xu 		}
3290da7f033dSHerbert Xu 	}, {
3291da7f033dSHerbert Xu 		.alg = "rmd160",
3292da7f033dSHerbert Xu 		.test = alg_test_hash,
3293da7f033dSHerbert Xu 		.suite = {
329421c8e720SArd Biesheuvel 			.hash = __VECS(rmd160_tv_template)
3295da7f033dSHerbert Xu 		}
3296da7f033dSHerbert Xu 	}, {
3297da7f033dSHerbert Xu 		.alg = "rmd256",
3298da7f033dSHerbert Xu 		.test = alg_test_hash,
3299da7f033dSHerbert Xu 		.suite = {
330021c8e720SArd Biesheuvel 			.hash = __VECS(rmd256_tv_template)
3301da7f033dSHerbert Xu 		}
3302da7f033dSHerbert Xu 	}, {
3303da7f033dSHerbert Xu 		.alg = "rmd320",
3304da7f033dSHerbert Xu 		.test = alg_test_hash,
3305da7f033dSHerbert Xu 		.suite = {
330621c8e720SArd Biesheuvel 			.hash = __VECS(rmd320_tv_template)
3307da7f033dSHerbert Xu 		}
3308da7f033dSHerbert Xu 	}, {
3309946cc463STadeusz Struk 		.alg = "rsa",
3310946cc463STadeusz Struk 		.test = alg_test_akcipher,
3311946cc463STadeusz Struk 		.fips_allowed = 1,
3312946cc463STadeusz Struk 		.suite = {
331321c8e720SArd Biesheuvel 			.akcipher = __VECS(rsa_tv_template)
3314946cc463STadeusz Struk 		}
3315946cc463STadeusz Struk 	}, {
3316da7f033dSHerbert Xu 		.alg = "salsa20",
33171aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3318da7f033dSHerbert Xu 		.suite = {
3319da7f033dSHerbert Xu 			.cipher = {
332021c8e720SArd Biesheuvel 				.enc = __VECS(salsa20_stream_enc_tv_template)
3321da7f033dSHerbert Xu 			}
3322da7f033dSHerbert Xu 		}
3323da7f033dSHerbert Xu 	}, {
3324da7f033dSHerbert Xu 		.alg = "sha1",
3325da7f033dSHerbert Xu 		.test = alg_test_hash,
3326a1915d51SJarod Wilson 		.fips_allowed = 1,
3327da7f033dSHerbert Xu 		.suite = {
332821c8e720SArd Biesheuvel 			.hash = __VECS(sha1_tv_template)
3329da7f033dSHerbert Xu 		}
3330da7f033dSHerbert Xu 	}, {
3331da7f033dSHerbert Xu 		.alg = "sha224",
3332da7f033dSHerbert Xu 		.test = alg_test_hash,
3333a1915d51SJarod Wilson 		.fips_allowed = 1,
3334da7f033dSHerbert Xu 		.suite = {
333521c8e720SArd Biesheuvel 			.hash = __VECS(sha224_tv_template)
3336da7f033dSHerbert Xu 		}
3337da7f033dSHerbert Xu 	}, {
3338da7f033dSHerbert Xu 		.alg = "sha256",
3339da7f033dSHerbert Xu 		.test = alg_test_hash,
3340a1915d51SJarod Wilson 		.fips_allowed = 1,
3341da7f033dSHerbert Xu 		.suite = {
334221c8e720SArd Biesheuvel 			.hash = __VECS(sha256_tv_template)
3343da7f033dSHerbert Xu 		}
3344da7f033dSHerbert Xu 	}, {
334579cc6ab8Sraveendra padasalagi 		.alg = "sha3-224",
334679cc6ab8Sraveendra padasalagi 		.test = alg_test_hash,
334779cc6ab8Sraveendra padasalagi 		.fips_allowed = 1,
334879cc6ab8Sraveendra padasalagi 		.suite = {
334921c8e720SArd Biesheuvel 			.hash = __VECS(sha3_224_tv_template)
335079cc6ab8Sraveendra padasalagi 		}
335179cc6ab8Sraveendra padasalagi 	}, {
335279cc6ab8Sraveendra padasalagi 		.alg = "sha3-256",
335379cc6ab8Sraveendra padasalagi 		.test = alg_test_hash,
335479cc6ab8Sraveendra padasalagi 		.fips_allowed = 1,
335579cc6ab8Sraveendra padasalagi 		.suite = {
335621c8e720SArd Biesheuvel 			.hash = __VECS(sha3_256_tv_template)
335779cc6ab8Sraveendra padasalagi 		}
335879cc6ab8Sraveendra padasalagi 	}, {
335979cc6ab8Sraveendra padasalagi 		.alg = "sha3-384",
336079cc6ab8Sraveendra padasalagi 		.test = alg_test_hash,
336179cc6ab8Sraveendra padasalagi 		.fips_allowed = 1,
336279cc6ab8Sraveendra padasalagi 		.suite = {
336321c8e720SArd Biesheuvel 			.hash = __VECS(sha3_384_tv_template)
336479cc6ab8Sraveendra padasalagi 		}
336579cc6ab8Sraveendra padasalagi 	}, {
336679cc6ab8Sraveendra padasalagi 		.alg = "sha3-512",
336779cc6ab8Sraveendra padasalagi 		.test = alg_test_hash,
336879cc6ab8Sraveendra padasalagi 		.fips_allowed = 1,
336979cc6ab8Sraveendra padasalagi 		.suite = {
337021c8e720SArd Biesheuvel 			.hash = __VECS(sha3_512_tv_template)
337179cc6ab8Sraveendra padasalagi 		}
337279cc6ab8Sraveendra padasalagi 	}, {
3373da7f033dSHerbert Xu 		.alg = "sha384",
3374da7f033dSHerbert Xu 		.test = alg_test_hash,
3375a1915d51SJarod Wilson 		.fips_allowed = 1,
3376da7f033dSHerbert Xu 		.suite = {
337721c8e720SArd Biesheuvel 			.hash = __VECS(sha384_tv_template)
3378da7f033dSHerbert Xu 		}
3379da7f033dSHerbert Xu 	}, {
3380da7f033dSHerbert Xu 		.alg = "sha512",
3381da7f033dSHerbert Xu 		.test = alg_test_hash,
3382a1915d51SJarod Wilson 		.fips_allowed = 1,
3383da7f033dSHerbert Xu 		.suite = {
338421c8e720SArd Biesheuvel 			.hash = __VECS(sha512_tv_template)
3385da7f033dSHerbert Xu 		}
3386da7f033dSHerbert Xu 	}, {
3387da7f033dSHerbert Xu 		.alg = "tgr128",
3388da7f033dSHerbert Xu 		.test = alg_test_hash,
3389da7f033dSHerbert Xu 		.suite = {
339021c8e720SArd Biesheuvel 			.hash = __VECS(tgr128_tv_template)
3391da7f033dSHerbert Xu 		}
3392da7f033dSHerbert Xu 	}, {
3393da7f033dSHerbert Xu 		.alg = "tgr160",
3394da7f033dSHerbert Xu 		.test = alg_test_hash,
3395da7f033dSHerbert Xu 		.suite = {
339621c8e720SArd Biesheuvel 			.hash = __VECS(tgr160_tv_template)
3397da7f033dSHerbert Xu 		}
3398da7f033dSHerbert Xu 	}, {
3399da7f033dSHerbert Xu 		.alg = "tgr192",
3400da7f033dSHerbert Xu 		.test = alg_test_hash,
3401da7f033dSHerbert Xu 		.suite = {
340221c8e720SArd Biesheuvel 			.hash = __VECS(tgr192_tv_template)
3403da7f033dSHerbert Xu 		}
3404da7f033dSHerbert Xu 	}, {
3405f1939f7cSShane Wang 		.alg = "vmac(aes)",
3406f1939f7cSShane Wang 		.test = alg_test_hash,
3407f1939f7cSShane Wang 		.suite = {
340821c8e720SArd Biesheuvel 			.hash = __VECS(aes_vmac128_tv_template)
3409f1939f7cSShane Wang 		}
3410f1939f7cSShane Wang 	}, {
3411da7f033dSHerbert Xu 		.alg = "wp256",
3412da7f033dSHerbert Xu 		.test = alg_test_hash,
3413da7f033dSHerbert Xu 		.suite = {
341421c8e720SArd Biesheuvel 			.hash = __VECS(wp256_tv_template)
3415da7f033dSHerbert Xu 		}
3416da7f033dSHerbert Xu 	}, {
3417da7f033dSHerbert Xu 		.alg = "wp384",
3418da7f033dSHerbert Xu 		.test = alg_test_hash,
3419da7f033dSHerbert Xu 		.suite = {
342021c8e720SArd Biesheuvel 			.hash = __VECS(wp384_tv_template)
3421da7f033dSHerbert Xu 		}
3422da7f033dSHerbert Xu 	}, {
3423da7f033dSHerbert Xu 		.alg = "wp512",
3424da7f033dSHerbert Xu 		.test = alg_test_hash,
3425da7f033dSHerbert Xu 		.suite = {
342621c8e720SArd Biesheuvel 			.hash = __VECS(wp512_tv_template)
3427da7f033dSHerbert Xu 		}
3428da7f033dSHerbert Xu 	}, {
3429da7f033dSHerbert Xu 		.alg = "xcbc(aes)",
3430da7f033dSHerbert Xu 		.test = alg_test_hash,
3431da7f033dSHerbert Xu 		.suite = {
343221c8e720SArd Biesheuvel 			.hash = __VECS(aes_xcbc128_tv_template)
3433da7f033dSHerbert Xu 		}
3434da7f033dSHerbert Xu 	}, {
3435da7f033dSHerbert Xu 		.alg = "xts(aes)",
34361aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
34372918aa8dSJarod Wilson 		.fips_allowed = 1,
3438da7f033dSHerbert Xu 		.suite = {
3439da7f033dSHerbert Xu 			.cipher = {
344021c8e720SArd Biesheuvel 				.enc = __VECS(aes_xts_enc_tv_template),
344121c8e720SArd Biesheuvel 				.dec = __VECS(aes_xts_dec_tv_template)
3442da7f033dSHerbert Xu 			}
3443da7f033dSHerbert Xu 		}
34440c01aed5SGeert Uytterhoeven 	}, {
34450840605eSJussi Kivilinna 		.alg = "xts(camellia)",
34460840605eSJussi Kivilinna 		.test = alg_test_skcipher,
34470840605eSJussi Kivilinna 		.suite = {
34480840605eSJussi Kivilinna 			.cipher = {
344921c8e720SArd Biesheuvel 				.enc = __VECS(camellia_xts_enc_tv_template),
345021c8e720SArd Biesheuvel 				.dec = __VECS(camellia_xts_dec_tv_template)
34510840605eSJussi Kivilinna 			}
34520840605eSJussi Kivilinna 		}
34530840605eSJussi Kivilinna 	}, {
34549b8b0405SJohannes Goetzfried 		.alg = "xts(cast6)",
34559b8b0405SJohannes Goetzfried 		.test = alg_test_skcipher,
34569b8b0405SJohannes Goetzfried 		.suite = {
34579b8b0405SJohannes Goetzfried 			.cipher = {
345821c8e720SArd Biesheuvel 				.enc = __VECS(cast6_xts_enc_tv_template),
345921c8e720SArd Biesheuvel 				.dec = __VECS(cast6_xts_dec_tv_template)
34609b8b0405SJohannes Goetzfried 			}
34619b8b0405SJohannes Goetzfried 		}
34629b8b0405SJohannes Goetzfried 	}, {
346318be20b9SJussi Kivilinna 		.alg = "xts(serpent)",
346418be20b9SJussi Kivilinna 		.test = alg_test_skcipher,
346518be20b9SJussi Kivilinna 		.suite = {
346618be20b9SJussi Kivilinna 			.cipher = {
346721c8e720SArd Biesheuvel 				.enc = __VECS(serpent_xts_enc_tv_template),
346821c8e720SArd Biesheuvel 				.dec = __VECS(serpent_xts_dec_tv_template)
346918be20b9SJussi Kivilinna 			}
347018be20b9SJussi Kivilinna 		}
347118be20b9SJussi Kivilinna 	}, {
3472aed265b9SJussi Kivilinna 		.alg = "xts(twofish)",
3473aed265b9SJussi Kivilinna 		.test = alg_test_skcipher,
3474aed265b9SJussi Kivilinna 		.suite = {
3475aed265b9SJussi Kivilinna 			.cipher = {
347621c8e720SArd Biesheuvel 				.enc = __VECS(tf_xts_enc_tv_template),
347721c8e720SArd Biesheuvel 				.dec = __VECS(tf_xts_dec_tv_template)
3478aed265b9SJussi Kivilinna 			}
3479aed265b9SJussi Kivilinna 		}
3480da7f033dSHerbert Xu 	}
3481da7f033dSHerbert Xu };
3482da7f033dSHerbert Xu 
34835714758bSJussi Kivilinna static bool alg_test_descs_checked;
34845714758bSJussi Kivilinna 
34855714758bSJussi Kivilinna static void alg_test_descs_check_order(void)
34865714758bSJussi Kivilinna {
34875714758bSJussi Kivilinna 	int i;
34885714758bSJussi Kivilinna 
34895714758bSJussi Kivilinna 	/* only check once */
34905714758bSJussi Kivilinna 	if (alg_test_descs_checked)
34915714758bSJussi Kivilinna 		return;
34925714758bSJussi Kivilinna 
34935714758bSJussi Kivilinna 	alg_test_descs_checked = true;
34945714758bSJussi Kivilinna 
34955714758bSJussi Kivilinna 	for (i = 1; i < ARRAY_SIZE(alg_test_descs); i++) {
34965714758bSJussi Kivilinna 		int diff = strcmp(alg_test_descs[i - 1].alg,
34975714758bSJussi Kivilinna 				  alg_test_descs[i].alg);
34985714758bSJussi Kivilinna 
34995714758bSJussi Kivilinna 		if (WARN_ON(diff > 0)) {
35005714758bSJussi Kivilinna 			pr_warn("testmgr: alg_test_descs entries in wrong order: '%s' before '%s'\n",
35015714758bSJussi Kivilinna 				alg_test_descs[i - 1].alg,
35025714758bSJussi Kivilinna 				alg_test_descs[i].alg);
35035714758bSJussi Kivilinna 		}
35045714758bSJussi Kivilinna 
35055714758bSJussi Kivilinna 		if (WARN_ON(diff == 0)) {
35065714758bSJussi Kivilinna 			pr_warn("testmgr: duplicate alg_test_descs entry: '%s'\n",
35075714758bSJussi Kivilinna 				alg_test_descs[i].alg);
35085714758bSJussi Kivilinna 		}
35095714758bSJussi Kivilinna 	}
35105714758bSJussi Kivilinna }
35115714758bSJussi Kivilinna 
35121aa4ecd9SHerbert Xu static int alg_find_test(const char *alg)
3513da7f033dSHerbert Xu {
3514da7f033dSHerbert Xu 	int start = 0;
3515da7f033dSHerbert Xu 	int end = ARRAY_SIZE(alg_test_descs);
3516da7f033dSHerbert Xu 
3517da7f033dSHerbert Xu 	while (start < end) {
3518da7f033dSHerbert Xu 		int i = (start + end) / 2;
3519da7f033dSHerbert Xu 		int diff = strcmp(alg_test_descs[i].alg, alg);
3520da7f033dSHerbert Xu 
3521da7f033dSHerbert Xu 		if (diff > 0) {
3522da7f033dSHerbert Xu 			end = i;
3523da7f033dSHerbert Xu 			continue;
3524da7f033dSHerbert Xu 		}
3525da7f033dSHerbert Xu 
3526da7f033dSHerbert Xu 		if (diff < 0) {
3527da7f033dSHerbert Xu 			start = i + 1;
3528da7f033dSHerbert Xu 			continue;
3529da7f033dSHerbert Xu 		}
3530da7f033dSHerbert Xu 
35311aa4ecd9SHerbert Xu 		return i;
3532da7f033dSHerbert Xu 	}
3533da7f033dSHerbert Xu 
35341aa4ecd9SHerbert Xu 	return -1;
35351aa4ecd9SHerbert Xu }
35361aa4ecd9SHerbert Xu 
35371aa4ecd9SHerbert Xu int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
35381aa4ecd9SHerbert Xu {
35391aa4ecd9SHerbert Xu 	int i;
3540a68f6610SHerbert Xu 	int j;
3541d12d6b6dSNeil Horman 	int rc;
35421aa4ecd9SHerbert Xu 
35439e5c9fe4SRichard W.M. Jones 	if (!fips_enabled && notests) {
35449e5c9fe4SRichard W.M. Jones 		printk_once(KERN_INFO "alg: self-tests disabled\n");
35459e5c9fe4SRichard W.M. Jones 		return 0;
35469e5c9fe4SRichard W.M. Jones 	}
35479e5c9fe4SRichard W.M. Jones 
35485714758bSJussi Kivilinna 	alg_test_descs_check_order();
35495714758bSJussi Kivilinna 
35501aa4ecd9SHerbert Xu 	if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) {
35511aa4ecd9SHerbert Xu 		char nalg[CRYPTO_MAX_ALG_NAME];
35521aa4ecd9SHerbert Xu 
35531aa4ecd9SHerbert Xu 		if (snprintf(nalg, sizeof(nalg), "ecb(%s)", alg) >=
35541aa4ecd9SHerbert Xu 		    sizeof(nalg))
35551aa4ecd9SHerbert Xu 			return -ENAMETOOLONG;
35561aa4ecd9SHerbert Xu 
35571aa4ecd9SHerbert Xu 		i = alg_find_test(nalg);
35581aa4ecd9SHerbert Xu 		if (i < 0)
35591aa4ecd9SHerbert Xu 			goto notest;
35601aa4ecd9SHerbert Xu 
3561a3bef3a3SJarod Wilson 		if (fips_enabled && !alg_test_descs[i].fips_allowed)
3562a3bef3a3SJarod Wilson 			goto non_fips_alg;
3563a3bef3a3SJarod Wilson 
3564941fb328SJarod Wilson 		rc = alg_test_cipher(alg_test_descs + i, driver, type, mask);
3565941fb328SJarod Wilson 		goto test_done;
35661aa4ecd9SHerbert Xu 	}
35671aa4ecd9SHerbert Xu 
35681aa4ecd9SHerbert Xu 	i = alg_find_test(alg);
3569a68f6610SHerbert Xu 	j = alg_find_test(driver);
3570a68f6610SHerbert Xu 	if (i < 0 && j < 0)
35711aa4ecd9SHerbert Xu 		goto notest;
35721aa4ecd9SHerbert Xu 
3573a68f6610SHerbert Xu 	if (fips_enabled && ((i >= 0 && !alg_test_descs[i].fips_allowed) ||
3574a68f6610SHerbert Xu 			     (j >= 0 && !alg_test_descs[j].fips_allowed)))
3575a3bef3a3SJarod Wilson 		goto non_fips_alg;
3576a3bef3a3SJarod Wilson 
3577a68f6610SHerbert Xu 	rc = 0;
3578a68f6610SHerbert Xu 	if (i >= 0)
3579a68f6610SHerbert Xu 		rc |= alg_test_descs[i].test(alg_test_descs + i, driver,
35801aa4ecd9SHerbert Xu 					     type, mask);
3581032c8cacSCristian Stoica 	if (j >= 0 && j != i)
3582a68f6610SHerbert Xu 		rc |= alg_test_descs[j].test(alg_test_descs + j, driver,
3583a68f6610SHerbert Xu 					     type, mask);
3584a68f6610SHerbert Xu 
3585941fb328SJarod Wilson test_done:
3586d12d6b6dSNeil Horman 	if (fips_enabled && rc)
3587d12d6b6dSNeil Horman 		panic("%s: %s alg self test failed in fips mode!\n", driver, alg);
3588d12d6b6dSNeil Horman 
358929ecd4abSJarod Wilson 	if (fips_enabled && !rc)
35903e8cffd4SMasanari Iida 		pr_info("alg: self-tests for %s (%s) passed\n", driver, alg);
359129ecd4abSJarod Wilson 
3592d12d6b6dSNeil Horman 	return rc;
35931aa4ecd9SHerbert Xu 
35941aa4ecd9SHerbert Xu notest:
3595da7f033dSHerbert Xu 	printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver);
3596da7f033dSHerbert Xu 	return 0;
3597a3bef3a3SJarod Wilson non_fips_alg:
3598a3bef3a3SJarod Wilson 	return -EINVAL;
3599da7f033dSHerbert Xu }
36000b767f96SAlexander Shishkin 
3601326a6346SHerbert Xu #endif /* CONFIG_CRYPTO_MANAGER_DISABLE_TESTS */
36020b767f96SAlexander Shishkin 
3603da7f033dSHerbert Xu EXPORT_SYMBOL_GPL(alg_test);
3604