public inbox for linux-cifs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/4] smb: client: Use AES-CMAC library
@ 2026-04-18 22:13 Eric Biggers
  2026-04-18 22:13 ` [PATCH v2 1/4] smb: client: Use AES-CMAC library for SMB3 signature calculation Eric Biggers
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Eric Biggers @ 2026-04-18 22:13 UTC (permalink / raw)
  To: linux-cifs, Steve French
  Cc: linux-crypto, samba-technical, linux-kernel, Ard Biesheuvel,
	Paulo Alcantara, Ronnie Sahlberg, Shyam Prasad N, Tom Talpey,
	Bharath SM, Eric Biggers

This series updates the SMB client to use the AES-CMAC library functions
that were recently added, instead of a "cmac(aes)" crypto_shash.  As
usual, this simplifies the code considerably and is much more efficient.

These patches were originally sent as patches 8-11 of the series
https://lore.kernel.org/r/20260218213501.136844-1-ebiggers@kernel.org/
The only change from that version was adding tags and rebasing.
I also added some microbenchmark results below.

This is intended to be taken through the smb tree, either 7.1 or 7.2
depending on maintainer preference.

A few microbenchmarks that demonstrate improved performance:

 - Total cycles spent in generate_key() during SMB3 mount
   decreased from 20640 to 10780 (3 calls total).

 - Total cycles spent in smb3_calc_signature() during SMB3 mount
   decreased from 177620 to 73180 (32 calls & 4255 bytes total).

 - Total cycles spent in smb3_calc_signature() while writing 10MB file
   decreased from 27551180 to 26628360 (10 calls & 10001392 bytes total)

 - Total cycles spent in smb3_calc_signature() while reading 10MB file
   decreased from 28390900 to 27879340 (14 calls & 10001781 bytes total)

Note that my "before" numbers were taken from current mainline which has
my changes that made the "cmac(aes)" crypto_shash a bit faster as well.
So the speedup vs v7.0 is actually even greater.

Eric Biggers (4):
  smb: client: Use AES-CMAC library for SMB3 signature calculation
  smb: client: Remove obsolete cmac(aes) allocation
  smb: client: Make generate_key() return void
  smb: client: Drop 'allocate_crypto' arg from smb*_calc_signature()

 fs/smb/client/Kconfig         |   2 +-
 fs/smb/client/cifs_unicode.c  |   1 +
 fs/smb/client/cifsencrypt.c   |  62 ++++++-------------
 fs/smb/client/cifsfs.c        |   1 -
 fs/smb/client/cifsglob.h      |   7 +--
 fs/smb/client/cifsproto.h     |   3 -
 fs/smb/client/misc.c          |  57 -----------------
 fs/smb/client/sess.c          |  11 ----
 fs/smb/client/smb2proto.h     |   1 -
 fs/smb/client/smb2transport.c | 113 +++++++++-------------------------
 10 files changed, 53 insertions(+), 205 deletions(-)


base-commit: 8541d8f725c673db3bd741947f27974358b2e163
-- 
2.53.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 1/4] smb: client: Use AES-CMAC library for SMB3 signature calculation
  2026-04-18 22:13 [PATCH v2 0/4] smb: client: Use AES-CMAC library Eric Biggers
@ 2026-04-18 22:13 ` Eric Biggers
  2026-04-18 22:13 ` [PATCH v2 2/4] smb: client: Remove obsolete cmac(aes) allocation Eric Biggers
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Eric Biggers @ 2026-04-18 22:13 UTC (permalink / raw)
  To: linux-cifs, Steve French
  Cc: linux-crypto, samba-technical, linux-kernel, Ard Biesheuvel,
	Paulo Alcantara, Ronnie Sahlberg, Shyam Prasad N, Tom Talpey,
	Bharath SM, Eric Biggers

Convert smb3_calc_signature() to use the AES-CMAC library instead of a
"cmac(aes)" crypto_shash.

The result is simpler and faster code.  With the library there's no need
to allocate memory, no need to handle errors except for key preparation,
and the AES-CMAC code is accessed directly without inefficient indirect
calls and other unnecessary API overhead.

For now a "cmac(aes)" crypto_shash is still being allocated in
'struct cifs_secmech'.  Later commits will remove that, simplifying the
code even further.

Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
 fs/smb/client/Kconfig         |  1 +
 fs/smb/client/cifsencrypt.c   | 60 ++++++++++++-----------------------
 fs/smb/client/cifsglob.h      |  2 +-
 fs/smb/client/smb2transport.c | 41 +++++-------------------
 4 files changed, 30 insertions(+), 74 deletions(-)

diff --git a/fs/smb/client/Kconfig b/fs/smb/client/Kconfig
index 63831242fddfb..029bbe595d5fa 100644
--- a/fs/smb/client/Kconfig
+++ b/fs/smb/client/Kconfig
@@ -8,10 +8,11 @@ config CIFS
 	select CRYPTO_CMAC
 	select CRYPTO_AEAD2
 	select CRYPTO_CCM
 	select CRYPTO_GCM
 	select CRYPTO_AES
+	select CRYPTO_LIB_AES_CBC_MACS
 	select CRYPTO_LIB_ARC4
 	select CRYPTO_LIB_MD5
 	select CRYPTO_LIB_SHA256
 	select CRYPTO_LIB_SHA512
 	select KEYS
diff --git a/fs/smb/client/cifsencrypt.c b/fs/smb/client/cifsencrypt.c
index 3d731f3af235f..d092bca2df62d 100644
--- a/fs/smb/client/cifsencrypt.c
+++ b/fs/smb/client/cifsencrypt.c
@@ -20,66 +20,49 @@
 #include <linux/random.h>
 #include <linux/highmem.h>
 #include <linux/fips.h>
 #include <linux/iov_iter.h>
 #include <crypto/aead.h>
+#include <crypto/aes-cbc-macs.h>
 #include <crypto/arc4.h>
 #include <crypto/md5.h>
 #include <crypto/sha2.h>
 
-static int cifs_sig_update(struct cifs_calc_sig_ctx *ctx,
-			   const u8 *data, size_t len)
+static size_t cifs_sig_step(void *iter_base, size_t progress, size_t len,
+			    void *priv, void *priv2)
 {
-	if (ctx->md5) {
-		md5_update(ctx->md5, data, len);
-		return 0;
-	}
-	if (ctx->hmac) {
-		hmac_sha256_update(ctx->hmac, data, len);
-		return 0;
-	}
-	return crypto_shash_update(ctx->shash, data, len);
+	struct cifs_calc_sig_ctx *ctx = priv;
+
+	if (ctx->md5)
+		md5_update(ctx->md5, iter_base, len);
+	else if (ctx->hmac)
+		hmac_sha256_update(ctx->hmac, iter_base, len);
+	else
+		aes_cmac_update(ctx->cmac, iter_base, len);
+	return 0; /* Return value is length *not* processed, i.e. 0. */
 }
 
-static int cifs_sig_final(struct cifs_calc_sig_ctx *ctx, u8 *out)
+static void cifs_sig_final(struct cifs_calc_sig_ctx *ctx, u8 *out)
 {
-	if (ctx->md5) {
+	if (ctx->md5)
 		md5_final(ctx->md5, out);
-		return 0;
-	}
-	if (ctx->hmac) {
+	else if (ctx->hmac)
 		hmac_sha256_final(ctx->hmac, out);
-		return 0;
-	}
-	return crypto_shash_final(ctx->shash, out);
-}
-
-static size_t cifs_sig_step(void *iter_base, size_t progress, size_t len,
-			    void *priv, void *priv2)
-{
-	struct cifs_calc_sig_ctx *ctx = priv;
-	int ret, *pret = priv2;
-
-	ret = cifs_sig_update(ctx, iter_base, len);
-	if (ret < 0) {
-		*pret = ret;
-		return len;
-	}
-	return 0;
+	else
+		aes_cmac_final(ctx->cmac, out);
 }
 
 /*
  * Pass the data from an iterator into a hash.
  */
 static int cifs_sig_iter(const struct iov_iter *iter, size_t maxsize,
 			 struct cifs_calc_sig_ctx *ctx)
 {
 	struct iov_iter tmp_iter = *iter;
 	size_t did;
-	int err;
 
-	did = iterate_and_advance_kernel(&tmp_iter, maxsize, ctx, &err,
+	did = iterate_and_advance_kernel(&tmp_iter, maxsize, ctx, NULL,
 					 cifs_sig_step);
 	if (did != maxsize)
 		return smb_EIO2(smb_eio_trace_sig_iter, did, maxsize);
 	return 0;
 }
@@ -106,15 +89,12 @@ int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
 
 	rc = cifs_sig_iter(&rqst->rq_iter, iov_iter_count(&rqst->rq_iter), ctx);
 	if (rc < 0)
 		return rc;
 
-	rc = cifs_sig_final(ctx, signature);
-	if (rc)
-		cifs_dbg(VFS, "%s: Could not generate hash\n", __func__);
-
-	return rc;
+	cifs_sig_final(ctx, signature);
+	return 0;
 }
 
 /* Build a proper attribute value/target info pairs blob.
  * Fill in netbios and dns domain name and workstation name
  * and client time (total five av pairs and + one end of fields indicator.
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index ccfde157d3bef..74265d055c265 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -2322,11 +2322,11 @@ static inline void mid_execute_callback(struct TCP_Server_Info *server,
 	  FILE_SUPPORTS_REPARSE_POINTS))
 
 struct cifs_calc_sig_ctx {
 	struct md5_ctx *md5;
 	struct hmac_sha256_ctx *hmac;
-	struct shash_desc *shash;
+	struct aes_cmac_ctx *cmac;
 };
 
 #define CIFS_RECONN_DELAY_SECS	30
 #define CIFS_MAX_RECONN_DELAY	(4 * CIFS_RECONN_DELAY_SECS)
 
diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c
index 81be2b226e264..b233e0cd91529 100644
--- a/fs/smb/client/smb2transport.c
+++ b/fs/smb/client/smb2transport.c
@@ -17,10 +17,11 @@
 #include <linux/uaccess.h>
 #include <asm/processor.h>
 #include <linux/mempool.h>
 #include <linux/highmem.h>
 #include <crypto/aead.h>
+#include <crypto/aes-cbc-macs.h>
 #include <crypto/sha2.h>
 #include <crypto/utils.h>
 #include "cifsglob.h"
 #include "cifsproto.h"
 #include "smb2proto.h"
@@ -472,11 +473,12 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
 {
 	int rc;
 	unsigned char smb3_signature[SMB2_CMACAES_SIZE];
 	struct kvec *iov = rqst->rq_iov;
 	struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base;
-	struct shash_desc *shash = NULL;
+	struct aes_cmac_key cmac_key;
+	struct aes_cmac_ctx cmac_ctx;
 	struct smb_rqst drqst;
 	u8 key[SMB3_SIGN_KEY_SIZE];
 
 	if (server->vals->protocol_id <= SMB21_PROT_ID)
 		return smb2_calc_signature(rqst, server, allocate_crypto);
@@ -485,67 +487,40 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
 	if (unlikely(rc)) {
 		cifs_server_dbg(FYI, "%s: Could not get signing key\n", __func__);
 		return rc;
 	}
 
-	if (allocate_crypto) {
-		rc = cifs_alloc_hash("cmac(aes)", &shash);
-		if (rc)
-			return rc;
-	} else {
-		shash = server->secmech.aes_cmac;
-	}
-
 	memset(smb3_signature, 0x0, SMB2_CMACAES_SIZE);
 	memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
 
-	rc = crypto_shash_setkey(shash->tfm, key, SMB2_CMACAES_SIZE);
+	rc = aes_cmac_preparekey(&cmac_key, key, SMB2_CMACAES_SIZE);
 	if (rc) {
 		cifs_server_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__);
-		goto out;
+		return rc;
 	}
 
-	/*
-	 * we already allocate aes_cmac when we init smb3 signing key,
-	 * so unlike smb2 case we do not have to check here if secmech are
-	 * initialized
-	 */
-	rc = crypto_shash_init(shash);
-	if (rc) {
-		cifs_server_dbg(VFS, "%s: Could not init cmac aes\n", __func__);
-		goto out;
-	}
+	aes_cmac_init(&cmac_ctx, &cmac_key);
 
 	/*
 	 * For SMB2+, __cifs_calc_signature() expects to sign only the actual
 	 * data, that is, iov[0] should not contain a rfc1002 length.
 	 *
 	 * Sign the rfc1002 length prior to passing the data (iov[1-N]) down to
 	 * __cifs_calc_signature().
 	 */
 	drqst = *rqst;
 	if (drqst.rq_nvec >= 2 && iov[0].iov_len == 4) {
-		rc = crypto_shash_update(shash, iov[0].iov_base,
-					 iov[0].iov_len);
-		if (rc) {
-			cifs_server_dbg(VFS, "%s: Could not update with payload\n",
-				 __func__);
-			goto out;
-		}
+		aes_cmac_update(&cmac_ctx, iov[0].iov_base, iov[0].iov_len);
 		drqst.rq_iov++;
 		drqst.rq_nvec--;
 	}
 
 	rc = __cifs_calc_signature(
 		&drqst, server, smb3_signature,
-		&(struct cifs_calc_sig_ctx){ .shash = shash });
+		&(struct cifs_calc_sig_ctx){ .cmac = &cmac_ctx });
 	if (!rc)
 		memcpy(shdr->Signature, smb3_signature, SMB2_SIGNATURE_SIZE);
-
-out:
-	if (allocate_crypto)
-		cifs_free_hash(&shash);
 	return rc;
 }
 
 /* must be called with server->srv_mutex held */
 static int
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 2/4] smb: client: Remove obsolete cmac(aes) allocation
  2026-04-18 22:13 [PATCH v2 0/4] smb: client: Use AES-CMAC library Eric Biggers
  2026-04-18 22:13 ` [PATCH v2 1/4] smb: client: Use AES-CMAC library for SMB3 signature calculation Eric Biggers
