diff options
author | Wang, Rui Y <rui.y.wang@intel.com> | 2016-02-03 05:26:57 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2016-02-06 02:33:27 -0500 |
commit | 018ba95c71c0b0ef7abc8d584bf556ffd1f5b230 (patch) | |
tree | b40361ec7f29cc999558dc6674d7be1a32c3622e /crypto/testmgr.c | |
parent | 1e0a6e1747b760b95b05ede659c8a6e5eb9b8acb (diff) |
crypto: testmgr - Add a test case for import()/export()
Modify __test_hash() so that hash import/export can be tested
from within the kernel. The test is unconditionally done when
a struct hash_testvec has its .np > 1.
v3: make the test unconditional
v2: Leverage template[i].np as suggested by Tim Chen
Signed-off-by: Rui Wang <rui.y.wang@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/testmgr.c')
-rw-r--r-- | crypto/testmgr.c | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/crypto/testmgr.c b/crypto/testmgr.c index cbd78c954844..cde6a2983937 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c | |||
@@ -190,6 +190,61 @@ static int wait_async_op(struct tcrypt_result *tr, int ret) | |||
190 | return ret; | 190 | return ret; |
191 | } | 191 | } |
192 | 192 | ||
193 | static int ahash_partial_update(struct ahash_request **preq, | ||
194 | struct crypto_ahash *tfm, struct hash_testvec *template, | ||
195 | void *hash_buff, int k, int temp, struct scatterlist *sg, | ||
196 | const char *algo, char *result, struct tcrypt_result *tresult) | ||
197 | { | ||
198 | char *state; | ||
199 | struct ahash_request *req; | ||
200 | int statesize, ret = -EINVAL; | ||
201 | |||
202 | req = *preq; | ||
203 | statesize = crypto_ahash_statesize( | ||
204 | crypto_ahash_reqtfm(req)); | ||
205 | state = kmalloc(statesize, GFP_KERNEL); | ||
206 | if (!state) { | ||
207 | pr_err("alt: hash: Failed to alloc state for %s\n", algo); | ||
208 | goto out_nostate; | ||
209 | } | ||
210 | ret = crypto_ahash_export(req, state); | ||
211 | if (ret) { | ||
212 | pr_err("alt: hash: Failed to export() for %s\n", algo); | ||
213 | goto out; | ||
214 | } | ||
215 | ahash_request_free(req); | ||
216 | req = ahash_request_alloc(tfm, GFP_KERNEL); | ||
217 | if (!req) { | ||
218 | pr_err("alg: hash: Failed to alloc request for %s\n", algo); | ||
219 | goto out_noreq; | ||
220 | } | ||
221 | ahash_request_set_callback(req, | ||
222 | CRYPTO_TFM_REQ_MAY_BACKLOG, | ||
223 | tcrypt_complete, tresult); | ||
224 | |||
225 | memcpy(hash_buff, template->plaintext + temp, | ||
226 | template->tap[k]); | ||
227 | sg_init_one(&sg[0], hash_buff, template->tap[k]); | ||
228 | ahash_request_set_crypt(req, sg, result, template->tap[k]); | ||
229 | ret = crypto_ahash_import(req, state); | ||
230 | if (ret) { | ||
231 | pr_err("alg: hash: Failed to import() for %s\n", algo); | ||
232 | goto out; | ||
233 | } | ||
234 | ret = wait_async_op(tresult, crypto_ahash_update(req)); | ||
235 | if (ret) | ||
236 | goto out; | ||
237 | *preq = req; | ||
238 | ret = 0; | ||
239 | goto out_noreq; | ||
240 | out: | ||
241 | ahash_request_free(req); | ||
242 | out_noreq: | ||
243 | kfree(state); | ||
244 | out_nostate: | ||
245 | return ret; | ||
246 | } | ||
247 | |||
193 | static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, | 248 | static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, |
194 | unsigned int tcount, bool use_digest, | 249 | unsigned int tcount, bool use_digest, |
195 | const int align_offset) | 250 | const int align_offset) |
@@ -377,6 +432,84 @@ static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, | |||
377 | } | 432 | } |
378 | } | 433 | } |
379 | 434 | ||
435 | /* partial update exercise */ | ||
436 | j = 0; | ||
437 | for (i = 0; i < tcount; i++) { | ||
438 | /* alignment tests are only done with continuous buffers */ | ||
439 | if (align_offset != 0) | ||
440 | break; | ||
441 | |||
442 | if (template[i].np < 2) | ||
443 | continue; | ||
444 | |||
445 | j++; | ||
446 | memset(result, 0, MAX_DIGEST_SIZE); | ||
447 | |||
448 | ret = -EINVAL; | ||
449 | hash_buff = xbuf[0]; | ||
450 | memcpy(hash_buff, template[i].plaintext, | ||
451 | template[i].tap[0]); | ||
452 | sg_init_one(&sg[0], hash_buff, template[i].tap[0]); | ||
453 | |||
454 | if (template[i].ksize) { | ||
455 | crypto_ahash_clear_flags(tfm, ~0); | ||
456 | if (template[i].ksize > MAX_KEYLEN) { | ||
457 | pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n", | ||
458 | j, algo, template[i].ksize, MAX_KEYLEN); | ||
459 | ret = -EINVAL; | ||
460 | goto out; | ||
461 | } | ||
462 | memcpy(key, template[i].key, template[i].ksize); | ||
463 | ret = crypto_ahash_setkey(tfm, key, template[i].ksize); | ||
464 | if (ret) { | ||
465 | pr_err("alg: hash: setkey failed on test %d for %s: ret=%d\n", | ||
466 | j, algo, -ret); | ||
467 | goto out; | ||
468 | } | ||
469 | } | ||
470 | |||
471 | ahash_request_set_crypt(req, sg, result, template[i].tap[0]); | ||
472 | ret = wait_async_op(&tresult, crypto_ahash_init(req)); | ||
473 | if (ret) { | ||
474 | pr_err("alt: hash: init failed on test %d for %s: ret=%d\n", | ||
475 | j, algo, -ret); | ||
476 | goto out; | ||
477 | } | ||
478 | ret = wait_async_op(&tresult, crypto_ahash_update(req)); | ||
479 | if (ret) { | ||
480 | pr_err("alt: hash: update failed on test %d for %s: ret=%d\n", | ||
481 | j, algo, -ret); | ||
482 | goto out; | ||
483 | } | ||
484 | |||
485 | temp = template[i].tap[0]; | ||
486 | for (k = 1; k < template[i].np; k++) { | ||
487 | ret = ahash_partial_update(&req, tfm, &template[i], | ||
488 | hash_buff, k, temp, &sg[0], algo, result, | ||
489 | &tresult); | ||
490 | if (ret) { | ||
491 | pr_err("hash: partial update failed on test %d for %s: ret=%d\n", | ||
492 | j, algo, -ret); | ||
493 | goto out_noreq; | ||
494 | } | ||
495 | temp += template[i].tap[k]; | ||
496 | } | ||
497 | ret = wait_async_op(&tresult, crypto_ahash_final(req)); | ||
498 | if (ret) { | ||
499 | pr_err("alt: hash: final failed on test %d for %s: ret=%d\n", | ||
500 | j, algo, -ret); | ||
501 | goto out; | ||
502 | } | ||
503 | if (memcmp(result, template[i].digest, | ||
504 | crypto_ahash_digestsize(tfm))) { | ||
505 | pr_err("alg: hash: Partial Test %d failed for %s\n", | ||
506 | j, algo); | ||
507 | hexdump(result, crypto_ahash_digestsize(tfm)); | ||
508 | ret = -EINVAL; | ||
509 | goto out; | ||
510 | } | ||
511 | } | ||
512 | |||
380 | ret = 0; | 513 | ret = 0; |
381 | 514 | ||
382 | out: | 515 | out: |