[RFC PATCH 11/36] cifs: Add new AEAD alloc and setup routines that draw from an iterator
David Howells <[email protected]> Tue, 19 May 2026 11:21:29 +0100
| Newsgroups | dev.linux.lists.netfs,org.kernel.vger.linux-cifs,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Add new AEAD alloc and setup routines that solely use an iterator to supply the buffers rather than disassembling an smb_rqst struct. Signed-off-by: David Howells <[email protected]> cc: Steve French <[email protected]> cc: Paulo Alcantara <[email protected]> cc: Shyam Prasad N <[email protected]> cc: Tom Talpey <[email protected]> cc: [email protected] cc: [email protected] cc: [email protected] --- fs/smb/client/smb2transport.c | 69 +++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c index f5b676802ce7..9df3a0b530e2 100644 --- a/fs/smb/client/smb2transport.c +++ b/fs/smb/client/smb2transport.c @@ -812,3 +812,72 @@ smb3_crypto_aead_allocate(struct TCP_Server_Info *server) return 0; } + +/* + * Allocate the context info needed for the encryption operation, along with a + * scatterlist to point to the buffer. + */ +static void *smb2_aead_req_alloc_new(struct crypto_aead *tfm, const struct iov_iter *iter, + u8 **iv, + struct aead_request **req, struct sg_table *sgt, + unsigned int *num_sgs, size_t *sensitive_size) +{ + unsigned int req_size = sizeof(**req) + crypto_aead_reqsize(tfm); + unsigned int iv_size = crypto_aead_ivsize(tfm); + unsigned int len; + u8 *p; + + *num_sgs = iov_iter_npages(iter, INT_MAX); + + len = iv_size; + len += crypto_aead_alignmask(tfm) & ~(crypto_tfm_ctx_alignment() - 1); + len = ALIGN(len, crypto_tfm_ctx_alignment()); + len += req_size; + len = ALIGN(len, __alignof__(struct scatterlist)); + len += array_size(*num_sgs + 2, sizeof(struct scatterlist)); + *sensitive_size = len; + + p = kvzalloc(len, GFP_NOFS); + if (!p) + return ERR_PTR(-ENOMEM); + + *iv = (u8 *)PTR_ALIGN(p, crypto_aead_alignmask(tfm) + 1); + *req = (struct aead_request *)PTR_ALIGN(*iv + iv_size, + crypto_tfm_ctx_alignment()); + sgt->sgl = (struct scatterlist *)PTR_ALIGN((u8 *)*req + req_size, + __alignof__(struct scatterlist)); + return p; +} + +/* + * Set up for doing a crypto operation, building a scatterlist from the + * supplied iterator. + */ +static void *smb2_get_aead_req_new(struct crypto_aead *tfm, const struct iov_iter *iter, + const u8 *sig, u8 **iv, + struct aead_request **req, struct scatterlist **sgl, + size_t *sensitive_size) +{ + struct sg_table sgtable = {}; + struct iov_iter tmp = *iter; + unsigned int num_sgs; + ssize_t rc; + void *p; + + p = smb2_aead_req_alloc_new(tfm, iter, iv, req, &sgtable, + &num_sgs, sensitive_size); + if (IS_ERR(p)) + return ERR_CAST(p); + + sg_init_marker(sgtable.sgl, num_sgs + 2); + + rc = extract_iter_to_sg(&tmp, iov_iter_count(iter), &sgtable, num_sgs, 0); + sgtable.orig_nents = sgtable.nents + 1; + if (rc < 0) + return ERR_PTR(rc); + + cifs_sg_set_buf(&sgtable, sig, SMB2_SIGNATURE_SIZE); + sg_mark_end(&sgtable.sgl[sgtable.nents - 1]); + *sgl = sgtable.sgl; + return p; +}