Commit 99585c21 authored by Herbert Xu's avatar Herbert Xu
Browse files

crypto: testmgr - Add multibuffer acomp testing



Add rudimentary multibuffer acomp testing.  Testing coverage is
extended to compression vectors only.  However, as the compression
vectors are compressed and then decompressed, this covers both
compression and decompression.

Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 39fc22a8
Loading
Loading
Loading
Loading
+80 −64
Original line number Diff line number Diff line
@@ -3438,27 +3438,48 @@ static int test_acomp(struct crypto_acomp *tfm,
		      int ctcount, int dtcount)
{
	const char *algo = crypto_tfm_alg_driver_name(crypto_acomp_tfm(tfm));
	unsigned int i;
	char *output, *decomp_out;
	int ret;
	struct scatterlist src, dst;
	struct acomp_req *req;
	struct scatterlist *src = NULL, *dst = NULL;
	struct acomp_req *reqs[MAX_MB_MSGS] = {};
	char *decomp_out[MAX_MB_MSGS] = {};
	char *output[MAX_MB_MSGS] = {};
	struct crypto_wait wait;
	struct acomp_req *req;
	int ret = -ENOMEM;
	unsigned int i;

	output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL);
	if (!output)
		return -ENOMEM;
	src = kmalloc_array(MAX_MB_MSGS, sizeof(*src), GFP_KERNEL);
	if (!src)
		goto out;
	dst = kmalloc_array(MAX_MB_MSGS, sizeof(*dst), GFP_KERNEL);
	if (!dst)
		goto out;

	decomp_out = kmalloc(COMP_BUF_SIZE, GFP_KERNEL);
	if (!decomp_out) {
		kfree(output);
		return -ENOMEM;
	for (i = 0; i < MAX_MB_MSGS; i++) {
		reqs[i] = acomp_request_alloc(tfm);
		if (!reqs[i])
			goto out;

		acomp_request_set_callback(reqs[i],
					   CRYPTO_TFM_REQ_MAY_SLEEP |
					   CRYPTO_TFM_REQ_MAY_BACKLOG,
					   crypto_req_done, &wait);
		if (i)
			acomp_request_chain(reqs[i], reqs[0]);

		output[i] = kmalloc(COMP_BUF_SIZE, GFP_KERNEL);
		if (!output[i])
			goto out;

		decomp_out[i] = kmalloc(COMP_BUF_SIZE, GFP_KERNEL);
		if (!decomp_out[i])
			goto out;
	}

	for (i = 0; i < ctcount; i++) {
		unsigned int dlen = COMP_BUF_SIZE;
		int ilen = ctemplate[i].inlen;
		void *input_vec;
		int j;

		input_vec = kmemdup(ctemplate[i].input, ilen, GFP_KERNEL);
		if (!input_vec) {
@@ -3466,70 +3487,61 @@ static int test_acomp(struct crypto_acomp *tfm,
			goto out;
		}

		memset(output, 0, dlen);
		crypto_init_wait(&wait);
		sg_init_one(&src, input_vec, ilen);
		sg_init_one(&dst, output, dlen);
		sg_init_one(src, input_vec, ilen);

		req = acomp_request_alloc(tfm);
		if (!req) {
			pr_err("alg: acomp: request alloc failed for %s\n",
			       algo);
			kfree(input_vec);
			ret = -ENOMEM;
			goto out;
		for (j = 0; j < MAX_MB_MSGS; j++) {
			sg_init_one(dst + j, output[j], dlen);
			acomp_request_set_params(reqs[j], src, dst + j, ilen, dlen);
		}

		acomp_request_set_params(req, &src, &dst, ilen, dlen);
		acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
					   crypto_req_done, &wait);

		req = reqs[0];
		ret = crypto_wait_req(crypto_acomp_compress(req), &wait);
		if (ret) {
			pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n",
			       i + 1, algo, -ret);
			kfree(input_vec);
			acomp_request_free(req);
			goto out;
		}

		ilen = req->dlen;
		dlen = COMP_BUF_SIZE;
		sg_init_one(&src, output, ilen);
		sg_init_one(&dst, decomp_out, dlen);
		crypto_init_wait(&wait);
		acomp_request_set_params(req, &src, &dst, ilen, dlen);
		for (j = 0; j < MAX_MB_MSGS; j++) {
			sg_init_one(src + j, output[j], ilen);
			sg_init_one(dst + j, decomp_out[j], dlen);
			acomp_request_set_params(reqs[j], src + j, dst + j, ilen, dlen);
		}

		ret = crypto_wait_req(crypto_acomp_decompress(req), &wait);
		crypto_wait_req(crypto_acomp_decompress(req), &wait);
		for (j = 0; j < MAX_MB_MSGS; j++) {
			ret = reqs[j]->base.err;
			if (ret) {
			pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n",
			       i + 1, algo, -ret);
				pr_err("alg: acomp: compression failed on test %d (%d) for %s: ret=%d\n",
				       i + 1, j, algo, -ret);
				kfree(input_vec);
			acomp_request_free(req);
				goto out;
			}

		if (req->dlen != ctemplate[i].inlen) {
			pr_err("alg: acomp: Compression test %d failed for %s: output len = %d\n",
			       i + 1, algo, req->dlen);
			if (reqs[j]->dlen != ctemplate[i].inlen) {
				pr_err("alg: acomp: Compression test %d (%d) failed for %s: output len = %d\n",
				       i + 1, j, algo, reqs[j]->dlen);
				ret = -EINVAL;
				kfree(input_vec);
			acomp_request_free(req);
				goto out;
			}

		if (memcmp(input_vec, decomp_out, req->dlen)) {
			pr_err("alg: acomp: Compression test %d failed for %s\n",
			       i + 1, algo);
			hexdump(output, req->dlen);
			if (memcmp(input_vec, decomp_out[j], reqs[j]->dlen)) {
				pr_err("alg: acomp: Compression test %d (%d) failed for %s\n",
				       i + 1, j, algo);
				hexdump(output[j], reqs[j]->dlen);
				ret = -EINVAL;
				kfree(input_vec);
			acomp_request_free(req);
				goto out;
			}
		}

		kfree(input_vec);
		acomp_request_free(req);
	}

	for (i = 0; i < dtcount; i++) {
@@ -3543,10 +3555,9 @@ static int test_acomp(struct crypto_acomp *tfm,
			goto out;
		}

		memset(output, 0, dlen);
		crypto_init_wait(&wait);
		sg_init_one(&src, input_vec, ilen);
		sg_init_one(&dst, output, dlen);
		sg_init_one(src, input_vec, ilen);
		sg_init_one(dst, output[0], dlen);

		req = acomp_request_alloc(tfm);
		if (!req) {
@@ -3557,7 +3568,7 @@ static int test_acomp(struct crypto_acomp *tfm,
			goto out;
		}

		acomp_request_set_params(req, &src, &dst, ilen, dlen);
		acomp_request_set_params(req, src, dst, ilen, dlen);
		acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
					   crypto_req_done, &wait);

@@ -3579,10 +3590,10 @@ static int test_acomp(struct crypto_acomp *tfm,
			goto out;
		}

		if (memcmp(output, dtemplate[i].output, req->dlen)) {
		if (memcmp(output[0], dtemplate[i].output, req->dlen)) {
			pr_err("alg: acomp: Decompression test %d failed for %s\n",
			       i + 1, algo);
			hexdump(output, req->dlen);
			hexdump(output[0], req->dlen);
			ret = -EINVAL;
			kfree(input_vec);
			acomp_request_free(req);
@@ -3596,8 +3607,13 @@ static int test_acomp(struct crypto_acomp *tfm,
	ret = 0;

out:
	kfree(decomp_out);
	kfree(output);
	acomp_request_free(reqs[0]);
	for (i = 0; i < MAX_MB_MSGS; i++) {
		kfree(output[i]);
		kfree(decomp_out[i]);
	}
	kfree(dst);
	kfree(src);
	return ret;
}