--- zzzz-none-000/linux-4.4.271/crypto/testmgr.c 2021-06-03 06:22:09.000000000 +0000 +++ hawkeye-5590-750/linux-4.4.271/crypto/testmgr.c 2023-04-19 10:22:28.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,41 @@ 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++) { 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 +274,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 +297,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 +357,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 +385,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 +404,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 +416,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 +429,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 +441,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 +452,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 +474,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 +534,7 @@ char *xbuf[XBUFSIZE]; char *xoutbuf[XBUFSIZE]; char *axbuf[XBUFSIZE]; + const char *algo; iv = kzalloc(MAX_IVLEN, GFP_KERNEL); if (!iv) @@ -476,25 +565,32 @@ 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); - - iv_len = crypto_aead_ivsize(tfm); - + pr_info("running aead test for %s driver\n", driver); for (i = 0, j = 0; i < tcount; i++) { 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 @@ -505,11 +601,15 @@ 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); + iv_len = crypto_aead_ivsize(tfm); if (template[i].iv) memcpy(iv, template[i].iv, iv_len); else @@ -524,6 +624,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); @@ -532,6 +634,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; @@ -541,6 +645,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; } @@ -576,24 +682,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; } @@ -603,11 +717,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; @@ -615,6 +737,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) @@ -629,6 +773,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); @@ -637,6 +783,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; @@ -651,8 +799,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]), @@ -669,10 +821,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]); @@ -700,6 +856,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; } @@ -708,6 +866,8 @@ sg[template[i].anp + k - 1].length + authsize > PAGE_SIZE)) { ret = -EINVAL; + aead_request_free(req); + crypto_free_aead(tfm); goto out; } @@ -733,24 +893,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; } @@ -771,6 +939,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; } @@ -790,17 +960,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) @@ -815,36 +989,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; /* 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; - +#ifdef CONFIG_CRYPTO_ALL_CASES /* 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; } @@ -923,15 +1108,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; @@ -941,7 +1125,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; @@ -959,23 +1144,35 @@ 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++) { 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 @@ -983,8 +1180,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; @@ -1000,6 +1200,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; @@ -1021,6 +1223,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; @@ -1030,6 +1233,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; } @@ -1039,6 +1244,8 @@ d, j, e, algo); hexdump(q, template[i].rlen); ret = -EINVAL; + skcipher_request_free(req); + crypto_free_skcipher(tfm); goto out; } @@ -1049,12 +1256,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; @@ -1062,6 +1277,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 @@ -1078,6 +1314,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; @@ -1089,8 +1327,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]); @@ -1126,6 +1367,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; @@ -1135,6 +1377,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; } @@ -1153,6 +1397,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; } @@ -1163,16 +1409,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: @@ -1181,36 +1430,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; /* 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; - +#ifdef CONFIG_CRYPTO_ALL_CASES /* 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; } @@ -1535,29 +1794,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; } @@ -1593,29 +1847,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; } @@ -1666,23 +1914,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; } @@ -2124,6 +2368,7 @@ }, { .alg = "authenc(hmac(sha1),cbc(aes))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -2150,6 +2395,7 @@ }, { .alg = "authenc(hmac(sha1),cbc(des3_ede))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -2208,6 +2454,7 @@ }, { .alg = "authenc(hmac(sha256),cbc(aes))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -2234,6 +2481,7 @@ }, { .alg = "authenc(hmac(sha256),cbc(des3_ede))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -2244,6 +2492,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,