--- zzzz-none-000/linux-4.4.60/crypto/testmgr.c 2017-04-08 07:53:53.000000000 +0000 +++ scorpion-7490-727/linux-4.4.60/crypto/testmgr.c 2021-02-04 17:41:59.000000000 +0000 @@ -153,6 +153,8 @@ static void tcrypt_complete(struct crypto_async_request *req, int err) { struct tcrypt_result *res = req->data; + if (err) + pr_err("Error received in %s(), error = %d\n", __func__, err); if (err == -EINPROGRESS) return; @@ -198,11 +200,11 @@ return ret; } -static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, - unsigned int tcount, bool use_digest, - const int align_offset) +static int __test_hash(struct hash_testvec *template, unsigned int tcount, + bool use_digest, const int align_offset, + const char *driver, u32 type, u32 mask) { - const char *algo = crypto_tfm_alg_driver_name(crypto_ahash_tfm(tfm)); + struct crypto_ahash *tfm; unsigned int i, j, k, temp; struct scatterlist sg[8]; char *result; @@ -211,6 +213,7 @@ struct tcrypt_result tresult; void *hash_buff; char *xbuf[XBUFSIZE]; + const char *algo; int ret = -ENOMEM; result = kmalloc(MAX_DIGEST_SIZE, GFP_KERNEL); @@ -222,27 +225,43 @@ if (testmgr_alloc_buf(xbuf)) goto out_nobuf; - init_completion(&tresult.completion); - - req = ahash_request_alloc(tfm, GFP_KERNEL); - if (!req) { - printk(KERN_ERR "alg: hash: Failed to allocate request for " - "%s\n", algo); - goto out_noreq; - } - ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, - tcrypt_complete, &tresult); - j = 0; + pr_info("ahash test for %s driver on continuous test vectors\n", + driver); + for (i = 0; i < tcount; i++) { + const char *algo; + if (template[i].np) continue; ret = -EINVAL; if (WARN_ON(align_offset + template[i].psize > PAGE_SIZE)) - goto out; + goto out_noreq; j++; + tfm = crypto_alloc_ahash(driver, type | CRYPTO_ALG_INTERNAL, mask); + if (IS_ERR(tfm)) { + pr_warn("alg: hash: Failed to load transform for %s: " + "%ld\n", driver, PTR_ERR(tfm)); + return PTR_ERR(tfm); + } + + algo = crypto_tfm_alg_driver_name(crypto_ahash_tfm(tfm)); + + init_completion(&tresult.completion); + + req = ahash_request_alloc(tfm, GFP_KERNEL); + if (!req) { + pr_warn("alg: hash: Failed to allocate request for %s\n", + algo); + crypto_free_ahash(tfm); + goto out_noreq; + } + + ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + tcrypt_complete, &tresult); + memset(result, 0, MAX_DIGEST_SIZE); hash_buff = xbuf[0]; @@ -257,15 +276,20 @@ pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n", j, algo, template[i].ksize, MAX_KEYLEN); ret = -EINVAL; - goto out; + crypto_free_ahash(tfm); + ahash_request_free(req); + goto out_noreq; } + memcpy(key, template[i].key, template[i].ksize); ret = crypto_ahash_setkey(tfm, key, template[i].ksize); if (ret) { printk(KERN_ERR "alg: hash: setkey failed on " "test %d for %s: ret=%d\n", j, algo, -ret); - goto out; + crypto_free_ahash(tfm); + ahash_request_free(req); + goto out_noreq; } } @@ -275,41 +299,58 @@ if (ret) { pr_err("alg: hash: digest failed on test %d " "for %s: ret=%d\n", j, algo, -ret); - goto out; + crypto_free_ahash(tfm); + ahash_request_free(req); + goto out_noreq; } } else { ret = wait_async_op(&tresult, crypto_ahash_init(req)); if (ret) { pr_err("alt: hash: init failed on test %d " "for %s: ret=%d\n", j, algo, -ret); - goto out; + crypto_free_ahash(tfm); + ahash_request_free(req); + goto out_noreq; } ret = wait_async_op(&tresult, crypto_ahash_update(req)); if (ret) { pr_err("alt: hash: update failed on test %d " "for %s: ret=%d\n", j, algo, -ret); - goto out; + crypto_free_ahash(tfm); + ahash_request_free(req); + goto out_noreq; } ret = wait_async_op(&tresult, crypto_ahash_final(req)); if (ret) { pr_err("alt: hash: final failed on test %d " "for %s: ret=%d\n", j, algo, -ret); - goto out; + crypto_free_ahash(tfm); + ahash_request_free(req); + goto out_noreq; } } - if (memcmp(result, template[i].digest, - crypto_ahash_digestsize(tfm))) { - printk(KERN_ERR "alg: hash: Test %d failed for %s\n", - j, algo); + if (memcmp(result, template[i].digest, crypto_ahash_digestsize(tfm))) { + pr_warn("alg: hash: Test %d failed for %s(plaintext size: %d)\n", + j, algo, template[i].psize); hexdump(result, crypto_ahash_digestsize(tfm)); ret = -EINVAL; - goto out; + crypto_free_ahash(tfm); + ahash_request_free(req); + goto out_noreq; } + + crypto_free_ahash(tfm); + ahash_request_free(req); + pr_info("ahash test completed for %s algorithm(plaintext size: %d)\n", + algo, template[i].psize); } + pr_info("ahash test on noncontinuous test vectors for %s driver\n", driver); j = 0; for (i = 0; i < tcount; i++) { + const char *algo; + /* alignment tests are only done with continuous buffers */ if (align_offset != 0) break; @@ -318,6 +359,27 @@ continue; j++; + tfm = crypto_alloc_ahash(driver, type | CRYPTO_ALG_INTERNAL, mask); + if (IS_ERR(tfm)) { + pr_warn("alg: hash: Failed to load transform for %s: " + "%ld\n", driver, PTR_ERR(tfm)); + return PTR_ERR(tfm); + } + + algo = crypto_tfm_alg_driver_name(crypto_ahash_tfm(tfm)); + + init_completion(&tresult.completion); + + req = ahash_request_alloc(tfm, GFP_KERNEL); + if (!req) { + printk(KERN_ERR "alg: hash: Failed to allocate request for %s\n", algo); + crypto_free_ahash(tfm); + goto out_noreq; + } + + ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + tcrypt_complete, &tresult); + memset(result, 0, MAX_DIGEST_SIZE); temp = 0; @@ -325,8 +387,11 @@ ret = -EINVAL; for (k = 0; k < template[i].np; k++) { if (WARN_ON(offset_in_page(IDX[k]) + - template[i].tap[k] > PAGE_SIZE)) - goto out; + template[i].tap[k] > PAGE_SIZE)) { + crypto_free_ahash(tfm); + ahash_request_free(req); + goto out_noreq; + } sg_set_buf(&sg[k], memcpy(xbuf[IDX[k] >> PAGE_SHIFT] + offset_in_page(IDX[k]), @@ -341,7 +406,9 @@ pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n", j, algo, template[i].ksize, MAX_KEYLEN); ret = -EINVAL; - goto out; + crypto_free_ahash(tfm); + ahash_request_free(req); + goto out_noreq; } crypto_ahash_clear_flags(tfm, ~0); memcpy(key, template[i].key, template[i].ksize); @@ -351,7 +418,9 @@ printk(KERN_ERR "alg: hash: setkey " "failed on chunking test %d " "for %s: ret=%d\n", j, algo, -ret); - goto out; + crypto_free_ahash(tfm); + ahash_request_free(req); + goto out_noreq; } } @@ -362,6 +431,8 @@ break; case -EINPROGRESS: case -EBUSY: + pr_info("ahash test is waiting to be completed for %s algorithm on noncontinuous " + "test vector (plaintext size: %d)\n", algo, template[i].psize); wait_for_completion(&tresult.completion); reinit_completion(&tresult.completion); ret = tresult.err; @@ -372,7 +443,9 @@ printk(KERN_ERR "alg: hash: digest failed " "on chunking test %d for %s: " "ret=%d\n", j, algo, -ret); - goto out; + crypto_free_ahash(tfm); + ahash_request_free(req); + goto out_noreq; } if (memcmp(result, template[i].digest, @@ -381,14 +454,20 @@ "failed for %s\n", j, algo); hexdump(result, crypto_ahash_digestsize(tfm)); ret = -EINVAL; - goto out; - } + crypto_free_ahash(tfm); + ahash_request_free(req); + goto out_noreq; + } + crypto_free_ahash(tfm); + ahash_request_free(req); + pr_info("ahash test completed for %s algorithm on noncontinuous " + "test vector(plaintext size: %d)\n", algo, template[i].psize); } + pr_info("AHASH test %s for non-continuous test vectors " + "on %s driver", j ? "completed" : "not completed", driver); ret = 0; -out: - ahash_request_free(req); out_noreq: testmgr_free_buf(xbuf); out_nobuf: @@ -397,43 +476,54 @@ return ret; } -static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, - unsigned int tcount, bool use_digest) +static int test_hash(struct hash_testvec *template, unsigned int tcount, + bool use_digest, const char *driver, u32 type, u32 mask) { +#ifdef CONFIG_CRYPTO_ALL_CASES unsigned int alignmask; + struct crypto_ahash *tfm; +#endif int ret; - ret = __test_hash(tfm, template, tcount, use_digest, 0); + ret = __test_hash(template, tcount, use_digest, 0, driver, type, mask); if (ret) return ret; - +#ifdef CONFIG_CRYPTO_ALL_CASES /* test unaligned buffers, check with one byte offset */ - ret = __test_hash(tfm, template, tcount, use_digest, 1); + ret = __test_hash(template, tcount, use_digest, 1, driver, type, mask); if (ret) return ret; + tfm = crypto_alloc_ahash(driver, type | CRYPTO_ALG_INTERNAL, mask); + if (IS_ERR(tfm)) { + pr_warn("alg: hash: Failed to load transform for %s: " + "%ld\n", driver, PTR_ERR(tfm)); + return PTR_ERR(tfm); + } + alignmask = crypto_tfm_alg_alignmask(&tfm->base); + crypto_free_ahash(tfm); if (alignmask) { /* Check if alignment mask for tfm is correctly set. */ - ret = __test_hash(tfm, template, tcount, use_digest, - alignmask + 1); + ret = __test_hash(template, tcount, use_digest, + alignmask + 1, driver, type, mask); if (ret) return ret; } - +#endif return 0; } -static int __test_aead(struct crypto_aead *tfm, int enc, - struct aead_testvec *template, unsigned int tcount, - const bool diff_dst, const int align_offset) +static int __test_aead(struct aead_testvec *template, unsigned int tcount, + int enc, const bool diff_dst, const int align_offset, + const char *driver, u32 type, u32 mask) { - const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)); + struct crypto_aead *tfm; + struct aead_request *req; unsigned int i, j, k, n, temp; int ret = -ENOMEM; char *q; char *key; - struct aead_request *req; struct scatterlist *sg; struct scatterlist *sgout; const char *e, *d; @@ -446,6 +536,7 @@ char *xbuf[XBUFSIZE]; char *xoutbuf[XBUFSIZE]; char *axbuf[XBUFSIZE]; + const char *algo; iv = kzalloc(MAX_IVLEN, GFP_KERNEL); if (!iv) @@ -476,23 +567,34 @@ else e = "decryption"; - init_completion(&result.completion); - - req = aead_request_alloc(tfm, GFP_KERNEL); - if (!req) { - pr_err("alg: aead%s: Failed to allocate request for %s\n", - d, algo); - goto out; - } - - aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, - tcrypt_complete, &result); - + pr_info("running aead test for %s driver\n", driver); for (i = 0, j = 0; i < tcount; i++) { + const char *algo; + if (template[i].np) continue; - j++; + tfm = crypto_alloc_aead(driver, type | CRYPTO_ALG_INTERNAL, mask); + if (IS_ERR(tfm)) { + pr_err("alg: aead: Failed to load transform for %s: " + "%ld\n", driver, PTR_ERR(tfm)); + return PTR_ERR(tfm); + } + + algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)); + + init_completion(&result.completion); + + req = aead_request_alloc(tfm, GFP_KERNEL); + if (!req) { + pr_err("alg: aead%s: Failed to allocate request for %s\n", + d, algo); + crypto_free_aead(tfm); + goto out; + } + + aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + tcrypt_complete, &result); /* some templates have no input data but they will * touch input @@ -503,8 +605,11 @@ ret = -EINVAL; if (WARN_ON(align_offset + template[i].ilen > - PAGE_SIZE || template[i].alen > PAGE_SIZE)) + PAGE_SIZE || template[i].alen > PAGE_SIZE)) { + aead_request_free(req); + crypto_free_aead(tfm); goto out; + } memcpy(input, template[i].input, template[i].ilen); memcpy(assoc, template[i].assoc, template[i].alen); @@ -523,6 +628,8 @@ d, j, algo, template[i].klen, MAX_KEYLEN); ret = -EINVAL; + aead_request_free(req); + crypto_free_aead(tfm); goto out; } memcpy(key, template[i].key, template[i].klen); @@ -531,6 +638,8 @@ if (!ret == template[i].fail) { pr_err("alg: aead%s: setkey failed on test %d for %s: flags=%x\n", d, j, algo, crypto_aead_get_flags(tfm)); + aead_request_free(req); + crypto_free_aead(tfm); goto out; } else if (ret) continue; @@ -540,6 +649,8 @@ if (ret) { pr_err("alg: aead%s: Failed to set authsize to %u on test %d for %s\n", d, authsize, j, algo); + aead_request_free(req); + crypto_free_aead(tfm); goto out; } @@ -575,24 +686,32 @@ d, e, j, algo); /* so really, we got a bad message */ ret = -EBADMSG; + aead_request_free(req); + crypto_free_aead(tfm); goto out; } break; case -EINPROGRESS: case -EBUSY: + pr_info("aead test started for %s algorithm (cipher_keylen:%d, auth_keylen:%d) \n", algo, template[i].klen, template[i].alen); wait_for_completion(&result.completion); reinit_completion(&result.completion); ret = result.err; if (!ret) break; case -EBADMSG: - if (template[i].novrfy) + if (template[i].novrfy) { /* verification failure was expected */ + aead_request_free(req); + crypto_free_aead(tfm); continue; + } /* fall through */ default: pr_err("alg: aead%s: %s failed on test %d for %s: ret=%d\n", d, e, j, algo, -ret); + aead_request_free(req); + crypto_free_aead(tfm); goto out; } @@ -602,11 +721,19 @@ d, j, e, algo); hexdump(q, template[i].rlen); ret = -EINVAL; + aead_request_free(req); + crypto_free_aead(tfm); goto out; } + pr_info("aead test completed for %s algorithm (cipher_keylen:%d, auth_keylen:%d) \n", algo, template[i].klen, template[i].alen); + aead_request_free(req); + crypto_free_aead(tfm); } + pr_info("running aead test for %s driver on noncontinuous buffers\n", driver); for (i = 0, j = 0; i < tcount; i++) { + const char *algo; + /* alignment tests are only done with continuous buffers */ if (align_offset != 0) break; @@ -614,6 +741,28 @@ if (!template[i].np) continue; + tfm = crypto_alloc_aead(driver, type | CRYPTO_ALG_INTERNAL, mask); + if (IS_ERR(tfm)) { + pr_err("alg: aead: Failed to load transform for %s: " + "%ld\n", driver, PTR_ERR(tfm)); + return PTR_ERR(tfm); + } + + algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)); + + init_completion(&result.completion); + + req = aead_request_alloc(tfm, GFP_KERNEL); + if (!req) { + pr_err("alg: aead%s: Failed to allocate request for %s\n", + d, algo); + crypto_free_aead(tfm); + goto out; + } + + aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + tcrypt_complete, &result); + j++; if (template[i].iv) @@ -628,6 +777,8 @@ pr_err("alg: aead%s: setkey failed on test %d for %s: key size %d > %d\n", d, j, algo, template[i].klen, MAX_KEYLEN); ret = -EINVAL; + aead_request_free(req); + crypto_free_aead(tfm); goto out; } memcpy(key, template[i].key, template[i].klen); @@ -636,6 +787,8 @@ if (!ret == template[i].fail) { pr_err("alg: aead%s: setkey failed on chunk test %d for %s: flags=%x\n", d, j, algo, crypto_aead_get_flags(tfm)); + aead_request_free(req); + crypto_free_aead(tfm); goto out; } else if (ret) continue; @@ -650,8 +803,12 @@ ret = -EINVAL; for (k = 0, temp = 0; k < template[i].anp; k++) { if (WARN_ON(offset_in_page(IDX[k]) + - template[i].atap[k] > PAGE_SIZE)) + template[i].atap[k] > PAGE_SIZE)) { + aead_request_free(req); + crypto_free_aead(tfm); goto out; + } + sg_set_buf(&sg[k], memcpy(axbuf[IDX[k] >> PAGE_SHIFT] + offset_in_page(IDX[k]), @@ -668,10 +825,14 @@ for (k = 0, temp = 0; k < template[i].np; k++) { if (WARN_ON(offset_in_page(IDX[k]) + - template[i].tap[k] > PAGE_SIZE)) + template[i].tap[k] > PAGE_SIZE)) { + aead_request_free(req); + crypto_free_aead(tfm); goto out; + } q = xbuf[IDX[k] >> PAGE_SHIFT] + offset_in_page(IDX[k]); + memcpy(q, template[i].input + temp, template[i].tap[k]); sg_set_buf(&sg[template[i].anp + k], q, template[i].tap[k]); @@ -699,6 +860,8 @@ if (ret) { pr_err("alg: aead%s: Failed to set authsize to %u on chunk test %d for %s\n", d, authsize, j, algo); + aead_request_free(req); + crypto_free_aead(tfm); goto out; } @@ -707,6 +870,8 @@ sg[template[i].anp + k - 1].length + authsize > PAGE_SIZE)) { ret = -EINVAL; + aead_request_free(req); + crypto_free_aead(tfm); goto out; } @@ -732,24 +897,32 @@ d, e, j, algo); /* so really, we got a bad message */ ret = -EBADMSG; + aead_request_free(req); + crypto_free_aead(tfm); goto out; } break; case -EINPROGRESS: case -EBUSY: + pr_info("aead on noncontinuous test vectors started for %s algorithm (cipher_keylen:%d, auth_keylen:%d) \n", algo, template[i].klen, template[i].alen); wait_for_completion(&result.completion); reinit_completion(&result.completion); ret = result.err; if (!ret) break; case -EBADMSG: - if (template[i].novrfy) + if (template[i].novrfy) { /* verification failure was expected */ + aead_request_free(req); + crypto_free_aead(tfm); continue; + } /* fall through */ default: pr_err("alg: aead%s: %s failed on chunk test %d for %s: ret=%d\n", d, e, j, algo, -ret); + aead_request_free(req); + crypto_free_aead(tfm); goto out; } @@ -770,6 +943,8 @@ pr_err("alg: aead%s: Chunk test %d failed on %s at page %u for %s\n", d, j, e, k, algo); hexdump(q, n); + aead_request_free(req); + crypto_free_aead(tfm); goto out; } @@ -789,17 +964,21 @@ pr_err("alg: aead%s: Result buffer corruption in chunk test %d on %s at page %u for %s: %u bytes:\n", d, j, e, k, algo, n); hexdump(q, n); + aead_request_free(req); + crypto_free_aead(tfm); goto out; } temp += template[i].tap[k]; } + pr_info("aead on noncontinuous test vectors completed for %s algorithm (cipher_keylen:%d, auth_keylen:%d) \n", algo, template[i].klen, template[i].alen); + aead_request_free(req); + crypto_free_aead(tfm); } ret = 0; out: - aead_request_free(req); kfree(sg); out_nosg: if (diff_dst) @@ -814,36 +993,47 @@ return ret; } -static int test_aead(struct crypto_aead *tfm, int enc, - struct aead_testvec *template, unsigned int tcount) +static int test_aead(struct aead_testvec *template, unsigned int tcount, + int enc, const char *driver, u32 type, u32 mask) { +#ifdef CONFIG_CRYPTO_ALL_CASES + struct crypto_aead *tfm; unsigned int alignmask; +#endif int ret; /* test 'dst == src' case */ - ret = __test_aead(tfm, enc, template, tcount, false, 0); + ret = __test_aead(template, tcount, enc, false, 0, driver, type, mask); if (ret) return ret; - +#ifdef CONFIG_CRYPTO_ALL_CASES /* test 'dst != src' case */ - ret = __test_aead(tfm, enc, template, tcount, true, 0); + ret = __test_aead(template, tcount, enc, true, 0, driver, type, mask); if (ret) return ret; /* test unaligned buffers, check with one byte offset */ - ret = __test_aead(tfm, enc, template, tcount, true, 1); + ret = __test_aead(template, tcount, enc, true, 1, driver, type, mask); if (ret) return ret; + tfm = crypto_alloc_aead(driver, type | CRYPTO_ALG_INTERNAL, mask); + if (IS_ERR(tfm)) { + printk(KERN_ERR "alg: aead: Failed to load transform for %s: " + "%ld\n", driver, PTR_ERR(tfm)); + return PTR_ERR(tfm); + } + alignmask = crypto_tfm_alg_alignmask(&tfm->base); + crypto_free_aead(tfm); if (alignmask) { /* Check if alignment mask for tfm is correctly set. */ - ret = __test_aead(tfm, enc, template, tcount, true, - alignmask + 1); + ret = __test_aead(template, tcount, enc, true, + alignmask + 1, driver, type, mask); if (ret) return ret; } - +#endif return 0; } @@ -922,15 +1112,14 @@ return ret; } -static int __test_skcipher(struct crypto_skcipher *tfm, int enc, - struct cipher_testvec *template, unsigned int tcount, - const bool diff_dst, const int align_offset) +static int __test_skcipher(struct cipher_testvec *template, unsigned int tcount, + int enc, const bool diff_dst, const int align_offset, + const char *driver, u32 type, u32 mask) { - const char *algo = - crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)); + struct crypto_skcipher *tfm; + struct skcipher_request *req; unsigned int i, j, k, n, temp; char *q; - struct skcipher_request *req; struct scatterlist sg[8]; struct scatterlist sgout[8]; const char *e, *d; @@ -940,7 +1129,8 @@ char *xbuf[XBUFSIZE]; char *xoutbuf[XBUFSIZE]; int ret = -ENOMEM; - unsigned int ivsize = crypto_skcipher_ivsize(tfm); + unsigned int ivsize; + const char *algo; if (testmgr_alloc_buf(xbuf)) goto out_nobuf; @@ -958,23 +1148,37 @@ else e = "decryption"; - init_completion(&result.completion); - - req = skcipher_request_alloc(tfm, GFP_KERNEL); - if (!req) { - pr_err("alg: skcipher%s: Failed to allocate request for %s\n", - d, algo); - goto out; - } - - skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, - tcrypt_complete, &result); - + pr_info("cipher test for %s driver\n", driver); j = 0; for (i = 0; i < tcount; i++) { + const char *algo; + if (template[i].np && !template[i].also_non_np) continue; + tfm = crypto_alloc_skcipher(driver, type | CRYPTO_ALG_INTERNAL, mask); + if (IS_ERR(tfm)) { + pr_err("alg: skcipher: Failed to load transform for " + "%s: %ld\n", driver, PTR_ERR(tfm)); + return PTR_ERR(tfm); + } + + ivsize = crypto_skcipher_ivsize(tfm); + + algo = crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)); + init_completion(&result.completion); + + req = skcipher_request_alloc(tfm, GFP_KERNEL); + if (!req) { + pr_err("alg: skcipher%s: Failed to allocate request for %s\n", + d, algo); + crypto_free_skcipher(tfm); + goto out; + } + + skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + tcrypt_complete, &result); + if (template[i].iv) memcpy(iv, template[i].iv, ivsize); else @@ -982,8 +1186,11 @@ j++; ret = -EINVAL; - if (WARN_ON(align_offset + template[i].ilen > PAGE_SIZE)) + if (WARN_ON(align_offset + template[i].ilen > PAGE_SIZE)) { + skcipher_request_free(req); + crypto_free_skcipher(tfm); goto out; + } data = xbuf[0]; data += align_offset; @@ -999,6 +1206,8 @@ if (!ret == template[i].fail) { pr_err("alg: skcipher%s: setkey failed on test %d for %s: flags=%x\n", d, j, algo, crypto_skcipher_get_flags(tfm)); + skcipher_request_free(req); + crypto_free_skcipher(tfm); goto out; } else if (ret) continue; @@ -1020,6 +1229,7 @@ break; case -EINPROGRESS: case -EBUSY: + pr_info("%s test started for %s algorithm (cipher_keylen:%d) \n", e, algo, template[i].klen); wait_for_completion(&result.completion); reinit_completion(&result.completion); ret = result.err; @@ -1029,6 +1239,8 @@ default: pr_err("alg: skcipher%s: %s failed on test %d for %s: ret=%d\n", d, e, j, algo, -ret); + skcipher_request_free(req); + crypto_free_skcipher(tfm); goto out; } @@ -1038,6 +1250,8 @@ d, j, e, algo); hexdump(q, template[i].rlen); ret = -EINVAL; + skcipher_request_free(req); + crypto_free_skcipher(tfm); goto out; } @@ -1048,12 +1262,20 @@ d, j, e, algo); hexdump(iv, crypto_skcipher_ivsize(tfm)); ret = -EINVAL; + skcipher_request_free(req); + crypto_free_skcipher(tfm); goto out; } + skcipher_request_free(req); + crypto_free_skcipher(tfm); + pr_info("%s test completed for %s algorithm (cipher_keylen:%d) \n", e, algo, template[i].klen); } + pr_info("cipher test on noncontinuous test vectors for %s driver\n", driver); j = 0; for (i = 0; i < tcount; i++) { + const char *algo; + /* alignment tests are only done with continuous buffers */ if (align_offset != 0) break; @@ -1061,6 +1283,27 @@ if (!template[i].np) continue; + tfm = crypto_alloc_skcipher(driver, type | CRYPTO_ALG_INTERNAL, mask); + if (IS_ERR(tfm)) { + pr_err("alg: skcipher: Failed to load transform for " + "%s: %ld\n", driver, PTR_ERR(tfm)); + return PTR_ERR(tfm); + } + ivsize = crypto_skcipher_ivsize(tfm); + algo = crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)); + init_completion(&result.completion); + + req = skcipher_request_alloc(tfm, GFP_KERNEL); + if (!req) { + pr_err("alg: skcipher%s: Failed to allocate request for %s\n", + d, algo); + crypto_free_skcipher(tfm); + goto out; + } + + skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + tcrypt_complete, &result); + if (template[i].iv) memcpy(iv, template[i].iv, ivsize); else @@ -1077,6 +1320,8 @@ if (!ret == template[i].fail) { pr_err("alg: skcipher%s: setkey failed on chunk test %d for %s: flags=%x\n", d, j, algo, crypto_skcipher_get_flags(tfm)); + skcipher_request_free(req); + crypto_free_skcipher(tfm); goto out; } else if (ret) continue; @@ -1088,8 +1333,11 @@ sg_init_table(sgout, template[i].np); for (k = 0; k < template[i].np; k++) { if (WARN_ON(offset_in_page(IDX[k]) + - template[i].tap[k] > PAGE_SIZE)) + template[i].tap[k] > PAGE_SIZE)) { + skcipher_request_free(req); + crypto_free_skcipher(tfm); goto out; + } q = xbuf[IDX[k] >> PAGE_SHIFT] + offset_in_page(IDX[k]); @@ -1125,6 +1373,7 @@ break; case -EINPROGRESS: case -EBUSY: + pr_info("%s test on noncontinuous test vectors started for %s algorithm (cipher_keylen:%d) \n", e, algo, template[i].klen); wait_for_completion(&result.completion); reinit_completion(&result.completion); ret = result.err; @@ -1134,6 +1383,8 @@ default: pr_err("alg: skcipher%s: %s failed on chunk test %d for %s: ret=%d\n", d, e, j, algo, -ret); + skcipher_request_free(req); + crypto_free_skcipher(tfm); goto out; } @@ -1152,6 +1403,8 @@ pr_err("alg: skcipher%s: Chunk test %d failed on %s at page %u for %s\n", d, j, e, k, algo); hexdump(q, template[i].tap[k]); + skcipher_request_free(req); + crypto_free_skcipher(tfm); goto out; } @@ -1162,16 +1415,19 @@ pr_err("alg: skcipher%s: Result buffer corruption in chunk test %d on %s at page %u for %s: %u bytes:\n", d, j, e, k, algo, n); hexdump(q, n); + skcipher_request_free(req); + crypto_free_skcipher(tfm); goto out; } temp += template[i].tap[k]; } + skcipher_request_free(req); + crypto_free_skcipher(tfm); + pr_info("%s test completed on noncontinuous test vectors for %s algorithm (cipher_keylen:%d) \n", e, algo, template[i].klen); } ret = 0; - out: - skcipher_request_free(req); if (diff_dst) testmgr_free_buf(xoutbuf); out_nooutbuf: @@ -1180,36 +1436,46 @@ return ret; } -static int test_skcipher(struct crypto_skcipher *tfm, int enc, - struct cipher_testvec *template, unsigned int tcount) +static int test_skcipher(struct cipher_testvec *template, unsigned int tcount, + int enc, const char *driver, u32 type, u32 mask) { +#ifdef CONFIG_CRYPTO_ALL_CASES + struct crypto_skcipher *tfm; unsigned int alignmask; +#endif int ret; /* test 'dst == src' case */ - ret = __test_skcipher(tfm, enc, template, tcount, false, 0); + ret = __test_skcipher(template, tcount, enc, false, 0, driver, type, mask); if (ret) return ret; - +#ifdef CONFIG_CRYPTO_ALL_CASES /* test 'dst != src' case */ - ret = __test_skcipher(tfm, enc, template, tcount, true, 0); + ret = __test_skcipher(template, tcount, enc, true, 0, driver, type, mask); if (ret) return ret; /* test unaligned buffers, check with one byte offset */ - ret = __test_skcipher(tfm, enc, template, tcount, true, 1); + ret = __test_skcipher(template, tcount, enc, true, 1, driver, type, mask); if (ret) return ret; + tfm = crypto_alloc_skcipher(driver, type | CRYPTO_ALG_INTERNAL, mask); + if (IS_ERR(tfm)) { + pr_err("alg: skcipher: Failed to load transform for " + "%s: %ld\n", driver, PTR_ERR(tfm)); + return PTR_ERR(tfm); + } alignmask = crypto_tfm_alg_alignmask(&tfm->base); + crypto_free_skcipher(tfm); if (alignmask) { /* Check if alignment mask for tfm is correctly set. */ - ret = __test_skcipher(tfm, enc, template, tcount, true, - alignmask + 1); + ret = __test_skcipher(template, tcount, enc, true, + alignmask + 1, driver, type, mask); if (ret) return ret; } - +#endif return 0; } @@ -1534,29 +1800,24 @@ static int alg_test_aead(const struct alg_test_desc *desc, const char *driver, u32 type, u32 mask) { - struct crypto_aead *tfm; int err = 0; - tfm = crypto_alloc_aead(driver, type | CRYPTO_ALG_INTERNAL, mask); - if (IS_ERR(tfm)) { - printk(KERN_ERR "alg: aead: Failed to load transform for %s: " - "%ld\n", driver, PTR_ERR(tfm)); - return PTR_ERR(tfm); - } - if (desc->suite.aead.enc.vecs) { - err = test_aead(tfm, ENCRYPT, desc->suite.aead.enc.vecs, - desc->suite.aead.enc.count); + err = test_aead(desc->suite.aead.enc.vecs, + desc->suite.aead.enc.count, ENCRYPT, driver, type, mask); if (err) goto out; } - if (!err && desc->suite.aead.dec.vecs) - err = test_aead(tfm, DECRYPT, desc->suite.aead.dec.vecs, - desc->suite.aead.dec.count); + if (!err && desc->suite.aead.dec.vecs) { + err = test_aead(desc->suite.aead.dec.vecs, + desc->suite.aead.dec.count, DECRYPT, driver, type, mask); + if (err) + goto out; + } + pr_info("AEAD test completed for %s algorithm\n", driver); out: - crypto_free_aead(tfm); return err; } @@ -1592,29 +1853,23 @@ static int alg_test_skcipher(const struct alg_test_desc *desc, const char *driver, u32 type, u32 mask) { - struct crypto_skcipher *tfm; int err = 0; - - tfm = crypto_alloc_skcipher(driver, type | CRYPTO_ALG_INTERNAL, mask); - if (IS_ERR(tfm)) { - printk(KERN_ERR "alg: skcipher: Failed to load transform for " - "%s: %ld\n", driver, PTR_ERR(tfm)); - return PTR_ERR(tfm); - } + pr_info("Starting cipher test for %s driver\n", driver); if (desc->suite.cipher.enc.vecs) { - err = test_skcipher(tfm, ENCRYPT, desc->suite.cipher.enc.vecs, - desc->suite.cipher.enc.count); + err = test_skcipher(desc->suite.cipher.enc.vecs, + desc->suite.cipher.enc.count, ENCRYPT, driver, type, mask); if (err) goto out; } - if (desc->suite.cipher.dec.vecs) - err = test_skcipher(tfm, DECRYPT, desc->suite.cipher.dec.vecs, - desc->suite.cipher.dec.count); + if (desc->suite.cipher.dec.vecs) { + err = test_skcipher(desc->suite.cipher.dec.vecs, + desc->suite.cipher.dec.count, DECRYPT, driver, type, mask); + } out: - crypto_free_skcipher(tfm); + pr_info("cipher test %s for %s\n", err ? "failed" : "passed", driver); return err; } @@ -1665,23 +1920,19 @@ static int alg_test_hash(const struct alg_test_desc *desc, const char *driver, u32 type, u32 mask) { - struct crypto_ahash *tfm; int err; + pr_info("Starting ahash test for %s driver\n", driver); - tfm = crypto_alloc_ahash(driver, type | CRYPTO_ALG_INTERNAL, mask); - if (IS_ERR(tfm)) { - printk(KERN_ERR "alg: hash: Failed to load transform for %s: " - "%ld\n", driver, PTR_ERR(tfm)); - return PTR_ERR(tfm); - } + /* Test hash using digest */ + err = test_hash(desc->suite.hash.vecs, desc->suite.hash.count, + true, driver, type, mask); - err = test_hash(tfm, desc->suite.hash.vecs, - desc->suite.hash.count, true); + /* If no error, then test hash without digest */ if (!err) - err = test_hash(tfm, desc->suite.hash.vecs, - desc->suite.hash.count, false); + err = test_hash(desc->suite.hash.vecs, desc->suite.hash.count, + false, driver, type, mask); - crypto_free_ahash(tfm); + pr_info("ahash test %s for %s\n", err ? "failed" : "passed", driver); return err; } @@ -2123,6 +2374,7 @@ }, { .alg = "authenc(hmac(sha1),cbc(aes))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -2149,6 +2401,7 @@ }, { .alg = "authenc(hmac(sha1),cbc(des3_ede))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -2207,6 +2460,7 @@ }, { .alg = "authenc(hmac(sha256),cbc(aes))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -2233,6 +2487,7 @@ }, { .alg = "authenc(hmac(sha256),cbc(des3_ede))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -2243,6 +2498,20 @@ } } } + }, { + .alg = "authenc(hmac(sha384),cbc(aes))", + .test = alg_test_aead, + .fips_allowed = 1, + .suite = { + .aead = { + .enc = { + .vecs = + hmac_sha384_aes_cbc_enc_tv_temp, + .count = + HMAC_SHA384_AES_CBC_ENC_TEST_VEC + } + } + } }, { .alg = "authenc(hmac(sha384),cbc(des))", .test = alg_test_aead,