diff options
author | Marek Vasut <marex@denx.de> | 2014-03-13 21:37:06 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2014-03-21 09:54:22 -0400 |
commit | d4a7a0fbe959e12bdd071b79b50ed34853a6db8f (patch) | |
tree | 05da76d4006eb8395ee5ed442827468ec7c03e73 /crypto/ahash.c | |
parent | 1ffc9fbd1e5071948b6d48f9a27d845738ee890f (diff) |
crypto: hash - Simplify the ahash_finup implementation
The ahash_def_finup() can make use of the request save/restore functions,
thus make it so. This simplifies the code a little and unifies the code
paths.
Note that the same remark about free()ing the req->priv applies here, the
req->priv can only be free()'d after the original request was restored.
Finally, squash a bug in the invocation of completion in the ASYNC path.
In both ahash_def_finup_done{1,2}, the function areq->base.complete(X, err);
was called with X=areq->base.data . This is incorrect , as X=&areq->base
is the correct value. By analysis of the data structures, we see the areq is
of type 'struct ahash_request' , areq->base is of type 'struct crypto_async_request'
and areq->base.completion is of type crypto_completion_t, which is defined in
include/linux/crypto.h as:
typedef void (*crypto_completion_t)(struct crypto_async_request *req, int err);
This is one lead that the X should be &areq->base . Next up, we can inspect
other code which calls the completion callback to give us kind-of statistical
idea of how this callback is used. We can try:
$ git grep base\.complete\( drivers/crypto/
Finally, by inspecting ahash_request_set_callback() implementation defined
in include/crypto/hash.h , we observe that the .data entry of 'struct
crypto_async_request' is intended for arbitrary data, not for completion
argument.
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: David S. Miller <davem@davemloft.net>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Shawn Guo <shawn.guo@linaro.org>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/ahash.c')
-rw-r--r-- | crypto/ahash.c | 36 |
1 files changed, 9 insertions, 27 deletions
diff --git a/crypto/ahash.c b/crypto/ahash.c index fcc6077b9af0..6e7223392e80 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c | |||
@@ -349,19 +349,16 @@ static void ahash_def_finup_finish2(struct ahash_request *req, int err) | |||
349 | memcpy(priv->result, req->result, | 349 | memcpy(priv->result, req->result, |
350 | crypto_ahash_digestsize(crypto_ahash_reqtfm(req))); | 350 | crypto_ahash_digestsize(crypto_ahash_reqtfm(req))); |
351 | 351 | ||
352 | kzfree(priv); | 352 | ahash_restore_req(req); |
353 | } | 353 | } |
354 | 354 | ||
355 | static void ahash_def_finup_done2(struct crypto_async_request *req, int err) | 355 | static void ahash_def_finup_done2(struct crypto_async_request *req, int err) |
356 | { | 356 | { |
357 | struct ahash_request *areq = req->data; | 357 | struct ahash_request *areq = req->data; |
358 | struct ahash_request_priv *priv = areq->priv; | ||
359 | crypto_completion_t complete = priv->complete; | ||
360 | void *data = priv->data; | ||
361 | 358 | ||
362 | ahash_def_finup_finish2(areq, err); | 359 | ahash_def_finup_finish2(areq, err); |
363 | 360 | ||
364 | complete(data, err); | 361 | areq->base.complete(&areq->base, err); |
365 | } | 362 | } |
366 | 363 | ||
367 | static int ahash_def_finup_finish1(struct ahash_request *req, int err) | 364 | static int ahash_def_finup_finish1(struct ahash_request *req, int err) |
@@ -381,38 +378,23 @@ out: | |||
381 | static void ahash_def_finup_done1(struct crypto_async_request *req, int err) | 378 | static void ahash_def_finup_done1(struct crypto_async_request *req, int err) |
382 | { | 379 | { |
383 | struct ahash_request *areq = req->data; | 380 | struct ahash_request *areq = req->data; |
384 | struct ahash_request_priv *priv = areq->priv; | ||
385 | crypto_completion_t complete = priv->complete; | ||
386 | void *data = priv->data; | ||
387 | 381 | ||
388 | err = ahash_def_finup_finish1(areq, err); | 382 | err = ahash_def_finup_finish1(areq, err); |
389 | 383 | ||
390 | complete(data, err); | 384 | areq->base.complete(&areq->base, err); |
391 | } | 385 | } |
392 | 386 | ||
393 | static int ahash_def_finup(struct ahash_request *req) | 387 | static int ahash_def_finup(struct ahash_request *req) |
394 | { | 388 | { |
395 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); | 389 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); |
396 | unsigned long alignmask = crypto_ahash_alignmask(tfm); | 390 | int err; |
397 | unsigned int ds = crypto_ahash_digestsize(tfm); | ||
398 | struct ahash_request_priv *priv; | ||
399 | |||
400 | priv = kmalloc(sizeof(*priv) + ahash_align_buffer_size(ds, alignmask), | ||
401 | (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? | ||
402 | GFP_KERNEL : GFP_ATOMIC); | ||
403 | if (!priv) | ||
404 | return -ENOMEM; | ||
405 | |||
406 | priv->result = req->result; | ||
407 | priv->complete = req->base.complete; | ||
408 | priv->data = req->base.data; | ||
409 | 391 | ||
410 | req->result = PTR_ALIGN((u8 *)priv->ubuf, alignmask + 1); | 392 | err = ahash_save_req(req, ahash_def_finup_done1); |
411 | req->base.complete = ahash_def_finup_done1; | 393 | if (err) |
412 | req->base.data = req; | 394 | return err; |
413 | req->priv = priv; | ||
414 | 395 | ||
415 | return ahash_def_finup_finish1(req, tfm->update(req)); | 396 | err = tfm->update(req); |
397 | return ahash_def_finup_finish1(req, err); | ||
416 | } | 398 | } |
417 | 399 | ||
418 | static int ahash_no_export(struct ahash_request *req, void *out) | 400 | static int ahash_no_export(struct ahash_request *req, void *out) |