diff options
author | Vitaly Chikunov <vt@altlinux.org> | 2019-01-07 12:54:27 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2019-01-18 05:40:24 -0500 |
commit | 0507de9404992edafa3d1d86450a37d6a726399d (patch) | |
tree | 681b8d55bf606da4438939d7b23ca545eca0c5d7 /crypto/testmgr.c | |
parent | 2b091e32a2d357beb9ffe283c696eec104729c2a (diff) |
crypto: testmgr - split akcipher tests by a key type
Before this, if akcipher_testvec have `public_key_vec' set to true
(i.e. having a public key) only sign/encrypt test is performed, but
verify/decrypt test is skipped.
With a public key we could do encrypt and verify, but to sign and decrypt
a private key is required.
This logic is correct for encrypt/decrypt tests (decrypt is skipped if
no private key). But incorrect for sign/verify tests - sign is performed
no matter if there is no private key, but verify is skipped if there is
a public key.
Rework `test_akcipher_one' to arrange tests properly depending on value
of `public_key_vec` and `siggen_sigver_test'.
No tests were missed since there is only one sign/verify test (which
have `siggen_sigver_test' set to true) and it has a private key, but
future tests could benefit from this improvement.
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/testmgr.c')
-rw-r--r-- | crypto/testmgr.c | 86 |
1 files changed, 57 insertions, 29 deletions
diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 0f684a414acb..1ce53f8058d2 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c | |||
@@ -2238,6 +2238,9 @@ static int test_akcipher_one(struct crypto_akcipher *tfm, | |||
2238 | unsigned int out_len_max, out_len = 0; | 2238 | unsigned int out_len_max, out_len = 0; |
2239 | int err = -ENOMEM; | 2239 | int err = -ENOMEM; |
2240 | struct scatterlist src, dst, src_tab[2]; | 2240 | struct scatterlist src, dst, src_tab[2]; |
2241 | const char *m, *c; | ||
2242 | unsigned int m_size, c_size; | ||
2243 | const char *op; | ||
2241 | 2244 | ||
2242 | if (testmgr_alloc_buf(xbuf)) | 2245 | if (testmgr_alloc_buf(xbuf)) |
2243 | return err; | 2246 | return err; |
@@ -2259,46 +2262,72 @@ static int test_akcipher_one(struct crypto_akcipher *tfm, | |||
2259 | 2262 | ||
2260 | err = -ENOMEM; | 2263 | err = -ENOMEM; |
2261 | out_len_max = crypto_akcipher_maxsize(tfm); | 2264 | out_len_max = crypto_akcipher_maxsize(tfm); |
2265 | |||
2266 | /* | ||
2267 | * First run test which do not require a private key, such as | ||
2268 | * encrypt or verify. | ||
2269 | */ | ||
2262 | outbuf_enc = kzalloc(out_len_max, GFP_KERNEL); | 2270 | outbuf_enc = kzalloc(out_len_max, GFP_KERNEL); |
2263 | if (!outbuf_enc) | 2271 | if (!outbuf_enc) |
2264 | goto free_req; | 2272 | goto free_req; |
2265 | 2273 | ||
2266 | if (WARN_ON(vecs->m_size > PAGE_SIZE)) | 2274 | if (!vecs->siggen_sigver_test) { |
2267 | goto free_all; | 2275 | m = vecs->m; |
2276 | m_size = vecs->m_size; | ||
2277 | c = vecs->c; | ||
2278 | c_size = vecs->c_size; | ||
2279 | op = "encrypt"; | ||
2280 | } else { | ||
2281 | /* Swap args so we could keep plaintext (digest) | ||
2282 | * in vecs->m, and cooked signature in vecs->c. | ||
2283 | */ | ||
2284 | m = vecs->c; /* signature */ | ||
2285 | m_size = vecs->c_size; | ||
2286 | c = vecs->m; /* digest */ | ||
2287 | c_size = vecs->m_size; | ||
2288 | op = "verify"; | ||
2289 | } | ||
2268 | 2290 | ||
2269 | memcpy(xbuf[0], vecs->m, vecs->m_size); | 2291 | if (WARN_ON(m_size > PAGE_SIZE)) |
2292 | goto free_all; | ||
2293 | memcpy(xbuf[0], m, m_size); | ||
2270 | 2294 | ||
2271 | sg_init_table(src_tab, 2); | 2295 | sg_init_table(src_tab, 2); |
2272 | sg_set_buf(&src_tab[0], xbuf[0], 8); | 2296 | sg_set_buf(&src_tab[0], xbuf[0], 8); |
2273 | sg_set_buf(&src_tab[1], xbuf[0] + 8, vecs->m_size - 8); | 2297 | sg_set_buf(&src_tab[1], xbuf[0] + 8, m_size - 8); |
2274 | sg_init_one(&dst, outbuf_enc, out_len_max); | 2298 | sg_init_one(&dst, outbuf_enc, out_len_max); |
2275 | akcipher_request_set_crypt(req, src_tab, &dst, vecs->m_size, | 2299 | akcipher_request_set_crypt(req, src_tab, &dst, m_size, |
2276 | out_len_max); | 2300 | out_len_max); |
2277 | akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, | 2301 | akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, |
2278 | crypto_req_done, &wait); | 2302 | crypto_req_done, &wait); |
2279 | 2303 | ||
2280 | err = crypto_wait_req(vecs->siggen_sigver_test ? | 2304 | err = crypto_wait_req(vecs->siggen_sigver_test ? |
2281 | /* Run asymmetric signature generation */ | 2305 | /* Run asymmetric signature verification */ |
2282 | crypto_akcipher_sign(req) : | 2306 | crypto_akcipher_verify(req) : |
2283 | /* Run asymmetric encrypt */ | 2307 | /* Run asymmetric encrypt */ |
2284 | crypto_akcipher_encrypt(req), &wait); | 2308 | crypto_akcipher_encrypt(req), &wait); |
2285 | if (err) { | 2309 | if (err) { |
2286 | pr_err("alg: akcipher: encrypt test failed. err %d\n", err); | 2310 | pr_err("alg: akcipher: %s test failed. err %d\n", op, err); |
2287 | goto free_all; | 2311 | goto free_all; |
2288 | } | 2312 | } |
2289 | if (req->dst_len != vecs->c_size) { | 2313 | if (req->dst_len != c_size) { |
2290 | pr_err("alg: akcipher: encrypt test failed. Invalid output len\n"); | 2314 | pr_err("alg: akcipher: %s test failed. Invalid output len\n", |
2315 | op); | ||
2291 | err = -EINVAL; | 2316 | err = -EINVAL; |
2292 | goto free_all; | 2317 | goto free_all; |
2293 | } | 2318 | } |
2294 | /* verify that encrypted message is equal to expected */ | 2319 | /* verify that encrypted message is equal to expected */ |
2295 | if (memcmp(vecs->c, outbuf_enc, vecs->c_size)) { | 2320 | if (memcmp(c, outbuf_enc, c_size)) { |
2296 | pr_err("alg: akcipher: encrypt test failed. Invalid output\n"); | 2321 | pr_err("alg: akcipher: %s test failed. Invalid output\n", op); |
2297 | hexdump(outbuf_enc, vecs->c_size); | 2322 | hexdump(outbuf_enc, c_size); |
2298 | err = -EINVAL; | 2323 | err = -EINVAL; |
2299 | goto free_all; | 2324 | goto free_all; |
2300 | } | 2325 | } |
2301 | /* Don't invoke decrypt for vectors with public key */ | 2326 | |
2327 | /* | ||
2328 | * Don't invoke (decrypt or sign) test which require a private key | ||
2329 | * for vectors with only a public key. | ||
2330 | */ | ||
2302 | if (vecs->public_key_vec) { | 2331 | if (vecs->public_key_vec) { |
2303 | err = 0; | 2332 | err = 0; |
2304 | goto free_all; | 2333 | goto free_all; |
@@ -2309,37 +2338,36 @@ static int test_akcipher_one(struct crypto_akcipher *tfm, | |||
2309 | goto free_all; | 2338 | goto free_all; |
2310 | } | 2339 | } |
2311 | 2340 | ||
2312 | if (WARN_ON(vecs->c_size > PAGE_SIZE)) | 2341 | op = vecs->siggen_sigver_test ? "sign" : "decrypt"; |
2342 | if (WARN_ON(c_size > PAGE_SIZE)) | ||
2313 | goto free_all; | 2343 | goto free_all; |
2344 | memcpy(xbuf[0], c, c_size); | ||
2314 | 2345 | ||
2315 | memcpy(xbuf[0], vecs->c, vecs->c_size); | 2346 | sg_init_one(&src, xbuf[0], c_size); |
2316 | |||
2317 | sg_init_one(&src, xbuf[0], vecs->c_size); | ||
2318 | sg_init_one(&dst, outbuf_dec, out_len_max); | 2347 | sg_init_one(&dst, outbuf_dec, out_len_max); |
2319 | crypto_init_wait(&wait); | 2348 | crypto_init_wait(&wait); |
2320 | akcipher_request_set_crypt(req, &src, &dst, vecs->c_size, out_len_max); | 2349 | akcipher_request_set_crypt(req, &src, &dst, c_size, out_len_max); |
2321 | 2350 | ||
2322 | err = crypto_wait_req(vecs->siggen_sigver_test ? | 2351 | err = crypto_wait_req(vecs->siggen_sigver_test ? |
2323 | /* Run asymmetric signature verification */ | 2352 | /* Run asymmetric signature generation */ |
2324 | crypto_akcipher_verify(req) : | 2353 | crypto_akcipher_sign(req) : |
2325 | /* Run asymmetric decrypt */ | 2354 | /* Run asymmetric decrypt */ |
2326 | crypto_akcipher_decrypt(req), &wait); | 2355 | crypto_akcipher_decrypt(req), &wait); |
2327 | if (err) { | 2356 | if (err) { |
2328 | pr_err("alg: akcipher: decrypt test failed. err %d\n", err); | 2357 | pr_err("alg: akcipher: %s test failed. err %d\n", op, err); |
2329 | goto free_all; | 2358 | goto free_all; |
2330 | } | 2359 | } |
2331 | out_len = req->dst_len; | 2360 | out_len = req->dst_len; |
2332 | if (out_len < vecs->m_size) { | 2361 | if (out_len < m_size) { |
2333 | pr_err("alg: akcipher: decrypt test failed. " | 2362 | pr_err("alg: akcipher: %s test failed. Invalid output len %u\n", |
2334 | "Invalid output len %u\n", out_len); | 2363 | op, out_len); |
2335 | err = -EINVAL; | 2364 | err = -EINVAL; |
2336 | goto free_all; | 2365 | goto free_all; |
2337 | } | 2366 | } |
2338 | /* verify that decrypted message is equal to the original msg */ | 2367 | /* verify that decrypted message is equal to the original msg */ |
2339 | if (memchr_inv(outbuf_dec, 0, out_len - vecs->m_size) || | 2368 | if (memchr_inv(outbuf_dec, 0, out_len - m_size) || |
2340 | memcmp(vecs->m, outbuf_dec + out_len - vecs->m_size, | 2369 | memcmp(m, outbuf_dec + out_len - m_size, m_size)) { |
2341 | vecs->m_size)) { | 2370 | pr_err("alg: akcipher: %s test failed. Invalid output\n", op); |
2342 | pr_err("alg: akcipher: decrypt test failed. Invalid output\n"); | ||
2343 | hexdump(outbuf_dec, out_len); | 2371 | hexdump(outbuf_dec, out_len); |
2344 | err = -EINVAL; | 2372 | err = -EINVAL; |
2345 | } | 2373 | } |