diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2017-05-11 12:29:40 +0200 |
---|---|---|
committer | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2017-05-11 12:29:40 +0200 |
commit | 381b497ced64866b33870aa827c911facf173d59 (patch) | |
tree | 1d7b4c36ede577039fa114b03aa1d315b904579c /crypto | |
parent | 9343ab61e1709b0aa6973f08157f0318f39e7f0b (diff) | |
parent | 89f3b8d5f264d5dab9818c6667c71e3cc55b13f5 (diff) |
Merge tag 'v4.9.27' into linux-4.9.y-rt
This is the 4.9.27 stable release
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/ahash.c | 79 | ||||
-rw-r--r-- | crypto/algif_aead.c | 12 |
2 files changed, 56 insertions, 35 deletions
diff --git a/crypto/ahash.c b/crypto/ahash.c index 2ce8bcb9049c..cce0268a13fe 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c @@ -31,6 +31,7 @@ struct ahash_request_priv { crypto_completion_t complete; void *data; u8 *result; + u32 flags; void *ubuf[] CRYPTO_MINALIGN_ATTR; }; @@ -252,6 +253,8 @@ static int ahash_save_req(struct ahash_request *req, crypto_completion_t cplt) priv->result = req->result; priv->complete = req->base.complete; priv->data = req->base.data; + priv->flags = req->base.flags; + /* * WARNING: We do not backup req->priv here! The req->priv * is for internal use of the Crypto API and the @@ -266,38 +269,44 @@ static int ahash_save_req(struct ahash_request *req, crypto_completion_t cplt) return 0; } -static void ahash_restore_req(struct ahash_request *req) +static void ahash_restore_req(struct ahash_request *req, int err) { struct ahash_request_priv *priv = req->priv; + if (!err) + memcpy(priv->result, req->result, + crypto_ahash_digestsize(crypto_ahash_reqtfm(req))); + /* Restore the original crypto request. */ req->result = priv->result; - req->base.complete = priv->complete; - req->base.data = priv->data; + + ahash_request_set_callback(req, priv->flags, + priv->complete, priv->data); req->priv = NULL; /* Free the req->priv.priv from the ADJUSTED request. */ kzfree(priv); } -static void ahash_op_unaligned_finish(struct ahash_request *req, int err) +static void ahash_notify_einprogress(struct ahash_request *req) { struct ahash_request_priv *priv = req->priv; + struct crypto_async_request oreq; - if (err == -EINPROGRESS) - return; - - if (!err) - memcpy(priv->result, req->result, - crypto_ahash_digestsize(crypto_ahash_reqtfm(req))); + oreq.data = priv->data; - ahash_restore_req(req); + priv->complete(&oreq, -EINPROGRESS); } static void ahash_op_unaligned_done(struct crypto_async_request *req, int err) { struct ahash_request *areq = req->data; + if (err == -EINPROGRESS) { + ahash_notify_einprogress(areq); + return; + } + /* * Restore the original request, see ahash_op_unaligned() for what * goes where. @@ -308,7 +317,7 @@ static void ahash_op_unaligned_done(struct crypto_async_request *req, int err) */ /* First copy req->result into req->priv.result */ - ahash_op_unaligned_finish(areq, err); + ahash_restore_req(areq, err); /* Complete the ORIGINAL request. */ areq->base.complete(&areq->base, err); @@ -324,7 +333,12 @@ static int ahash_op_unaligned(struct ahash_request *req, return err; err = op(req); - ahash_op_unaligned_finish(req, err); + if (err == -EINPROGRESS || + (err == -EBUSY && (ahash_request_flags(req) & + CRYPTO_TFM_REQ_MAY_BACKLOG))) + return err; + + ahash_restore_req(req, err); return err; } @@ -359,25 +373,14 @@ int crypto_ahash_digest(struct ahash_request *req) } EXPORT_SYMBOL_GPL(crypto_ahash_digest); -static void ahash_def_finup_finish2(struct ahash_request *req, int err) +static void ahash_def_finup_done2(struct crypto_async_request *req, int err) { - struct ahash_request_priv *priv = req->priv; + struct ahash_request *areq = req->data; if (err == -EINPROGRESS) return; - if (!err) - memcpy(priv->result, req->result, - crypto_ahash_digestsize(crypto_ahash_reqtfm(req))); - - ahash_restore_req(req); -} - -static void ahash_def_finup_done2(struct crypto_async_request *req, int err) -{ - struct ahash_request *areq = req->data; - - ahash_def_finup_finish2(areq, err); + ahash_restore_req(areq, err); areq->base.complete(&areq->base, err); } @@ -388,11 +391,15 @@ static int ahash_def_finup_finish1(struct ahash_request *req, int err) goto out; req->base.complete = ahash_def_finup_done2; - req->base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + err = crypto_ahash_reqtfm(req)->final(req); + if (err == -EINPROGRESS || + (err == -EBUSY && (ahash_request_flags(req) & + CRYPTO_TFM_REQ_MAY_BACKLOG))) + return err; out: - ahash_def_finup_finish2(req, err); + ahash_restore_req(req, err); return err; } @@ -400,7 +407,16 @@ static void ahash_def_finup_done1(struct crypto_async_request *req, int err) { struct ahash_request *areq = req->data; + if (err == -EINPROGRESS) { + ahash_notify_einprogress(areq); + return; + } + + areq->base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + err = ahash_def_finup_finish1(areq, err); + if (areq->priv) + return; areq->base.complete(&areq->base, err); } @@ -415,6 +431,11 @@ static int ahash_def_finup(struct ahash_request *req) return err; err = tfm->update(req); + if (err == -EINPROGRESS || + (err == -EBUSY && (ahash_request_flags(req) & + CRYPTO_TFM_REQ_MAY_BACKLOG))) + return err; + return ahash_def_finup_finish1(req, err); } diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c index e8817e2f0597..fde8d885f7b6 100644 --- a/crypto/algif_aead.c +++ b/crypto/algif_aead.c @@ -39,6 +39,7 @@ struct aead_async_req { struct aead_async_rsgl first_rsgl; struct list_head list; struct kiocb *iocb; + struct sock *sk; unsigned int tsgls; char iv[]; }; @@ -379,12 +380,10 @@ unlock: static void aead_async_cb(struct crypto_async_request *_req, int err) { - struct sock *sk = _req->data; - struct alg_sock *ask = alg_sk(sk); - struct aead_ctx *ctx = ask->private; - struct crypto_aead *tfm = crypto_aead_reqtfm(&ctx->aead_req); - struct aead_request *req = aead_request_cast(_req); + struct aead_request *req = _req->data; + struct crypto_aead *tfm = crypto_aead_reqtfm(req); struct aead_async_req *areq = GET_ASYM_REQ(req, tfm); + struct sock *sk = areq->sk; struct scatterlist *sg = areq->tsgl; struct aead_async_rsgl *rsgl; struct kiocb *iocb = areq->iocb; @@ -447,11 +446,12 @@ static int aead_recvmsg_async(struct socket *sock, struct msghdr *msg, memset(&areq->first_rsgl, '\0', sizeof(areq->first_rsgl)); INIT_LIST_HEAD(&areq->list); areq->iocb = msg->msg_iocb; + areq->sk = sk; memcpy(areq->iv, ctx->iv, crypto_aead_ivsize(tfm)); aead_request_set_tfm(req, tfm); aead_request_set_ad(req, ctx->aead_assoclen); aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, - aead_async_cb, sk); + aead_async_cb, req); used -= ctx->aead_assoclen; /* take over all tx sgls from ctx */ |