summaryrefslogtreecommitdiffstats
path: root/crypto/algif_aead.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/algif_aead.c')
-rw-r--r--crypto/algif_aead.c31
1 files changed, 11 insertions, 20 deletions
diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
index e9c0993b131d..5a8053758657 100644
--- a/crypto/algif_aead.c
+++ b/crypto/algif_aead.c
@@ -19,6 +19,7 @@
#include <linux/init.h>
#include <linux/list.h>
#include <linux/kernel.h>
+#include <linux/sched/signal.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/net.h>
@@ -136,28 +137,27 @@ static void aead_wmem_wakeup(struct sock *sk)
static int aead_wait_for_data(struct sock *sk, unsigned flags)
{
+ DEFINE_WAIT_FUNC(wait, woken_wake_function);
struct alg_sock *ask = alg_sk(sk);
struct aead_ctx *ctx = ask->private;
long timeout;
- DEFINE_WAIT(wait);
int err = -ERESTARTSYS;
if (flags & MSG_DONTWAIT)
return -EAGAIN;
sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
-
+ add_wait_queue(sk_sleep(sk), &wait);
for (;;) {
if (signal_pending(current))
break;
- prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
timeout = MAX_SCHEDULE_TIMEOUT;
- if (sk_wait_event(sk, &timeout, !ctx->more)) {
+ if (sk_wait_event(sk, &timeout, !ctx->more, &wait)) {
err = 0;
break;
}
}
- finish_wait(sk_sleep(sk), &wait);
+ remove_wait_queue(sk_sleep(sk), &wait);
sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
@@ -455,12 +455,13 @@ static int aead_recvmsg_async(struct socket *sock, struct msghdr *msg,
used -= ctx->aead_assoclen;
/* take over all tx sgls from ctx */
- areq->tsgl = sock_kmalloc(sk, sizeof(*areq->tsgl) * sgl->cur,
+ areq->tsgl = sock_kmalloc(sk,
+ sizeof(*areq->tsgl) * max_t(u32, sgl->cur, 1),
GFP_KERNEL);
if (unlikely(!areq->tsgl))
goto free;
- sg_init_table(areq->tsgl, sgl->cur);
+ sg_init_table(areq->tsgl, max_t(u32, sgl->cur, 1));
for (i = 0; i < sgl->cur; i++)
sg_set_page(&areq->tsgl[i], sg_page(&sgl->sg[i]),
sgl->sg[i].length, sgl->sg[i].offset);
@@ -556,18 +557,8 @@ static int aead_recvmsg_sync(struct socket *sock, struct msghdr *msg, int flags)
lock_sock(sk);
/*
- * AEAD memory structure: For encryption, the tag is appended to the
- * ciphertext which implies that the memory allocated for the ciphertext
- * must be increased by the tag length. For decryption, the tag
- * is expected to be concatenated to the ciphertext. The plaintext
- * therefore has a memory size of the ciphertext minus the tag length.
- *
- * The memory structure for cipher operation has the following
- * structure:
- * AEAD encryption input: assoc data || plaintext
- * AEAD encryption output: cipherntext || auth tag
- * AEAD decryption input: assoc data || ciphertext || auth tag
- * AEAD decryption output: plaintext
+ * Please see documentation of aead_request_set_crypt for the
+ * description of the AEAD memory structure expected from the caller.
*/
if (ctx->more) {
@@ -671,9 +662,9 @@ static int aead_recvmsg_sync(struct socket *sock, struct msghdr *msg, int flags)
unlock:
list_for_each_entry_safe(rsgl, tmp, &ctx->list, list) {
af_alg_free_sg(&rsgl->sgl);
+ list_del(&rsgl->list);
if (rsgl != &ctx->first_rsgl)
sock_kfree_s(sk, rsgl, sizeof(*rsgl));
- list_del(&rsgl->list);
}
INIT_LIST_HEAD(&ctx->list);
aead_wmem_wakeup(sk);