@ 2026-04-18 22:13 ` Eric Biggers
  2026-04-18 22:13 ` [PATCH v2 3/4] smb: client: Make generate_key() return void Eric Biggers
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Eric Biggers @ 2026-04-18 22:13 UTC (permalink / raw)
  To: linux-cifs, Steve French
  Cc: linux-crypto, samba-technical, linux-kernel, Ard Biesheuvel,
	Paulo Alcantara, Ronnie Sahlberg, Shyam Prasad N, Tom Talpey,
	Bharath SM, Eric Biggers

Since the crypto library API is now being used instead of crypto_shash,
the "cmac(aes)" crypto_shash that is being allocated and stored in
'struct cifs_secmech' is no longer used.  Remove it.

That makes the kconfig selection of CRYPTO_CMAC and the module softdep
on "cmac" unnecessary.  So remove those too.

Finally, since this removes the last use of crypto_shash from the smb
client, also remove the remaining crypto_shash-related helper functions.

Note: cifs_unicode.c was relying on <linux/unaligned.h> being included
transitively via <crypto/internal/hash.h>.  Since the latter include is
removed, make cifs_unicode.c include <linux/unaligned.h> explicitly.

Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
 fs/smb/client/Kconfig         |  1 -
 fs/smb/client/cifs_unicode.c  |  1 +
 fs/smb/client/cifsencrypt.c   |  2 --
 fs/smb/client/cifsfs.c        |  1 -
 fs/smb/client/cifsglob.h      |  5 +--
 fs/smb/client/cifsproto.h     |  3 --
 fs/smb/client/misc.c          | 57 -----------------------------------
 fs/smb/client/sess.c          | 11 -------
 fs/smb/client/smb2proto.h     |  1 -
 fs/smb/client/smb2transport.c | 15 ---------
 10 files changed, 2 insertions(+), 95 deletions(-)

