This patch makes use of the new AEAD interface which uses a single SG list instead of separate lists for the AD and plain text. Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> --- crypto/algif_aead.c | 61 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c index 53702e9..5674a33 100644 --- a/crypto/algif_aead.c +++ b/crypto/algif_aead.c @@ -26,7 +26,7 @@ struct aead_sg_list { unsigned int cur; - struct scatterlist sg[ALG_MAX_PAGES]; + struct scatterlist sg[ALG_MAX_PAGES + 1]; }; struct aead_ctx { @@ -357,7 +357,8 @@ static int aead_recvmsg(struct socket *sock, struct msghdr *msg, size_t ignored, unsigned as = crypto_aead_authsize(crypto_aead_reqtfm(&ctx->aead_req)); struct aead_sg_list *sgl = &ctx->tsgl; struct scatterlist *sg = NULL; - struct scatterlist assoc[ALG_MAX_PAGES]; + struct scatterlist dstbuf[ALG_MAX_PAGES + 1]; + struct scatterlist *dst = dstbuf; size_t assoclen = 0; unsigned int i = 0; int err = -EINVAL; @@ -453,7 +454,7 @@ static int aead_recvmsg(struct socket *sock, struct msghdr *msg, size_t ignored, if (usedpages < outlen) goto unlock; - sg_init_table(assoc, ALG_MAX_PAGES); + sg_mark_end(sgl->sg + sgl->cur); assoclen = ctx->aead_assoclen; /* * Split scatterlist into two: first part becomes AD, second part @@ -465,35 +466,45 @@ static int aead_recvmsg(struct socket *sock, struct msghdr *msg, size_t ignored, sg = sgl->sg + i; if (sg->length <= assoclen) { /* AD is larger than one page */ - sg_set_page(assoc + i, sg_page(sg), + sg_set_page(dst + i, sg_page(sg), sg->length, sg->offset); assoclen -= sg->length; - if (i >= ctx->tsgl.cur) - goto unlock; - } else if (!assoclen) { - /* current page is to start of plaintext / ciphertext */ - if (i) - /* AD terminates at page boundary */ - sg_mark_end(assoc + i - 1); - else - /* AD size is zero */ - sg_mark_end(assoc); - break; - } else { + continue; + } + + if (assoclen) { /* AD does not terminate at page boundary */ - sg_set_page(assoc + i, sg_page(sg), + sg_set_page(dst + i, sg_page(sg), assoclen, sg->offset); - sg_mark_end(assoc + i); - /* plaintext / ciphertext starts after AD */ - sg->length -= assoclen; - sg->offset += assoclen; - break; + assoclen = 0; + i++; } + + break; } - aead_request_set_assoc(&ctx->aead_req, assoc, ctx->aead_assoclen); - aead_request_set_crypt(&ctx->aead_req, sg, ctx->rsgl[0].sg, used, - ctx->iv); + /* This should never happen because of aead_sufficient_data. */ + if (WARN_ON_ONCE(assoclen)) + goto unlock; + + /* current page is the start of plaintext / ciphertext */ + if (!i) + /* AD size is zero */ + dst = ctx->rsgl[0].sg; + else if (outlen) + /* AD size is non-zero */ + scatterwalk_crypto_chain( + dst, ctx->rsgl[0].sg, + sg_page(ctx->rsgl[0].sg) == sg_page(dst + i - 1) && + ctx->rsgl[0].sg[0].offset == dst[i - 1].offset + + dst[i - 1].length, + i + 1); + else + /* AD only */ + sg_mark_end(dst + i); + + aead_request_set_crypt(&ctx->aead_req, sgl->sg, dst, used, ctx->iv); + aead_request_set_ad(&ctx->aead_req, ctx->aead_assoclen, 0); err = af_alg_wait_for_completion(ctx->enc ? crypto_aead_encrypt(&ctx->aead_req) : -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html