@@ -1049,6 +1049,37 @@ ssize_t af_alg_sendpage(struct socket *sock, struct page *page,
}
EXPORT_SYMBOL_GPL(af_alg_sendpage);
+/**
+ * af_alg_async_cb - AIO callback handler
+ *
+ * This handler cleans up the struct af_alg_async_req upon completion of the
+ * AIO operation.
+ *
+ * The number of bytes to be generated with the AIO operation must be set
+ * in areq->outlen before the AIO callback handler is invoked.
+ */
+void af_alg_async_cb(struct crypto_async_request *_req, int err)
+{
+ struct af_alg_async_req *areq = _req->data;
+ struct sock *sk = areq->sk;
+ struct kiocb *iocb = areq->iocb;
+ unsigned int resultlen;
+
+ lock_sock(sk);
+
+ /* Buffer size written by crypto operation. */
+ resultlen = areq->outlen;
+
+ af_alg_free_areq_sgls(areq);
+ sock_kfree_s(sk, areq, areq->areqlen);
+ __sock_put(sk);
+
+ iocb->ki_complete(iocb, err ? err : resultlen, 0);
+
+ release_sock(sk);
+}
+EXPORT_SYMBOL_GPL(af_alg_async_cb);
+
static int __init af_alg_init(void)
{
int err = proto_register(&alg_proto, 0);
@@ -76,27 +76,6 @@ static int aead_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
return af_alg_sendmsg(sock, msg, size, ivsize);
}
-static void aead_async_cb(struct crypto_async_request *_req, int err)
-{
- struct af_alg_async_req *areq = _req->data;
- struct sock *sk = areq->sk;
- struct kiocb *iocb = areq->iocb;
- unsigned int resultlen;
-
- lock_sock(sk);
-
- /* Buffer size written by crypto operation. */
- resultlen = areq->outlen;
-
- af_alg_free_areq_sgls(areq);
- sock_kfree_s(sk, areq, areq->areqlen);
- __sock_put(sk);
-
- iocb->ki_complete(iocb, err ? err : resultlen, 0);
-
- release_sock(sk);
-}
-
static int crypto_aead_copy_sgl(struct crypto_skcipher *null_tfm,
struct scatterlist *src,
struct scatterlist *dst, unsigned int len)
@@ -341,7 +320,7 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
areq->iocb = msg->msg_iocb;
aead_request_set_callback(&areq->cra_u.aead_req,
CRYPTO_TFM_REQ_MAY_BACKLOG,
- aead_async_cb, areq);
+ af_alg_async_cb, areq);
err = ctx->enc ? crypto_aead_encrypt(&areq->cra_u.aead_req) :
crypto_aead_decrypt(&areq->cra_u.aead_req);
} else {
@@ -57,27 +57,6 @@ static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg,
return af_alg_sendmsg(sock, msg, size, ivsize);
}
-static void skcipher_async_cb(struct crypto_async_request *req, int err)
-{
- struct af_alg_async_req *areq = req->data;
- struct sock *sk = areq->sk;
- struct kiocb *iocb = areq->iocb;
- unsigned int resultlen;
-
- lock_sock(sk);
-
- /* Buffer size written by crypto operation. */
- resultlen = areq->cra_u.skcipher_req.cryptlen;
-
- af_alg_free_areq_sgls(areq);
- sock_kfree_s(sk, areq, areq->areqlen);
- __sock_put(sk);
-
- iocb->ki_complete(iocb, err ? err : resultlen, 0);
-
- release_sock(sk);
-}
-
static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
size_t ignored, int flags)
{
@@ -189,7 +168,7 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
areq->iocb = msg->msg_iocb;
skcipher_request_set_callback(&areq->cra_u.skcipher_req,
CRYPTO_TFM_REQ_MAY_SLEEP,
- skcipher_async_cb, areq);
+ af_alg_async_cb, areq);
err = ctx->enc ?
crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) :
crypto_skcipher_decrypt(&areq->cra_u.skcipher_req);
@@ -209,6 +188,10 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
/* AIO operation in progress */
if (err == -EINPROGRESS) {
sock_hold(sk);
+
+ /* Remember output size that will be generated. */
+ areq->outlen = len;
+
return -EIOCBQUEUED;
}
@@ -253,5 +253,6 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
unsigned int ivsize);
ssize_t af_alg_sendpage(struct socket *sock, struct page *page,
int offset, size_t size, int flags);
+void af_alg_async_cb(struct crypto_async_request *_req, int err);
#endif /* _CRYPTO_IF_ALG_H */
Consoliate aead_async_cb, skcipher_async_cb ==> af_alg_async_cb algif_skcipher has been changed to store the number of output bytes in areq->outlen before the AIO callback is triggered. Signed-off-by: Stephan Mueller <smueller@chronox.de> --- crypto/af_alg.c | 31 +++++++++++++++++++++++++++++++ crypto/algif_aead.c | 23 +---------------------- crypto/algif_skcipher.c | 27 +++++---------------------- include/crypto/if_alg.h | 1 + 4 files changed, 38 insertions(+), 44 deletions(-)