crypto: testmgr - make test_skcipher also test 'dst != src' code paths

Currrently test_skcipher uses same buffer for destination and source. However
in any places, 'dst != src' take different path than 'dst == src' case.

Therefore make test_skcipher also run tests with destination buffer being
different than source buffer.

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Jussi Kivilinna 2012-09-21 10:26:47 +03:00 committed by Herbert Xu
parent 549595a0c7
commit 08d6af8c16

View file

@ -761,8 +761,9 @@ out_nobuf:
return ret; return ret;
} }
static int test_skcipher(struct crypto_ablkcipher *tfm, int enc, static int __test_skcipher(struct crypto_ablkcipher *tfm, int enc,
struct cipher_testvec *template, unsigned int tcount) struct cipher_testvec *template, unsigned int tcount,
const bool diff_dst)
{ {
const char *algo = const char *algo =
crypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm)); crypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm));
@ -770,16 +771,26 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
char *q; char *q;
struct ablkcipher_request *req; struct ablkcipher_request *req;
struct scatterlist sg[8]; struct scatterlist sg[8];
const char *e; struct scatterlist sgout[8];
const char *e, *d;
struct tcrypt_result result; struct tcrypt_result result;
void *data; void *data;
char iv[MAX_IVLEN]; char iv[MAX_IVLEN];
char *xbuf[XBUFSIZE]; char *xbuf[XBUFSIZE];
char *xoutbuf[XBUFSIZE];
int ret = -ENOMEM; int ret = -ENOMEM;
if (testmgr_alloc_buf(xbuf)) if (testmgr_alloc_buf(xbuf))
goto out_nobuf; goto out_nobuf;
if (diff_dst && testmgr_alloc_buf(xoutbuf))
goto out_nooutbuf;
if (diff_dst)
d = "-ddst";
else
d = "";
if (enc == ENCRYPT) if (enc == ENCRYPT)
e = "encryption"; e = "encryption";
else else
@ -789,8 +800,8 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
req = ablkcipher_request_alloc(tfm, GFP_KERNEL); req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
if (!req) { if (!req) {
printk(KERN_ERR "alg: skcipher: Failed to allocate request " pr_err("alg: skcipher%s: Failed to allocate request for %s\n",
"for %s\n", algo); d, algo);
goto out; goto out;
} }
@ -822,16 +833,21 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
ret = crypto_ablkcipher_setkey(tfm, template[i].key, ret = crypto_ablkcipher_setkey(tfm, template[i].key,
template[i].klen); template[i].klen);
if (!ret == template[i].fail) { if (!ret == template[i].fail) {
printk(KERN_ERR "alg: skcipher: setkey failed " pr_err("alg: skcipher%s: setkey failed on test %d for %s: flags=%x\n",
"on test %d for %s: flags=%x\n", j, d, j, algo,
algo, crypto_ablkcipher_get_flags(tfm)); crypto_ablkcipher_get_flags(tfm));
goto out; goto out;
} else if (ret) } else if (ret)
continue; continue;
sg_init_one(&sg[0], data, template[i].ilen); sg_init_one(&sg[0], data, template[i].ilen);
if (diff_dst) {
data = xoutbuf[0];
sg_init_one(&sgout[0], data, template[i].ilen);
}
ablkcipher_request_set_crypt(req, sg, sg, ablkcipher_request_set_crypt(req, sg,
(diff_dst) ? sgout : sg,
template[i].ilen, iv); template[i].ilen, iv);
ret = enc ? ret = enc ?
crypto_ablkcipher_encrypt(req) : crypto_ablkcipher_encrypt(req) :
@ -850,16 +866,15 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
} }
/* fall through */ /* fall through */
default: default:
printk(KERN_ERR "alg: skcipher: %s failed on " pr_err("alg: skcipher%s: %s failed on test %d for %s: ret=%d\n",
"test %d for %s: ret=%d\n", e, j, algo, d, e, j, algo, -ret);
-ret);
goto out; goto out;
} }
q = data; q = data;
if (memcmp(q, template[i].result, template[i].rlen)) { if (memcmp(q, template[i].result, template[i].rlen)) {
printk(KERN_ERR "alg: skcipher: Test %d " pr_err("alg: skcipher%s: Test %d failed on %s for %s\n",
"failed on %s for %s\n", j, e, algo); d, j, e, algo);
hexdump(q, template[i].rlen); hexdump(q, template[i].rlen);
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
@ -886,9 +901,8 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
ret = crypto_ablkcipher_setkey(tfm, template[i].key, ret = crypto_ablkcipher_setkey(tfm, template[i].key,
template[i].klen); template[i].klen);
if (!ret == template[i].fail) { if (!ret == template[i].fail) {
printk(KERN_ERR "alg: skcipher: setkey failed " pr_err("alg: skcipher%s: setkey failed on chunk test %d for %s: flags=%x\n",
"on chunk test %d for %s: flags=%x\n", d, j, algo,
j, algo,
crypto_ablkcipher_get_flags(tfm)); crypto_ablkcipher_get_flags(tfm));
goto out; goto out;
} else if (ret) } else if (ret)
@ -897,6 +911,8 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
temp = 0; temp = 0;
ret = -EINVAL; ret = -EINVAL;
sg_init_table(sg, template[i].np); sg_init_table(sg, template[i].np);
if (diff_dst)
sg_init_table(sgout, template[i].np);
for (k = 0; k < template[i].np; k++) { for (k = 0; k < template[i].np; k++) {
if (WARN_ON(offset_in_page(IDX[k]) + if (WARN_ON(offset_in_page(IDX[k]) +
template[i].tap[k] > PAGE_SIZE)) template[i].tap[k] > PAGE_SIZE))
@ -913,11 +929,24 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
q[template[i].tap[k]] = 0; q[template[i].tap[k]] = 0;
sg_set_buf(&sg[k], q, template[i].tap[k]); sg_set_buf(&sg[k], q, template[i].tap[k]);
if (diff_dst) {
q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
offset_in_page(IDX[k]);
sg_set_buf(&sgout[k], q,
template[i].tap[k]);
memset(q, 0, template[i].tap[k]);
if (offset_in_page(q) +
template[i].tap[k] < PAGE_SIZE)
q[template[i].tap[k]] = 0;
}
temp += template[i].tap[k]; temp += template[i].tap[k];
} }
ablkcipher_request_set_crypt(req, sg, sg, ablkcipher_request_set_crypt(req, sg,
(diff_dst) ? sgout : sg,
template[i].ilen, iv); template[i].ilen, iv);
ret = enc ? ret = enc ?
@ -937,23 +966,25 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
} }
/* fall through */ /* fall through */
default: default:
printk(KERN_ERR "alg: skcipher: %s failed on " pr_err("alg: skcipher%s: %s failed on chunk test %d for %s: ret=%d\n",
"chunk test %d for %s: ret=%d\n", e, j, d, e, j, algo, -ret);
algo, -ret);
goto out; goto out;
} }
temp = 0; temp = 0;
ret = -EINVAL; ret = -EINVAL;
for (k = 0; k < template[i].np; k++) { for (k = 0; k < template[i].np; k++) {
q = xbuf[IDX[k] >> PAGE_SHIFT] + if (diff_dst)
offset_in_page(IDX[k]); q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
offset_in_page(IDX[k]);
else
q = xbuf[IDX[k] >> PAGE_SHIFT] +
offset_in_page(IDX[k]);
if (memcmp(q, template[i].result + temp, if (memcmp(q, template[i].result + temp,
template[i].tap[k])) { template[i].tap[k])) {
printk(KERN_ERR "alg: skcipher: Chunk " pr_err("alg: skcipher%s: Chunk test %d failed on %s at page %u for %s\n",
"test %d failed on %s at page " d, j, e, k, algo);
"%u for %s\n", j, e, k, algo);
hexdump(q, template[i].tap[k]); hexdump(q, template[i].tap[k]);
goto out; goto out;
} }
@ -962,11 +993,8 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
for (n = 0; offset_in_page(q + n) && q[n]; n++) for (n = 0; offset_in_page(q + n) && q[n]; n++)
; ;
if (n) { if (n) {
printk(KERN_ERR "alg: skcipher: " pr_err("alg: skcipher%s: Result buffer corruption in chunk test %d on %s at page %u for %s: %u bytes:\n",
"Result buffer corruption in " d, j, e, k, algo, n);
"chunk test %d on %s at page "
"%u for %s: %u bytes:\n", j, e,
k, algo, n);
hexdump(q, n); hexdump(q, n);
goto out; goto out;
} }
@ -979,11 +1007,28 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
out: out:
ablkcipher_request_free(req); ablkcipher_request_free(req);
if (diff_dst)
testmgr_free_buf(xoutbuf);
out_nooutbuf:
testmgr_free_buf(xbuf); testmgr_free_buf(xbuf);
out_nobuf: out_nobuf:
return ret; return ret;
} }
static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
struct cipher_testvec *template, unsigned int tcount)
{
int ret;
/* test 'dst == src' case */
ret = __test_skcipher(tfm, enc, template, tcount, false);
if (ret)
return ret;
/* test 'dst != src' case */
return __test_skcipher(tfm, enc, template, tcount, true);
}
static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate, static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate,
struct comp_testvec *dtemplate, int ctcount, int dtcount) struct comp_testvec *dtemplate, int ctcount, int dtcount)
{ {