diff --git a/fs/smb/client/Kconfig b/fs/smb/client/Kconfig
index 029bbe595d5fa..a1c6ad4d574a0 100644
--- a/fs/smb/client/Kconfig
+++ b/fs/smb/client/Kconfig
@@ -3,11 +3,10 @@ config CIFS
 	tristate "SMB3 and CIFS support (advanced network filesystem)"
 	depends on INET
 	select NLS
 	select NLS_UCS2_UTILS
 	select CRYPTO
-	select CRYPTO_CMAC
 	select CRYPTO_AEAD2
 	select CRYPTO_CCM
 	select CRYPTO_GCM
 	select CRYPTO_AES
 	select CRYPTO_LIB_AES_CBC_MACS
diff --git a/fs/smb/client/cifs_unicode.c b/fs/smb/client/cifs_unicode.c
index e2edc207cef25..4a8a591f4bcac 100644
--- a/fs/smb/client/cifs_unicode.c
+++ b/fs/smb/client/cifs_unicode.c
@@ -4,10 +4,11 @@
  *   Copyright (c) International Business Machines  Corp., 2000,2009
  *   Modified by Steve French (sfrench@us.ibm.com)
  */
 #include <linux/fs.h>
 #include <linux/slab.h>
+#include <linux/unaligned.h>
 #include "cifs_fs_sb.h"
 #include "cifs_unicode.h"
 #include "cifsglob.h"
 #include "cifs_debug.h"
 
