xref: /openbmc/linux/crypto/testmgr.c (revision 326a6346)
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  *
9da7f033dSHerbert Xu  * This program is free software; you can redistribute it and/or modify it
10da7f033dSHerbert Xu  * under the terms of the GNU General Public License as published by the Free
11da7f033dSHerbert Xu  * Software Foundation; either version 2 of the License, or (at your option)
12da7f033dSHerbert Xu  * any later version.
13da7f033dSHerbert Xu  *
14da7f033dSHerbert Xu  */
15da7f033dSHerbert Xu 
16da7f033dSHerbert Xu #include <crypto/hash.h>
17da7f033dSHerbert Xu #include <linux/err.h>
18da7f033dSHerbert Xu #include <linux/module.h>
19da7f033dSHerbert Xu #include <linux/scatterlist.h>
20da7f033dSHerbert Xu #include <linux/slab.h>
21da7f033dSHerbert Xu #include <linux/string.h>
227647d6ceSJarod Wilson #include <crypto/rng.h>
23da7f033dSHerbert Xu 
24da7f033dSHerbert Xu #include "internal.h"
250b767f96SAlexander Shishkin 
26326a6346SHerbert Xu #ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS
270b767f96SAlexander Shishkin 
280b767f96SAlexander Shishkin /* a perfect nop */
290b767f96SAlexander Shishkin int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
300b767f96SAlexander Shishkin {
310b767f96SAlexander Shishkin 	return 0;
320b767f96SAlexander Shishkin }
330b767f96SAlexander Shishkin 
340b767f96SAlexander Shishkin #else
350b767f96SAlexander Shishkin 
36da7f033dSHerbert Xu #include "testmgr.h"
37da7f033dSHerbert Xu 
38da7f033dSHerbert Xu /*
39da7f033dSHerbert Xu  * Need slab memory for testing (size in number of pages).
40da7f033dSHerbert Xu  */
41da7f033dSHerbert Xu #define XBUFSIZE	8
42da7f033dSHerbert Xu 
43da7f033dSHerbert Xu /*
44da7f033dSHerbert Xu  * Indexes into the xbuf to simulate cross-page access.
45da7f033dSHerbert Xu  */
46da7f033dSHerbert Xu #define IDX1		32
47da7f033dSHerbert Xu #define IDX2		32400
48da7f033dSHerbert Xu #define IDX3		1
49da7f033dSHerbert Xu #define IDX4		8193
50da7f033dSHerbert Xu #define IDX5		22222
51da7f033dSHerbert Xu #define IDX6		17101
52da7f033dSHerbert Xu #define IDX7		27333
53da7f033dSHerbert Xu #define IDX8		3000
54da7f033dSHerbert Xu 
55da7f033dSHerbert Xu /*
56da7f033dSHerbert Xu * Used by test_cipher()
57da7f033dSHerbert Xu */
58da7f033dSHerbert Xu #define ENCRYPT 1
59da7f033dSHerbert Xu #define DECRYPT 0
60da7f033dSHerbert Xu 
61da7f033dSHerbert Xu struct tcrypt_result {
62da7f033dSHerbert Xu 	struct completion completion;
63da7f033dSHerbert Xu 	int err;
64da7f033dSHerbert Xu };
65da7f033dSHerbert Xu 
66da7f033dSHerbert Xu struct aead_test_suite {
67da7f033dSHerbert Xu 	struct {
68da7f033dSHerbert Xu 		struct aead_testvec *vecs;
69da7f033dSHerbert Xu 		unsigned int count;
70da7f033dSHerbert Xu 	} enc, dec;
71da7f033dSHerbert Xu };
72da7f033dSHerbert Xu 
73da7f033dSHerbert Xu struct cipher_test_suite {
74da7f033dSHerbert Xu 	struct {
75da7f033dSHerbert Xu 		struct cipher_testvec *vecs;
76da7f033dSHerbert Xu 		unsigned int count;
77da7f033dSHerbert Xu 	} enc, dec;
78da7f033dSHerbert Xu };
79da7f033dSHerbert Xu 
80da7f033dSHerbert Xu struct comp_test_suite {
81da7f033dSHerbert Xu 	struct {
82da7f033dSHerbert Xu 		struct comp_testvec *vecs;
83da7f033dSHerbert Xu 		unsigned int count;
84da7f033dSHerbert Xu 	} comp, decomp;
85da7f033dSHerbert Xu };
86da7f033dSHerbert Xu 
878064efb8SGeert Uytterhoeven struct pcomp_test_suite {
888064efb8SGeert Uytterhoeven 	struct {
898064efb8SGeert Uytterhoeven 		struct pcomp_testvec *vecs;
908064efb8SGeert Uytterhoeven 		unsigned int count;
918064efb8SGeert Uytterhoeven 	} comp, decomp;
928064efb8SGeert Uytterhoeven };
938064efb8SGeert Uytterhoeven 
94da7f033dSHerbert Xu struct hash_test_suite {
95da7f033dSHerbert Xu 	struct hash_testvec *vecs;
96da7f033dSHerbert Xu 	unsigned int count;
97da7f033dSHerbert Xu };
98da7f033dSHerbert Xu 
997647d6ceSJarod Wilson struct cprng_test_suite {
1007647d6ceSJarod Wilson 	struct cprng_testvec *vecs;
1017647d6ceSJarod Wilson 	unsigned int count;
1027647d6ceSJarod Wilson };
1037647d6ceSJarod Wilson 
104da7f033dSHerbert Xu struct alg_test_desc {
105da7f033dSHerbert Xu 	const char *alg;
106da7f033dSHerbert Xu 	int (*test)(const struct alg_test_desc *desc, const char *driver,
107da7f033dSHerbert Xu 		    u32 type, u32 mask);
108a1915d51SJarod Wilson 	int fips_allowed;	/* set if alg is allowed in fips mode */
109da7f033dSHerbert Xu 
110da7f033dSHerbert Xu 	union {
111da7f033dSHerbert Xu 		struct aead_test_suite aead;
112da7f033dSHerbert Xu 		struct cipher_test_suite cipher;
113da7f033dSHerbert Xu 		struct comp_test_suite comp;
1148064efb8SGeert Uytterhoeven 		struct pcomp_test_suite pcomp;
115da7f033dSHerbert Xu 		struct hash_test_suite hash;
1167647d6ceSJarod Wilson 		struct cprng_test_suite cprng;
117da7f033dSHerbert Xu 	} suite;
118da7f033dSHerbert Xu };
119da7f033dSHerbert Xu 
120da7f033dSHerbert Xu static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 };
121da7f033dSHerbert Xu 
122da7f033dSHerbert Xu static void hexdump(unsigned char *buf, unsigned int len)
123da7f033dSHerbert Xu {
124da7f033dSHerbert Xu 	print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
125da7f033dSHerbert Xu 			16, 1,
126da7f033dSHerbert Xu 			buf, len, false);
127da7f033dSHerbert Xu }
128da7f033dSHerbert Xu 
129da7f033dSHerbert Xu static void tcrypt_complete(struct crypto_async_request *req, int err)
130da7f033dSHerbert Xu {
131da7f033dSHerbert Xu 	struct tcrypt_result *res = req->data;
132da7f033dSHerbert Xu 
133da7f033dSHerbert Xu 	if (err == -EINPROGRESS)
134da7f033dSHerbert Xu 		return;
135da7f033dSHerbert Xu 
136da7f033dSHerbert Xu 	res->err = err;
137da7f033dSHerbert Xu 	complete(&res->completion);
138da7f033dSHerbert Xu }
139da7f033dSHerbert Xu 
140f8b0d4d0SHerbert Xu static int testmgr_alloc_buf(char *buf[XBUFSIZE])
141f8b0d4d0SHerbert Xu {
142f8b0d4d0SHerbert Xu 	int i;
143f8b0d4d0SHerbert Xu 
144f8b0d4d0SHerbert Xu 	for (i = 0; i < XBUFSIZE; i++) {
145f8b0d4d0SHerbert Xu 		buf[i] = (void *)__get_free_page(GFP_KERNEL);
146f8b0d4d0SHerbert Xu 		if (!buf[i])
147f8b0d4d0SHerbert Xu 			goto err_free_buf;
148f8b0d4d0SHerbert Xu 	}
149f8b0d4d0SHerbert Xu 
150f8b0d4d0SHerbert Xu 	return 0;
151f8b0d4d0SHerbert Xu 
152f8b0d4d0SHerbert Xu err_free_buf:
153f8b0d4d0SHerbert Xu 	while (i-- > 0)
154f8b0d4d0SHerbert Xu 		free_page((unsigned long)buf[i]);
155f8b0d4d0SHerbert Xu 
156f8b0d4d0SHerbert Xu 	return -ENOMEM;
157f8b0d4d0SHerbert Xu }
158f8b0d4d0SHerbert Xu 
159f8b0d4d0SHerbert Xu static void testmgr_free_buf(char *buf[XBUFSIZE])
160f8b0d4d0SHerbert Xu {
161f8b0d4d0SHerbert Xu 	int i;
162f8b0d4d0SHerbert Xu 
163f8b0d4d0SHerbert Xu 	for (i = 0; i < XBUFSIZE; i++)
164f8b0d4d0SHerbert Xu 		free_page((unsigned long)buf[i]);
165f8b0d4d0SHerbert Xu }
166f8b0d4d0SHerbert Xu 
167a8f1a052SDavid S. Miller static int do_one_async_hash_op(struct ahash_request *req,
168a8f1a052SDavid S. Miller 				struct tcrypt_result *tr,
169a8f1a052SDavid S. Miller 				int ret)
170a8f1a052SDavid S. Miller {
171a8f1a052SDavid S. Miller 	if (ret == -EINPROGRESS || ret == -EBUSY) {
172a8f1a052SDavid S. Miller 		ret = wait_for_completion_interruptible(&tr->completion);
173a8f1a052SDavid S. Miller 		if (!ret)
174a8f1a052SDavid S. Miller 			ret = tr->err;
175a8f1a052SDavid S. Miller 		INIT_COMPLETION(tr->completion);
176a8f1a052SDavid S. Miller 	}
177a8f1a052SDavid S. Miller 	return ret;
178a8f1a052SDavid S. Miller }
179a8f1a052SDavid S. Miller 
180da7f033dSHerbert Xu static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
181a8f1a052SDavid S. Miller 		     unsigned int tcount, bool use_digest)
182da7f033dSHerbert Xu {
183da7f033dSHerbert Xu 	const char *algo = crypto_tfm_alg_driver_name(crypto_ahash_tfm(tfm));
184da7f033dSHerbert Xu 	unsigned int i, j, k, temp;
185da7f033dSHerbert Xu 	struct scatterlist sg[8];
186da7f033dSHerbert Xu 	char result[64];
187da7f033dSHerbert Xu 	struct ahash_request *req;
188da7f033dSHerbert Xu 	struct tcrypt_result tresult;
189da7f033dSHerbert Xu 	void *hash_buff;
190f8b0d4d0SHerbert Xu 	char *xbuf[XBUFSIZE];
191f8b0d4d0SHerbert Xu 	int ret = -ENOMEM;
192f8b0d4d0SHerbert Xu 
193f8b0d4d0SHerbert Xu 	if (testmgr_alloc_buf(xbuf))
194f8b0d4d0SHerbert Xu 		goto out_nobuf;
195da7f033dSHerbert Xu 
196da7f033dSHerbert Xu 	init_completion(&tresult.completion);
197da7f033dSHerbert Xu 
198da7f033dSHerbert Xu 	req = ahash_request_alloc(tfm, GFP_KERNEL);
199da7f033dSHerbert Xu 	if (!req) {
200da7f033dSHerbert Xu 		printk(KERN_ERR "alg: hash: Failed to allocate request for "
201da7f033dSHerbert Xu 		       "%s\n", algo);
202da7f033dSHerbert Xu 		goto out_noreq;
203da7f033dSHerbert Xu 	}
204da7f033dSHerbert Xu 	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
205da7f033dSHerbert Xu 				   tcrypt_complete, &tresult);
206da7f033dSHerbert Xu 
207a0cfae59SHerbert Xu 	j = 0;
208da7f033dSHerbert Xu 	for (i = 0; i < tcount; i++) {
209a0cfae59SHerbert Xu 		if (template[i].np)
210a0cfae59SHerbert Xu 			continue;
211a0cfae59SHerbert Xu 
212a0cfae59SHerbert Xu 		j++;
213da7f033dSHerbert Xu 		memset(result, 0, 64);
214da7f033dSHerbert Xu 
215da7f033dSHerbert Xu 		hash_buff = xbuf[0];
216da7f033dSHerbert Xu 
217da7f033dSHerbert Xu 		memcpy(hash_buff, template[i].plaintext, template[i].psize);
218da7f033dSHerbert Xu 		sg_init_one(&sg[0], hash_buff, template[i].psize);
219da7f033dSHerbert Xu 
220da7f033dSHerbert Xu 		if (template[i].ksize) {
221da7f033dSHerbert Xu 			crypto_ahash_clear_flags(tfm, ~0);
222da7f033dSHerbert Xu 			ret = crypto_ahash_setkey(tfm, template[i].key,
223da7f033dSHerbert Xu 						  template[i].ksize);
224da7f033dSHerbert Xu 			if (ret) {
225da7f033dSHerbert Xu 				printk(KERN_ERR "alg: hash: setkey failed on "
226a0cfae59SHerbert Xu 				       "test %d for %s: ret=%d\n", j, algo,
227da7f033dSHerbert Xu 				       -ret);
228da7f033dSHerbert Xu 				goto out;
229da7f033dSHerbert Xu 			}
230da7f033dSHerbert Xu 		}
231da7f033dSHerbert Xu 
232da7f033dSHerbert Xu 		ahash_request_set_crypt(req, sg, result, template[i].psize);
233a8f1a052SDavid S. Miller 		if (use_digest) {
234a8f1a052SDavid S. Miller 			ret = do_one_async_hash_op(req, &tresult,
235a8f1a052SDavid S. Miller 						   crypto_ahash_digest(req));
236a8f1a052SDavid S. Miller 			if (ret) {
237a8f1a052SDavid S. Miller 				pr_err("alg: hash: digest failed on test %d "
238a0cfae59SHerbert Xu 				       "for %s: ret=%d\n", j, algo, -ret);
239da7f033dSHerbert Xu 				goto out;
240da7f033dSHerbert Xu 			}
241a8f1a052SDavid S. Miller 		} else {
242a8f1a052SDavid S. Miller 			ret = do_one_async_hash_op(req, &tresult,
243a8f1a052SDavid S. Miller 						   crypto_ahash_init(req));
244a8f1a052SDavid S. Miller 			if (ret) {
245a8f1a052SDavid S. Miller 				pr_err("alt: hash: init failed on test %d "
246a8f1a052SDavid S. Miller 				       "for %s: ret=%d\n", j, algo, -ret);
247a8f1a052SDavid S. Miller 				goto out;
248a8f1a052SDavid S. Miller 			}
249a8f1a052SDavid S. Miller 			ret = do_one_async_hash_op(req, &tresult,
250a8f1a052SDavid S. Miller 						   crypto_ahash_update(req));
251a8f1a052SDavid S. Miller 			if (ret) {
252a8f1a052SDavid S. Miller 				pr_err("alt: hash: update failed on test %d "
253a8f1a052SDavid S. Miller 				       "for %s: ret=%d\n", j, algo, -ret);
254a8f1a052SDavid S. Miller 				goto out;
255a8f1a052SDavid S. Miller 			}
256a8f1a052SDavid S. Miller 			ret = do_one_async_hash_op(req, &tresult,
257a8f1a052SDavid S. Miller 						   crypto_ahash_final(req));
258a8f1a052SDavid S. Miller 			if (ret) {
259a8f1a052SDavid S. Miller 				pr_err("alt: hash: final failed on test %d "
260a8f1a052SDavid S. Miller 				       "for %s: ret=%d\n", j, algo, -ret);
261a8f1a052SDavid S. Miller 				goto out;
262a8f1a052SDavid S. Miller 			}
263a8f1a052SDavid S. Miller 		}
264da7f033dSHerbert Xu 
265da7f033dSHerbert Xu 		if (memcmp(result, template[i].digest,
266da7f033dSHerbert Xu 			   crypto_ahash_digestsize(tfm))) {
267da7f033dSHerbert Xu 			printk(KERN_ERR "alg: hash: Test %d failed for %s\n",
268a0cfae59SHerbert Xu 			       j, algo);
269da7f033dSHerbert Xu 			hexdump(result, crypto_ahash_digestsize(tfm));
270da7f033dSHerbert Xu 			ret = -EINVAL;
271da7f033dSHerbert Xu 			goto out;
272da7f033dSHerbert Xu 		}
273da7f033dSHerbert Xu 	}
274da7f033dSHerbert Xu 
275da7f033dSHerbert Xu 	j = 0;
276da7f033dSHerbert Xu 	for (i = 0; i < tcount; i++) {
277da7f033dSHerbert Xu 		if (template[i].np) {
278da7f033dSHerbert Xu 			j++;
279da7f033dSHerbert Xu 			memset(result, 0, 64);
280da7f033dSHerbert Xu 
281da7f033dSHerbert Xu 			temp = 0;
282da7f033dSHerbert Xu 			sg_init_table(sg, template[i].np);
283fd57f22aSHerbert Xu 			ret = -EINVAL;
284da7f033dSHerbert Xu 			for (k = 0; k < template[i].np; k++) {
285fd57f22aSHerbert Xu 				if (WARN_ON(offset_in_page(IDX[k]) +
286fd57f22aSHerbert Xu 					    template[i].tap[k] > PAGE_SIZE))
287fd57f22aSHerbert Xu 					goto out;
288da7f033dSHerbert Xu 				sg_set_buf(&sg[k],
289da7f033dSHerbert Xu 					   memcpy(xbuf[IDX[k] >> PAGE_SHIFT] +
290da7f033dSHerbert Xu 						  offset_in_page(IDX[k]),
291da7f033dSHerbert Xu 						  template[i].plaintext + temp,
292da7f033dSHerbert Xu 						  template[i].tap[k]),
293da7f033dSHerbert Xu 					   template[i].tap[k]);
294da7f033dSHerbert Xu 				temp += template[i].tap[k];
295da7f033dSHerbert Xu 			}
296da7f033dSHerbert Xu 
297da7f033dSHerbert Xu 			if (template[i].ksize) {
298da7f033dSHerbert Xu 				crypto_ahash_clear_flags(tfm, ~0);
299da7f033dSHerbert Xu 				ret = crypto_ahash_setkey(tfm, template[i].key,
300da7f033dSHerbert Xu 							  template[i].ksize);
301da7f033dSHerbert Xu 
302da7f033dSHerbert Xu 				if (ret) {
303da7f033dSHerbert Xu 					printk(KERN_ERR "alg: hash: setkey "
304da7f033dSHerbert Xu 					       "failed on chunking test %d "
305da7f033dSHerbert Xu 					       "for %s: ret=%d\n", j, algo,
306da7f033dSHerbert Xu 					       -ret);
307da7f033dSHerbert Xu 					goto out;
308da7f033dSHerbert Xu 				}
309da7f033dSHerbert Xu 			}
310da7f033dSHerbert Xu 
311da7f033dSHerbert Xu 			ahash_request_set_crypt(req, sg, result,
312da7f033dSHerbert Xu 						template[i].psize);
313da7f033dSHerbert Xu 			ret = crypto_ahash_digest(req);
314da7f033dSHerbert Xu 			switch (ret) {
315da7f033dSHerbert Xu 			case 0:
316da7f033dSHerbert Xu 				break;
317da7f033dSHerbert Xu 			case -EINPROGRESS:
318da7f033dSHerbert Xu 			case -EBUSY:
319da7f033dSHerbert Xu 				ret = wait_for_completion_interruptible(
320da7f033dSHerbert Xu 					&tresult.completion);
321da7f033dSHerbert Xu 				if (!ret && !(ret = tresult.err)) {
322da7f033dSHerbert Xu 					INIT_COMPLETION(tresult.completion);
323da7f033dSHerbert Xu 					break;
324da7f033dSHerbert Xu 				}
325da7f033dSHerbert Xu 				/* fall through */
326da7f033dSHerbert Xu 			default:
327da7f033dSHerbert Xu 				printk(KERN_ERR "alg: hash: digest failed "
328da7f033dSHerbert Xu 				       "on chunking test %d for %s: "
329da7f033dSHerbert Xu 				       "ret=%d\n", j, algo, -ret);
330da7f033dSHerbert Xu 				goto out;
331da7f033dSHerbert Xu 			}
332da7f033dSHerbert Xu 
333da7f033dSHerbert Xu 			if (memcmp(result, template[i].digest,
334da7f033dSHerbert Xu 				   crypto_ahash_digestsize(tfm))) {
335da7f033dSHerbert Xu 				printk(KERN_ERR "alg: hash: Chunking test %d "
336da7f033dSHerbert Xu 				       "failed for %s\n", j, algo);
337da7f033dSHerbert Xu 				hexdump(result, crypto_ahash_digestsize(tfm));
338da7f033dSHerbert Xu 				ret = -EINVAL;
339da7f033dSHerbert Xu 				goto out;
340da7f033dSHerbert Xu 			}
341da7f033dSHerbert Xu 		}
342da7f033dSHerbert Xu 	}
343da7f033dSHerbert Xu 
344da7f033dSHerbert Xu 	ret = 0;
345da7f033dSHerbert Xu 
346da7f033dSHerbert Xu out:
347da7f033dSHerbert Xu 	ahash_request_free(req);
348da7f033dSHerbert Xu out_noreq:
349f8b0d4d0SHerbert Xu 	testmgr_free_buf(xbuf);
350f8b0d4d0SHerbert Xu out_nobuf:
351da7f033dSHerbert Xu 	return ret;
352da7f033dSHerbert Xu }
353da7f033dSHerbert Xu 
354da7f033dSHerbert Xu static int test_aead(struct crypto_aead *tfm, int enc,
355da7f033dSHerbert Xu 		     struct aead_testvec *template, unsigned int tcount)
356da7f033dSHerbert Xu {
357da7f033dSHerbert Xu 	const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm));
358da7f033dSHerbert Xu 	unsigned int i, j, k, n, temp;
359f8b0d4d0SHerbert Xu 	int ret = -ENOMEM;
360da7f033dSHerbert Xu 	char *q;
361da7f033dSHerbert Xu 	char *key;
362da7f033dSHerbert Xu 	struct aead_request *req;
363da7f033dSHerbert Xu 	struct scatterlist sg[8];
364da7f033dSHerbert Xu 	struct scatterlist asg[8];
365da7f033dSHerbert Xu 	const char *e;
366da7f033dSHerbert Xu 	struct tcrypt_result result;
367da7f033dSHerbert Xu 	unsigned int authsize;
368da7f033dSHerbert Xu 	void *input;
369da7f033dSHerbert Xu 	void *assoc;
370da7f033dSHerbert Xu 	char iv[MAX_IVLEN];
371f8b0d4d0SHerbert Xu 	char *xbuf[XBUFSIZE];
372f8b0d4d0SHerbert Xu 	char *axbuf[XBUFSIZE];
373f8b0d4d0SHerbert Xu 
374f8b0d4d0SHerbert Xu 	if (testmgr_alloc_buf(xbuf))
375f8b0d4d0SHerbert Xu 		goto out_noxbuf;
376f8b0d4d0SHerbert Xu 	if (testmgr_alloc_buf(axbuf))
377f8b0d4d0SHerbert Xu 		goto out_noaxbuf;
378da7f033dSHerbert Xu 
379da7f033dSHerbert Xu 	if (enc == ENCRYPT)
380da7f033dSHerbert Xu 		e = "encryption";
381da7f033dSHerbert Xu 	else
382da7f033dSHerbert Xu 		e = "decryption";
383da7f033dSHerbert Xu 
384da7f033dSHerbert Xu 	init_completion(&result.completion);
385da7f033dSHerbert Xu 
386da7f033dSHerbert Xu 	req = aead_request_alloc(tfm, GFP_KERNEL);
387da7f033dSHerbert Xu 	if (!req) {
388da7f033dSHerbert Xu 		printk(KERN_ERR "alg: aead: Failed to allocate request for "
389da7f033dSHerbert Xu 		       "%s\n", algo);
390da7f033dSHerbert Xu 		goto out;
391da7f033dSHerbert Xu 	}
392da7f033dSHerbert Xu 
393da7f033dSHerbert Xu 	aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
394da7f033dSHerbert Xu 				  tcrypt_complete, &result);
395da7f033dSHerbert Xu 
396da7f033dSHerbert Xu 	for (i = 0, j = 0; i < tcount; i++) {
397da7f033dSHerbert Xu 		if (!template[i].np) {
398da7f033dSHerbert Xu 			j++;
399da7f033dSHerbert Xu 
400da7f033dSHerbert Xu 			/* some tepmplates have no input data but they will
401da7f033dSHerbert Xu 			 * touch input
402da7f033dSHerbert Xu 			 */
403da7f033dSHerbert Xu 			input = xbuf[0];
404da7f033dSHerbert Xu 			assoc = axbuf[0];
405da7f033dSHerbert Xu 
406fd57f22aSHerbert Xu 			ret = -EINVAL;
407fd57f22aSHerbert Xu 			if (WARN_ON(template[i].ilen > PAGE_SIZE ||
408fd57f22aSHerbert Xu 				    template[i].alen > PAGE_SIZE))
409fd57f22aSHerbert Xu 				goto out;
410fd57f22aSHerbert Xu 
411da7f033dSHerbert Xu 			memcpy(input, template[i].input, template[i].ilen);
412da7f033dSHerbert Xu 			memcpy(assoc, template[i].assoc, template[i].alen);
413da7f033dSHerbert Xu 			if (template[i].iv)
414da7f033dSHerbert Xu 				memcpy(iv, template[i].iv, MAX_IVLEN);
415da7f033dSHerbert Xu 			else
416da7f033dSHerbert Xu 				memset(iv, 0, MAX_IVLEN);
417da7f033dSHerbert Xu 
418da7f033dSHerbert Xu 			crypto_aead_clear_flags(tfm, ~0);
419da7f033dSHerbert Xu 			if (template[i].wk)
420da7f033dSHerbert Xu 				crypto_aead_set_flags(
421da7f033dSHerbert Xu 					tfm, CRYPTO_TFM_REQ_WEAK_KEY);
422da7f033dSHerbert Xu 
423da7f033dSHerbert Xu 			key = template[i].key;
424da7f033dSHerbert Xu 
425da7f033dSHerbert Xu 			ret = crypto_aead_setkey(tfm, key,
426da7f033dSHerbert Xu 						 template[i].klen);
427da7f033dSHerbert Xu 			if (!ret == template[i].fail) {
428da7f033dSHerbert Xu 				printk(KERN_ERR "alg: aead: setkey failed on "
429da7f033dSHerbert Xu 				       "test %d for %s: flags=%x\n", j, algo,
430da7f033dSHerbert Xu 				       crypto_aead_get_flags(tfm));
431da7f033dSHerbert Xu 				goto out;
432da7f033dSHerbert Xu 			} else if (ret)
433da7f033dSHerbert Xu 				continue;
434da7f033dSHerbert Xu 
435da7f033dSHerbert Xu 			authsize = abs(template[i].rlen - template[i].ilen);
436da7f033dSHerbert Xu 			ret = crypto_aead_setauthsize(tfm, authsize);
437da7f033dSHerbert Xu 			if (ret) {
438da7f033dSHerbert Xu 				printk(KERN_ERR "alg: aead: Failed to set "
439da7f033dSHerbert Xu 				       "authsize to %u on test %d for %s\n",
440da7f033dSHerbert Xu 				       authsize, j, algo);
441da7f033dSHerbert Xu 				goto out;
442da7f033dSHerbert Xu 			}
443da7f033dSHerbert Xu 
444da7f033dSHerbert Xu 			sg_init_one(&sg[0], input,
445da7f033dSHerbert Xu 				    template[i].ilen + (enc ? authsize : 0));
446da7f033dSHerbert Xu 
447da7f033dSHerbert Xu 			sg_init_one(&asg[0], assoc, template[i].alen);
448da7f033dSHerbert Xu 
449da7f033dSHerbert Xu 			aead_request_set_crypt(req, sg, sg,
450da7f033dSHerbert Xu 					       template[i].ilen, iv);
451da7f033dSHerbert Xu 
452da7f033dSHerbert Xu 			aead_request_set_assoc(req, asg, template[i].alen);
453da7f033dSHerbert Xu 
454da7f033dSHerbert Xu 			ret = enc ?
455da7f033dSHerbert Xu 				crypto_aead_encrypt(req) :
456da7f033dSHerbert Xu 				crypto_aead_decrypt(req);
457da7f033dSHerbert Xu 
458da7f033dSHerbert Xu 			switch (ret) {
459da7f033dSHerbert Xu 			case 0:
460e44a1b44SJarod Wilson 				if (template[i].novrfy) {
461e44a1b44SJarod Wilson 					/* verification was supposed to fail */
462e44a1b44SJarod Wilson 					printk(KERN_ERR "alg: aead: %s failed "
463e44a1b44SJarod Wilson 					       "on test %d for %s: ret was 0, "
464e44a1b44SJarod Wilson 					       "expected -EBADMSG\n",
465e44a1b44SJarod Wilson 					       e, j, algo);
466e44a1b44SJarod Wilson 					/* so really, we got a bad message */
467e44a1b44SJarod Wilson 					ret = -EBADMSG;
468e44a1b44SJarod Wilson 					goto out;
469e44a1b44SJarod Wilson 				}
470da7f033dSHerbert Xu 				break;
471da7f033dSHerbert Xu 			case -EINPROGRESS:
472da7f033dSHerbert Xu 			case -EBUSY:
473da7f033dSHerbert Xu 				ret = wait_for_completion_interruptible(
474da7f033dSHerbert Xu 					&result.completion);
475da7f033dSHerbert Xu 				if (!ret && !(ret = result.err)) {
476da7f033dSHerbert Xu 					INIT_COMPLETION(result.completion);
477da7f033dSHerbert Xu 					break;
478da7f033dSHerbert Xu 				}
479e44a1b44SJarod Wilson 			case -EBADMSG:
480e44a1b44SJarod Wilson 				if (template[i].novrfy)
481e44a1b44SJarod Wilson 					/* verification failure was expected */
482e44a1b44SJarod Wilson 					continue;
483da7f033dSHerbert Xu 				/* fall through */
484da7f033dSHerbert Xu 			default:
485da7f033dSHerbert Xu 				printk(KERN_ERR "alg: aead: %s failed on test "
486da7f033dSHerbert Xu 				       "%d for %s: ret=%d\n", e, j, algo, -ret);
487da7f033dSHerbert Xu 				goto out;
488da7f033dSHerbert Xu 			}
489da7f033dSHerbert Xu 
490da7f033dSHerbert Xu 			q = input;
491da7f033dSHerbert Xu 			if (memcmp(q, template[i].result, template[i].rlen)) {
492da7f033dSHerbert Xu 				printk(KERN_ERR "alg: aead: Test %d failed on "
493da7f033dSHerbert Xu 				       "%s for %s\n", j, e, algo);
494da7f033dSHerbert Xu 				hexdump(q, template[i].rlen);
495da7f033dSHerbert Xu 				ret = -EINVAL;
496da7f033dSHerbert Xu 				goto out;
497da7f033dSHerbert Xu 			}
498da7f033dSHerbert Xu 		}
499da7f033dSHerbert Xu 	}
500da7f033dSHerbert Xu 
501da7f033dSHerbert Xu 	for (i = 0, j = 0; i < tcount; i++) {
502da7f033dSHerbert Xu 		if (template[i].np) {
503da7f033dSHerbert Xu 			j++;
504da7f033dSHerbert Xu 
505da7f033dSHerbert Xu 			if (template[i].iv)
506da7f033dSHerbert Xu 				memcpy(iv, template[i].iv, MAX_IVLEN);
507da7f033dSHerbert Xu 			else
508da7f033dSHerbert Xu 				memset(iv, 0, MAX_IVLEN);
509da7f033dSHerbert Xu 
510da7f033dSHerbert Xu 			crypto_aead_clear_flags(tfm, ~0);
511da7f033dSHerbert Xu 			if (template[i].wk)
512da7f033dSHerbert Xu 				crypto_aead_set_flags(
513da7f033dSHerbert Xu 					tfm, CRYPTO_TFM_REQ_WEAK_KEY);
514da7f033dSHerbert Xu 			key = template[i].key;
515da7f033dSHerbert Xu 
516da7f033dSHerbert Xu 			ret = crypto_aead_setkey(tfm, key, template[i].klen);
517da7f033dSHerbert Xu 			if (!ret == template[i].fail) {
518da7f033dSHerbert Xu 				printk(KERN_ERR "alg: aead: setkey failed on "
519da7f033dSHerbert Xu 				       "chunk test %d for %s: flags=%x\n", j,
520da7f033dSHerbert Xu 				       algo, crypto_aead_get_flags(tfm));
521da7f033dSHerbert Xu 				goto out;
522da7f033dSHerbert Xu 			} else if (ret)
523da7f033dSHerbert Xu 				continue;
524da7f033dSHerbert Xu 
525da7f033dSHerbert Xu 			authsize = abs(template[i].rlen - template[i].ilen);
526da7f033dSHerbert Xu 
527da7f033dSHerbert Xu 			ret = -EINVAL;
528da7f033dSHerbert Xu 			sg_init_table(sg, template[i].np);
529da7f033dSHerbert Xu 			for (k = 0, temp = 0; k < template[i].np; k++) {
530da7f033dSHerbert Xu 				if (WARN_ON(offset_in_page(IDX[k]) +
531da7f033dSHerbert Xu 					    template[i].tap[k] > PAGE_SIZE))
532da7f033dSHerbert Xu 					goto out;
533da7f033dSHerbert Xu 
534da7f033dSHerbert Xu 				q = xbuf[IDX[k] >> PAGE_SHIFT] +
535da7f033dSHerbert Xu 				    offset_in_page(IDX[k]);
536da7f033dSHerbert Xu 
537da7f033dSHerbert Xu 				memcpy(q, template[i].input + temp,
538da7f033dSHerbert Xu 				       template[i].tap[k]);
539da7f033dSHerbert Xu 
540da7f033dSHerbert Xu 				n = template[i].tap[k];
541da7f033dSHerbert Xu 				if (k == template[i].np - 1 && enc)
542da7f033dSHerbert Xu 					n += authsize;
543da7f033dSHerbert Xu 				if (offset_in_page(q) + n < PAGE_SIZE)
544da7f033dSHerbert Xu 					q[n] = 0;
545da7f033dSHerbert Xu 
546da7f033dSHerbert Xu 				sg_set_buf(&sg[k], q, template[i].tap[k]);
547da7f033dSHerbert Xu 				temp += template[i].tap[k];
548da7f033dSHerbert Xu 			}
549da7f033dSHerbert Xu 
550da7f033dSHerbert Xu 			ret = crypto_aead_setauthsize(tfm, authsize);
551da7f033dSHerbert Xu 			if (ret) {
552da7f033dSHerbert Xu 				printk(KERN_ERR "alg: aead: Failed to set "
553da7f033dSHerbert Xu 				       "authsize to %u on chunk test %d for "
554da7f033dSHerbert Xu 				       "%s\n", authsize, j, algo);
555da7f033dSHerbert Xu 				goto out;
556da7f033dSHerbert Xu 			}
557da7f033dSHerbert Xu 
558da7f033dSHerbert Xu 			if (enc) {
559da7f033dSHerbert Xu 				if (WARN_ON(sg[k - 1].offset +
560da7f033dSHerbert Xu 					    sg[k - 1].length + authsize >
561da7f033dSHerbert Xu 					    PAGE_SIZE)) {
562da7f033dSHerbert Xu 					ret = -EINVAL;
563da7f033dSHerbert Xu 					goto out;
564da7f033dSHerbert Xu 				}
565da7f033dSHerbert Xu 
566da7f033dSHerbert Xu 				sg[k - 1].length += authsize;
567da7f033dSHerbert Xu 			}
568da7f033dSHerbert Xu 
569da7f033dSHerbert Xu 			sg_init_table(asg, template[i].anp);
570fd57f22aSHerbert Xu 			ret = -EINVAL;
571da7f033dSHerbert Xu 			for (k = 0, temp = 0; k < template[i].anp; k++) {
572fd57f22aSHerbert Xu 				if (WARN_ON(offset_in_page(IDX[k]) +
573fd57f22aSHerbert Xu 					    template[i].atap[k] > PAGE_SIZE))
574fd57f22aSHerbert Xu 					goto out;
575da7f033dSHerbert Xu 				sg_set_buf(&asg[k],
576da7f033dSHerbert Xu 					   memcpy(axbuf[IDX[k] >> PAGE_SHIFT] +
577da7f033dSHerbert Xu 						  offset_in_page(IDX[k]),
578da7f033dSHerbert Xu 						  template[i].assoc + temp,
579da7f033dSHerbert Xu 						  template[i].atap[k]),
580da7f033dSHerbert Xu 					   template[i].atap[k]);
581da7f033dSHerbert Xu 				temp += template[i].atap[k];
582da7f033dSHerbert Xu 			}
583da7f033dSHerbert Xu 
584da7f033dSHerbert Xu 			aead_request_set_crypt(req, sg, sg,
585da7f033dSHerbert Xu 					       template[i].ilen,
586da7f033dSHerbert Xu 					       iv);
587da7f033dSHerbert Xu 
588da7f033dSHerbert Xu 			aead_request_set_assoc(req, asg, template[i].alen);
589da7f033dSHerbert Xu 
590da7f033dSHerbert Xu 			ret = enc ?
591da7f033dSHerbert Xu 				crypto_aead_encrypt(req) :
592da7f033dSHerbert Xu 				crypto_aead_decrypt(req);
593da7f033dSHerbert Xu 
594da7f033dSHerbert Xu 			switch (ret) {
595da7f033dSHerbert Xu 			case 0:
596e44a1b44SJarod Wilson 				if (template[i].novrfy) {
597e44a1b44SJarod Wilson 					/* verification was supposed to fail */
598e44a1b44SJarod Wilson 					printk(KERN_ERR "alg: aead: %s failed "
599e44a1b44SJarod Wilson 					       "on chunk test %d for %s: ret "
600e44a1b44SJarod Wilson 					       "was 0, expected -EBADMSG\n",
601e44a1b44SJarod Wilson 					       e, j, algo);
602e44a1b44SJarod Wilson 					/* so really, we got a bad message */
603e44a1b44SJarod Wilson 					ret = -EBADMSG;
604e44a1b44SJarod Wilson 					goto out;
605e44a1b44SJarod Wilson 				}
606da7f033dSHerbert Xu 				break;
607da7f033dSHerbert Xu 			case -EINPROGRESS:
608da7f033dSHerbert Xu 			case -EBUSY:
609da7f033dSHerbert Xu 				ret = wait_for_completion_interruptible(
610da7f033dSHerbert Xu 					&result.completion);
611da7f033dSHerbert Xu 				if (!ret && !(ret = result.err)) {
612da7f033dSHerbert Xu 					INIT_COMPLETION(result.completion);
613da7f033dSHerbert Xu 					break;
614da7f033dSHerbert Xu 				}
615e44a1b44SJarod Wilson 			case -EBADMSG:
616e44a1b44SJarod Wilson 				if (template[i].novrfy)
617e44a1b44SJarod Wilson 					/* verification failure was expected */
618e44a1b44SJarod Wilson 					continue;
619da7f033dSHerbert Xu 				/* fall through */
620da7f033dSHerbert Xu 			default:
621da7f033dSHerbert Xu 				printk(KERN_ERR "alg: aead: %s failed on "
622da7f033dSHerbert Xu 				       "chunk test %d for %s: ret=%d\n", e, j,
623da7f033dSHerbert Xu 				       algo, -ret);
624da7f033dSHerbert Xu 				goto out;
625da7f033dSHerbert Xu 			}
626da7f033dSHerbert Xu 
627da7f033dSHerbert Xu 			ret = -EINVAL;
628da7f033dSHerbert Xu 			for (k = 0, temp = 0; k < template[i].np; k++) {
629da7f033dSHerbert Xu 				q = xbuf[IDX[k] >> PAGE_SHIFT] +
630da7f033dSHerbert Xu 				    offset_in_page(IDX[k]);
631da7f033dSHerbert Xu 
632da7f033dSHerbert Xu 				n = template[i].tap[k];
633da7f033dSHerbert Xu 				if (k == template[i].np - 1)
634da7f033dSHerbert Xu 					n += enc ? authsize : -authsize;
635da7f033dSHerbert Xu 
636da7f033dSHerbert Xu 				if (memcmp(q, template[i].result + temp, n)) {
637da7f033dSHerbert Xu 					printk(KERN_ERR "alg: aead: Chunk "
638da7f033dSHerbert Xu 					       "test %d failed on %s at page "
639da7f033dSHerbert Xu 					       "%u for %s\n", j, e, k, algo);
640da7f033dSHerbert Xu 					hexdump(q, n);
641da7f033dSHerbert Xu 					goto out;
642da7f033dSHerbert Xu 				}
643da7f033dSHerbert Xu 
644da7f033dSHerbert Xu 				q += n;
645da7f033dSHerbert Xu 				if (k == template[i].np - 1 && !enc) {
646da7f033dSHerbert Xu 					if (memcmp(q, template[i].input +
647da7f033dSHerbert Xu 						      temp + n, authsize))
648da7f033dSHerbert Xu 						n = authsize;
649da7f033dSHerbert Xu 					else
650da7f033dSHerbert Xu 						n = 0;
651da7f033dSHerbert Xu 				} else {
652da7f033dSHerbert Xu 					for (n = 0; offset_in_page(q + n) &&
653da7f033dSHerbert Xu 						    q[n]; n++)
654da7f033dSHerbert Xu 						;
655da7f033dSHerbert Xu 				}
656da7f033dSHerbert Xu 				if (n) {
657da7f033dSHerbert Xu 					printk(KERN_ERR "alg: aead: Result "
658da7f033dSHerbert Xu 					       "buffer corruption in chunk "
659da7f033dSHerbert Xu 					       "test %d on %s at page %u for "
660da7f033dSHerbert Xu 					       "%s: %u bytes:\n", j, e, k,
661da7f033dSHerbert Xu 					       algo, n);
662da7f033dSHerbert Xu 					hexdump(q, n);
663da7f033dSHerbert Xu 					goto out;
664da7f033dSHerbert Xu 				}
665da7f033dSHerbert Xu 
666da7f033dSHerbert Xu 				temp += template[i].tap[k];
667da7f033dSHerbert Xu 			}
668da7f033dSHerbert Xu 		}
669da7f033dSHerbert Xu 	}
670da7f033dSHerbert Xu 
671da7f033dSHerbert Xu 	ret = 0;
672da7f033dSHerbert Xu 
673da7f033dSHerbert Xu out:
674da7f033dSHerbert Xu 	aead_request_free(req);
675f8b0d4d0SHerbert Xu 	testmgr_free_buf(axbuf);
676f8b0d4d0SHerbert Xu out_noaxbuf:
677f8b0d4d0SHerbert Xu 	testmgr_free_buf(xbuf);
678f8b0d4d0SHerbert Xu out_noxbuf:
679da7f033dSHerbert Xu 	return ret;
680da7f033dSHerbert Xu }
681da7f033dSHerbert Xu 
6821aa4ecd9SHerbert Xu static int test_cipher(struct crypto_cipher *tfm, int enc,
6831aa4ecd9SHerbert Xu 		       struct cipher_testvec *template, unsigned int tcount)
6841aa4ecd9SHerbert Xu {
6851aa4ecd9SHerbert Xu 	const char *algo = crypto_tfm_alg_driver_name(crypto_cipher_tfm(tfm));
6861aa4ecd9SHerbert Xu 	unsigned int i, j, k;
6871aa4ecd9SHerbert Xu 	char *q;
6881aa4ecd9SHerbert Xu 	const char *e;
6891aa4ecd9SHerbert Xu 	void *data;
690f8b0d4d0SHerbert Xu 	char *xbuf[XBUFSIZE];
691f8b0d4d0SHerbert Xu 	int ret = -ENOMEM;
692f8b0d4d0SHerbert Xu 
693f8b0d4d0SHerbert Xu 	if (testmgr_alloc_buf(xbuf))
694f8b0d4d0SHerbert Xu 		goto out_nobuf;
6951aa4ecd9SHerbert Xu 
6961aa4ecd9SHerbert Xu 	if (enc == ENCRYPT)
6971aa4ecd9SHerbert Xu 	        e = "encryption";
6981aa4ecd9SHerbert Xu 	else
6991aa4ecd9SHerbert Xu 		e = "decryption";
7001aa4ecd9SHerbert Xu 
7011aa4ecd9SHerbert Xu 	j = 0;
7021aa4ecd9SHerbert Xu 	for (i = 0; i < tcount; i++) {
7031aa4ecd9SHerbert Xu 		if (template[i].np)
7041aa4ecd9SHerbert Xu 			continue;
7051aa4ecd9SHerbert Xu 
7061aa4ecd9SHerbert Xu 		j++;
7071aa4ecd9SHerbert Xu 
708fd57f22aSHerbert Xu 		ret = -EINVAL;
709fd57f22aSHerbert Xu 		if (WARN_ON(template[i].ilen > PAGE_SIZE))
710fd57f22aSHerbert Xu 			goto out;
711fd57f22aSHerbert Xu 
7121aa4ecd9SHerbert Xu 		data = xbuf[0];
7131aa4ecd9SHerbert Xu 		memcpy(data, template[i].input, template[i].ilen);
7141aa4ecd9SHerbert Xu 
7151aa4ecd9SHerbert Xu 		crypto_cipher_clear_flags(tfm, ~0);
7161aa4ecd9SHerbert Xu 		if (template[i].wk)
7171aa4ecd9SHerbert Xu 			crypto_cipher_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY);
7181aa4ecd9SHerbert Xu 
7191aa4ecd9SHerbert Xu 		ret = crypto_cipher_setkey(tfm, template[i].key,
7201aa4ecd9SHerbert Xu 					   template[i].klen);
7211aa4ecd9SHerbert Xu 		if (!ret == template[i].fail) {
7221aa4ecd9SHerbert Xu 			printk(KERN_ERR "alg: cipher: setkey failed "
7231aa4ecd9SHerbert Xu 			       "on test %d for %s: flags=%x\n", j,
7241aa4ecd9SHerbert Xu 			       algo, crypto_cipher_get_flags(tfm));
7251aa4ecd9SHerbert Xu 			goto out;
7261aa4ecd9SHerbert Xu 		} else if (ret)
7271aa4ecd9SHerbert Xu 			continue;
7281aa4ecd9SHerbert Xu 
7291aa4ecd9SHerbert Xu 		for (k = 0; k < template[i].ilen;
7301aa4ecd9SHerbert Xu 		     k += crypto_cipher_blocksize(tfm)) {
7311aa4ecd9SHerbert Xu 			if (enc)
7321aa4ecd9SHerbert Xu 				crypto_cipher_encrypt_one(tfm, data + k,
7331aa4ecd9SHerbert Xu 							  data + k);
7341aa4ecd9SHerbert Xu 			else
7351aa4ecd9SHerbert Xu 				crypto_cipher_decrypt_one(tfm, data + k,
7361aa4ecd9SHerbert Xu 							  data + k);
7371aa4ecd9SHerbert Xu 		}
7381aa4ecd9SHerbert Xu 
7391aa4ecd9SHerbert Xu 		q = data;
7401aa4ecd9SHerbert Xu 		if (memcmp(q, template[i].result, template[i].rlen)) {
7411aa4ecd9SHerbert Xu 			printk(KERN_ERR "alg: cipher: Test %d failed "
7421aa4ecd9SHerbert Xu 			       "on %s for %s\n", j, e, algo);
7431aa4ecd9SHerbert Xu 			hexdump(q, template[i].rlen);
7441aa4ecd9SHerbert Xu 			ret = -EINVAL;
7451aa4ecd9SHerbert Xu 			goto out;
7461aa4ecd9SHerbert Xu 		}
7471aa4ecd9SHerbert Xu 	}
7481aa4ecd9SHerbert Xu 
7491aa4ecd9SHerbert Xu 	ret = 0;
7501aa4ecd9SHerbert Xu 
7511aa4ecd9SHerbert Xu out:
752f8b0d4d0SHerbert Xu 	testmgr_free_buf(xbuf);
753f8b0d4d0SHerbert Xu out_nobuf:
7541aa4ecd9SHerbert Xu 	return ret;
7551aa4ecd9SHerbert Xu }
7561aa4ecd9SHerbert Xu 
7571aa4ecd9SHerbert Xu static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
758da7f033dSHerbert Xu 			 struct cipher_testvec *template, unsigned int tcount)
759da7f033dSHerbert Xu {
760da7f033dSHerbert Xu 	const char *algo =
761da7f033dSHerbert Xu 		crypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm));
762da7f033dSHerbert Xu 	unsigned int i, j, k, n, temp;
763da7f033dSHerbert Xu 	char *q;
764da7f033dSHerbert Xu 	struct ablkcipher_request *req;
765da7f033dSHerbert Xu 	struct scatterlist sg[8];
766da7f033dSHerbert Xu 	const char *e;
767da7f033dSHerbert Xu 	struct tcrypt_result result;
768da7f033dSHerbert Xu 	void *data;
769da7f033dSHerbert Xu 	char iv[MAX_IVLEN];
770f8b0d4d0SHerbert Xu 	char *xbuf[XBUFSIZE];
771f8b0d4d0SHerbert Xu 	int ret = -ENOMEM;
772f8b0d4d0SHerbert Xu 
773f8b0d4d0SHerbert Xu 	if (testmgr_alloc_buf(xbuf))
774f8b0d4d0SHerbert Xu 		goto out_nobuf;
775da7f033dSHerbert Xu 
776da7f033dSHerbert Xu 	if (enc == ENCRYPT)
777da7f033dSHerbert Xu 	        e = "encryption";
778da7f033dSHerbert Xu 	else
779da7f033dSHerbert Xu 		e = "decryption";
780da7f033dSHerbert Xu 
781da7f033dSHerbert Xu 	init_completion(&result.completion);
782da7f033dSHerbert Xu 
783da7f033dSHerbert Xu 	req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
784da7f033dSHerbert Xu 	if (!req) {
7851aa4ecd9SHerbert Xu 		printk(KERN_ERR "alg: skcipher: Failed to allocate request "
7861aa4ecd9SHerbert Xu 		       "for %s\n", algo);
787da7f033dSHerbert Xu 		goto out;
788da7f033dSHerbert Xu 	}
789da7f033dSHerbert Xu 
790da7f033dSHerbert Xu 	ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
791da7f033dSHerbert Xu 					tcrypt_complete, &result);
792da7f033dSHerbert Xu 
793da7f033dSHerbert Xu 	j = 0;
794da7f033dSHerbert Xu 	for (i = 0; i < tcount; i++) {
795da7f033dSHerbert Xu 		if (template[i].iv)
796da7f033dSHerbert Xu 			memcpy(iv, template[i].iv, MAX_IVLEN);
797da7f033dSHerbert Xu 		else
798da7f033dSHerbert Xu 			memset(iv, 0, MAX_IVLEN);
799da7f033dSHerbert Xu 
800da7f033dSHerbert Xu 		if (!(template[i].np)) {
801da7f033dSHerbert Xu 			j++;
802da7f033dSHerbert Xu 
803fd57f22aSHerbert Xu 			ret = -EINVAL;
804fd57f22aSHerbert Xu 			if (WARN_ON(template[i].ilen > PAGE_SIZE))
805fd57f22aSHerbert Xu 				goto out;
806fd57f22aSHerbert Xu 
807da7f033dSHerbert Xu 			data = xbuf[0];
808da7f033dSHerbert Xu 			memcpy(data, template[i].input, template[i].ilen);
809da7f033dSHerbert Xu 
810da7f033dSHerbert Xu 			crypto_ablkcipher_clear_flags(tfm, ~0);
811da7f033dSHerbert Xu 			if (template[i].wk)
812da7f033dSHerbert Xu 				crypto_ablkcipher_set_flags(
813da7f033dSHerbert Xu 					tfm, CRYPTO_TFM_REQ_WEAK_KEY);
814da7f033dSHerbert Xu 
815da7f033dSHerbert Xu 			ret = crypto_ablkcipher_setkey(tfm, template[i].key,
816da7f033dSHerbert Xu 						       template[i].klen);
817da7f033dSHerbert Xu 			if (!ret == template[i].fail) {
8181aa4ecd9SHerbert Xu 				printk(KERN_ERR "alg: skcipher: setkey failed "
819da7f033dSHerbert Xu 				       "on test %d for %s: flags=%x\n", j,
820da7f033dSHerbert Xu 				       algo, crypto_ablkcipher_get_flags(tfm));
821da7f033dSHerbert Xu 				goto out;
822da7f033dSHerbert Xu 			} else if (ret)
823da7f033dSHerbert Xu 				continue;
824da7f033dSHerbert Xu 
825da7f033dSHerbert Xu 			sg_init_one(&sg[0], data, template[i].ilen);
826da7f033dSHerbert Xu 
827da7f033dSHerbert Xu 			ablkcipher_request_set_crypt(req, sg, sg,
828da7f033dSHerbert Xu 						     template[i].ilen, iv);
829da7f033dSHerbert Xu 			ret = enc ?
830da7f033dSHerbert Xu 				crypto_ablkcipher_encrypt(req) :
831da7f033dSHerbert Xu 				crypto_ablkcipher_decrypt(req);
832da7f033dSHerbert Xu 
833da7f033dSHerbert Xu 			switch (ret) {
834da7f033dSHerbert Xu 			case 0:
835da7f033dSHerbert Xu 				break;
836da7f033dSHerbert Xu 			case -EINPROGRESS:
837da7f033dSHerbert Xu 			case -EBUSY:
838da7f033dSHerbert Xu 				ret = wait_for_completion_interruptible(
839da7f033dSHerbert Xu 					&result.completion);
840da7f033dSHerbert Xu 				if (!ret && !((ret = result.err))) {
841da7f033dSHerbert Xu 					INIT_COMPLETION(result.completion);
842da7f033dSHerbert Xu 					break;
843da7f033dSHerbert Xu 				}
844da7f033dSHerbert Xu 				/* fall through */
845da7f033dSHerbert Xu 			default:
8461aa4ecd9SHerbert Xu 				printk(KERN_ERR "alg: skcipher: %s failed on "
847da7f033dSHerbert Xu 				       "test %d for %s: ret=%d\n", e, j, algo,
848da7f033dSHerbert Xu 				       -ret);
849da7f033dSHerbert Xu 				goto out;
850da7f033dSHerbert Xu 			}
851da7f033dSHerbert Xu 
852da7f033dSHerbert Xu 			q = data;
853da7f033dSHerbert Xu 			if (memcmp(q, template[i].result, template[i].rlen)) {
8541aa4ecd9SHerbert Xu 				printk(KERN_ERR "alg: skcipher: Test %d "
8551aa4ecd9SHerbert Xu 				       "failed on %s for %s\n", j, e, algo);
856da7f033dSHerbert Xu 				hexdump(q, template[i].rlen);
857da7f033dSHerbert Xu 				ret = -EINVAL;
858da7f033dSHerbert Xu 				goto out;
859da7f033dSHerbert Xu 			}
860da7f033dSHerbert Xu 		}
861da7f033dSHerbert Xu 	}
862da7f033dSHerbert Xu 
863da7f033dSHerbert Xu 	j = 0;
864da7f033dSHerbert Xu 	for (i = 0; i < tcount; i++) {
865da7f033dSHerbert Xu 
866da7f033dSHerbert Xu 		if (template[i].iv)
867da7f033dSHerbert Xu 			memcpy(iv, template[i].iv, MAX_IVLEN);
868da7f033dSHerbert Xu 		else
869da7f033dSHerbert Xu 			memset(iv, 0, MAX_IVLEN);
870da7f033dSHerbert Xu 
871da7f033dSHerbert Xu 		if (template[i].np) {
872da7f033dSHerbert Xu 			j++;
873da7f033dSHerbert Xu 
874da7f033dSHerbert Xu 			crypto_ablkcipher_clear_flags(tfm, ~0);
875da7f033dSHerbert Xu 			if (template[i].wk)
876da7f033dSHerbert Xu 				crypto_ablkcipher_set_flags(
877da7f033dSHerbert Xu 					tfm, CRYPTO_TFM_REQ_WEAK_KEY);
878da7f033dSHerbert Xu 
879da7f033dSHerbert Xu 			ret = crypto_ablkcipher_setkey(tfm, template[i].key,
880da7f033dSHerbert Xu 						       template[i].klen);
881da7f033dSHerbert Xu 			if (!ret == template[i].fail) {
8821aa4ecd9SHerbert Xu 				printk(KERN_ERR "alg: skcipher: setkey failed "
883da7f033dSHerbert Xu 				       "on chunk test %d for %s: flags=%x\n",
884da7f033dSHerbert Xu 				       j, algo,
885da7f033dSHerbert Xu 				       crypto_ablkcipher_get_flags(tfm));
886da7f033dSHerbert Xu 				goto out;
887da7f033dSHerbert Xu 			} else if (ret)
888da7f033dSHerbert Xu 				continue;
889da7f033dSHerbert Xu 
890da7f033dSHerbert Xu 			temp = 0;
891da7f033dSHerbert Xu 			ret = -EINVAL;
892da7f033dSHerbert Xu 			sg_init_table(sg, template[i].np);
893da7f033dSHerbert Xu 			for (k = 0; k < template[i].np; k++) {
894da7f033dSHerbert Xu 				if (WARN_ON(offset_in_page(IDX[k]) +
895da7f033dSHerbert Xu 					    template[i].tap[k] > PAGE_SIZE))
896da7f033dSHerbert Xu 					goto out;
897da7f033dSHerbert Xu 
898da7f033dSHerbert Xu 				q = xbuf[IDX[k] >> PAGE_SHIFT] +
899da7f033dSHerbert Xu 				    offset_in_page(IDX[k]);
900da7f033dSHerbert Xu 
901da7f033dSHerbert Xu 				memcpy(q, template[i].input + temp,
902da7f033dSHerbert Xu 				       template[i].tap[k]);
903da7f033dSHerbert Xu 
904da7f033dSHerbert Xu 				if (offset_in_page(q) + template[i].tap[k] <
905da7f033dSHerbert Xu 				    PAGE_SIZE)
906da7f033dSHerbert Xu 					q[template[i].tap[k]] = 0;
907da7f033dSHerbert Xu 
908da7f033dSHerbert Xu 				sg_set_buf(&sg[k], q, template[i].tap[k]);
909da7f033dSHerbert Xu 
910da7f033dSHerbert Xu 				temp += template[i].tap[k];
911da7f033dSHerbert Xu 			}
912da7f033dSHerbert Xu 
913da7f033dSHerbert Xu 			ablkcipher_request_set_crypt(req, sg, sg,
914da7f033dSHerbert Xu 					template[i].ilen, iv);
915da7f033dSHerbert Xu 
916da7f033dSHerbert Xu 			ret = enc ?
917da7f033dSHerbert Xu 				crypto_ablkcipher_encrypt(req) :
918da7f033dSHerbert Xu 				crypto_ablkcipher_decrypt(req);
919da7f033dSHerbert Xu 
920da7f033dSHerbert Xu 			switch (ret) {
921da7f033dSHerbert Xu 			case 0:
922da7f033dSHerbert Xu 				break;
923da7f033dSHerbert Xu 			case -EINPROGRESS:
924da7f033dSHerbert Xu 			case -EBUSY:
925da7f033dSHerbert Xu 				ret = wait_for_completion_interruptible(
926da7f033dSHerbert Xu 					&result.completion);
927da7f033dSHerbert Xu 				if (!ret && !((ret = result.err))) {
928da7f033dSHerbert Xu 					INIT_COMPLETION(result.completion);
929da7f033dSHerbert Xu 					break;
930da7f033dSHerbert Xu 				}
931da7f033dSHerbert Xu 				/* fall through */
932da7f033dSHerbert Xu 			default:
9331aa4ecd9SHerbert Xu 				printk(KERN_ERR "alg: skcipher: %s failed on "
934da7f033dSHerbert Xu 				       "chunk test %d for %s: ret=%d\n", e, j,
935da7f033dSHerbert Xu 				       algo, -ret);
936da7f033dSHerbert Xu 				goto out;
937da7f033dSHerbert Xu 			}
938da7f033dSHerbert Xu 
939da7f033dSHerbert Xu 			temp = 0;
940da7f033dSHerbert Xu 			ret = -EINVAL;
941da7f033dSHerbert Xu 			for (k = 0; k < template[i].np; k++) {
942da7f033dSHerbert Xu 				q = xbuf[IDX[k] >> PAGE_SHIFT] +
943da7f033dSHerbert Xu 				    offset_in_page(IDX[k]);
944da7f033dSHerbert Xu 
945da7f033dSHerbert Xu 				if (memcmp(q, template[i].result + temp,
946da7f033dSHerbert Xu 					   template[i].tap[k])) {
9471aa4ecd9SHerbert Xu 					printk(KERN_ERR "alg: skcipher: Chunk "
948da7f033dSHerbert Xu 					       "test %d failed on %s at page "
949da7f033dSHerbert Xu 					       "%u for %s\n", j, e, k, algo);
950da7f033dSHerbert Xu 					hexdump(q, template[i].tap[k]);
951da7f033dSHerbert Xu 					goto out;
952da7f033dSHerbert Xu 				}
953da7f033dSHerbert Xu 
954da7f033dSHerbert Xu 				q += template[i].tap[k];
955da7f033dSHerbert Xu 				for (n = 0; offset_in_page(q + n) && q[n]; n++)
956da7f033dSHerbert Xu 					;
957da7f033dSHerbert Xu 				if (n) {
9581aa4ecd9SHerbert Xu 					printk(KERN_ERR "alg: skcipher: "
959da7f033dSHerbert Xu 					       "Result buffer corruption in "
960da7f033dSHerbert Xu 					       "chunk test %d on %s at page "
961da7f033dSHerbert Xu 					       "%u for %s: %u bytes:\n", j, e,
962da7f033dSHerbert Xu 					       k, algo, n);
963da7f033dSHerbert Xu 					hexdump(q, n);
964da7f033dSHerbert Xu 					goto out;
965da7f033dSHerbert Xu 				}
966da7f033dSHerbert Xu 				temp += template[i].tap[k];
967da7f033dSHerbert Xu 			}
968da7f033dSHerbert Xu 		}
969da7f033dSHerbert Xu 	}
970da7f033dSHerbert Xu 
971da7f033dSHerbert Xu 	ret = 0;
972da7f033dSHerbert Xu 
973da7f033dSHerbert Xu out:
974da7f033dSHerbert Xu 	ablkcipher_request_free(req);
975f8b0d4d0SHerbert Xu 	testmgr_free_buf(xbuf);
976f8b0d4d0SHerbert Xu out_nobuf:
977da7f033dSHerbert Xu 	return ret;
978da7f033dSHerbert Xu }
979da7f033dSHerbert Xu 
980da7f033dSHerbert Xu static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate,
981da7f033dSHerbert Xu 		     struct comp_testvec *dtemplate, int ctcount, int dtcount)
982da7f033dSHerbert Xu {
983da7f033dSHerbert Xu 	const char *algo = crypto_tfm_alg_driver_name(crypto_comp_tfm(tfm));
984da7f033dSHerbert Xu 	unsigned int i;
985da7f033dSHerbert Xu 	char result[COMP_BUF_SIZE];
986da7f033dSHerbert Xu 	int ret;
987da7f033dSHerbert Xu 
988da7f033dSHerbert Xu 	for (i = 0; i < ctcount; i++) {
989c79cf910SGeert Uytterhoeven 		int ilen;
990c79cf910SGeert Uytterhoeven 		unsigned int dlen = COMP_BUF_SIZE;
991da7f033dSHerbert Xu 
992da7f033dSHerbert Xu 		memset(result, 0, sizeof (result));
993da7f033dSHerbert Xu 
994da7f033dSHerbert Xu 		ilen = ctemplate[i].inlen;
995da7f033dSHerbert Xu 		ret = crypto_comp_compress(tfm, ctemplate[i].input,
996da7f033dSHerbert Xu 		                           ilen, result, &dlen);
997da7f033dSHerbert Xu 		if (ret) {
998da7f033dSHerbert Xu 			printk(KERN_ERR "alg: comp: compression failed "
999da7f033dSHerbert Xu 			       "on test %d for %s: ret=%d\n", i + 1, algo,
1000da7f033dSHerbert Xu 			       -ret);
1001da7f033dSHerbert Xu 			goto out;
1002da7f033dSHerbert Xu 		}
1003da7f033dSHerbert Xu 
1004b812eb00SGeert Uytterhoeven 		if (dlen != ctemplate[i].outlen) {
1005b812eb00SGeert Uytterhoeven 			printk(KERN_ERR "alg: comp: Compression test %d "
1006b812eb00SGeert Uytterhoeven 			       "failed for %s: output len = %d\n", i + 1, algo,
1007b812eb00SGeert Uytterhoeven 			       dlen);
1008b812eb00SGeert Uytterhoeven 			ret = -EINVAL;
1009b812eb00SGeert Uytterhoeven 			goto out;
1010b812eb00SGeert Uytterhoeven 		}
1011b812eb00SGeert Uytterhoeven 
1012da7f033dSHerbert Xu 		if (memcmp(result, ctemplate[i].output, dlen)) {
1013da7f033dSHerbert Xu 			printk(KERN_ERR "alg: comp: Compression test %d "
1014da7f033dSHerbert Xu 			       "failed for %s\n", i + 1, algo);
1015da7f033dSHerbert Xu 			hexdump(result, dlen);
1016da7f033dSHerbert Xu 			ret = -EINVAL;
1017da7f033dSHerbert Xu 			goto out;
1018da7f033dSHerbert Xu 		}
1019da7f033dSHerbert Xu 	}
1020da7f033dSHerbert Xu 
1021da7f033dSHerbert Xu 	for (i = 0; i < dtcount; i++) {
1022c79cf910SGeert Uytterhoeven 		int ilen;
1023c79cf910SGeert Uytterhoeven 		unsigned int dlen = COMP_BUF_SIZE;
1024da7f033dSHerbert Xu 
1025da7f033dSHerbert Xu 		memset(result, 0, sizeof (result));
1026da7f033dSHerbert Xu 
1027da7f033dSHerbert Xu 		ilen = dtemplate[i].inlen;
1028da7f033dSHerbert Xu 		ret = crypto_comp_decompress(tfm, dtemplate[i].input,
1029da7f033dSHerbert Xu 		                             ilen, result, &dlen);
1030da7f033dSHerbert Xu 		if (ret) {
1031da7f033dSHerbert Xu 			printk(KERN_ERR "alg: comp: decompression failed "
1032da7f033dSHerbert Xu 			       "on test %d for %s: ret=%d\n", i + 1, algo,
1033da7f033dSHerbert Xu 			       -ret);
1034da7f033dSHerbert Xu 			goto out;
1035da7f033dSHerbert Xu 		}
1036da7f033dSHerbert Xu 
1037b812eb00SGeert Uytterhoeven 		if (dlen != dtemplate[i].outlen) {
1038b812eb00SGeert Uytterhoeven 			printk(KERN_ERR "alg: comp: Decompression test %d "
1039b812eb00SGeert Uytterhoeven 			       "failed for %s: output len = %d\n", i + 1, algo,
1040b812eb00SGeert Uytterhoeven 			       dlen);
1041b812eb00SGeert Uytterhoeven 			ret = -EINVAL;
1042b812eb00SGeert Uytterhoeven 			goto out;
1043b812eb00SGeert Uytterhoeven 		}
1044b812eb00SGeert Uytterhoeven 
1045da7f033dSHerbert Xu 		if (memcmp(result, dtemplate[i].output, dlen)) {
1046da7f033dSHerbert Xu 			printk(KERN_ERR "alg: comp: Decompression test %d "
1047da7f033dSHerbert Xu 			       "failed for %s\n", i + 1, algo);
1048da7f033dSHerbert Xu 			hexdump(result, dlen);
1049da7f033dSHerbert Xu 			ret = -EINVAL;
1050da7f033dSHerbert Xu 			goto out;
1051da7f033dSHerbert Xu 		}
1052da7f033dSHerbert Xu 	}
1053da7f033dSHerbert Xu 
1054da7f033dSHerbert Xu 	ret = 0;
1055da7f033dSHerbert Xu 
1056da7f033dSHerbert Xu out:
1057da7f033dSHerbert Xu 	return ret;
1058da7f033dSHerbert Xu }
1059da7f033dSHerbert Xu 
10608064efb8SGeert Uytterhoeven static int test_pcomp(struct crypto_pcomp *tfm,
10618064efb8SGeert Uytterhoeven 		      struct pcomp_testvec *ctemplate,
10628064efb8SGeert Uytterhoeven 		      struct pcomp_testvec *dtemplate, int ctcount,
10638064efb8SGeert Uytterhoeven 		      int dtcount)
10648064efb8SGeert Uytterhoeven {
10658064efb8SGeert Uytterhoeven 	const char *algo = crypto_tfm_alg_driver_name(crypto_pcomp_tfm(tfm));
10668064efb8SGeert Uytterhoeven 	unsigned int i;
10678064efb8SGeert Uytterhoeven 	char result[COMP_BUF_SIZE];
10683ce858cbSGeert Uytterhoeven 	int res;
10698064efb8SGeert Uytterhoeven 
10708064efb8SGeert Uytterhoeven 	for (i = 0; i < ctcount; i++) {
10718064efb8SGeert Uytterhoeven 		struct comp_request req;
10723ce858cbSGeert Uytterhoeven 		unsigned int produced = 0;
10738064efb8SGeert Uytterhoeven 
10743ce858cbSGeert Uytterhoeven 		res = crypto_compress_setup(tfm, ctemplate[i].params,
10758064efb8SGeert Uytterhoeven 					    ctemplate[i].paramsize);
10763ce858cbSGeert Uytterhoeven 		if (res) {
10778064efb8SGeert Uytterhoeven 			pr_err("alg: pcomp: compression setup failed on test "
10783ce858cbSGeert Uytterhoeven 			       "%d for %s: error=%d\n", i + 1, algo, res);
10793ce858cbSGeert Uytterhoeven 			return res;
10808064efb8SGeert Uytterhoeven 		}
10818064efb8SGeert Uytterhoeven 
10823ce858cbSGeert Uytterhoeven 		res = crypto_compress_init(tfm);
10833ce858cbSGeert Uytterhoeven 		if (res) {
10848064efb8SGeert Uytterhoeven 			pr_err("alg: pcomp: compression init failed on test "
10853ce858cbSGeert Uytterhoeven 			       "%d for %s: error=%d\n", i + 1, algo, res);
10863ce858cbSGeert Uytterhoeven 			return res;
10878064efb8SGeert Uytterhoeven 		}
10888064efb8SGeert Uytterhoeven 
10898064efb8SGeert Uytterhoeven 		memset(result, 0, sizeof(result));
10908064efb8SGeert Uytterhoeven 
10918064efb8SGeert Uytterhoeven 		req.next_in = ctemplate[i].input;
10928064efb8SGeert Uytterhoeven 		req.avail_in = ctemplate[i].inlen / 2;
10938064efb8SGeert Uytterhoeven 		req.next_out = result;
10948064efb8SGeert Uytterhoeven 		req.avail_out = ctemplate[i].outlen / 2;
10958064efb8SGeert Uytterhoeven 
10963ce858cbSGeert Uytterhoeven 		res = crypto_compress_update(tfm, &req);
10973ce858cbSGeert Uytterhoeven 		if (res < 0 && (res != -EAGAIN || req.avail_in)) {
10988064efb8SGeert Uytterhoeven 			pr_err("alg: pcomp: compression update failed on test "
10993ce858cbSGeert Uytterhoeven 			       "%d for %s: error=%d\n", i + 1, algo, res);
11003ce858cbSGeert Uytterhoeven 			return res;
11018064efb8SGeert Uytterhoeven 		}
11023ce858cbSGeert Uytterhoeven 		if (res > 0)
11033ce858cbSGeert Uytterhoeven 			produced += res;
11048064efb8SGeert Uytterhoeven 
11058064efb8SGeert Uytterhoeven 		/* Add remaining input data */
11068064efb8SGeert Uytterhoeven 		req.avail_in += (ctemplate[i].inlen + 1) / 2;
11078064efb8SGeert Uytterhoeven 
11083ce858cbSGeert Uytterhoeven 		res = crypto_compress_update(tfm, &req);
11093ce858cbSGeert Uytterhoeven 		if (res < 0 && (res != -EAGAIN || req.avail_in)) {
11108064efb8SGeert Uytterhoeven 			pr_err("alg: pcomp: compression update failed on test "
11113ce858cbSGeert Uytterhoeven 			       "%d for %s: error=%d\n", i + 1, algo, res);
11123ce858cbSGeert Uytterhoeven 			return res;
11138064efb8SGeert Uytterhoeven 		}
11143ce858cbSGeert Uytterhoeven 		if (res > 0)
11153ce858cbSGeert Uytterhoeven 			produced += res;
11168064efb8SGeert Uytterhoeven 
11178064efb8SGeert Uytterhoeven 		/* Provide remaining output space */
11188064efb8SGeert Uytterhoeven 		req.avail_out += COMP_BUF_SIZE - ctemplate[i].outlen / 2;
11198064efb8SGeert Uytterhoeven 
11203ce858cbSGeert Uytterhoeven 		res = crypto_compress_final(tfm, &req);
11213ce858cbSGeert Uytterhoeven 		if (res < 0) {
11228064efb8SGeert Uytterhoeven 			pr_err("alg: pcomp: compression final failed on test "
11233ce858cbSGeert Uytterhoeven 			       "%d for %s: error=%d\n", i + 1, algo, res);
11243ce858cbSGeert Uytterhoeven 			return res;
11258064efb8SGeert Uytterhoeven 		}
11263ce858cbSGeert Uytterhoeven 		produced += res;
11278064efb8SGeert Uytterhoeven 
11288064efb8SGeert Uytterhoeven 		if (COMP_BUF_SIZE - req.avail_out != ctemplate[i].outlen) {
11298064efb8SGeert Uytterhoeven 			pr_err("alg: comp: Compression test %d failed for %s: "
11308064efb8SGeert Uytterhoeven 			       "output len = %d (expected %d)\n", i + 1, algo,
11318064efb8SGeert Uytterhoeven 			       COMP_BUF_SIZE - req.avail_out,
11328064efb8SGeert Uytterhoeven 			       ctemplate[i].outlen);
11338064efb8SGeert Uytterhoeven 			return -EINVAL;
11348064efb8SGeert Uytterhoeven 		}
11358064efb8SGeert Uytterhoeven 
11363ce858cbSGeert Uytterhoeven 		if (produced != ctemplate[i].outlen) {
11373ce858cbSGeert Uytterhoeven 			pr_err("alg: comp: Compression test %d failed for %s: "
11383ce858cbSGeert Uytterhoeven 			       "returned len = %u (expected %d)\n", i + 1,
11393ce858cbSGeert Uytterhoeven 			       algo, produced, ctemplate[i].outlen);
11403ce858cbSGeert Uytterhoeven 			return -EINVAL;
11413ce858cbSGeert Uytterhoeven 		}
11423ce858cbSGeert Uytterhoeven 
11438064efb8SGeert Uytterhoeven 		if (memcmp(result, ctemplate[i].output, ctemplate[i].outlen)) {
11448064efb8SGeert Uytterhoeven 			pr_err("alg: pcomp: Compression test %d failed for "
11458064efb8SGeert Uytterhoeven 			       "%s\n", i + 1, algo);
11468064efb8SGeert Uytterhoeven 			hexdump(result, ctemplate[i].outlen);
11478064efb8SGeert Uytterhoeven 			return -EINVAL;
11488064efb8SGeert Uytterhoeven 		}
11498064efb8SGeert Uytterhoeven 	}
11508064efb8SGeert Uytterhoeven 
11518064efb8SGeert Uytterhoeven 	for (i = 0; i < dtcount; i++) {
11528064efb8SGeert Uytterhoeven 		struct comp_request req;
11533ce858cbSGeert Uytterhoeven 		unsigned int produced = 0;
11548064efb8SGeert Uytterhoeven 
11553ce858cbSGeert Uytterhoeven 		res = crypto_decompress_setup(tfm, dtemplate[i].params,
11568064efb8SGeert Uytterhoeven 					      dtemplate[i].paramsize);
11573ce858cbSGeert Uytterhoeven 		if (res) {
11588064efb8SGeert Uytterhoeven 			pr_err("alg: pcomp: decompression setup failed on "
11593ce858cbSGeert Uytterhoeven 			       "test %d for %s: error=%d\n", i + 1, algo, res);
11603ce858cbSGeert Uytterhoeven 			return res;
11618064efb8SGeert Uytterhoeven 		}
11628064efb8SGeert Uytterhoeven 
11633ce858cbSGeert Uytterhoeven 		res = crypto_decompress_init(tfm);
11643ce858cbSGeert Uytterhoeven 		if (res) {
11658064efb8SGeert Uytterhoeven 			pr_err("alg: pcomp: decompression init failed on test "
11663ce858cbSGeert Uytterhoeven 			       "%d for %s: error=%d\n", i + 1, algo, res);
11673ce858cbSGeert Uytterhoeven 			return res;
11688064efb8SGeert Uytterhoeven 		}
11698064efb8SGeert Uytterhoeven 
11708064efb8SGeert Uytterhoeven 		memset(result, 0, sizeof(result));
11718064efb8SGeert Uytterhoeven 
11728064efb8SGeert Uytterhoeven 		req.next_in = dtemplate[i].input;
11738064efb8SGeert Uytterhoeven 		req.avail_in = dtemplate[i].inlen / 2;
11748064efb8SGeert Uytterhoeven 		req.next_out = result;
11758064efb8SGeert Uytterhoeven 		req.avail_out = dtemplate[i].outlen / 2;
11768064efb8SGeert Uytterhoeven 
11773ce858cbSGeert Uytterhoeven 		res = crypto_decompress_update(tfm, &req);
11783ce858cbSGeert Uytterhoeven 		if (res < 0 && (res != -EAGAIN || req.avail_in)) {
11798064efb8SGeert Uytterhoeven 			pr_err("alg: pcomp: decompression update failed on "
11803ce858cbSGeert Uytterhoeven 			       "test %d for %s: error=%d\n", i + 1, algo, res);
11813ce858cbSGeert Uytterhoeven 			return res;
11828064efb8SGeert Uytterhoeven 		}
11833ce858cbSGeert Uytterhoeven 		if (res > 0)
11843ce858cbSGeert Uytterhoeven 			produced += res;
11858064efb8SGeert Uytterhoeven 
11868064efb8SGeert Uytterhoeven 		/* Add remaining input data */
11878064efb8SGeert Uytterhoeven 		req.avail_in += (dtemplate[i].inlen + 1) / 2;
11888064efb8SGeert Uytterhoeven 
11893ce858cbSGeert Uytterhoeven 		res = crypto_decompress_update(tfm, &req);
11903ce858cbSGeert Uytterhoeven 		if (res < 0 && (res != -EAGAIN || req.avail_in)) {
11918064efb8SGeert Uytterhoeven 			pr_err("alg: pcomp: decompression update failed on "
11923ce858cbSGeert Uytterhoeven 			       "test %d for %s: error=%d\n", i + 1, algo, res);
11933ce858cbSGeert Uytterhoeven 			return res;
11948064efb8SGeert Uytterhoeven 		}
11953ce858cbSGeert Uytterhoeven 		if (res > 0)
11963ce858cbSGeert Uytterhoeven 			produced += res;
11978064efb8SGeert Uytterhoeven 
11988064efb8SGeert Uytterhoeven 		/* Provide remaining output space */
11998064efb8SGeert Uytterhoeven 		req.avail_out += COMP_BUF_SIZE - dtemplate[i].outlen / 2;
12008064efb8SGeert Uytterhoeven 
12013ce858cbSGeert Uytterhoeven 		res = crypto_decompress_final(tfm, &req);
12023ce858cbSGeert Uytterhoeven 		if (res < 0 && (res != -EAGAIN || req.avail_in)) {
12038064efb8SGeert Uytterhoeven 			pr_err("alg: pcomp: decompression final failed on "
12043ce858cbSGeert Uytterhoeven 			       "test %d for %s: error=%d\n", i + 1, algo, res);
12053ce858cbSGeert Uytterhoeven 			return res;
12068064efb8SGeert Uytterhoeven 		}
12073ce858cbSGeert Uytterhoeven 		if (res > 0)
12083ce858cbSGeert Uytterhoeven 			produced += res;
12098064efb8SGeert Uytterhoeven 
12108064efb8SGeert Uytterhoeven 		if (COMP_BUF_SIZE - req.avail_out != dtemplate[i].outlen) {
12118064efb8SGeert Uytterhoeven 			pr_err("alg: comp: Decompression test %d failed for "
12128064efb8SGeert Uytterhoeven 			       "%s: output len = %d (expected %d)\n", i + 1,
12138064efb8SGeert Uytterhoeven 			       algo, COMP_BUF_SIZE - req.avail_out,
12148064efb8SGeert Uytterhoeven 			       dtemplate[i].outlen);
12158064efb8SGeert Uytterhoeven 			return -EINVAL;
12168064efb8SGeert Uytterhoeven 		}
12178064efb8SGeert Uytterhoeven 
12183ce858cbSGeert Uytterhoeven 		if (produced != dtemplate[i].outlen) {
12193ce858cbSGeert Uytterhoeven 			pr_err("alg: comp: Decompression test %d failed for "
12203ce858cbSGeert Uytterhoeven 			       "%s: returned len = %u (expected %d)\n", i + 1,
12213ce858cbSGeert Uytterhoeven 			       algo, produced, dtemplate[i].outlen);
12223ce858cbSGeert Uytterhoeven 			return -EINVAL;
12233ce858cbSGeert Uytterhoeven 		}
12243ce858cbSGeert Uytterhoeven 
12258064efb8SGeert Uytterhoeven 		if (memcmp(result, dtemplate[i].output, dtemplate[i].outlen)) {
12268064efb8SGeert Uytterhoeven 			pr_err("alg: pcomp: Decompression test %d failed for "
12278064efb8SGeert Uytterhoeven 			       "%s\n", i + 1, algo);
12288064efb8SGeert Uytterhoeven 			hexdump(result, dtemplate[i].outlen);
12298064efb8SGeert Uytterhoeven 			return -EINVAL;
12308064efb8SGeert Uytterhoeven 		}
12318064efb8SGeert Uytterhoeven 	}
12328064efb8SGeert Uytterhoeven 
12338064efb8SGeert Uytterhoeven 	return 0;
12348064efb8SGeert Uytterhoeven }
12358064efb8SGeert Uytterhoeven 
12367647d6ceSJarod Wilson 
12377647d6ceSJarod Wilson static int test_cprng(struct crypto_rng *tfm, struct cprng_testvec *template,
12387647d6ceSJarod Wilson 		      unsigned int tcount)
12397647d6ceSJarod Wilson {
12407647d6ceSJarod Wilson 	const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm));
1241fa4ef8a6SFelipe Contreras 	int err = 0, i, j, seedsize;
12427647d6ceSJarod Wilson 	u8 *seed;
12437647d6ceSJarod Wilson 	char result[32];
12447647d6ceSJarod Wilson 
12457647d6ceSJarod Wilson 	seedsize = crypto_rng_seedsize(tfm);
12467647d6ceSJarod Wilson 
12477647d6ceSJarod Wilson 	seed = kmalloc(seedsize, GFP_KERNEL);
12487647d6ceSJarod Wilson 	if (!seed) {
12497647d6ceSJarod Wilson 		printk(KERN_ERR "alg: cprng: Failed to allocate seed space "
12507647d6ceSJarod Wilson 		       "for %s\n", algo);
12517647d6ceSJarod Wilson 		return -ENOMEM;
12527647d6ceSJarod Wilson 	}
12537647d6ceSJarod Wilson 
12547647d6ceSJarod Wilson 	for (i = 0; i < tcount; i++) {
12557647d6ceSJarod Wilson 		memset(result, 0, 32);
12567647d6ceSJarod Wilson 
12577647d6ceSJarod Wilson 		memcpy(seed, template[i].v, template[i].vlen);
12587647d6ceSJarod Wilson 		memcpy(seed + template[i].vlen, template[i].key,
12597647d6ceSJarod Wilson 		       template[i].klen);
12607647d6ceSJarod Wilson 		memcpy(seed + template[i].vlen + template[i].klen,
12617647d6ceSJarod Wilson 		       template[i].dt, template[i].dtlen);
12627647d6ceSJarod Wilson 
12637647d6ceSJarod Wilson 		err = crypto_rng_reset(tfm, seed, seedsize);
12647647d6ceSJarod Wilson 		if (err) {
12657647d6ceSJarod Wilson 			printk(KERN_ERR "alg: cprng: Failed to reset rng "
12667647d6ceSJarod Wilson 			       "for %s\n", algo);
12677647d6ceSJarod Wilson 			goto out;
12687647d6ceSJarod Wilson 		}
12697647d6ceSJarod Wilson 
12707647d6ceSJarod Wilson 		for (j = 0; j < template[i].loops; j++) {
12717647d6ceSJarod Wilson 			err = crypto_rng_get_bytes(tfm, result,
12727647d6ceSJarod Wilson 						   template[i].rlen);
12737647d6ceSJarod Wilson 			if (err != template[i].rlen) {
12747647d6ceSJarod Wilson 				printk(KERN_ERR "alg: cprng: Failed to obtain "
12757647d6ceSJarod Wilson 				       "the correct amount of random data for "
12767647d6ceSJarod Wilson 				       "%s (requested %d, got %d)\n", algo,
12777647d6ceSJarod Wilson 				       template[i].rlen, err);
12787647d6ceSJarod Wilson 				goto out;
12797647d6ceSJarod Wilson 			}
12807647d6ceSJarod Wilson 		}
12817647d6ceSJarod Wilson 
12827647d6ceSJarod Wilson 		err = memcmp(result, template[i].result,
12837647d6ceSJarod Wilson 			     template[i].rlen);
12847647d6ceSJarod Wilson 		if (err) {
12857647d6ceSJarod Wilson 			printk(KERN_ERR "alg: cprng: Test %d failed for %s\n",
12867647d6ceSJarod Wilson 			       i, algo);
12877647d6ceSJarod Wilson 			hexdump(result, template[i].rlen);
12887647d6ceSJarod Wilson 			err = -EINVAL;
12897647d6ceSJarod Wilson 			goto out;
12907647d6ceSJarod Wilson 		}
12917647d6ceSJarod Wilson 	}
12927647d6ceSJarod Wilson 
12937647d6ceSJarod Wilson out:
12947647d6ceSJarod Wilson 	kfree(seed);
12957647d6ceSJarod Wilson 	return err;
12967647d6ceSJarod Wilson }
12977647d6ceSJarod Wilson 
1298da7f033dSHerbert Xu static int alg_test_aead(const struct alg_test_desc *desc, const char *driver,
1299da7f033dSHerbert Xu 			 u32 type, u32 mask)
1300da7f033dSHerbert Xu {
1301da7f033dSHerbert Xu 	struct crypto_aead *tfm;
1302da7f033dSHerbert Xu 	int err = 0;
1303da7f033dSHerbert Xu 
1304da7f033dSHerbert Xu 	tfm = crypto_alloc_aead(driver, type, mask);
1305da7f033dSHerbert Xu 	if (IS_ERR(tfm)) {
1306da7f033dSHerbert Xu 		printk(KERN_ERR "alg: aead: Failed to load transform for %s: "
1307da7f033dSHerbert Xu 		       "%ld\n", driver, PTR_ERR(tfm));
1308da7f033dSHerbert Xu 		return PTR_ERR(tfm);
1309da7f033dSHerbert Xu 	}
1310da7f033dSHerbert Xu 
1311da7f033dSHerbert Xu 	if (desc->suite.aead.enc.vecs) {
1312da7f033dSHerbert Xu 		err = test_aead(tfm, ENCRYPT, desc->suite.aead.enc.vecs,
1313da7f033dSHerbert Xu 				desc->suite.aead.enc.count);
1314da7f033dSHerbert Xu 		if (err)
1315da7f033dSHerbert Xu 			goto out;
1316da7f033dSHerbert Xu 	}
1317da7f033dSHerbert Xu 
1318da7f033dSHerbert Xu 	if (!err && desc->suite.aead.dec.vecs)
1319da7f033dSHerbert Xu 		err = test_aead(tfm, DECRYPT, desc->suite.aead.dec.vecs,
1320da7f033dSHerbert Xu 				desc->suite.aead.dec.count);
1321da7f033dSHerbert Xu 
1322da7f033dSHerbert Xu out:
1323da7f033dSHerbert Xu 	crypto_free_aead(tfm);
1324da7f033dSHerbert Xu 	return err;
1325da7f033dSHerbert Xu }
1326da7f033dSHerbert Xu 
1327da7f033dSHerbert Xu static int alg_test_cipher(const struct alg_test_desc *desc,
1328da7f033dSHerbert Xu 			   const char *driver, u32 type, u32 mask)
1329da7f033dSHerbert Xu {
13301aa4ecd9SHerbert Xu 	struct crypto_cipher *tfm;
1331da7f033dSHerbert Xu 	int err = 0;
1332da7f033dSHerbert Xu 
13331aa4ecd9SHerbert Xu 	tfm = crypto_alloc_cipher(driver, type, mask);
1334da7f033dSHerbert Xu 	if (IS_ERR(tfm)) {
1335da7f033dSHerbert Xu 		printk(KERN_ERR "alg: cipher: Failed to load transform for "
1336da7f033dSHerbert Xu 		       "%s: %ld\n", driver, PTR_ERR(tfm));
1337da7f033dSHerbert Xu 		return PTR_ERR(tfm);
1338da7f033dSHerbert Xu 	}
1339da7f033dSHerbert Xu 
1340da7f033dSHerbert Xu 	if (desc->suite.cipher.enc.vecs) {
1341da7f033dSHerbert Xu 		err = test_cipher(tfm, ENCRYPT, desc->suite.cipher.enc.vecs,
1342da7f033dSHerbert Xu 				  desc->suite.cipher.enc.count);
1343da7f033dSHerbert Xu 		if (err)
1344da7f033dSHerbert Xu 			goto out;
1345da7f033dSHerbert Xu 	}
1346da7f033dSHerbert Xu 
1347da7f033dSHerbert Xu 	if (desc->suite.cipher.dec.vecs)
1348da7f033dSHerbert Xu 		err = test_cipher(tfm, DECRYPT, desc->suite.cipher.dec.vecs,
1349da7f033dSHerbert Xu 				  desc->suite.cipher.dec.count);
1350da7f033dSHerbert Xu 
1351da7f033dSHerbert Xu out:
13521aa4ecd9SHerbert Xu 	crypto_free_cipher(tfm);
13531aa4ecd9SHerbert Xu 	return err;
13541aa4ecd9SHerbert Xu }
13551aa4ecd9SHerbert Xu 
13561aa4ecd9SHerbert Xu static int alg_test_skcipher(const struct alg_test_desc *desc,
13571aa4ecd9SHerbert Xu 			     const char *driver, u32 type, u32 mask)
13581aa4ecd9SHerbert Xu {
13591aa4ecd9SHerbert Xu 	struct crypto_ablkcipher *tfm;
13601aa4ecd9SHerbert Xu 	int err = 0;
13611aa4ecd9SHerbert Xu 
13621aa4ecd9SHerbert Xu 	tfm = crypto_alloc_ablkcipher(driver, type, mask);
13631aa4ecd9SHerbert Xu 	if (IS_ERR(tfm)) {
13641aa4ecd9SHerbert Xu 		printk(KERN_ERR "alg: skcipher: Failed to load transform for "
13651aa4ecd9SHerbert Xu 		       "%s: %ld\n", driver, PTR_ERR(tfm));
13661aa4ecd9SHerbert Xu 		return PTR_ERR(tfm);
13671aa4ecd9SHerbert Xu 	}
13681aa4ecd9SHerbert Xu 
13691aa4ecd9SHerbert Xu 	if (desc->suite.cipher.enc.vecs) {
13701aa4ecd9SHerbert Xu 		err = test_skcipher(tfm, ENCRYPT, desc->suite.cipher.enc.vecs,
13711aa4ecd9SHerbert Xu 				    desc->suite.cipher.enc.count);
13721aa4ecd9SHerbert Xu 		if (err)
13731aa4ecd9SHerbert Xu 			goto out;
13741aa4ecd9SHerbert Xu 	}
13751aa4ecd9SHerbert Xu 
13761aa4ecd9SHerbert Xu 	if (desc->suite.cipher.dec.vecs)
13771aa4ecd9SHerbert Xu 		err = test_skcipher(tfm, DECRYPT, desc->suite.cipher.dec.vecs,
13781aa4ecd9SHerbert Xu 				    desc->suite.cipher.dec.count);
13791aa4ecd9SHerbert Xu 
13801aa4ecd9SHerbert Xu out:
1381da7f033dSHerbert Xu 	crypto_free_ablkcipher(tfm);
1382da7f033dSHerbert Xu 	return err;
1383da7f033dSHerbert Xu }
1384da7f033dSHerbert Xu 
1385da7f033dSHerbert Xu static int alg_test_comp(const struct alg_test_desc *desc, const char *driver,
1386da7f033dSHerbert Xu 			 u32 type, u32 mask)
1387da7f033dSHerbert Xu {
1388da7f033dSHerbert Xu 	struct crypto_comp *tfm;
1389da7f033dSHerbert Xu 	int err;
1390da7f033dSHerbert Xu 
1391da7f033dSHerbert Xu 	tfm = crypto_alloc_comp(driver, type, mask);
1392da7f033dSHerbert Xu 	if (IS_ERR(tfm)) {
1393da7f033dSHerbert Xu 		printk(KERN_ERR "alg: comp: Failed to load transform for %s: "
1394da7f033dSHerbert Xu 		       "%ld\n", driver, PTR_ERR(tfm));
1395da7f033dSHerbert Xu 		return PTR_ERR(tfm);
1396da7f033dSHerbert Xu 	}
1397da7f033dSHerbert Xu 
1398da7f033dSHerbert Xu 	err = test_comp(tfm, desc->suite.comp.comp.vecs,
1399da7f033dSHerbert Xu 			desc->suite.comp.decomp.vecs,
1400da7f033dSHerbert Xu 			desc->suite.comp.comp.count,
1401da7f033dSHerbert Xu 			desc->suite.comp.decomp.count);
1402da7f033dSHerbert Xu 
1403da7f033dSHerbert Xu 	crypto_free_comp(tfm);
1404da7f033dSHerbert Xu 	return err;
1405da7f033dSHerbert Xu }
1406da7f033dSHerbert Xu 
14078064efb8SGeert Uytterhoeven static int alg_test_pcomp(const struct alg_test_desc *desc, const char *driver,
14088064efb8SGeert Uytterhoeven 			  u32 type, u32 mask)
14098064efb8SGeert Uytterhoeven {
14108064efb8SGeert Uytterhoeven 	struct crypto_pcomp *tfm;
14118064efb8SGeert Uytterhoeven 	int err;
14128064efb8SGeert Uytterhoeven 
14138064efb8SGeert Uytterhoeven 	tfm = crypto_alloc_pcomp(driver, type, mask);
14148064efb8SGeert Uytterhoeven 	if (IS_ERR(tfm)) {
14158064efb8SGeert Uytterhoeven 		pr_err("alg: pcomp: Failed to load transform for %s: %ld\n",
14168064efb8SGeert Uytterhoeven 		       driver, PTR_ERR(tfm));
14178064efb8SGeert Uytterhoeven 		return PTR_ERR(tfm);
14188064efb8SGeert Uytterhoeven 	}
14198064efb8SGeert Uytterhoeven 
14208064efb8SGeert Uytterhoeven 	err = test_pcomp(tfm, desc->suite.pcomp.comp.vecs,
14218064efb8SGeert Uytterhoeven 			 desc->suite.pcomp.decomp.vecs,
14228064efb8SGeert Uytterhoeven 			 desc->suite.pcomp.comp.count,
14238064efb8SGeert Uytterhoeven 			 desc->suite.pcomp.decomp.count);
14248064efb8SGeert Uytterhoeven 
14258064efb8SGeert Uytterhoeven 	crypto_free_pcomp(tfm);
14268064efb8SGeert Uytterhoeven 	return err;
14278064efb8SGeert Uytterhoeven }
14288064efb8SGeert Uytterhoeven 
1429da7f033dSHerbert Xu static int alg_test_hash(const struct alg_test_desc *desc, const char *driver,
1430da7f033dSHerbert Xu 			 u32 type, u32 mask)
1431da7f033dSHerbert Xu {
1432da7f033dSHerbert Xu 	struct crypto_ahash *tfm;
1433da7f033dSHerbert Xu 	int err;
1434da7f033dSHerbert Xu 
1435da7f033dSHerbert Xu 	tfm = crypto_alloc_ahash(driver, type, mask);
1436da7f033dSHerbert Xu 	if (IS_ERR(tfm)) {
1437da7f033dSHerbert Xu 		printk(KERN_ERR "alg: hash: Failed to load transform for %s: "
1438da7f033dSHerbert Xu 		       "%ld\n", driver, PTR_ERR(tfm));
1439da7f033dSHerbert Xu 		return PTR_ERR(tfm);
1440da7f033dSHerbert Xu 	}
1441da7f033dSHerbert Xu 
1442a8f1a052SDavid S. Miller 	err = test_hash(tfm, desc->suite.hash.vecs,
1443a8f1a052SDavid S. Miller 			desc->suite.hash.count, true);
1444a8f1a052SDavid S. Miller 	if (!err)
1445a8f1a052SDavid S. Miller 		err = test_hash(tfm, desc->suite.hash.vecs,
1446a8f1a052SDavid S. Miller 				desc->suite.hash.count, false);
1447da7f033dSHerbert Xu 
1448da7f033dSHerbert Xu 	crypto_free_ahash(tfm);
1449da7f033dSHerbert Xu 	return err;
1450da7f033dSHerbert Xu }
1451da7f033dSHerbert Xu 
14528e3ee85eSHerbert Xu static int alg_test_crc32c(const struct alg_test_desc *desc,
14538e3ee85eSHerbert Xu 			   const char *driver, u32 type, u32 mask)
14548e3ee85eSHerbert Xu {
14558e3ee85eSHerbert Xu 	struct crypto_shash *tfm;
14568e3ee85eSHerbert Xu 	u32 val;
14578e3ee85eSHerbert Xu 	int err;
14588e3ee85eSHerbert Xu 
14598e3ee85eSHerbert Xu 	err = alg_test_hash(desc, driver, type, mask);
14608e3ee85eSHerbert Xu 	if (err)
14618e3ee85eSHerbert Xu 		goto out;
14628e3ee85eSHerbert Xu 
14638e3ee85eSHerbert Xu 	tfm = crypto_alloc_shash(driver, type, mask);
14648e3ee85eSHerbert Xu 	if (IS_ERR(tfm)) {
14658e3ee85eSHerbert Xu 		printk(KERN_ERR "alg: crc32c: Failed to load transform for %s: "
14668e3ee85eSHerbert Xu 		       "%ld\n", driver, PTR_ERR(tfm));
14678e3ee85eSHerbert Xu 		err = PTR_ERR(tfm);
14688e3ee85eSHerbert Xu 		goto out;
14698e3ee85eSHerbert Xu 	}
14708e3ee85eSHerbert Xu 
14718e3ee85eSHerbert Xu 	do {
14728e3ee85eSHerbert Xu 		struct {
14738e3ee85eSHerbert Xu 			struct shash_desc shash;
14748e3ee85eSHerbert Xu 			char ctx[crypto_shash_descsize(tfm)];
14758e3ee85eSHerbert Xu 		} sdesc;
14768e3ee85eSHerbert Xu 
14778e3ee85eSHerbert Xu 		sdesc.shash.tfm = tfm;
14788e3ee85eSHerbert Xu 		sdesc.shash.flags = 0;
14798e3ee85eSHerbert Xu 
14808e3ee85eSHerbert Xu 		*(u32 *)sdesc.ctx = le32_to_cpu(420553207);
14818e3ee85eSHerbert Xu 		err = crypto_shash_final(&sdesc.shash, (u8 *)&val);
14828e3ee85eSHerbert Xu 		if (err) {
14838e3ee85eSHerbert Xu 			printk(KERN_ERR "alg: crc32c: Operation failed for "
14848e3ee85eSHerbert Xu 			       "%s: %d\n", driver, err);
14858e3ee85eSHerbert Xu 			break;
14868e3ee85eSHerbert Xu 		}
14878e3ee85eSHerbert Xu 
14888e3ee85eSHerbert Xu 		if (val != ~420553207) {
14898e3ee85eSHerbert Xu 			printk(KERN_ERR "alg: crc32c: Test failed for %s: "
14908e3ee85eSHerbert Xu 			       "%d\n", driver, val);
14918e3ee85eSHerbert Xu 			err = -EINVAL;
14928e3ee85eSHerbert Xu 		}
14938e3ee85eSHerbert Xu 	} while (0);
14948e3ee85eSHerbert Xu 
14958e3ee85eSHerbert Xu 	crypto_free_shash(tfm);
14968e3ee85eSHerbert Xu 
14978e3ee85eSHerbert Xu out:
14988e3ee85eSHerbert Xu 	return err;
14998e3ee85eSHerbert Xu }
15008e3ee85eSHerbert Xu 
15017647d6ceSJarod Wilson static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver,
15027647d6ceSJarod Wilson 			  u32 type, u32 mask)
15037647d6ceSJarod Wilson {
15047647d6ceSJarod Wilson 	struct crypto_rng *rng;
15057647d6ceSJarod Wilson 	int err;
15067647d6ceSJarod Wilson 
15077647d6ceSJarod Wilson 	rng = crypto_alloc_rng(driver, type, mask);
15087647d6ceSJarod Wilson 	if (IS_ERR(rng)) {
15097647d6ceSJarod Wilson 		printk(KERN_ERR "alg: cprng: Failed to load transform for %s: "
15107647d6ceSJarod Wilson 		       "%ld\n", driver, PTR_ERR(rng));
15117647d6ceSJarod Wilson 		return PTR_ERR(rng);
15127647d6ceSJarod Wilson 	}
15137647d6ceSJarod Wilson 
15147647d6ceSJarod Wilson 	err = test_cprng(rng, desc->suite.cprng.vecs, desc->suite.cprng.count);
15157647d6ceSJarod Wilson 
15167647d6ceSJarod Wilson 	crypto_free_rng(rng);
15177647d6ceSJarod Wilson 
15187647d6ceSJarod Wilson 	return err;
15197647d6ceSJarod Wilson }
15207647d6ceSJarod Wilson 
1521863b557aSYouquan, Song static int alg_test_null(const struct alg_test_desc *desc,
1522863b557aSYouquan, Song 			     const char *driver, u32 type, u32 mask)
1523863b557aSYouquan, Song {
1524863b557aSYouquan, Song 	return 0;
1525863b557aSYouquan, Song }
1526863b557aSYouquan, Song 
1527da7f033dSHerbert Xu /* Please keep this list sorted by algorithm name. */
1528da7f033dSHerbert Xu static const struct alg_test_desc alg_test_descs[] = {
1529da7f033dSHerbert Xu 	{
1530863b557aSYouquan, Song 		.alg = "__driver-cbc-aes-aesni",
1531863b557aSYouquan, Song 		.test = alg_test_null,
1532863b557aSYouquan, Song 		.suite = {
1533863b557aSYouquan, Song 			.cipher = {
1534863b557aSYouquan, Song 				.enc = {
1535863b557aSYouquan, Song 					.vecs = NULL,
1536863b557aSYouquan, Song 					.count = 0
1537863b557aSYouquan, Song 				},
1538863b557aSYouquan, Song 				.dec = {
1539863b557aSYouquan, Song 					.vecs = NULL,
1540863b557aSYouquan, Song 					.count = 0
1541863b557aSYouquan, Song 				}
1542863b557aSYouquan, Song 			}
1543863b557aSYouquan, Song 		}
1544863b557aSYouquan, Song 	}, {
1545863b557aSYouquan, Song 		.alg = "__driver-ecb-aes-aesni",
1546863b557aSYouquan, Song 		.test = alg_test_null,
1547863b557aSYouquan, Song 		.suite = {
1548863b557aSYouquan, Song 			.cipher = {
1549863b557aSYouquan, Song 				.enc = {
1550863b557aSYouquan, Song 					.vecs = NULL,
1551863b557aSYouquan, Song 					.count = 0
1552863b557aSYouquan, Song 				},
1553863b557aSYouquan, Song 				.dec = {
1554863b557aSYouquan, Song 					.vecs = NULL,
1555863b557aSYouquan, Song 					.count = 0
1556863b557aSYouquan, Song 				}
1557863b557aSYouquan, Song 			}
1558863b557aSYouquan, Song 		}
1559863b557aSYouquan, Song 	}, {
1560863b557aSYouquan, Song 		.alg = "__ghash-pclmulqdqni",
1561863b557aSYouquan, Song 		.test = alg_test_null,
1562863b557aSYouquan, Song 		.suite = {
1563863b557aSYouquan, Song 			.hash = {
1564863b557aSYouquan, Song 				.vecs = NULL,
1565863b557aSYouquan, Song 				.count = 0
1566863b557aSYouquan, Song 			}
1567863b557aSYouquan, Song 		}
1568863b557aSYouquan, Song 	}, {
1569e08ca2daSJarod Wilson 		.alg = "ansi_cprng",
1570e08ca2daSJarod Wilson 		.test = alg_test_cprng,
1571a1915d51SJarod Wilson 		.fips_allowed = 1,
1572e08ca2daSJarod Wilson 		.suite = {
1573e08ca2daSJarod Wilson 			.cprng = {
1574e08ca2daSJarod Wilson 				.vecs = ansi_cprng_aes_tv_template,
1575e08ca2daSJarod Wilson 				.count = ANSI_CPRNG_AES_TEST_VECTORS
1576e08ca2daSJarod Wilson 			}
1577e08ca2daSJarod Wilson 		}
1578e08ca2daSJarod Wilson 	}, {
1579da7f033dSHerbert Xu 		.alg = "cbc(aes)",
15801aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1581a1915d51SJarod Wilson 		.fips_allowed = 1,
1582da7f033dSHerbert Xu 		.suite = {
1583da7f033dSHerbert Xu 			.cipher = {
1584da7f033dSHerbert Xu 				.enc = {
1585da7f033dSHerbert Xu 					.vecs = aes_cbc_enc_tv_template,
1586da7f033dSHerbert Xu 					.count = AES_CBC_ENC_TEST_VECTORS
1587da7f033dSHerbert Xu 				},
1588da7f033dSHerbert Xu 				.dec = {
1589da7f033dSHerbert Xu 					.vecs = aes_cbc_dec_tv_template,
1590da7f033dSHerbert Xu 					.count = AES_CBC_DEC_TEST_VECTORS
1591da7f033dSHerbert Xu 				}
1592da7f033dSHerbert Xu 			}
1593da7f033dSHerbert Xu 		}
1594da7f033dSHerbert Xu 	}, {
1595da7f033dSHerbert Xu 		.alg = "cbc(anubis)",
15961aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1597da7f033dSHerbert Xu 		.suite = {
1598da7f033dSHerbert Xu 			.cipher = {
1599da7f033dSHerbert Xu 				.enc = {
1600da7f033dSHerbert Xu 					.vecs = anubis_cbc_enc_tv_template,
1601da7f033dSHerbert Xu 					.count = ANUBIS_CBC_ENC_TEST_VECTORS
1602da7f033dSHerbert Xu 				},
1603da7f033dSHerbert Xu 				.dec = {
1604da7f033dSHerbert Xu 					.vecs = anubis_cbc_dec_tv_template,
1605da7f033dSHerbert Xu 					.count = ANUBIS_CBC_DEC_TEST_VECTORS
1606da7f033dSHerbert Xu 				}
1607da7f033dSHerbert Xu 			}
1608da7f033dSHerbert Xu 		}
1609da7f033dSHerbert Xu 	}, {
1610da7f033dSHerbert Xu 		.alg = "cbc(blowfish)",
16111aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1612da7f033dSHerbert Xu 		.suite = {
1613da7f033dSHerbert Xu 			.cipher = {
1614da7f033dSHerbert Xu 				.enc = {
1615da7f033dSHerbert Xu 					.vecs = bf_cbc_enc_tv_template,
1616da7f033dSHerbert Xu 					.count = BF_CBC_ENC_TEST_VECTORS
1617da7f033dSHerbert Xu 				},
1618da7f033dSHerbert Xu 				.dec = {
1619da7f033dSHerbert Xu 					.vecs = bf_cbc_dec_tv_template,
1620da7f033dSHerbert Xu 					.count = BF_CBC_DEC_TEST_VECTORS
1621da7f033dSHerbert Xu 				}
1622da7f033dSHerbert Xu 			}
1623da7f033dSHerbert Xu 		}
1624da7f033dSHerbert Xu 	}, {
1625da7f033dSHerbert Xu 		.alg = "cbc(camellia)",
16261aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1627da7f033dSHerbert Xu 		.suite = {
1628da7f033dSHerbert Xu 			.cipher = {
1629da7f033dSHerbert Xu 				.enc = {
1630da7f033dSHerbert Xu 					.vecs = camellia_cbc_enc_tv_template,
1631da7f033dSHerbert Xu 					.count = CAMELLIA_CBC_ENC_TEST_VECTORS
1632da7f033dSHerbert Xu 				},
1633da7f033dSHerbert Xu 				.dec = {
1634da7f033dSHerbert Xu 					.vecs = camellia_cbc_dec_tv_template,
1635da7f033dSHerbert Xu 					.count = CAMELLIA_CBC_DEC_TEST_VECTORS
1636da7f033dSHerbert Xu 				}
1637da7f033dSHerbert Xu 			}
1638da7f033dSHerbert Xu 		}
1639da7f033dSHerbert Xu 	}, {
1640da7f033dSHerbert Xu 		.alg = "cbc(des)",
16411aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1642da7f033dSHerbert Xu 		.suite = {
1643da7f033dSHerbert Xu 			.cipher = {
1644da7f033dSHerbert Xu 				.enc = {
1645da7f033dSHerbert Xu 					.vecs = des_cbc_enc_tv_template,
1646da7f033dSHerbert Xu 					.count = DES_CBC_ENC_TEST_VECTORS
1647da7f033dSHerbert Xu 				},
1648da7f033dSHerbert Xu 				.dec = {
1649da7f033dSHerbert Xu 					.vecs = des_cbc_dec_tv_template,
1650da7f033dSHerbert Xu 					.count = DES_CBC_DEC_TEST_VECTORS
1651da7f033dSHerbert Xu 				}
1652da7f033dSHerbert Xu 			}
1653da7f033dSHerbert Xu 		}
1654da7f033dSHerbert Xu 	}, {
1655da7f033dSHerbert Xu 		.alg = "cbc(des3_ede)",
16561aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1657a1915d51SJarod Wilson 		.fips_allowed = 1,
1658da7f033dSHerbert Xu 		.suite = {
1659da7f033dSHerbert Xu 			.cipher = {
1660da7f033dSHerbert Xu 				.enc = {
1661da7f033dSHerbert Xu 					.vecs = des3_ede_cbc_enc_tv_template,
1662da7f033dSHerbert Xu 					.count = DES3_EDE_CBC_ENC_TEST_VECTORS
1663da7f033dSHerbert Xu 				},
1664da7f033dSHerbert Xu 				.dec = {
1665da7f033dSHerbert Xu 					.vecs = des3_ede_cbc_dec_tv_template,
1666da7f033dSHerbert Xu 					.count = DES3_EDE_CBC_DEC_TEST_VECTORS
1667da7f033dSHerbert Xu 				}
1668da7f033dSHerbert Xu 			}
1669da7f033dSHerbert Xu 		}
1670da7f033dSHerbert Xu 	}, {
1671da7f033dSHerbert Xu 		.alg = "cbc(twofish)",
16721aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1673da7f033dSHerbert Xu 		.suite = {
1674da7f033dSHerbert Xu 			.cipher = {
1675da7f033dSHerbert Xu 				.enc = {
1676da7f033dSHerbert Xu 					.vecs = tf_cbc_enc_tv_template,
1677da7f033dSHerbert Xu 					.count = TF_CBC_ENC_TEST_VECTORS
1678da7f033dSHerbert Xu 				},
1679da7f033dSHerbert Xu 				.dec = {
1680da7f033dSHerbert Xu 					.vecs = tf_cbc_dec_tv_template,
1681da7f033dSHerbert Xu 					.count = TF_CBC_DEC_TEST_VECTORS
1682da7f033dSHerbert Xu 				}
1683da7f033dSHerbert Xu 			}
1684da7f033dSHerbert Xu 		}
1685da7f033dSHerbert Xu 	}, {
1686da7f033dSHerbert Xu 		.alg = "ccm(aes)",
1687da7f033dSHerbert Xu 		.test = alg_test_aead,
1688a1915d51SJarod Wilson 		.fips_allowed = 1,
1689da7f033dSHerbert Xu 		.suite = {
1690da7f033dSHerbert Xu 			.aead = {
1691da7f033dSHerbert Xu 				.enc = {
1692da7f033dSHerbert Xu 					.vecs = aes_ccm_enc_tv_template,
1693da7f033dSHerbert Xu 					.count = AES_CCM_ENC_TEST_VECTORS
1694da7f033dSHerbert Xu 				},
1695da7f033dSHerbert Xu 				.dec = {
1696da7f033dSHerbert Xu 					.vecs = aes_ccm_dec_tv_template,
1697da7f033dSHerbert Xu 					.count = AES_CCM_DEC_TEST_VECTORS
1698da7f033dSHerbert Xu 				}
1699da7f033dSHerbert Xu 			}
1700da7f033dSHerbert Xu 		}
1701da7f033dSHerbert Xu 	}, {
1702da7f033dSHerbert Xu 		.alg = "crc32c",
17038e3ee85eSHerbert Xu 		.test = alg_test_crc32c,
1704a1915d51SJarod Wilson 		.fips_allowed = 1,
1705da7f033dSHerbert Xu 		.suite = {
1706da7f033dSHerbert Xu 			.hash = {
1707da7f033dSHerbert Xu 				.vecs = crc32c_tv_template,
1708da7f033dSHerbert Xu 				.count = CRC32C_TEST_VECTORS
1709da7f033dSHerbert Xu 			}
1710da7f033dSHerbert Xu 		}
1711da7f033dSHerbert Xu 	}, {
1712863b557aSYouquan, Song 		.alg = "cryptd(__driver-ecb-aes-aesni)",
1713863b557aSYouquan, Song 		.test = alg_test_null,
1714863b557aSYouquan, Song 		.suite = {
1715863b557aSYouquan, Song 			.cipher = {
1716863b557aSYouquan, Song 				.enc = {
1717863b557aSYouquan, Song 					.vecs = NULL,
1718863b557aSYouquan, Song 					.count = 0
1719863b557aSYouquan, Song 				},
1720863b557aSYouquan, Song 				.dec = {
1721863b557aSYouquan, Song 					.vecs = NULL,
1722863b557aSYouquan, Song 					.count = 0
1723863b557aSYouquan, Song 				}
1724863b557aSYouquan, Song 			}
1725863b557aSYouquan, Song 		}
1726863b557aSYouquan, Song 	}, {
1727863b557aSYouquan, Song 		.alg = "cryptd(__ghash-pclmulqdqni)",
1728863b557aSYouquan, Song 		.test = alg_test_null,
1729863b557aSYouquan, Song 		.suite = {
1730863b557aSYouquan, Song 			.hash = {
1731863b557aSYouquan, Song 				.vecs = NULL,
1732863b557aSYouquan, Song 				.count = 0
1733863b557aSYouquan, Song 			}
1734863b557aSYouquan, Song 		}
1735863b557aSYouquan, Song 	}, {
1736f7cb80f2SJarod Wilson 		.alg = "ctr(aes)",
1737f7cb80f2SJarod Wilson 		.test = alg_test_skcipher,
1738a1915d51SJarod Wilson 		.fips_allowed = 1,
1739f7cb80f2SJarod Wilson 		.suite = {
1740f7cb80f2SJarod Wilson 			.cipher = {
1741f7cb80f2SJarod Wilson 				.enc = {
1742f7cb80f2SJarod Wilson 					.vecs = aes_ctr_enc_tv_template,
1743f7cb80f2SJarod Wilson 					.count = AES_CTR_ENC_TEST_VECTORS
1744f7cb80f2SJarod Wilson 				},
1745f7cb80f2SJarod Wilson 				.dec = {
1746f7cb80f2SJarod Wilson 					.vecs = aes_ctr_dec_tv_template,
1747f7cb80f2SJarod Wilson 					.count = AES_CTR_DEC_TEST_VECTORS
1748f7cb80f2SJarod Wilson 				}
1749f7cb80f2SJarod Wilson 			}
1750f7cb80f2SJarod Wilson 		}
1751f7cb80f2SJarod Wilson 	}, {
1752da7f033dSHerbert Xu 		.alg = "cts(cbc(aes))",
17531aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1754da7f033dSHerbert Xu 		.suite = {
1755da7f033dSHerbert Xu 			.cipher = {
1756da7f033dSHerbert Xu 				.enc = {
1757da7f033dSHerbert Xu 					.vecs = cts_mode_enc_tv_template,
1758da7f033dSHerbert Xu 					.count = CTS_MODE_ENC_TEST_VECTORS
1759da7f033dSHerbert Xu 				},
1760da7f033dSHerbert Xu 				.dec = {
1761da7f033dSHerbert Xu 					.vecs = cts_mode_dec_tv_template,
1762da7f033dSHerbert Xu 					.count = CTS_MODE_DEC_TEST_VECTORS
1763da7f033dSHerbert Xu 				}
1764da7f033dSHerbert Xu 			}
1765da7f033dSHerbert Xu 		}
1766da7f033dSHerbert Xu 	}, {
1767da7f033dSHerbert Xu 		.alg = "deflate",
1768da7f033dSHerbert Xu 		.test = alg_test_comp,
1769da7f033dSHerbert Xu 		.suite = {
1770da7f033dSHerbert Xu 			.comp = {
1771da7f033dSHerbert Xu 				.comp = {
1772da7f033dSHerbert Xu 					.vecs = deflate_comp_tv_template,
1773da7f033dSHerbert Xu 					.count = DEFLATE_COMP_TEST_VECTORS
1774da7f033dSHerbert Xu 				},
1775da7f033dSHerbert Xu 				.decomp = {
1776da7f033dSHerbert Xu 					.vecs = deflate_decomp_tv_template,
1777da7f033dSHerbert Xu 					.count = DEFLATE_DECOMP_TEST_VECTORS
1778da7f033dSHerbert Xu 				}
1779da7f033dSHerbert Xu 			}
1780da7f033dSHerbert Xu 		}
1781da7f033dSHerbert Xu 	}, {
1782863b557aSYouquan, Song 		.alg = "ecb(__aes-aesni)",
1783863b557aSYouquan, Song 		.test = alg_test_null,
1784863b557aSYouquan, Song 		.suite = {
1785863b557aSYouquan, Song 			.cipher = {
1786863b557aSYouquan, Song 				.enc = {
1787863b557aSYouquan, Song 					.vecs = NULL,
1788863b557aSYouquan, Song 					.count = 0
1789863b557aSYouquan, Song 				},
1790863b557aSYouquan, Song 				.dec = {
1791863b557aSYouquan, Song 					.vecs = NULL,
1792863b557aSYouquan, Song 					.count = 0
1793863b557aSYouquan, Song 				}
1794863b557aSYouquan, Song 			}
1795863b557aSYouquan, Song 		}
1796863b557aSYouquan, Song 	}, {
1797da7f033dSHerbert Xu 		.alg = "ecb(aes)",
17981aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1799a1915d51SJarod Wilson 		.fips_allowed = 1,
1800da7f033dSHerbert Xu 		.suite = {
1801da7f033dSHerbert Xu 			.cipher = {
1802da7f033dSHerbert Xu 				.enc = {
1803da7f033dSHerbert Xu 					.vecs = aes_enc_tv_template,
1804da7f033dSHerbert Xu 					.count = AES_ENC_TEST_VECTORS
1805da7f033dSHerbert Xu 				},
1806da7f033dSHerbert Xu 				.dec = {
1807da7f033dSHerbert Xu 					.vecs = aes_dec_tv_template,
1808da7f033dSHerbert Xu 					.count = AES_DEC_TEST_VECTORS
1809da7f033dSHerbert Xu 				}
1810da7f033dSHerbert Xu 			}
1811da7f033dSHerbert Xu 		}
1812da7f033dSHerbert Xu 	}, {
1813da7f033dSHerbert Xu 		.alg = "ecb(anubis)",
18141aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1815da7f033dSHerbert Xu 		.suite = {
1816da7f033dSHerbert Xu 			.cipher = {
1817da7f033dSHerbert Xu 				.enc = {
1818da7f033dSHerbert Xu 					.vecs = anubis_enc_tv_template,
1819da7f033dSHerbert Xu 					.count = ANUBIS_ENC_TEST_VECTORS
1820da7f033dSHerbert Xu 				},
1821da7f033dSHerbert Xu 				.dec = {
1822da7f033dSHerbert Xu 					.vecs = anubis_dec_tv_template,
1823da7f033dSHerbert Xu 					.count = ANUBIS_DEC_TEST_VECTORS
1824da7f033dSHerbert Xu 				}
1825da7f033dSHerbert Xu 			}
1826da7f033dSHerbert Xu 		}
1827da7f033dSHerbert Xu 	}, {
1828da7f033dSHerbert Xu 		.alg = "ecb(arc4)",
18291aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1830da7f033dSHerbert Xu 		.suite = {
1831da7f033dSHerbert Xu 			.cipher = {
1832da7f033dSHerbert Xu 				.enc = {
1833da7f033dSHerbert Xu 					.vecs = arc4_enc_tv_template,
1834da7f033dSHerbert Xu 					.count = ARC4_ENC_TEST_VECTORS
1835da7f033dSHerbert Xu 				},
1836da7f033dSHerbert Xu 				.dec = {
1837da7f033dSHerbert Xu 					.vecs = arc4_dec_tv_template,
1838da7f033dSHerbert Xu 					.count = ARC4_DEC_TEST_VECTORS
1839da7f033dSHerbert Xu 				}
1840da7f033dSHerbert Xu 			}
1841da7f033dSHerbert Xu 		}
1842da7f033dSHerbert Xu 	}, {
1843da7f033dSHerbert Xu 		.alg = "ecb(blowfish)",
18441aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1845da7f033dSHerbert Xu 		.suite = {
1846da7f033dSHerbert Xu 			.cipher = {
1847da7f033dSHerbert Xu 				.enc = {
1848da7f033dSHerbert Xu 					.vecs = bf_enc_tv_template,
1849da7f033dSHerbert Xu 					.count = BF_ENC_TEST_VECTORS
1850da7f033dSHerbert Xu 				},
1851da7f033dSHerbert Xu 				.dec = {
1852da7f033dSHerbert Xu 					.vecs = bf_dec_tv_template,
1853da7f033dSHerbert Xu 					.count = BF_DEC_TEST_VECTORS
1854da7f033dSHerbert Xu 				}
1855da7f033dSHerbert Xu 			}
1856da7f033dSHerbert Xu 		}
1857da7f033dSHerbert Xu 	}, {
1858da7f033dSHerbert Xu 		.alg = "ecb(camellia)",
18591aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1860da7f033dSHerbert Xu 		.suite = {
1861da7f033dSHerbert Xu 			.cipher = {
1862da7f033dSHerbert Xu 				.enc = {
1863da7f033dSHerbert Xu 					.vecs = camellia_enc_tv_template,
1864da7f033dSHerbert Xu 					.count = CAMELLIA_ENC_TEST_VECTORS
1865da7f033dSHerbert Xu 				},
1866da7f033dSHerbert Xu 				.dec = {
1867da7f033dSHerbert Xu 					.vecs = camellia_dec_tv_template,
1868da7f033dSHerbert Xu 					.count = CAMELLIA_DEC_TEST_VECTORS
1869da7f033dSHerbert Xu 				}
1870da7f033dSHerbert Xu 			}
1871da7f033dSHerbert Xu 		}
1872da7f033dSHerbert Xu 	}, {
1873da7f033dSHerbert Xu 		.alg = "ecb(cast5)",
18741aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1875da7f033dSHerbert Xu 		.suite = {
1876da7f033dSHerbert Xu 			.cipher = {
1877da7f033dSHerbert Xu 				.enc = {
1878da7f033dSHerbert Xu 					.vecs = cast5_enc_tv_template,
1879da7f033dSHerbert Xu 					.count = CAST5_ENC_TEST_VECTORS
1880da7f033dSHerbert Xu 				},
1881da7f033dSHerbert Xu 				.dec = {
1882da7f033dSHerbert Xu 					.vecs = cast5_dec_tv_template,
1883da7f033dSHerbert Xu 					.count = CAST5_DEC_TEST_VECTORS
1884da7f033dSHerbert Xu 				}
1885da7f033dSHerbert Xu 			}
1886da7f033dSHerbert Xu 		}
1887da7f033dSHerbert Xu 	}, {
1888da7f033dSHerbert Xu 		.alg = "ecb(cast6)",
18891aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1890da7f033dSHerbert Xu 		.suite = {
1891da7f033dSHerbert Xu 			.cipher = {
1892da7f033dSHerbert Xu 				.enc = {
1893da7f033dSHerbert Xu 					.vecs = cast6_enc_tv_template,
1894da7f033dSHerbert Xu 					.count = CAST6_ENC_TEST_VECTORS
1895da7f033dSHerbert Xu 				},
1896da7f033dSHerbert Xu 				.dec = {
1897da7f033dSHerbert Xu 					.vecs = cast6_dec_tv_template,
1898da7f033dSHerbert Xu 					.count = CAST6_DEC_TEST_VECTORS
1899da7f033dSHerbert Xu 				}
1900da7f033dSHerbert Xu 			}
1901da7f033dSHerbert Xu 		}
1902da7f033dSHerbert Xu 	}, {
1903da7f033dSHerbert Xu 		.alg = "ecb(des)",
19041aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1905a1915d51SJarod Wilson 		.fips_allowed = 1,
1906da7f033dSHerbert Xu 		.suite = {
1907da7f033dSHerbert Xu 			.cipher = {
1908da7f033dSHerbert Xu 				.enc = {
1909da7f033dSHerbert Xu 					.vecs = des_enc_tv_template,
1910da7f033dSHerbert Xu 					.count = DES_ENC_TEST_VECTORS
1911da7f033dSHerbert Xu 				},
1912da7f033dSHerbert Xu 				.dec = {
1913da7f033dSHerbert Xu 					.vecs = des_dec_tv_template,
1914da7f033dSHerbert Xu 					.count = DES_DEC_TEST_VECTORS
1915da7f033dSHerbert Xu 				}
1916da7f033dSHerbert Xu 			}
1917da7f033dSHerbert Xu 		}
1918da7f033dSHerbert Xu 	}, {
1919da7f033dSHerbert Xu 		.alg = "ecb(des3_ede)",
19201aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1921a1915d51SJarod Wilson 		.fips_allowed = 1,
1922da7f033dSHerbert Xu 		.suite = {
1923da7f033dSHerbert Xu 			.cipher = {
1924da7f033dSHerbert Xu 				.enc = {
1925da7f033dSHerbert Xu 					.vecs = des3_ede_enc_tv_template,
1926da7f033dSHerbert Xu 					.count = DES3_EDE_ENC_TEST_VECTORS
1927da7f033dSHerbert Xu 				},
1928da7f033dSHerbert Xu 				.dec = {
1929da7f033dSHerbert Xu 					.vecs = des3_ede_dec_tv_template,
1930da7f033dSHerbert Xu 					.count = DES3_EDE_DEC_TEST_VECTORS
1931da7f033dSHerbert Xu 				}
1932da7f033dSHerbert Xu 			}
1933da7f033dSHerbert Xu 		}
1934da7f033dSHerbert Xu 	}, {
1935da7f033dSHerbert Xu 		.alg = "ecb(khazad)",
19361aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1937da7f033dSHerbert Xu 		.suite = {
1938da7f033dSHerbert Xu 			.cipher = {
1939da7f033dSHerbert Xu 				.enc = {
1940da7f033dSHerbert Xu 					.vecs = khazad_enc_tv_template,
1941da7f033dSHerbert Xu 					.count = KHAZAD_ENC_TEST_VECTORS
1942da7f033dSHerbert Xu 				},
1943da7f033dSHerbert Xu 				.dec = {
1944da7f033dSHerbert Xu 					.vecs = khazad_dec_tv_template,
1945da7f033dSHerbert Xu 					.count = KHAZAD_DEC_TEST_VECTORS
1946da7f033dSHerbert Xu 				}
1947da7f033dSHerbert Xu 			}
1948da7f033dSHerbert Xu 		}
1949da7f033dSHerbert Xu 	}, {
1950da7f033dSHerbert Xu 		.alg = "ecb(seed)",
19511aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1952da7f033dSHerbert Xu 		.suite = {
1953da7f033dSHerbert Xu 			.cipher = {
1954da7f033dSHerbert Xu 				.enc = {
1955da7f033dSHerbert Xu 					.vecs = seed_enc_tv_template,
1956da7f033dSHerbert Xu 					.count = SEED_ENC_TEST_VECTORS
1957da7f033dSHerbert Xu 				},
1958da7f033dSHerbert Xu 				.dec = {
1959da7f033dSHerbert Xu 					.vecs = seed_dec_tv_template,
1960da7f033dSHerbert Xu 					.count = SEED_DEC_TEST_VECTORS
1961da7f033dSHerbert Xu 				}
1962da7f033dSHerbert Xu 			}
1963da7f033dSHerbert Xu 		}
1964da7f033dSHerbert Xu 	}, {
1965da7f033dSHerbert Xu 		.alg = "ecb(serpent)",
19661aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1967da7f033dSHerbert Xu 		.suite = {
1968da7f033dSHerbert Xu 			.cipher = {
1969da7f033dSHerbert Xu 				.enc = {
1970da7f033dSHerbert Xu 					.vecs = serpent_enc_tv_template,
1971da7f033dSHerbert Xu 					.count = SERPENT_ENC_TEST_VECTORS
1972da7f033dSHerbert Xu 				},
1973da7f033dSHerbert Xu 				.dec = {
1974da7f033dSHerbert Xu 					.vecs = serpent_dec_tv_template,
1975da7f033dSHerbert Xu 					.count = SERPENT_DEC_TEST_VECTORS
1976da7f033dSHerbert Xu 				}
1977da7f033dSHerbert Xu 			}
1978da7f033dSHerbert Xu 		}
1979da7f033dSHerbert Xu 	}, {
1980da7f033dSHerbert Xu 		.alg = "ecb(tea)",
19811aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1982da7f033dSHerbert Xu 		.suite = {
1983da7f033dSHerbert Xu 			.cipher = {
1984da7f033dSHerbert Xu 				.enc = {
1985da7f033dSHerbert Xu 					.vecs = tea_enc_tv_template,
1986da7f033dSHerbert Xu 					.count = TEA_ENC_TEST_VECTORS
1987da7f033dSHerbert Xu 				},
1988da7f033dSHerbert Xu 				.dec = {
1989da7f033dSHerbert Xu 					.vecs = tea_dec_tv_template,
1990da7f033dSHerbert Xu 					.count = TEA_DEC_TEST_VECTORS
1991da7f033dSHerbert Xu 				}
1992da7f033dSHerbert Xu 			}
1993da7f033dSHerbert Xu 		}
1994da7f033dSHerbert Xu 	}, {
1995da7f033dSHerbert Xu 		.alg = "ecb(tnepres)",
19961aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
1997da7f033dSHerbert Xu 		.suite = {
1998da7f033dSHerbert Xu 			.cipher = {
1999da7f033dSHerbert Xu 				.enc = {
2000da7f033dSHerbert Xu 					.vecs = tnepres_enc_tv_template,
2001da7f033dSHerbert Xu 					.count = TNEPRES_ENC_TEST_VECTORS
2002da7f033dSHerbert Xu 				},
2003da7f033dSHerbert Xu 				.dec = {
2004da7f033dSHerbert Xu 					.vecs = tnepres_dec_tv_template,
2005da7f033dSHerbert Xu 					.count = TNEPRES_DEC_TEST_VECTORS
2006da7f033dSHerbert Xu 				}
2007da7f033dSHerbert Xu 			}
2008da7f033dSHerbert Xu 		}
2009da7f033dSHerbert Xu 	}, {
2010da7f033dSHerbert Xu 		.alg = "ecb(twofish)",
20111aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2012da7f033dSHerbert Xu 		.suite = {
2013da7f033dSHerbert Xu 			.cipher = {
2014da7f033dSHerbert Xu 				.enc = {
2015da7f033dSHerbert Xu 					.vecs = tf_enc_tv_template,
2016da7f033dSHerbert Xu 					.count = TF_ENC_TEST_VECTORS
2017da7f033dSHerbert Xu 				},
2018da7f033dSHerbert Xu 				.dec = {
2019da7f033dSHerbert Xu 					.vecs = tf_dec_tv_template,
2020da7f033dSHerbert Xu 					.count = TF_DEC_TEST_VECTORS
2021da7f033dSHerbert Xu 				}
2022da7f033dSHerbert Xu 			}
2023da7f033dSHerbert Xu 		}
2024da7f033dSHerbert Xu 	}, {
2025da7f033dSHerbert Xu 		.alg = "ecb(xeta)",
20261aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2027da7f033dSHerbert Xu 		.suite = {
2028da7f033dSHerbert Xu 			.cipher = {
2029da7f033dSHerbert Xu 				.enc = {
2030da7f033dSHerbert Xu 					.vecs = xeta_enc_tv_template,
2031da7f033dSHerbert Xu 					.count = XETA_ENC_TEST_VECTORS
2032da7f033dSHerbert Xu 				},
2033da7f033dSHerbert Xu 				.dec = {
2034da7f033dSHerbert Xu 					.vecs = xeta_dec_tv_template,
2035da7f033dSHerbert Xu 					.count = XETA_DEC_TEST_VECTORS
2036da7f033dSHerbert Xu 				}
2037da7f033dSHerbert Xu 			}
2038da7f033dSHerbert Xu 		}
2039da7f033dSHerbert Xu 	}, {
2040da7f033dSHerbert Xu 		.alg = "ecb(xtea)",
20411aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2042da7f033dSHerbert Xu 		.suite = {
2043da7f033dSHerbert Xu 			.cipher = {
2044da7f033dSHerbert Xu 				.enc = {
2045da7f033dSHerbert Xu 					.vecs = xtea_enc_tv_template,
2046da7f033dSHerbert Xu 					.count = XTEA_ENC_TEST_VECTORS
2047da7f033dSHerbert Xu 				},
2048da7f033dSHerbert Xu 				.dec = {
2049da7f033dSHerbert Xu 					.vecs = xtea_dec_tv_template,
2050da7f033dSHerbert Xu 					.count = XTEA_DEC_TEST_VECTORS
2051da7f033dSHerbert Xu 				}
2052da7f033dSHerbert Xu 			}
2053da7f033dSHerbert Xu 		}
2054da7f033dSHerbert Xu 	}, {
2055da7f033dSHerbert Xu 		.alg = "gcm(aes)",
2056da7f033dSHerbert Xu 		.test = alg_test_aead,
2057a1915d51SJarod Wilson 		.fips_allowed = 1,
2058da7f033dSHerbert Xu 		.suite = {
2059da7f033dSHerbert Xu 			.aead = {
2060da7f033dSHerbert Xu 				.enc = {
2061da7f033dSHerbert Xu 					.vecs = aes_gcm_enc_tv_template,
2062da7f033dSHerbert Xu 					.count = AES_GCM_ENC_TEST_VECTORS
2063da7f033dSHerbert Xu 				},
2064da7f033dSHerbert Xu 				.dec = {
2065da7f033dSHerbert Xu 					.vecs = aes_gcm_dec_tv_template,
2066da7f033dSHerbert Xu 					.count = AES_GCM_DEC_TEST_VECTORS
2067da7f033dSHerbert Xu 				}
2068da7f033dSHerbert Xu 			}
2069da7f033dSHerbert Xu 		}
2070da7f033dSHerbert Xu 	}, {
2071507069c9SYouquan, Song 		.alg = "ghash",
2072507069c9SYouquan, Song 		.test = alg_test_hash,
2073507069c9SYouquan, Song 		.suite = {
2074507069c9SYouquan, Song 			.hash = {
2075507069c9SYouquan, Song 				.vecs = ghash_tv_template,
2076507069c9SYouquan, Song 				.count = GHASH_TEST_VECTORS
2077507069c9SYouquan, Song 			}
2078507069c9SYouquan, Song 		}
2079507069c9SYouquan, Song 	}, {
2080da7f033dSHerbert Xu 		.alg = "hmac(md5)",
2081da7f033dSHerbert Xu 		.test = alg_test_hash,
2082da7f033dSHerbert Xu 		.suite = {
2083da7f033dSHerbert Xu 			.hash = {
2084da7f033dSHerbert Xu 				.vecs = hmac_md5_tv_template,
2085da7f033dSHerbert Xu 				.count = HMAC_MD5_TEST_VECTORS
2086da7f033dSHerbert Xu 			}
2087da7f033dSHerbert Xu 		}
2088da7f033dSHerbert Xu 	}, {
2089da7f033dSHerbert Xu 		.alg = "hmac(rmd128)",
2090da7f033dSHerbert Xu 		.test = alg_test_hash,
2091da7f033dSHerbert Xu 		.suite = {
2092da7f033dSHerbert Xu 			.hash = {
2093da7f033dSHerbert Xu 				.vecs = hmac_rmd128_tv_template,
2094da7f033dSHerbert Xu 				.count = HMAC_RMD128_TEST_VECTORS
2095da7f033dSHerbert Xu 			}
2096da7f033dSHerbert Xu 		}
2097da7f033dSHerbert Xu 	}, {
2098da7f033dSHerbert Xu 		.alg = "hmac(rmd160)",
2099da7f033dSHerbert Xu 		.test = alg_test_hash,
2100da7f033dSHerbert Xu 		.suite = {
2101da7f033dSHerbert Xu 			.hash = {
2102da7f033dSHerbert Xu 				.vecs = hmac_rmd160_tv_template,
2103da7f033dSHerbert Xu 				.count = HMAC_RMD160_TEST_VECTORS
2104da7f033dSHerbert Xu 			}
2105da7f033dSHerbert Xu 		}
2106da7f033dSHerbert Xu 	}, {
2107da7f033dSHerbert Xu 		.alg = "hmac(sha1)",
2108da7f033dSHerbert Xu 		.test = alg_test_hash,
2109a1915d51SJarod Wilson 		.fips_allowed = 1,
2110da7f033dSHerbert Xu 		.suite = {
2111da7f033dSHerbert Xu 			.hash = {
2112da7f033dSHerbert Xu 				.vecs = hmac_sha1_tv_template,
2113da7f033dSHerbert Xu 				.count = HMAC_SHA1_TEST_VECTORS
2114da7f033dSHerbert Xu 			}
2115da7f033dSHerbert Xu 		}
2116da7f033dSHerbert Xu 	}, {
2117da7f033dSHerbert Xu 		.alg = "hmac(sha224)",
2118da7f033dSHerbert Xu 		.test = alg_test_hash,
2119a1915d51SJarod Wilson 		.fips_allowed = 1,
2120da7f033dSHerbert Xu 		.suite = {
2121da7f033dSHerbert Xu 			.hash = {
2122da7f033dSHerbert Xu 				.vecs = hmac_sha224_tv_template,
2123da7f033dSHerbert Xu 				.count = HMAC_SHA224_TEST_VECTORS
2124da7f033dSHerbert Xu 			}
2125da7f033dSHerbert Xu 		}
2126da7f033dSHerbert Xu 	}, {
2127da7f033dSHerbert Xu 		.alg = "hmac(sha256)",
2128da7f033dSHerbert Xu 		.test = alg_test_hash,
2129a1915d51SJarod Wilson 		.fips_allowed = 1,
2130da7f033dSHerbert Xu 		.suite = {
2131da7f033dSHerbert Xu 			.hash = {
2132da7f033dSHerbert Xu 				.vecs = hmac_sha256_tv_template,
2133da7f033dSHerbert Xu 				.count = HMAC_SHA256_TEST_VECTORS
2134da7f033dSHerbert Xu 			}
2135da7f033dSHerbert Xu 		}
2136da7f033dSHerbert Xu 	}, {
2137da7f033dSHerbert Xu 		.alg = "hmac(sha384)",
2138da7f033dSHerbert Xu 		.test = alg_test_hash,
2139a1915d51SJarod Wilson 		.fips_allowed = 1,
2140da7f033dSHerbert Xu 		.suite = {
2141da7f033dSHerbert Xu 			.hash = {
2142da7f033dSHerbert Xu 				.vecs = hmac_sha384_tv_template,
2143da7f033dSHerbert Xu 				.count = HMAC_SHA384_TEST_VECTORS
2144da7f033dSHerbert Xu 			}
2145da7f033dSHerbert Xu 		}
2146da7f033dSHerbert Xu 	}, {
2147da7f033dSHerbert Xu 		.alg = "hmac(sha512)",
2148da7f033dSHerbert Xu 		.test = alg_test_hash,
2149a1915d51SJarod Wilson 		.fips_allowed = 1,
2150da7f033dSHerbert Xu 		.suite = {
2151da7f033dSHerbert Xu 			.hash = {
2152da7f033dSHerbert Xu 				.vecs = hmac_sha512_tv_template,
2153da7f033dSHerbert Xu 				.count = HMAC_SHA512_TEST_VECTORS
2154da7f033dSHerbert Xu 			}
2155da7f033dSHerbert Xu 		}
2156da7f033dSHerbert Xu 	}, {
2157da7f033dSHerbert Xu 		.alg = "lrw(aes)",
21581aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2159da7f033dSHerbert Xu 		.suite = {
2160da7f033dSHerbert Xu 			.cipher = {
2161da7f033dSHerbert Xu 				.enc = {
2162da7f033dSHerbert Xu 					.vecs = aes_lrw_enc_tv_template,
2163da7f033dSHerbert Xu 					.count = AES_LRW_ENC_TEST_VECTORS
2164da7f033dSHerbert Xu 				},
2165da7f033dSHerbert Xu 				.dec = {
2166da7f033dSHerbert Xu 					.vecs = aes_lrw_dec_tv_template,
2167da7f033dSHerbert Xu 					.count = AES_LRW_DEC_TEST_VECTORS
2168da7f033dSHerbert Xu 				}
2169da7f033dSHerbert Xu 			}
2170da7f033dSHerbert Xu 		}
2171da7f033dSHerbert Xu 	}, {
2172da7f033dSHerbert Xu 		.alg = "lzo",
2173da7f033dSHerbert Xu 		.test = alg_test_comp,
2174da7f033dSHerbert Xu 		.suite = {
2175da7f033dSHerbert Xu 			.comp = {
2176da7f033dSHerbert Xu 				.comp = {
2177da7f033dSHerbert Xu 					.vecs = lzo_comp_tv_template,
2178da7f033dSHerbert Xu 					.count = LZO_COMP_TEST_VECTORS
2179da7f033dSHerbert Xu 				},
2180da7f033dSHerbert Xu 				.decomp = {
2181da7f033dSHerbert Xu 					.vecs = lzo_decomp_tv_template,
2182da7f033dSHerbert Xu 					.count = LZO_DECOMP_TEST_VECTORS
2183da7f033dSHerbert Xu 				}
2184da7f033dSHerbert Xu 			}
2185da7f033dSHerbert Xu 		}
2186da7f033dSHerbert Xu 	}, {
2187da7f033dSHerbert Xu 		.alg = "md4",
2188da7f033dSHerbert Xu 		.test = alg_test_hash,
2189da7f033dSHerbert Xu 		.suite = {
2190da7f033dSHerbert Xu 			.hash = {
2191da7f033dSHerbert Xu 				.vecs = md4_tv_template,
2192da7f033dSHerbert Xu 				.count = MD4_TEST_VECTORS
2193da7f033dSHerbert Xu 			}
2194da7f033dSHerbert Xu 		}
2195da7f033dSHerbert Xu 	}, {
2196da7f033dSHerbert Xu 		.alg = "md5",
2197da7f033dSHerbert Xu 		.test = alg_test_hash,
2198da7f033dSHerbert Xu 		.suite = {
2199da7f033dSHerbert Xu 			.hash = {
2200da7f033dSHerbert Xu 				.vecs = md5_tv_template,
2201da7f033dSHerbert Xu 				.count = MD5_TEST_VECTORS
2202da7f033dSHerbert Xu 			}
2203da7f033dSHerbert Xu 		}
2204da7f033dSHerbert Xu 	}, {
2205da7f033dSHerbert Xu 		.alg = "michael_mic",
2206da7f033dSHerbert Xu 		.test = alg_test_hash,
2207da7f033dSHerbert Xu 		.suite = {
2208da7f033dSHerbert Xu 			.hash = {
2209da7f033dSHerbert Xu 				.vecs = michael_mic_tv_template,
2210da7f033dSHerbert Xu 				.count = MICHAEL_MIC_TEST_VECTORS
2211da7f033dSHerbert Xu 			}
2212da7f033dSHerbert Xu 		}
2213da7f033dSHerbert Xu 	}, {
2214da7f033dSHerbert Xu 		.alg = "pcbc(fcrypt)",
22151aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2216da7f033dSHerbert Xu 		.suite = {
2217da7f033dSHerbert Xu 			.cipher = {
2218da7f033dSHerbert Xu 				.enc = {
2219da7f033dSHerbert Xu 					.vecs = fcrypt_pcbc_enc_tv_template,
2220da7f033dSHerbert Xu 					.count = FCRYPT_ENC_TEST_VECTORS
2221da7f033dSHerbert Xu 				},
2222da7f033dSHerbert Xu 				.dec = {
2223da7f033dSHerbert Xu 					.vecs = fcrypt_pcbc_dec_tv_template,
2224da7f033dSHerbert Xu 					.count = FCRYPT_DEC_TEST_VECTORS
2225da7f033dSHerbert Xu 				}
2226da7f033dSHerbert Xu 			}
2227da7f033dSHerbert Xu 		}
2228da7f033dSHerbert Xu 	}, {
2229da7f033dSHerbert Xu 		.alg = "rfc3686(ctr(aes))",
22301aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2231a1915d51SJarod Wilson 		.fips_allowed = 1,
2232da7f033dSHerbert Xu 		.suite = {
2233da7f033dSHerbert Xu 			.cipher = {
2234da7f033dSHerbert Xu 				.enc = {
2235f7cb80f2SJarod Wilson 					.vecs = aes_ctr_rfc3686_enc_tv_template,
2236f7cb80f2SJarod Wilson 					.count = AES_CTR_3686_ENC_TEST_VECTORS
2237da7f033dSHerbert Xu 				},
2238da7f033dSHerbert Xu 				.dec = {
2239f7cb80f2SJarod Wilson 					.vecs = aes_ctr_rfc3686_dec_tv_template,
2240f7cb80f2SJarod Wilson 					.count = AES_CTR_3686_DEC_TEST_VECTORS
2241da7f033dSHerbert Xu 				}
2242da7f033dSHerbert Xu 			}
2243da7f033dSHerbert Xu 		}
2244da7f033dSHerbert Xu 	}, {
22455d667322SJarod Wilson 		.alg = "rfc4309(ccm(aes))",
22465d667322SJarod Wilson 		.test = alg_test_aead,
2247a1915d51SJarod Wilson 		.fips_allowed = 1,
22485d667322SJarod Wilson 		.suite = {
22495d667322SJarod Wilson 			.aead = {
22505d667322SJarod Wilson 				.enc = {
22515d667322SJarod Wilson 					.vecs = aes_ccm_rfc4309_enc_tv_template,
22525d667322SJarod Wilson 					.count = AES_CCM_4309_ENC_TEST_VECTORS
22535d667322SJarod Wilson 				},
22545d667322SJarod Wilson 				.dec = {
22555d667322SJarod Wilson 					.vecs = aes_ccm_rfc4309_dec_tv_template,
22565d667322SJarod Wilson 					.count = AES_CCM_4309_DEC_TEST_VECTORS
22575d667322SJarod Wilson 				}
22585d667322SJarod Wilson 			}
22595d667322SJarod Wilson 		}
22605d667322SJarod Wilson 	}, {
2261da7f033dSHerbert Xu 		.alg = "rmd128",
2262da7f033dSHerbert Xu 		.test = alg_test_hash,
2263da7f033dSHerbert Xu 		.suite = {
2264da7f033dSHerbert Xu 			.hash = {
2265da7f033dSHerbert Xu 				.vecs = rmd128_tv_template,
2266da7f033dSHerbert Xu 				.count = RMD128_TEST_VECTORS
2267da7f033dSHerbert Xu 			}
2268da7f033dSHerbert Xu 		}
2269da7f033dSHerbert Xu 	}, {
2270da7f033dSHerbert Xu 		.alg = "rmd160",
2271da7f033dSHerbert Xu 		.test = alg_test_hash,
2272da7f033dSHerbert Xu 		.suite = {
2273da7f033dSHerbert Xu 			.hash = {
2274da7f033dSHerbert Xu 				.vecs = rmd160_tv_template,
2275da7f033dSHerbert Xu 				.count = RMD160_TEST_VECTORS
2276da7f033dSHerbert Xu 			}
2277da7f033dSHerbert Xu 		}
2278da7f033dSHerbert Xu 	}, {
2279da7f033dSHerbert Xu 		.alg = "rmd256",
2280da7f033dSHerbert Xu 		.test = alg_test_hash,
2281da7f033dSHerbert Xu 		.suite = {
2282da7f033dSHerbert Xu 			.hash = {
2283da7f033dSHerbert Xu 				.vecs = rmd256_tv_template,
2284da7f033dSHerbert Xu 				.count = RMD256_TEST_VECTORS
2285da7f033dSHerbert Xu 			}
2286da7f033dSHerbert Xu 		}
2287da7f033dSHerbert Xu 	}, {
2288da7f033dSHerbert Xu 		.alg = "rmd320",
2289da7f033dSHerbert Xu 		.test = alg_test_hash,
2290da7f033dSHerbert Xu 		.suite = {
2291da7f033dSHerbert Xu 			.hash = {
2292da7f033dSHerbert Xu 				.vecs = rmd320_tv_template,
2293da7f033dSHerbert Xu 				.count = RMD320_TEST_VECTORS
2294da7f033dSHerbert Xu 			}
2295da7f033dSHerbert Xu 		}
2296da7f033dSHerbert Xu 	}, {
2297da7f033dSHerbert Xu 		.alg = "salsa20",
22981aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2299da7f033dSHerbert Xu 		.suite = {
2300da7f033dSHerbert Xu 			.cipher = {
2301da7f033dSHerbert Xu 				.enc = {
2302da7f033dSHerbert Xu 					.vecs = salsa20_stream_enc_tv_template,
2303da7f033dSHerbert Xu 					.count = SALSA20_STREAM_ENC_TEST_VECTORS
2304da7f033dSHerbert Xu 				}
2305da7f033dSHerbert Xu 			}
2306da7f033dSHerbert Xu 		}
2307da7f033dSHerbert Xu 	}, {
2308da7f033dSHerbert Xu 		.alg = "sha1",
2309da7f033dSHerbert Xu 		.test = alg_test_hash,
2310a1915d51SJarod Wilson 		.fips_allowed = 1,
2311da7f033dSHerbert Xu 		.suite = {
2312da7f033dSHerbert Xu 			.hash = {
2313da7f033dSHerbert Xu 				.vecs = sha1_tv_template,
2314da7f033dSHerbert Xu 				.count = SHA1_TEST_VECTORS
2315da7f033dSHerbert Xu 			}
2316da7f033dSHerbert Xu 		}
2317da7f033dSHerbert Xu 	}, {
2318da7f033dSHerbert Xu 		.alg = "sha224",
2319da7f033dSHerbert Xu 		.test = alg_test_hash,
2320a1915d51SJarod Wilson 		.fips_allowed = 1,
2321da7f033dSHerbert Xu 		.suite = {
2322da7f033dSHerbert Xu 			.hash = {
2323da7f033dSHerbert Xu 				.vecs = sha224_tv_template,
2324da7f033dSHerbert Xu 				.count = SHA224_TEST_VECTORS
2325da7f033dSHerbert Xu 			}
2326da7f033dSHerbert Xu 		}
2327da7f033dSHerbert Xu 	}, {
2328da7f033dSHerbert Xu 		.alg = "sha256",
2329da7f033dSHerbert Xu 		.test = alg_test_hash,
2330a1915d51SJarod Wilson 		.fips_allowed = 1,
2331da7f033dSHerbert Xu 		.suite = {
2332da7f033dSHerbert Xu 			.hash = {
2333da7f033dSHerbert Xu 				.vecs = sha256_tv_template,
2334da7f033dSHerbert Xu 				.count = SHA256_TEST_VECTORS
2335da7f033dSHerbert Xu 			}
2336da7f033dSHerbert Xu 		}
2337da7f033dSHerbert Xu 	}, {
2338da7f033dSHerbert Xu 		.alg = "sha384",
2339da7f033dSHerbert Xu 		.test = alg_test_hash,
2340a1915d51SJarod Wilson 		.fips_allowed = 1,
2341da7f033dSHerbert Xu 		.suite = {
2342da7f033dSHerbert Xu 			.hash = {
2343da7f033dSHerbert Xu 				.vecs = sha384_tv_template,
2344da7f033dSHerbert Xu 				.count = SHA384_TEST_VECTORS
2345da7f033dSHerbert Xu 			}
2346da7f033dSHerbert Xu 		}
2347da7f033dSHerbert Xu 	}, {
2348da7f033dSHerbert Xu 		.alg = "sha512",
2349da7f033dSHerbert Xu 		.test = alg_test_hash,
2350a1915d51SJarod Wilson 		.fips_allowed = 1,
2351da7f033dSHerbert Xu 		.suite = {
2352da7f033dSHerbert Xu 			.hash = {
2353da7f033dSHerbert Xu 				.vecs = sha512_tv_template,
2354da7f033dSHerbert Xu 				.count = SHA512_TEST_VECTORS
2355da7f033dSHerbert Xu 			}
2356da7f033dSHerbert Xu 		}
2357da7f033dSHerbert Xu 	}, {
2358da7f033dSHerbert Xu 		.alg = "tgr128",
2359da7f033dSHerbert Xu 		.test = alg_test_hash,
2360da7f033dSHerbert Xu 		.suite = {
2361da7f033dSHerbert Xu 			.hash = {
2362da7f033dSHerbert Xu 				.vecs = tgr128_tv_template,
2363da7f033dSHerbert Xu 				.count = TGR128_TEST_VECTORS
2364da7f033dSHerbert Xu 			}
2365da7f033dSHerbert Xu 		}
2366da7f033dSHerbert Xu 	}, {
2367da7f033dSHerbert Xu 		.alg = "tgr160",
2368da7f033dSHerbert Xu 		.test = alg_test_hash,
2369da7f033dSHerbert Xu 		.suite = {
2370da7f033dSHerbert Xu 			.hash = {
2371da7f033dSHerbert Xu 				.vecs = tgr160_tv_template,
2372da7f033dSHerbert Xu 				.count = TGR160_TEST_VECTORS
2373da7f033dSHerbert Xu 			}
2374da7f033dSHerbert Xu 		}
2375da7f033dSHerbert Xu 	}, {
2376da7f033dSHerbert Xu 		.alg = "tgr192",
2377da7f033dSHerbert Xu 		.test = alg_test_hash,
2378da7f033dSHerbert Xu 		.suite = {
2379da7f033dSHerbert Xu 			.hash = {
2380da7f033dSHerbert Xu 				.vecs = tgr192_tv_template,
2381da7f033dSHerbert Xu 				.count = TGR192_TEST_VECTORS
2382da7f033dSHerbert Xu 			}
2383da7f033dSHerbert Xu 		}
2384da7f033dSHerbert Xu 	}, {
2385f1939f7cSShane Wang 		.alg = "vmac(aes)",
2386f1939f7cSShane Wang 		.test = alg_test_hash,
2387f1939f7cSShane Wang 		.suite = {
2388f1939f7cSShane Wang 			.hash = {
2389f1939f7cSShane Wang 				.vecs = aes_vmac128_tv_template,
2390f1939f7cSShane Wang 				.count = VMAC_AES_TEST_VECTORS
2391f1939f7cSShane Wang 			}
2392f1939f7cSShane Wang 		}
2393f1939f7cSShane Wang 	}, {
2394da7f033dSHerbert Xu 		.alg = "wp256",
2395da7f033dSHerbert Xu 		.test = alg_test_hash,
2396da7f033dSHerbert Xu 		.suite = {
2397da7f033dSHerbert Xu 			.hash = {
2398da7f033dSHerbert Xu 				.vecs = wp256_tv_template,
2399da7f033dSHerbert Xu 				.count = WP256_TEST_VECTORS
2400da7f033dSHerbert Xu 			}
2401da7f033dSHerbert Xu 		}
2402da7f033dSHerbert Xu 	}, {
2403da7f033dSHerbert Xu 		.alg = "wp384",
2404da7f033dSHerbert Xu 		.test = alg_test_hash,
2405da7f033dSHerbert Xu 		.suite = {
2406da7f033dSHerbert Xu 			.hash = {
2407da7f033dSHerbert Xu 				.vecs = wp384_tv_template,
2408da7f033dSHerbert Xu 				.count = WP384_TEST_VECTORS
2409da7f033dSHerbert Xu 			}
2410da7f033dSHerbert Xu 		}
2411da7f033dSHerbert Xu 	}, {
2412da7f033dSHerbert Xu 		.alg = "wp512",
2413da7f033dSHerbert Xu 		.test = alg_test_hash,
2414da7f033dSHerbert Xu 		.suite = {
2415da7f033dSHerbert Xu 			.hash = {
2416da7f033dSHerbert Xu 				.vecs = wp512_tv_template,
2417da7f033dSHerbert Xu 				.count = WP512_TEST_VECTORS
2418da7f033dSHerbert Xu 			}
2419da7f033dSHerbert Xu 		}
2420da7f033dSHerbert Xu 	}, {
2421da7f033dSHerbert Xu 		.alg = "xcbc(aes)",
2422da7f033dSHerbert Xu 		.test = alg_test_hash,
2423da7f033dSHerbert Xu 		.suite = {
2424da7f033dSHerbert Xu 			.hash = {
2425da7f033dSHerbert Xu 				.vecs = aes_xcbc128_tv_template,
2426da7f033dSHerbert Xu 				.count = XCBC_AES_TEST_VECTORS
2427da7f033dSHerbert Xu 			}
2428da7f033dSHerbert Xu 		}
2429da7f033dSHerbert Xu 	}, {
2430da7f033dSHerbert Xu 		.alg = "xts(aes)",
24311aa4ecd9SHerbert Xu 		.test = alg_test_skcipher,
2432da7f033dSHerbert Xu 		.suite = {
2433da7f033dSHerbert Xu 			.cipher = {
2434da7f033dSHerbert Xu 				.enc = {
2435da7f033dSHerbert Xu 					.vecs = aes_xts_enc_tv_template,
2436da7f033dSHerbert Xu 					.count = AES_XTS_ENC_TEST_VECTORS
2437da7f033dSHerbert Xu 				},
2438da7f033dSHerbert Xu 				.dec = {
2439da7f033dSHerbert Xu 					.vecs = aes_xts_dec_tv_template,
2440da7f033dSHerbert Xu 					.count = AES_XTS_DEC_TEST_VECTORS
2441da7f033dSHerbert Xu 				}
2442da7f033dSHerbert Xu 			}
2443da7f033dSHerbert Xu 		}
24440c01aed5SGeert Uytterhoeven 	}, {
24450c01aed5SGeert Uytterhoeven 		.alg = "zlib",
24460c01aed5SGeert Uytterhoeven 		.test = alg_test_pcomp,
24470c01aed5SGeert Uytterhoeven 		.suite = {
24480c01aed5SGeert Uytterhoeven 			.pcomp = {
24490c01aed5SGeert Uytterhoeven 				.comp = {
24500c01aed5SGeert Uytterhoeven 					.vecs = zlib_comp_tv_template,
24510c01aed5SGeert Uytterhoeven 					.count = ZLIB_COMP_TEST_VECTORS
24520c01aed5SGeert Uytterhoeven 				},
24530c01aed5SGeert Uytterhoeven 				.decomp = {
24540c01aed5SGeert Uytterhoeven 					.vecs = zlib_decomp_tv_template,
24550c01aed5SGeert Uytterhoeven 					.count = ZLIB_DECOMP_TEST_VECTORS
24560c01aed5SGeert Uytterhoeven 				}
24570c01aed5SGeert Uytterhoeven 			}
24580c01aed5SGeert Uytterhoeven 		}
2459da7f033dSHerbert Xu 	}
2460da7f033dSHerbert Xu };
2461da7f033dSHerbert Xu 
24621aa4ecd9SHerbert Xu static int alg_find_test(const char *alg)
2463da7f033dSHerbert Xu {
2464da7f033dSHerbert Xu 	int start = 0;
2465da7f033dSHerbert Xu 	int end = ARRAY_SIZE(alg_test_descs);
2466da7f033dSHerbert Xu 
2467da7f033dSHerbert Xu 	while (start < end) {
2468da7f033dSHerbert Xu 		int i = (start + end) / 2;
2469da7f033dSHerbert Xu 		int diff = strcmp(alg_test_descs[i].alg, alg);
2470da7f033dSHerbert Xu 
2471da7f033dSHerbert Xu 		if (diff > 0) {
2472da7f033dSHerbert Xu 			end = i;
2473da7f033dSHerbert Xu 			continue;
2474da7f033dSHerbert Xu 		}
2475da7f033dSHerbert Xu 
2476da7f033dSHerbert Xu 		if (diff < 0) {
2477da7f033dSHerbert Xu 			start = i + 1;
2478da7f033dSHerbert Xu 			continue;
2479da7f033dSHerbert Xu 		}
2480da7f033dSHerbert Xu 
24811aa4ecd9SHerbert Xu 		return i;
2482da7f033dSHerbert Xu 	}
2483da7f033dSHerbert Xu 
24841aa4ecd9SHerbert Xu 	return -1;
24851aa4ecd9SHerbert Xu }
24861aa4ecd9SHerbert Xu 
24871aa4ecd9SHerbert Xu int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
24881aa4ecd9SHerbert Xu {
24891aa4ecd9SHerbert Xu 	int i;
2490a68f6610SHerbert Xu 	int j;
2491d12d6b6dSNeil Horman 	int rc;
24921aa4ecd9SHerbert Xu 
24931aa4ecd9SHerbert Xu 	if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) {
24941aa4ecd9SHerbert Xu 		char nalg[CRYPTO_MAX_ALG_NAME];
24951aa4ecd9SHerbert Xu 
24961aa4ecd9SHerbert Xu 		if (snprintf(nalg, sizeof(nalg), "ecb(%s)", alg) >=
24971aa4ecd9SHerbert Xu 		    sizeof(nalg))
24981aa4ecd9SHerbert Xu 			return -ENAMETOOLONG;
24991aa4ecd9SHerbert Xu 
25001aa4ecd9SHerbert Xu 		i = alg_find_test(nalg);
25011aa4ecd9SHerbert Xu 		if (i < 0)
25021aa4ecd9SHerbert Xu 			goto notest;
25031aa4ecd9SHerbert Xu 
2504a3bef3a3SJarod Wilson 		if (fips_enabled && !alg_test_descs[i].fips_allowed)
2505a3bef3a3SJarod Wilson 			goto non_fips_alg;
2506a3bef3a3SJarod Wilson 
2507941fb328SJarod Wilson 		rc = alg_test_cipher(alg_test_descs + i, driver, type, mask);
2508941fb328SJarod Wilson 		goto test_done;
25091aa4ecd9SHerbert Xu 	}
25101aa4ecd9SHerbert Xu 
25111aa4ecd9SHerbert Xu 	i = alg_find_test(alg);
2512a68f6610SHerbert Xu 	j = alg_find_test(driver);
2513a68f6610SHerbert Xu 	if (i < 0 && j < 0)
25141aa4ecd9SHerbert Xu 		goto notest;
25151aa4ecd9SHerbert Xu 
2516a68f6610SHerbert Xu 	if (fips_enabled && ((i >= 0 && !alg_test_descs[i].fips_allowed) ||
2517a68f6610SHerbert Xu 			     (j >= 0 && !alg_test_descs[j].fips_allowed)))
2518a3bef3a3SJarod Wilson 		goto non_fips_alg;
2519a3bef3a3SJarod Wilson 
2520a68f6610SHerbert Xu 	rc = 0;
2521a68f6610SHerbert Xu 	if (i >= 0)
2522a68f6610SHerbert Xu 		rc |= alg_test_descs[i].test(alg_test_descs + i, driver,
25231aa4ecd9SHerbert Xu 					     type, mask);
2524a68f6610SHerbert Xu 	if (j >= 0)
2525a68f6610SHerbert Xu 		rc |= alg_test_descs[j].test(alg_test_descs + j, driver,
2526a68f6610SHerbert Xu 					     type, mask);
2527a68f6610SHerbert Xu 
2528941fb328SJarod Wilson test_done:
2529d12d6b6dSNeil Horman 	if (fips_enabled && rc)
2530d12d6b6dSNeil Horman 		panic("%s: %s alg self test failed in fips mode!\n", driver, alg);
2531d12d6b6dSNeil Horman 
253229ecd4abSJarod Wilson 	if (fips_enabled && !rc)
253329ecd4abSJarod Wilson 		printk(KERN_INFO "alg: self-tests for %s (%s) passed\n",
253429ecd4abSJarod Wilson 		       driver, alg);
253529ecd4abSJarod Wilson 
2536d12d6b6dSNeil Horman 	return rc;
25371aa4ecd9SHerbert Xu 
25381aa4ecd9SHerbert Xu notest:
2539da7f033dSHerbert Xu 	printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver);
2540da7f033dSHerbert Xu 	return 0;
2541a3bef3a3SJarod Wilson non_fips_alg:
2542a3bef3a3SJarod Wilson 	return -EINVAL;
2543da7f033dSHerbert Xu }
25440b767f96SAlexander Shishkin 
2545326a6346SHerbert Xu #endif /* CONFIG_CRYPTO_MANAGER_DISABLE_TESTS */
25460b767f96SAlexander Shishkin 
2547da7f033dSHerbert Xu EXPORT_SYMBOL_GPL(alg_test);
2548