xref: /openbmc/linux/crypto/testmgr.c (revision cb9dde88)
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 aead_test_suite {
80da7f033dSHerbert Xu 	struct {
81b13b1e0cSEric Biggers 		const struct aead_testvec *vecs;
82da7f033dSHerbert Xu 		unsigned int count;
83da7f033dSHerbert Xu 	} enc, dec;
84da7f033dSHerbert Xu };
85da7f033dSHerbert Xu 
86da7f033dSHerbert Xu struct cipher_test_suite {
87b13b1e0cSEric Biggers 	const struct cipher_testvec *vecs;
88da7f033dSHerbert Xu 	unsigned int count;
89da7f033dSHerbert Xu };
90da7f033dSHerbert Xu 
91da7f033dSHerbert Xu struct comp_test_suite {
92da7f033dSHerbert Xu 	struct {
93b13b1e0cSEric Biggers 		const struct comp_testvec *vecs;
94da7f033dSHerbert Xu 		unsigned int count;
95da7f033dSHerbert Xu 	} comp, decomp;
96da7f033dSHerbert Xu };
97da7f033dSHerbert Xu 
98da7f033dSHerbert Xu struct hash_test_suite {
99b13b1e0cSEric Biggers 	const struct hash_testvec *vecs;
100da7f033dSHerbert Xu 	unsigned int count;
101da7f033dSHerbert Xu };
102da7f033dSHerbert Xu 
1037647d6ceSJarod Wilson struct cprng_test_suite {
104b13b1e0cSEric Biggers 	const struct cprng_testvec *vecs;
1057647d6ceSJarod Wilson 	unsigned int count;
1067647d6ceSJarod Wilson };
1077647d6ceSJarod Wilson 
10864d1cdfbSStephan Mueller struct drbg_test_suite {
109b13b1e0cSEric Biggers 	const struct drbg_testvec *vecs;
11064d1cdfbSStephan Mueller 	unsigned int count;
11164d1cdfbSStephan Mueller };
11264d1cdfbSStephan Mueller 
113946cc463STadeusz Struk struct akcipher_test_suite {
114b13b1e0cSEric Biggers 	const struct akcipher_testvec *vecs;
115946cc463STadeusz Struk 	unsigned int count;
116946cc463STadeusz Struk };
117946cc463STadeusz Struk 
118802c7f1cSSalvatore Benedetto struct kpp_test_suite {
119b13b1e0cSEric Biggers 	const struct kpp_testvec *vecs;
120802c7f1cSSalvatore Benedetto 	unsigned int count;
121802c7f1cSSalvatore Benedetto };
122802c7f1cSSalvatore Benedetto 
123da7f033dSHerbert Xu struct alg_test_desc {
124da7f033dSHerbert Xu 	const char *alg;
125da7f033dSHerbert Xu 	int (*test)(const struct alg_test_desc *desc, const char *driver,
126da7f033dSHerbert Xu 		    u32 type, u32 mask);
127a1915d51SJarod Wilson 	int fips_allowed;	/* set if alg is allowed in fips mode */
128da7f033dSHerbert Xu 
129da7f033dSHerbert Xu 	union {
130da7f033dSHerbert Xu 		struct aead_test_suite aead;
131da7f033dSHerbert Xu 		struct cipher_test_suite cipher;
132da7f033dSHerbert Xu 		struct comp_test_suite comp;
133da7f033dSHerbert Xu 		struct hash_test_suite hash;
1347647d6ceSJarod Wilson 		struct cprng_test_suite cprng;
13564d1cdfbSStephan Mueller 		struct drbg_test_suite drbg;
136946cc463STadeusz Struk 		struct akcipher_test_suite akcipher;
137802c7f1cSSalvatore Benedetto 		struct kpp_test_suite kpp;
138da7f033dSHerbert Xu 	} suite;
139da7f033dSHerbert Xu };
140da7f033dSHerbert Xu 
141b13b1e0cSEric Biggers static const unsigned int IDX[8] = {
142b13b1e0cSEric Biggers 	IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 };
143da7f033dSHerbert Xu 
144da7f033dSHerbert Xu static void hexdump(unsigned char *buf, unsigned int len)
145da7f033dSHerbert Xu {
146da7f033dSHerbert Xu 	print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
147da7f033dSHerbert Xu 			16, 1,
148da7f033dSHerbert Xu 			buf, len, false);
149da7f033dSHerbert Xu }
150da7f033dSHerbert Xu 
151f8b0d4d0SHerbert Xu static int testmgr_alloc_buf(char *buf[XBUFSIZE])
152f8b0d4d0SHerbert Xu {
153f8b0d4d0SHerbert Xu 	int i;
154f8b0d4d0SHerbert Xu 
155f8b0d4d0SHerbert Xu 	for (i = 0; i < XBUFSIZE; i++) {
156f8b0d4d0SHerbert Xu 		buf[i] = (void *)__get_free_page(GFP_KERNEL);
157f8b0d4d0SHerbert Xu 		if (!buf[i])
158f8b0d4d0SHerbert Xu 			goto err_free_buf;
159f8b0d4d0SHerbert Xu 	}
160f8b0d4d0SHerbert Xu 
161f8b0d4d0SHerbert Xu 	return 0;
162f8b0d4d0SHerbert Xu 
163f8b0d4d0SHerbert Xu err_free_buf:
164f8b0d4d0SHerbert Xu 	while (i-- > 0)
165f8b0d4d0SHerbert Xu 		free_page((unsigned long)buf[i]);
166f8b0d4d0SHerbert Xu 
167f8b0d4d0SHerbert Xu 	return -ENOMEM;
168f8b0d4d0SHerbert Xu }
169f8b0d4d0SHerbert Xu 
170f8b0d4d0SHerbert Xu static void testmgr_free_buf(char *buf[XBUFSIZE])
171f8b0d4d0SHerbert Xu {
172f8b0d4d0SHerbert Xu 	int i;
173f8b0d4d0SHerbert Xu 
174f8b0d4d0SHerbert Xu 	for (i = 0; i < XBUFSIZE; i++)
175f8b0d4d0SHerbert Xu 		free_page((unsigned long)buf[i]);
176f8b0d4d0SHerbert Xu }
177f8b0d4d0SHerbert Xu 
178466d7b9fSKamil Konieczny static int ahash_guard_result(char *result, char c, int size)
179466d7b9fSKamil Konieczny {
180466d7b9fSKamil Konieczny 	int i;
181466d7b9fSKamil Konieczny 
182466d7b9fSKamil Konieczny 	for (i = 0; i < size; i++) {
183466d7b9fSKamil Konieczny 		if (result[i] != c)
184466d7b9fSKamil Konieczny 			return -EINVAL;
185466d7b9fSKamil Konieczny 	}
186466d7b9fSKamil Konieczny 
187466d7b9fSKamil Konieczny 	return 0;
188466d7b9fSKamil Konieczny }
189466d7b9fSKamil Konieczny 
190018ba95cSWang, Rui Y static int ahash_partial_update(struct ahash_request **preq,
191b13b1e0cSEric Biggers 	struct crypto_ahash *tfm, const struct hash_testvec *template,
192018ba95cSWang, Rui Y 	void *hash_buff, int k, int temp, struct scatterlist *sg,
1937f397136SGilad Ben-Yossef 	const char *algo, char *result, struct crypto_wait *wait)
194018ba95cSWang, Rui Y {
195018ba95cSWang, Rui Y 	char *state;
196018ba95cSWang, Rui Y 	struct ahash_request *req;
197018ba95cSWang, Rui Y 	int statesize, ret = -EINVAL;
198da1729ceSJoey Pabalinas 	static const unsigned char guard[] = { 0x00, 0xba, 0xad, 0x00 };
199466d7b9fSKamil Konieczny 	int digestsize = crypto_ahash_digestsize(tfm);
200018ba95cSWang, Rui Y 
201018ba95cSWang, Rui Y 	req = *preq;
202018ba95cSWang, Rui Y 	statesize = crypto_ahash_statesize(
203018ba95cSWang, Rui Y 			crypto_ahash_reqtfm(req));
2047bcb87bcSJan Stancek 	state = kmalloc(statesize + sizeof(guard), GFP_KERNEL);
205018ba95cSWang, Rui Y 	if (!state) {
206cf3f9609SGilad Ben-Yossef 		pr_err("alg: hash: Failed to alloc state for %s\n", algo);
207018ba95cSWang, Rui Y 		goto out_nostate;
208018ba95cSWang, Rui Y 	}
2097bcb87bcSJan Stancek 	memcpy(state + statesize, guard, sizeof(guard));
210466d7b9fSKamil Konieczny 	memset(result, 1, digestsize);
211018ba95cSWang, Rui Y 	ret = crypto_ahash_export(req, state);
2127bcb87bcSJan Stancek 	WARN_ON(memcmp(state + statesize, guard, sizeof(guard)));
213018ba95cSWang, Rui Y 	if (ret) {
214cf3f9609SGilad Ben-Yossef 		pr_err("alg: hash: Failed to export() for %s\n", algo);
215018ba95cSWang, Rui Y 		goto out;
216018ba95cSWang, Rui Y 	}
217466d7b9fSKamil Konieczny 	ret = ahash_guard_result(result, 1, digestsize);
218466d7b9fSKamil Konieczny 	if (ret) {
219466d7b9fSKamil Konieczny 		pr_err("alg: hash: Failed, export used req->result for %s\n",
220466d7b9fSKamil Konieczny 		       algo);
221466d7b9fSKamil Konieczny 		goto out;
222466d7b9fSKamil Konieczny 	}
223018ba95cSWang, Rui Y 	ahash_request_free(req);
224018ba95cSWang, Rui Y 	req = ahash_request_alloc(tfm, GFP_KERNEL);
225018ba95cSWang, Rui Y 	if (!req) {
226018ba95cSWang, Rui Y 		pr_err("alg: hash: Failed to alloc request for %s\n", algo);
227018ba95cSWang, Rui Y 		goto out_noreq;
228018ba95cSWang, Rui Y 	}
229018ba95cSWang, Rui Y 	ahash_request_set_callback(req,
230018ba95cSWang, Rui Y 		CRYPTO_TFM_REQ_MAY_BACKLOG,
2317f397136SGilad Ben-Yossef 		crypto_req_done, wait);
232018ba95cSWang, Rui Y 
233018ba95cSWang, Rui Y 	memcpy(hash_buff, template->plaintext + temp,
234018ba95cSWang, Rui Y 		template->tap[k]);
235018ba95cSWang, Rui Y 	sg_init_one(&sg[0], hash_buff, template->tap[k]);
236018ba95cSWang, Rui Y 	ahash_request_set_crypt(req, sg, result, template->tap[k]);
237018ba95cSWang, Rui Y 	ret = crypto_ahash_import(req, state);
238018ba95cSWang, Rui Y 	if (ret) {
239018ba95cSWang, Rui Y 		pr_err("alg: hash: Failed to import() for %s\n", algo);
240018ba95cSWang, Rui Y 		goto out;
241018ba95cSWang, Rui Y 	}
242466d7b9fSKamil Konieczny 	ret = ahash_guard_result(result, 1, digestsize);
243466d7b9fSKamil Konieczny 	if (ret) {
244466d7b9fSKamil Konieczny 		pr_err("alg: hash: Failed, import used req->result for %s\n",
245466d7b9fSKamil Konieczny 		       algo);
246466d7b9fSKamil Konieczny 		goto out;
247466d7b9fSKamil Konieczny 	}
2487f397136SGilad Ben-Yossef 	ret = crypto_wait_req(crypto_ahash_update(req), wait);
249018ba95cSWang, Rui Y 	if (ret)
250018ba95cSWang, Rui Y 		goto out;
251018ba95cSWang, Rui Y 	*preq = req;
252018ba95cSWang, Rui Y 	ret = 0;
253018ba95cSWang, Rui Y 	goto out_noreq;
254018ba95cSWang, Rui Y out:
255018ba95cSWang, Rui Y 	ahash_request_free(req);
256018ba95cSWang, Rui Y out_noreq:
257018ba95cSWang, Rui Y 	kfree(state);
258018ba95cSWang, Rui Y out_nostate:
259018ba95cSWang, Rui Y 	return ret;
260018ba95cSWang, Rui Y }
261018ba95cSWang, Rui Y 
26276715095SGilad Ben-Yossef enum hash_test {
26376715095SGilad Ben-Yossef 	HASH_TEST_DIGEST,
26476715095SGilad Ben-Yossef 	HASH_TEST_FINAL,
26576715095SGilad Ben-Yossef 	HASH_TEST_FINUP
26676715095SGilad Ben-Yossef };
26776715095SGilad Ben-Yossef 
268b13b1e0cSEric Biggers static int __test_hash(struct crypto_ahash *tfm,
269b13b1e0cSEric Biggers 		       const struct hash_testvec *template, unsigned int tcount,
27076715095SGilad Ben-Yossef 		       enum hash_test test_type, const int align_offset)
271da7f033dSHerbert Xu {
272da7f033dSHerbert Xu 	const char *algo = crypto_tfm_alg_driver_name(crypto_ahash_tfm(tfm));
273e93acd6fSAndrew Lutomirski 	size_t digest_size = crypto_ahash_digestsize(tfm);
274da7f033dSHerbert Xu 	unsigned int i, j, k, temp;
275da7f033dSHerbert Xu 	struct scatterlist sg[8];
27629b77e5dSHoria Geanta 	char *result;
27729b77e5dSHoria Geanta 	char *key;
278da7f033dSHerbert Xu 	struct ahash_request *req;
2797f397136SGilad Ben-Yossef 	struct crypto_wait wait;
280da7f033dSHerbert Xu 	void *hash_buff;
281f8b0d4d0SHerbert Xu 	char *xbuf[XBUFSIZE];
282f8b0d4d0SHerbert Xu 	int ret = -ENOMEM;
283f8b0d4d0SHerbert Xu 
284e93acd6fSAndrew Lutomirski 	result = kmalloc(digest_size, GFP_KERNEL);
28529b77e5dSHoria Geanta 	if (!result)
28629b77e5dSHoria Geanta 		return ret;
28729b77e5dSHoria Geanta 	key = kmalloc(MAX_KEYLEN, GFP_KERNEL);
28829b77e5dSHoria Geanta 	if (!key)
28929b77e5dSHoria Geanta 		goto out_nobuf;
290f8b0d4d0SHerbert Xu 	if (testmgr_alloc_buf(xbuf))
291f8b0d4d0SHerbert Xu 		goto out_nobuf;
292da7f033dSHerbert Xu 
2937f397136SGilad Ben-Yossef 	crypto_init_wait(&wait);
294da7f033dSHerbert Xu 
295da7f033dSHerbert Xu 	req = ahash_request_alloc(tfm, GFP_KERNEL);
296da7f033dSHerbert Xu 	if (!req) {
297da7f033dSHerbert Xu 		printk(KERN_ERR "alg: hash: Failed to allocate request for "
298da7f033dSHerbert Xu 		       "%s\n", algo);
299da7f033dSHerbert Xu 		goto out_noreq;
300da7f033dSHerbert Xu 	}
301da7f033dSHerbert Xu 	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
3027f397136SGilad Ben-Yossef 				   crypto_req_done, &wait);
303da7f033dSHerbert Xu 
304a0cfae59SHerbert Xu 	j = 0;
305da7f033dSHerbert Xu 	for (i = 0; i < tcount; i++) {
306a0cfae59SHerbert Xu 		if (template[i].np)
307a0cfae59SHerbert Xu 			continue;
308a0cfae59SHerbert Xu 
309da5ffe11SJussi Kivilinna 		ret = -EINVAL;
310da5ffe11SJussi Kivilinna 		if (WARN_ON(align_offset + template[i].psize > PAGE_SIZE))
311da5ffe11SJussi Kivilinna 			goto out;
312da5ffe11SJussi Kivilinna 
313a0cfae59SHerbert Xu 		j++;
314e93acd6fSAndrew Lutomirski 		memset(result, 0, digest_size);
315da7f033dSHerbert Xu 
316da7f033dSHerbert Xu 		hash_buff = xbuf[0];
317da5ffe11SJussi Kivilinna 		hash_buff += align_offset;
318da7f033dSHerbert Xu 
319da7f033dSHerbert Xu 		memcpy(hash_buff, template[i].plaintext, template[i].psize);
320da7f033dSHerbert Xu 		sg_init_one(&sg[0], hash_buff, template[i].psize);
321da7f033dSHerbert Xu 
322da7f033dSHerbert Xu 		if (template[i].ksize) {
323da7f033dSHerbert Xu 			crypto_ahash_clear_flags(tfm, ~0);
32429b77e5dSHoria Geanta 			if (template[i].ksize > MAX_KEYLEN) {
32529b77e5dSHoria Geanta 				pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n",
32629b77e5dSHoria Geanta 				       j, algo, template[i].ksize, MAX_KEYLEN);
32729b77e5dSHoria Geanta 				ret = -EINVAL;
32829b77e5dSHoria Geanta 				goto out;
32929b77e5dSHoria Geanta 			}
33029b77e5dSHoria Geanta 			memcpy(key, template[i].key, template[i].ksize);
33129b77e5dSHoria Geanta 			ret = crypto_ahash_setkey(tfm, key, template[i].ksize);
332da7f033dSHerbert Xu 			if (ret) {
333da7f033dSHerbert Xu 				printk(KERN_ERR "alg: hash: setkey failed on "
334a0cfae59SHerbert Xu 				       "test %d for %s: ret=%d\n", j, algo,
335da7f033dSHerbert Xu 				       -ret);
336da7f033dSHerbert Xu 				goto out;
337da7f033dSHerbert Xu 			}
338da7f033dSHerbert Xu 		}
339da7f033dSHerbert Xu 
340da7f033dSHerbert Xu 		ahash_request_set_crypt(req, sg, result, template[i].psize);
34176715095SGilad Ben-Yossef 		switch (test_type) {
34276715095SGilad Ben-Yossef 		case HASH_TEST_DIGEST:
3437f397136SGilad Ben-Yossef 			ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
344a8f1a052SDavid S. Miller 			if (ret) {
345a8f1a052SDavid S. Miller 				pr_err("alg: hash: digest failed on test %d "
346a0cfae59SHerbert Xu 				       "for %s: ret=%d\n", j, algo, -ret);
347da7f033dSHerbert Xu 				goto out;
348da7f033dSHerbert Xu 			}
34976715095SGilad Ben-Yossef 			break;
35076715095SGilad Ben-Yossef 
35176715095SGilad Ben-Yossef 		case HASH_TEST_FINAL:
352466d7b9fSKamil Konieczny 			memset(result, 1, digest_size);
3537f397136SGilad Ben-Yossef 			ret = crypto_wait_req(crypto_ahash_init(req), &wait);
354a8f1a052SDavid S. Miller 			if (ret) {
355cf3f9609SGilad Ben-Yossef 				pr_err("alg: hash: init failed on test %d "
356a8f1a052SDavid S. Miller 				       "for %s: ret=%d\n", j, algo, -ret);
357a8f1a052SDavid S. Miller 				goto out;
358a8f1a052SDavid S. Miller 			}
359466d7b9fSKamil Konieczny 			ret = ahash_guard_result(result, 1, digest_size);
360466d7b9fSKamil Konieczny 			if (ret) {
361466d7b9fSKamil Konieczny 				pr_err("alg: hash: init failed on test %d "
362466d7b9fSKamil Konieczny 				       "for %s: used req->result\n", j, algo);
363466d7b9fSKamil Konieczny 				goto out;
364466d7b9fSKamil Konieczny 			}
3657f397136SGilad Ben-Yossef 			ret = crypto_wait_req(crypto_ahash_update(req), &wait);
366a8f1a052SDavid S. Miller 			if (ret) {
367cf3f9609SGilad Ben-Yossef 				pr_err("alg: hash: update failed on test %d "
368a8f1a052SDavid S. Miller 				       "for %s: ret=%d\n", j, algo, -ret);
369a8f1a052SDavid S. Miller 				goto out;
370a8f1a052SDavid S. Miller 			}
371466d7b9fSKamil Konieczny 			ret = ahash_guard_result(result, 1, digest_size);
372466d7b9fSKamil Konieczny 			if (ret) {
373466d7b9fSKamil Konieczny 				pr_err("alg: hash: update failed on test %d "
374466d7b9fSKamil Konieczny 				       "for %s: used req->result\n", j, algo);
375466d7b9fSKamil Konieczny 				goto out;
376466d7b9fSKamil Konieczny 			}
3777f397136SGilad Ben-Yossef 			ret = crypto_wait_req(crypto_ahash_final(req), &wait);
378a8f1a052SDavid S. Miller 			if (ret) {
379cf3f9609SGilad Ben-Yossef 				pr_err("alg: hash: final failed on test %d "
380a8f1a052SDavid S. Miller 				       "for %s: ret=%d\n", j, algo, -ret);
381a8f1a052SDavid S. Miller 				goto out;
382a8f1a052SDavid S. Miller 			}
38376715095SGilad Ben-Yossef 			break;
38476715095SGilad Ben-Yossef 
38576715095SGilad Ben-Yossef 		case HASH_TEST_FINUP:
38676715095SGilad Ben-Yossef 			memset(result, 1, digest_size);
38776715095SGilad Ben-Yossef 			ret = crypto_wait_req(crypto_ahash_init(req), &wait);
38876715095SGilad Ben-Yossef 			if (ret) {
38976715095SGilad Ben-Yossef 				pr_err("alg: hash: init failed on test %d "
39076715095SGilad Ben-Yossef 				       "for %s: ret=%d\n", j, algo, -ret);
39176715095SGilad Ben-Yossef 				goto out;
39276715095SGilad Ben-Yossef 			}
39376715095SGilad Ben-Yossef 			ret = ahash_guard_result(result, 1, digest_size);
39476715095SGilad Ben-Yossef 			if (ret) {
39576715095SGilad Ben-Yossef 				pr_err("alg: hash: init failed on test %d "
39676715095SGilad Ben-Yossef 				       "for %s: used req->result\n", j, algo);
39776715095SGilad Ben-Yossef 				goto out;
39876715095SGilad Ben-Yossef 			}
39976715095SGilad Ben-Yossef 			ret = crypto_wait_req(crypto_ahash_finup(req), &wait);
40076715095SGilad Ben-Yossef 			if (ret) {
40176715095SGilad Ben-Yossef 				pr_err("alg: hash: final failed on test %d "
40276715095SGilad Ben-Yossef 				       "for %s: ret=%d\n", j, algo, -ret);
40376715095SGilad Ben-Yossef 				goto out;
40476715095SGilad Ben-Yossef 			}
40576715095SGilad Ben-Yossef 			break;
406a8f1a052SDavid S. Miller 		}
407da7f033dSHerbert Xu 
408da7f033dSHerbert Xu 		if (memcmp(result, template[i].digest,
409da7f033dSHerbert Xu 			   crypto_ahash_digestsize(tfm))) {
410da7f033dSHerbert Xu 			printk(KERN_ERR "alg: hash: Test %d failed for %s\n",
411a0cfae59SHerbert Xu 			       j, algo);
412da7f033dSHerbert Xu 			hexdump(result, crypto_ahash_digestsize(tfm));
413da7f033dSHerbert Xu 			ret = -EINVAL;
414da7f033dSHerbert Xu 			goto out;
415da7f033dSHerbert Xu 		}
416da7f033dSHerbert Xu 	}
417da7f033dSHerbert Xu 
41876715095SGilad Ben-Yossef 	if (test_type)
41976715095SGilad Ben-Yossef 		goto out;
42076715095SGilad Ben-Yossef 
421da7f033dSHerbert Xu 	j = 0;
422da7f033dSHerbert Xu 	for (i = 0; i < tcount; i++) {
423da5ffe11SJussi Kivilinna 		/* alignment tests are only done with continuous buffers */
424da5ffe11SJussi Kivilinna 		if (align_offset != 0)
425da5ffe11SJussi Kivilinna 			break;
426da5ffe11SJussi Kivilinna 
4275f2b424eSCristian Stoica 		if (!template[i].np)
4285f2b424eSCristian Stoica 			continue;
4295f2b424eSCristian Stoica 
430da7f033dSHerbert Xu 		j++;
431e93acd6fSAndrew Lutomirski 		memset(result, 0, digest_size);
432da7f033dSHerbert Xu 
433da7f033dSHerbert Xu 		temp = 0;
434da7f033dSHerbert Xu 		sg_init_table(sg, template[i].np);
435fd57f22aSHerbert Xu 		ret = -EINVAL;
436da7f033dSHerbert Xu 		for (k = 0; k < template[i].np; k++) {
437fd57f22aSHerbert Xu 			if (WARN_ON(offset_in_page(IDX[k]) +
438fd57f22aSHerbert Xu 				    template[i].tap[k] > PAGE_SIZE))
439fd57f22aSHerbert Xu 				goto out;
440da7f033dSHerbert Xu 			sg_set_buf(&sg[k],
441da7f033dSHerbert Xu 				   memcpy(xbuf[IDX[k] >> PAGE_SHIFT] +
442da7f033dSHerbert Xu 					  offset_in_page(IDX[k]),
443da7f033dSHerbert Xu 					  template[i].plaintext + temp,
444da7f033dSHerbert Xu 					  template[i].tap[k]),
445da7f033dSHerbert Xu 				   template[i].tap[k]);
446da7f033dSHerbert Xu 			temp += template[i].tap[k];
447da7f033dSHerbert Xu 		}
448da7f033dSHerbert Xu 
449da7f033dSHerbert Xu 		if (template[i].ksize) {
45029b77e5dSHoria Geanta 			if (template[i].ksize > MAX_KEYLEN) {
45129b77e5dSHoria Geanta 				pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n",
4525f2b424eSCristian Stoica 				       j, algo, template[i].ksize, MAX_KEYLEN);
45329b77e5dSHoria Geanta 				ret = -EINVAL;
45429b77e5dSHoria Geanta 				goto out;
45529b77e5dSHoria Geanta 			}
456da7f033dSHerbert Xu 			crypto_ahash_clear_flags(tfm, ~0);
45729b77e5dSHoria Geanta 			memcpy(key, template[i].key, template[i].ksize);
4585f2b424eSCristian Stoica 			ret = crypto_ahash_setkey(tfm, key, template[i].ksize);
459da7f033dSHerbert Xu 
460da7f033dSHerbert Xu 			if (ret) {
461da7f033dSHerbert Xu 				printk(KERN_ERR "alg: hash: setkey "
462da7f033dSHerbert Xu 				       "failed on chunking test %d "
4635f2b424eSCristian Stoica 				       "for %s: ret=%d\n", j, algo, -ret);
464da7f033dSHerbert Xu 				goto out;
465da7f033dSHerbert Xu 			}
466da7f033dSHerbert Xu 		}
467da7f033dSHerbert Xu 
4685f2b424eSCristian Stoica 		ahash_request_set_crypt(req, sg, result, template[i].psize);
4697f397136SGilad Ben-Yossef 		ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
4707f397136SGilad Ben-Yossef 		if (ret) {
4717f397136SGilad Ben-Yossef 			pr_err("alg: hash: digest failed on chunking test %d for %s: ret=%d\n",
4727f397136SGilad Ben-Yossef 			       j, algo, -ret);
473da7f033dSHerbert Xu 			goto out;
474da7f033dSHerbert Xu 		}
475da7f033dSHerbert Xu 
476da7f033dSHerbert Xu 		if (memcmp(result, template[i].digest,
477da7f033dSHerbert Xu 			   crypto_ahash_digestsize(tfm))) {
478da7f033dSHerbert Xu 			printk(KERN_ERR "alg: hash: Chunking test %d "
479da7f033dSHerbert Xu 			       "failed for %s\n", j, algo);
480da7f033dSHerbert Xu 			hexdump(result, crypto_ahash_digestsize(tfm));
481da7f033dSHerbert Xu 			ret = -EINVAL;
482da7f033dSHerbert Xu 			goto out;
483da7f033dSHerbert Xu 		}
484da7f033dSHerbert Xu 	}
485da7f033dSHerbert Xu 
486018ba95cSWang, Rui Y 	/* partial update exercise */
487018ba95cSWang, Rui Y 	j = 0;
488018ba95cSWang, Rui Y 	for (i = 0; i < tcount; i++) {
489018ba95cSWang, Rui Y 		/* alignment tests are only done with continuous buffers */
490018ba95cSWang, Rui Y 		if (align_offset != 0)
491018ba95cSWang, Rui Y 			break;
492018ba95cSWang, Rui Y 
493018ba95cSWang, Rui Y 		if (template[i].np < 2)
494018ba95cSWang, Rui Y 			continue;
495018ba95cSWang, Rui Y 
496018ba95cSWang, Rui Y 		j++;
497e93acd6fSAndrew Lutomirski 		memset(result, 0, digest_size);
498018ba95cSWang, Rui Y 
499018ba95cSWang, Rui Y 		ret = -EINVAL;
500018ba95cSWang, Rui Y 		hash_buff = xbuf[0];
501018ba95cSWang, Rui Y 		memcpy(hash_buff, template[i].plaintext,
502018ba95cSWang, Rui Y 			template[i].tap[0]);
503018ba95cSWang, Rui Y 		sg_init_one(&sg[0], hash_buff, template[i].tap[0]);
504018ba95cSWang, Rui Y 
505018ba95cSWang, Rui Y 		if (template[i].ksize) {
506018ba95cSWang, Rui Y 			crypto_ahash_clear_flags(tfm, ~0);
507018ba95cSWang, Rui Y 			if (template[i].ksize > MAX_KEYLEN) {
508018ba95cSWang, Rui Y 				pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n",
509018ba95cSWang, Rui Y 					j, algo, template[i].ksize, MAX_KEYLEN);
510018ba95cSWang, Rui Y 				ret = -EINVAL;
511018ba95cSWang, Rui Y 				goto out;
512018ba95cSWang, Rui Y 			}
513018ba95cSWang, Rui Y 			memcpy(key, template[i].key, template[i].ksize);
514018ba95cSWang, Rui Y 			ret = crypto_ahash_setkey(tfm, key, template[i].ksize);
515018ba95cSWang, Rui Y 			if (ret) {
516018ba95cSWang, Rui Y 				pr_err("alg: hash: setkey failed on test %d for %s: ret=%d\n",
517018ba95cSWang, Rui Y 					j, algo, -ret);
518018ba95cSWang, Rui Y 				goto out;
519018ba95cSWang, Rui Y 			}
520018ba95cSWang, Rui Y 		}
521018ba95cSWang, Rui Y 
522018ba95cSWang, Rui Y 		ahash_request_set_crypt(req, sg, result, template[i].tap[0]);
5237f397136SGilad Ben-Yossef 		ret = crypto_wait_req(crypto_ahash_init(req), &wait);
524018ba95cSWang, Rui Y 		if (ret) {
525cf3f9609SGilad Ben-Yossef 			pr_err("alg: hash: init failed on test %d for %s: ret=%d\n",
526018ba95cSWang, Rui Y 				j, algo, -ret);
527018ba95cSWang, Rui Y 			goto out;
528018ba95cSWang, Rui Y 		}
5297f397136SGilad Ben-Yossef 		ret = crypto_wait_req(crypto_ahash_update(req), &wait);
530018ba95cSWang, Rui Y 		if (ret) {
531cf3f9609SGilad Ben-Yossef 			pr_err("alg: hash: update failed on test %d for %s: ret=%d\n",
532018ba95cSWang, Rui Y 				j, algo, -ret);
533018ba95cSWang, Rui Y 			goto out;
534018ba95cSWang, Rui Y 		}
535018ba95cSWang, Rui Y 
536018ba95cSWang, Rui Y 		temp = template[i].tap[0];
537018ba95cSWang, Rui Y 		for (k = 1; k < template[i].np; k++) {
538018ba95cSWang, Rui Y 			ret = ahash_partial_update(&req, tfm, &template[i],
539018ba95cSWang, Rui Y 				hash_buff, k, temp, &sg[0], algo, result,
5407f397136SGilad Ben-Yossef 				&wait);
541018ba95cSWang, Rui Y 			if (ret) {
542cf3f9609SGilad Ben-Yossef 				pr_err("alg: hash: partial update failed on test %d for %s: ret=%d\n",
543018ba95cSWang, Rui Y 					j, algo, -ret);
544018ba95cSWang, Rui Y 				goto out_noreq;
545018ba95cSWang, Rui Y 			}
546018ba95cSWang, Rui Y 			temp += template[i].tap[k];
547018ba95cSWang, Rui Y 		}
5487f397136SGilad Ben-Yossef 		ret = crypto_wait_req(crypto_ahash_final(req), &wait);
549018ba95cSWang, Rui Y 		if (ret) {
550cf3f9609SGilad Ben-Yossef 			pr_err("alg: hash: final failed on test %d for %s: ret=%d\n",
551018ba95cSWang, Rui Y 				j, algo, -ret);
552018ba95cSWang, Rui Y 			goto out;
553018ba95cSWang, Rui Y 		}
554018ba95cSWang, Rui Y 		if (memcmp(result, template[i].digest,
555018ba95cSWang, Rui Y 			   crypto_ahash_digestsize(tfm))) {
556018ba95cSWang, Rui Y 			pr_err("alg: hash: Partial Test %d failed for %s\n",
557018ba95cSWang, Rui Y 			       j, algo);
558018ba95cSWang, Rui Y 			hexdump(result, crypto_ahash_digestsize(tfm));
559018ba95cSWang, Rui Y 			ret = -EINVAL;
560018ba95cSWang, Rui Y 			goto out;
561018ba95cSWang, Rui Y 		}
562018ba95cSWang, Rui Y 	}
563018ba95cSWang, Rui Y 
564da7f033dSHerbert Xu 	ret = 0;
565da7f033dSHerbert Xu 
566da7f033dSHerbert Xu out:
567da7f033dSHerbert Xu 	ahash_request_free(req);
568da7f033dSHerbert Xu out_noreq:
569f8b0d4d0SHerbert Xu 	testmgr_free_buf(xbuf);
570f8b0d4d0SHerbert Xu out_nobuf:
57129b77e5dSHoria Geanta 	kfree(key);
57229b77e5dSHoria Geanta 	kfree(result);
573da7f033dSHerbert Xu 	return ret;
574da7f033dSHerbert Xu }
575da7f033dSHerbert Xu 
576b13b1e0cSEric Biggers static int test_hash(struct crypto_ahash *tfm,
577b13b1e0cSEric Biggers 		     const struct hash_testvec *template,
57876715095SGilad Ben-Yossef 		     unsigned int tcount, enum hash_test test_type)
579da5ffe11SJussi Kivilinna {
580da5ffe11SJussi Kivilinna 	unsigned int alignmask;
581da5ffe11SJussi Kivilinna 	int ret;
582da5ffe11SJussi Kivilinna 
58376715095SGilad Ben-Yossef 	ret = __test_hash(tfm, template, tcount, test_type, 0);
584da5ffe11SJussi Kivilinna 	if (ret)
585da5ffe11SJussi Kivilinna 		return ret;
586da5ffe11SJussi Kivilinna 
587da5ffe11SJussi Kivilinna 	/* test unaligned buffers, check with one byte offset */
58876715095SGilad Ben-Yossef 	ret = __test_hash(tfm, template, tcount, test_type, 1);
589da5ffe11SJussi Kivilinna 	if (ret)
590da5ffe11SJussi Kivilinna 		return ret;
591da5ffe11SJussi Kivilinna 
592da5ffe11SJussi Kivilinna 	alignmask = crypto_tfm_alg_alignmask(&tfm->base);
593da5ffe11SJussi Kivilinna 	if (alignmask) {
594da5ffe11SJussi Kivilinna 		/* Check if alignment mask for tfm is correctly set. */
59576715095SGilad Ben-Yossef 		ret = __test_hash(tfm, template, tcount, test_type,
596da5ffe11SJussi Kivilinna 				  alignmask + 1);
597da5ffe11SJussi Kivilinna 		if (ret)
598da5ffe11SJussi Kivilinna 			return ret;
599da5ffe11SJussi Kivilinna 	}
600da5ffe11SJussi Kivilinna 
601da5ffe11SJussi Kivilinna 	return 0;
602da5ffe11SJussi Kivilinna }
603da5ffe11SJussi Kivilinna 
604d8a32ac2SJussi Kivilinna static int __test_aead(struct crypto_aead *tfm, int enc,
605b13b1e0cSEric Biggers 		       const struct aead_testvec *template, unsigned int tcount,
60658dcf548SJussi Kivilinna 		       const bool diff_dst, const int align_offset)
607da7f033dSHerbert Xu {
608da7f033dSHerbert Xu 	const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm));
609da7f033dSHerbert Xu 	unsigned int i, j, k, n, temp;
610f8b0d4d0SHerbert Xu 	int ret = -ENOMEM;
611da7f033dSHerbert Xu 	char *q;
612da7f033dSHerbert Xu 	char *key;
613da7f033dSHerbert Xu 	struct aead_request *req;
614d8a32ac2SJussi Kivilinna 	struct scatterlist *sg;
615d8a32ac2SJussi Kivilinna 	struct scatterlist *sgout;
616d8a32ac2SJussi Kivilinna 	const char *e, *d;
6177f397136SGilad Ben-Yossef 	struct crypto_wait wait;
618424a5da6SCristian Stoica 	unsigned int authsize, iv_len;
619da7f033dSHerbert Xu 	void *input;
620d8a32ac2SJussi Kivilinna 	void *output;
621da7f033dSHerbert Xu 	void *assoc;
6229bac019dSTadeusz Struk 	char *iv;
623f8b0d4d0SHerbert Xu 	char *xbuf[XBUFSIZE];
624d8a32ac2SJussi Kivilinna 	char *xoutbuf[XBUFSIZE];
625f8b0d4d0SHerbert Xu 	char *axbuf[XBUFSIZE];
626f8b0d4d0SHerbert Xu 
6279bac019dSTadeusz Struk 	iv = kzalloc(MAX_IVLEN, GFP_KERNEL);
6289bac019dSTadeusz Struk 	if (!iv)
6299bac019dSTadeusz Struk 		return ret;
63029b77e5dSHoria Geanta 	key = kmalloc(MAX_KEYLEN, GFP_KERNEL);
63129b77e5dSHoria Geanta 	if (!key)
63229b77e5dSHoria Geanta 		goto out_noxbuf;
633f8b0d4d0SHerbert Xu 	if (testmgr_alloc_buf(xbuf))
634f8b0d4d0SHerbert Xu 		goto out_noxbuf;
635f8b0d4d0SHerbert Xu 	if (testmgr_alloc_buf(axbuf))
636f8b0d4d0SHerbert Xu 		goto out_noaxbuf;
637d8a32ac2SJussi Kivilinna 	if (diff_dst && testmgr_alloc_buf(xoutbuf))
638d8a32ac2SJussi Kivilinna 		goto out_nooutbuf;
639d8a32ac2SJussi Kivilinna 
640d8a32ac2SJussi Kivilinna 	/* avoid "the frame size is larger than 1024 bytes" compiler warning */
6416da2ec56SKees Cook 	sg = kmalloc(array3_size(sizeof(*sg), 8, (diff_dst ? 4 : 2)),
6426da2ec56SKees Cook 		     GFP_KERNEL);
643d8a32ac2SJussi Kivilinna 	if (!sg)
644d8a32ac2SJussi Kivilinna 		goto out_nosg;
6458a525fcdSHerbert Xu 	sgout = &sg[16];
646d8a32ac2SJussi Kivilinna 
647d8a32ac2SJussi Kivilinna 	if (diff_dst)
648d8a32ac2SJussi Kivilinna 		d = "-ddst";
649d8a32ac2SJussi Kivilinna 	else
650d8a32ac2SJussi Kivilinna 		d = "";
651d8a32ac2SJussi Kivilinna 
652da7f033dSHerbert Xu 	if (enc == ENCRYPT)
653da7f033dSHerbert Xu 		e = "encryption";
654da7f033dSHerbert Xu 	else
655da7f033dSHerbert Xu 		e = "decryption";
656da7f033dSHerbert Xu 
6577f397136SGilad Ben-Yossef 	crypto_init_wait(&wait);
658da7f033dSHerbert Xu 
659da7f033dSHerbert Xu 	req = aead_request_alloc(tfm, GFP_KERNEL);
660da7f033dSHerbert Xu 	if (!req) {
661d8a32ac2SJussi Kivilinna 		pr_err("alg: aead%s: Failed to allocate request for %s\n",
662d8a32ac2SJussi Kivilinna 		       d, algo);
663da7f033dSHerbert Xu 		goto out;
664da7f033dSHerbert Xu 	}
665da7f033dSHerbert Xu 
666da7f033dSHerbert Xu 	aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
6677f397136SGilad Ben-Yossef 				  crypto_req_done, &wait);
668da7f033dSHerbert Xu 
669abfa7f43SJerome Marchand 	iv_len = crypto_aead_ivsize(tfm);
670abfa7f43SJerome Marchand 
671da7f033dSHerbert Xu 	for (i = 0, j = 0; i < tcount; i++) {
67205b1d338SCristian Stoica 		if (template[i].np)
67305b1d338SCristian Stoica 			continue;
67405b1d338SCristian Stoica 
675da7f033dSHerbert Xu 		j++;
676da7f033dSHerbert Xu 
67758dcf548SJussi Kivilinna 		/* some templates have no input data but they will
678da7f033dSHerbert Xu 		 * touch input
679da7f033dSHerbert Xu 		 */
680da7f033dSHerbert Xu 		input = xbuf[0];
68158dcf548SJussi Kivilinna 		input += align_offset;
682da7f033dSHerbert Xu 		assoc = axbuf[0];
683da7f033dSHerbert Xu 
684fd57f22aSHerbert Xu 		ret = -EINVAL;
68558dcf548SJussi Kivilinna 		if (WARN_ON(align_offset + template[i].ilen >
68658dcf548SJussi Kivilinna 			    PAGE_SIZE || template[i].alen > PAGE_SIZE))
687fd57f22aSHerbert Xu 			goto out;
688fd57f22aSHerbert Xu 
689da7f033dSHerbert Xu 		memcpy(input, template[i].input, template[i].ilen);
690da7f033dSHerbert Xu 		memcpy(assoc, template[i].assoc, template[i].alen);
691da7f033dSHerbert Xu 		if (template[i].iv)
692424a5da6SCristian Stoica 			memcpy(iv, template[i].iv, iv_len);
693da7f033dSHerbert Xu 		else
694424a5da6SCristian Stoica 			memset(iv, 0, iv_len);
695da7f033dSHerbert Xu 
696da7f033dSHerbert Xu 		crypto_aead_clear_flags(tfm, ~0);
697da7f033dSHerbert Xu 		if (template[i].wk)
69805b1d338SCristian Stoica 			crypto_aead_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY);
699da7f033dSHerbert Xu 
70029b77e5dSHoria Geanta 		if (template[i].klen > MAX_KEYLEN) {
70129b77e5dSHoria Geanta 			pr_err("alg: aead%s: setkey failed on test %d for %s: key size %d > %d\n",
70229b77e5dSHoria Geanta 			       d, j, algo, template[i].klen,
70329b77e5dSHoria Geanta 			       MAX_KEYLEN);
70429b77e5dSHoria Geanta 			ret = -EINVAL;
70529b77e5dSHoria Geanta 			goto out;
70629b77e5dSHoria Geanta 		}
70729b77e5dSHoria Geanta 		memcpy(key, template[i].key, template[i].klen);
708da7f033dSHerbert Xu 
70905b1d338SCristian Stoica 		ret = crypto_aead_setkey(tfm, key, template[i].klen);
7100fae0c1eSYanjiang Jin 		if (template[i].fail == !ret) {
711d8a32ac2SJussi Kivilinna 			pr_err("alg: aead%s: setkey failed on test %d for %s: flags=%x\n",
712d8a32ac2SJussi Kivilinna 			       d, j, algo, crypto_aead_get_flags(tfm));
713da7f033dSHerbert Xu 			goto out;
714da7f033dSHerbert Xu 		} else if (ret)
715da7f033dSHerbert Xu 			continue;
716da7f033dSHerbert Xu 
717da7f033dSHerbert Xu 		authsize = abs(template[i].rlen - template[i].ilen);
718da7f033dSHerbert Xu 		ret = crypto_aead_setauthsize(tfm, authsize);
719da7f033dSHerbert Xu 		if (ret) {
720d8a32ac2SJussi Kivilinna 			pr_err("alg: aead%s: Failed to set authsize to %u on test %d for %s\n",
721d8a32ac2SJussi Kivilinna 			       d, authsize, j, algo);
722da7f033dSHerbert Xu 			goto out;
723da7f033dSHerbert Xu 		}
724da7f033dSHerbert Xu 
7258a525fcdSHerbert Xu 		k = !!template[i].alen;
7268a525fcdSHerbert Xu 		sg_init_table(sg, k + 1);
7278a525fcdSHerbert Xu 		sg_set_buf(&sg[0], assoc, template[i].alen);
7288a525fcdSHerbert Xu 		sg_set_buf(&sg[k], input,
72905b1d338SCristian Stoica 			   template[i].ilen + (enc ? authsize : 0));
730d8a32ac2SJussi Kivilinna 		output = input;
731d8a32ac2SJussi Kivilinna 
7328a525fcdSHerbert Xu 		if (diff_dst) {
7338a525fcdSHerbert Xu 			sg_init_table(sgout, k + 1);
7348a525fcdSHerbert Xu 			sg_set_buf(&sgout[0], assoc, template[i].alen);
7358a525fcdSHerbert Xu 
7368a525fcdSHerbert Xu 			output = xoutbuf[0];
7378a525fcdSHerbert Xu 			output += align_offset;
7388a525fcdSHerbert Xu 			sg_set_buf(&sgout[k], output,
7398a525fcdSHerbert Xu 				   template[i].rlen + (enc ? 0 : authsize));
7408a525fcdSHerbert Xu 		}
741da7f033dSHerbert Xu 
742d8a32ac2SJussi Kivilinna 		aead_request_set_crypt(req, sg, (diff_dst) ? sgout : sg,
743da7f033dSHerbert Xu 				       template[i].ilen, iv);
744da7f033dSHerbert Xu 
7458a525fcdSHerbert Xu 		aead_request_set_ad(req, template[i].alen);
746da7f033dSHerbert Xu 
7477f397136SGilad Ben-Yossef 		ret = crypto_wait_req(enc ? crypto_aead_encrypt(req)
7487f397136SGilad Ben-Yossef 				      : crypto_aead_decrypt(req), &wait);
749da7f033dSHerbert Xu 
750da7f033dSHerbert Xu 		switch (ret) {
751da7f033dSHerbert Xu 		case 0:
752e44a1b44SJarod Wilson 			if (template[i].novrfy) {
753e44a1b44SJarod Wilson 				/* verification was supposed to fail */
754d8a32ac2SJussi Kivilinna 				pr_err("alg: aead%s: %s failed on test %d for %s: ret was 0, expected -EBADMSG\n",
755d8a32ac2SJussi Kivilinna 				       d, e, j, algo);
756e44a1b44SJarod Wilson 				/* so really, we got a bad message */
757e44a1b44SJarod Wilson 				ret = -EBADMSG;
758e44a1b44SJarod Wilson 				goto out;
759e44a1b44SJarod Wilson 			}
760da7f033dSHerbert Xu 			break;
761e44a1b44SJarod Wilson 		case -EBADMSG:
762e44a1b44SJarod Wilson 			if (template[i].novrfy)
763e44a1b44SJarod Wilson 				/* verification failure was expected */
764e44a1b44SJarod Wilson 				continue;
765da7f033dSHerbert Xu 			/* fall through */
766da7f033dSHerbert Xu 		default:
767d8a32ac2SJussi Kivilinna 			pr_err("alg: aead%s: %s failed on test %d for %s: ret=%d\n",
768d8a32ac2SJussi Kivilinna 			       d, e, j, algo, -ret);
769da7f033dSHerbert Xu 			goto out;
770da7f033dSHerbert Xu 		}
771da7f033dSHerbert Xu 
772d8a32ac2SJussi Kivilinna 		q = output;
773da7f033dSHerbert Xu 		if (memcmp(q, template[i].result, template[i].rlen)) {
774d8a32ac2SJussi Kivilinna 			pr_err("alg: aead%s: Test %d failed on %s for %s\n",
775d8a32ac2SJussi Kivilinna 			       d, j, e, algo);
776da7f033dSHerbert Xu 			hexdump(q, template[i].rlen);
777da7f033dSHerbert Xu 			ret = -EINVAL;
778da7f033dSHerbert Xu 			goto out;
779da7f033dSHerbert Xu 		}
780da7f033dSHerbert Xu 	}
781da7f033dSHerbert Xu 
782da7f033dSHerbert Xu 	for (i = 0, j = 0; i < tcount; i++) {
78358dcf548SJussi Kivilinna 		/* alignment tests are only done with continuous buffers */
78458dcf548SJussi Kivilinna 		if (align_offset != 0)
78558dcf548SJussi Kivilinna 			break;
78658dcf548SJussi Kivilinna 
78705b1d338SCristian Stoica 		if (!template[i].np)
78805b1d338SCristian Stoica 			continue;
78905b1d338SCristian Stoica 
790da7f033dSHerbert Xu 		j++;
791da7f033dSHerbert Xu 
792da7f033dSHerbert Xu 		if (template[i].iv)
793abfa7f43SJerome Marchand 			memcpy(iv, template[i].iv, iv_len);
794da7f033dSHerbert Xu 		else
795da7f033dSHerbert Xu 			memset(iv, 0, MAX_IVLEN);
796da7f033dSHerbert Xu 
797da7f033dSHerbert Xu 		crypto_aead_clear_flags(tfm, ~0);
798da7f033dSHerbert Xu 		if (template[i].wk)
79905b1d338SCristian Stoica 			crypto_aead_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY);
80029b77e5dSHoria Geanta 		if (template[i].klen > MAX_KEYLEN) {
80129b77e5dSHoria Geanta 			pr_err("alg: aead%s: setkey failed on test %d for %s: key size %d > %d\n",
80205b1d338SCristian Stoica 			       d, j, algo, template[i].klen, MAX_KEYLEN);
80329b77e5dSHoria Geanta 			ret = -EINVAL;
80429b77e5dSHoria Geanta 			goto out;
80529b77e5dSHoria Geanta 		}
80629b77e5dSHoria Geanta 		memcpy(key, template[i].key, template[i].klen);
807da7f033dSHerbert Xu 
808da7f033dSHerbert Xu 		ret = crypto_aead_setkey(tfm, key, template[i].klen);
8090fae0c1eSYanjiang Jin 		if (template[i].fail == !ret) {
810d8a32ac2SJussi Kivilinna 			pr_err("alg: aead%s: setkey failed on chunk test %d for %s: flags=%x\n",
811d8a32ac2SJussi Kivilinna 			       d, j, algo, crypto_aead_get_flags(tfm));
812da7f033dSHerbert Xu 			goto out;
813da7f033dSHerbert Xu 		} else if (ret)
814da7f033dSHerbert Xu 			continue;
815da7f033dSHerbert Xu 
816da7f033dSHerbert Xu 		authsize = abs(template[i].rlen - template[i].ilen);
817da7f033dSHerbert Xu 
818da7f033dSHerbert Xu 		ret = -EINVAL;
8198a525fcdSHerbert Xu 		sg_init_table(sg, template[i].anp + template[i].np);
820d8a32ac2SJussi Kivilinna 		if (diff_dst)
8218a525fcdSHerbert Xu 			sg_init_table(sgout, template[i].anp + template[i].np);
8228a525fcdSHerbert Xu 
8238a525fcdSHerbert Xu 		ret = -EINVAL;
8248a525fcdSHerbert Xu 		for (k = 0, temp = 0; k < template[i].anp; k++) {
8258a525fcdSHerbert Xu 			if (WARN_ON(offset_in_page(IDX[k]) +
8268a525fcdSHerbert Xu 				    template[i].atap[k] > PAGE_SIZE))
8278a525fcdSHerbert Xu 				goto out;
8288a525fcdSHerbert Xu 			sg_set_buf(&sg[k],
8298a525fcdSHerbert Xu 				   memcpy(axbuf[IDX[k] >> PAGE_SHIFT] +
8308a525fcdSHerbert Xu 					  offset_in_page(IDX[k]),
8318a525fcdSHerbert Xu 					  template[i].assoc + temp,
8328a525fcdSHerbert Xu 					  template[i].atap[k]),
8338a525fcdSHerbert Xu 				   template[i].atap[k]);
8348a525fcdSHerbert Xu 			if (diff_dst)
8358a525fcdSHerbert Xu 				sg_set_buf(&sgout[k],
8368a525fcdSHerbert Xu 					   axbuf[IDX[k] >> PAGE_SHIFT] +
8378a525fcdSHerbert Xu 					   offset_in_page(IDX[k]),
8388a525fcdSHerbert Xu 					   template[i].atap[k]);
8398a525fcdSHerbert Xu 			temp += template[i].atap[k];
8408a525fcdSHerbert Xu 		}
8418a525fcdSHerbert Xu 
842da7f033dSHerbert Xu 		for (k = 0, temp = 0; k < template[i].np; k++) {
843da7f033dSHerbert Xu 			if (WARN_ON(offset_in_page(IDX[k]) +
844da7f033dSHerbert Xu 				    template[i].tap[k] > PAGE_SIZE))
845da7f033dSHerbert Xu 				goto out;
846da7f033dSHerbert Xu 
84705b1d338SCristian Stoica 			q = xbuf[IDX[k] >> PAGE_SHIFT] + offset_in_page(IDX[k]);
84805b1d338SCristian Stoica 			memcpy(q, template[i].input + temp, template[i].tap[k]);
8498a525fcdSHerbert Xu 			sg_set_buf(&sg[template[i].anp + k],
8508a525fcdSHerbert Xu 				   q, template[i].tap[k]);
851d8a32ac2SJussi Kivilinna 
852d8a32ac2SJussi Kivilinna 			if (diff_dst) {
853d8a32ac2SJussi Kivilinna 				q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
854d8a32ac2SJussi Kivilinna 				    offset_in_page(IDX[k]);
855d8a32ac2SJussi Kivilinna 
856d8a32ac2SJussi Kivilinna 				memset(q, 0, template[i].tap[k]);
857d8a32ac2SJussi Kivilinna 
8588a525fcdSHerbert Xu 				sg_set_buf(&sgout[template[i].anp + k],
8598a525fcdSHerbert Xu 					   q, template[i].tap[k]);
860d8a32ac2SJussi Kivilinna 			}
861d8a32ac2SJussi Kivilinna 
8628ec25c51SHoria Geanta 			n = template[i].tap[k];
8638ec25c51SHoria Geanta 			if (k == template[i].np - 1 && enc)
8648ec25c51SHoria Geanta 				n += authsize;
8658ec25c51SHoria Geanta 			if (offset_in_page(q) + n < PAGE_SIZE)
8668ec25c51SHoria Geanta 				q[n] = 0;
8678ec25c51SHoria Geanta 
868da7f033dSHerbert Xu 			temp += template[i].tap[k];
869da7f033dSHerbert Xu 		}
870da7f033dSHerbert Xu 
871da7f033dSHerbert Xu 		ret = crypto_aead_setauthsize(tfm, authsize);
872da7f033dSHerbert Xu 		if (ret) {
873d8a32ac2SJussi Kivilinna 			pr_err("alg: aead%s: Failed to set authsize to %u on chunk test %d for %s\n",
874d8a32ac2SJussi Kivilinna 			       d, authsize, j, algo);
875da7f033dSHerbert Xu 			goto out;
876da7f033dSHerbert Xu 		}
877da7f033dSHerbert Xu 
878da7f033dSHerbert Xu 		if (enc) {
8798a525fcdSHerbert Xu 			if (WARN_ON(sg[template[i].anp + k - 1].offset +
8808a525fcdSHerbert Xu 				    sg[template[i].anp + k - 1].length +
8818a525fcdSHerbert Xu 				    authsize > PAGE_SIZE)) {
882da7f033dSHerbert Xu 				ret = -EINVAL;
883da7f033dSHerbert Xu 				goto out;
884da7f033dSHerbert Xu 			}
885da7f033dSHerbert Xu 
886d8a32ac2SJussi Kivilinna 			if (diff_dst)
8878a525fcdSHerbert Xu 				sgout[template[i].anp + k - 1].length +=
8888a525fcdSHerbert Xu 					authsize;
8898a525fcdSHerbert Xu 			sg[template[i].anp + k - 1].length += authsize;
890da7f033dSHerbert Xu 		}
891da7f033dSHerbert Xu 
892d8a32ac2SJussi Kivilinna 		aead_request_set_crypt(req, sg, (diff_dst) ? sgout : sg,
893da7f033dSHerbert Xu 				       template[i].ilen,
894da7f033dSHerbert Xu 				       iv);
895da7f033dSHerbert Xu 
8968a525fcdSHerbert Xu 		aead_request_set_ad(req, template[i].alen);
897da7f033dSHerbert Xu 
8987f397136SGilad Ben-Yossef 		ret = crypto_wait_req(enc ? crypto_aead_encrypt(req)
8997f397136SGilad Ben-Yossef 				      : crypto_aead_decrypt(req), &wait);
900da7f033dSHerbert Xu 
901da7f033dSHerbert Xu 		switch (ret) {
902da7f033dSHerbert Xu 		case 0:
903e44a1b44SJarod Wilson 			if (template[i].novrfy) {
904e44a1b44SJarod Wilson 				/* verification was supposed to fail */
905d8a32ac2SJussi Kivilinna 				pr_err("alg: aead%s: %s failed on chunk test %d for %s: ret was 0, expected -EBADMSG\n",
906d8a32ac2SJussi Kivilinna 				       d, e, j, algo);
907e44a1b44SJarod Wilson 				/* so really, we got a bad message */
908e44a1b44SJarod Wilson 				ret = -EBADMSG;
909e44a1b44SJarod Wilson 				goto out;
910e44a1b44SJarod Wilson 			}
911da7f033dSHerbert Xu 			break;
912e44a1b44SJarod Wilson 		case -EBADMSG:
913e44a1b44SJarod Wilson 			if (template[i].novrfy)
914e44a1b44SJarod Wilson 				/* verification failure was expected */
915e44a1b44SJarod Wilson 				continue;
916da7f033dSHerbert Xu 			/* fall through */
917da7f033dSHerbert Xu 		default:
918d8a32ac2SJussi Kivilinna 			pr_err("alg: aead%s: %s failed on chunk test %d for %s: ret=%d\n",
919d8a32ac2SJussi Kivilinna 			       d, e, j, algo, -ret);
920da7f033dSHerbert Xu 			goto out;
921da7f033dSHerbert Xu 		}
922da7f033dSHerbert Xu 
923da7f033dSHerbert Xu 		ret = -EINVAL;
924da7f033dSHerbert Xu 		for (k = 0, temp = 0; k < template[i].np; k++) {
925d8a32ac2SJussi Kivilinna 			if (diff_dst)
926d8a32ac2SJussi Kivilinna 				q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
927d8a32ac2SJussi Kivilinna 				    offset_in_page(IDX[k]);
928d8a32ac2SJussi Kivilinna 			else
929da7f033dSHerbert Xu 				q = xbuf[IDX[k] >> PAGE_SHIFT] +
930da7f033dSHerbert Xu 				    offset_in_page(IDX[k]);
931da7f033dSHerbert Xu 
932da7f033dSHerbert Xu 			n = template[i].tap[k];
933da7f033dSHerbert Xu 			if (k == template[i].np - 1)
934da7f033dSHerbert Xu 				n += enc ? authsize : -authsize;
935da7f033dSHerbert Xu 
936da7f033dSHerbert Xu 			if (memcmp(q, template[i].result + temp, n)) {
937d8a32ac2SJussi Kivilinna 				pr_err("alg: aead%s: Chunk test %d failed on %s at page %u for %s\n",
938d8a32ac2SJussi Kivilinna 				       d, j, e, k, algo);
939da7f033dSHerbert Xu 				hexdump(q, n);
940da7f033dSHerbert Xu 				goto out;
941da7f033dSHerbert Xu 			}
942da7f033dSHerbert Xu 
943da7f033dSHerbert Xu 			q += n;
944da7f033dSHerbert Xu 			if (k == template[i].np - 1 && !enc) {
945d8a32ac2SJussi Kivilinna 				if (!diff_dst &&
946d8a32ac2SJussi Kivilinna 					memcmp(q, template[i].input +
947da7f033dSHerbert Xu 					      temp + n, authsize))
948da7f033dSHerbert Xu 					n = authsize;
949da7f033dSHerbert Xu 				else
950da7f033dSHerbert Xu 					n = 0;
951da7f033dSHerbert Xu 			} else {
95205b1d338SCristian Stoica 				for (n = 0; offset_in_page(q + n) && q[n]; n++)
953da7f033dSHerbert Xu 					;
954da7f033dSHerbert Xu 			}
955da7f033dSHerbert Xu 			if (n) {
956d8a32ac2SJussi Kivilinna 				pr_err("alg: aead%s: Result buffer corruption in chunk test %d on %s at page %u for %s: %u bytes:\n",
957d8a32ac2SJussi Kivilinna 				       d, j, e, k, algo, n);
958da7f033dSHerbert Xu 				hexdump(q, n);
959da7f033dSHerbert Xu 				goto out;
960da7f033dSHerbert Xu 			}
961da7f033dSHerbert Xu 
962da7f033dSHerbert Xu 			temp += template[i].tap[k];
963da7f033dSHerbert Xu 		}
964da7f033dSHerbert Xu 	}
965da7f033dSHerbert Xu 
966da7f033dSHerbert Xu 	ret = 0;
967da7f033dSHerbert Xu 
968da7f033dSHerbert Xu out:
969da7f033dSHerbert Xu 	aead_request_free(req);
970d8a32ac2SJussi Kivilinna 	kfree(sg);
971d8a32ac2SJussi Kivilinna out_nosg:
972d8a32ac2SJussi Kivilinna 	if (diff_dst)
973d8a32ac2SJussi Kivilinna 		testmgr_free_buf(xoutbuf);
974d8a32ac2SJussi Kivilinna out_nooutbuf:
975f8b0d4d0SHerbert Xu 	testmgr_free_buf(axbuf);
976f8b0d4d0SHerbert Xu out_noaxbuf:
977f8b0d4d0SHerbert Xu 	testmgr_free_buf(xbuf);
978f8b0d4d0SHerbert Xu out_noxbuf:
97929b77e5dSHoria Geanta 	kfree(key);
9809bac019dSTadeusz Struk 	kfree(iv);
981da7f033dSHerbert Xu 	return ret;
982da7f033dSHerbert Xu }
983da7f033dSHerbert Xu 
984d8a32ac2SJussi Kivilinna static int test_aead(struct crypto_aead *tfm, int enc,
985b13b1e0cSEric Biggers 		     const struct aead_testvec *template, unsigned int tcount)
986d8a32ac2SJussi Kivilinna {
98758dcf548SJussi Kivilinna 	unsigned int alignmask;
988d8a32ac2SJussi Kivilinna 	int ret;
989d8a32ac2SJussi Kivilinna 
990d8a32ac2SJussi Kivilinna 	/* test 'dst == src' case */
99158dcf548SJussi Kivilinna 	ret = __test_aead(tfm, enc, template, tcount, false, 0);
992d8a32ac2SJussi Kivilinna 	if (ret)
993d8a32ac2SJussi Kivilinna 		return ret;
994d8a32ac2SJussi Kivilinna 
995d8a32ac2SJussi Kivilinna 	/* test 'dst != src' case */
99658dcf548SJussi Kivilinna 	ret = __test_aead(tfm, enc, template, tcount, true, 0);
99758dcf548SJussi Kivilinna 	if (ret)
99858dcf548SJussi Kivilinna 		return ret;
99958dcf548SJussi Kivilinna 
100058dcf548SJussi Kivilinna 	/* test unaligned buffers, check with one byte offset */
100158dcf548SJussi Kivilinna 	ret = __test_aead(tfm, enc, template, tcount, true, 1);
100258dcf548SJussi Kivilinna 	if (ret)
100358dcf548SJussi Kivilinna 		return ret;
100458dcf548SJussi Kivilinna 
100558dcf548SJussi Kivilinna 	alignmask = crypto_tfm_alg_alignmask(&tfm->base);
100658dcf548SJussi Kivilinna 	if (alignmask) {
100758dcf548SJussi Kivilinna 		/* Check if alignment mask for tfm is correctly set. */
100858dcf548SJussi Kivilinna 		ret = __test_aead(tfm, enc, template, tcount, true,
100958dcf548SJussi Kivilinna 				  alignmask + 1);
101058dcf548SJussi Kivilinna 		if (ret)
101158dcf548SJussi Kivilinna 			return ret;
101258dcf548SJussi Kivilinna 	}
101358dcf548SJussi Kivilinna 
101458dcf548SJussi Kivilinna 	return 0;
1015d8a32ac2SJussi Kivilinna }
1016d8a32ac2SJussi Kivilinna 
10171aa4ecd9SHerbert Xu static int test_cipher(struct crypto_cipher *tfm, int enc,
1018b13b1e0cSEric Biggers 		       const struct cipher_testvec *template,
1019b13b1e0cSEric Biggers 		       unsigned int tcount)
10201aa4ecd9SHerbert Xu {
10211aa4ecd9SHerbert Xu 	const char *algo = crypto_tfm_alg_driver_name(crypto_cipher_tfm(tfm));
10221aa4ecd9SHerbert Xu 	unsigned int i, j, k;
10231aa4ecd9SHerbert Xu 	char *q;
10241aa4ecd9SHerbert Xu 	const char *e;
102592a4c9feSEric Biggers 	const char *input, *result;
10261aa4ecd9SHerbert Xu 	void *data;
1027f8b0d4d0SHerbert Xu 	char *xbuf[XBUFSIZE];
1028f8b0d4d0SHerbert Xu 	int ret = -ENOMEM;
1029f8b0d4d0SHerbert Xu 
1030f8b0d4d0SHerbert Xu 	if (testmgr_alloc_buf(xbuf))
1031f8b0d4d0SHerbert Xu 		goto out_nobuf;
10321aa4ecd9SHerbert Xu 
10331aa4ecd9SHerbert Xu 	if (enc == ENCRYPT)
10341aa4ecd9SHerbert Xu 	        e = "encryption";
10351aa4ecd9SHerbert Xu 	else
10361aa4ecd9SHerbert Xu 		e = "decryption";
10371aa4ecd9SHerbert Xu 
10381aa4ecd9SHerbert Xu 	j = 0;
10391aa4ecd9SHerbert Xu 	for (i = 0; i < tcount; i++) {
10401aa4ecd9SHerbert Xu 		if (template[i].np)
10411aa4ecd9SHerbert Xu 			continue;
10421aa4ecd9SHerbert Xu 
104310faa8c0SStephan Mueller 		if (fips_enabled && template[i].fips_skip)
104410faa8c0SStephan Mueller 			continue;
104510faa8c0SStephan Mueller 
104692a4c9feSEric Biggers 		input  = enc ? template[i].ptext : template[i].ctext;
104792a4c9feSEric Biggers 		result = enc ? template[i].ctext : template[i].ptext;
10481aa4ecd9SHerbert Xu 		j++;
10491aa4ecd9SHerbert Xu 
1050fd57f22aSHerbert Xu 		ret = -EINVAL;
105192a4c9feSEric Biggers 		if (WARN_ON(template[i].len > PAGE_SIZE))
1052fd57f22aSHerbert Xu 			goto out;
1053fd57f22aSHerbert Xu 
10541aa4ecd9SHerbert Xu 		data = xbuf[0];
105592a4c9feSEric Biggers 		memcpy(data, input, template[i].len);
10561aa4ecd9SHerbert Xu 
10571aa4ecd9SHerbert Xu 		crypto_cipher_clear_flags(tfm, ~0);
10581aa4ecd9SHerbert Xu 		if (template[i].wk)
10591aa4ecd9SHerbert Xu 			crypto_cipher_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY);
10601aa4ecd9SHerbert Xu 
10611aa4ecd9SHerbert Xu 		ret = crypto_cipher_setkey(tfm, template[i].key,
10621aa4ecd9SHerbert Xu 					   template[i].klen);
10630fae0c1eSYanjiang Jin 		if (template[i].fail == !ret) {
10641aa4ecd9SHerbert Xu 			printk(KERN_ERR "alg: cipher: setkey failed "
10651aa4ecd9SHerbert Xu 			       "on test %d for %s: flags=%x\n", j,
10661aa4ecd9SHerbert Xu 			       algo, crypto_cipher_get_flags(tfm));
10671aa4ecd9SHerbert Xu 			goto out;
10681aa4ecd9SHerbert Xu 		} else if (ret)
10691aa4ecd9SHerbert Xu 			continue;
10701aa4ecd9SHerbert Xu 
107192a4c9feSEric Biggers 		for (k = 0; k < template[i].len;
10721aa4ecd9SHerbert Xu 		     k += crypto_cipher_blocksize(tfm)) {
10731aa4ecd9SHerbert Xu 			if (enc)
10741aa4ecd9SHerbert Xu 				crypto_cipher_encrypt_one(tfm, data + k,
10751aa4ecd9SHerbert Xu 							  data + k);
10761aa4ecd9SHerbert Xu 			else
10771aa4ecd9SHerbert Xu 				crypto_cipher_decrypt_one(tfm, data + k,
10781aa4ecd9SHerbert Xu 							  data + k);
10791aa4ecd9SHerbert Xu 		}
10801aa4ecd9SHerbert Xu 
10811aa4ecd9SHerbert Xu 		q = data;
108292a4c9feSEric Biggers 		if (memcmp(q, result, template[i].len)) {
10831aa4ecd9SHerbert Xu 			printk(KERN_ERR "alg: cipher: Test %d failed "
10841aa4ecd9SHerbert Xu 			       "on %s for %s\n", j, e, algo);
108592a4c9feSEric Biggers 			hexdump(q, template[i].len);
10861aa4ecd9SHerbert Xu 			ret = -EINVAL;
10871aa4ecd9SHerbert Xu 			goto out;
10881aa4ecd9SHerbert Xu 		}
10891aa4ecd9SHerbert Xu 	}
10901aa4ecd9SHerbert Xu 
10911aa4ecd9SHerbert Xu 	ret = 0;
10921aa4ecd9SHerbert Xu 
10931aa4ecd9SHerbert Xu out:
1094f8b0d4d0SHerbert Xu 	testmgr_free_buf(xbuf);
1095f8b0d4d0SHerbert Xu out_nobuf:
10961aa4ecd9SHerbert Xu 	return ret;
10971aa4ecd9SHerbert Xu }
10981aa4ecd9SHerbert Xu 
109912773d93SHerbert Xu static int __test_skcipher(struct crypto_skcipher *tfm, int enc,
1100b13b1e0cSEric Biggers 			   const struct cipher_testvec *template,
1101b13b1e0cSEric Biggers 			   unsigned int tcount,
11023a338f20SJussi Kivilinna 			   const bool diff_dst, const int align_offset)
1103da7f033dSHerbert Xu {
1104da7f033dSHerbert Xu 	const char *algo =
110512773d93SHerbert Xu 		crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm));
1106da7f033dSHerbert Xu 	unsigned int i, j, k, n, temp;
1107da7f033dSHerbert Xu 	char *q;
110812773d93SHerbert Xu 	struct skcipher_request *req;
1109da7f033dSHerbert Xu 	struct scatterlist sg[8];
111008d6af8cSJussi Kivilinna 	struct scatterlist sgout[8];
111108d6af8cSJussi Kivilinna 	const char *e, *d;
11127f397136SGilad Ben-Yossef 	struct crypto_wait wait;
111392a4c9feSEric Biggers 	const char *input, *result;
1114da7f033dSHerbert Xu 	void *data;
1115da7f033dSHerbert Xu 	char iv[MAX_IVLEN];
1116f8b0d4d0SHerbert Xu 	char *xbuf[XBUFSIZE];
111708d6af8cSJussi Kivilinna 	char *xoutbuf[XBUFSIZE];
1118f8b0d4d0SHerbert Xu 	int ret = -ENOMEM;
111984cba178SAndrey Ryabinin 	unsigned int ivsize = crypto_skcipher_ivsize(tfm);
1120f8b0d4d0SHerbert Xu 
1121f8b0d4d0SHerbert Xu 	if (testmgr_alloc_buf(xbuf))
1122f8b0d4d0SHerbert Xu 		goto out_nobuf;
1123da7f033dSHerbert Xu 
112408d6af8cSJussi Kivilinna 	if (diff_dst && testmgr_alloc_buf(xoutbuf))
112508d6af8cSJussi Kivilinna 		goto out_nooutbuf;
112608d6af8cSJussi Kivilinna 
112708d6af8cSJussi Kivilinna 	if (diff_dst)
112808d6af8cSJussi Kivilinna 		d = "-ddst";
112908d6af8cSJussi Kivilinna 	else
113008d6af8cSJussi Kivilinna 		d = "";
113108d6af8cSJussi Kivilinna 
1132da7f033dSHerbert Xu 	if (enc == ENCRYPT)
1133da7f033dSHerbert Xu 	        e = "encryption";
1134da7f033dSHerbert Xu 	else
1135da7f033dSHerbert Xu 		e = "decryption";
1136da7f033dSHerbert Xu 
11377f397136SGilad Ben-Yossef 	crypto_init_wait(&wait);
1138da7f033dSHerbert Xu 
113912773d93SHerbert Xu 	req = skcipher_request_alloc(tfm, GFP_KERNEL);
1140da7f033dSHerbert Xu 	if (!req) {
114108d6af8cSJussi Kivilinna 		pr_err("alg: skcipher%s: Failed to allocate request for %s\n",
114208d6af8cSJussi Kivilinna 		       d, algo);
1143da7f033dSHerbert Xu 		goto out;
1144da7f033dSHerbert Xu 	}
1145da7f033dSHerbert Xu 
114612773d93SHerbert Xu 	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
11477f397136SGilad Ben-Yossef 				      crypto_req_done, &wait);
1148da7f033dSHerbert Xu 
1149da7f033dSHerbert Xu 	j = 0;
1150da7f033dSHerbert Xu 	for (i = 0; i < tcount; i++) {
1151bbb9a7ddSCristian Stoica 		if (template[i].np && !template[i].also_non_np)
1152bbb9a7ddSCristian Stoica 			continue;
1153bbb9a7ddSCristian Stoica 
115410faa8c0SStephan Mueller 		if (fips_enabled && template[i].fips_skip)
115510faa8c0SStephan Mueller 			continue;
115610faa8c0SStephan Mueller 
115792a4c9feSEric Biggers 		if (template[i].iv && !(template[i].generates_iv && enc))
115884cba178SAndrey Ryabinin 			memcpy(iv, template[i].iv, ivsize);
1159da7f033dSHerbert Xu 		else
1160da7f033dSHerbert Xu 			memset(iv, 0, MAX_IVLEN);
1161da7f033dSHerbert Xu 
116292a4c9feSEric Biggers 		input  = enc ? template[i].ptext : template[i].ctext;
116392a4c9feSEric Biggers 		result = enc ? template[i].ctext : template[i].ptext;
1164da7f033dSHerbert Xu 		j++;
1165fd57f22aSHerbert Xu 		ret = -EINVAL;
116692a4c9feSEric Biggers 		if (WARN_ON(align_offset + template[i].len > PAGE_SIZE))
1167fd57f22aSHerbert Xu 			goto out;
1168fd57f22aSHerbert Xu 
1169da7f033dSHerbert Xu 		data = xbuf[0];
11703a338f20SJussi Kivilinna 		data += align_offset;
117192a4c9feSEric Biggers 		memcpy(data, input, template[i].len);
1172da7f033dSHerbert Xu 
117312773d93SHerbert Xu 		crypto_skcipher_clear_flags(tfm, ~0);
1174da7f033dSHerbert Xu 		if (template[i].wk)
117512773d93SHerbert Xu 			crypto_skcipher_set_flags(tfm,
117612773d93SHerbert Xu 						  CRYPTO_TFM_REQ_WEAK_KEY);
1177da7f033dSHerbert Xu 
117812773d93SHerbert Xu 		ret = crypto_skcipher_setkey(tfm, template[i].key,
1179da7f033dSHerbert Xu 					     template[i].klen);
11800fae0c1eSYanjiang Jin 		if (template[i].fail == !ret) {
118108d6af8cSJussi Kivilinna 			pr_err("alg: skcipher%s: setkey failed on test %d for %s: flags=%x\n",
118212773d93SHerbert Xu 			       d, j, algo, crypto_skcipher_get_flags(tfm));
1183da7f033dSHerbert Xu 			goto out;
1184da7f033dSHerbert Xu 		} else if (ret)
1185da7f033dSHerbert Xu 			continue;
1186da7f033dSHerbert Xu 
118792a4c9feSEric Biggers 		sg_init_one(&sg[0], data, template[i].len);
118808d6af8cSJussi Kivilinna 		if (diff_dst) {
118908d6af8cSJussi Kivilinna 			data = xoutbuf[0];
11903a338f20SJussi Kivilinna 			data += align_offset;
119192a4c9feSEric Biggers 			sg_init_one(&sgout[0], data, template[i].len);
119208d6af8cSJussi Kivilinna 		}
1193da7f033dSHerbert Xu 
119412773d93SHerbert Xu 		skcipher_request_set_crypt(req, sg, (diff_dst) ? sgout : sg,
119592a4c9feSEric Biggers 					   template[i].len, iv);
11967f397136SGilad Ben-Yossef 		ret = crypto_wait_req(enc ? crypto_skcipher_encrypt(req) :
11977f397136SGilad Ben-Yossef 				      crypto_skcipher_decrypt(req), &wait);
1198da7f033dSHerbert Xu 
11997f397136SGilad Ben-Yossef 		if (ret) {
120008d6af8cSJussi Kivilinna 			pr_err("alg: skcipher%s: %s failed on test %d for %s: ret=%d\n",
120108d6af8cSJussi Kivilinna 			       d, e, j, algo, -ret);
1202da7f033dSHerbert Xu 			goto out;
1203da7f033dSHerbert Xu 		}
1204da7f033dSHerbert Xu 
1205da7f033dSHerbert Xu 		q = data;
120692a4c9feSEric Biggers 		if (memcmp(q, result, template[i].len)) {
12078a826a34SBoris BREZILLON 			pr_err("alg: skcipher%s: Test %d failed (invalid result) on %s for %s\n",
120808d6af8cSJussi Kivilinna 			       d, j, e, algo);
120992a4c9feSEric Biggers 			hexdump(q, template[i].len);
1210da7f033dSHerbert Xu 			ret = -EINVAL;
1211da7f033dSHerbert Xu 			goto out;
1212da7f033dSHerbert Xu 		}
12138a826a34SBoris BREZILLON 
121492a4c9feSEric Biggers 		if (template[i].generates_iv && enc &&
121592a4c9feSEric Biggers 		    memcmp(iv, template[i].iv, crypto_skcipher_ivsize(tfm))) {
12168a826a34SBoris BREZILLON 			pr_err("alg: skcipher%s: Test %d failed (invalid output IV) on %s for %s\n",
12178a826a34SBoris BREZILLON 			       d, j, e, algo);
12188a826a34SBoris BREZILLON 			hexdump(iv, crypto_skcipher_ivsize(tfm));
12198a826a34SBoris BREZILLON 			ret = -EINVAL;
12208a826a34SBoris BREZILLON 			goto out;
12218a826a34SBoris BREZILLON 		}
1222da7f033dSHerbert Xu 	}
1223da7f033dSHerbert Xu 
1224da7f033dSHerbert Xu 	j = 0;
1225da7f033dSHerbert Xu 	for (i = 0; i < tcount; i++) {
12263a338f20SJussi Kivilinna 		/* alignment tests are only done with continuous buffers */
12273a338f20SJussi Kivilinna 		if (align_offset != 0)
12283a338f20SJussi Kivilinna 			break;
1229da7f033dSHerbert Xu 
1230bbb9a7ddSCristian Stoica 		if (!template[i].np)
1231bbb9a7ddSCristian Stoica 			continue;
1232bbb9a7ddSCristian Stoica 
123310faa8c0SStephan Mueller 		if (fips_enabled && template[i].fips_skip)
123410faa8c0SStephan Mueller 			continue;
123510faa8c0SStephan Mueller 
123692a4c9feSEric Biggers 		if (template[i].iv && !(template[i].generates_iv && enc))
123784cba178SAndrey Ryabinin 			memcpy(iv, template[i].iv, ivsize);
1238da7f033dSHerbert Xu 		else
1239da7f033dSHerbert Xu 			memset(iv, 0, MAX_IVLEN);
1240da7f033dSHerbert Xu 
124192a4c9feSEric Biggers 		input  = enc ? template[i].ptext : template[i].ctext;
124292a4c9feSEric Biggers 		result = enc ? template[i].ctext : template[i].ptext;
1243da7f033dSHerbert Xu 		j++;
124412773d93SHerbert Xu 		crypto_skcipher_clear_flags(tfm, ~0);
1245da7f033dSHerbert Xu 		if (template[i].wk)
124612773d93SHerbert Xu 			crypto_skcipher_set_flags(tfm,
124712773d93SHerbert Xu 						  CRYPTO_TFM_REQ_WEAK_KEY);
1248da7f033dSHerbert Xu 
124912773d93SHerbert Xu 		ret = crypto_skcipher_setkey(tfm, template[i].key,
1250da7f033dSHerbert Xu 					     template[i].klen);
12510fae0c1eSYanjiang Jin 		if (template[i].fail == !ret) {
125208d6af8cSJussi Kivilinna 			pr_err("alg: skcipher%s: setkey failed on chunk test %d for %s: flags=%x\n",
125312773d93SHerbert Xu 			       d, j, algo, crypto_skcipher_get_flags(tfm));
1254da7f033dSHerbert Xu 			goto out;
1255da7f033dSHerbert Xu 		} else if (ret)
1256da7f033dSHerbert Xu 			continue;
1257da7f033dSHerbert Xu 
1258da7f033dSHerbert Xu 		temp = 0;
1259da7f033dSHerbert Xu 		ret = -EINVAL;
1260da7f033dSHerbert Xu 		sg_init_table(sg, template[i].np);
126108d6af8cSJussi Kivilinna 		if (diff_dst)
126208d6af8cSJussi Kivilinna 			sg_init_table(sgout, template[i].np);
1263da7f033dSHerbert Xu 		for (k = 0; k < template[i].np; k++) {
1264da7f033dSHerbert Xu 			if (WARN_ON(offset_in_page(IDX[k]) +
1265da7f033dSHerbert Xu 				    template[i].tap[k] > PAGE_SIZE))
1266da7f033dSHerbert Xu 				goto out;
1267da7f033dSHerbert Xu 
1268a1aa44a2SCristian Stoica 			q = xbuf[IDX[k] >> PAGE_SHIFT] + offset_in_page(IDX[k]);
1269da7f033dSHerbert Xu 
127092a4c9feSEric Biggers 			memcpy(q, input + temp, template[i].tap[k]);
1271da7f033dSHerbert Xu 
1272a1aa44a2SCristian Stoica 			if (offset_in_page(q) + template[i].tap[k] < PAGE_SIZE)
1273da7f033dSHerbert Xu 				q[template[i].tap[k]] = 0;
1274da7f033dSHerbert Xu 
1275da7f033dSHerbert Xu 			sg_set_buf(&sg[k], q, template[i].tap[k]);
127608d6af8cSJussi Kivilinna 			if (diff_dst) {
127708d6af8cSJussi Kivilinna 				q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
127808d6af8cSJussi Kivilinna 				    offset_in_page(IDX[k]);
127908d6af8cSJussi Kivilinna 
1280a1aa44a2SCristian Stoica 				sg_set_buf(&sgout[k], q, template[i].tap[k]);
128108d6af8cSJussi Kivilinna 
128208d6af8cSJussi Kivilinna 				memset(q, 0, template[i].tap[k]);
128308d6af8cSJussi Kivilinna 				if (offset_in_page(q) +
128408d6af8cSJussi Kivilinna 				    template[i].tap[k] < PAGE_SIZE)
128508d6af8cSJussi Kivilinna 					q[template[i].tap[k]] = 0;
128608d6af8cSJussi Kivilinna 			}
1287da7f033dSHerbert Xu 
1288da7f033dSHerbert Xu 			temp += template[i].tap[k];
1289da7f033dSHerbert Xu 		}
1290da7f033dSHerbert Xu 
129112773d93SHerbert Xu 		skcipher_request_set_crypt(req, sg, (diff_dst) ? sgout : sg,
129292a4c9feSEric Biggers 					   template[i].len, iv);
1293da7f033dSHerbert Xu 
12947f397136SGilad Ben-Yossef 		ret = crypto_wait_req(enc ? crypto_skcipher_encrypt(req) :
12957f397136SGilad Ben-Yossef 				      crypto_skcipher_decrypt(req), &wait);
1296da7f033dSHerbert Xu 
12977f397136SGilad Ben-Yossef 		if (ret) {
129808d6af8cSJussi Kivilinna 			pr_err("alg: skcipher%s: %s failed on chunk test %d for %s: ret=%d\n",
129908d6af8cSJussi Kivilinna 			       d, e, j, algo, -ret);
1300da7f033dSHerbert Xu 			goto out;
1301da7f033dSHerbert Xu 		}
1302da7f033dSHerbert Xu 
1303da7f033dSHerbert Xu 		temp = 0;
1304da7f033dSHerbert Xu 		ret = -EINVAL;
1305da7f033dSHerbert Xu 		for (k = 0; k < template[i].np; k++) {
130608d6af8cSJussi Kivilinna 			if (diff_dst)
130708d6af8cSJussi Kivilinna 				q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
130808d6af8cSJussi Kivilinna 				    offset_in_page(IDX[k]);
130908d6af8cSJussi Kivilinna 			else
1310da7f033dSHerbert Xu 				q = xbuf[IDX[k] >> PAGE_SHIFT] +
1311da7f033dSHerbert Xu 				    offset_in_page(IDX[k]);
1312da7f033dSHerbert Xu 
131392a4c9feSEric Biggers 			if (memcmp(q, result + temp, template[i].tap[k])) {
131408d6af8cSJussi Kivilinna 				pr_err("alg: skcipher%s: Chunk test %d failed on %s at page %u for %s\n",
131508d6af8cSJussi Kivilinna 				       d, j, e, k, algo);
1316da7f033dSHerbert Xu 				hexdump(q, template[i].tap[k]);
1317da7f033dSHerbert Xu 				goto out;
1318da7f033dSHerbert Xu 			}
1319da7f033dSHerbert Xu 
1320da7f033dSHerbert Xu 			q += template[i].tap[k];
1321da7f033dSHerbert Xu 			for (n = 0; offset_in_page(q + n) && q[n]; n++)
1322da7f033dSHerbert Xu 				;
1323da7f033dSHerbert Xu 			if (n) {
132408d6af8cSJussi Kivilinna 				pr_err("alg: skcipher%s: Result buffer corruption in chunk test %d on %s at page %u for %s: %u bytes:\n",
132508d6af8cSJussi Kivilinna 				       d, j, e, k, algo, n);
1326da7f033dSHerbert Xu 				hexdump(q, n);
1327da7f033dSHerbert Xu 				goto out;
1328da7f033dSHerbert Xu 			}
1329da7f033dSHerbert Xu 			temp += template[i].tap[k];
1330da7f033dSHerbert Xu 		}
1331da7f033dSHerbert Xu 	}
1332da7f033dSHerbert Xu 
1333da7f033dSHerbert Xu 	ret = 0;
1334da7f033dSHerbert Xu 
1335da7f033dSHerbert Xu out:
133612773d93SHerbert Xu 	skcipher_request_free(req);
133708d6af8cSJussi Kivilinna 	if (diff_dst)
133808d6af8cSJussi Kivilinna 		testmgr_free_buf(xoutbuf);
133908d6af8cSJussi Kivilinna out_nooutbuf:
1340f8b0d4d0SHerbert Xu 	testmgr_free_buf(xbuf);
1341f8b0d4d0SHerbert Xu out_nobuf:
1342da7f033dSHerbert Xu 	return ret;
1343da7f033dSHerbert Xu }
1344da7f033dSHerbert Xu 
134512773d93SHerbert Xu static int test_skcipher(struct crypto_skcipher *tfm, int enc,
1346b13b1e0cSEric Biggers 			 const struct cipher_testvec *template,
1347b13b1e0cSEric Biggers 			 unsigned int tcount)
134808d6af8cSJussi Kivilinna {
13493a338f20SJussi Kivilinna 	unsigned int alignmask;
135008d6af8cSJussi Kivilinna 	int ret;
135108d6af8cSJussi Kivilinna 
135208d6af8cSJussi Kivilinna 	/* test 'dst == src' case */
13533a338f20SJussi Kivilinna 	ret = __test_skcipher(tfm, enc, template, tcount, false, 0);
135408d6af8cSJussi Kivilinna 	if (ret)
135508d6af8cSJussi Kivilinna 		return ret;
135608d6af8cSJussi Kivilinna 
135708d6af8cSJussi Kivilinna 	/* test 'dst != src' case */
13583a338f20SJussi Kivilinna 	ret = __test_skcipher(tfm, enc, template, tcount, true, 0);
13593a338f20SJussi Kivilinna 	if (ret)
13603a338f20SJussi Kivilinna 		return ret;
13613a338f20SJussi Kivilinna 
13623a338f20SJussi Kivilinna 	/* test unaligned buffers, check with one byte offset */
13633a338f20SJussi Kivilinna 	ret = __test_skcipher(tfm, enc, template, tcount, true, 1);
13643a338f20SJussi Kivilinna 	if (ret)
13653a338f20SJussi Kivilinna 		return ret;
13663a338f20SJussi Kivilinna 
13673a338f20SJussi Kivilinna 	alignmask = crypto_tfm_alg_alignmask(&tfm->base);
13683a338f20SJussi Kivilinna 	if (alignmask) {
13693a338f20SJussi Kivilinna 		/* Check if alignment mask for tfm is correctly set. */
13703a338f20SJussi Kivilinna 		ret = __test_skcipher(tfm, enc, template, tcount, true,
13713a338f20SJussi Kivilinna 				      alignmask + 1);
13723a338f20SJussi Kivilinna 		if (ret)
13733a338f20SJussi Kivilinna 			return ret;
13743a338f20SJussi Kivilinna 	}
13753a338f20SJussi Kivilinna 
13763a338f20SJussi Kivilinna 	return 0;
137708d6af8cSJussi Kivilinna }
137808d6af8cSJussi Kivilinna 
1379b13b1e0cSEric Biggers static int test_comp(struct crypto_comp *tfm,
1380b13b1e0cSEric Biggers 		     const struct comp_testvec *ctemplate,
1381b13b1e0cSEric Biggers 		     const struct comp_testvec *dtemplate,
1382b13b1e0cSEric Biggers 		     int ctcount, int dtcount)
1383da7f033dSHerbert Xu {
1384da7f033dSHerbert Xu 	const char *algo = crypto_tfm_alg_driver_name(crypto_comp_tfm(tfm));
138533607384SMahipal Challa 	char *output, *decomp_output;
1386da7f033dSHerbert Xu 	unsigned int i;
1387da7f033dSHerbert Xu 	int ret;
1388da7f033dSHerbert Xu 
138933607384SMahipal Challa 	output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL);
139033607384SMahipal Challa 	if (!output)
139133607384SMahipal Challa 		return -ENOMEM;
139233607384SMahipal Challa 
139333607384SMahipal Challa 	decomp_output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL);
139433607384SMahipal Challa 	if (!decomp_output) {
139533607384SMahipal Challa 		kfree(output);
139633607384SMahipal Challa 		return -ENOMEM;
139733607384SMahipal Challa 	}
139833607384SMahipal Challa 
1399da7f033dSHerbert Xu 	for (i = 0; i < ctcount; i++) {
1400c79cf910SGeert Uytterhoeven 		int ilen;
1401c79cf910SGeert Uytterhoeven 		unsigned int dlen = COMP_BUF_SIZE;
1402da7f033dSHerbert Xu 
140322a8118dSMichael Schupikov 		memset(output, 0, COMP_BUF_SIZE);
140422a8118dSMichael Schupikov 		memset(decomp_output, 0, COMP_BUF_SIZE);
1405da7f033dSHerbert Xu 
1406da7f033dSHerbert Xu 		ilen = ctemplate[i].inlen;
1407da7f033dSHerbert Xu 		ret = crypto_comp_compress(tfm, ctemplate[i].input,
140833607384SMahipal Challa 					   ilen, output, &dlen);
1409da7f033dSHerbert Xu 		if (ret) {
1410da7f033dSHerbert Xu 			printk(KERN_ERR "alg: comp: compression failed "
1411da7f033dSHerbert Xu 			       "on test %d for %s: ret=%d\n", i + 1, algo,
1412da7f033dSHerbert Xu 			       -ret);
1413da7f033dSHerbert Xu 			goto out;
1414da7f033dSHerbert Xu 		}
1415da7f033dSHerbert Xu 
141633607384SMahipal Challa 		ilen = dlen;
141733607384SMahipal Challa 		dlen = COMP_BUF_SIZE;
141833607384SMahipal Challa 		ret = crypto_comp_decompress(tfm, output,
141933607384SMahipal Challa 					     ilen, decomp_output, &dlen);
142033607384SMahipal Challa 		if (ret) {
142133607384SMahipal Challa 			pr_err("alg: comp: compression failed: decompress: on test %d for %s failed: ret=%d\n",
142233607384SMahipal Challa 			       i + 1, algo, -ret);
142333607384SMahipal Challa 			goto out;
142433607384SMahipal Challa 		}
142533607384SMahipal Challa 
142633607384SMahipal Challa 		if (dlen != ctemplate[i].inlen) {
1427b812eb00SGeert Uytterhoeven 			printk(KERN_ERR "alg: comp: Compression test %d "
1428b812eb00SGeert Uytterhoeven 			       "failed for %s: output len = %d\n", i + 1, algo,
1429b812eb00SGeert Uytterhoeven 			       dlen);
1430b812eb00SGeert Uytterhoeven 			ret = -EINVAL;
1431b812eb00SGeert Uytterhoeven 			goto out;
1432b812eb00SGeert Uytterhoeven 		}
1433b812eb00SGeert Uytterhoeven 
143433607384SMahipal Challa 		if (memcmp(decomp_output, ctemplate[i].input,
143533607384SMahipal Challa 			   ctemplate[i].inlen)) {
143633607384SMahipal Challa 			pr_err("alg: comp: compression failed: output differs: on test %d for %s\n",
143733607384SMahipal Challa 			       i + 1, algo);
143833607384SMahipal Challa 			hexdump(decomp_output, dlen);
1439da7f033dSHerbert Xu 			ret = -EINVAL;
1440da7f033dSHerbert Xu 			goto out;
1441da7f033dSHerbert Xu 		}
1442da7f033dSHerbert Xu 	}
1443da7f033dSHerbert Xu 
1444da7f033dSHerbert Xu 	for (i = 0; i < dtcount; i++) {
1445c79cf910SGeert Uytterhoeven 		int ilen;
1446c79cf910SGeert Uytterhoeven 		unsigned int dlen = COMP_BUF_SIZE;
1447da7f033dSHerbert Xu 
144822a8118dSMichael Schupikov 		memset(decomp_output, 0, COMP_BUF_SIZE);
1449da7f033dSHerbert Xu 
1450da7f033dSHerbert Xu 		ilen = dtemplate[i].inlen;
1451da7f033dSHerbert Xu 		ret = crypto_comp_decompress(tfm, dtemplate[i].input,
145233607384SMahipal Challa 					     ilen, decomp_output, &dlen);
1453da7f033dSHerbert Xu 		if (ret) {
1454da7f033dSHerbert Xu 			printk(KERN_ERR "alg: comp: decompression failed "
1455da7f033dSHerbert Xu 			       "on test %d for %s: ret=%d\n", i + 1, algo,
1456da7f033dSHerbert Xu 			       -ret);
1457da7f033dSHerbert Xu 			goto out;
1458da7f033dSHerbert Xu 		}
1459da7f033dSHerbert Xu 
1460b812eb00SGeert Uytterhoeven 		if (dlen != dtemplate[i].outlen) {
1461b812eb00SGeert Uytterhoeven 			printk(KERN_ERR "alg: comp: Decompression test %d "
1462b812eb00SGeert Uytterhoeven 			       "failed for %s: output len = %d\n", i + 1, algo,
1463b812eb00SGeert Uytterhoeven 			       dlen);
1464b812eb00SGeert Uytterhoeven 			ret = -EINVAL;
1465b812eb00SGeert Uytterhoeven 			goto out;
1466b812eb00SGeert Uytterhoeven 		}
1467b812eb00SGeert Uytterhoeven 
146833607384SMahipal Challa 		if (memcmp(decomp_output, dtemplate[i].output, dlen)) {
1469da7f033dSHerbert Xu 			printk(KERN_ERR "alg: comp: Decompression test %d "
1470da7f033dSHerbert Xu 			       "failed for %s\n", i + 1, algo);
147133607384SMahipal Challa 			hexdump(decomp_output, dlen);
1472da7f033dSHerbert Xu 			ret = -EINVAL;
1473da7f033dSHerbert Xu 			goto out;
1474da7f033dSHerbert Xu 		}
1475da7f033dSHerbert Xu 	}
1476da7f033dSHerbert Xu 
1477da7f033dSHerbert Xu 	ret = 0;
1478da7f033dSHerbert Xu 
1479da7f033dSHerbert Xu out:
148033607384SMahipal Challa 	kfree(decomp_output);
148133607384SMahipal Challa 	kfree(output);
1482da7f033dSHerbert Xu 	return ret;
1483da7f033dSHerbert Xu }
1484da7f033dSHerbert Xu 
1485b13b1e0cSEric Biggers static int test_acomp(struct crypto_acomp *tfm,
1486b13b1e0cSEric Biggers 			      const struct comp_testvec *ctemplate,
1487b13b1e0cSEric Biggers 		      const struct comp_testvec *dtemplate,
1488b13b1e0cSEric Biggers 		      int ctcount, int dtcount)
1489d7db7a88SGiovanni Cabiddu {
1490d7db7a88SGiovanni Cabiddu 	const char *algo = crypto_tfm_alg_driver_name(crypto_acomp_tfm(tfm));
1491d7db7a88SGiovanni Cabiddu 	unsigned int i;
1492a9943a0aSGiovanni Cabiddu 	char *output, *decomp_out;
1493d7db7a88SGiovanni Cabiddu 	int ret;
1494d7db7a88SGiovanni Cabiddu 	struct scatterlist src, dst;
1495d7db7a88SGiovanni Cabiddu 	struct acomp_req *req;
14967f397136SGilad Ben-Yossef 	struct crypto_wait wait;
1497d7db7a88SGiovanni Cabiddu 
1498eb095593SEric Biggers 	output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL);
1499eb095593SEric Biggers 	if (!output)
1500eb095593SEric Biggers 		return -ENOMEM;
1501eb095593SEric Biggers 
1502a9943a0aSGiovanni Cabiddu 	decomp_out = kmalloc(COMP_BUF_SIZE, GFP_KERNEL);
1503a9943a0aSGiovanni Cabiddu 	if (!decomp_out) {
1504a9943a0aSGiovanni Cabiddu 		kfree(output);
1505a9943a0aSGiovanni Cabiddu 		return -ENOMEM;
1506a9943a0aSGiovanni Cabiddu 	}
1507a9943a0aSGiovanni Cabiddu 
1508d7db7a88SGiovanni Cabiddu 	for (i = 0; i < ctcount; i++) {
1509d7db7a88SGiovanni Cabiddu 		unsigned int dlen = COMP_BUF_SIZE;
1510d7db7a88SGiovanni Cabiddu 		int ilen = ctemplate[i].inlen;
151102608e02SLaura Abbott 		void *input_vec;
1512d7db7a88SGiovanni Cabiddu 
1513d2110224SEric Biggers 		input_vec = kmemdup(ctemplate[i].input, ilen, GFP_KERNEL);
151402608e02SLaura Abbott 		if (!input_vec) {
151502608e02SLaura Abbott 			ret = -ENOMEM;
151602608e02SLaura Abbott 			goto out;
151702608e02SLaura Abbott 		}
151802608e02SLaura Abbott 
1519eb095593SEric Biggers 		memset(output, 0, dlen);
15207f397136SGilad Ben-Yossef 		crypto_init_wait(&wait);
152102608e02SLaura Abbott 		sg_init_one(&src, input_vec, ilen);
1522d7db7a88SGiovanni Cabiddu 		sg_init_one(&dst, output, dlen);
1523d7db7a88SGiovanni Cabiddu 
1524d7db7a88SGiovanni Cabiddu 		req = acomp_request_alloc(tfm);
1525d7db7a88SGiovanni Cabiddu 		if (!req) {
1526d7db7a88SGiovanni Cabiddu 			pr_err("alg: acomp: request alloc failed for %s\n",
1527d7db7a88SGiovanni Cabiddu 			       algo);
152802608e02SLaura Abbott 			kfree(input_vec);
1529d7db7a88SGiovanni Cabiddu 			ret = -ENOMEM;
1530d7db7a88SGiovanni Cabiddu 			goto out;
1531d7db7a88SGiovanni Cabiddu 		}
1532d7db7a88SGiovanni Cabiddu 
1533d7db7a88SGiovanni Cabiddu 		acomp_request_set_params(req, &src, &dst, ilen, dlen);
1534d7db7a88SGiovanni Cabiddu 		acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
15357f397136SGilad Ben-Yossef 					   crypto_req_done, &wait);
1536d7db7a88SGiovanni Cabiddu 
15377f397136SGilad Ben-Yossef 		ret = crypto_wait_req(crypto_acomp_compress(req), &wait);
1538d7db7a88SGiovanni Cabiddu 		if (ret) {
1539d7db7a88SGiovanni Cabiddu 			pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n",
1540d7db7a88SGiovanni Cabiddu 			       i + 1, algo, -ret);
154102608e02SLaura Abbott 			kfree(input_vec);
1542d7db7a88SGiovanni Cabiddu 			acomp_request_free(req);
1543d7db7a88SGiovanni Cabiddu 			goto out;
1544d7db7a88SGiovanni Cabiddu 		}
1545d7db7a88SGiovanni Cabiddu 
1546a9943a0aSGiovanni Cabiddu 		ilen = req->dlen;
1547a9943a0aSGiovanni Cabiddu 		dlen = COMP_BUF_SIZE;
1548a9943a0aSGiovanni Cabiddu 		sg_init_one(&src, output, ilen);
1549a9943a0aSGiovanni Cabiddu 		sg_init_one(&dst, decomp_out, dlen);
15507f397136SGilad Ben-Yossef 		crypto_init_wait(&wait);
1551a9943a0aSGiovanni Cabiddu 		acomp_request_set_params(req, &src, &dst, ilen, dlen);
1552a9943a0aSGiovanni Cabiddu 
15537f397136SGilad Ben-Yossef 		ret = crypto_wait_req(crypto_acomp_decompress(req), &wait);
1554a9943a0aSGiovanni Cabiddu 		if (ret) {
1555a9943a0aSGiovanni Cabiddu 			pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n",
1556a9943a0aSGiovanni Cabiddu 			       i + 1, algo, -ret);
1557a9943a0aSGiovanni Cabiddu 			kfree(input_vec);
1558a9943a0aSGiovanni Cabiddu 			acomp_request_free(req);
1559a9943a0aSGiovanni Cabiddu 			goto out;
1560a9943a0aSGiovanni Cabiddu 		}
1561a9943a0aSGiovanni Cabiddu 
1562a9943a0aSGiovanni Cabiddu 		if (req->dlen != ctemplate[i].inlen) {
1563d7db7a88SGiovanni Cabiddu 			pr_err("alg: acomp: Compression test %d failed for %s: output len = %d\n",
1564d7db7a88SGiovanni Cabiddu 			       i + 1, algo, req->dlen);
1565d7db7a88SGiovanni Cabiddu 			ret = -EINVAL;
156602608e02SLaura Abbott 			kfree(input_vec);
1567d7db7a88SGiovanni Cabiddu 			acomp_request_free(req);
1568d7db7a88SGiovanni Cabiddu 			goto out;
1569d7db7a88SGiovanni Cabiddu 		}
1570d7db7a88SGiovanni Cabiddu 
1571a9943a0aSGiovanni Cabiddu 		if (memcmp(input_vec, decomp_out, req->dlen)) {
1572d7db7a88SGiovanni Cabiddu 			pr_err("alg: acomp: Compression test %d failed for %s\n",
1573d7db7a88SGiovanni Cabiddu 			       i + 1, algo);
1574d7db7a88SGiovanni Cabiddu 			hexdump(output, req->dlen);
1575d7db7a88SGiovanni Cabiddu 			ret = -EINVAL;
157602608e02SLaura Abbott 			kfree(input_vec);
1577d7db7a88SGiovanni Cabiddu 			acomp_request_free(req);
1578d7db7a88SGiovanni Cabiddu 			goto out;
1579d7db7a88SGiovanni Cabiddu 		}
1580d7db7a88SGiovanni Cabiddu 
158102608e02SLaura Abbott 		kfree(input_vec);
1582d7db7a88SGiovanni Cabiddu 		acomp_request_free(req);
1583d7db7a88SGiovanni Cabiddu 	}
1584d7db7a88SGiovanni Cabiddu 
1585d7db7a88SGiovanni Cabiddu 	for (i = 0; i < dtcount; i++) {
1586d7db7a88SGiovanni Cabiddu 		unsigned int dlen = COMP_BUF_SIZE;
1587d7db7a88SGiovanni Cabiddu 		int ilen = dtemplate[i].inlen;
158802608e02SLaura Abbott 		void *input_vec;
1589d7db7a88SGiovanni Cabiddu 
1590d2110224SEric Biggers 		input_vec = kmemdup(dtemplate[i].input, ilen, GFP_KERNEL);
159102608e02SLaura Abbott 		if (!input_vec) {
159202608e02SLaura Abbott 			ret = -ENOMEM;
159302608e02SLaura Abbott 			goto out;
159402608e02SLaura Abbott 		}
159502608e02SLaura Abbott 
1596eb095593SEric Biggers 		memset(output, 0, dlen);
15977f397136SGilad Ben-Yossef 		crypto_init_wait(&wait);
159802608e02SLaura Abbott 		sg_init_one(&src, input_vec, ilen);
1599d7db7a88SGiovanni Cabiddu 		sg_init_one(&dst, output, dlen);
1600d7db7a88SGiovanni Cabiddu 
1601d7db7a88SGiovanni Cabiddu 		req = acomp_request_alloc(tfm);
1602d7db7a88SGiovanni Cabiddu 		if (!req) {
1603d7db7a88SGiovanni Cabiddu 			pr_err("alg: acomp: request alloc failed for %s\n",
1604d7db7a88SGiovanni Cabiddu 			       algo);
160502608e02SLaura Abbott 			kfree(input_vec);
1606d7db7a88SGiovanni Cabiddu 			ret = -ENOMEM;
1607d7db7a88SGiovanni Cabiddu 			goto out;
1608d7db7a88SGiovanni Cabiddu 		}
1609d7db7a88SGiovanni Cabiddu 
1610d7db7a88SGiovanni Cabiddu 		acomp_request_set_params(req, &src, &dst, ilen, dlen);
1611d7db7a88SGiovanni Cabiddu 		acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
16127f397136SGilad Ben-Yossef 					   crypto_req_done, &wait);
1613d7db7a88SGiovanni Cabiddu 
16147f397136SGilad Ben-Yossef 		ret = crypto_wait_req(crypto_acomp_decompress(req), &wait);
1615d7db7a88SGiovanni Cabiddu 		if (ret) {
1616d7db7a88SGiovanni Cabiddu 			pr_err("alg: acomp: decompression failed on test %d for %s: ret=%d\n",
1617d7db7a88SGiovanni Cabiddu 			       i + 1, algo, -ret);
161802608e02SLaura Abbott 			kfree(input_vec);
1619d7db7a88SGiovanni Cabiddu 			acomp_request_free(req);
1620d7db7a88SGiovanni Cabiddu 			goto out;
1621d7db7a88SGiovanni Cabiddu 		}
1622d7db7a88SGiovanni Cabiddu 
1623d7db7a88SGiovanni Cabiddu 		if (req->dlen != dtemplate[i].outlen) {
1624d7db7a88SGiovanni Cabiddu 			pr_err("alg: acomp: Decompression test %d failed for %s: output len = %d\n",
1625d7db7a88SGiovanni Cabiddu 			       i + 1, algo, req->dlen);
1626d7db7a88SGiovanni Cabiddu 			ret = -EINVAL;
162702608e02SLaura Abbott 			kfree(input_vec);
1628d7db7a88SGiovanni Cabiddu 			acomp_request_free(req);
1629d7db7a88SGiovanni Cabiddu 			goto out;
1630d7db7a88SGiovanni Cabiddu 		}
1631d7db7a88SGiovanni Cabiddu 
1632d7db7a88SGiovanni Cabiddu 		if (memcmp(output, dtemplate[i].output, req->dlen)) {
1633d7db7a88SGiovanni Cabiddu 			pr_err("alg: acomp: Decompression test %d failed for %s\n",
1634d7db7a88SGiovanni Cabiddu 			       i + 1, algo);
1635d7db7a88SGiovanni Cabiddu 			hexdump(output, req->dlen);
1636d7db7a88SGiovanni Cabiddu 			ret = -EINVAL;
163702608e02SLaura Abbott 			kfree(input_vec);
1638d7db7a88SGiovanni Cabiddu 			acomp_request_free(req);
1639d7db7a88SGiovanni Cabiddu 			goto out;
1640d7db7a88SGiovanni Cabiddu 		}
1641d7db7a88SGiovanni Cabiddu 
164202608e02SLaura Abbott 		kfree(input_vec);
1643d7db7a88SGiovanni Cabiddu 		acomp_request_free(req);
1644d7db7a88SGiovanni Cabiddu 	}
1645d7db7a88SGiovanni Cabiddu 
1646d7db7a88SGiovanni Cabiddu 	ret = 0;
1647d7db7a88SGiovanni Cabiddu 
1648d7db7a88SGiovanni Cabiddu out:
1649a9943a0aSGiovanni Cabiddu 	kfree(decomp_out);
1650eb095593SEric Biggers 	kfree(output);
1651d7db7a88SGiovanni Cabiddu 	return ret;
1652d7db7a88SGiovanni Cabiddu }
1653d7db7a88SGiovanni Cabiddu 
1654b13b1e0cSEric Biggers static int test_cprng(struct crypto_rng *tfm,
1655b13b1e0cSEric Biggers 		      const struct cprng_testvec *template,
16567647d6ceSJarod Wilson 		      unsigned int tcount)
16577647d6ceSJarod Wilson {
16587647d6ceSJarod Wilson 	const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm));
1659fa4ef8a6SFelipe Contreras 	int err = 0, i, j, seedsize;
16607647d6ceSJarod Wilson 	u8 *seed;
16617647d6ceSJarod Wilson 	char result[32];
16627647d6ceSJarod Wilson 
16637647d6ceSJarod Wilson 	seedsize = crypto_rng_seedsize(tfm);
16647647d6ceSJarod Wilson 
16657647d6ceSJarod Wilson 	seed = kmalloc(seedsize, GFP_KERNEL);
16667647d6ceSJarod Wilson 	if (!seed) {
16677647d6ceSJarod Wilson 		printk(KERN_ERR "alg: cprng: Failed to allocate seed space "
16687647d6ceSJarod Wilson 		       "for %s\n", algo);
16697647d6ceSJarod Wilson 		return -ENOMEM;
16707647d6ceSJarod Wilson 	}
16717647d6ceSJarod Wilson 
16727647d6ceSJarod Wilson 	for (i = 0; i < tcount; i++) {
16737647d6ceSJarod Wilson 		memset(result, 0, 32);
16747647d6ceSJarod Wilson 
16757647d6ceSJarod Wilson 		memcpy(seed, template[i].v, template[i].vlen);
16767647d6ceSJarod Wilson 		memcpy(seed + template[i].vlen, template[i].key,
16777647d6ceSJarod Wilson 		       template[i].klen);
16787647d6ceSJarod Wilson 		memcpy(seed + template[i].vlen + template[i].klen,
16797647d6ceSJarod Wilson 		       template[i].dt, template[i].dtlen);
16807647d6ceSJarod Wilson 
16817647d6ceSJarod Wilson 		err = crypto_rng_reset(tfm, seed, seedsize);
16827647d6ceSJarod Wilson 		if (err) {
16837647d6ceSJarod Wilson 			printk(KERN_ERR "alg: cprng: Failed to reset rng "
16847647d6ceSJarod Wilson 			       "for %s\n", algo);
16857647d6ceSJarod Wilson 			goto out;
16867647d6ceSJarod Wilson 		}
16877647d6ceSJarod Wilson 
16887647d6ceSJarod Wilson 		for (j = 0; j < template[i].loops; j++) {
16897647d6ceSJarod Wilson 			err = crypto_rng_get_bytes(tfm, result,
16907647d6ceSJarod Wilson 						   template[i].rlen);
169119e60e13SStephan Mueller 			if (err < 0) {
16927647d6ceSJarod Wilson 				printk(KERN_ERR "alg: cprng: Failed to obtain "
16937647d6ceSJarod Wilson 				       "the correct amount of random data for "
169419e60e13SStephan Mueller 				       "%s (requested %d)\n", algo,
169519e60e13SStephan Mueller 				       template[i].rlen);
16967647d6ceSJarod Wilson 				goto out;
16977647d6ceSJarod Wilson 			}
16987647d6ceSJarod Wilson 		}
16997647d6ceSJarod Wilson 
17007647d6ceSJarod Wilson 		err = memcmp(result, template[i].result,
17017647d6ceSJarod Wilson 			     template[i].rlen);
17027647d6ceSJarod Wilson 		if (err) {
17037647d6ceSJarod Wilson 			printk(KERN_ERR "alg: cprng: Test %d failed for %s\n",
17047647d6ceSJarod Wilson 			       i, algo);
17057647d6ceSJarod Wilson 			hexdump(result, template[i].rlen);
17067647d6ceSJarod Wilson 			err = -EINVAL;
17077647d6ceSJarod Wilson 			goto out;
17087647d6ceSJarod Wilson 		}
17097647d6ceSJarod Wilson 	}
17107647d6ceSJarod Wilson 
17117647d6ceSJarod Wilson out:
17127647d6ceSJarod Wilson 	kfree(seed);
17137647d6ceSJarod Wilson 	return err;
17147647d6ceSJarod Wilson }
17157647d6ceSJarod Wilson 
1716da7f033dSHerbert Xu static int alg_test_aead(const struct alg_test_desc *desc, const char *driver,
1717da7f033dSHerbert Xu 			 u32 type, u32 mask)
1718da7f033dSHerbert Xu {
1719da7f033dSHerbert Xu 	struct crypto_aead *tfm;
1720da7f033dSHerbert Xu 	int err = 0;
1721da7f033dSHerbert Xu 
1722eed93e0cSHerbert Xu 	tfm = crypto_alloc_aead(driver, type, mask);
1723da7f033dSHerbert Xu 	if (IS_ERR(tfm)) {
1724da7f033dSHerbert Xu 		printk(KERN_ERR "alg: aead: Failed to load transform for %s: "
1725da7f033dSHerbert Xu 		       "%ld\n", driver, PTR_ERR(tfm));
1726da7f033dSHerbert Xu 		return PTR_ERR(tfm);
1727da7f033dSHerbert Xu 	}
1728da7f033dSHerbert Xu 
1729da7f033dSHerbert Xu 	if (desc->suite.aead.enc.vecs) {
1730da7f033dSHerbert Xu 		err = test_aead(tfm, ENCRYPT, desc->suite.aead.enc.vecs,
1731da7f033dSHerbert Xu 				desc->suite.aead.enc.count);
1732da7f033dSHerbert Xu 		if (err)
1733da7f033dSHerbert Xu 			goto out;
1734da7f033dSHerbert Xu 	}
1735da7f033dSHerbert Xu 
1736da7f033dSHerbert Xu 	if (!err && desc->suite.aead.dec.vecs)
1737da7f033dSHerbert Xu 		err = test_aead(tfm, DECRYPT, desc->suite.aead.dec.vecs,
1738da7f033dSHerbert Xu 				desc->suite.aead.dec.count);
1739da7f033dSHerbert Xu 
1740da7f033dSHerbert Xu out:
1741da7f033dSHerbert Xu 	crypto_free_aead(tfm);
1742da7f033dSHerbert Xu 	return err;
1743da7f033dSHerbert Xu }
1744da7f033dSHerbert Xu 
1745da7f033dSHerbert Xu static int alg_test_cipher(const struct alg_test_desc *desc,
1746da7f033dSHerbert Xu 			   const char *driver, u32 type, u32 mask)
1747da7f033dSHerbert Xu {
174892a4c9feSEric Biggers 	const struct cipher_test_suite *suite = &desc->suite.cipher;
17491aa4ecd9SHerbert Xu 	struct crypto_cipher *tfm;
175092a4c9feSEric Biggers 	int err;
1751da7f033dSHerbert Xu 
1752eed93e0cSHerbert Xu 	tfm = crypto_alloc_cipher(driver, type, mask);
1753da7f033dSHerbert Xu 	if (IS_ERR(tfm)) {
1754da7f033dSHerbert Xu 		printk(KERN_ERR "alg: cipher: Failed to load transform for "
1755da7f033dSHerbert Xu 		       "%s: %ld\n", driver, PTR_ERR(tfm));
1756da7f033dSHerbert Xu 		return PTR_ERR(tfm);
1757da7f033dSHerbert Xu 	}
1758da7f033dSHerbert Xu 
175992a4c9feSEric Biggers 	err = test_cipher(tfm, ENCRYPT, suite->vecs, suite->count);
176092a4c9feSEric Biggers 	if (!err)
176192a4c9feSEric Biggers 		err = test_cipher(tfm, DECRYPT, suite->vecs, suite->count);
1762da7f033dSHerbert Xu 
17631aa4ecd9SHerbert Xu 	crypto_free_cipher(tfm);
17641aa4ecd9SHerbert Xu 	return err;
17651aa4ecd9SHerbert Xu }
17661aa4ecd9SHerbert Xu 
17671aa4ecd9SHerbert Xu static int alg_test_skcipher(const struct alg_test_desc *desc,
17681aa4ecd9SHerbert Xu 			     const char *driver, u32 type, u32 mask)
17691aa4ecd9SHerbert Xu {
177092a4c9feSEric Biggers 	const struct cipher_test_suite *suite = &desc->suite.cipher;
177112773d93SHerbert Xu 	struct crypto_skcipher *tfm;
177292a4c9feSEric Biggers 	int err;
17731aa4ecd9SHerbert Xu 
1774eed93e0cSHerbert Xu 	tfm = crypto_alloc_skcipher(driver, type, mask);
17751aa4ecd9SHerbert Xu 	if (IS_ERR(tfm)) {
17761aa4ecd9SHerbert Xu 		printk(KERN_ERR "alg: skcipher: Failed to load transform for "
17771aa4ecd9SHerbert Xu 		       "%s: %ld\n", driver, PTR_ERR(tfm));
17781aa4ecd9SHerbert Xu 		return PTR_ERR(tfm);
17791aa4ecd9SHerbert Xu 	}
17801aa4ecd9SHerbert Xu 
178192a4c9feSEric Biggers 	err = test_skcipher(tfm, ENCRYPT, suite->vecs, suite->count);
178292a4c9feSEric Biggers 	if (!err)
178392a4c9feSEric Biggers 		err = test_skcipher(tfm, DECRYPT, suite->vecs, suite->count);
17841aa4ecd9SHerbert Xu 
178512773d93SHerbert Xu 	crypto_free_skcipher(tfm);
1786da7f033dSHerbert Xu 	return err;
1787da7f033dSHerbert Xu }
1788da7f033dSHerbert Xu 
1789da7f033dSHerbert Xu static int alg_test_comp(const struct alg_test_desc *desc, const char *driver,
1790da7f033dSHerbert Xu 			 u32 type, u32 mask)
1791da7f033dSHerbert Xu {
1792d7db7a88SGiovanni Cabiddu 	struct crypto_comp *comp;
1793d7db7a88SGiovanni Cabiddu 	struct crypto_acomp *acomp;
1794da7f033dSHerbert Xu 	int err;
1795d7db7a88SGiovanni Cabiddu 	u32 algo_type = type & CRYPTO_ALG_TYPE_ACOMPRESS_MASK;
1796da7f033dSHerbert Xu 
1797d7db7a88SGiovanni Cabiddu 	if (algo_type == CRYPTO_ALG_TYPE_ACOMPRESS) {
1798d7db7a88SGiovanni Cabiddu 		acomp = crypto_alloc_acomp(driver, type, mask);
1799d7db7a88SGiovanni Cabiddu 		if (IS_ERR(acomp)) {
1800d7db7a88SGiovanni Cabiddu 			pr_err("alg: acomp: Failed to load transform for %s: %ld\n",
1801d7db7a88SGiovanni Cabiddu 			       driver, PTR_ERR(acomp));
1802d7db7a88SGiovanni Cabiddu 			return PTR_ERR(acomp);
1803d7db7a88SGiovanni Cabiddu 		}
1804d7db7a88SGiovanni Cabiddu 		err = test_acomp(acomp, desc->suite.comp.comp.vecs,
1805d7db7a88SGiovanni Cabiddu 				 desc->suite.comp.decomp.vecs,
1806d7db7a88SGiovanni Cabiddu 				 desc->suite.comp.comp.count,
1807d7db7a88SGiovanni Cabiddu 				 desc->suite.comp.decomp.count);
1808d7db7a88SGiovanni Cabiddu 		crypto_free_acomp(acomp);
1809d7db7a88SGiovanni Cabiddu 	} else {
1810d7db7a88SGiovanni Cabiddu 		comp = crypto_alloc_comp(driver, type, mask);
1811d7db7a88SGiovanni Cabiddu 		if (IS_ERR(comp)) {
1812d7db7a88SGiovanni Cabiddu 			pr_err("alg: comp: Failed to load transform for %s: %ld\n",
1813d7db7a88SGiovanni Cabiddu 			       driver, PTR_ERR(comp));
1814d7db7a88SGiovanni Cabiddu 			return PTR_ERR(comp);
1815da7f033dSHerbert Xu 		}
1816da7f033dSHerbert Xu 
1817d7db7a88SGiovanni Cabiddu 		err = test_comp(comp, desc->suite.comp.comp.vecs,
1818da7f033dSHerbert Xu 				desc->suite.comp.decomp.vecs,
1819da7f033dSHerbert Xu 				desc->suite.comp.comp.count,
1820da7f033dSHerbert Xu 				desc->suite.comp.decomp.count);
1821da7f033dSHerbert Xu 
1822d7db7a88SGiovanni Cabiddu 		crypto_free_comp(comp);
1823d7db7a88SGiovanni Cabiddu 	}
1824da7f033dSHerbert Xu 	return err;
1825da7f033dSHerbert Xu }
1826da7f033dSHerbert Xu 
18279b3abc01SEric Biggers static int __alg_test_hash(const struct hash_testvec *template,
18289b3abc01SEric Biggers 			   unsigned int tcount, const char *driver,
1829da7f033dSHerbert Xu 			   u32 type, u32 mask)
1830da7f033dSHerbert Xu {
1831da7f033dSHerbert Xu 	struct crypto_ahash *tfm;
1832da7f033dSHerbert Xu 	int err;
1833da7f033dSHerbert Xu 
1834eed93e0cSHerbert Xu 	tfm = crypto_alloc_ahash(driver, type, mask);
1835da7f033dSHerbert Xu 	if (IS_ERR(tfm)) {
1836da7f033dSHerbert Xu 		printk(KERN_ERR "alg: hash: Failed to load transform for %s: "
1837da7f033dSHerbert Xu 		       "%ld\n", driver, PTR_ERR(tfm));
1838da7f033dSHerbert Xu 		return PTR_ERR(tfm);
1839da7f033dSHerbert Xu 	}
1840da7f033dSHerbert Xu 
184176715095SGilad Ben-Yossef 	err = test_hash(tfm, template, tcount, HASH_TEST_DIGEST);
1842a8f1a052SDavid S. Miller 	if (!err)
184376715095SGilad Ben-Yossef 		err = test_hash(tfm, template, tcount, HASH_TEST_FINAL);
184476715095SGilad Ben-Yossef 	if (!err)
184576715095SGilad Ben-Yossef 		err = test_hash(tfm, template, tcount, HASH_TEST_FINUP);
1846da7f033dSHerbert Xu 	crypto_free_ahash(tfm);
1847da7f033dSHerbert Xu 	return err;
1848da7f033dSHerbert Xu }
1849da7f033dSHerbert Xu 
18509b3abc01SEric Biggers static int alg_test_hash(const struct alg_test_desc *desc, const char *driver,
18519b3abc01SEric Biggers 			 u32 type, u32 mask)
18529b3abc01SEric Biggers {
18539b3abc01SEric Biggers 	const struct hash_testvec *template = desc->suite.hash.vecs;
18549b3abc01SEric Biggers 	unsigned int tcount = desc->suite.hash.count;
18559b3abc01SEric Biggers 	unsigned int nr_unkeyed, nr_keyed;
18569b3abc01SEric Biggers 	int err;
18579b3abc01SEric Biggers 
18589b3abc01SEric Biggers 	/*
18599b3abc01SEric Biggers 	 * For OPTIONAL_KEY algorithms, we have to do all the unkeyed tests
18609b3abc01SEric Biggers 	 * first, before setting a key on the tfm.  To make this easier, we
18619b3abc01SEric Biggers 	 * require that the unkeyed test vectors (if any) are listed first.
18629b3abc01SEric Biggers 	 */
18639b3abc01SEric Biggers 
18649b3abc01SEric Biggers 	for (nr_unkeyed = 0; nr_unkeyed < tcount; nr_unkeyed++) {
18659b3abc01SEric Biggers 		if (template[nr_unkeyed].ksize)
18669b3abc01SEric Biggers 			break;
18679b3abc01SEric Biggers 	}
18689b3abc01SEric Biggers 	for (nr_keyed = 0; nr_unkeyed + nr_keyed < tcount; nr_keyed++) {
18699b3abc01SEric Biggers 		if (!template[nr_unkeyed + nr_keyed].ksize) {
18709b3abc01SEric Biggers 			pr_err("alg: hash: test vectors for %s out of order, "
18719b3abc01SEric Biggers 			       "unkeyed ones must come first\n", desc->alg);
18729b3abc01SEric Biggers 			return -EINVAL;
18739b3abc01SEric Biggers 		}
18749b3abc01SEric Biggers 	}
18759b3abc01SEric Biggers 
18769b3abc01SEric Biggers 	err = 0;
18779b3abc01SEric Biggers 	if (nr_unkeyed) {
18789b3abc01SEric Biggers 		err = __alg_test_hash(template, nr_unkeyed, driver, type, mask);
18799b3abc01SEric Biggers 		template += nr_unkeyed;
18809b3abc01SEric Biggers 	}
18819b3abc01SEric Biggers 
18829b3abc01SEric Biggers 	if (!err && nr_keyed)
18839b3abc01SEric Biggers 		err = __alg_test_hash(template, nr_keyed, driver, type, mask);
18849b3abc01SEric Biggers 
18859b3abc01SEric Biggers 	return err;
18869b3abc01SEric Biggers }
18879b3abc01SEric Biggers 
18888e3ee85eSHerbert Xu static int alg_test_crc32c(const struct alg_test_desc *desc,
18898e3ee85eSHerbert Xu 			   const char *driver, u32 type, u32 mask)
18908e3ee85eSHerbert Xu {
18918e3ee85eSHerbert Xu 	struct crypto_shash *tfm;
1892cb9dde88SEric Biggers 	__le32 val;
18938e3ee85eSHerbert Xu 	int err;
18948e3ee85eSHerbert Xu 
18958e3ee85eSHerbert Xu 	err = alg_test_hash(desc, driver, type, mask);
18968e3ee85eSHerbert Xu 	if (err)
18978e3ee85eSHerbert Xu 		goto out;
18988e3ee85eSHerbert Xu 
1899eed93e0cSHerbert Xu 	tfm = crypto_alloc_shash(driver, type, mask);
19008e3ee85eSHerbert Xu 	if (IS_ERR(tfm)) {
19018e3ee85eSHerbert Xu 		printk(KERN_ERR "alg: crc32c: Failed to load transform for %s: "
19028e3ee85eSHerbert Xu 		       "%ld\n", driver, PTR_ERR(tfm));
19038e3ee85eSHerbert Xu 		err = PTR_ERR(tfm);
19048e3ee85eSHerbert Xu 		goto out;
19058e3ee85eSHerbert Xu 	}
19068e3ee85eSHerbert Xu 
19078e3ee85eSHerbert Xu 	do {
19084c5c3024SJan-Simon Möller 		SHASH_DESC_ON_STACK(shash, tfm);
19094c5c3024SJan-Simon Möller 		u32 *ctx = (u32 *)shash_desc_ctx(shash);
19108e3ee85eSHerbert Xu 
19114c5c3024SJan-Simon Möller 		shash->tfm = tfm;
19124c5c3024SJan-Simon Möller 		shash->flags = 0;
19138e3ee85eSHerbert Xu 
1914cb9dde88SEric Biggers 		*ctx = 420553207;
19154c5c3024SJan-Simon Möller 		err = crypto_shash_final(shash, (u8 *)&val);
19168e3ee85eSHerbert Xu 		if (err) {
19178e3ee85eSHerbert Xu 			printk(KERN_ERR "alg: crc32c: Operation failed for "
19188e3ee85eSHerbert Xu 			       "%s: %d\n", driver, err);
19198e3ee85eSHerbert Xu 			break;
19208e3ee85eSHerbert Xu 		}
19218e3ee85eSHerbert Xu 
1922cb9dde88SEric Biggers 		if (val != cpu_to_le32(~420553207)) {
1923cb9dde88SEric Biggers 			pr_err("alg: crc32c: Test failed for %s: %u\n",
1924cb9dde88SEric Biggers 			       driver, le32_to_cpu(val));
19258e3ee85eSHerbert Xu 			err = -EINVAL;
19268e3ee85eSHerbert Xu 		}
19278e3ee85eSHerbert Xu 	} while (0);
19288e3ee85eSHerbert Xu 
19298e3ee85eSHerbert Xu 	crypto_free_shash(tfm);
19308e3ee85eSHerbert Xu 
19318e3ee85eSHerbert Xu out:
19328e3ee85eSHerbert Xu 	return err;
19338e3ee85eSHerbert Xu }
19348e3ee85eSHerbert Xu 
19357647d6ceSJarod Wilson static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver,
19367647d6ceSJarod Wilson 			  u32 type, u32 mask)
19377647d6ceSJarod Wilson {
19387647d6ceSJarod Wilson 	struct crypto_rng *rng;
19397647d6ceSJarod Wilson 	int err;
19407647d6ceSJarod Wilson 
1941eed93e0cSHerbert Xu 	rng = crypto_alloc_rng(driver, type, mask);
19427647d6ceSJarod Wilson 	if (IS_ERR(rng)) {
19437647d6ceSJarod Wilson 		printk(KERN_ERR "alg: cprng: Failed to load transform for %s: "
19447647d6ceSJarod Wilson 		       "%ld\n", driver, PTR_ERR(rng));
19457647d6ceSJarod Wilson 		return PTR_ERR(rng);
19467647d6ceSJarod Wilson 	}
19477647d6ceSJarod Wilson 
19487647d6ceSJarod Wilson 	err = test_cprng(rng, desc->suite.cprng.vecs, desc->suite.cprng.count);
19497647d6ceSJarod Wilson 
19507647d6ceSJarod Wilson 	crypto_free_rng(rng);
19517647d6ceSJarod Wilson 
19527647d6ceSJarod Wilson 	return err;
19537647d6ceSJarod Wilson }
19547647d6ceSJarod Wilson 
195564d1cdfbSStephan Mueller 
1956b13b1e0cSEric Biggers static int drbg_cavs_test(const struct drbg_testvec *test, int pr,
195764d1cdfbSStephan Mueller 			  const char *driver, u32 type, u32 mask)
195864d1cdfbSStephan Mueller {
195964d1cdfbSStephan Mueller 	int ret = -EAGAIN;
196064d1cdfbSStephan Mueller 	struct crypto_rng *drng;
196164d1cdfbSStephan Mueller 	struct drbg_test_data test_data;
196264d1cdfbSStephan Mueller 	struct drbg_string addtl, pers, testentropy;
196364d1cdfbSStephan Mueller 	unsigned char *buf = kzalloc(test->expectedlen, GFP_KERNEL);
196464d1cdfbSStephan Mueller 
196564d1cdfbSStephan Mueller 	if (!buf)
196664d1cdfbSStephan Mueller 		return -ENOMEM;
196764d1cdfbSStephan Mueller 
1968eed93e0cSHerbert Xu 	drng = crypto_alloc_rng(driver, type, mask);
196964d1cdfbSStephan Mueller 	if (IS_ERR(drng)) {
197064d1cdfbSStephan Mueller 		printk(KERN_ERR "alg: drbg: could not allocate DRNG handle for "
197164d1cdfbSStephan Mueller 		       "%s\n", driver);
197264d1cdfbSStephan Mueller 		kzfree(buf);
197364d1cdfbSStephan Mueller 		return -ENOMEM;
197464d1cdfbSStephan Mueller 	}
197564d1cdfbSStephan Mueller 
197664d1cdfbSStephan Mueller 	test_data.testentropy = &testentropy;
197764d1cdfbSStephan Mueller 	drbg_string_fill(&testentropy, test->entropy, test->entropylen);
197864d1cdfbSStephan Mueller 	drbg_string_fill(&pers, test->pers, test->perslen);
197964d1cdfbSStephan Mueller 	ret = crypto_drbg_reset_test(drng, &pers, &test_data);
198064d1cdfbSStephan Mueller 	if (ret) {
198164d1cdfbSStephan Mueller 		printk(KERN_ERR "alg: drbg: Failed to reset rng\n");
198264d1cdfbSStephan Mueller 		goto outbuf;
198364d1cdfbSStephan Mueller 	}
198464d1cdfbSStephan Mueller 
198564d1cdfbSStephan Mueller 	drbg_string_fill(&addtl, test->addtla, test->addtllen);
198664d1cdfbSStephan Mueller 	if (pr) {
198764d1cdfbSStephan Mueller 		drbg_string_fill(&testentropy, test->entpra, test->entprlen);
198864d1cdfbSStephan Mueller 		ret = crypto_drbg_get_bytes_addtl_test(drng,
198964d1cdfbSStephan Mueller 			buf, test->expectedlen, &addtl,	&test_data);
199064d1cdfbSStephan Mueller 	} else {
199164d1cdfbSStephan Mueller 		ret = crypto_drbg_get_bytes_addtl(drng,
199264d1cdfbSStephan Mueller 			buf, test->expectedlen, &addtl);
199364d1cdfbSStephan Mueller 	}
199419e60e13SStephan Mueller 	if (ret < 0) {
199564d1cdfbSStephan Mueller 		printk(KERN_ERR "alg: drbg: could not obtain random data for "
199664d1cdfbSStephan Mueller 		       "driver %s\n", driver);
199764d1cdfbSStephan Mueller 		goto outbuf;
199864d1cdfbSStephan Mueller 	}
199964d1cdfbSStephan Mueller 
200064d1cdfbSStephan Mueller 	drbg_string_fill(&addtl, test->addtlb, test->addtllen);
200164d1cdfbSStephan Mueller 	if (pr) {
200264d1cdfbSStephan Mueller 		drbg_string_fill(&testentropy, test->entprb, test->entprlen);
200364d1cdfbSStephan Mueller 		ret = crypto_drbg_get_bytes_addtl_test(drng,
200464d1cdfbSStephan Mueller 			buf, test->expectedlen, &addtl, &test_data);
200564d1cdfbSStephan Mueller 	} else {
200664d1cdfbSStephan Mueller 		ret = crypto_drbg_get_bytes_addtl(drng,
200764d1cdfbSStephan Mueller 			buf, test->expectedlen, &addtl);
200864d1cdfbSStephan Mueller 	}
200919e60e13SStephan Mueller 	if (ret < 0) {
201064d1cdfbSStephan Mueller 		printk(KERN_ERR "alg: drbg: could not obtain random data for "
201164d1cdfbSStephan Mueller 		       "driver %s\n", driver);
201264d1cdfbSStephan Mueller 		goto outbuf;
201364d1cdfbSStephan Mueller 	}
201464d1cdfbSStephan Mueller 
201564d1cdfbSStephan Mueller 	ret = memcmp(test->expected, buf, test->expectedlen);
201664d1cdfbSStephan Mueller 
201764d1cdfbSStephan Mueller outbuf:
201864d1cdfbSStephan Mueller 	crypto_free_rng(drng);
201964d1cdfbSStephan Mueller 	kzfree(buf);
202064d1cdfbSStephan Mueller 	return ret;
202164d1cdfbSStephan Mueller }
202264d1cdfbSStephan Mueller 
202364d1cdfbSStephan Mueller 
202464d1cdfbSStephan Mueller static int alg_test_drbg(const struct alg_test_desc *desc, const char *driver,
202564d1cdfbSStephan Mueller 			 u32 type, u32 mask)
202664d1cdfbSStephan Mueller {
202764d1cdfbSStephan Mueller 	int err = 0;
202864d1cdfbSStephan Mueller 	int pr = 0;
202964d1cdfbSStephan Mueller 	int i = 0;
2030b13b1e0cSEric Biggers 	const struct drbg_testvec *template = desc->suite.drbg.vecs;
203164d1cdfbSStephan Mueller 	unsigned int tcount = desc->suite.drbg.count;
203264d1cdfbSStephan Mueller 
203364d1cdfbSStephan Mueller 	if (0 == memcmp(driver, "drbg_pr_", 8))
203464d1cdfbSStephan Mueller 		pr = 1;
203564d1cdfbSStephan Mueller 
203664d1cdfbSStephan Mueller 	for (i = 0; i < tcount; i++) {
203764d1cdfbSStephan Mueller 		err = drbg_cavs_test(&template[i], pr, driver, type, mask);
203864d1cdfbSStephan Mueller 		if (err) {
203964d1cdfbSStephan Mueller 			printk(KERN_ERR "alg: drbg: Test %d failed for %s\n",
204064d1cdfbSStephan Mueller 			       i, driver);
204164d1cdfbSStephan Mueller 			err = -EINVAL;
204264d1cdfbSStephan Mueller 			break;
204364d1cdfbSStephan Mueller 		}
204464d1cdfbSStephan Mueller 	}
204564d1cdfbSStephan Mueller 	return err;
204664d1cdfbSStephan Mueller 
204764d1cdfbSStephan Mueller }
204864d1cdfbSStephan Mueller 
2049b13b1e0cSEric Biggers static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec,
2050802c7f1cSSalvatore Benedetto 		       const char *alg)
2051802c7f1cSSalvatore Benedetto {
2052802c7f1cSSalvatore Benedetto 	struct kpp_request *req;
2053802c7f1cSSalvatore Benedetto 	void *input_buf = NULL;
2054802c7f1cSSalvatore Benedetto 	void *output_buf = NULL;
205547d3fd39STudor-Dan Ambarus 	void *a_public = NULL;
205647d3fd39STudor-Dan Ambarus 	void *a_ss = NULL;
205747d3fd39STudor-Dan Ambarus 	void *shared_secret = NULL;
20587f397136SGilad Ben-Yossef 	struct crypto_wait wait;
2059802c7f1cSSalvatore Benedetto 	unsigned int out_len_max;
2060802c7f1cSSalvatore Benedetto 	int err = -ENOMEM;
2061802c7f1cSSalvatore Benedetto 	struct scatterlist src, dst;
2062802c7f1cSSalvatore Benedetto 
2063802c7f1cSSalvatore Benedetto 	req = kpp_request_alloc(tfm, GFP_KERNEL);
2064802c7f1cSSalvatore Benedetto 	if (!req)
2065802c7f1cSSalvatore Benedetto 		return err;
2066802c7f1cSSalvatore Benedetto 
20677f397136SGilad Ben-Yossef 	crypto_init_wait(&wait);
2068802c7f1cSSalvatore Benedetto 
2069802c7f1cSSalvatore Benedetto 	err = crypto_kpp_set_secret(tfm, vec->secret, vec->secret_size);
2070802c7f1cSSalvatore Benedetto 	if (err < 0)
2071802c7f1cSSalvatore Benedetto 		goto free_req;
2072802c7f1cSSalvatore Benedetto 
2073802c7f1cSSalvatore Benedetto 	out_len_max = crypto_kpp_maxsize(tfm);
2074802c7f1cSSalvatore Benedetto 	output_buf = kzalloc(out_len_max, GFP_KERNEL);
2075802c7f1cSSalvatore Benedetto 	if (!output_buf) {
2076802c7f1cSSalvatore Benedetto 		err = -ENOMEM;
2077802c7f1cSSalvatore Benedetto 		goto free_req;
2078802c7f1cSSalvatore Benedetto 	}
2079802c7f1cSSalvatore Benedetto 
2080802c7f1cSSalvatore Benedetto 	/* Use appropriate parameter as base */
2081802c7f1cSSalvatore Benedetto 	kpp_request_set_input(req, NULL, 0);
2082802c7f1cSSalvatore Benedetto 	sg_init_one(&dst, output_buf, out_len_max);
2083802c7f1cSSalvatore Benedetto 	kpp_request_set_output(req, &dst, out_len_max);
2084802c7f1cSSalvatore Benedetto 	kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
20857f397136SGilad Ben-Yossef 				 crypto_req_done, &wait);
2086802c7f1cSSalvatore Benedetto 
208747d3fd39STudor-Dan Ambarus 	/* Compute party A's public key */
20887f397136SGilad Ben-Yossef 	err = crypto_wait_req(crypto_kpp_generate_public_key(req), &wait);
2089802c7f1cSSalvatore Benedetto 	if (err) {
209047d3fd39STudor-Dan Ambarus 		pr_err("alg: %s: Party A: generate public key test failed. err %d\n",
2091802c7f1cSSalvatore Benedetto 		       alg, err);
2092802c7f1cSSalvatore Benedetto 		goto free_output;
2093802c7f1cSSalvatore Benedetto 	}
209447d3fd39STudor-Dan Ambarus 
209547d3fd39STudor-Dan Ambarus 	if (vec->genkey) {
209647d3fd39STudor-Dan Ambarus 		/* Save party A's public key */
209747d3fd39STudor-Dan Ambarus 		a_public = kzalloc(out_len_max, GFP_KERNEL);
209847d3fd39STudor-Dan Ambarus 		if (!a_public) {
209947d3fd39STudor-Dan Ambarus 			err = -ENOMEM;
210047d3fd39STudor-Dan Ambarus 			goto free_output;
210147d3fd39STudor-Dan Ambarus 		}
210247d3fd39STudor-Dan Ambarus 		memcpy(a_public, sg_virt(req->dst), out_len_max);
210347d3fd39STudor-Dan Ambarus 	} else {
2104802c7f1cSSalvatore Benedetto 		/* Verify calculated public key */
2105802c7f1cSSalvatore Benedetto 		if (memcmp(vec->expected_a_public, sg_virt(req->dst),
2106802c7f1cSSalvatore Benedetto 			   vec->expected_a_public_size)) {
210747d3fd39STudor-Dan Ambarus 			pr_err("alg: %s: Party A: generate public key test failed. Invalid output\n",
2108802c7f1cSSalvatore Benedetto 			       alg);
2109802c7f1cSSalvatore Benedetto 			err = -EINVAL;
2110802c7f1cSSalvatore Benedetto 			goto free_output;
2111802c7f1cSSalvatore Benedetto 		}
211247d3fd39STudor-Dan Ambarus 	}
2113802c7f1cSSalvatore Benedetto 
2114802c7f1cSSalvatore Benedetto 	/* Calculate shared secret key by using counter part (b) public key. */
2115802c7f1cSSalvatore Benedetto 	input_buf = kzalloc(vec->b_public_size, GFP_KERNEL);
2116802c7f1cSSalvatore Benedetto 	if (!input_buf) {
2117802c7f1cSSalvatore Benedetto 		err = -ENOMEM;
2118802c7f1cSSalvatore Benedetto 		goto free_output;
2119802c7f1cSSalvatore Benedetto 	}
2120802c7f1cSSalvatore Benedetto 
2121802c7f1cSSalvatore Benedetto 	memcpy(input_buf, vec->b_public, vec->b_public_size);
2122802c7f1cSSalvatore Benedetto 	sg_init_one(&src, input_buf, vec->b_public_size);
2123802c7f1cSSalvatore Benedetto 	sg_init_one(&dst, output_buf, out_len_max);
2124802c7f1cSSalvatore Benedetto 	kpp_request_set_input(req, &src, vec->b_public_size);
2125802c7f1cSSalvatore Benedetto 	kpp_request_set_output(req, &dst, out_len_max);
2126802c7f1cSSalvatore Benedetto 	kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
21277f397136SGilad Ben-Yossef 				 crypto_req_done, &wait);
21287f397136SGilad Ben-Yossef 	err = crypto_wait_req(crypto_kpp_compute_shared_secret(req), &wait);
2129802c7f1cSSalvatore Benedetto 	if (err) {
213047d3fd39STudor-Dan Ambarus 		pr_err("alg: %s: Party A: compute shared secret test failed. err %d\n",
2131802c7f1cSSalvatore Benedetto 		       alg, err);
2132802c7f1cSSalvatore Benedetto 		goto free_all;
2133802c7f1cSSalvatore Benedetto 	}
213447d3fd39STudor-Dan Ambarus 
213547d3fd39STudor-Dan Ambarus 	if (vec->genkey) {
213647d3fd39STudor-Dan Ambarus 		/* Save the shared secret obtained by party A */
213747d3fd39STudor-Dan Ambarus 		a_ss = kzalloc(vec->expected_ss_size, GFP_KERNEL);
213847d3fd39STudor-Dan Ambarus 		if (!a_ss) {
213947d3fd39STudor-Dan Ambarus 			err = -ENOMEM;
214047d3fd39STudor-Dan Ambarus 			goto free_all;
214147d3fd39STudor-Dan Ambarus 		}
214247d3fd39STudor-Dan Ambarus 		memcpy(a_ss, sg_virt(req->dst), vec->expected_ss_size);
214347d3fd39STudor-Dan Ambarus 
214447d3fd39STudor-Dan Ambarus 		/*
214547d3fd39STudor-Dan Ambarus 		 * Calculate party B's shared secret by using party A's
214647d3fd39STudor-Dan Ambarus 		 * public key.
214747d3fd39STudor-Dan Ambarus 		 */
214847d3fd39STudor-Dan Ambarus 		err = crypto_kpp_set_secret(tfm, vec->b_secret,
214947d3fd39STudor-Dan Ambarus 					    vec->b_secret_size);
215047d3fd39STudor-Dan Ambarus 		if (err < 0)
215147d3fd39STudor-Dan Ambarus 			goto free_all;
215247d3fd39STudor-Dan Ambarus 
215347d3fd39STudor-Dan Ambarus 		sg_init_one(&src, a_public, vec->expected_a_public_size);
215447d3fd39STudor-Dan Ambarus 		sg_init_one(&dst, output_buf, out_len_max);
215547d3fd39STudor-Dan Ambarus 		kpp_request_set_input(req, &src, vec->expected_a_public_size);
215647d3fd39STudor-Dan Ambarus 		kpp_request_set_output(req, &dst, out_len_max);
215747d3fd39STudor-Dan Ambarus 		kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
21587f397136SGilad Ben-Yossef 					 crypto_req_done, &wait);
21597f397136SGilad Ben-Yossef 		err = crypto_wait_req(crypto_kpp_compute_shared_secret(req),
21607f397136SGilad Ben-Yossef 				      &wait);
216147d3fd39STudor-Dan Ambarus 		if (err) {
216247d3fd39STudor-Dan Ambarus 			pr_err("alg: %s: Party B: compute shared secret failed. err %d\n",
216347d3fd39STudor-Dan Ambarus 			       alg, err);
216447d3fd39STudor-Dan Ambarus 			goto free_all;
216547d3fd39STudor-Dan Ambarus 		}
216647d3fd39STudor-Dan Ambarus 
216747d3fd39STudor-Dan Ambarus 		shared_secret = a_ss;
216847d3fd39STudor-Dan Ambarus 	} else {
216947d3fd39STudor-Dan Ambarus 		shared_secret = (void *)vec->expected_ss;
217047d3fd39STudor-Dan Ambarus 	}
217147d3fd39STudor-Dan Ambarus 
2172802c7f1cSSalvatore Benedetto 	/*
2173802c7f1cSSalvatore Benedetto 	 * verify shared secret from which the user will derive
2174802c7f1cSSalvatore Benedetto 	 * secret key by executing whatever hash it has chosen
2175802c7f1cSSalvatore Benedetto 	 */
217647d3fd39STudor-Dan Ambarus 	if (memcmp(shared_secret, sg_virt(req->dst),
2177802c7f1cSSalvatore Benedetto 		   vec->expected_ss_size)) {
2178802c7f1cSSalvatore Benedetto 		pr_err("alg: %s: compute shared secret test failed. Invalid output\n",
2179802c7f1cSSalvatore Benedetto 		       alg);
2180802c7f1cSSalvatore Benedetto 		err = -EINVAL;
2181802c7f1cSSalvatore Benedetto 	}
2182802c7f1cSSalvatore Benedetto 
2183802c7f1cSSalvatore Benedetto free_all:
218447d3fd39STudor-Dan Ambarus 	kfree(a_ss);
2185802c7f1cSSalvatore Benedetto 	kfree(input_buf);
2186802c7f1cSSalvatore Benedetto free_output:
218747d3fd39STudor-Dan Ambarus 	kfree(a_public);
2188802c7f1cSSalvatore Benedetto 	kfree(output_buf);
2189802c7f1cSSalvatore Benedetto free_req:
2190802c7f1cSSalvatore Benedetto 	kpp_request_free(req);
2191802c7f1cSSalvatore Benedetto 	return err;
2192802c7f1cSSalvatore Benedetto }
2193802c7f1cSSalvatore Benedetto 
2194802c7f1cSSalvatore Benedetto static int test_kpp(struct crypto_kpp *tfm, const char *alg,
2195b13b1e0cSEric Biggers 		    const struct kpp_testvec *vecs, unsigned int tcount)
2196802c7f1cSSalvatore Benedetto {
2197802c7f1cSSalvatore Benedetto 	int ret, i;
2198802c7f1cSSalvatore Benedetto 
2199802c7f1cSSalvatore Benedetto 	for (i = 0; i < tcount; i++) {
2200802c7f1cSSalvatore Benedetto 		ret = do_test_kpp(tfm, vecs++, alg);
2201802c7f1cSSalvatore Benedetto 		if (ret) {
2202802c7f1cSSalvatore Benedetto 			pr_err("alg: %s: test failed on vector %d, err=%d\n",
2203802c7f1cSSalvatore Benedetto 			       alg, i + 1, ret);
2204802c7f1cSSalvatore Benedetto 			return ret;
2205802c7f1cSSalvatore Benedetto 		}
2206802c7f1cSSalvatore Benedetto 	}
2207802c7f1cSSalvatore Benedetto 	return 0;
2208802c7f1cSSalvatore Benedetto }
2209802c7f1cSSalvatore Benedetto 
2210802c7f1cSSalvatore Benedetto static int alg_test_kpp(const struct alg_test_desc *desc, const char *driver,
2211802c7f1cSSalvatore Benedetto 			u32 type, u32 mask)
2212802c7f1cSSalvatore Benedetto {
2213802c7f1cSSalvatore Benedetto 	struct crypto_kpp *tfm;
2214802c7f1cSSalvatore Benedetto 	int err = 0;
2215802c7f1cSSalvatore Benedetto 
2216eed93e0cSHerbert Xu 	tfm = crypto_alloc_kpp(driver, type, mask);
2217802c7f1cSSalvatore Benedetto 	if (IS_ERR(tfm)) {
2218802c7f1cSSalvatore Benedetto 		pr_err("alg: kpp: Failed to load tfm for %s: %ld\n",
2219802c7f1cSSalvatore Benedetto 		       driver, PTR_ERR(tfm));
2220802c7f1cSSalvatore Benedetto 		return PTR_ERR(tfm);
2221802c7f1cSSalvatore Benedetto 	}
2222802c7f1cSSalvatore Benedetto 	if (desc->suite.kpp.vecs)
2223802c7f1cSSalvatore Benedetto 		err = test_kpp(tfm, desc->alg, desc->suite.kpp.vecs,
2224802c7f1cSSalvatore Benedetto 			       desc->suite.kpp.count);
2225802c7f1cSSalvatore Benedetto 
2226802c7f1cSSalvatore Benedetto 	crypto_free_kpp(tfm);
2227802c7f1cSSalvatore Benedetto 	return err;
2228802c7f1cSSalvatore Benedetto }
2229802c7f1cSSalvatore Benedetto 
223050d2b643SHerbert Xu static int test_akcipher_one(struct crypto_akcipher *tfm,
2231b13b1e0cSEric Biggers 			     const struct akcipher_testvec *vecs)
2232946cc463STadeusz Struk {
2233df27b26fSHerbert Xu 	char *xbuf[XBUFSIZE];
2234946cc463STadeusz Struk 	struct akcipher_request *req;
2235946cc463STadeusz Struk 	void *outbuf_enc = NULL;
2236946cc463STadeusz Struk 	void *outbuf_dec = NULL;
22377f397136SGilad Ben-Yossef 	struct crypto_wait wait;
2238946cc463STadeusz Struk 	unsigned int out_len_max, out_len = 0;
2239946cc463STadeusz Struk 	int err = -ENOMEM;
224022287b0bSTadeusz Struk 	struct scatterlist src, dst, src_tab[2];
22410507de94SVitaly Chikunov 	const char *m, *c;
22420507de94SVitaly Chikunov 	unsigned int m_size, c_size;
22430507de94SVitaly Chikunov 	const char *op;
2244946cc463STadeusz Struk 
2245df27b26fSHerbert Xu 	if (testmgr_alloc_buf(xbuf))
2246df27b26fSHerbert Xu 		return err;
2247df27b26fSHerbert Xu 
2248946cc463STadeusz Struk 	req = akcipher_request_alloc(tfm, GFP_KERNEL);
2249946cc463STadeusz Struk 	if (!req)
2250df27b26fSHerbert Xu 		goto free_xbuf;
2251946cc463STadeusz Struk 
22527f397136SGilad Ben-Yossef 	crypto_init_wait(&wait);
225322287b0bSTadeusz Struk 
225422287b0bSTadeusz Struk 	if (vecs->public_key_vec)
225522287b0bSTadeusz Struk 		err = crypto_akcipher_set_pub_key(tfm, vecs->key,
225622287b0bSTadeusz Struk 						  vecs->key_len);
225722287b0bSTadeusz Struk 	else
225822287b0bSTadeusz Struk 		err = crypto_akcipher_set_priv_key(tfm, vecs->key,
225922287b0bSTadeusz Struk 						   vecs->key_len);
2260946cc463STadeusz Struk 	if (err)
2261946cc463STadeusz Struk 		goto free_req;
2262946cc463STadeusz Struk 
226357763f5eSSalvatore Benedetto 	err = -ENOMEM;
226422287b0bSTadeusz Struk 	out_len_max = crypto_akcipher_maxsize(tfm);
22650507de94SVitaly Chikunov 
22660507de94SVitaly Chikunov 	/*
22670507de94SVitaly Chikunov 	 * First run test which do not require a private key, such as
22680507de94SVitaly Chikunov 	 * encrypt or verify.
22690507de94SVitaly Chikunov 	 */
2270946cc463STadeusz Struk 	outbuf_enc = kzalloc(out_len_max, GFP_KERNEL);
2271946cc463STadeusz Struk 	if (!outbuf_enc)
2272946cc463STadeusz Struk 		goto free_req;
2273946cc463STadeusz Struk 
22740507de94SVitaly Chikunov 	if (!vecs->siggen_sigver_test) {
22750507de94SVitaly Chikunov 		m = vecs->m;
22760507de94SVitaly Chikunov 		m_size = vecs->m_size;
22770507de94SVitaly Chikunov 		c = vecs->c;
22780507de94SVitaly Chikunov 		c_size = vecs->c_size;
22790507de94SVitaly Chikunov 		op = "encrypt";
22800507de94SVitaly Chikunov 	} else {
22810507de94SVitaly Chikunov 		/* Swap args so we could keep plaintext (digest)
22820507de94SVitaly Chikunov 		 * in vecs->m, and cooked signature in vecs->c.
22830507de94SVitaly Chikunov 		 */
22840507de94SVitaly Chikunov 		m = vecs->c; /* signature */
22850507de94SVitaly Chikunov 		m_size = vecs->c_size;
22860507de94SVitaly Chikunov 		c = vecs->m; /* digest */
22870507de94SVitaly Chikunov 		c_size = vecs->m_size;
22880507de94SVitaly Chikunov 		op = "verify";
22890507de94SVitaly Chikunov 	}
2290df27b26fSHerbert Xu 
22910507de94SVitaly Chikunov 	if (WARN_ON(m_size > PAGE_SIZE))
22920507de94SVitaly Chikunov 		goto free_all;
22930507de94SVitaly Chikunov 	memcpy(xbuf[0], m, m_size);
2294df27b26fSHerbert Xu 
229522287b0bSTadeusz Struk 	sg_init_table(src_tab, 2);
2296df27b26fSHerbert Xu 	sg_set_buf(&src_tab[0], xbuf[0], 8);
22970507de94SVitaly Chikunov 	sg_set_buf(&src_tab[1], xbuf[0] + 8, m_size - 8);
229822287b0bSTadeusz Struk 	sg_init_one(&dst, outbuf_enc, out_len_max);
22990507de94SVitaly Chikunov 	akcipher_request_set_crypt(req, src_tab, &dst, m_size,
230022287b0bSTadeusz Struk 				   out_len_max);
2301946cc463STadeusz Struk 	akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
23027f397136SGilad Ben-Yossef 				      crypto_req_done, &wait);
2303946cc463STadeusz Struk 
23047f397136SGilad Ben-Yossef 	err = crypto_wait_req(vecs->siggen_sigver_test ?
23050507de94SVitaly Chikunov 			      /* Run asymmetric signature verification */
23060507de94SVitaly Chikunov 			      crypto_akcipher_verify(req) :
23071207107cSStephan Mueller 			      /* Run asymmetric encrypt */
23087f397136SGilad Ben-Yossef 			      crypto_akcipher_encrypt(req), &wait);
2309946cc463STadeusz Struk 	if (err) {
23100507de94SVitaly Chikunov 		pr_err("alg: akcipher: %s test failed. err %d\n", op, err);
2311946cc463STadeusz Struk 		goto free_all;
2312946cc463STadeusz Struk 	}
23130507de94SVitaly Chikunov 	if (req->dst_len != c_size) {
23140507de94SVitaly Chikunov 		pr_err("alg: akcipher: %s test failed. Invalid output len\n",
23150507de94SVitaly Chikunov 		       op);
2316946cc463STadeusz Struk 		err = -EINVAL;
2317946cc463STadeusz Struk 		goto free_all;
2318946cc463STadeusz Struk 	}
2319946cc463STadeusz Struk 	/* verify that encrypted message is equal to expected */
23200507de94SVitaly Chikunov 	if (memcmp(c, outbuf_enc, c_size)) {
23210507de94SVitaly Chikunov 		pr_err("alg: akcipher: %s test failed. Invalid output\n", op);
23220507de94SVitaly Chikunov 		hexdump(outbuf_enc, c_size);
2323946cc463STadeusz Struk 		err = -EINVAL;
2324946cc463STadeusz Struk 		goto free_all;
2325946cc463STadeusz Struk 	}
23260507de94SVitaly Chikunov 
23270507de94SVitaly Chikunov 	/*
23280507de94SVitaly Chikunov 	 * Don't invoke (decrypt or sign) test which require a private key
23290507de94SVitaly Chikunov 	 * for vectors with only a public key.
23300507de94SVitaly Chikunov 	 */
2331946cc463STadeusz Struk 	if (vecs->public_key_vec) {
2332946cc463STadeusz Struk 		err = 0;
2333946cc463STadeusz Struk 		goto free_all;
2334946cc463STadeusz Struk 	}
2335946cc463STadeusz Struk 	outbuf_dec = kzalloc(out_len_max, GFP_KERNEL);
2336946cc463STadeusz Struk 	if (!outbuf_dec) {
2337946cc463STadeusz Struk 		err = -ENOMEM;
2338946cc463STadeusz Struk 		goto free_all;
2339946cc463STadeusz Struk 	}
2340df27b26fSHerbert Xu 
23410507de94SVitaly Chikunov 	op = vecs->siggen_sigver_test ? "sign" : "decrypt";
23420507de94SVitaly Chikunov 	if (WARN_ON(c_size > PAGE_SIZE))
2343df27b26fSHerbert Xu 		goto free_all;
23440507de94SVitaly Chikunov 	memcpy(xbuf[0], c, c_size);
2345df27b26fSHerbert Xu 
23460507de94SVitaly Chikunov 	sg_init_one(&src, xbuf[0], c_size);
234722287b0bSTadeusz Struk 	sg_init_one(&dst, outbuf_dec, out_len_max);
23487f397136SGilad Ben-Yossef 	crypto_init_wait(&wait);
23490507de94SVitaly Chikunov 	akcipher_request_set_crypt(req, &src, &dst, c_size, out_len_max);
2350946cc463STadeusz Struk 
23517f397136SGilad Ben-Yossef 	err = crypto_wait_req(vecs->siggen_sigver_test ?
23520507de94SVitaly Chikunov 			      /* Run asymmetric signature generation */
23530507de94SVitaly Chikunov 			      crypto_akcipher_sign(req) :
23541207107cSStephan Mueller 			      /* Run asymmetric decrypt */
23557f397136SGilad Ben-Yossef 			      crypto_akcipher_decrypt(req), &wait);
2356946cc463STadeusz Struk 	if (err) {
23570507de94SVitaly Chikunov 		pr_err("alg: akcipher: %s test failed. err %d\n", op, err);
2358946cc463STadeusz Struk 		goto free_all;
2359946cc463STadeusz Struk 	}
2360946cc463STadeusz Struk 	out_len = req->dst_len;
23610507de94SVitaly Chikunov 	if (out_len < m_size) {
23620507de94SVitaly Chikunov 		pr_err("alg: akcipher: %s test failed. Invalid output len %u\n",
23630507de94SVitaly Chikunov 		       op, out_len);
2364946cc463STadeusz Struk 		err = -EINVAL;
2365946cc463STadeusz Struk 		goto free_all;
2366946cc463STadeusz Struk 	}
2367946cc463STadeusz Struk 	/* verify that decrypted message is equal to the original msg */
23680507de94SVitaly Chikunov 	if (memchr_inv(outbuf_dec, 0, out_len - m_size) ||
23690507de94SVitaly Chikunov 	    memcmp(m, outbuf_dec + out_len - m_size, m_size)) {
23700507de94SVitaly Chikunov 		pr_err("alg: akcipher: %s test failed. Invalid output\n", op);
237150d2b643SHerbert Xu 		hexdump(outbuf_dec, out_len);
2372946cc463STadeusz Struk 		err = -EINVAL;
2373946cc463STadeusz Struk 	}
2374946cc463STadeusz Struk free_all:
2375946cc463STadeusz Struk 	kfree(outbuf_dec);
2376946cc463STadeusz Struk 	kfree(outbuf_enc);
2377946cc463STadeusz Struk free_req:
2378946cc463STadeusz Struk 	akcipher_request_free(req);
2379df27b26fSHerbert Xu free_xbuf:
2380df27b26fSHerbert Xu 	testmgr_free_buf(xbuf);
2381946cc463STadeusz Struk 	return err;
2382946cc463STadeusz Struk }
2383946cc463STadeusz Struk 
238450d2b643SHerbert Xu static int test_akcipher(struct crypto_akcipher *tfm, const char *alg,
2385b13b1e0cSEric Biggers 			 const struct akcipher_testvec *vecs,
2386b13b1e0cSEric Biggers 			 unsigned int tcount)
2387946cc463STadeusz Struk {
238815226e48SHerbert Xu 	const char *algo =
238915226e48SHerbert Xu 		crypto_tfm_alg_driver_name(crypto_akcipher_tfm(tfm));
2390946cc463STadeusz Struk 	int ret, i;
2391946cc463STadeusz Struk 
2392946cc463STadeusz Struk 	for (i = 0; i < tcount; i++) {
239350d2b643SHerbert Xu 		ret = test_akcipher_one(tfm, vecs++);
239450d2b643SHerbert Xu 		if (!ret)
239550d2b643SHerbert Xu 			continue;
239650d2b643SHerbert Xu 
239715226e48SHerbert Xu 		pr_err("alg: akcipher: test %d failed for %s, err=%d\n",
239815226e48SHerbert Xu 		       i + 1, algo, ret);
2399946cc463STadeusz Struk 		return ret;
2400946cc463STadeusz Struk 	}
2401946cc463STadeusz Struk 	return 0;
2402946cc463STadeusz Struk }
2403946cc463STadeusz Struk 
2404946cc463STadeusz Struk static int alg_test_akcipher(const struct alg_test_desc *desc,
2405946cc463STadeusz Struk 			     const char *driver, u32 type, u32 mask)
2406946cc463STadeusz Struk {
2407946cc463STadeusz Struk 	struct crypto_akcipher *tfm;
2408946cc463STadeusz Struk 	int err = 0;
2409946cc463STadeusz Struk 
2410eed93e0cSHerbert Xu 	tfm = crypto_alloc_akcipher(driver, type, mask);
2411946cc463STadeusz Struk 	if (IS_ERR(tfm)) {
2412946cc463STadeusz Struk 		pr_err("alg: akcipher: Failed to load tfm for %s: %ld\n",
2413946cc463STadeusz Struk 		       driver, PTR_ERR(tfm));
2414946cc463STadeusz Struk 		return PTR_ERR(tfm);
2415946cc463STadeusz Struk 	}
2416946cc463STadeusz Struk 	if (desc->suite.akcipher.vecs)
2417946cc463STadeusz Struk 		err = test_akcipher(tfm, desc->alg, desc->suite.akcipher.vecs,
2418946cc463STadeusz Struk 				    desc->suite.akcipher.count);
2419946cc463STadeusz Struk 
2420946cc463STadeusz Struk 	crypto_free_akcipher(tfm);
2421946cc463STadeusz Struk 	return err;
2422946cc463STadeusz Struk }
2423946cc463STadeusz Struk 
2424863b557aSYouquan, Song static int alg_test_null(const struct alg_test_desc *desc,
2425863b557aSYouquan, Song 			     const char *driver, u32 type, u32 mask)
2426863b557aSYouquan, Song {
2427863b557aSYouquan, Song 	return 0;
2428863b557aSYouquan, Song }
2429863b557aSYouquan, Song 
243021c8e720SArd Biesheuvel #define __VECS(tv)	{ .vecs = tv, .count = ARRAY_SIZE(tv) }
243121c8e720SArd Biesheuvel 
2432da7f033dSHerbert Xu /* Please keep this list sorted by algorithm name. */
2433da7f033dSHerbert Xu static const struct alg_test_desc alg_test_descs[] = {
2434da7f033dSHerbert Xu 	{
2435059c2a4dSEric Biggers 		.alg = "adiantum(xchacha12,aes)",
2436059c2a4dSEric Biggers 		.test = alg_test_skcipher,
2437059c2a4dSEric Biggers 		.suite = {
2438059c2a4dSEric Biggers 			.cipher = __VECS(adiantum_xchacha12_aes_tv_template)
2439059c2a4dSEric Biggers 		},
2440059c2a4dSEric Biggers 	}, {
2441059c2a4dSEric Biggers 		.alg = "adiantum(xchacha20,aes)",
2442059c2a4dSEric Biggers 		.test = alg_test_skcipher,
2443059c2a4dSEric Biggers 		.suite = {
2444059c2a4dSEric Biggers 			.cipher = __VECS(adiantum_xchacha20_aes_tv_template)
2445059c2a4dSEric Biggers 		},
2446059c2a4dSEric Biggers 	}, {
2447b87dc203SOndrej Mosnacek 		.alg = "aegis128",
2448b87dc203SOndrej Mosnacek 		.test = alg_test_aead,
2449b87dc203SOndrej Mosnacek 		.suite = {
2450b87dc203SOndrej Mosnacek 			.aead = {
2451b87dc203SOndrej Mosnacek 				.enc = __VECS(aegis128_enc_tv_template),
2452b87dc203SOndrej Mosnacek 				.dec = __VECS(aegis128_dec_tv_template),
2453b87dc203SOndrej Mosnacek 			}
2454b87dc203SOndrej Mosnacek 		}
2455b87dc203SOndrej Mosnacek 	}, {
2456b87dc203SOndrej Mosnacek 		.alg = "aegis128l",
2457b87dc203SOndrej Mosnacek 		.test = alg_test_aead,
2458b87dc203SOndrej Mosnacek 		.suite = {
2459b87dc203SOndrej Mosnacek 			.aead = {
2460b87dc203SOndrej Mosnacek 				.enc = __VECS(aegis128l_enc_tv_template),
2461b87dc203SOndrej Mosnacek 				.dec = __VECS(aegis128l_dec_tv_template),
2462b87dc203SOndrej Mosnacek 			}
2463b87dc203SOndrej Mosnacek 		}
2464b87dc203SOndrej Mosnacek 	}, {
2465b87dc203SOndrej Mosnacek 		.alg = "aegis256",
2466b87dc203SOndrej Mosnacek 		.test = alg_test_aead,
2467b87dc203SOndrej Mosnacek 		.suite = {
2468b87dc203SOndrej Mosnacek 			.aead = {
2469b87dc203SOndrej Mosnacek 				.enc = __VECS(aegis256_enc_tv_template),
2470b87dc203SOndrej Mosnacek 				.dec = __VECS(aegis256_dec_tv_template),
2471b87dc203SOndrej Mosnacek 			}
2472b87dc203SOndrej Mosnacek 		}
2473b87dc203SOndrej Mosnacek 	}, {
2474e08ca2daSJarod Wilson 		.alg = "ansi_cprng",
2475e08ca2daSJarod Wilson 		.test = alg_test_cprng,
2476e08ca2daSJarod Wilson 		.suite = {
247721c8e720SArd Biesheuvel 			.cprng = __VECS(ansi_cprng_aes_tv_template)
2478e08ca2daSJarod Wilson 		}
2479e08ca2daSJarod Wilson 	}, {
2480bca4feb0SHoria Geanta 		.alg = "authenc(hmac(md5),ecb(cipher_null))",
2481bca4feb0SHoria Geanta 		.test = alg_test_aead,
2482bca4feb0SHoria Geanta 		.suite = {
2483bca4feb0SHoria Geanta 			.aead = {
248421c8e720SArd Biesheuvel 				.enc = __VECS(hmac_md5_ecb_cipher_null_enc_tv_template),
248521c8e720SArd Biesheuvel 				.dec = __VECS(hmac_md5_ecb_cipher_null_dec_tv_template)
2486bca4feb0SHoria Geanta 			}
2487bca4feb0SHoria Geanta 		}
2488bca4feb0SHoria Geanta 	}, {
2489a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha1),cbc(aes))",
2490e46e9a46SHoria Geanta 		.test = alg_test_aead,
2491bcf741cbSHerbert Xu 		.fips_allowed = 1,
2492e46e9a46SHoria Geanta 		.suite = {
2493e46e9a46SHoria Geanta 			.aead = {
249421c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha1_aes_cbc_enc_tv_temp)
24955208ed2cSNitesh Lal 			}
24965208ed2cSNitesh Lal 		}
24975208ed2cSNitesh Lal 	}, {
2498a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha1),cbc(des))",
24995208ed2cSNitesh Lal 		.test = alg_test_aead,
25005208ed2cSNitesh Lal 		.suite = {
25015208ed2cSNitesh Lal 			.aead = {
250221c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha1_des_cbc_enc_tv_temp)
25035208ed2cSNitesh Lal 			}
25045208ed2cSNitesh Lal 		}
25055208ed2cSNitesh Lal 	}, {
2506a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha1),cbc(des3_ede))",
25075208ed2cSNitesh Lal 		.test = alg_test_aead,
2508ed1afac9SMarcus Meissner 		.fips_allowed = 1,
25095208ed2cSNitesh Lal 		.suite = {
25105208ed2cSNitesh Lal 			.aead = {
251121c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha1_des3_ede_cbc_enc_tv_temp)
2512e46e9a46SHoria Geanta 			}
2513e46e9a46SHoria Geanta 		}
2514e46e9a46SHoria Geanta 	}, {
2515fb16abc2SMarcus Meissner 		.alg = "authenc(hmac(sha1),ctr(aes))",
2516fb16abc2SMarcus Meissner 		.test = alg_test_null,
2517fb16abc2SMarcus Meissner 		.fips_allowed = 1,
2518fb16abc2SMarcus Meissner 	}, {
2519bca4feb0SHoria Geanta 		.alg = "authenc(hmac(sha1),ecb(cipher_null))",
2520bca4feb0SHoria Geanta 		.test = alg_test_aead,
2521bca4feb0SHoria Geanta 		.suite = {
2522bca4feb0SHoria Geanta 			.aead = {
252321c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha1_ecb_cipher_null_enc_tv_temp),
252421c8e720SArd Biesheuvel 				.dec = __VECS(hmac_sha1_ecb_cipher_null_dec_tv_temp)
25255208ed2cSNitesh Lal 			}
25265208ed2cSNitesh Lal 		}
25275208ed2cSNitesh Lal 	}, {
25288888690eSMarcus Meissner 		.alg = "authenc(hmac(sha1),rfc3686(ctr(aes)))",
25298888690eSMarcus Meissner 		.test = alg_test_null,
25308888690eSMarcus Meissner 		.fips_allowed = 1,
25318888690eSMarcus Meissner 	}, {
2532a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha224),cbc(des))",
25335208ed2cSNitesh Lal 		.test = alg_test_aead,
25345208ed2cSNitesh Lal 		.suite = {
25355208ed2cSNitesh Lal 			.aead = {
253621c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha224_des_cbc_enc_tv_temp)
25375208ed2cSNitesh Lal 			}
25385208ed2cSNitesh Lal 		}
25395208ed2cSNitesh Lal 	}, {
2540a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha224),cbc(des3_ede))",
25415208ed2cSNitesh Lal 		.test = alg_test_aead,
2542ed1afac9SMarcus Meissner 		.fips_allowed = 1,
25435208ed2cSNitesh Lal 		.suite = {
25445208ed2cSNitesh Lal 			.aead = {
254521c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha224_des3_ede_cbc_enc_tv_temp)
2546bca4feb0SHoria Geanta 			}
2547bca4feb0SHoria Geanta 		}
2548bca4feb0SHoria Geanta 	}, {
2549a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha256),cbc(aes))",
2550e46e9a46SHoria Geanta 		.test = alg_test_aead,
2551ed1afac9SMarcus Meissner 		.fips_allowed = 1,
2552e46e9a46SHoria Geanta 		.suite = {
2553e46e9a46SHoria Geanta 			.aead = {
255421c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha256_aes_cbc_enc_tv_temp)
25555208ed2cSNitesh Lal 			}
25565208ed2cSNitesh Lal 		}
25575208ed2cSNitesh Lal 	}, {
2558a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha256),cbc(des))",
25595208ed2cSNitesh Lal 		.test = alg_test_aead,
25605208ed2cSNitesh Lal 		.suite = {
25615208ed2cSNitesh Lal 			.aead = {
256221c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha256_des_cbc_enc_tv_temp)
25635208ed2cSNitesh Lal 			}
25645208ed2cSNitesh Lal 		}
25655208ed2cSNitesh Lal 	}, {
2566a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha256),cbc(des3_ede))",
25675208ed2cSNitesh Lal 		.test = alg_test_aead,
2568ed1afac9SMarcus Meissner 		.fips_allowed = 1,
25695208ed2cSNitesh Lal 		.suite = {
25705208ed2cSNitesh Lal 			.aead = {
257121c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha256_des3_ede_cbc_enc_tv_temp)
25725208ed2cSNitesh Lal 			}
25735208ed2cSNitesh Lal 		}
25745208ed2cSNitesh Lal 	}, {
2575fb16abc2SMarcus Meissner 		.alg = "authenc(hmac(sha256),ctr(aes))",
2576fb16abc2SMarcus Meissner 		.test = alg_test_null,
2577fb16abc2SMarcus Meissner 		.fips_allowed = 1,
2578fb16abc2SMarcus Meissner 	}, {
25798888690eSMarcus Meissner 		.alg = "authenc(hmac(sha256),rfc3686(ctr(aes)))",
25808888690eSMarcus Meissner 		.test = alg_test_null,
25818888690eSMarcus Meissner 		.fips_allowed = 1,
25828888690eSMarcus Meissner 	}, {
2583a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha384),cbc(des))",
25845208ed2cSNitesh Lal 		.test = alg_test_aead,
25855208ed2cSNitesh Lal 		.suite = {
25865208ed2cSNitesh Lal 			.aead = {
258721c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha384_des_cbc_enc_tv_temp)
25885208ed2cSNitesh Lal 			}
25895208ed2cSNitesh Lal 		}
25905208ed2cSNitesh Lal 	}, {
2591a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha384),cbc(des3_ede))",
25925208ed2cSNitesh Lal 		.test = alg_test_aead,
2593ed1afac9SMarcus Meissner 		.fips_allowed = 1,
25945208ed2cSNitesh Lal 		.suite = {
25955208ed2cSNitesh Lal 			.aead = {
259621c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha384_des3_ede_cbc_enc_tv_temp)
2597e46e9a46SHoria Geanta 			}
2598e46e9a46SHoria Geanta 		}
2599e46e9a46SHoria Geanta 	}, {
2600fb16abc2SMarcus Meissner 		.alg = "authenc(hmac(sha384),ctr(aes))",
2601fb16abc2SMarcus Meissner 		.test = alg_test_null,
2602fb16abc2SMarcus Meissner 		.fips_allowed = 1,
2603fb16abc2SMarcus Meissner 	}, {
26048888690eSMarcus Meissner 		.alg = "authenc(hmac(sha384),rfc3686(ctr(aes)))",
26058888690eSMarcus Meissner 		.test = alg_test_null,
26068888690eSMarcus Meissner 		.fips_allowed = 1,
26078888690eSMarcus Meissner 	}, {
2608a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha512),cbc(aes))",
2609ed1afac9SMarcus Meissner 		.fips_allowed = 1,
2610e46e9a46SHoria Geanta 		.test = alg_test_aead,
2611e46e9a46SHoria Geanta 		.suite = {
2612e46e9a46SHoria Geanta 			.aead = {
261321c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha512_aes_cbc_enc_tv_temp)
26145208ed2cSNitesh Lal 			}
26155208ed2cSNitesh Lal 		}
26165208ed2cSNitesh Lal 	}, {
2617a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha512),cbc(des))",
26185208ed2cSNitesh Lal 		.test = alg_test_aead,
26195208ed2cSNitesh Lal 		.suite = {
26205208ed2cSNitesh Lal 			.aead = {
262121c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha512_des_cbc_enc_tv_temp)
26225208ed2cSNitesh Lal 			}
26235208ed2cSNitesh Lal 		}
26245208ed2cSNitesh Lal 	}, {
2625a4198fd4SHerbert Xu 		.alg = "authenc(hmac(sha512),cbc(des3_ede))",
26265208ed2cSNitesh Lal 		.test = alg_test_aead,
2627ed1afac9SMarcus Meissner 		.fips_allowed = 1,
26285208ed2cSNitesh Lal 		.suite = {
26295208ed2cSNitesh Lal 			.aead = {
263021c8e720SArd Biesheuvel 				.enc = __VECS(hmac_sha512_des3_ede_cbc_enc_tv_temp)
2631e46e9a46SHoria Geanta 			}
2632e46e9a46SHoria Geanta 		}
2633e46e9a46SHoria Geanta 	}, {
2634fb16abc2SMarcus Meissner 		.alg = "authenc(hmac(sha512),ctr(aes))",
2635fb16abc2SMarcus Meissner 		.test = alg_test_null,
2636fb16abc2SMarcus Meissner 		.fips_allowed = 1,
2637fb16abc2SMarcus Meissner 	}, {
26388888690eSMarcus Meissner 		.alg = "authenc(hmac(sha512),rfc3686(ctr(aes)))",
26398888690eSMarcus Meissner 		.test = alg_test_null,
26408888690eSMarcus Meissner 		.fips_allowed = 1,
26418888690eSMarcus Meissner 	}, {
2642da7f033dSHerbert Xu 		.alg = "cbc(aes)",
26431aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2644a1915d51SJarod Wilson 		.fips_allowed = 1,
2645da7f033dSHerbert Xu 		.suite = {
264692a4c9feSEric Biggers 			.cipher = __VECS(aes_cbc_tv_template)
264792a4c9feSEric Biggers 		},
2648da7f033dSHerbert Xu 	}, {
2649da7f033dSHerbert Xu 		.alg = "cbc(anubis)",
26501aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2651da7f033dSHerbert Xu 		.suite = {
265292a4c9feSEric Biggers 			.cipher = __VECS(anubis_cbc_tv_template)
265392a4c9feSEric Biggers 		},
2654da7f033dSHerbert Xu 	}, {
2655da7f033dSHerbert Xu 		.alg = "cbc(blowfish)",
26561aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2657da7f033dSHerbert Xu 		.suite = {
265892a4c9feSEric Biggers 			.cipher = __VECS(bf_cbc_tv_template)
265992a4c9feSEric Biggers 		},
2660da7f033dSHerbert Xu 	}, {
2661da7f033dSHerbert Xu 		.alg = "cbc(camellia)",
26621aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2663da7f033dSHerbert Xu 		.suite = {
266492a4c9feSEric Biggers 			.cipher = __VECS(camellia_cbc_tv_template)
266592a4c9feSEric Biggers 		},
2666da7f033dSHerbert Xu 	}, {
2667a2c58260SJohannes Goetzfried 		.alg = "cbc(cast5)",
2668a2c58260SJohannes Goetzfried 		.test = alg_test_skcipher,
2669a2c58260SJohannes Goetzfried 		.suite = {
267092a4c9feSEric Biggers 			.cipher = __VECS(cast5_cbc_tv_template)
267192a4c9feSEric Biggers 		},
2672a2c58260SJohannes Goetzfried 	}, {
26739b8b0405SJohannes Goetzfried 		.alg = "cbc(cast6)",
26749b8b0405SJohannes Goetzfried 		.test = alg_test_skcipher,
26759b8b0405SJohannes Goetzfried 		.suite = {
267692a4c9feSEric Biggers 			.cipher = __VECS(cast6_cbc_tv_template)
267792a4c9feSEric Biggers 		},
26789b8b0405SJohannes Goetzfried 	}, {
2679da7f033dSHerbert Xu 		.alg = "cbc(des)",
26801aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2681da7f033dSHerbert Xu 		.suite = {
268292a4c9feSEric Biggers 			.cipher = __VECS(des_cbc_tv_template)
268392a4c9feSEric Biggers 		},
2684da7f033dSHerbert Xu 	}, {
2685da7f033dSHerbert Xu 		.alg = "cbc(des3_ede)",
26861aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2687a1915d51SJarod Wilson 		.fips_allowed = 1,
2688da7f033dSHerbert Xu 		.suite = {
268992a4c9feSEric Biggers 			.cipher = __VECS(des3_ede_cbc_tv_template)
269092a4c9feSEric Biggers 		},
2691da7f033dSHerbert Xu 	}, {
2692a794d8d8SGilad Ben-Yossef 		/* Same as cbc(aes) except the key is stored in
2693a794d8d8SGilad Ben-Yossef 		 * hardware secure memory which we reference by index
2694a794d8d8SGilad Ben-Yossef 		 */
2695a794d8d8SGilad Ben-Yossef 		.alg = "cbc(paes)",
2696a794d8d8SGilad Ben-Yossef 		.test = alg_test_null,
2697a794d8d8SGilad Ben-Yossef 		.fips_allowed = 1,
2698a794d8d8SGilad Ben-Yossef 	}, {
26999d25917dSJussi Kivilinna 		.alg = "cbc(serpent)",
27009d25917dSJussi Kivilinna 		.test = alg_test_skcipher,
27019d25917dSJussi Kivilinna 		.suite = {
270292a4c9feSEric Biggers 			.cipher = __VECS(serpent_cbc_tv_template)
270392a4c9feSEric Biggers 		},
27049d25917dSJussi Kivilinna 	}, {
270595ba5973SGilad Ben-Yossef 		.alg = "cbc(sm4)",
270695ba5973SGilad Ben-Yossef 		.test = alg_test_skcipher,
270795ba5973SGilad Ben-Yossef 		.suite = {
270895ba5973SGilad Ben-Yossef 			.cipher = __VECS(sm4_cbc_tv_template)
270995ba5973SGilad Ben-Yossef 		}
271095ba5973SGilad Ben-Yossef 	}, {
2711da7f033dSHerbert Xu 		.alg = "cbc(twofish)",
27121aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2713da7f033dSHerbert Xu 		.suite = {
271492a4c9feSEric Biggers 			.cipher = __VECS(tf_cbc_tv_template)
271592a4c9feSEric Biggers 		},
2716da7f033dSHerbert Xu 	}, {
2717092acf06SArd Biesheuvel 		.alg = "cbcmac(aes)",
2718092acf06SArd Biesheuvel 		.fips_allowed = 1,
2719092acf06SArd Biesheuvel 		.test = alg_test_hash,
2720092acf06SArd Biesheuvel 		.suite = {
2721092acf06SArd Biesheuvel 			.hash = __VECS(aes_cbcmac_tv_template)
2722092acf06SArd Biesheuvel 		}
2723092acf06SArd Biesheuvel 	}, {
2724da7f033dSHerbert Xu 		.alg = "ccm(aes)",
2725da7f033dSHerbert Xu 		.test = alg_test_aead,
2726a1915d51SJarod Wilson 		.fips_allowed = 1,
2727da7f033dSHerbert Xu 		.suite = {
2728da7f033dSHerbert Xu 			.aead = {
272921c8e720SArd Biesheuvel 				.enc = __VECS(aes_ccm_enc_tv_template),
273021c8e720SArd Biesheuvel 				.dec = __VECS(aes_ccm_dec_tv_template)
2731da7f033dSHerbert Xu 			}
2732da7f033dSHerbert Xu 		}
2733da7f033dSHerbert Xu 	}, {
27347da66670SDmitry Eremin-Solenikov 		.alg = "cfb(aes)",
27357da66670SDmitry Eremin-Solenikov 		.test = alg_test_skcipher,
27367da66670SDmitry Eremin-Solenikov 		.fips_allowed = 1,
27377da66670SDmitry Eremin-Solenikov 		.suite = {
27387da66670SDmitry Eremin-Solenikov 			.cipher = __VECS(aes_cfb_tv_template)
27397da66670SDmitry Eremin-Solenikov 		},
27407da66670SDmitry Eremin-Solenikov 	}, {
27413590ebf2SMartin Willi 		.alg = "chacha20",
27423590ebf2SMartin Willi 		.test = alg_test_skcipher,
27433590ebf2SMartin Willi 		.suite = {
274492a4c9feSEric Biggers 			.cipher = __VECS(chacha20_tv_template)
274592a4c9feSEric Biggers 		},
27463590ebf2SMartin Willi 	}, {
274793b5e86aSJussi Kivilinna 		.alg = "cmac(aes)",
27488f183751SStephan Mueller 		.fips_allowed = 1,
274993b5e86aSJussi Kivilinna 		.test = alg_test_hash,
275093b5e86aSJussi Kivilinna 		.suite = {
275121c8e720SArd Biesheuvel 			.hash = __VECS(aes_cmac128_tv_template)
275293b5e86aSJussi Kivilinna 		}
275393b5e86aSJussi Kivilinna 	}, {
275493b5e86aSJussi Kivilinna 		.alg = "cmac(des3_ede)",
27558f183751SStephan Mueller 		.fips_allowed = 1,
275693b5e86aSJussi Kivilinna 		.test = alg_test_hash,
275793b5e86aSJussi Kivilinna 		.suite = {
275821c8e720SArd Biesheuvel 			.hash = __VECS(des3_ede_cmac64_tv_template)
275993b5e86aSJussi Kivilinna 		}
276093b5e86aSJussi Kivilinna 	}, {
2761e448370dSJussi Kivilinna 		.alg = "compress_null",
2762e448370dSJussi Kivilinna 		.test = alg_test_null,
2763e448370dSJussi Kivilinna 	}, {
2764ebb3472fSArd Biesheuvel 		.alg = "crc32",
2765ebb3472fSArd Biesheuvel 		.test = alg_test_hash,
2766ebb3472fSArd Biesheuvel 		.suite = {
276721c8e720SArd Biesheuvel 			.hash = __VECS(crc32_tv_template)
2768ebb3472fSArd Biesheuvel 		}
2769ebb3472fSArd Biesheuvel 	}, {
2770da7f033dSHerbert Xu 		.alg = "crc32c",
27718e3ee85eSHerbert Xu 		.test = alg_test_crc32c,
2772a1915d51SJarod Wilson 		.fips_allowed = 1,
2773da7f033dSHerbert Xu 		.suite = {
277421c8e720SArd Biesheuvel 			.hash = __VECS(crc32c_tv_template)
2775da7f033dSHerbert Xu 		}
2776da7f033dSHerbert Xu 	}, {
277768411521SHerbert Xu 		.alg = "crct10dif",
277868411521SHerbert Xu 		.test = alg_test_hash,
277968411521SHerbert Xu 		.fips_allowed = 1,
278068411521SHerbert Xu 		.suite = {
278121c8e720SArd Biesheuvel 			.hash = __VECS(crct10dif_tv_template)
278268411521SHerbert Xu 		}
278368411521SHerbert Xu 	}, {
2784f7cb80f2SJarod Wilson 		.alg = "ctr(aes)",
2785f7cb80f2SJarod Wilson 		.test = alg_test_skcipher,
2786a1915d51SJarod Wilson 		.fips_allowed = 1,
2787f7cb80f2SJarod Wilson 		.suite = {
278892a4c9feSEric Biggers 			.cipher = __VECS(aes_ctr_tv_template)
2789f7cb80f2SJarod Wilson 		}
2790f7cb80f2SJarod Wilson 	}, {
279185b63e34SJussi Kivilinna 		.alg = "ctr(blowfish)",
279285b63e34SJussi Kivilinna 		.test = alg_test_skcipher,
279385b63e34SJussi Kivilinna 		.suite = {
279492a4c9feSEric Biggers 			.cipher = __VECS(bf_ctr_tv_template)
279585b63e34SJussi Kivilinna 		}
279685b63e34SJussi Kivilinna 	}, {
27970840605eSJussi Kivilinna 		.alg = "ctr(camellia)",
27980840605eSJussi Kivilinna 		.test = alg_test_skcipher,
27990840605eSJussi Kivilinna 		.suite = {
280092a4c9feSEric Biggers 			.cipher = __VECS(camellia_ctr_tv_template)
28010840605eSJussi Kivilinna 		}
28020840605eSJussi Kivilinna 	}, {
2803a2c58260SJohannes Goetzfried 		.alg = "ctr(cast5)",
2804a2c58260SJohannes Goetzfried 		.test = alg_test_skcipher,
2805a2c58260SJohannes Goetzfried 		.suite = {
280692a4c9feSEric Biggers 			.cipher = __VECS(cast5_ctr_tv_template)
2807a2c58260SJohannes Goetzfried 		}
2808a2c58260SJohannes Goetzfried 	}, {
28099b8b0405SJohannes Goetzfried 		.alg = "ctr(cast6)",
28109b8b0405SJohannes Goetzfried 		.test = alg_test_skcipher,
28119b8b0405SJohannes Goetzfried 		.suite = {
281292a4c9feSEric Biggers 			.cipher = __VECS(cast6_ctr_tv_template)
28139b8b0405SJohannes Goetzfried 		}
28149b8b0405SJohannes Goetzfried 	}, {
28158163fc30SJussi Kivilinna 		.alg = "ctr(des)",
28168163fc30SJussi Kivilinna 		.test = alg_test_skcipher,
28178163fc30SJussi Kivilinna 		.suite = {
281892a4c9feSEric Biggers 			.cipher = __VECS(des_ctr_tv_template)
28198163fc30SJussi Kivilinna 		}
28208163fc30SJussi Kivilinna 	}, {
2821e080b17aSJussi Kivilinna 		.alg = "ctr(des3_ede)",
2822e080b17aSJussi Kivilinna 		.test = alg_test_skcipher,
28230d8da104SMarcelo Cerri 		.fips_allowed = 1,
2824e080b17aSJussi Kivilinna 		.suite = {
282592a4c9feSEric Biggers 			.cipher = __VECS(des3_ede_ctr_tv_template)
2826e080b17aSJussi Kivilinna 		}
2827e080b17aSJussi Kivilinna 	}, {
2828a794d8d8SGilad Ben-Yossef 		/* Same as ctr(aes) except the key is stored in
2829a794d8d8SGilad Ben-Yossef 		 * hardware secure memory which we reference by index
2830a794d8d8SGilad Ben-Yossef 		 */
2831a794d8d8SGilad Ben-Yossef 		.alg = "ctr(paes)",
2832a794d8d8SGilad Ben-Yossef 		.test = alg_test_null,
2833a794d8d8SGilad Ben-Yossef 		.fips_allowed = 1,
2834a794d8d8SGilad Ben-Yossef 	}, {
28359d25917dSJussi Kivilinna 		.alg = "ctr(serpent)",
28369d25917dSJussi Kivilinna 		.test = alg_test_skcipher,
28379d25917dSJussi Kivilinna 		.suite = {
283892a4c9feSEric Biggers 			.cipher = __VECS(serpent_ctr_tv_template)
28399d25917dSJussi Kivilinna 		}
28409d25917dSJussi Kivilinna 	}, {
284195ba5973SGilad Ben-Yossef 		.alg = "ctr(sm4)",
284295ba5973SGilad Ben-Yossef 		.test = alg_test_skcipher,
284395ba5973SGilad Ben-Yossef 		.suite = {
284495ba5973SGilad Ben-Yossef 			.cipher = __VECS(sm4_ctr_tv_template)
284595ba5973SGilad Ben-Yossef 		}
284695ba5973SGilad Ben-Yossef 	}, {
2847573da620SJussi Kivilinna 		.alg = "ctr(twofish)",
2848573da620SJussi Kivilinna 		.test = alg_test_skcipher,
2849573da620SJussi Kivilinna 		.suite = {
285092a4c9feSEric Biggers 			.cipher = __VECS(tf_ctr_tv_template)
2851573da620SJussi Kivilinna 		}
2852573da620SJussi Kivilinna 	}, {
2853da7f033dSHerbert Xu 		.alg = "cts(cbc(aes))",
28541aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2855196ad604SGilad Ben-Yossef 		.fips_allowed = 1,
2856da7f033dSHerbert Xu 		.suite = {
285792a4c9feSEric Biggers 			.cipher = __VECS(cts_mode_tv_template)
2858da7f033dSHerbert Xu 		}
2859da7f033dSHerbert Xu 	}, {
2860da7f033dSHerbert Xu 		.alg = "deflate",
2861da7f033dSHerbert Xu 		.test = alg_test_comp,
28620818904dSMilan Broz 		.fips_allowed = 1,
2863da7f033dSHerbert Xu 		.suite = {
2864da7f033dSHerbert Xu 			.comp = {
286521c8e720SArd Biesheuvel 				.comp = __VECS(deflate_comp_tv_template),
286621c8e720SArd Biesheuvel 				.decomp = __VECS(deflate_decomp_tv_template)
2867da7f033dSHerbert Xu 			}
2868da7f033dSHerbert Xu 		}
2869da7f033dSHerbert Xu 	}, {
2870802c7f1cSSalvatore Benedetto 		.alg = "dh",
2871802c7f1cSSalvatore Benedetto 		.test = alg_test_kpp,
2872802c7f1cSSalvatore Benedetto 		.fips_allowed = 1,
2873802c7f1cSSalvatore Benedetto 		.suite = {
287421c8e720SArd Biesheuvel 			.kpp = __VECS(dh_tv_template)
2875802c7f1cSSalvatore Benedetto 		}
2876802c7f1cSSalvatore Benedetto 	}, {
2877e448370dSJussi Kivilinna 		.alg = "digest_null",
2878e448370dSJussi Kivilinna 		.test = alg_test_null,
2879e448370dSJussi Kivilinna 	}, {
288064d1cdfbSStephan Mueller 		.alg = "drbg_nopr_ctr_aes128",
288164d1cdfbSStephan Mueller 		.test = alg_test_drbg,
288264d1cdfbSStephan Mueller 		.fips_allowed = 1,
288364d1cdfbSStephan Mueller 		.suite = {
288421c8e720SArd Biesheuvel 			.drbg = __VECS(drbg_nopr_ctr_aes128_tv_template)
288564d1cdfbSStephan Mueller 		}
288664d1cdfbSStephan Mueller 	}, {
288764d1cdfbSStephan Mueller 		.alg = "drbg_nopr_ctr_aes192",
288864d1cdfbSStephan Mueller 		.test = alg_test_drbg,
288964d1cdfbSStephan Mueller 		.fips_allowed = 1,
289064d1cdfbSStephan Mueller 		.suite = {
289121c8e720SArd Biesheuvel 			.drbg = __VECS(drbg_nopr_ctr_aes192_tv_template)
289264d1cdfbSStephan Mueller 		}
289364d1cdfbSStephan Mueller 	}, {
289464d1cdfbSStephan Mueller 		.alg = "drbg_nopr_ctr_aes256",
289564d1cdfbSStephan Mueller 		.test = alg_test_drbg,
289664d1cdfbSStephan Mueller 		.fips_allowed = 1,
289764d1cdfbSStephan Mueller 		.suite = {
289821c8e720SArd Biesheuvel 			.drbg = __VECS(drbg_nopr_ctr_aes256_tv_template)
289964d1cdfbSStephan Mueller 		}
290064d1cdfbSStephan Mueller 	}, {
290164d1cdfbSStephan Mueller 		/*
290264d1cdfbSStephan Mueller 		 * There is no need to specifically test the DRBG with every
290364d1cdfbSStephan Mueller 		 * backend cipher -- covered by drbg_nopr_hmac_sha256 test
290464d1cdfbSStephan Mueller 		 */
290564d1cdfbSStephan Mueller 		.alg = "drbg_nopr_hmac_sha1",
290664d1cdfbSStephan Mueller 		.fips_allowed = 1,
290764d1cdfbSStephan Mueller 		.test = alg_test_null,
290864d1cdfbSStephan Mueller 	}, {
290964d1cdfbSStephan Mueller 		.alg = "drbg_nopr_hmac_sha256",
291064d1cdfbSStephan Mueller 		.test = alg_test_drbg,
291164d1cdfbSStephan Mueller 		.fips_allowed = 1,
291264d1cdfbSStephan Mueller 		.suite = {
291321c8e720SArd Biesheuvel 			.drbg = __VECS(drbg_nopr_hmac_sha256_tv_template)
291464d1cdfbSStephan Mueller 		}
291564d1cdfbSStephan Mueller 	}, {
291664d1cdfbSStephan Mueller 		/* covered by drbg_nopr_hmac_sha256 test */
291764d1cdfbSStephan Mueller 		.alg = "drbg_nopr_hmac_sha384",
291864d1cdfbSStephan Mueller 		.fips_allowed = 1,
291964d1cdfbSStephan Mueller 		.test = alg_test_null,
292064d1cdfbSStephan Mueller 	}, {
292164d1cdfbSStephan Mueller 		.alg = "drbg_nopr_hmac_sha512",
292264d1cdfbSStephan Mueller 		.test = alg_test_null,
292364d1cdfbSStephan Mueller 		.fips_allowed = 1,
292464d1cdfbSStephan Mueller 	}, {
292564d1cdfbSStephan Mueller 		.alg = "drbg_nopr_sha1",
292664d1cdfbSStephan Mueller 		.fips_allowed = 1,
292764d1cdfbSStephan Mueller 		.test = alg_test_null,
292864d1cdfbSStephan Mueller 	}, {
292964d1cdfbSStephan Mueller 		.alg = "drbg_nopr_sha256",
293064d1cdfbSStephan Mueller 		.test = alg_test_drbg,
293164d1cdfbSStephan Mueller 		.fips_allowed = 1,
293264d1cdfbSStephan Mueller 		.suite = {
293321c8e720SArd Biesheuvel 			.drbg = __VECS(drbg_nopr_sha256_tv_template)
293464d1cdfbSStephan Mueller 		}
293564d1cdfbSStephan Mueller 	}, {
293664d1cdfbSStephan Mueller 		/* covered by drbg_nopr_sha256 test */
293764d1cdfbSStephan Mueller 		.alg = "drbg_nopr_sha384",
293864d1cdfbSStephan Mueller 		.fips_allowed = 1,
293964d1cdfbSStephan Mueller 		.test = alg_test_null,
294064d1cdfbSStephan Mueller 	}, {
294164d1cdfbSStephan Mueller 		.alg = "drbg_nopr_sha512",
294264d1cdfbSStephan Mueller 		.fips_allowed = 1,
294364d1cdfbSStephan Mueller 		.test = alg_test_null,
294464d1cdfbSStephan Mueller 	}, {
294564d1cdfbSStephan Mueller 		.alg = "drbg_pr_ctr_aes128",
294664d1cdfbSStephan Mueller 		.test = alg_test_drbg,
294764d1cdfbSStephan Mueller 		.fips_allowed = 1,
294864d1cdfbSStephan Mueller 		.suite = {
294921c8e720SArd Biesheuvel 			.drbg = __VECS(drbg_pr_ctr_aes128_tv_template)
295064d1cdfbSStephan Mueller 		}
295164d1cdfbSStephan Mueller 	}, {
295264d1cdfbSStephan Mueller 		/* covered by drbg_pr_ctr_aes128 test */
295364d1cdfbSStephan Mueller 		.alg = "drbg_pr_ctr_aes192",
295464d1cdfbSStephan Mueller 		.fips_allowed = 1,
295564d1cdfbSStephan Mueller 		.test = alg_test_null,
295664d1cdfbSStephan Mueller 	}, {
295764d1cdfbSStephan Mueller 		.alg = "drbg_pr_ctr_aes256",
295864d1cdfbSStephan Mueller 		.fips_allowed = 1,
295964d1cdfbSStephan Mueller 		.test = alg_test_null,
296064d1cdfbSStephan Mueller 	}, {
296164d1cdfbSStephan Mueller 		.alg = "drbg_pr_hmac_sha1",
296264d1cdfbSStephan Mueller 		.fips_allowed = 1,
296364d1cdfbSStephan Mueller 		.test = alg_test_null,
296464d1cdfbSStephan Mueller 	}, {
296564d1cdfbSStephan Mueller 		.alg = "drbg_pr_hmac_sha256",
296664d1cdfbSStephan Mueller 		.test = alg_test_drbg,
296764d1cdfbSStephan Mueller 		.fips_allowed = 1,
296864d1cdfbSStephan Mueller 		.suite = {
296921c8e720SArd Biesheuvel 			.drbg = __VECS(drbg_pr_hmac_sha256_tv_template)
297064d1cdfbSStephan Mueller 		}
297164d1cdfbSStephan Mueller 	}, {
297264d1cdfbSStephan Mueller 		/* covered by drbg_pr_hmac_sha256 test */
297364d1cdfbSStephan Mueller 		.alg = "drbg_pr_hmac_sha384",
297464d1cdfbSStephan Mueller 		.fips_allowed = 1,
297564d1cdfbSStephan Mueller 		.test = alg_test_null,
297664d1cdfbSStephan Mueller 	}, {
297764d1cdfbSStephan Mueller 		.alg = "drbg_pr_hmac_sha512",
297864d1cdfbSStephan Mueller 		.test = alg_test_null,
297964d1cdfbSStephan Mueller 		.fips_allowed = 1,
298064d1cdfbSStephan Mueller 	}, {
298164d1cdfbSStephan Mueller 		.alg = "drbg_pr_sha1",
298264d1cdfbSStephan Mueller 		.fips_allowed = 1,
298364d1cdfbSStephan Mueller 		.test = alg_test_null,
298464d1cdfbSStephan Mueller 	}, {
298564d1cdfbSStephan Mueller 		.alg = "drbg_pr_sha256",
298664d1cdfbSStephan Mueller 		.test = alg_test_drbg,
298764d1cdfbSStephan Mueller 		.fips_allowed = 1,
298864d1cdfbSStephan Mueller 		.suite = {
298921c8e720SArd Biesheuvel 			.drbg = __VECS(drbg_pr_sha256_tv_template)
299064d1cdfbSStephan Mueller 		}
299164d1cdfbSStephan Mueller 	}, {
299264d1cdfbSStephan Mueller 		/* covered by drbg_pr_sha256 test */
299364d1cdfbSStephan Mueller 		.alg = "drbg_pr_sha384",
299464d1cdfbSStephan Mueller 		.fips_allowed = 1,
299564d1cdfbSStephan Mueller 		.test = alg_test_null,
299664d1cdfbSStephan Mueller 	}, {
299764d1cdfbSStephan Mueller 		.alg = "drbg_pr_sha512",
299864d1cdfbSStephan Mueller 		.fips_allowed = 1,
299964d1cdfbSStephan Mueller 		.test = alg_test_null,
300064d1cdfbSStephan Mueller 	}, {
3001da7f033dSHerbert Xu 		.alg = "ecb(aes)",
30021aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3003a1915d51SJarod Wilson 		.fips_allowed = 1,
3004da7f033dSHerbert Xu 		.suite = {
300592a4c9feSEric Biggers 			.cipher = __VECS(aes_tv_template)
3006da7f033dSHerbert Xu 		}
3007da7f033dSHerbert Xu 	}, {
3008da7f033dSHerbert Xu 		.alg = "ecb(anubis)",
30091aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3010da7f033dSHerbert Xu 		.suite = {
301192a4c9feSEric Biggers 			.cipher = __VECS(anubis_tv_template)
3012da7f033dSHerbert Xu 		}
3013da7f033dSHerbert Xu 	}, {
3014da7f033dSHerbert Xu 		.alg = "ecb(arc4)",
30151aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3016da7f033dSHerbert Xu 		.suite = {
301792a4c9feSEric Biggers 			.cipher = __VECS(arc4_tv_template)
3018da7f033dSHerbert Xu 		}
3019da7f033dSHerbert Xu 	}, {
3020da7f033dSHerbert Xu 		.alg = "ecb(blowfish)",
30211aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3022da7f033dSHerbert Xu 		.suite = {
302392a4c9feSEric Biggers 			.cipher = __VECS(bf_tv_template)
3024da7f033dSHerbert Xu 		}
3025da7f033dSHerbert Xu 	}, {
3026da7f033dSHerbert Xu 		.alg = "ecb(camellia)",
30271aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3028da7f033dSHerbert Xu 		.suite = {
302992a4c9feSEric Biggers 			.cipher = __VECS(camellia_tv_template)
3030da7f033dSHerbert Xu 		}
3031da7f033dSHerbert Xu 	}, {
3032da7f033dSHerbert Xu 		.alg = "ecb(cast5)",
30331aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3034da7f033dSHerbert Xu 		.suite = {
303592a4c9feSEric Biggers 			.cipher = __VECS(cast5_tv_template)
3036da7f033dSHerbert Xu 		}
3037da7f033dSHerbert Xu 	}, {
3038da7f033dSHerbert Xu 		.alg = "ecb(cast6)",
30391aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3040da7f033dSHerbert Xu 		.suite = {
304192a4c9feSEric Biggers 			.cipher = __VECS(cast6_tv_template)
3042da7f033dSHerbert Xu 		}
3043da7f033dSHerbert Xu 	}, {
3044e448370dSJussi Kivilinna 		.alg = "ecb(cipher_null)",
3045e448370dSJussi Kivilinna 		.test = alg_test_null,
30466175ca2bSMilan Broz 		.fips_allowed = 1,
3047e448370dSJussi Kivilinna 	}, {
3048da7f033dSHerbert Xu 		.alg = "ecb(des)",
30491aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3050da7f033dSHerbert Xu 		.suite = {
305192a4c9feSEric Biggers 			.cipher = __VECS(des_tv_template)
3052da7f033dSHerbert Xu 		}
3053da7f033dSHerbert Xu 	}, {
3054da7f033dSHerbert Xu 		.alg = "ecb(des3_ede)",
30551aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3056a1915d51SJarod Wilson 		.fips_allowed = 1,
3057da7f033dSHerbert Xu 		.suite = {
305892a4c9feSEric Biggers 			.cipher = __VECS(des3_ede_tv_template)
3059da7f033dSHerbert Xu 		}
3060da7f033dSHerbert Xu 	}, {
306166e5bd00SJussi Kivilinna 		.alg = "ecb(fcrypt)",
306266e5bd00SJussi Kivilinna 		.test = alg_test_skcipher,
306366e5bd00SJussi Kivilinna 		.suite = {
306466e5bd00SJussi Kivilinna 			.cipher = {
306592a4c9feSEric Biggers 				.vecs = fcrypt_pcbc_tv_template,
306666e5bd00SJussi Kivilinna 				.count = 1
306766e5bd00SJussi Kivilinna 			}
306866e5bd00SJussi Kivilinna 		}
306966e5bd00SJussi Kivilinna 	}, {
3070da7f033dSHerbert Xu 		.alg = "ecb(khazad)",
30711aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3072da7f033dSHerbert Xu 		.suite = {
307392a4c9feSEric Biggers 			.cipher = __VECS(khazad_tv_template)
3074da7f033dSHerbert Xu 		}
3075da7f033dSHerbert Xu 	}, {
307615f47ce5SGilad Ben-Yossef 		/* Same as ecb(aes) except the key is stored in
307715f47ce5SGilad Ben-Yossef 		 * hardware secure memory which we reference by index
307815f47ce5SGilad Ben-Yossef 		 */
307915f47ce5SGilad Ben-Yossef 		.alg = "ecb(paes)",
308015f47ce5SGilad Ben-Yossef 		.test = alg_test_null,
308115f47ce5SGilad Ben-Yossef 		.fips_allowed = 1,
308215f47ce5SGilad Ben-Yossef 	}, {
3083da7f033dSHerbert Xu 		.alg = "ecb(seed)",
30841aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3085da7f033dSHerbert Xu 		.suite = {
308692a4c9feSEric Biggers 			.cipher = __VECS(seed_tv_template)
3087da7f033dSHerbert Xu 		}
3088da7f033dSHerbert Xu 	}, {
3089da7f033dSHerbert Xu 		.alg = "ecb(serpent)",
30901aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3091da7f033dSHerbert Xu 		.suite = {
309292a4c9feSEric Biggers 			.cipher = __VECS(serpent_tv_template)
3093da7f033dSHerbert Xu 		}
3094da7f033dSHerbert Xu 	}, {
3095cd83a8a7SGilad Ben-Yossef 		.alg = "ecb(sm4)",
3096cd83a8a7SGilad Ben-Yossef 		.test = alg_test_skcipher,
3097cd83a8a7SGilad Ben-Yossef 		.suite = {
309892a4c9feSEric Biggers 			.cipher = __VECS(sm4_tv_template)
3099cd83a8a7SGilad Ben-Yossef 		}
3100cd83a8a7SGilad Ben-Yossef 	}, {
3101da7f033dSHerbert Xu 		.alg = "ecb(tea)",
31021aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3103da7f033dSHerbert Xu 		.suite = {
310492a4c9feSEric Biggers 			.cipher = __VECS(tea_tv_template)
3105da7f033dSHerbert Xu 		}
3106da7f033dSHerbert Xu 	}, {
3107da7f033dSHerbert Xu 		.alg = "ecb(tnepres)",
31081aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3109da7f033dSHerbert Xu 		.suite = {
311092a4c9feSEric Biggers 			.cipher = __VECS(tnepres_tv_template)
3111da7f033dSHerbert Xu 		}
3112da7f033dSHerbert Xu 	}, {
3113da7f033dSHerbert Xu 		.alg = "ecb(twofish)",
31141aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3115da7f033dSHerbert Xu 		.suite = {
311692a4c9feSEric Biggers 			.cipher = __VECS(tf_tv_template)
3117da7f033dSHerbert Xu 		}
3118da7f033dSHerbert Xu 	}, {
3119da7f033dSHerbert Xu 		.alg = "ecb(xeta)",
31201aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3121da7f033dSHerbert Xu 		.suite = {
312292a4c9feSEric Biggers 			.cipher = __VECS(xeta_tv_template)
3123da7f033dSHerbert Xu 		}
3124da7f033dSHerbert Xu 	}, {
3125da7f033dSHerbert Xu 		.alg = "ecb(xtea)",
31261aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3127da7f033dSHerbert Xu 		.suite = {
312892a4c9feSEric Biggers 			.cipher = __VECS(xtea_tv_template)
3129da7f033dSHerbert Xu 		}
3130da7f033dSHerbert Xu 	}, {
31313c4b2390SSalvatore Benedetto 		.alg = "ecdh",
31323c4b2390SSalvatore Benedetto 		.test = alg_test_kpp,
31333c4b2390SSalvatore Benedetto 		.fips_allowed = 1,
31343c4b2390SSalvatore Benedetto 		.suite = {
313521c8e720SArd Biesheuvel 			.kpp = __VECS(ecdh_tv_template)
31363c4b2390SSalvatore Benedetto 		}
31373c4b2390SSalvatore Benedetto 	}, {
3138da7f033dSHerbert Xu 		.alg = "gcm(aes)",
3139da7f033dSHerbert Xu 		.test = alg_test_aead,
3140a1915d51SJarod Wilson 		.fips_allowed = 1,
3141da7f033dSHerbert Xu 		.suite = {
3142da7f033dSHerbert Xu 			.aead = {
314321c8e720SArd Biesheuvel 				.enc = __VECS(aes_gcm_enc_tv_template),
314421c8e720SArd Biesheuvel 				.dec = __VECS(aes_gcm_dec_tv_template)
3145da7f033dSHerbert Xu 			}
3146da7f033dSHerbert Xu 		}
3147da7f033dSHerbert Xu 	}, {
3148507069c9SYouquan, Song 		.alg = "ghash",
3149507069c9SYouquan, Song 		.test = alg_test_hash,
315018c0ebd2SJarod Wilson 		.fips_allowed = 1,
3151507069c9SYouquan, Song 		.suite = {
315221c8e720SArd Biesheuvel 			.hash = __VECS(ghash_tv_template)
3153507069c9SYouquan, Song 		}
3154507069c9SYouquan, Song 	}, {
3155da7f033dSHerbert Xu 		.alg = "hmac(md5)",
3156da7f033dSHerbert Xu 		.test = alg_test_hash,
3157da7f033dSHerbert Xu 		.suite = {
315821c8e720SArd Biesheuvel 			.hash = __VECS(hmac_md5_tv_template)
3159da7f033dSHerbert Xu 		}
3160da7f033dSHerbert Xu 	}, {
3161da7f033dSHerbert Xu 		.alg = "hmac(rmd128)",
3162da7f033dSHerbert Xu 		.test = alg_test_hash,
3163da7f033dSHerbert Xu 		.suite = {
316421c8e720SArd Biesheuvel 			.hash = __VECS(hmac_rmd128_tv_template)
3165da7f033dSHerbert Xu 		}
3166da7f033dSHerbert Xu 	}, {
3167da7f033dSHerbert Xu 		.alg = "hmac(rmd160)",
3168da7f033dSHerbert Xu 		.test = alg_test_hash,
3169da7f033dSHerbert Xu 		.suite = {
317021c8e720SArd Biesheuvel 			.hash = __VECS(hmac_rmd160_tv_template)
3171da7f033dSHerbert Xu 		}
3172da7f033dSHerbert Xu 	}, {
3173da7f033dSHerbert Xu 		.alg = "hmac(sha1)",
3174da7f033dSHerbert Xu 		.test = alg_test_hash,
3175a1915d51SJarod Wilson 		.fips_allowed = 1,
3176da7f033dSHerbert Xu 		.suite = {
317721c8e720SArd Biesheuvel 			.hash = __VECS(hmac_sha1_tv_template)
3178da7f033dSHerbert Xu 		}
3179da7f033dSHerbert Xu 	}, {
3180da7f033dSHerbert Xu 		.alg = "hmac(sha224)",
3181da7f033dSHerbert Xu 		.test = alg_test_hash,
3182a1915d51SJarod Wilson 		.fips_allowed = 1,
3183da7f033dSHerbert Xu 		.suite = {
318421c8e720SArd Biesheuvel 			.hash = __VECS(hmac_sha224_tv_template)
3185da7f033dSHerbert Xu 		}
3186da7f033dSHerbert Xu 	}, {
3187da7f033dSHerbert Xu 		.alg = "hmac(sha256)",
3188da7f033dSHerbert Xu 		.test = alg_test_hash,
3189a1915d51SJarod Wilson 		.fips_allowed = 1,
3190da7f033dSHerbert Xu 		.suite = {
319121c8e720SArd Biesheuvel 			.hash = __VECS(hmac_sha256_tv_template)
3192da7f033dSHerbert Xu 		}
3193da7f033dSHerbert Xu 	}, {
319498eca72fSraveendra padasalagi 		.alg = "hmac(sha3-224)",
319598eca72fSraveendra padasalagi 		.test = alg_test_hash,
319698eca72fSraveendra padasalagi 		.fips_allowed = 1,
319798eca72fSraveendra padasalagi 		.suite = {
319821c8e720SArd Biesheuvel 			.hash = __VECS(hmac_sha3_224_tv_template)
319998eca72fSraveendra padasalagi 		}
320098eca72fSraveendra padasalagi 	}, {
320198eca72fSraveendra padasalagi 		.alg = "hmac(sha3-256)",
320298eca72fSraveendra padasalagi 		.test = alg_test_hash,
320398eca72fSraveendra padasalagi 		.fips_allowed = 1,
320498eca72fSraveendra padasalagi 		.suite = {
320521c8e720SArd Biesheuvel 			.hash = __VECS(hmac_sha3_256_tv_template)
320698eca72fSraveendra padasalagi 		}
320798eca72fSraveendra padasalagi 	}, {
320898eca72fSraveendra padasalagi 		.alg = "hmac(sha3-384)",
320998eca72fSraveendra padasalagi 		.test = alg_test_hash,
321098eca72fSraveendra padasalagi 		.fips_allowed = 1,
321198eca72fSraveendra padasalagi 		.suite = {
321221c8e720SArd Biesheuvel 			.hash = __VECS(hmac_sha3_384_tv_template)
321398eca72fSraveendra padasalagi 		}
321498eca72fSraveendra padasalagi 	}, {
321598eca72fSraveendra padasalagi 		.alg = "hmac(sha3-512)",
321698eca72fSraveendra padasalagi 		.test = alg_test_hash,
321798eca72fSraveendra padasalagi 		.fips_allowed = 1,
321898eca72fSraveendra padasalagi 		.suite = {
321921c8e720SArd Biesheuvel 			.hash = __VECS(hmac_sha3_512_tv_template)
322098eca72fSraveendra padasalagi 		}
322198eca72fSraveendra padasalagi 	}, {
3222da7f033dSHerbert Xu 		.alg = "hmac(sha384)",
3223da7f033dSHerbert Xu 		.test = alg_test_hash,
3224a1915d51SJarod Wilson 		.fips_allowed = 1,
3225da7f033dSHerbert Xu 		.suite = {
322621c8e720SArd Biesheuvel 			.hash = __VECS(hmac_sha384_tv_template)
3227da7f033dSHerbert Xu 		}
3228da7f033dSHerbert Xu 	}, {
3229da7f033dSHerbert Xu 		.alg = "hmac(sha512)",
3230da7f033dSHerbert Xu 		.test = alg_test_hash,
3231a1915d51SJarod Wilson 		.fips_allowed = 1,
3232da7f033dSHerbert Xu 		.suite = {
323321c8e720SArd Biesheuvel 			.hash = __VECS(hmac_sha512_tv_template)
3234da7f033dSHerbert Xu 		}
3235da7f033dSHerbert Xu 	}, {
323625a0b9d4SVitaly Chikunov 		.alg = "hmac(streebog256)",
323725a0b9d4SVitaly Chikunov 		.test = alg_test_hash,
323825a0b9d4SVitaly Chikunov 		.suite = {
323925a0b9d4SVitaly Chikunov 			.hash = __VECS(hmac_streebog256_tv_template)
324025a0b9d4SVitaly Chikunov 		}
324125a0b9d4SVitaly Chikunov 	}, {
324225a0b9d4SVitaly Chikunov 		.alg = "hmac(streebog512)",
324325a0b9d4SVitaly Chikunov 		.test = alg_test_hash,
324425a0b9d4SVitaly Chikunov 		.suite = {
324525a0b9d4SVitaly Chikunov 			.hash = __VECS(hmac_streebog512_tv_template)
324625a0b9d4SVitaly Chikunov 		}
324725a0b9d4SVitaly Chikunov 	}, {
3248bb5530e4SStephan Mueller 		.alg = "jitterentropy_rng",
3249bb5530e4SStephan Mueller 		.fips_allowed = 1,
3250bb5530e4SStephan Mueller 		.test = alg_test_null,
3251bb5530e4SStephan Mueller 	}, {
325235351988SStephan Mueller 		.alg = "kw(aes)",
325335351988SStephan Mueller 		.test = alg_test_skcipher,
325435351988SStephan Mueller 		.fips_allowed = 1,
325535351988SStephan Mueller 		.suite = {
325692a4c9feSEric Biggers 			.cipher = __VECS(aes_kw_tv_template)
325735351988SStephan Mueller 		}
325835351988SStephan Mueller 	}, {
3259da7f033dSHerbert Xu 		.alg = "lrw(aes)",
32601aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3261da7f033dSHerbert Xu 		.suite = {
326292a4c9feSEric Biggers 			.cipher = __VECS(aes_lrw_tv_template)
3263da7f033dSHerbert Xu 		}
3264da7f033dSHerbert Xu 	}, {
32650840605eSJussi Kivilinna 		.alg = "lrw(camellia)",
32660840605eSJussi Kivilinna 		.test = alg_test_skcipher,
32670840605eSJussi Kivilinna 		.suite = {
326892a4c9feSEric Biggers 			.cipher = __VECS(camellia_lrw_tv_template)
32690840605eSJussi Kivilinna 		}
32700840605eSJussi Kivilinna 	}, {
32719b8b0405SJohannes Goetzfried 		.alg = "lrw(cast6)",
32729b8b0405SJohannes Goetzfried 		.test = alg_test_skcipher,
32739b8b0405SJohannes Goetzfried 		.suite = {
327492a4c9feSEric Biggers 			.cipher = __VECS(cast6_lrw_tv_template)
32759b8b0405SJohannes Goetzfried 		}
32769b8b0405SJohannes Goetzfried 	}, {
3277d7bfc0faSJussi Kivilinna 		.alg = "lrw(serpent)",
3278d7bfc0faSJussi Kivilinna 		.test = alg_test_skcipher,
3279d7bfc0faSJussi Kivilinna 		.suite = {
328092a4c9feSEric Biggers 			.cipher = __VECS(serpent_lrw_tv_template)
3281d7bfc0faSJussi Kivilinna 		}
3282d7bfc0faSJussi Kivilinna 	}, {
32830b2a1551SJussi Kivilinna 		.alg = "lrw(twofish)",
32840b2a1551SJussi Kivilinna 		.test = alg_test_skcipher,
32850b2a1551SJussi Kivilinna 		.suite = {
328692a4c9feSEric Biggers 			.cipher = __VECS(tf_lrw_tv_template)
32870b2a1551SJussi Kivilinna 		}
32880b2a1551SJussi Kivilinna 	}, {
32891443cc9bSKOVACS Krisztian 		.alg = "lz4",
32901443cc9bSKOVACS Krisztian 		.test = alg_test_comp,
32911443cc9bSKOVACS Krisztian 		.fips_allowed = 1,
32921443cc9bSKOVACS Krisztian 		.suite = {
32931443cc9bSKOVACS Krisztian 			.comp = {
329421c8e720SArd Biesheuvel 				.comp = __VECS(lz4_comp_tv_template),
329521c8e720SArd Biesheuvel 				.decomp = __VECS(lz4_decomp_tv_template)
32961443cc9bSKOVACS Krisztian 			}
32971443cc9bSKOVACS Krisztian 		}
32981443cc9bSKOVACS Krisztian 	}, {
32991443cc9bSKOVACS Krisztian 		.alg = "lz4hc",
33001443cc9bSKOVACS Krisztian 		.test = alg_test_comp,
33011443cc9bSKOVACS Krisztian 		.fips_allowed = 1,
33021443cc9bSKOVACS Krisztian 		.suite = {
33031443cc9bSKOVACS Krisztian 			.comp = {
330421c8e720SArd Biesheuvel 				.comp = __VECS(lz4hc_comp_tv_template),
330521c8e720SArd Biesheuvel 				.decomp = __VECS(lz4hc_decomp_tv_template)
33061443cc9bSKOVACS Krisztian 			}
33071443cc9bSKOVACS Krisztian 		}
33081443cc9bSKOVACS Krisztian 	}, {
3309da7f033dSHerbert Xu 		.alg = "lzo",
3310da7f033dSHerbert Xu 		.test = alg_test_comp,
33110818904dSMilan Broz 		.fips_allowed = 1,
3312da7f033dSHerbert Xu 		.suite = {
3313da7f033dSHerbert Xu 			.comp = {
331421c8e720SArd Biesheuvel 				.comp = __VECS(lzo_comp_tv_template),
331521c8e720SArd Biesheuvel 				.decomp = __VECS(lzo_decomp_tv_template)
3316da7f033dSHerbert Xu 			}
3317da7f033dSHerbert Xu 		}
3318da7f033dSHerbert Xu 	}, {
3319da7f033dSHerbert Xu 		.alg = "md4",
3320da7f033dSHerbert Xu 		.test = alg_test_hash,
3321da7f033dSHerbert Xu 		.suite = {
332221c8e720SArd Biesheuvel 			.hash = __VECS(md4_tv_template)
3323da7f033dSHerbert Xu 		}
3324da7f033dSHerbert Xu 	}, {
3325da7f033dSHerbert Xu 		.alg = "md5",
3326da7f033dSHerbert Xu 		.test = alg_test_hash,
3327da7f033dSHerbert Xu 		.suite = {
332821c8e720SArd Biesheuvel 			.hash = __VECS(md5_tv_template)
3329da7f033dSHerbert Xu 		}
3330da7f033dSHerbert Xu 	}, {
3331da7f033dSHerbert Xu 		.alg = "michael_mic",
3332da7f033dSHerbert Xu 		.test = alg_test_hash,
3333da7f033dSHerbert Xu 		.suite = {
333421c8e720SArd Biesheuvel 			.hash = __VECS(michael_mic_tv_template)
3335da7f033dSHerbert Xu 		}
3336da7f033dSHerbert Xu 	}, {
33374feb4c59SOndrej Mosnacek 		.alg = "morus1280",
33384feb4c59SOndrej Mosnacek 		.test = alg_test_aead,
33394feb4c59SOndrej Mosnacek 		.suite = {
33404feb4c59SOndrej Mosnacek 			.aead = {
33414feb4c59SOndrej Mosnacek 				.enc = __VECS(morus1280_enc_tv_template),
33424feb4c59SOndrej Mosnacek 				.dec = __VECS(morus1280_dec_tv_template),
33434feb4c59SOndrej Mosnacek 			}
33444feb4c59SOndrej Mosnacek 		}
33454feb4c59SOndrej Mosnacek 	}, {
33464feb4c59SOndrej Mosnacek 		.alg = "morus640",
33474feb4c59SOndrej Mosnacek 		.test = alg_test_aead,
33484feb4c59SOndrej Mosnacek 		.suite = {
33494feb4c59SOndrej Mosnacek 			.aead = {
33504feb4c59SOndrej Mosnacek 				.enc = __VECS(morus640_enc_tv_template),
33514feb4c59SOndrej Mosnacek 				.dec = __VECS(morus640_dec_tv_template),
33524feb4c59SOndrej Mosnacek 			}
33534feb4c59SOndrej Mosnacek 		}
33544feb4c59SOndrej Mosnacek 	}, {
335526609a21SEric Biggers 		.alg = "nhpoly1305",
335626609a21SEric Biggers 		.test = alg_test_hash,
335726609a21SEric Biggers 		.suite = {
335826609a21SEric Biggers 			.hash = __VECS(nhpoly1305_tv_template)
335926609a21SEric Biggers 		}
336026609a21SEric Biggers 	}, {
3361ba0e14acSPuneet Saxena 		.alg = "ofb(aes)",
3362ba0e14acSPuneet Saxena 		.test = alg_test_skcipher,
3363ba0e14acSPuneet Saxena 		.fips_allowed = 1,
3364ba0e14acSPuneet Saxena 		.suite = {
336592a4c9feSEric Biggers 			.cipher = __VECS(aes_ofb_tv_template)
3366ba0e14acSPuneet Saxena 		}
3367ba0e14acSPuneet Saxena 	}, {
3368a794d8d8SGilad Ben-Yossef 		/* Same as ofb(aes) except the key is stored in
3369a794d8d8SGilad Ben-Yossef 		 * hardware secure memory which we reference by index
3370a794d8d8SGilad Ben-Yossef 		 */
3371a794d8d8SGilad Ben-Yossef 		.alg = "ofb(paes)",
3372a794d8d8SGilad Ben-Yossef 		.test = alg_test_null,
3373a794d8d8SGilad Ben-Yossef 		.fips_allowed = 1,
3374a794d8d8SGilad Ben-Yossef 	}, {
3375da7f033dSHerbert Xu 		.alg = "pcbc(fcrypt)",
33761aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3377da7f033dSHerbert Xu 		.suite = {
337892a4c9feSEric Biggers 			.cipher = __VECS(fcrypt_pcbc_tv_template)
3379da7f033dSHerbert Xu 		}
3380da7f033dSHerbert Xu 	}, {
33811207107cSStephan Mueller 		.alg = "pkcs1pad(rsa,sha224)",
33821207107cSStephan Mueller 		.test = alg_test_null,
33831207107cSStephan Mueller 		.fips_allowed = 1,
33841207107cSStephan Mueller 	}, {
33851207107cSStephan Mueller 		.alg = "pkcs1pad(rsa,sha256)",
33861207107cSStephan Mueller 		.test = alg_test_akcipher,
33871207107cSStephan Mueller 		.fips_allowed = 1,
33881207107cSStephan Mueller 		.suite = {
33891207107cSStephan Mueller 			.akcipher = __VECS(pkcs1pad_rsa_tv_template)
33901207107cSStephan Mueller 		}
33911207107cSStephan Mueller 	}, {
33921207107cSStephan Mueller 		.alg = "pkcs1pad(rsa,sha384)",
33931207107cSStephan Mueller 		.test = alg_test_null,
33941207107cSStephan Mueller 		.fips_allowed = 1,
33951207107cSStephan Mueller 	}, {
33961207107cSStephan Mueller 		.alg = "pkcs1pad(rsa,sha512)",
33971207107cSStephan Mueller 		.test = alg_test_null,
33981207107cSStephan Mueller 		.fips_allowed = 1,
33991207107cSStephan Mueller 	}, {
3400eee9dc61SMartin Willi 		.alg = "poly1305",
3401eee9dc61SMartin Willi 		.test = alg_test_hash,
3402eee9dc61SMartin Willi 		.suite = {
340321c8e720SArd Biesheuvel 			.hash = __VECS(poly1305_tv_template)
3404eee9dc61SMartin Willi 		}
3405eee9dc61SMartin Willi 	}, {
3406da7f033dSHerbert Xu 		.alg = "rfc3686(ctr(aes))",
34071aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3408a1915d51SJarod Wilson 		.fips_allowed = 1,
3409da7f033dSHerbert Xu 		.suite = {
341092a4c9feSEric Biggers 			.cipher = __VECS(aes_ctr_rfc3686_tv_template)
3411da7f033dSHerbert Xu 		}
3412da7f033dSHerbert Xu 	}, {
34133f31a740SHerbert Xu 		.alg = "rfc4106(gcm(aes))",
341469435b94SAdrian Hoban 		.test = alg_test_aead,
3415db71f29aSJarod Wilson 		.fips_allowed = 1,
341669435b94SAdrian Hoban 		.suite = {
341769435b94SAdrian Hoban 			.aead = {
341821c8e720SArd Biesheuvel 				.enc = __VECS(aes_gcm_rfc4106_enc_tv_template),
341921c8e720SArd Biesheuvel 				.dec = __VECS(aes_gcm_rfc4106_dec_tv_template)
342069435b94SAdrian Hoban 			}
342169435b94SAdrian Hoban 		}
342269435b94SAdrian Hoban 	}, {
3423544c436aSHerbert Xu 		.alg = "rfc4309(ccm(aes))",
34245d667322SJarod Wilson 		.test = alg_test_aead,
3425a1915d51SJarod Wilson 		.fips_allowed = 1,
34265d667322SJarod Wilson 		.suite = {
34275d667322SJarod Wilson 			.aead = {
342821c8e720SArd Biesheuvel 				.enc = __VECS(aes_ccm_rfc4309_enc_tv_template),
342921c8e720SArd Biesheuvel 				.dec = __VECS(aes_ccm_rfc4309_dec_tv_template)
34305d667322SJarod Wilson 			}
34315d667322SJarod Wilson 		}
34325d667322SJarod Wilson 	}, {
3433bb68745eSHerbert Xu 		.alg = "rfc4543(gcm(aes))",
3434e9b7441aSJussi Kivilinna 		.test = alg_test_aead,
3435e9b7441aSJussi Kivilinna 		.suite = {
3436e9b7441aSJussi Kivilinna 			.aead = {
343721c8e720SArd Biesheuvel 				.enc = __VECS(aes_gcm_rfc4543_enc_tv_template),
343821c8e720SArd Biesheuvel 				.dec = __VECS(aes_gcm_rfc4543_dec_tv_template),
3439e9b7441aSJussi Kivilinna 			}
3440e9b7441aSJussi Kivilinna 		}
3441e9b7441aSJussi Kivilinna 	}, {
3442af2b76b5SMartin Willi 		.alg = "rfc7539(chacha20,poly1305)",
3443af2b76b5SMartin Willi 		.test = alg_test_aead,
3444af2b76b5SMartin Willi 		.suite = {
3445af2b76b5SMartin Willi 			.aead = {
344621c8e720SArd Biesheuvel 				.enc = __VECS(rfc7539_enc_tv_template),
344721c8e720SArd Biesheuvel 				.dec = __VECS(rfc7539_dec_tv_template),
3448af2b76b5SMartin Willi 			}
3449af2b76b5SMartin Willi 		}
3450af2b76b5SMartin Willi 	}, {
34515900758dSMartin Willi 		.alg = "rfc7539esp(chacha20,poly1305)",
34525900758dSMartin Willi 		.test = alg_test_aead,
34535900758dSMartin Willi 		.suite = {
34545900758dSMartin Willi 			.aead = {
345521c8e720SArd Biesheuvel 				.enc = __VECS(rfc7539esp_enc_tv_template),
345621c8e720SArd Biesheuvel 				.dec = __VECS(rfc7539esp_dec_tv_template),
34575900758dSMartin Willi 			}
34585900758dSMartin Willi 		}
34595900758dSMartin Willi 	}, {
3460da7f033dSHerbert Xu 		.alg = "rmd128",
3461da7f033dSHerbert Xu 		.test = alg_test_hash,
3462da7f033dSHerbert Xu 		.suite = {
346321c8e720SArd Biesheuvel 			.hash = __VECS(rmd128_tv_template)
3464da7f033dSHerbert Xu 		}
3465da7f033dSHerbert Xu 	}, {
3466da7f033dSHerbert Xu 		.alg = "rmd160",
3467da7f033dSHerbert Xu 		.test = alg_test_hash,
3468da7f033dSHerbert Xu 		.suite = {
346921c8e720SArd Biesheuvel 			.hash = __VECS(rmd160_tv_template)
3470da7f033dSHerbert Xu 		}
3471da7f033dSHerbert Xu 	}, {
3472da7f033dSHerbert Xu 		.alg = "rmd256",
3473da7f033dSHerbert Xu 		.test = alg_test_hash,
3474da7f033dSHerbert Xu 		.suite = {
347521c8e720SArd Biesheuvel 			.hash = __VECS(rmd256_tv_template)
3476da7f033dSHerbert Xu 		}
3477da7f033dSHerbert Xu 	}, {
3478da7f033dSHerbert Xu 		.alg = "rmd320",
3479da7f033dSHerbert Xu 		.test = alg_test_hash,
3480da7f033dSHerbert Xu 		.suite = {
348121c8e720SArd Biesheuvel 			.hash = __VECS(rmd320_tv_template)
3482da7f033dSHerbert Xu 		}
3483da7f033dSHerbert Xu 	}, {
3484946cc463STadeusz Struk 		.alg = "rsa",
3485946cc463STadeusz Struk 		.test = alg_test_akcipher,
3486946cc463STadeusz Struk 		.fips_allowed = 1,
3487946cc463STadeusz Struk 		.suite = {
348821c8e720SArd Biesheuvel 			.akcipher = __VECS(rsa_tv_template)
3489946cc463STadeusz Struk 		}
3490946cc463STadeusz Struk 	}, {
3491da7f033dSHerbert Xu 		.alg = "salsa20",
34921aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
3493da7f033dSHerbert Xu 		.suite = {
349492a4c9feSEric Biggers 			.cipher = __VECS(salsa20_stream_tv_template)
3495da7f033dSHerbert Xu 		}
3496da7f033dSHerbert Xu 	}, {
3497da7f033dSHerbert Xu 		.alg = "sha1",
3498da7f033dSHerbert Xu 		.test = alg_test_hash,
3499a1915d51SJarod Wilson 		.fips_allowed = 1,
3500da7f033dSHerbert Xu 		.suite = {
350121c8e720SArd Biesheuvel 			.hash = __VECS(sha1_tv_template)
3502da7f033dSHerbert Xu 		}
3503da7f033dSHerbert Xu 	}, {
3504da7f033dSHerbert Xu 		.alg = "sha224",
3505da7f033dSHerbert Xu 		.test = alg_test_hash,
3506a1915d51SJarod Wilson 		.fips_allowed = 1,
3507da7f033dSHerbert Xu 		.suite = {
350821c8e720SArd Biesheuvel 			.hash = __VECS(sha224_tv_template)
3509da7f033dSHerbert Xu 		}
3510da7f033dSHerbert Xu 	}, {
3511da7f033dSHerbert Xu 		.alg = "sha256",
3512da7f033dSHerbert Xu 		.test = alg_test_hash,
3513a1915d51SJarod Wilson 		.fips_allowed = 1,
3514da7f033dSHerbert Xu 		.suite = {
351521c8e720SArd Biesheuvel 			.hash = __VECS(sha256_tv_template)
3516da7f033dSHerbert Xu 		}
3517da7f033dSHerbert Xu 	}, {
351879cc6ab8Sraveendra padasalagi 		.alg = "sha3-224",
351979cc6ab8Sraveendra padasalagi 		.test = alg_test_hash,
352079cc6ab8Sraveendra padasalagi 		.fips_allowed = 1,
352179cc6ab8Sraveendra padasalagi 		.suite = {
352221c8e720SArd Biesheuvel 			.hash = __VECS(sha3_224_tv_template)
352379cc6ab8Sraveendra padasalagi 		}
352479cc6ab8Sraveendra padasalagi 	}, {
352579cc6ab8Sraveendra padasalagi 		.alg = "sha3-256",
352679cc6ab8Sraveendra padasalagi 		.test = alg_test_hash,
352779cc6ab8Sraveendra padasalagi 		.fips_allowed = 1,
352879cc6ab8Sraveendra padasalagi 		.suite = {
352921c8e720SArd Biesheuvel 			.hash = __VECS(sha3_256_tv_template)
353079cc6ab8Sraveendra padasalagi 		}
353179cc6ab8Sraveendra padasalagi 	}, {
353279cc6ab8Sraveendra padasalagi 		.alg = "sha3-384",
353379cc6ab8Sraveendra padasalagi 		.test = alg_test_hash,
353479cc6ab8Sraveendra padasalagi 		.fips_allowed = 1,
353579cc6ab8Sraveendra padasalagi 		.suite = {
353621c8e720SArd Biesheuvel 			.hash = __VECS(sha3_384_tv_template)
353779cc6ab8Sraveendra padasalagi 		}
353879cc6ab8Sraveendra padasalagi 	}, {
353979cc6ab8Sraveendra padasalagi 		.alg = "sha3-512",
354079cc6ab8Sraveendra padasalagi 		.test = alg_test_hash,
354179cc6ab8Sraveendra padasalagi 		.fips_allowed = 1,
354279cc6ab8Sraveendra padasalagi 		.suite = {
354321c8e720SArd Biesheuvel 			.hash = __VECS(sha3_512_tv_template)
354479cc6ab8Sraveendra padasalagi 		}
354579cc6ab8Sraveendra padasalagi 	}, {
3546da7f033dSHerbert Xu 		.alg = "sha384",
3547da7f033dSHerbert Xu 		.test = alg_test_hash,
3548a1915d51SJarod Wilson 		.fips_allowed = 1,
3549da7f033dSHerbert Xu 		.suite = {
355021c8e720SArd Biesheuvel 			.hash = __VECS(sha384_tv_template)
3551da7f033dSHerbert Xu 		}
3552da7f033dSHerbert Xu 	}, {
3553da7f033dSHerbert Xu 		.alg = "sha512",
3554da7f033dSHerbert Xu 		.test = alg_test_hash,
3555a1915d51SJarod Wilson 		.fips_allowed = 1,
3556da7f033dSHerbert Xu 		.suite = {
355721c8e720SArd Biesheuvel 			.hash = __VECS(sha512_tv_template)
3558da7f033dSHerbert Xu 		}
3559da7f033dSHerbert Xu 	}, {
3560b7e27530SGilad Ben-Yossef 		.alg = "sm3",
3561b7e27530SGilad Ben-Yossef 		.test = alg_test_hash,
3562b7e27530SGilad Ben-Yossef 		.suite = {
3563b7e27530SGilad Ben-Yossef 			.hash = __VECS(sm3_tv_template)
3564b7e27530SGilad Ben-Yossef 		}
3565b7e27530SGilad Ben-Yossef 	}, {
356625a0b9d4SVitaly Chikunov 		.alg = "streebog256",
356725a0b9d4SVitaly Chikunov 		.test = alg_test_hash,
356825a0b9d4SVitaly Chikunov 		.suite = {
356925a0b9d4SVitaly Chikunov 			.hash = __VECS(streebog256_tv_template)
357025a0b9d4SVitaly Chikunov 		}
357125a0b9d4SVitaly Chikunov 	}, {
357225a0b9d4SVitaly Chikunov 		.alg = "streebog512",
357325a0b9d4SVitaly Chikunov 		.test = alg_test_hash,
357425a0b9d4SVitaly Chikunov 		.suite = {
357525a0b9d4SVitaly Chikunov 			.hash = __VECS(streebog512_tv_template)
357625a0b9d4SVitaly Chikunov 		}
357725a0b9d4SVitaly Chikunov 	}, {
3578da7f033dSHerbert Xu 		.alg = "tgr128",
3579da7f033dSHerbert Xu 		.test = alg_test_hash,
3580da7f033dSHerbert Xu 		.suite = {
358121c8e720SArd Biesheuvel 			.hash = __VECS(tgr128_tv_template)
3582da7f033dSHerbert Xu 		}
3583da7f033dSHerbert Xu 	}, {
3584da7f033dSHerbert Xu 		.alg = "tgr160",
3585da7f033dSHerbert Xu 		.test = alg_test_hash,
3586da7f033dSHerbert Xu 		.suite = {
358721c8e720SArd Biesheuvel 			.hash = __VECS(tgr160_tv_template)
3588da7f033dSHerbert Xu 		}
3589da7f033dSHerbert Xu 	}, {
3590da7f033dSHerbert Xu 		.alg = "tgr192",
3591da7f033dSHerbert Xu 		.test = alg_test_hash,
3592da7f033dSHerbert Xu 		.suite = {
359321c8e720SArd Biesheuvel 			.hash = __VECS(tgr192_tv_template)
3594da7f033dSHerbert Xu 		}
3595da7f033dSHerbert Xu 	}, {
3596ed331adaSEric Biggers 		.alg = "vmac64(aes)",
3597ed331adaSEric Biggers 		.test = alg_test_hash,
3598ed331adaSEric Biggers 		.suite = {
3599ed331adaSEric Biggers 			.hash = __VECS(vmac64_aes_tv_template)
3600ed331adaSEric Biggers 		}
3601ed331adaSEric Biggers 	}, {
3602da7f033dSHerbert Xu 		.alg = "wp256",
3603da7f033dSHerbert Xu 		.test = alg_test_hash,
3604da7f033dSHerbert Xu 		.suite = {
360521c8e720SArd Biesheuvel 			.hash = __VECS(wp256_tv_template)
3606da7f033dSHerbert Xu 		}
3607da7f033dSHerbert Xu 	}, {
3608da7f033dSHerbert Xu 		.alg = "wp384",
3609da7f033dSHerbert Xu 		.test = alg_test_hash,
3610da7f033dSHerbert Xu 		.suite = {
361121c8e720SArd Biesheuvel 			.hash = __VECS(wp384_tv_template)
3612da7f033dSHerbert Xu 		}
3613da7f033dSHerbert Xu 	}, {
3614da7f033dSHerbert Xu 		.alg = "wp512",
3615da7f033dSHerbert Xu 		.test = alg_test_hash,
3616da7f033dSHerbert Xu 		.suite = {
361721c8e720SArd Biesheuvel 			.hash = __VECS(wp512_tv_template)
3618da7f033dSHerbert Xu 		}
3619da7f033dSHerbert Xu 	}, {
3620da7f033dSHerbert Xu 		.alg = "xcbc(aes)",
3621da7f033dSHerbert Xu 		.test = alg_test_hash,
3622da7f033dSHerbert Xu 		.suite = {
362321c8e720SArd Biesheuvel 			.hash = __VECS(aes_xcbc128_tv_template)
3624da7f033dSHerbert Xu 		}
3625da7f033dSHerbert Xu 	}, {
3626aa762409SEric Biggers 		.alg = "xchacha12",
3627aa762409SEric Biggers 		.test = alg_test_skcipher,
3628aa762409SEric Biggers 		.suite = {
3629aa762409SEric Biggers 			.cipher = __VECS(xchacha12_tv_template)
3630aa762409SEric Biggers 		},
3631aa762409SEric Biggers 	}, {
3632de61d7aeSEric Biggers 		.alg = "xchacha20",
3633de61d7aeSEric Biggers 		.test = alg_test_skcipher,
3634de61d7aeSEric Biggers 		.suite = {
3635de61d7aeSEric Biggers 			.cipher = __VECS(xchacha20_tv_template)
3636de61d7aeSEric Biggers 		},
3637de61d7aeSEric Biggers 	}, {
3638da7f033dSHerbert Xu 		.alg = "xts(aes)",
36391aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
36402918aa8dSJarod Wilson 		.fips_allowed = 1,
3641da7f033dSHerbert Xu 		.suite = {
364292a4c9feSEric Biggers 			.cipher = __VECS(aes_xts_tv_template)
3643da7f033dSHerbert Xu 		}
36440c01aed5SGeert Uytterhoeven 	}, {
36450840605eSJussi Kivilinna 		.alg = "xts(camellia)",
36460840605eSJussi Kivilinna 		.test = alg_test_skcipher,
36470840605eSJussi Kivilinna 		.suite = {
364892a4c9feSEric Biggers 			.cipher = __VECS(camellia_xts_tv_template)
36490840605eSJussi Kivilinna 		}
36500840605eSJussi Kivilinna 	}, {
36519b8b0405SJohannes Goetzfried 		.alg = "xts(cast6)",
36529b8b0405SJohannes Goetzfried 		.test = alg_test_skcipher,
36539b8b0405SJohannes Goetzfried 		.suite = {
365492a4c9feSEric Biggers 			.cipher = __VECS(cast6_xts_tv_template)
36559b8b0405SJohannes Goetzfried 		}
36569b8b0405SJohannes Goetzfried 	}, {
365715f47ce5SGilad Ben-Yossef 		/* Same as xts(aes) except the key is stored in
365815f47ce5SGilad Ben-Yossef 		 * hardware secure memory which we reference by index
365915f47ce5SGilad Ben-Yossef 		 */
366015f47ce5SGilad Ben-Yossef 		.alg = "xts(paes)",
366115f47ce5SGilad Ben-Yossef 		.test = alg_test_null,
366215f47ce5SGilad Ben-Yossef 		.fips_allowed = 1,
366315f47ce5SGilad Ben-Yossef 	}, {
366418be20b9SJussi Kivilinna 		.alg = "xts(serpent)",
366518be20b9SJussi Kivilinna 		.test = alg_test_skcipher,
366618be20b9SJussi Kivilinna 		.suite = {
366792a4c9feSEric Biggers 			.cipher = __VECS(serpent_xts_tv_template)
366818be20b9SJussi Kivilinna 		}
366918be20b9SJussi Kivilinna 	}, {
3670aed265b9SJussi Kivilinna 		.alg = "xts(twofish)",
3671aed265b9SJussi Kivilinna 		.test = alg_test_skcipher,
3672aed265b9SJussi Kivilinna 		.suite = {
367392a4c9feSEric Biggers 			.cipher = __VECS(tf_xts_tv_template)
3674aed265b9SJussi Kivilinna 		}
3675a368f43dSGiovanni Cabiddu 	}, {
367615f47ce5SGilad Ben-Yossef 		.alg = "xts4096(paes)",
367715f47ce5SGilad Ben-Yossef 		.test = alg_test_null,
367815f47ce5SGilad Ben-Yossef 		.fips_allowed = 1,
367915f47ce5SGilad Ben-Yossef 	}, {
368015f47ce5SGilad Ben-Yossef 		.alg = "xts512(paes)",
368115f47ce5SGilad Ben-Yossef 		.test = alg_test_null,
368215f47ce5SGilad Ben-Yossef 		.fips_allowed = 1,
368315f47ce5SGilad Ben-Yossef 	}, {
3684a368f43dSGiovanni Cabiddu 		.alg = "zlib-deflate",
3685a368f43dSGiovanni Cabiddu 		.test = alg_test_comp,
3686a368f43dSGiovanni Cabiddu 		.fips_allowed = 1,
3687a368f43dSGiovanni Cabiddu 		.suite = {
3688a368f43dSGiovanni Cabiddu 			.comp = {
3689a368f43dSGiovanni Cabiddu 				.comp = __VECS(zlib_deflate_comp_tv_template),
3690a368f43dSGiovanni Cabiddu 				.decomp = __VECS(zlib_deflate_decomp_tv_template)
3691a368f43dSGiovanni Cabiddu 			}
3692a368f43dSGiovanni Cabiddu 		}
3693d28fc3dbSNick Terrell 	}, {
3694d28fc3dbSNick Terrell 		.alg = "zstd",
3695d28fc3dbSNick Terrell 		.test = alg_test_comp,
3696d28fc3dbSNick Terrell 		.fips_allowed = 1,
3697d28fc3dbSNick Terrell 		.suite = {
3698d28fc3dbSNick Terrell 			.comp = {
3699d28fc3dbSNick Terrell 				.comp = __VECS(zstd_comp_tv_template),
3700d28fc3dbSNick Terrell 				.decomp = __VECS(zstd_decomp_tv_template)
3701d28fc3dbSNick Terrell 			}
3702d28fc3dbSNick Terrell 		}
3703da7f033dSHerbert Xu 	}
3704da7f033dSHerbert Xu };
3705da7f033dSHerbert Xu 
37065714758bSJussi Kivilinna static bool alg_test_descs_checked;
37075714758bSJussi Kivilinna 
37085714758bSJussi Kivilinna static void alg_test_descs_check_order(void)
37095714758bSJussi Kivilinna {
37105714758bSJussi Kivilinna 	int i;
37115714758bSJussi Kivilinna 
37125714758bSJussi Kivilinna 	/* only check once */
37135714758bSJussi Kivilinna 	if (alg_test_descs_checked)
37145714758bSJussi Kivilinna 		return;
37155714758bSJussi Kivilinna 
37165714758bSJussi Kivilinna 	alg_test_descs_checked = true;
37175714758bSJussi Kivilinna 
37185714758bSJussi Kivilinna 	for (i = 1; i < ARRAY_SIZE(alg_test_descs); i++) {
37195714758bSJussi Kivilinna 		int diff = strcmp(alg_test_descs[i - 1].alg,
37205714758bSJussi Kivilinna 				  alg_test_descs[i].alg);
37215714758bSJussi Kivilinna 
37225714758bSJussi Kivilinna 		if (WARN_ON(diff > 0)) {
37235714758bSJussi Kivilinna 			pr_warn("testmgr: alg_test_descs entries in wrong order: '%s' before '%s'\n",
37245714758bSJussi Kivilinna 				alg_test_descs[i - 1].alg,
37255714758bSJussi Kivilinna 				alg_test_descs[i].alg);
37265714758bSJussi Kivilinna 		}
37275714758bSJussi Kivilinna 
37285714758bSJussi Kivilinna 		if (WARN_ON(diff == 0)) {
37295714758bSJussi Kivilinna 			pr_warn("testmgr: duplicate alg_test_descs entry: '%s'\n",
37305714758bSJussi Kivilinna 				alg_test_descs[i].alg);
37315714758bSJussi Kivilinna 		}
37325714758bSJussi Kivilinna 	}
37335714758bSJussi Kivilinna }
37345714758bSJussi Kivilinna 
37351aa4ecd9SHerbert Xu static int alg_find_test(const char *alg)
3736da7f033dSHerbert Xu {
3737da7f033dSHerbert Xu 	int start = 0;
3738da7f033dSHerbert Xu 	int end = ARRAY_SIZE(alg_test_descs);
3739da7f033dSHerbert Xu 
3740da7f033dSHerbert Xu 	while (start < end) {
3741da7f033dSHerbert Xu 		int i = (start + end) / 2;
3742da7f033dSHerbert Xu 		int diff = strcmp(alg_test_descs[i].alg, alg);
3743da7f033dSHerbert Xu 
3744da7f033dSHerbert Xu 		if (diff > 0) {
3745da7f033dSHerbert Xu 			end = i;
3746da7f033dSHerbert Xu 			continue;
3747da7f033dSHerbert Xu 		}
3748da7f033dSHerbert Xu 
3749da7f033dSHerbert Xu 		if (diff < 0) {
3750da7f033dSHerbert Xu 			start = i + 1;
3751da7f033dSHerbert Xu 			continue;
3752da7f033dSHerbert Xu 		}
3753da7f033dSHerbert Xu 
37541aa4ecd9SHerbert Xu 		return i;
3755da7f033dSHerbert Xu 	}
3756da7f033dSHerbert Xu 
37571aa4ecd9SHerbert Xu 	return -1;
37581aa4ecd9SHerbert Xu }
37591aa4ecd9SHerbert Xu 
37601aa4ecd9SHerbert Xu int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
37611aa4ecd9SHerbert Xu {
37621aa4ecd9SHerbert Xu 	int i;
3763a68f6610SHerbert Xu 	int j;
3764d12d6b6dSNeil Horman 	int rc;
37651aa4ecd9SHerbert Xu 
37669e5c9fe4SRichard W.M. Jones 	if (!fips_enabled && notests) {
37679e5c9fe4SRichard W.M. Jones 		printk_once(KERN_INFO "alg: self-tests disabled\n");
37689e5c9fe4SRichard W.M. Jones 		return 0;
37699e5c9fe4SRichard W.M. Jones 	}
37709e5c9fe4SRichard W.M. Jones 
37715714758bSJussi Kivilinna 	alg_test_descs_check_order();
37725714758bSJussi Kivilinna 
37731aa4ecd9SHerbert Xu 	if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) {
37741aa4ecd9SHerbert Xu 		char nalg[CRYPTO_MAX_ALG_NAME];
37751aa4ecd9SHerbert Xu 
37761aa4ecd9SHerbert Xu 		if (snprintf(nalg, sizeof(nalg), "ecb(%s)", alg) >=
37771aa4ecd9SHerbert Xu 		    sizeof(nalg))
37781aa4ecd9SHerbert Xu 			return -ENAMETOOLONG;
37791aa4ecd9SHerbert Xu 
37801aa4ecd9SHerbert Xu 		i = alg_find_test(nalg);
37811aa4ecd9SHerbert Xu 		if (i < 0)
37821aa4ecd9SHerbert Xu 			goto notest;
37831aa4ecd9SHerbert Xu 
3784a3bef3a3SJarod Wilson 		if (fips_enabled && !alg_test_descs[i].fips_allowed)
3785a3bef3a3SJarod Wilson 			goto non_fips_alg;
3786a3bef3a3SJarod Wilson 
3787941fb328SJarod Wilson 		rc = alg_test_cipher(alg_test_descs + i, driver, type, mask);
3788941fb328SJarod Wilson 		goto test_done;
37891aa4ecd9SHerbert Xu 	}
37901aa4ecd9SHerbert Xu 
37911aa4ecd9SHerbert Xu 	i = alg_find_test(alg);
3792a68f6610SHerbert Xu 	j = alg_find_test(driver);
3793a68f6610SHerbert Xu 	if (i < 0 && j < 0)
37941aa4ecd9SHerbert Xu 		goto notest;
37951aa4ecd9SHerbert Xu 
3796a68f6610SHerbert Xu 	if (fips_enabled && ((i >= 0 && !alg_test_descs[i].fips_allowed) ||
3797a68f6610SHerbert Xu 			     (j >= 0 && !alg_test_descs[j].fips_allowed)))
3798a3bef3a3SJarod Wilson 		goto non_fips_alg;
3799a3bef3a3SJarod Wilson 
3800a68f6610SHerbert Xu 	rc = 0;
3801a68f6610SHerbert Xu 	if (i >= 0)
3802a68f6610SHerbert Xu 		rc |= alg_test_descs[i].test(alg_test_descs + i, driver,
38031aa4ecd9SHerbert Xu 					     type, mask);
3804032c8cacSCristian Stoica 	if (j >= 0 && j != i)
3805a68f6610SHerbert Xu 		rc |= alg_test_descs[j].test(alg_test_descs + j, driver,
3806a68f6610SHerbert Xu 					     type, mask);
3807a68f6610SHerbert Xu 
3808941fb328SJarod Wilson test_done:
3809d12d6b6dSNeil Horman 	if (fips_enabled && rc)
3810d12d6b6dSNeil Horman 		panic("%s: %s alg self test failed in fips mode!\n", driver, alg);
3811d12d6b6dSNeil Horman 
381229ecd4abSJarod Wilson 	if (fips_enabled && !rc)
38133e8cffd4SMasanari Iida 		pr_info("alg: self-tests for %s (%s) passed\n", driver, alg);
381429ecd4abSJarod Wilson 
3815d12d6b6dSNeil Horman 	return rc;
38161aa4ecd9SHerbert Xu 
38171aa4ecd9SHerbert Xu notest:
3818da7f033dSHerbert Xu 	printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver);
3819da7f033dSHerbert Xu 	return 0;
3820a3bef3a3SJarod Wilson non_fips_alg:
3821a3bef3a3SJarod Wilson 	return -EINVAL;
3822da7f033dSHerbert Xu }
38230b767f96SAlexander Shishkin 
3824326a6346SHerbert Xu #endif /* CONFIG_CRYPTO_MANAGER_DISABLE_TESTS */
38250b767f96SAlexander Shishkin 
3826da7f033dSHerbert Xu EXPORT_SYMBOL_GPL(alg_test);
3827