diff --git a/fs/smb/client/cifsencrypt.c b/fs/smb/client/cifsencrypt.c
index d092bca2df62d..34804e9842a80 100644
--- a/fs/smb/client/cifsencrypt.c
+++ b/fs/smb/client/cifsencrypt.c
@@ -501,12 +501,10 @@ calc_seckey(struct cifs_ses *ses)
 }
 
 void
 cifs_crypto_secmech_release(struct TCP_Server_Info *server)
 {
-	cifs_free_hash(&server->secmech.aes_cmac);
-
 	if (server->secmech.enc) {
 		crypto_free_aead(server->secmech.enc);
 		server->secmech.enc = NULL;
 	}
 	if (server->secmech.dec) {
diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c
index 2025739f070ac..081fc1f9447da 100644
--- a/fs/smb/client/cifsfs.c
+++ b/fs/smb/client/cifsfs.c
@@ -2158,11 +2158,10 @@ MODULE_DESCRIPTION
 	("VFS to access SMB3 servers e.g. Samba, Macs, Azure and Windows (and "
 	"also older servers complying with the SNIA CIFS Specification)");
 MODULE_VERSION(CIFS_VERSION);
 MODULE_SOFTDEP("nls");
 MODULE_SOFTDEP("aes");
-MODULE_SOFTDEP("cmac");
 MODULE_SOFTDEP("aead2");
 MODULE_SOFTDEP("ccm");
 MODULE_SOFTDEP("gcm");
 module_init(init_cifs)
 module_exit(exit_cifs)
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index 74265d055c265..82e0adc1dabd0 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -21,11 +21,10 @@
 #include <linux/sched/mm.h>
 #include <linux/netfs.h>
 #include <linux/fcntl.h>
 #include "cifs_fs_sb.h"
 #include "cifsacl.h"
-#include <crypto/internal/hash.h>
 #include <uapi/linux/cifs/cifs_mount.h>
 #include "../common/smbglob.h"
 #include "../common/smb2pdu.h"
 #include "../common/fscc.h"
 #include "smb2pdu.h"
@@ -219,14 +218,12 @@ static inline const char *cifs_symlink_type_str(enum cifs_symlink_type type)
 struct session_key {
 	unsigned int len;
 	char *response;
 };
 
-/* crypto hashing related structure/fields, not specific to a sec mech */
+/* encryption related structure/fields, not specific to a sec mech */
 struct cifs_secmech {
-	struct shash_desc *aes_cmac; /* block-cipher based MAC function, for SMB3 signatures */
-
 	struct crypto_aead *enc; /* smb3 encryption AEAD TFM (AES-CCM and AES-GCM) */
 	struct crypto_aead *dec; /* smb3 decryption AEAD TFM (AES-CCM and AES-GCM) */
 };
 
 /* per smb session structure/fields */
diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
index c24c50d732e64..4a25afda9448a 100644
--- a/fs/smb/client/cifsproto.h
+++ b/fs/smb/client/cifsproto.h
@@ -349,13 +349,10 @@ int __cifs_calc_signature(struct smb_rqst *rqst,
 			  struct TCP_Server_Info *server, char *signature,
 			  struct cifs_calc_sig_ctx *ctx);
 enum securityEnum cifs_select_sectype(struct TCP_Server_Info *server,
 				      enum securityEnum requested);
 
-int cifs_alloc_hash(const char *name, struct shash_desc **sdesc);
-void cifs_free_hash(struct shash_desc **sdesc);
-
 int cifs_try_adding_channels(struct cifs_ses *ses);
 int smb3_update_ses_channels(struct cifs_ses *ses,
 			     struct TCP_Server_Info *server,
 			     bool from_reconnect, bool disable_mchan);
 bool is_ses_using_iface(struct cifs_ses *ses, struct cifs_server_iface *iface);
diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c
index 2aff1cab6c31e..0c54b9b79a2ce 100644
--- a/fs/smb/client/misc.c
+++ b/fs/smb/client/misc.c
@@ -783,67 +783,10 @@ parse_dfs_referrals(struct get_dfs_referral_rsp *rsp, u32 rsp_size,
 		*num_of_nodes = 0;
 	}
 	return rc;
 }
 
-/**
- * cifs_alloc_hash - allocate hash and hash context together
- * @name: The name of the crypto hash algo
- * @sdesc: SHASH descriptor where to put the pointer to the hash TFM
- *
- * The caller has to make sure @sdesc is initialized to either NULL or
- * a valid context. It can be freed via cifs_free_hash().
- */
-int
-cifs_alloc_hash(const char *name, struct shash_desc **sdesc)
-{
-	int rc = 0;
-	struct crypto_shash *alg = NULL;
-
-	if (*sdesc)
-		return 0;
-
-	alg = crypto_alloc_shash(name, 0, 0);
-	if (IS_ERR(alg)) {
-		cifs_dbg(VFS, "Could not allocate shash TFM '%s'\n", name);
-		rc = PTR_ERR(alg);
-		*sdesc = NULL;
-		return rc;
-	}
-
-	*sdesc = kmalloc(sizeof(struct shash_desc) + crypto_shash_descsize(alg), GFP_KERNEL);
-	if (*sdesc == NULL) {
-		cifs_dbg(VFS, "no memory left to allocate shash TFM '%s'\n", name);
-		crypto_free_shash(alg);
-		return -ENOMEM;
-	}
-
-	(*sdesc)->tfm = alg;
-	return 0;
-}
-
-/**
- * cifs_free_hash - free hash and hash context together
- * @sdesc: Where to find the pointer to the hash TFM
- *
- * Freeing a NULL descriptor is safe.
- */
-void
-cifs_free_hash(struct shash_desc **sdesc)
-{
-	if (unlikely(!sdesc) || !*sdesc)
-		return;
-
-	if ((*sdesc)->tfm) {
-		crypto_free_shash((*sdesc)->tfm);
-		(*sdesc)->tfm = NULL;
-	}
-
-	kfree_sensitive(*sdesc);
-	*sdesc = NULL;
-}
-
 void extract_unc_hostname(const char *unc, const char **h, size_t *len)
 {
 	const char *end;
 
 	/* skip initial slashes */
diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c
index 698bd27119ae0..de2012cc9cf3e 100644
--- a/fs/smb/client/sess.c
+++ b/fs/smb/client/sess.c
@@ -593,21 +593,10 @@ cifs_ses_add_channel(struct cifs_ses *ses,
 	cifs_chan_set_need_reconnect(ses, chan->server);
 
 	spin_unlock(&ses->chan_lock);
 
 	mutex_lock(&ses->session_mutex);
-	/*
-	 * We need to allocate the server crypto now as we will need
-	 * to sign packets before we generate the channel signing key
-	 * (we sign with the session key)
-	 */
-	rc = smb3_crypto_shash_allocate(chan->server);
-	if (rc) {
-		cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__);
-		mutex_unlock(&ses->session_mutex);
-		goto out;
-	}
 
 	rc = cifs_negotiate_protocol(xid, ses, chan->server);
 	if (!rc)
 		rc = cifs_setup_session(xid, ses, chan->server, ses->local_nls);
 
diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h
index 5f74475ba9d19..1ceb95b907e6b 100644
--- a/fs/smb/client/smb2proto.h
+++ b/fs/smb/client/smb2proto.h
@@ -255,11 +255,10 @@ int smb2_validate_iov(unsigned int offset, unsigned int buffer_length,
 int smb2_validate_and_copy_iov(unsigned int offset, unsigned int buffer_length,
 			       struct kvec *iov, unsigned int minbufsize,
 			       char *data);
 void smb2_copy_fs_info_to_kstatfs(struct smb2_fs_full_size_info *pfs_inf,
 				  struct kstatfs *kst);
-int smb3_crypto_shash_allocate(struct TCP_Server_Info *server);
 void smb311_update_preauth_hash(struct cifs_ses *ses,
 				struct TCP_Server_Info *server,
 				struct kvec *iov, int nvec);
 int smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
 			     const char *path, u32 desired_access, u32 class,
diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c
index b233e0cd91529..716e58d1b1c92 100644
--- a/fs/smb/client/smb2transport.c
+++ b/fs/smb/client/smb2transport.c
@@ -27,18 +27,10 @@
 #include "smb2proto.h"
 #include "cifs_debug.h"
 #include "../common/smb2status.h"
 #include "smb2glob.h"
 
-int
-smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
-{
-	struct cifs_secmech *p = &server->secmech;
-
-	return cifs_alloc_hash("cmac(aes)", &p->aes_cmac);
-}
-
 static
 int smb3_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key)
 {
 	struct cifs_chan *chan;
 	struct TCP_Server_Info *pserver;
@@ -264,24 +256,17 @@ static int generate_key(struct cifs_ses *ses, struct kvec label,
 {
 	unsigned char zero = 0x0;
 	__u8 i[4] = {0, 0, 0, 1};
 	__u8 L128[4] = {0, 0, 0, 128};
 	__u8 L256[4] = {0, 0, 1, 0};
-	int rc = 0;
 	unsigned char prfhash[SMB2_HMACSHA256_SIZE];
 	struct TCP_Server_Info *server = ses->server;
 	struct hmac_sha256_ctx hmac_ctx;
 
 	memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
 	memset(key, 0x0, key_size);
 
-	rc = smb3_crypto_shash_allocate(server);
-	if (rc) {
-		cifs_server_dbg(VFS, "%s: crypto alloc failed\n", __func__);
-		return rc;
-	}
-
 	hmac_sha256_init_usingrawkey(&hmac_ctx, ses->auth_key.response,
 				     SMB2_NTLMV2_SESSKEY_SIZE);
 	hmac_sha256_update(&hmac_ctx, i, 4);
 	hmac_sha256_update(&hmac_ctx, label.iov_base, label.iov_len);
 	hmac_sha256_update(&hmac_ctx, &zero, 1);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 3/4] smb: client: Make generate_key() return void
  2026-04-18 22:13 [PATCH v2 0/4] smb: client: Use AES-CMAC library Eric Biggers
  2026-04-18 22:13 ` [PATCH v2 1/4] smb: client: Use AES-CMAC library for SMB3 signature calculation Eric Biggers
  2026-04-18 22:13 ` [PATCH v2 2/4] smb: client: Remove obsolete cmac(aes) allocation Eric Biggers
@ 2026-04-18 22:13 ` Eric Biggers
  2026-04-18 22:13 ` [PATCH v2 4/4] smb: client: Drop 'allocate_crypto' arg from smb*_calc_signature() Eric Biggers
  2026-04-19  1:36 ` [PATCH v2 0/4] smb: client: Use AES-CMAC library Steve French
  4 siblings, 0 replies; 6+ messages in thread
From: Eric Biggers @ 2026-04-18 22:13 UTC (permalink / raw)
  To: linux-cifs, Steve French
  Cc: linux-crypto, samba-technical, linux-kernel, Ard Biesheuvel,
	Paulo Alcantara, Ronnie Sahlberg, Shyam Prasad N, Tom Talpey,
	Bharath SM, Eric Biggers

Since the crypto library API is now being used instead of crypto_shash,
generate_key() can no longer fail.  Make it return void and simplify the
callers accordingly.

Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
 fs/smb/client/smb2transport.c | 45 +++++++++++++----------------------
 1 file changed, 16 insertions(+), 29 deletions(-)

diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c
index 716e58d1b1c92..0176185a1efcb 100644
--- a/fs/smb/client/smb2transport.c
+++ b/fs/smb/client/smb2transport.c
@@ -249,12 +249,12 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
 		memcpy(shdr->Signature, smb2_signature, SMB2_SIGNATURE_SIZE);
 
 	return rc;
 }
 
-static int generate_key(struct cifs_ses *ses, struct kvec label,
-			struct kvec context, __u8 *key, unsigned int key_size)
+static void generate_key(struct cifs_ses *ses, struct kvec label,
+			 struct kvec context, __u8 *key, unsigned int key_size)
 {
 	unsigned char zero = 0x0;
 	__u8 i[4] = {0, 0, 0, 1};
 	__u8 L128[4] = {0, 0, 0, 128};
 	__u8 L256[4] = {0, 0, 1, 0};
@@ -279,11 +279,10 @@ static int generate_key(struct cifs_ses *ses, struct kvec label,
 		hmac_sha256_update(&hmac_ctx, L128, 4);
 	}
 	hmac_sha256_final(&hmac_ctx, prfhash);
 
 	memcpy(key, prfhash, key_size);
-	return 0;
 }
 
 struct derivation {
 	struct kvec label;
 	struct kvec context;
@@ -298,11 +297,10 @@ struct derivation_triplet {
 static int
 generate_smb3signingkey(struct cifs_ses *ses,
 			struct TCP_Server_Info *server,
 			const struct derivation_triplet *ptriplet)
 {
-	int rc;
 	bool is_binding = false;
 	int chan_index = 0;
 
 	spin_lock(&ses->ses_lock);
 	spin_lock(&ses->chan_lock);
@@ -329,42 +327,31 @@ generate_smb3signingkey(struct cifs_ses *ses,
 	 * key and store it in the channel as to not overwrite the
 	 * master connection signing key stored in the session
 	 */
 
 	if (is_binding) {
-		rc = generate_key(ses, ptriplet->signing.label,
-				  ptriplet->signing.context,
-				  ses->chans[chan_index].signkey,
-				  SMB3_SIGN_KEY_SIZE);
-		if (rc)
-			return rc;
+		generate_key(ses, ptriplet->signing.label,
+			     ptriplet->signing.context,
+			     ses->chans[chan_index].signkey,
+			     SMB3_SIGN_KEY_SIZE);
 	} else {
-		rc = generate_key(ses, ptriplet->signing.label,
-				  ptriplet->signing.context,
-				  ses->smb3signingkey,
-				  SMB3_SIGN_KEY_SIZE);
-		if (rc)
-			return rc;
+		generate_key(ses, ptriplet->signing.label,
+			     ptriplet->signing.context,
+			     ses->smb3signingkey, SMB3_SIGN_KEY_SIZE);
 
 		/* safe to access primary channel, since it will never go away */
 		spin_lock(&ses->chan_lock);
 		memcpy(ses->chans[chan_index].signkey, ses->smb3signingkey,
 		       SMB3_SIGN_KEY_SIZE);
 		spin_unlock(&ses->chan_lock);
 
-		rc = generate_key(ses, ptriplet->encryption.label,
-				  ptriplet->encryption.context,
-				  ses->smb3encryptionkey,
-				  SMB3_ENC_DEC_KEY_SIZE);
-		if (rc)
-			return rc;
-		rc = generate_key(ses, ptriplet->decryption.label,
-				  ptriplet->decryption.context,
-				  ses->smb3decryptionkey,
-				  SMB3_ENC_DEC_KEY_SIZE);
-		if (rc)
-			return rc;
+		generate_key(ses, ptriplet->encryption.label,
+			     ptriplet->encryption.context,
+			     ses->smb3encryptionkey, SMB3_ENC_DEC_KEY_SIZE);
+		generate_key(ses, ptriplet->decryption.label,
+			     ptriplet->decryption.context,
+			     ses->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE);
 	}
 
 #ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS
 	cifs_dbg(VFS, "%s: dumping generated AES session keys\n", __func__);
 	/*
@@ -389,11 +376,11 @@ generate_smb3signingkey(struct cifs_ses *ses,
 				SMB3_GCM128_CRYPTKEY_SIZE, ses->smb3encryptionkey);
 		cifs_dbg(VFS, "ServerOut Key %*ph\n",
 				SMB3_GCM128_CRYPTKEY_SIZE, ses->smb3decryptionkey);
 	}
 #endif
-	return rc;
+	return 0;
 }
 
 int
 generate_smb30signingkey(struct cifs_ses *ses,
 			 struct TCP_Server_Info *server)
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 4/4] smb: client: Drop 'allocate_crypto' arg from smb*_calc_signature()
  2026-04-18 22:13 [PATCH v2 0/4] smb: client: Use AES-CMAC library Eric Biggers
                   ` (2 preceding siblings ...)
  2026-04-18 22:13 ` [PATCH v2 3/4] smb: client: Make generate_key() return void Eric Biggers
@ 2026-04-18 22:13 ` Eric Biggers
  2026-04-19  1:36 ` [PATCH v2 0/4] smb: client: Use AES-CMAC library Steve French
  4 siblings, 0 replies; 6+ messages in thread
From: Eric Biggers @ 2026-04-18 22:13 UTC (permalink / raw)
  To: linux-cifs, Steve French
  Cc: linux-crypto, samba-technical, linux-kernel, Ard Biesheuvel,
	Paulo Alcantara, Ronnie Sahlberg, Shyam Prasad N, Tom Talpey,
	Bharath SM, Eric Biggers, Steve French

Since the crypto library API is now being used instead of crypto_shash,
all structs for MAC computation are now just fixed-size structs
allocated on the stack; no dynamic allocations are ever required.
Besides being much more efficient, this also means that the
'allocate_crypto' argument to smb2_calc_signature() and
smb3_calc_signature() is no longer used.  Remove this unused argument.

Acked-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
 fs/smb/client/smb2transport.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c
index 0176185a1efcb..41009039b4cbe 100644
--- a/fs/smb/client/smb2transport.c
+++ b/fs/smb/client/smb2transport.c
@@ -202,12 +202,11 @@ smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32  tid)
 
 	return tcon;
 }
 
 static int
-smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
-		    bool allocate_crypto)
+smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
 {
 	int rc;
 	unsigned char smb2_signature[SMB2_HMACSHA256_SIZE];
 	struct kvec *iov = rqst->rq_iov;
 	struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base;
@@ -438,12 +437,11 @@ generate_smb311signingkey(struct cifs_ses *ses,
 
 	return generate_smb3signingkey(ses, server, &triplet);
 }
 
 static int
-smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
-		    bool allocate_crypto)
+smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
 {
 	int rc;
 	unsigned char smb3_signature[SMB2_CMACAES_SIZE];
 	struct kvec *iov = rqst->rq_iov;
 	struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base;
@@ -451,11 +449,11 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
 	struct aes_cmac_ctx cmac_ctx;
 	struct smb_rqst drqst;
 	u8 key[SMB3_SIGN_KEY_SIZE];
 
 	if (server->vals->protocol_id <= SMB21_PROT_ID)
-		return smb2_calc_signature(rqst, server, allocate_crypto);
+		return smb2_calc_signature(rqst, server);
 
 	rc = smb3_get_sign_key(le64_to_cpu(shdr->SessionId), server, key);
 	if (unlikely(rc)) {
 		cifs_server_dbg(FYI, "%s: Could not get signing key\n", __func__);
 		return rc;
@@ -522,11 +520,11 @@ smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
 	if (!is_binding && !server->session_estab) {
 		strscpy(shdr->Signature, "BSRSPYL");
 		return 0;
 	}
 
-	return smb3_calc_signature(rqst, server, false);
+	return smb3_calc_signature(rqst, server);
 }
 
 int
 smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
 {
@@ -558,11 +556,11 @@ smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
 	 */
 	memcpy(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE);
 
 	memset(shdr->Signature, 0, SMB2_SIGNATURE_SIZE);
 
-	rc = smb3_calc_signature(rqst, server, true);
+	rc = smb3_calc_signature(rqst, server);
 
 	if (rc)
 		return rc;
 
 	if (crypto_memneq(server_response_sig, shdr->Signature,
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 0/4] smb: client: Use AES-CMAC library
  2026-04-18 22:13 [PATCH v2 0/4] smb: client: Use AES-CMAC library Eric Biggers
                   ` (3 preceding siblings ...)
  2026-04-18 22:13 ` [PATCH v2 4/4] smb: client: Drop 'allocate_crypto' arg from smb*_calc_signature() Eric Biggers
@ 2026-04-19  1:36 ` Steve French
  4 siblings, 0 replies; 6+ messages in thread
From: Steve French @ 2026-04-19  1:36 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-cifs, Steve French, linux-crypto, samba-technical,
	linux-kernel, Ard Biesheuvel, Paulo Alcantara, Ronnie Sahlberg,
	Shyam Prasad N, Tom Talpey, Bharath SM

merged into cifs-2.6.git for-next pending additional testing and review

On Sat, Apr 18, 2026 at 5:13 PM Eric Biggers <ebiggers@kernel.org> wrote:
>
> This series updates the SMB client to use the AES-CMAC library functions
> that were recently added, instead of a "cmac(aes)" crypto_shash.  As
> usual, this simplifies the code considerably and is much more efficient.
>
> These patches were originally sent as patches 8-11 of the series
> https://lore.kernel.org/r/20260218213501.136844-1-ebiggers@kernel.org/
> The only change from that version was adding tags and rebasing.
> I also added some microbenchmark results below.
>
> This is intended to be taken through the smb tree, either 7.1 or 7.2
> depending on maintainer preference.
>
> A few microbenchmarks that demonstrate improved performance:
>
>  - Total cycles spent in generate_key() during SMB3 mount
>    decreased from 20640 to 10780 (3 calls total).
>
>  - Total cycles spent in smb3_calc_signature() during SMB3 mount
>    decreased from 177620 to 73180 (32 calls & 4255 bytes total).
>
>  - Total cycles spent in smb3_calc_signature() while writing 10MB file
>    decreased from 27551180 to 26628360 (10 calls & 10001392 bytes total)
>
>  - Total cycles spent in smb3_calc_signature() while reading 10MB file
>    decreased from 28390900 to 27879340 (14 calls & 10001781 bytes total)
>
> Note that my "before" numbers were taken from current mainline which has
> my changes that made the "cmac(aes)" crypto_shash a bit faster as well.
> So the speedup vs v7.0 is actually even greater.
>
> Eric Biggers (4):
>   smb: client: Use AES-CMAC library for SMB3 signature calculation
>   smb: client: Remove obsolete cmac(aes) allocation
>   smb: client: Make generate_key() return void
>   smb: client: Drop 'allocate_crypto' arg from smb*_calc_signature()
>
>  fs/smb/client/Kconfig         |   2 +-
>  fs/smb/client/cifs_unicode.c  |   1 +
>  fs/smb/client/cifsencrypt.c   |  62 ++++++-------------
>  fs/smb/client/cifsfs.c        |   1 -
>  fs/smb/client/cifsglob.h      |   7 +--
>  fs/smb/client/cifsproto.h     |   3 -
>  fs/smb/client/misc.c          |  57 -----------------
>  fs/smb/client/sess.c          |  11 ----
>  fs/smb/client/smb2proto.h     |   1 -
>  fs/smb/client/smb2transport.c | 113 +++++++++-------------------------
>  10 files changed, 53 insertions(+), 205 deletions(-)
>
>
> base-commit: 8541d8f725c673db3bd741947f27974358b2e163
> --
> 2.53.0
>
>


-- 
Thanks,

Steve

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-04-19  1:36 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-18 22:13 [PATCH v2 0/4] smb: client: Use AES-CMAC library Eric Biggers
2026-04-18 22:13 ` [PATCH v2 1/4] smb: client: Use AES-CMAC library for SMB3 signature calculation Eric Biggers
2026-04-18 22:13 ` [PATCH v2 2/4] smb: client: Remove obsolete cmac(aes) allocation Eric Biggers
2026-04-18 22:13 ` [PATCH v2 3/4] smb: client: Make generate_key() return void Eric Biggers
2026-04-18 22:13 ` [PATCH v2 4/4] smb: client: Drop 'allocate_crypto' arg from smb*_calc_signature() Eric Biggers
2026-04-19  1:36 ` [PATCH v2 0/4] smb: client: Use AES-CMAC library Steve French

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox