diff options
Diffstat (limited to 'crypto/testmgr.c')
-rw-r--r-- | crypto/testmgr.c | 366 |
1 files changed, 115 insertions, 251 deletions
diff --git a/crypto/testmgr.c b/crypto/testmgr.c index e61490ba4095..abd609d4c8ef 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -58,6 +58,9 @@ module_param(fuzz_iterations, uint, 0644); MODULE_PARM_DESC(fuzz_iterations, "number of fuzz test iterations"); #endif +/* Multibuffer is unlimited. Set arbitrary limit for testing. */ +#define MAX_MB_MSGS 16 + #ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS /* a perfect nop */ @@ -3320,139 +3323,54 @@ out: return err; } -static int test_comp(struct crypto_comp *tfm, - const struct comp_testvec *ctemplate, - const struct comp_testvec *dtemplate, - int ctcount, int dtcount) +static int test_acomp(struct crypto_acomp *tfm, + const struct comp_testvec *ctemplate, + const struct comp_testvec *dtemplate, + int ctcount, int dtcount) { - const char *algo = crypto_tfm_alg_driver_name(crypto_comp_tfm(tfm)); - char *output, *decomp_output; + const char *algo = crypto_tfm_alg_driver_name(crypto_acomp_tfm(tfm)); + struct scatterlist *src = NULL, *dst = NULL; + struct acomp_req *reqs[MAX_MB_MSGS] = {}; + char *decomp_out[MAX_MB_MSGS] = {}; + char *output[MAX_MB_MSGS] = {}; + struct crypto_wait wait; + struct acomp_req *req; + int ret = -ENOMEM; unsigned int i; - int ret; - - output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); - if (!output) - return -ENOMEM; - - decomp_output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); - if (!decomp_output) { - kfree(output); - return -ENOMEM; - } - - for (i = 0; i < ctcount; i++) { - int ilen; - unsigned int dlen = COMP_BUF_SIZE; - - memset(output, 0, COMP_BUF_SIZE); - memset(decomp_output, 0, COMP_BUF_SIZE); - - ilen = ctemplate[i].inlen; - ret = crypto_comp_compress(tfm, ctemplate[i].input, - ilen, output, &dlen); - if (ret) { - printk(KERN_ERR "alg: comp: compression failed " - "on test %d for %s: ret=%d\n", i + 1, algo, - -ret); - goto out; - } - ilen = dlen; - dlen = COMP_BUF_SIZE; - ret = crypto_comp_decompress(tfm, output, - ilen, decomp_output, &dlen); - if (ret) { - pr_err("alg: comp: compression failed: decompress: on test %d for %s failed: ret=%d\n", - i + 1, algo, -ret); - goto out; - } - - if (dlen != ctemplate[i].inlen) { - printk(KERN_ERR "alg: comp: Compression test %d " - "failed for %s: output len = %d\n", i + 1, algo, - dlen); - ret = -EINVAL; - goto out; - } + src = kmalloc_array(MAX_MB_MSGS, sizeof(*src), GFP_KERNEL); + if (!src) + goto out; + dst = kmalloc_array(MAX_MB_MSGS, sizeof(*dst), GFP_KERNEL); + if (!dst) + goto out; - if (memcmp(decomp_output, ctemplate[i].input, - ctemplate[i].inlen)) { - pr_err("alg: comp: compression failed: output differs: on test %d for %s\n", - i + 1, algo); - hexdump(decomp_output, dlen); - ret = -EINVAL; + for (i = 0; i < MAX_MB_MSGS; i++) { + reqs[i] = acomp_request_alloc(tfm); + if (!reqs[i]) goto out; - } - } - for (i = 0; i < dtcount; i++) { - int ilen; - unsigned int dlen = COMP_BUF_SIZE; - - memset(decomp_output, 0, COMP_BUF_SIZE); - - ilen = dtemplate[i].inlen; - ret = crypto_comp_decompress(tfm, dtemplate[i].input, - ilen, decomp_output, &dlen); - if (ret) { - printk(KERN_ERR "alg: comp: decompression failed " - "on test %d for %s: ret=%d\n", i + 1, algo, - -ret); - goto out; - } + acomp_request_set_callback(reqs[i], + CRYPTO_TFM_REQ_MAY_SLEEP | + CRYPTO_TFM_REQ_MAY_BACKLOG, + crypto_req_done, &wait); + if (i) + acomp_request_chain(reqs[i], reqs[0]); - if (dlen != dtemplate[i].outlen) { - printk(KERN_ERR "alg: comp: Decompression test %d " - "failed for %s: output len = %d\n", i + 1, algo, - dlen); - ret = -EINVAL; + output[i] = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); + if (!output[i]) goto out; - } - if (memcmp(decomp_output, dtemplate[i].output, dlen)) { - printk(KERN_ERR "alg: comp: Decompression test %d " - "failed for %s\n", i + 1, algo); - hexdump(decomp_output, dlen); - ret = -EINVAL; + decomp_out[i] = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); + if (!decomp_out[i]) goto out; - } - } - - ret = 0; - -out: - kfree(decomp_output); - kfree(output); - return ret; -} - -static int test_acomp(struct crypto_acomp *tfm, - const struct comp_testvec *ctemplate, - const struct comp_testvec *dtemplate, - int ctcount, int dtcount) -{ - const char *algo = crypto_tfm_alg_driver_name(crypto_acomp_tfm(tfm)); - unsigned int i; - char *output, *decomp_out; - int ret; - struct scatterlist src, dst; - struct acomp_req *req; - struct crypto_wait wait; - - output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); - if (!output) - return -ENOMEM; - - decomp_out = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); - if (!decomp_out) { - kfree(output); - return -ENOMEM; } for (i = 0; i < ctcount; i++) { unsigned int dlen = COMP_BUF_SIZE; int ilen = ctemplate[i].inlen; void *input_vec; + int j; input_vec = kmemdup(ctemplate[i].input, ilen, GFP_KERNEL); if (!input_vec) { @@ -3460,85 +3378,61 @@ static int test_acomp(struct crypto_acomp *tfm, goto out; } - memset(output, 0, dlen); crypto_init_wait(&wait); - sg_init_one(&src, input_vec, ilen); - sg_init_one(&dst, output, dlen); + sg_init_one(src, input_vec, ilen); - req = acomp_request_alloc(tfm); - if (!req) { - pr_err("alg: acomp: request alloc failed for %s\n", - algo); - kfree(input_vec); - ret = -ENOMEM; - goto out; + for (j = 0; j < MAX_MB_MSGS; j++) { + sg_init_one(dst + j, output[j], dlen); + acomp_request_set_params(reqs[j], src, dst + j, ilen, dlen); } - acomp_request_set_params(req, &src, &dst, ilen, dlen); - acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, - crypto_req_done, &wait); - + req = reqs[0]; ret = crypto_wait_req(crypto_acomp_compress(req), &wait); if (ret) { pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n", i + 1, algo, -ret); kfree(input_vec); - acomp_request_free(req); goto out; } ilen = req->dlen; dlen = COMP_BUF_SIZE; - sg_init_one(&src, output, ilen); - sg_init_one(&dst, decomp_out, dlen); crypto_init_wait(&wait); - acomp_request_set_params(req, &src, &dst, ilen, dlen); - - ret = crypto_wait_req(crypto_acomp_decompress(req), &wait); - if (ret) { - pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n", - i + 1, algo, -ret); - kfree(input_vec); - acomp_request_free(req); - goto out; - } - - if (req->dlen != ctemplate[i].inlen) { - pr_err("alg: acomp: Compression test %d failed for %s: output len = %d\n", - i + 1, algo, req->dlen); - ret = -EINVAL; - kfree(input_vec); - acomp_request_free(req); - goto out; - } - - if (memcmp(input_vec, decomp_out, req->dlen)) { - pr_err("alg: acomp: Compression test %d failed for %s\n", - i + 1, algo); - hexdump(output, req->dlen); - ret = -EINVAL; - kfree(input_vec); - acomp_request_free(req); - goto out; - } + for (j = 0; j < MAX_MB_MSGS; j++) { + sg_init_one(src + j, output[j], ilen); + sg_init_one(dst + j, decomp_out[j], dlen); + acomp_request_set_params(reqs[j], src + j, dst + j, ilen, dlen); + } + + crypto_wait_req(crypto_acomp_decompress(req), &wait); + for (j = 0; j < MAX_MB_MSGS; j++) { + ret = reqs[j]->base.err; + if (ret) { + pr_err("alg: acomp: compression failed on test %d (%d) for %s: ret=%d\n", + i + 1, j, algo, -ret); + kfree(input_vec); + goto out; + } -#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS - crypto_init_wait(&wait); - sg_init_one(&src, input_vec, ilen); - acomp_request_set_params(req, &src, NULL, ilen, 0); + if (reqs[j]->dlen != ctemplate[i].inlen) { + pr_err("alg: acomp: Compression test %d (%d) failed for %s: output len = %d\n", + i + 1, j, algo, reqs[j]->dlen); + ret = -EINVAL; + kfree(input_vec); + goto out; + } - ret = crypto_wait_req(crypto_acomp_compress(req), &wait); - if (ret) { - pr_err("alg: acomp: compression failed on NULL dst buffer test %d for %s: ret=%d\n", - i + 1, algo, -ret); - kfree(input_vec); - acomp_request_free(req); - goto out; + if (memcmp(input_vec, decomp_out[j], reqs[j]->dlen)) { + pr_err("alg: acomp: Compression test %d (%d) failed for %s\n", + i + 1, j, algo); + hexdump(output[j], reqs[j]->dlen); + ret = -EINVAL; + kfree(input_vec); + goto out; + } } -#endif kfree(input_vec); - acomp_request_free(req); } for (i = 0; i < dtcount; i++) { @@ -3552,10 +3446,9 @@ static int test_acomp(struct crypto_acomp *tfm, goto out; } - memset(output, 0, dlen); crypto_init_wait(&wait); - sg_init_one(&src, input_vec, ilen); - sg_init_one(&dst, output, dlen); + sg_init_one(src, input_vec, ilen); + sg_init_one(dst, output[0], dlen); req = acomp_request_alloc(tfm); if (!req) { @@ -3566,7 +3459,7 @@ static int test_acomp(struct crypto_acomp *tfm, goto out; } - acomp_request_set_params(req, &src, &dst, ilen, dlen); + acomp_request_set_params(req, src, dst, ilen, dlen); acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, crypto_req_done, &wait); @@ -3588,30 +3481,16 @@ static int test_acomp(struct crypto_acomp *tfm, goto out; } - if (memcmp(output, dtemplate[i].output, req->dlen)) { + if (memcmp(output[0], dtemplate[i].output, req->dlen)) { pr_err("alg: acomp: Decompression test %d failed for %s\n", i + 1, algo); - hexdump(output, req->dlen); + hexdump(output[0], req->dlen); ret = -EINVAL; kfree(input_vec); acomp_request_free(req); goto out; } -#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS - crypto_init_wait(&wait); - acomp_request_set_params(req, &src, NULL, ilen, 0); - - ret = crypto_wait_req(crypto_acomp_decompress(req), &wait); - if (ret) { - pr_err("alg: acomp: decompression failed on NULL dst buffer test %d for %s: ret=%d\n", - i + 1, algo, -ret); - kfree(input_vec); - acomp_request_free(req); - goto out; - } -#endif - kfree(input_vec); acomp_request_free(req); } @@ -3619,8 +3498,13 @@ static int test_acomp(struct crypto_acomp *tfm, ret = 0; out: - kfree(decomp_out); - kfree(output); + acomp_request_free(reqs[0]); + for (i = 0; i < MAX_MB_MSGS; i++) { + kfree(output[i]); + kfree(decomp_out[i]); + } + kfree(dst); + kfree(src); return ret; } @@ -3713,42 +3597,22 @@ static int alg_test_cipher(const struct alg_test_desc *desc, static int alg_test_comp(const struct alg_test_desc *desc, const char *driver, u32 type, u32 mask) { - struct crypto_comp *comp; struct crypto_acomp *acomp; int err; - u32 algo_type = type & CRYPTO_ALG_TYPE_ACOMPRESS_MASK; - if (algo_type == CRYPTO_ALG_TYPE_ACOMPRESS) { - acomp = crypto_alloc_acomp(driver, type, mask); - if (IS_ERR(acomp)) { - if (PTR_ERR(acomp) == -ENOENT) - return 0; - pr_err("alg: acomp: Failed to load transform for %s: %ld\n", - driver, PTR_ERR(acomp)); - return PTR_ERR(acomp); - } - err = test_acomp(acomp, desc->suite.comp.comp.vecs, - desc->suite.comp.decomp.vecs, - desc->suite.comp.comp.count, - desc->suite.comp.decomp.count); - crypto_free_acomp(acomp); - } else { - comp = crypto_alloc_comp(driver, type, mask); - if (IS_ERR(comp)) { - if (PTR_ERR(comp) == -ENOENT) - return 0; - pr_err("alg: comp: Failed to load transform for %s: %ld\n", - driver, PTR_ERR(comp)); - return PTR_ERR(comp); - } - - err = test_comp(comp, desc->suite.comp.comp.vecs, - desc->suite.comp.decomp.vecs, - desc->suite.comp.comp.count, - desc->suite.comp.decomp.count); - - crypto_free_comp(comp); - } + acomp = crypto_alloc_acomp(driver, type, mask); + if (IS_ERR(acomp)) { + if (PTR_ERR(acomp) == -ENOENT) + return 0; + pr_err("alg: acomp: Failed to load transform for %s: %ld\n", + driver, PTR_ERR(acomp)); + return PTR_ERR(acomp); + } + err = test_acomp(acomp, desc->suite.comp.comp.vecs, + desc->suite.comp.decomp.vecs, + desc->suite.comp.comp.count, + desc->suite.comp.decomp.count); + crypto_free_acomp(acomp); return err; } @@ -4328,7 +4192,7 @@ static int test_sig_one(struct crypto_sig *tfm, const struct sig_testvec *vecs) if (vecs->public_key_vec) return 0; - sig_size = crypto_sig_keysize(tfm); + sig_size = crypto_sig_maxsize(tfm); if (sig_size < vecs->c_size) { pr_err("alg: sig: invalid maxsize %u\n", sig_size); return -EINVAL; @@ -4340,13 +4204,14 @@ static int test_sig_one(struct crypto_sig *tfm, const struct sig_testvec *vecs) /* Run asymmetric signature generation */ err = crypto_sig_sign(tfm, vecs->m, vecs->m_size, sig, sig_size); - if (err) { + if (err < 0) { pr_err("alg: sig: sign test failed: err %d\n", err); return err; } /* Verify that generated signature equals cooked signature */ - if (memcmp(sig, vecs->c, vecs->c_size) || + if (err != vecs->c_size || + memcmp(sig, vecs->c, vecs->c_size) || memchr_inv(sig + vecs->c_size, 0, sig_size - vecs->c_size)) { pr_err("alg: sig: sign test failed: invalid output\n"); hexdump(sig, sig_size); @@ -4505,6 +4370,12 @@ static const struct alg_test_desc alg_test_descs[] = { .test = alg_test_null, .fips_allowed = 1, }, { + .alg = "authenc(hmac(sha256),cts(cbc(aes)))", + .test = alg_test_aead, + .suite = { + .aead = __VECS(krb5_test_aes128_cts_hmac_sha256_128) + } + }, { .alg = "authenc(hmac(sha256),rfc3686(ctr(aes)))", .test = alg_test_null, .fips_allowed = 1, @@ -4525,6 +4396,12 @@ static const struct alg_test_desc alg_test_descs[] = { .test = alg_test_null, .fips_allowed = 1, }, { + .alg = "authenc(hmac(sha384),cts(cbc(aes)))", + .test = alg_test_aead, + .suite = { + .aead = __VECS(krb5_test_aes256_cts_hmac_sha384_192) + } + }, { .alg = "authenc(hmac(sha384),rfc3686(ctr(aes)))", .test = alg_test_null, .fips_allowed = 1, @@ -4743,9 +4620,6 @@ static const struct alg_test_desc alg_test_descs[] = { .hash = __VECS(sm4_cmac128_tv_template) } }, { - .alg = "compress_null", - .test = alg_test_null, - }, { .alg = "crc32", .test = alg_test_hash, .fips_allowed = 1, @@ -4760,20 +4634,6 @@ static const struct alg_test_desc alg_test_descs[] = { .hash = __VECS(crc32c_tv_template) } }, { - .alg = "crc64-rocksoft", - .test = alg_test_hash, - .fips_allowed = 1, - .suite = { - .hash = __VECS(crc64_rocksoft_tv_template) - } - }, { - .alg = "crct10dif", - .test = alg_test_hash, - .fips_allowed = 1, - .suite = { - .hash = __VECS(crct10dif_tv_template) - } - }, { .alg = "ctr(aes)", .test = alg_test_skcipher, .fips_allowed = 1, @@ -5398,6 +5258,10 @@ static const struct alg_test_desc alg_test_descs[] = { .fips_allowed = 1, .test = alg_test_null, }, { + .alg = "krb5enc(cmac(camellia),cts(cbc(camellia)))", + .test = alg_test_aead, + .suite.aead = __VECS(krb5_test_camellia_cts_cmac) + }, { .alg = "lrw(aes)", .generic_driver = "lrw(ecb(aes-generic))", .test = alg_test_skcipher, |