summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGilad Ben-Yossef <gilad@benyossef.com>2017-10-18 03:00:38 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2017-11-03 10:11:18 -0400
commitada69a1639eca54ff74d839a6513c43db8d57d70 (patch)
treef22353657a65c0b90d9412224ee508898d9c874a
parent3d549e325e3c7dd294b96720f22cbc39ec2e02e9 (diff)
crypto: introduce crypto wait for async op
Invoking a possibly async. crypto op and waiting for completion while correctly handling backlog processing is a common task in the crypto API implementation and outside users of it. This patch adds a generic implementation for doing so in preparation for using it across the board instead of hand rolled versions. Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com> CC: Eric Biggers <ebiggers3@gmail.com> CC: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--crypto/api.c13
-rw-r--r--include/linux/crypto.h40
2 files changed, 53 insertions, 0 deletions
diff --git a/crypto/api.c b/crypto/api.c
index 941cd4c6c7ec..2a2479d168aa 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -24,6 +24,7 @@
24#include <linux/sched/signal.h> 24#include <linux/sched/signal.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/string.h> 26#include <linux/string.h>
27#include <linux/completion.h>
27#include "internal.h" 28#include "internal.h"
28 29
29LIST_HEAD(crypto_alg_list); 30LIST_HEAD(crypto_alg_list);
@@ -595,5 +596,17 @@ int crypto_has_alg(const char *name, u32 type, u32 mask)
595} 596}
596EXPORT_SYMBOL_GPL(crypto_has_alg); 597EXPORT_SYMBOL_GPL(crypto_has_alg);
597 598
599void crypto_req_done(struct crypto_async_request *req, int err)
600{
601 struct crypto_wait *wait = req->data;
602
603 if (err == -EINPROGRESS)
604 return;
605
606 wait->err = err;
607 complete(&wait->completion);
608}
609EXPORT_SYMBOL_GPL(crypto_req_done);
610
598MODULE_DESCRIPTION("Cryptographic core API"); 611MODULE_DESCRIPTION("Cryptographic core API");
599MODULE_LICENSE("GPL"); 612MODULE_LICENSE("GPL");
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 84da9978e951..78508ca4b108 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -24,6 +24,7 @@
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/string.h> 25#include <linux/string.h>
26#include <linux/uaccess.h> 26#include <linux/uaccess.h>
27#include <linux/completion.h>
27 28
28/* 29/*
29 * Autoloaded crypto modules should only use a prefixed name to avoid allowing 30 * Autoloaded crypto modules should only use a prefixed name to avoid allowing
@@ -468,6 +469,45 @@ struct crypto_alg {
468} CRYPTO_MINALIGN_ATTR; 469} CRYPTO_MINALIGN_ATTR;
469 470
470/* 471/*
472 * A helper struct for waiting for completion of async crypto ops
473 */
474struct crypto_wait {
475 struct completion completion;
476 int err;
477};
478
479/*
480 * Macro for declaring a crypto op async wait object on stack
481 */
482#define DECLARE_CRYPTO_WAIT(_wait) \
483 struct crypto_wait _wait = { \
484 COMPLETION_INITIALIZER_ONSTACK((_wait).completion), 0 }
485
486/*
487 * Async ops completion helper functioons
488 */
489void crypto_req_done(struct crypto_async_request *req, int err);
490
491static inline int crypto_wait_req(int err, struct crypto_wait *wait)
492{
493 switch (err) {
494 case -EINPROGRESS:
495 case -EBUSY:
496 wait_for_completion(&wait->completion);
497 reinit_completion(&wait->completion);
498 err = wait->err;
499 break;
500 };
501
502 return err;
503}
504
505static inline void crypto_init_wait(struct crypto_wait *wait)
506{
507 init_completion(&wait->completion);
508}
509
510/*
471 * Algorithm registration interface. 511 * Algorithm registration interface.
472 */ 512 */
473int crypto_register_alg(struct crypto_alg *alg); 513int crypto_register_alg(struct crypto_alg *alg);