>From cbd8a171c56008ce4932de9f0a54926279c6061d Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Wed, 22 Feb 2017 17:22:02 +0100 Subject: [PATCH] crypto: algif_aead - copy AAD from src to dst Use the NULL cipher to copy the AAD from the TX SGL to the RX SGL. The required null cipher is allocated when allocating other components used by algif_aead and released when those components are deallocated. Signed-off-by: Stephan Mueller --- crypto/Kconfig | 2 ++ crypto/algif_aead.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/crypto/Kconfig b/crypto/Kconfig index 5a51b87..bfa531d 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -1735,6 +1735,8 @@ config CRYPTO_USER_API_AEAD tristate "User-space interface for AEAD cipher algorithms" depends on NET select CRYPTO_AEAD + select CRYPTO_BLKCIPHER + select CRYPTO_NULL select CRYPTO_USER_API help This option enables the user-spaces interface for AEAD diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c index 050a866..98c988b 100644 --- a/crypto/algif_aead.c +++ b/crypto/algif_aead.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #include #include @@ -82,6 +84,7 @@ struct aead_ctx { unsigned int len; /* Length of allocated memory for this struct */ struct crypto_aead *aead_tfm; + struct crypto_skcipher *null; }; static DECLARE_WAIT_QUEUE_HEAD(aead_aio_finish_wait); @@ -559,6 +562,20 @@ static void aead_async_cb(struct crypto_async_request *_req, int err) wake_up_interruptible(&aead_aio_finish_wait); } +static int crypto_aead_copy_sgl(struct crypto_skcipher *null, + struct scatterlist *src, + struct scatterlist *dst, unsigned int len) +{ + SKCIPHER_REQUEST_ON_STACK(skreq, null); + + skcipher_request_set_tfm(skreq, null); + skcipher_request_set_callback(skreq, CRYPTO_TFM_REQ_MAY_BACKLOG, + NULL, NULL); + skcipher_request_set_crypt(skreq, src, dst, len, NULL); + + return crypto_skcipher_encrypt(skreq); +} + static int aead_recvmsg(struct socket *sock, struct msghdr *msg, size_t ignored, int flags) { @@ -704,6 +721,12 @@ static int aead_recvmsg(struct socket *sock, struct msghdr *msg, size_t ignored, sg_init_table(areq->tsgl, areq->tsgl_entries); aead_pull_tsgl(sk, processed, areq->tsgl); + /* copy AAD from src to dst */ + err = crypto_aead_copy_sgl(ctx->null, areq->tsgl, + areq->first_rsgl.sgl.sg, ctx->aead_assoclen); + if (err) + goto free; + /* Initialize the crypto operation */ aead_request_set_crypt(&areq->aead_req, areq->tsgl, areq->first_rsgl.sgl.sg, used, ctx->iv); @@ -825,6 +848,7 @@ static void aead_sock_destruct(struct sock *sk) wait_event_interruptible(aead_aio_finish_wait, (ctx->inflight == 0)); aead_pull_tsgl(sk, ctx->used, NULL); + crypto_put_default_null_skcipher2(); sock_kzfree_s(sk, ctx->iv, ivlen); sock_kfree_s(sk, ctx, ctx->len); af_alg_release_parent(sk); @@ -836,6 +860,7 @@ static int aead_accept_parent(void *private, struct sock *sk) struct alg_sock *ask = alg_sk(sk); unsigned int len = sizeof(*ctx); unsigned int ivlen = crypto_aead_ivsize(private); + struct crypto_skcipher *null; ctx = sock_kmalloc(sk, len, GFP_KERNEL); if (!ctx) @@ -849,6 +874,14 @@ static int aead_accept_parent(void *private, struct sock *sk) } memset(ctx->iv, 0, ivlen); + null = crypto_get_default_null_skcipher2(); + if (IS_ERR(null)) { + sock_kfree_s(sk, ctx->iv, ivlen); + sock_kfree_s(sk, ctx, len); + return PTR_ERR(null); + } + ctx->null = null; + INIT_LIST_HEAD(&ctx->tsgl_list); ctx->len = len; ctx->used = 0; -- 2.9.3