diff options
author | Tony Lindgren <tony@atomide.com> | 2016-03-30 20:36:06 +0300 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2016-03-30 20:36:06 +0300 |
commit | 1809de7e7d37c585e01a1bcc583ea92b78fc759d (patch) | |
tree | 76c5b35c2b04eafce86a1a729c02ab705eba44bc /crypto/testmgr.c | |
parent | ebf24414809200915b9ddf7f109bba7c278c8210 (diff) | |
parent | 3ca4a238106dedc285193ee47f494a6584b6fd2f (diff) | |
download | linux-1809de7e7d37c585e01a1bcc583ea92b78fc759d.tar.xz |
Merge tag 'for-v4.6-rc/omap-fixes-a' of git://git.kernel.org/pub/scm/linux/kernel/git/pjw/omap-pending into omap-for-v4.6/fixes
ARM: OMAP2+: first hwmod fix for v4.6-rc
Fix a longstanding bug in the hwmod code that could cause
hardware SYSCONFIG register values to not match the kernel's
idea of what they should be, and that could result in lower
performance during IP block idle entry.
Basic build, boot, and PM test logs are available here:
http://www.pwsan.com/omap/testlogs/omap-hwmod-fixes-a-for-v4.6-rc/20160326231727/
Diffstat (limited to 'crypto/testmgr.c')
-rw-r--r-- | crypto/testmgr.c | 401 |
1 files changed, 175 insertions, 226 deletions
diff --git a/crypto/testmgr.c b/crypto/testmgr.c index ae8c57fd8bc7..b86883aedca1 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -96,13 +96,6 @@ struct comp_test_suite { } comp, decomp; }; -struct pcomp_test_suite { - struct { - struct pcomp_testvec *vecs; - unsigned int count; - } comp, decomp; -}; - struct hash_test_suite { struct hash_testvec *vecs; unsigned int count; @@ -133,7 +126,6 @@ struct alg_test_desc { struct aead_test_suite aead; struct cipher_test_suite cipher; struct comp_test_suite comp; - struct pcomp_test_suite pcomp; struct hash_test_suite hash; struct cprng_test_suite cprng; struct drbg_test_suite drbg; @@ -198,6 +190,61 @@ static int wait_async_op(struct tcrypt_result *tr, int ret) return ret; } +static int ahash_partial_update(struct ahash_request **preq, + struct crypto_ahash *tfm, struct hash_testvec *template, + void *hash_buff, int k, int temp, struct scatterlist *sg, + const char *algo, char *result, struct tcrypt_result *tresult) +{ + char *state; + struct ahash_request *req; + int statesize, ret = -EINVAL; + + req = *preq; + statesize = crypto_ahash_statesize( + crypto_ahash_reqtfm(req)); + state = kmalloc(statesize, GFP_KERNEL); + if (!state) { + pr_err("alt: hash: Failed to alloc state for %s\n", algo); + goto out_nostate; + } + ret = crypto_ahash_export(req, state); + if (ret) { + pr_err("alt: hash: Failed to export() for %s\n", algo); + goto out; + } + ahash_request_free(req); + req = ahash_request_alloc(tfm, GFP_KERNEL); + if (!req) { + pr_err("alg: hash: Failed to alloc request for %s\n", algo); + goto out_noreq; + } + ahash_request_set_callback(req, + CRYPTO_TFM_REQ_MAY_BACKLOG, + tcrypt_complete, tresult); + + memcpy(hash_buff, template->plaintext + temp, + template->tap[k]); + sg_init_one(&sg[0], hash_buff, template->tap[k]); + ahash_request_set_crypt(req, sg, result, template->tap[k]); + ret = crypto_ahash_import(req, state); + if (ret) { + pr_err("alg: hash: Failed to import() for %s\n", algo); + goto out; + } + ret = wait_async_op(tresult, crypto_ahash_update(req)); + if (ret) + goto out; + *preq = req; + ret = 0; + goto out_noreq; +out: + ahash_request_free(req); +out_noreq: + kfree(state); +out_nostate: + return ret; +} + static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, unsigned int tcount, bool use_digest, const int align_offset) @@ -385,6 +432,84 @@ static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, } } + /* partial update exercise */ + j = 0; + for (i = 0; i < tcount; i++) { + /* alignment tests are only done with continuous buffers */ + if (align_offset != 0) + break; + + if (template[i].np < 2) + continue; + + j++; + memset(result, 0, MAX_DIGEST_SIZE); + + ret = -EINVAL; + hash_buff = xbuf[0]; + memcpy(hash_buff, template[i].plaintext, + template[i].tap[0]); + sg_init_one(&sg[0], hash_buff, template[i].tap[0]); + + if (template[i].ksize) { + crypto_ahash_clear_flags(tfm, ~0); + if (template[i].ksize > MAX_KEYLEN) { + 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; + } + memcpy(key, template[i].key, template[i].ksize); + ret = crypto_ahash_setkey(tfm, key, template[i].ksize); + if (ret) { + pr_err("alg: hash: setkey failed on test %d for %s: ret=%d\n", + j, algo, -ret); + goto out; + } + } + + ahash_request_set_crypt(req, sg, result, template[i].tap[0]); + 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; + } + 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; + } + + temp = template[i].tap[0]; + for (k = 1; k < template[i].np; k++) { + ret = ahash_partial_update(&req, tfm, &template[i], + hash_buff, k, temp, &sg[0], algo, result, + &tresult); + if (ret) { + pr_err("hash: partial update failed on test %d for %s: ret=%d\n", + j, algo, -ret); + goto out_noreq; + } + temp += template[i].tap[k]; + } + 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; + } + if (memcmp(result, template[i].digest, + crypto_ahash_digestsize(tfm))) { + pr_err("alg: hash: Partial Test %d failed for %s\n", + j, algo); + hexdump(result, crypto_ahash_digestsize(tfm)); + ret = -EINVAL; + goto out; + } + } + ret = 0; out: @@ -488,6 +613,8 @@ static int __test_aead(struct crypto_aead *tfm, int enc, aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, tcrypt_complete, &result); + iv_len = crypto_aead_ivsize(tfm); + for (i = 0, j = 0; i < tcount; i++) { if (template[i].np) continue; @@ -508,7 +635,6 @@ static int __test_aead(struct crypto_aead *tfm, int enc, 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 @@ -617,7 +743,7 @@ static int __test_aead(struct crypto_aead *tfm, int enc, j++; if (template[i].iv) - memcpy(iv, template[i].iv, MAX_IVLEN); + memcpy(iv, template[i].iv, iv_len); else memset(iv, 0, MAX_IVLEN); @@ -1293,183 +1419,6 @@ out: return ret; } -static int test_pcomp(struct crypto_pcomp *tfm, - struct pcomp_testvec *ctemplate, - struct pcomp_testvec *dtemplate, int ctcount, - int dtcount) -{ - const char *algo = crypto_tfm_alg_driver_name(crypto_pcomp_tfm(tfm)); - unsigned int i; - char result[COMP_BUF_SIZE]; - int res; - - for (i = 0; i < ctcount; i++) { - struct comp_request req; - unsigned int produced = 0; - - res = crypto_compress_setup(tfm, ctemplate[i].params, - ctemplate[i].paramsize); - if (res) { - pr_err("alg: pcomp: compression setup failed on test " - "%d for %s: error=%d\n", i + 1, algo, res); - return res; - } - - res = crypto_compress_init(tfm); - if (res) { - pr_err("alg: pcomp: compression init failed on test " - "%d for %s: error=%d\n", i + 1, algo, res); - return res; - } - - memset(result, 0, sizeof(result)); - - req.next_in = ctemplate[i].input; - req.avail_in = ctemplate[i].inlen / 2; - req.next_out = result; - req.avail_out = ctemplate[i].outlen / 2; - - res = crypto_compress_update(tfm, &req); - if (res < 0 && (res != -EAGAIN || req.avail_in)) { - pr_err("alg: pcomp: compression update failed on test " - "%d for %s: error=%d\n", i + 1, algo, res); - return res; - } - if (res > 0) - produced += res; - - /* Add remaining input data */ - req.avail_in += (ctemplate[i].inlen + 1) / 2; - - res = crypto_compress_update(tfm, &req); - if (res < 0 && (res != -EAGAIN || req.avail_in)) { - pr_err("alg: pcomp: compression update failed on test " - "%d for %s: error=%d\n", i + 1, algo, res); - return res; - } - if (res > 0) - produced += res; - - /* Provide remaining output space */ - req.avail_out += COMP_BUF_SIZE - ctemplate[i].outlen / 2; - - res = crypto_compress_final(tfm, &req); - if (res < 0) { - pr_err("alg: pcomp: compression final failed on test " - "%d for %s: error=%d\n", i + 1, algo, res); - return res; - } - produced += res; - - if (COMP_BUF_SIZE - req.avail_out != ctemplate[i].outlen) { - pr_err("alg: comp: Compression test %d failed for %s: " - "output len = %d (expected %d)\n", i + 1, algo, - COMP_BUF_SIZE - req.avail_out, - ctemplate[i].outlen); - return -EINVAL; - } - - if (produced != ctemplate[i].outlen) { - pr_err("alg: comp: Compression test %d failed for %s: " - "returned len = %u (expected %d)\n", i + 1, - algo, produced, ctemplate[i].outlen); - return -EINVAL; - } - - if (memcmp(result, ctemplate[i].output, ctemplate[i].outlen)) { - pr_err("alg: pcomp: Compression test %d failed for " - "%s\n", i + 1, algo); - hexdump(result, ctemplate[i].outlen); - return -EINVAL; - } - } - - for (i = 0; i < dtcount; i++) { - struct comp_request req; - unsigned int produced = 0; - - res = crypto_decompress_setup(tfm, dtemplate[i].params, - dtemplate[i].paramsize); - if (res) { - pr_err("alg: pcomp: decompression setup failed on " - "test %d for %s: error=%d\n", i + 1, algo, res); - return res; - } - - res = crypto_decompress_init(tfm); - if (res) { - pr_err("alg: pcomp: decompression init failed on test " - "%d for %s: error=%d\n", i + 1, algo, res); - return res; - } - - memset(result, 0, sizeof(result)); - - req.next_in = dtemplate[i].input; - req.avail_in = dtemplate[i].inlen / 2; - req.next_out = result; - req.avail_out = dtemplate[i].outlen / 2; - - res = crypto_decompress_update(tfm, &req); - if (res < 0 && (res != -EAGAIN || req.avail_in)) { - pr_err("alg: pcomp: decompression update failed on " - "test %d for %s: error=%d\n", i + 1, algo, res); - return res; - } - if (res > 0) - produced += res; - - /* Add remaining input data */ - req.avail_in += (dtemplate[i].inlen + 1) / 2; - - res = crypto_decompress_update(tfm, &req); - if (res < 0 && (res != -EAGAIN || req.avail_in)) { - pr_err("alg: pcomp: decompression update failed on " - "test %d for %s: error=%d\n", i + 1, algo, res); - return res; - } - if (res > 0) - produced += res; - - /* Provide remaining output space */ - req.avail_out += COMP_BUF_SIZE - dtemplate[i].outlen / 2; - - res = crypto_decompress_final(tfm, &req); - if (res < 0 && (res != -EAGAIN || req.avail_in)) { - pr_err("alg: pcomp: decompression final failed on " - "test %d for %s: error=%d\n", i + 1, algo, res); - return res; - } - if (res > 0) - produced += res; - - if (COMP_BUF_SIZE - req.avail_out != dtemplate[i].outlen) { - pr_err("alg: comp: Decompression test %d failed for " - "%s: output len = %d (expected %d)\n", i + 1, - algo, COMP_BUF_SIZE - req.avail_out, - dtemplate[i].outlen); - return -EINVAL; - } - - if (produced != dtemplate[i].outlen) { - pr_err("alg: comp: Decompression test %d failed for " - "%s: returned len = %u (expected %d)\n", i + 1, - algo, produced, dtemplate[i].outlen); - return -EINVAL; - } - - if (memcmp(result, dtemplate[i].output, dtemplate[i].outlen)) { - pr_err("alg: pcomp: Decompression test %d failed for " - "%s\n", i + 1, algo); - hexdump(result, dtemplate[i].outlen); - return -EINVAL; - } - } - - return 0; -} - - static int test_cprng(struct crypto_rng *tfm, struct cprng_testvec *template, unsigned int tcount) { @@ -1640,28 +1589,6 @@ static int alg_test_comp(const struct alg_test_desc *desc, const char *driver, return err; } -static int alg_test_pcomp(const struct alg_test_desc *desc, const char *driver, - u32 type, u32 mask) -{ - struct crypto_pcomp *tfm; - int err; - - tfm = crypto_alloc_pcomp(driver, type, mask); - if (IS_ERR(tfm)) { - pr_err("alg: pcomp: Failed to load transform for %s: %ld\n", - driver, PTR_ERR(tfm)); - return PTR_ERR(tfm); - } - - err = test_pcomp(tfm, desc->suite.pcomp.comp.vecs, - desc->suite.pcomp.decomp.vecs, - desc->suite.pcomp.comp.count, - desc->suite.pcomp.decomp.count); - - crypto_free_pcomp(tfm); - return err; -} - static int alg_test_hash(const struct alg_test_desc *desc, const char *driver, u32 type, u32 mask) { @@ -2081,7 +2008,6 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "ansi_cprng", .test = alg_test_cprng, - .fips_allowed = 1, .suite = { .cprng = { .vecs = ansi_cprng_aes_tv_template, @@ -2132,6 +2058,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "authenc(hmac(sha1),cbc(des3_ede))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -2143,6 +2070,10 @@ static const struct alg_test_desc alg_test_descs[] = { } } }, { + .alg = "authenc(hmac(sha1),ctr(aes))", + .test = alg_test_null, + .fips_allowed = 1, + }, { .alg = "authenc(hmac(sha1),ecb(cipher_null))", .test = alg_test_aead, .suite = { @@ -2162,6 +2093,10 @@ static const struct alg_test_desc alg_test_descs[] = { } } }, { + .alg = "authenc(hmac(sha1),rfc3686(ctr(aes)))", + .test = alg_test_null, + .fips_allowed = 1, + }, { .alg = "authenc(hmac(sha224),cbc(des))", .test = alg_test_aead, .suite = { @@ -2177,6 +2112,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "authenc(hmac(sha224),cbc(des3_ede))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -2190,6 +2126,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "authenc(hmac(sha256),cbc(aes))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -2216,6 +2153,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "authenc(hmac(sha256),cbc(des3_ede))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -2227,6 +2165,14 @@ static const struct alg_test_desc alg_test_descs[] = { } } }, { + .alg = "authenc(hmac(sha256),ctr(aes))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "authenc(hmac(sha256),rfc3686(ctr(aes)))", + .test = alg_test_null, + .fips_allowed = 1, + }, { .alg = "authenc(hmac(sha384),cbc(des))", .test = alg_test_aead, .suite = { @@ -2242,6 +2188,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "authenc(hmac(sha384),cbc(des3_ede))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -2253,7 +2200,16 @@ static const struct alg_test_desc alg_test_descs[] = { } } }, { + .alg = "authenc(hmac(sha384),ctr(aes))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "authenc(hmac(sha384),rfc3686(ctr(aes)))", + .test = alg_test_null, + .fips_allowed = 1, + }, { .alg = "authenc(hmac(sha512),cbc(aes))", + .fips_allowed = 1, .test = alg_test_aead, .suite = { .aead = { @@ -2281,6 +2237,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "authenc(hmac(sha512),cbc(des3_ede))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -2292,6 +2249,14 @@ static const struct alg_test_desc alg_test_descs[] = { } } }, { + .alg = "authenc(hmac(sha512),ctr(aes))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "authenc(hmac(sha512),rfc3686(ctr(aes)))", + .test = alg_test_null, + .fips_allowed = 1, + }, { .alg = "cbc(aes)", .test = alg_test_skcipher, .fips_allowed = 1, @@ -3840,22 +3805,6 @@ static const struct alg_test_desc alg_test_descs[] = { } } } - }, { - .alg = "zlib", - .test = alg_test_pcomp, - .fips_allowed = 1, - .suite = { - .pcomp = { - .comp = { - .vecs = zlib_comp_tv_template, - .count = ZLIB_COMP_TEST_VECTORS - }, - .decomp = { - .vecs = zlib_decomp_tv_template, - .count = ZLIB_DECOMP_TEST_VECTORS - } - } - } } }; |