-static void hexdump(unsigned char *buf, unsigned int len)
-{
- print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
- 16, 1,
- buf, len, false);
-}
-
-static void tcrypt_complete(struct crypto_async_request *req, int err)
-{
- struct tcrypt_result *res = req->data;
-
- if (err == -EINPROGRESS)
- return;
-
- res->err = err;
- complete(&res->completion);
-}
-
-static void test_hash(char *algo, struct hash_testvec *template,
- unsigned int tcount)
-{
- unsigned int i, j, k, temp;
- struct scatterlist sg[8];
- char result[64];
- struct crypto_hash *tfm;
- struct hash_desc desc;
- struct hash_testvec *hash_tv;
- unsigned int tsize;
- int ret;
-
- 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,
- PTR_ERR(tfm));
- return;
- }
-
- desc.tfm = tfm;
- desc.flags = 0;
-
- for (i = 0; i < tcount; i++) {
- printk("test %u:\n", i + 1);
- memset(result, 0, 64);
-
- sg_init_one(&sg[0], hash_tv[i].plaintext, hash_tv[i].psize);
-
- if (hash_tv[i].ksize) {
- ret = crypto_hash_setkey(tfm, hash_tv[i].key,
- hash_tv[i].ksize);
- if (ret) {
- printk("setkey() failed ret=%d\n", ret);
- goto out;
- }
- }
-
- ret = crypto_hash_digest(&desc, sg, hash_tv[i].psize, result);
- if (ret) {
- printk("digest () failed ret=%d\n", ret);
- goto out;
- }
-
- hexdump(result, crypto_hash_digestsize(tfm));
- printk("%s\n",
- memcmp(result, hash_tv[i].digest,
- crypto_hash_digestsize(tfm)) ?
- "fail" : "pass");
- }
-
- printk("testing %s across pages\n", algo);
-
- /* setup the dummy buffer first */
- memset(xbuf, 0, XBUFSIZE);
- memset(axbuf, 0, XBUFSIZE);
-
- j = 0;
- for (i = 0; i < tcount; i++) {
- if (hash_tv[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++) {
- memcpy(&xbuf[IDX[k]],
- hash_tv[i].plaintext + temp,
- hash_tv[i].tap[k]);
- temp += hash_tv[i].tap[k];
- sg_set_buf(&sg[k], &xbuf[IDX[k]],
- hash_tv[i].tap[k]);
- }
-
- if (hash_tv[i].ksize) {
- ret = crypto_hash_setkey(tfm, hash_tv[i].key,
- hash_tv[i].ksize);
-
- if (ret) {
- printk("setkey() failed ret=%d\n", ret);
- goto out;
- }
- }
-
- ret = crypto_hash_digest(&desc, sg, hash_tv[i].psize,
- result);
- if (ret) {
- printk("digest () failed ret=%d\n", ret);
- goto out;
- }
-
- hexdump(result, crypto_hash_digestsize(tfm));
- printk("%s\n",
- memcmp(result, hash_tv[i].digest,
- crypto_hash_digestsize(tfm)) ?
- "fail" : "pass");
- }
- }
-
-out:
- crypto_free_hash(tfm);
-}
-
-static void test_aead(char *algo, int enc, struct aead_testvec *template,
- 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;
-
- if (enc == ENCRYPT)
- e = "encryption";
- else
- e = "decryption";
-
- 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);
-
- if (IS_ERR(tfm)) {
- printk(KERN_INFO "failed to load transform for %s: %ld\n",
- algo, PTR_ERR(tfm));
- return;
- }
-
- authsize = crypto_aead_authsize(tfm);
-
- req = aead_request_alloc(tfm, GFP_KERNEL);
- if (!req) {
- printk(KERN_INFO "failed to allocate request for %s\n", algo);
- goto out;
- }
-
- aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
- tcrypt_complete, &result);
-
- for (i = 0, j = 0; i < tcount; i++) {
- if (!aead_tv[i].np) {
- printk(KERN_INFO "test %u (%d bit key):\n",
- ++j, aead_tv[i].klen * 8);
-
- crypto_aead_clear_flags(tfm, ~0);
- if (aead_tv[i].wk)
- crypto_aead_set_flags(
- tfm, CRYPTO_TFM_REQ_WEAK_KEY);
- key = aead_tv[i].key;
-
- ret = crypto_aead_setkey(tfm, key,
- aead_tv[i].klen);
- if (ret) {
- printk(KERN_INFO "setkey() failed flags=%x\n",
- crypto_aead_get_flags(tfm));
-
- if (!aead_tv[i].fail)
- goto out;
- }
-
- sg_init_one(&sg[0], aead_tv[i].input,
- aead_tv[i].ilen + (enc ? authsize : 0));
-
- sg_init_one(&asg[0], aead_tv[i].assoc,
- aead_tv[i].alen);
-
- aead_request_set_crypt(req, sg, sg,
- aead_tv[i].ilen,
- aead_tv[i].iv);
-
- aead_request_set_assoc(req, asg, aead_tv[i].alen);
-
- ret = enc ?
- crypto_aead_encrypt(req) :
- crypto_aead_decrypt(req);
-
- switch (ret) {
- case 0:
- break;
- case -EINPROGRESS:
- case -EBUSY:
- ret = wait_for_completion_interruptible(
- &result.completion);
- if (!ret && !(ret = result.err)) {
- INIT_COMPLETION(result.completion);
- break;
- }
- /* fall through */
- default:
- printk(KERN_INFO "%s () failed err=%d\n",
- e, -ret);
- goto out;
- }
-
- q = kmap(sg_page(&sg[0])) + sg[0].offset;
- hexdump(q, aead_tv[i].rlen);
-
- printk(KERN_INFO "enc/dec: %s\n",
- memcmp(q, aead_tv[i].result,
- aead_tv[i].rlen) ? "fail" : "pass");
- }
- }
-
- printk(KERN_INFO "\ntesting %s %s across pages (chunking)\n", algo, e);
- memset(xbuf, 0, XBUFSIZE);
-
- for (i = 0, j = 0; i < tcount; i++) {
- if (aead_tv[i].np) {
- printk(KERN_INFO "test %u (%d bit key):\n",
- ++j, aead_tv[i].klen * 8);
-
- crypto_aead_clear_flags(tfm, ~0);
- if (aead_tv[i].wk)
- crypto_aead_set_flags(
- tfm, CRYPTO_TFM_REQ_WEAK_KEY);
- key = aead_tv[i].key;
-
- ret = crypto_aead_setkey(tfm, key, aead_tv[i].klen);
- if (ret) {
- printk(KERN_INFO "setkey() failed flags=%x\n",
- crypto_aead_get_flags(tfm));
-
- if (!aead_tv[i].fail)
- goto out;
- }
-
- sg_init_table(sg, aead_tv[i].np);
- for (k = 0, temp = 0; k < aead_tv[i].np; k++) {
- memcpy(&xbuf[IDX[k]],
- aead_tv[i].input + temp,
- aead_tv[i].tap[k]);
- temp += aead_tv[i].tap[k];
- sg_set_buf(&sg[k], &xbuf[IDX[k]],
- aead_tv[i].tap[k]);
- }
-
- 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++) {
- memcpy(&axbuf[IDX[k]],
- aead_tv[i].assoc + temp,
- aead_tv[i].atap[k]);
- temp += aead_tv[i].atap[k];
- sg_set_buf(&asg[k], &axbuf[IDX[k]],
- aead_tv[i].atap[k]);
- }
-
- aead_request_set_crypt(req, sg, sg,
- aead_tv[i].ilen,
- aead_tv[i].iv);
-
- aead_request_set_assoc(req, asg, aead_tv[i].alen);
-
- ret = enc ?
- crypto_aead_encrypt(req) :
- crypto_aead_decrypt(req);
-
- switch (ret) {
- case 0:
- break;
- case -EINPROGRESS:
- case -EBUSY:
- ret = wait_for_completion_interruptible(
- &result.completion);
- if (!ret && !(ret = result.err)) {
- INIT_COMPLETION(result.completion);
- break;
- }
- /* fall through */
- default:
- printk(KERN_INFO "%s () failed err=%d\n",
- e, -ret);
- goto out;
- }
-
- for (k = 0, temp = 0; k < aead_tv[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]);
- printk(KERN_INFO "%s\n",
- memcmp(q, aead_tv[i].result + temp,
- aead_tv[i].tap[k] -
- (k < aead_tv[i].np - 1 || enc ?
- 0 : authsize)) ?
- "fail" : "pass");
-
- temp += aead_tv[i].tap[k];
- }
- }
- }
-
-out:
- crypto_free_aead(tfm);
- aead_request_free(req);
-}
-
-static void test_cipher(char *algo, int enc,
- 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;
-
- if (enc == ENCRYPT)
- e = "encryption";
- else
- e = "decryption";
-
- 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)) {
- printk("failed to load transform for %s: %ld\n", algo,
- PTR_ERR(tfm));
- return;
- }
-
- req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
- if (!req) {
- printk("failed to allocate request for %s\n", algo);
- goto out;
- }
-
- ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
- tcrypt_complete, &result);
-
- j = 0;
- for (i = 0; i < tcount; i++) {
- memcpy(cipher_tv, &template[i], tsize);
- if (!(cipher_tv->np)) {
- j++;
- printk("test %u (%d bit key):\n",
- j, cipher_tv->klen * 8);
-
- crypto_ablkcipher_clear_flags(tfm, ~0);
- if (cipher_tv->wk)
- crypto_ablkcipher_set_flags(
- tfm, CRYPTO_TFM_REQ_WEAK_KEY);
- key = cipher_tv->key;
-
- ret = crypto_ablkcipher_setkey(tfm, key,
- cipher_tv->klen);
- if (ret) {
- printk("setkey() failed flags=%x\n",
- crypto_ablkcipher_get_flags(tfm));
-
- if (!cipher_tv->fail)
- goto out;
- }
-
- sg_init_one(&sg[0], cipher_tv->input,
- cipher_tv->ilen);
-
- ablkcipher_request_set_crypt(req, sg, sg,
- cipher_tv->ilen,
- cipher_tv->iv);
-
- ret = enc ?
- crypto_ablkcipher_encrypt(req) :
- crypto_ablkcipher_decrypt(req);
-
- switch (ret) {
- case 0:
- break;
- case -EINPROGRESS:
- case -EBUSY:
- ret = wait_for_completion_interruptible(
- &result.completion);
- if (!ret && !((ret = result.err))) {
- INIT_COMPLETION(result.completion);
- break;
- }
- /* fall through */
- default:
- printk("%s () failed err=%d\n", e, -ret);
- goto out;
- }
-
- q = kmap(sg_page(&sg[0])) + sg[0].offset;
- hexdump(q, cipher_tv->rlen);
-
- printk("%s\n",
- memcmp(q, cipher_tv->result,
- cipher_tv->rlen) ? "fail" : "pass");
- }
- }
-
- printk("\ntesting %s %s across pages (chunking)\n", algo, e);
- memset(xbuf, 0, XBUFSIZE);
-
- j = 0;
- for (i = 0; i < tcount; i++) {
- memcpy(cipher_tv, &template[i], tsize);
- if (cipher_tv->np) {
- j++;
- printk("test %u (%d bit key):\n",
- j, cipher_tv->klen * 8);
-
- crypto_ablkcipher_clear_flags(tfm, ~0);
- if (cipher_tv->wk)
- crypto_ablkcipher_set_flags(
- tfm, CRYPTO_TFM_REQ_WEAK_KEY);
- key = cipher_tv->key;
-
- ret = crypto_ablkcipher_setkey(tfm, key,
- cipher_tv->klen);
- if (ret) {
- printk("setkey() failed flags=%x\n",
- crypto_ablkcipher_get_flags(tfm));
-
- if (!cipher_tv->fail)
- goto out;
- }
-
- temp = 0;
- sg_init_table(sg, cipher_tv->np);
- for (k = 0; k < cipher_tv->np; k++) {
- memcpy(&xbuf[IDX[k]],
- cipher_tv->input + temp,
- cipher_tv->tap[k]);
- temp += cipher_tv->tap[k];
- sg_set_buf(&sg[k], &xbuf[IDX[k]],
- cipher_tv->tap[k]);
- }
-
- ablkcipher_request_set_crypt(req, sg, sg,
- cipher_tv->ilen,
- cipher_tv->iv);
-
- ret = enc ?
- crypto_ablkcipher_encrypt(req) :
- crypto_ablkcipher_decrypt(req);
-
- switch (ret) {
- case 0:
- break;
- case -EINPROGRESS:
- case -EBUSY:
- ret = wait_for_completion_interruptible(
- &result.completion);
- if (!ret && !((ret = result.err))) {
- INIT_COMPLETION(result.completion);
- break;
- }
- /* fall through */
- default:
- printk("%s () failed err=%d\n", e, -ret);
- goto out;
- }
-
- temp = 0;
- for (k = 0; k < cipher_tv->np; k++) {
- printk("page %u\n", k);
- q = kmap(sg_page(&sg[k])) + sg[k].offset;
- hexdump(q, cipher_tv->tap[k]);
- printk("%s\n",
- memcmp(q, cipher_tv->result + temp,
- cipher_tv->tap[k]) ? "fail" :
- "pass");
- temp += cipher_tv->tap[k];
- }
- }
- }
-
-out:
- crypto_free_ablkcipher(tfm);
- ablkcipher_request_free(req);
-}
-
-static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc, char *p,
- int blen, int sec)