[CRYPTO] tcrypt: Change the usage of the test vectors
The test routines (test_{cipher,hash,aead}) are makeing a copy
of the test template and are processing the encryption process
in place. This patch changes the creation of the copy so it will
work even if the source address of the input data isn't an array
inside of the template but a pointer.
Signed-off-by: Sebastian Siewior <sebastian@breakpoint.cc>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 6b8315b..30e75d4 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -113,23 +113,11 @@
char result[64];
struct crypto_hash *tfm;
struct hash_desc desc;
- struct hash_testvec *hash_tv;
- unsigned int tsize;
int ret;
+ void *hash_buff;
printk("\ntesting %s\n", algo);
- tsize = sizeof(struct hash_testvec);
- tsize *= tcount;
-
- if (tsize > TVMEMSIZE) {
- printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE);
- return;
- }
-
- memcpy(tvmem, template, tsize);
- hash_tv = (void *)tvmem;
-
tfm = crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(tfm)) {
printk("failed to load transform for %s: %ld\n", algo,
@@ -144,28 +132,36 @@
printk("test %u:\n", i + 1);
memset(result, 0, 64);
- sg_init_one(&sg[0], hash_tv[i].plaintext, hash_tv[i].psize);
+ hash_buff = kzalloc(template[i].psize, GFP_KERNEL);
+ if (!hash_buff)
+ continue;
- if (hash_tv[i].ksize) {
- ret = crypto_hash_setkey(tfm, hash_tv[i].key,
- hash_tv[i].ksize);
+ memcpy(hash_buff, template[i].plaintext, template[i].psize);
+ sg_init_one(&sg[0], hash_buff, template[i].psize);
+
+ if (template[i].ksize) {
+ ret = crypto_hash_setkey(tfm, template[i].key,
+ template[i].ksize);
if (ret) {
printk("setkey() failed ret=%d\n", ret);
+ kfree(hash_buff);
goto out;
}
}
- ret = crypto_hash_digest(&desc, sg, hash_tv[i].psize, result);
+ ret = crypto_hash_digest(&desc, sg, template[i].psize, result);
if (ret) {
printk("digest () failed ret=%d\n", ret);
+ kfree(hash_buff);
goto out;
}
hexdump(result, crypto_hash_digestsize(tfm));
printk("%s\n",
- memcmp(result, hash_tv[i].digest,
+ memcmp(result, template[i].digest,
crypto_hash_digestsize(tfm)) ?
"fail" : "pass");
+ kfree(hash_buff);
}
printk("testing %s across pages\n", algo);
@@ -175,25 +171,25 @@
j = 0;
for (i = 0; i < tcount; i++) {
- if (hash_tv[i].np) {
+ if (template[i].np) {
j++;
printk("test %u:\n", j);
memset(result, 0, 64);
temp = 0;
- sg_init_table(sg, hash_tv[i].np);
- for (k = 0; k < hash_tv[i].np; k++) {
+ sg_init_table(sg, template[i].np);
+ for (k = 0; k < template[i].np; k++) {
memcpy(&xbuf[IDX[k]],
- hash_tv[i].plaintext + temp,
- hash_tv[i].tap[k]);
- temp += hash_tv[i].tap[k];
+ template[i].plaintext + temp,
+ template[i].tap[k]);
+ temp += template[i].tap[k];
sg_set_buf(&sg[k], &xbuf[IDX[k]],
- hash_tv[i].tap[k]);
+ template[i].tap[k]);
}
- if (hash_tv[i].ksize) {
- ret = crypto_hash_setkey(tfm, hash_tv[i].key,
- hash_tv[i].ksize);
+ if (template[i].ksize) {
+ ret = crypto_hash_setkey(tfm, template[i].key,
+ template[i].ksize);
if (ret) {
printk("setkey() failed ret=%d\n", ret);
@@ -201,7 +197,7 @@
}
}
- ret = crypto_hash_digest(&desc, sg, hash_tv[i].psize,
+ ret = crypto_hash_digest(&desc, sg, template[i].psize,
result);
if (ret) {
printk("digest () failed ret=%d\n", ret);
@@ -210,7 +206,7 @@
hexdump(result, crypto_hash_digestsize(tfm));
printk("%s\n",
- memcmp(result, hash_tv[i].digest,
+ memcmp(result, template[i].digest,
crypto_hash_digestsize(tfm)) ?
"fail" : "pass");
}
@@ -224,17 +220,18 @@
unsigned int tcount)
{
unsigned int ret, i, j, k, temp;
- unsigned int tsize;
char *q;
struct crypto_aead *tfm;
char *key;
- struct aead_testvec *aead_tv;
struct aead_request *req;
struct scatterlist sg[8];
struct scatterlist asg[8];
const char *e;
struct tcrypt_result result;
unsigned int authsize;
+ void *input;
+ void *assoc;
+ char iv[MAX_IVLEN];
if (enc == ENCRYPT)
e = "encryption";
@@ -243,18 +240,6 @@
printk(KERN_INFO "\ntesting %s %s\n", algo, e);
- tsize = sizeof(struct aead_testvec);
- tsize *= tcount;
-
- if (tsize > TVMEMSIZE) {
- printk(KERN_INFO "template (%u) too big for tvmem (%u)\n",
- tsize, TVMEMSIZE);
- return;
- }
-
- memcpy(tvmem, template, tsize);
- aead_tv = (void *)tvmem;
-
init_completion(&result.completion);
tfm = crypto_alloc_aead(algo, 0, 0);
@@ -275,46 +260,68 @@
tcrypt_complete, &result);
for (i = 0, j = 0; i < tcount; i++) {
- if (!aead_tv[i].np) {
+ if (!template[i].np) {
printk(KERN_INFO "test %u (%d bit key):\n",
- ++j, aead_tv[i].klen * 8);
+ ++j, template[i].klen * 8);
+
+ /* some tepmplates have no input data but they will
+ * touch input
+ */
+ input = kzalloc(template[i].ilen + template[i].rlen, GFP_KERNEL);
+ if (!input)
+ continue;
+
+ assoc = kzalloc(template[i].alen, GFP_KERNEL);
+ if (!assoc) {
+ kfree(input);
+ continue;
+ }
+
+ memcpy(input, template[i].input, template[i].ilen);
+ memcpy(assoc, template[i].assoc, template[i].alen);
+ if (template[i].iv)
+ memcpy(iv, template[i].iv, MAX_IVLEN);
+ else
+ memset(iv, 0, MAX_IVLEN);
crypto_aead_clear_flags(tfm, ~0);
- if (aead_tv[i].wk)
+ if (template[i].wk)
crypto_aead_set_flags(
tfm, CRYPTO_TFM_REQ_WEAK_KEY);
- key = aead_tv[i].key;
+
+ if (template[i].key)
+ key = template[i].key;
+ else
+ key = kzalloc(template[i].klen, GFP_KERNEL);
ret = crypto_aead_setkey(tfm, key,
- aead_tv[i].klen);
+ template[i].klen);
if (ret) {
printk(KERN_INFO "setkey() failed flags=%x\n",
crypto_aead_get_flags(tfm));
- if (!aead_tv[i].fail)
- goto out;
+ if (!template[i].fail)
+ goto next_one;
}
- authsize = abs(aead_tv[i].rlen - aead_tv[i].ilen);
+ authsize = abs(template[i].rlen - template[i].ilen);
ret = crypto_aead_setauthsize(tfm, authsize);
if (ret) {
printk(KERN_INFO
"failed to set authsize = %u\n",
authsize);
- goto out;
+ goto next_one;
}
- sg_init_one(&sg[0], aead_tv[i].input,
- aead_tv[i].ilen + (enc ? authsize : 0));
+ sg_init_one(&sg[0], input,
+ template[i].ilen + (enc ? authsize : 0));
- sg_init_one(&asg[0], aead_tv[i].assoc,
- aead_tv[i].alen);
+ sg_init_one(&asg[0], assoc, template[i].alen);
aead_request_set_crypt(req, sg, sg,
- aead_tv[i].ilen,
- aead_tv[i].iv);
+ template[i].ilen, iv);
- aead_request_set_assoc(req, asg, aead_tv[i].alen);
+ aead_request_set_assoc(req, asg, template[i].alen);
ret = enc ?
crypto_aead_encrypt(req) :
@@ -335,15 +342,21 @@
default:
printk(KERN_INFO "%s () failed err=%d\n",
e, -ret);
- goto out;
+ goto next_one;
}
q = kmap(sg_page(&sg[0])) + sg[0].offset;
- hexdump(q, aead_tv[i].rlen);
+ hexdump(q, template[i].rlen);
printk(KERN_INFO "enc/dec: %s\n",
- memcmp(q, aead_tv[i].result,
- aead_tv[i].rlen) ? "fail" : "pass");
+ memcmp(q, template[i].result,
+ template[i].rlen) ? "fail" : "pass");
+ kunmap(sg_page(&sg[0]));
+next_one:
+ if (!template[i].key)
+ kfree(key);
+ kfree(assoc);
+ kfree(input);
}
}
@@ -352,36 +365,41 @@
memset(axbuf, 0, XBUFSIZE);
for (i = 0, j = 0; i < tcount; i++) {
- if (aead_tv[i].np) {
+ if (template[i].np) {
printk(KERN_INFO "test %u (%d bit key):\n",
- ++j, aead_tv[i].klen * 8);
+ ++j, template[i].klen * 8);
+
+ if (template[i].iv)
+ memcpy(iv, template[i].iv, MAX_IVLEN);
+ else
+ memset(iv, 0, MAX_IVLEN);
crypto_aead_clear_flags(tfm, ~0);
- if (aead_tv[i].wk)
+ if (template[i].wk)
crypto_aead_set_flags(
tfm, CRYPTO_TFM_REQ_WEAK_KEY);
- key = aead_tv[i].key;
+ key = template[i].key;
- ret = crypto_aead_setkey(tfm, key, aead_tv[i].klen);
+ ret = crypto_aead_setkey(tfm, key, template[i].klen);
if (ret) {
printk(KERN_INFO "setkey() failed flags=%x\n",
crypto_aead_get_flags(tfm));
- if (!aead_tv[i].fail)
+ if (!template[i].fail)
goto out;
}
- sg_init_table(sg, aead_tv[i].np);
- for (k = 0, temp = 0; k < aead_tv[i].np; k++) {
+ sg_init_table(sg, template[i].np);
+ for (k = 0, temp = 0; k < template[i].np; k++) {
memcpy(&xbuf[IDX[k]],
- aead_tv[i].input + temp,
- aead_tv[i].tap[k]);
- temp += aead_tv[i].tap[k];
+ template[i].input + temp,
+ template[i].tap[k]);
+ temp += template[i].tap[k];
sg_set_buf(&sg[k], &xbuf[IDX[k]],
- aead_tv[i].tap[k]);
+ template[i].tap[k]);
}
- authsize = abs(aead_tv[i].rlen - aead_tv[i].ilen);
+ authsize = abs(template[i].rlen - template[i].ilen);
ret = crypto_aead_setauthsize(tfm, authsize);
if (ret) {
printk(KERN_INFO
@@ -393,21 +411,21 @@
if (enc)
sg[k - 1].length += authsize;
- sg_init_table(asg, aead_tv[i].anp);
- for (k = 0, temp = 0; k < aead_tv[i].anp; k++) {
+ sg_init_table(asg, template[i].anp);
+ for (k = 0, temp = 0; k < template[i].anp; k++) {
memcpy(&axbuf[IDX[k]],
- aead_tv[i].assoc + temp,
- aead_tv[i].atap[k]);
- temp += aead_tv[i].atap[k];
+ template[i].assoc + temp,
+ template[i].atap[k]);
+ temp += template[i].atap[k];
sg_set_buf(&asg[k], &axbuf[IDX[k]],
- aead_tv[i].atap[k]);
+ template[i].atap[k]);
}
aead_request_set_crypt(req, sg, sg,
- aead_tv[i].ilen,
- aead_tv[i].iv);
+ template[i].ilen,
+ iv);
- aead_request_set_assoc(req, asg, aead_tv[i].alen);
+ aead_request_set_assoc(req, asg, template[i].alen);
ret = enc ?
crypto_aead_encrypt(req) :
@@ -431,18 +449,19 @@
goto out;
}
- for (k = 0, temp = 0; k < aead_tv[i].np; k++) {
+ for (k = 0, temp = 0; k < template[i].np; k++) {
printk(KERN_INFO "page %u\n", k);
q = kmap(sg_page(&sg[k])) + sg[k].offset;
- hexdump(q, aead_tv[i].tap[k]);
+ hexdump(q, template[i].tap[k]);
printk(KERN_INFO "%s\n",
- memcmp(q, aead_tv[i].result + temp,
- aead_tv[i].tap[k] -
- (k < aead_tv[i].np - 1 || enc ?
+ memcmp(q, template[i].result + temp,
+ template[i].tap[k] -
+ (k < template[i].np - 1 || enc ?
0 : authsize)) ?
"fail" : "pass");
- temp += aead_tv[i].tap[k];
+ temp += template[i].tap[k];
+ kunmap(sg_page(&sg[k]));
}
}
}
@@ -456,15 +475,14 @@
struct cipher_testvec *template, unsigned int tcount)
{
unsigned int ret, i, j, k, temp;
- unsigned int tsize;
char *q;
struct crypto_ablkcipher *tfm;
- char *key;
- struct cipher_testvec *cipher_tv;
struct ablkcipher_request *req;
struct scatterlist sg[8];
const char *e;
struct tcrypt_result result;
+ void *data;
+ char iv[MAX_IVLEN];
if (enc == ENCRYPT)
e = "encryption";
@@ -473,16 +491,7 @@
printk("\ntesting %s %s\n", algo, e);
- tsize = sizeof (struct cipher_testvec);
- if (tsize > TVMEMSIZE) {
- printk("template (%u) too big for tvmem (%u)\n", tsize,
- TVMEMSIZE);
- return;
- }
- cipher_tv = (void *)tvmem;
-
init_completion(&result.completion);
-
tfm = crypto_alloc_ablkcipher(algo, 0, 0);
if (IS_ERR(tfm)) {
@@ -502,35 +511,43 @@
j = 0;
for (i = 0; i < tcount; i++) {
- memcpy(cipher_tv, &template[i], tsize);
- if (!(cipher_tv->np)) {
+
+ data = kzalloc(template[i].ilen, GFP_KERNEL);
+ if (!data)
+ continue;
+
+ memcpy(data, template[i].input, template[i].ilen);
+ if (template[i].iv)
+ memcpy(iv, template[i].iv, MAX_IVLEN);
+ else
+ memset(iv, 0, MAX_IVLEN);
+
+ if (!(template[i].np)) {
j++;
printk("test %u (%d bit key):\n",
- j, cipher_tv->klen * 8);
+ j, template[i].klen * 8);
crypto_ablkcipher_clear_flags(tfm, ~0);
- if (cipher_tv->wk)
+ if (template[i].wk)
crypto_ablkcipher_set_flags(
tfm, CRYPTO_TFM_REQ_WEAK_KEY);
- key = cipher_tv->key;
- ret = crypto_ablkcipher_setkey(tfm, key,
- cipher_tv->klen);
+ ret = crypto_ablkcipher_setkey(tfm, template[i].key,
+ template[i].klen);
if (ret) {
printk("setkey() failed flags=%x\n",
crypto_ablkcipher_get_flags(tfm));
- if (!cipher_tv->fail)
+ if (!template[i].fail) {
+ kfree(data);
goto out;
+ }
}
- sg_init_one(&sg[0], cipher_tv->input,
- cipher_tv->ilen);
+ sg_init_one(&sg[0], data, template[i].ilen);
ablkcipher_request_set_crypt(req, sg, sg,
- cipher_tv->ilen,
- cipher_tv->iv);
-
+ template[i].ilen, iv);
ret = enc ?
crypto_ablkcipher_encrypt(req) :
crypto_ablkcipher_decrypt(req);
@@ -549,16 +566,19 @@
/* fall through */
default:
printk("%s () failed err=%d\n", e, -ret);
+ kfree(data);
goto out;
}
q = kmap(sg_page(&sg[0])) + sg[0].offset;
- hexdump(q, cipher_tv->rlen);
+ hexdump(q, template[i].rlen);
printk("%s\n",
- memcmp(q, cipher_tv->result,
- cipher_tv->rlen) ? "fail" : "pass");
+ memcmp(q, template[i].result,
+ template[i].rlen) ? "fail" : "pass");
+ kunmap(sg_page(&sg[0]));
}
+ kfree(data);
}
printk("\ntesting %s %s across pages (chunking)\n", algo, e);
@@ -566,42 +586,53 @@
j = 0;
for (i = 0; i < tcount; i++) {
- memcpy(cipher_tv, &template[i], tsize);
- if (cipher_tv->np) {
+
+ data = kzalloc(template[i].ilen, GFP_KERNEL);
+ if (!data)
+ continue;
+
+ memcpy(data, template[i].input, template[i].ilen);
+
+ if (template[i].iv)
+ memcpy(iv, template[i].iv, MAX_IVLEN);
+ else
+ memset(iv, 0, MAX_IVLEN);
+
+ if (template[i].np) {
j++;
printk("test %u (%d bit key):\n",
- j, cipher_tv->klen * 8);
+ j, template[i].klen * 8);
crypto_ablkcipher_clear_flags(tfm, ~0);
- if (cipher_tv->wk)
+ if (template[i].wk)
crypto_ablkcipher_set_flags(
tfm, CRYPTO_TFM_REQ_WEAK_KEY);
- key = cipher_tv->key;
- ret = crypto_ablkcipher_setkey(tfm, key,
- cipher_tv->klen);
+ ret = crypto_ablkcipher_setkey(tfm, template[i].key,
+ template[i].klen);
if (ret) {
printk("setkey() failed flags=%x\n",
- crypto_ablkcipher_get_flags(tfm));
+ crypto_ablkcipher_get_flags(tfm));
- if (!cipher_tv->fail)
+ if (!template[i].fail) {
+ kfree(data);
goto out;
+ }
}
temp = 0;
- sg_init_table(sg, cipher_tv->np);
- for (k = 0; k < cipher_tv->np; k++) {
+ sg_init_table(sg, template[i].np);
+ for (k = 0; k < template[i].np; k++) {
memcpy(&xbuf[IDX[k]],
- cipher_tv->input + temp,
- cipher_tv->tap[k]);
- temp += cipher_tv->tap[k];
+ template[i].input + temp,
+ template[i].tap[k]);
+ temp += template[i].tap[k];
sg_set_buf(&sg[k], &xbuf[IDX[k]],
- cipher_tv->tap[k]);
+ template[i].tap[k]);
}
ablkcipher_request_set_crypt(req, sg, sg,
- cipher_tv->ilen,
- cipher_tv->iv);
+ template[i].ilen, iv);
ret = enc ?
crypto_ablkcipher_encrypt(req) :
@@ -625,19 +656,19 @@
}
temp = 0;
- for (k = 0; k < cipher_tv->np; k++) {
+ for (k = 0; k < template[i].np; k++) {
printk("page %u\n", k);
q = kmap(sg_page(&sg[k])) + sg[k].offset;
- hexdump(q, cipher_tv->tap[k]);
+ hexdump(q, template[i].tap[k]);
printk("%s\n",
- memcmp(q, cipher_tv->result + temp,
- cipher_tv->tap[k]) ? "fail" :
+ memcmp(q, template[i].result + temp,
+ template[i].tap[k]) ? "fail" :
"pass");
- temp += cipher_tv->tap[k];
+ temp += template[i].tap[k];
+ kunmap(sg_page(&sg[k]));
}
}
}
-
out:
crypto_free_ablkcipher(tfm);
ablkcipher_request_free(req);
@@ -1052,22 +1083,10 @@
unsigned int i;
char result[COMP_BUF_SIZE];
struct crypto_comp *tfm;
- struct comp_testvec *tv;
unsigned int tsize;
printk("\ntesting %s compression\n", algo);
- tsize = sizeof(struct comp_testvec);
- tsize *= ctcount;
- if (tsize > TVMEMSIZE) {
- printk("template (%u) too big for tvmem (%u)\n", tsize,
- TVMEMSIZE);
- return;
- }
-
- memcpy(tvmem, ctemplate, tsize);
- tv = (void *)tvmem;
-
tfm = crypto_alloc_comp(algo, 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(tfm)) {
printk("failed to load transform for %s\n", algo);
@@ -1080,8 +1099,8 @@
printk("test %u:\n", i + 1);
memset(result, 0, sizeof (result));
- ilen = tv[i].inlen;
- ret = crypto_comp_compress(tfm, tv[i].input,
+ ilen = ctemplate[i].inlen;
+ ret = crypto_comp_compress(tfm, ctemplate[i].input,
ilen, result, &dlen);
if (ret) {
printk("fail: ret=%d\n", ret);
@@ -1089,7 +1108,7 @@
}
hexdump(result, dlen);
printk("%s (ratio %d:%d)\n",
- memcmp(result, tv[i].output, dlen) ? "fail" : "pass",
+ memcmp(result, ctemplate[i].output, dlen) ? "fail" : "pass",
ilen, dlen);
}
@@ -1103,17 +1122,14 @@
goto out;
}
- memcpy(tvmem, dtemplate, tsize);
- tv = (void *)tvmem;
-
for (i = 0; i < dtcount; i++) {
int ilen, ret, dlen = COMP_BUF_SIZE;
printk("test %u:\n", i + 1);
memset(result, 0, sizeof (result));
- ilen = tv[i].inlen;
- ret = crypto_comp_decompress(tfm, tv[i].input,
+ ilen = dtemplate[i].inlen;
+ ret = crypto_comp_decompress(tfm, dtemplate[i].input,
ilen, result, &dlen);
if (ret) {
printk("fail: ret=%d\n", ret);
@@ -1121,7 +1137,7 @@
}
hexdump(result, dlen);
printk("%s (ratio %d:%d)\n",
- memcmp(result, tv[i].output, dlen) ? "fail" : "pass",
+ memcmp(result, dtemplate[i].output, dlen) ? "fail" : "pass",
ilen, dlen);
}
out: