crypto: algif_aead, ccm - stabilize IV handling for async CCM requests
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 1/1 crypto: algif_aead, ccm - stabilize IV handling for async CCM requests
From: Douya Le <[email protected]>
AF_ALG AEAD AIO requests currently use the socket-wide IV buffer during request processing. For async CCM requests, later socket activity can update that shared state before the original request has fully completed, which can lead to inconsistent IV handling.
Fix this in two places:
- snapshot the IV into per-request storage in algif_aead before submitting an async AEAD operation, so in-flight requests no longer depend on mutable socket state;
- make CCM keep a private IV copy for authentication, separate from the working IV that is consumed by the CTR walk.
Together these changes make async CCM IV handling stable without changing normal AF_ALG or CCM behaviour.
--- crypto/algif_aead.c | 10 ++++++++-- crypto/ccm.c | 19 ++++++++++++------- 2 files changed, 20 insertions(+), 9 deletions(-)
crypto/algif_aead.c +8 -2
@@ -72,8 +72,10 @@struct af_alg_ctx *ctx = ask->private;struct crypto_aead *tfm = pask->private;unsigned int as =crypto_aead_authsize (tfm); +unsigned int ivsize =crypto_aead_ivsize (tfm);struct af_alg_async_req *areq;struct scatterlist *rsgl_src, *tsgl_src =NULL ; +void *iv;int err =0 ;size_t used =0 ;/* [in] TX bufs to be en/decrypted */ size_t outlen =0 ;/* [out] RX bufs produced by kernel */
@@ -125,10 +127,14 @@/* Allocate cipher request for current operation. */ areq =af_alg_alloc_areq (sk,sizeof (struct af_alg_async_req ) + -crypto_aead_reqsize (tfm)); +crypto_aead_reqsize (tfm) + ivsize);if (IS_ERR (areq))return PTR_ERR (areq); + iv = (u8 *)aead_request_ctx (&areq->cra_u.aead_req) + +crypto_aead_reqsize (tfm); +memcpy (iv, ctx->iv, ivsize); +/* convert iovecs of output buffers into RX SGL */ err =af_alg_get_rsgl (sk, msg, flags, areq, outlen, &usedpages);if (err)
@@ -187,7 +193,7 @@/* Initialize the crypto operation */ aead_request_set_crypt (&areq->cra_u.aead_req, tsgl_src, - areq->first_rsgl.sgl.sgt.sgl, used, ctx->iv); + areq->first_rsgl.sgl.sgt.sgl, used, iv);aead_request_set_ad (&areq->cra_u.aead_req, ctx->aead_assoclen);aead_request_set_tfm (&areq->cra_u.aead_req, tfm);
crypto/ccm.c +12 -7
@@ -42,6 +42,7 @@u8 odata[16 ];u8 idata[16 ];u8 auth_tag[16 ]; +u8 iv[16 ];u32 flags;struct scatterlist src[3 ];struct scatterlist dst[3 ];
@@ -121,17 +122,17 @@return 0 ; } -static int format_input (u8 *info,struct aead_request *req, +static int format_input (u8 *info,const u8 *iv,struct aead_request *req,unsigned int cryptlen) {struct crypto_aead *aead =crypto_aead_reqtfm (req); -unsigned int lp = req->iv[0 ]; +unsigned int lp = iv[0 ];unsigned int l = lp +1 ;unsigned int m; m =crypto_aead_authsize (aead); -memcpy (info, req->iv,16 ); +memcpy (info, iv,16 );/* format control info per RFC 3610 and * NIST Special Publication 800-38C
@@ -176,7 +177,7 @@int ilen, err;/* format control data for input */ - err =format_input (odata, req, cryptlen); + err =format_input (odata, pctx->iv, req, cryptlen);if (err) goto out;
@@ -248,9 +249,11 @@ {struct crypto_ccm_req_priv_ctx *pctx =crypto_ccm_reqctx (req);struct scatterlist *sg; -u8 *iv = req->iv; +u8 *iv = pctx->iv;int err; +memcpy (iv, req->iv,sizeof (pctx->iv)); + err =crypto_ccm_check_iv (iv);if (err)return err;
@@ -288,7 +291,7 @@struct scatterlist *dst;unsigned int cryptlen = req->cryptlen;u8 *odata = pctx->odata; -u8 *iv = req->iv; +u8 *iv = pctx->idata;int err; err =crypto_ccm_init_crypt (req, odata);
@@ -303,6 +306,8 @@if (req->src != req->dst) dst = pctx->dst; +memcpy (iv, pctx->iv,16 ); +skcipher_request_set_tfm (skreq, ctx->ctr);skcipher_request_set_callback (skreq, pctx->flags, crypto_ccm_encrypt_done, req);
@@ -365,7 +370,7 @@if (req->src != req->dst) dst = pctx->dst; -memcpy (iv, req->iv,16 ); +memcpy (iv, pctx->iv,16 );skcipher_request_set_tfm (skreq, ctx->ctr); skcipher_request_set_callback(skreq, pctx->flags,
--
2.43.0
Herbert Xu
maintainerQuoted 29 lines · Ren Wei
From: Douya Le <[email protected]>
AF_ALGAEAD AIO requests currently use the socket-wide IV buffer during request processing. For async CCM requests, later socket activity can update that shared state before the original request has fully completed, which can lead to inconsistent IV handling.Fix this in two places:
- snapshot the IV into per-request storage in
algif_aeadbefore submitting an async AEAD operation, so in-flight requests no longer depend on mutable socket state;
- make CCM keep a private IV copy for authentication, separate from the working IV that is consumed by the CTR walk.Together these changes make async CCM IV handling stable without changing normal
AF_ALGor CCM behaviour.Fixes d887c52d6ae4 ("crypto: algif_aead - overhaul memory management")Reported-by Yuan Tan <[email protected]>Reported-by Yifan Wu <[email protected]>Reported-by Juefei Pu <[email protected]>Reported-by Xin Liu <[email protected]>Co-developed-by Luxing Yin <[email protected]>Signed-off-by Luxing Yin <[email protected]>Tested-by Yucheng Lu <[email protected]>Signed-off-by Douya Le <[email protected]>Signed-off-by Ren Wei <[email protected]>
Quoted 4 lines
--- crypto/algif_aead.c | 10 ++++++++-- crypto/ccm.c | 19 ++++++++++++------- 2 files changed, 20 insertions(+), 9 deletions(-)
Thanks, your fix looks good to me. But please split into two patches.
Thanks,
Signature · 3 lines
Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt