* [PATCH 1/8] smb: client: Use SHA-512 library for SMB3.1.1 preauth hash
2025-10-12 1:57 [PATCH 0/8] smb: client: More crypto library conversions Eric Biggers
@ 2025-10-12 1:57 ` Eric Biggers
2025-10-12 1:57 ` [PATCH 2/8] smb: client: Use HMAC-SHA256 library for key generation Eric Biggers
` (9 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Eric Biggers @ 2025-10-12 1:57 UTC (permalink / raw)
To: linux-cifs, Steve French
Cc: samba-technical, linux-crypto, linux-kernel, Paulo Alcantara,
Ronnie Sahlberg, Shyam Prasad N, Tom Talpey, Bharath SM,
Eric Biggers
Convert smb311_update_preauth_hash() to use the SHA-512 library instead
of a "sha512" crypto_shash. This is simpler and faster. With the
library there's no need to allocate memory, no need to handle errors,
and the SHA-512 code is accessed directly without inefficient indirect
calls and other unnecessary API overhead.
Remove the call to smb311_crypto_shash_allocate() from
smb311_update_preauth_hash(), since it appears to have been needed only
to allocate the "sha512" crypto_shash. (It also had the side effect of
allocating the "cmac(aes)" crypto_shash, but that's also done in
generate_key() which is where the AES-CMAC key is initialized.)
For now the "sha512" crypto_shash is still being allocated elsewhere.
It will be removed in a later commit.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
fs/smb/client/Kconfig | 1 +
fs/smb/client/smb2misc.c | 53 +++++++++------------------------------
fs/smb/client/smb2proto.h | 6 ++---
3 files changed, 16 insertions(+), 44 deletions(-)
diff --git a/fs/smb/client/Kconfig b/fs/smb/client/Kconfig
index a4c02199fef48..4ac79ff5649bf 100644
--- a/fs/smb/client/Kconfig
+++ b/fs/smb/client/Kconfig
@@ -14,10 +14,11 @@ config CIFS
select CRYPTO_CCM
select CRYPTO_GCM
select CRYPTO_ECB
select CRYPTO_AES
select CRYPTO_LIB_ARC4
+ select CRYPTO_LIB_SHA512
select KEYS
select DNS_RESOLVER
select ASN1
select OID_REGISTRY
select NETFS_SUPPORT
diff --git a/fs/smb/client/smb2misc.c b/fs/smb/client/smb2misc.c
index 89d933b4a8bc2..96bfe4c63ccf9 100644
--- a/fs/smb/client/smb2misc.c
+++ b/fs/smb/client/smb2misc.c
@@ -5,10 +5,11 @@
* Etersoft, 2012
* Author(s): Steve French (sfrench@us.ibm.com)
* Pavel Shilovsky (pshilovsky@samba.org) 2012
*
*/
+#include <crypto/sha2.h>
#include <linux/ctype.h>
#include "cifsglob.h"
#include "cifsproto.h"
#include "smb2proto.h"
#include "cifs_debug.h"
@@ -886,17 +887,17 @@ smb2_handle_cancelled_mid(struct mid_q_entry *mid, struct TCP_Server_Info *serve
* @ses: server session structure
* @server: pointer to server info
* @iov: array containing the SMB request we will send to the server
* @nvec: number of array entries for the iov
*/
-int
+void
smb311_update_preauth_hash(struct cifs_ses *ses, struct TCP_Server_Info *server,
struct kvec *iov, int nvec)
{
- int i, rc;
+ int i;
struct smb2_hdr *hdr;
- struct shash_desc *sha512 = NULL;
+ struct sha512_ctx sha_ctx;
hdr = (struct smb2_hdr *)iov[0].iov_base;
/* neg prot are always taken */
if (hdr->Command == SMB2_NEGOTIATE)
goto ok;
@@ -905,54 +906,24 @@ smb311_update_preauth_hash(struct cifs_ses *ses, struct TCP_Server_Info *server,
* If we process a command which wasn't a negprot it means the
* neg prot was already done, so the server dialect was set
* and we can test it. Preauth requires 3.1.1 for now.
*/
if (server->dialect != SMB311_PROT_ID)
- return 0;
+ return;
if (hdr->Command != SMB2_SESSION_SETUP)
- return 0;
+ return;
/* skip last sess setup response */
if ((hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
&& (hdr->Status == NT_STATUS_OK
|| (hdr->Status !=
cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))))
- return 0;
+ return;
ok:
- rc = smb311_crypto_shash_allocate(server);
- if (rc)
- return rc;
-
- sha512 = server->secmech.sha512;
- rc = crypto_shash_init(sha512);
- if (rc) {
- cifs_dbg(VFS, "%s: Could not init sha512 shash\n", __func__);
- return rc;
- }
-
- rc = crypto_shash_update(sha512, ses->preauth_sha_hash,
- SMB2_PREAUTH_HASH_SIZE);
- if (rc) {
- cifs_dbg(VFS, "%s: Could not update sha512 shash\n", __func__);
- return rc;
- }
-
- for (i = 0; i < nvec; i++) {
- rc = crypto_shash_update(sha512, iov[i].iov_base, iov[i].iov_len);
- if (rc) {
- cifs_dbg(VFS, "%s: Could not update sha512 shash\n",
- __func__);
- return rc;
- }
- }
-
- rc = crypto_shash_final(sha512, ses->preauth_sha_hash);
- if (rc) {
- cifs_dbg(VFS, "%s: Could not finalize sha512 shash\n",
- __func__);
- return rc;
- }
-
- return 0;
+ sha512_init(&sha_ctx);
+ sha512_update(&sha_ctx, ses->preauth_sha_hash, SMB2_PREAUTH_HASH_SIZE);
+ for (i = 0; i < nvec; i++)
+ sha512_update(&sha_ctx, iov[i].iov_base, iov[i].iov_len);
+ sha512_final(&sha_ctx, ses->preauth_sha_hash);
}
diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h
index b3f1398c9f790..e7cda885c39f0 100644
--- a/fs/smb/client/smb2proto.h
+++ b/fs/smb/client/smb2proto.h
@@ -294,13 +294,13 @@ extern int smb2_validate_and_copy_iov(unsigned int offset,
unsigned int minbufsize, char *data);
extern void smb2_copy_fs_info_to_kstatfs(
struct smb2_fs_full_size_info *pfs_inf,
struct kstatfs *kst);
extern int smb311_crypto_shash_allocate(struct TCP_Server_Info *server);
-extern int smb311_update_preauth_hash(struct cifs_ses *ses,
- struct TCP_Server_Info *server,
- struct kvec *iov, int nvec);
+extern void smb311_update_preauth_hash(struct cifs_ses *ses,
+ struct TCP_Server_Info *server,
+ struct kvec *iov, int nvec);
extern int smb2_query_info_compound(const unsigned int xid,
struct cifs_tcon *tcon,
const char *path, u32 desired_access,
u32 class, u32 type, u32 output_len,
struct kvec *rsp, int *buftype,
--
2.51.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 2/8] smb: client: Use HMAC-SHA256 library for key generation
2025-10-12 1:57 [PATCH 0/8] smb: client: More crypto library conversions Eric Biggers
2025-10-12 1:57 ` [PATCH 1/8] smb: client: Use SHA-512 library for SMB3.1.1 preauth hash Eric Biggers
@ 2025-10-12 1:57 ` Eric Biggers
2025-10-12 1:57 ` [PATCH 3/8] smb: client: Use HMAC-SHA256 library for SMB2 signature calculation Eric Biggers
` (8 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Eric Biggers @ 2025-10-12 1:57 UTC (permalink / raw)
To: linux-cifs, Steve French
Cc: samba-technical, linux-crypto, linux-kernel, Paulo Alcantara,
Ronnie Sahlberg, Shyam Prasad N, Tom Talpey, Bharath SM,
Eric Biggers
Convert generate_key() to use the HMAC-SHA256 library instead of a
"hmac(sha256)" crypto_shash. This is simpler and faster. With the
library there's no need to allocate memory, no need to handle errors,
and the HMAC-SHA256 code is accessed directly without inefficient
indirect calls and other unnecessary API overhead.
Also remove the unnecessary 'hashptr' variable.
For now smb3_crypto_shash_allocate() still allocates a "hmac(sha256)"
crypto_shash. It will be removed in a later commit.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
fs/smb/client/Kconfig | 1 +
fs/smb/client/smb2transport.c | 68 ++++++++---------------------------
2 files changed, 15 insertions(+), 54 deletions(-)
diff --git a/fs/smb/client/Kconfig b/fs/smb/client/Kconfig
index 4ac79ff5649bf..f0c1ff8544f67 100644
--- a/fs/smb/client/Kconfig
+++ b/fs/smb/client/Kconfig
@@ -14,10 +14,11 @@ config CIFS
select CRYPTO_CCM
select CRYPTO_GCM
select CRYPTO_ECB
select CRYPTO_AES
select CRYPTO_LIB_ARC4
+ select CRYPTO_LIB_SHA256
select CRYPTO_LIB_SHA512
select KEYS
select DNS_RESOLVER
select ASN1
select OID_REGISTRY
diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c
index 33f33013b3927..bde96eace8c94 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/sha2.h>
#include "cifsglob.h"
#include "cifsproto.h"
#include "smb2proto.h"
#include "cifs_debug.h"
#include "../common/smb2status.h"
@@ -334,80 +335,39 @@ static int generate_key(struct cifs_ses *ses, struct kvec label,
__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];
- unsigned char *hashptr = prfhash;
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__);
- goto smb3signkey_ret;
- }
-
- rc = crypto_shash_setkey(server->secmech.hmacsha256->tfm,
- ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
- if (rc) {
- cifs_server_dbg(VFS, "%s: Could not set with session key\n", __func__);
- goto smb3signkey_ret;
- }
-
- rc = crypto_shash_init(server->secmech.hmacsha256);
- if (rc) {
- cifs_server_dbg(VFS, "%s: Could not init sign hmac\n", __func__);
- goto smb3signkey_ret;
- }
-
- rc = crypto_shash_update(server->secmech.hmacsha256, i, 4);
- if (rc) {
- cifs_server_dbg(VFS, "%s: Could not update with n\n", __func__);
- goto smb3signkey_ret;
- }
-
- rc = crypto_shash_update(server->secmech.hmacsha256, label.iov_base, label.iov_len);
- if (rc) {
- cifs_server_dbg(VFS, "%s: Could not update with label\n", __func__);
- goto smb3signkey_ret;
- }
-
- rc = crypto_shash_update(server->secmech.hmacsha256, &zero, 1);
- if (rc) {
- cifs_server_dbg(VFS, "%s: Could not update with zero\n", __func__);
- goto smb3signkey_ret;
+ return rc;
}
- rc = crypto_shash_update(server->secmech.hmacsha256, context.iov_base, context.iov_len);
- if (rc) {
- cifs_server_dbg(VFS, "%s: Could not update with context\n", __func__);
- goto smb3signkey_ret;
- }
+ 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);
+ hmac_sha256_update(&hmac_ctx, context.iov_base, context.iov_len);
if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
(server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) {
- rc = crypto_shash_update(server->secmech.hmacsha256, L256, 4);
+ hmac_sha256_update(&hmac_ctx, L256, 4);
} else {
- rc = crypto_shash_update(server->secmech.hmacsha256, L128, 4);
- }
- if (rc) {
- cifs_server_dbg(VFS, "%s: Could not update with L\n", __func__);
- goto smb3signkey_ret;
+ hmac_sha256_update(&hmac_ctx, L128, 4);
}
+ hmac_sha256_final(&hmac_ctx, prfhash);
- rc = crypto_shash_final(server->secmech.hmacsha256, hashptr);
- if (rc) {
- cifs_server_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__);
- goto smb3signkey_ret;
- }
-
- memcpy(key, hashptr, key_size);
-
-smb3signkey_ret:
- return rc;
+ memcpy(key, prfhash, key_size);
+ return 0;
}
struct derivation {
struct kvec label;
struct kvec context;
--
2.51.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 3/8] smb: client: Use HMAC-SHA256 library for SMB2 signature calculation
2025-10-12 1:57 [PATCH 0/8] smb: client: More crypto library conversions Eric Biggers
2025-10-12 1:57 ` [PATCH 1/8] smb: client: Use SHA-512 library for SMB3.1.1 preauth hash Eric Biggers
2025-10-12 1:57 ` [PATCH 2/8] smb: client: Use HMAC-SHA256 library for key generation Eric Biggers
@ 2025-10-12 1:57 ` Eric Biggers
2025-10-12 1:57 ` [PATCH 4/8] smb: client: Use MD5 library for M-F symlink hashing Eric Biggers
` (7 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Eric Biggers @ 2025-10-12 1:57 UTC (permalink / raw)
To: linux-cifs, Steve French
Cc: samba-technical, linux-crypto, linux-kernel, Paulo Alcantara,
Ronnie Sahlberg, Shyam Prasad N, Tom Talpey, Bharath SM,
Eric Biggers
Convert smb2_calc_signature() to use the HMAC-SHA256 library instead of
a "hmac(sha256)" crypto_shash. This is simpler and faster. With the
library there's no need to allocate memory, no need to handle errors,
and the HMAC-SHA256 code is accessed directly without inefficient
indirect calls and other unnecessary API overhead.
To make this possible, make __cifs_calc_signature() support both the
HMAC-SHA256 library and crypto_shash. (crypto_shash is still needed for
HMAC-MD5 and AES-CMAC. A later commit will switch HMAC-MD5 from shash
to the library. I'd like to eventually do the same for AES-CMAC, but it
doesn't have a library API yet. So for now, shash is still needed.)
Also remove the unnecessary 'sigptr' variable.
For now smb3_crypto_shash_allocate() still allocates a "hmac(sha256)"
crypto_shash. It will be removed in a later commit.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
fs/smb/client/cifsencrypt.c | 52 +++++++++++++++++++++++-----------
fs/smb/client/cifsproto.h | 9 ++++--
fs/smb/client/smb2transport.c | 53 ++++++++---------------------------
3 files changed, 53 insertions(+), 61 deletions(-)
diff --git a/fs/smb/client/cifsencrypt.c b/fs/smb/client/cifsencrypt.c
index 7b7c8c38fdd08..9522088a1cfb7 100644
--- a/fs/smb/client/cifsencrypt.c
+++ b/fs/smb/client/cifsencrypt.c
@@ -22,43 +22,62 @@
#include <linux/highmem.h>
#include <linux/fips.h>
#include <linux/iov_iter.h>
#include <crypto/aead.h>
#include <crypto/arc4.h>
+#include <crypto/sha2.h>
-static size_t cifs_shash_step(void *iter_base, size_t progress, size_t len,
- void *priv, void *priv2)
+static int cifs_sig_update(struct cifs_calc_sig_ctx *ctx,
+ const u8 *data, size_t len)
{
- struct shash_desc *shash = priv;
+ if (ctx->hmac) {
+ hmac_sha256_update(ctx->hmac, data, len);
+ return 0;
+ }
+ return crypto_shash_update(ctx->shash, data, len);
+}
+
+static int cifs_sig_final(struct cifs_calc_sig_ctx *ctx, u8 *out)
+{
+ 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 = crypto_shash_update(shash, iter_base, len);
+ ret = cifs_sig_update(ctx, iter_base, len);
if (ret < 0) {
*pret = ret;
return len;
}
return 0;
}
/*
* Pass the data from an iterator into a hash.
*/
-static int cifs_shash_iter(const struct iov_iter *iter, size_t maxsize,
- struct shash_desc *shash)
+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;
int err = -EIO;
- if (iterate_and_advance_kernel(&tmp_iter, maxsize, shash, &err,
- cifs_shash_step) != maxsize)
+ if (iterate_and_advance_kernel(&tmp_iter, maxsize, ctx, &err,
+ cifs_sig_step) != maxsize)
return err;
return 0;
}
-int __cifs_calc_signature(struct smb_rqst *rqst,
- struct TCP_Server_Info *server, char *signature,
- struct shash_desc *shash)
+int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
+ char *signature, struct cifs_calc_sig_ctx *ctx)
{
int i;
ssize_t rc;
struct kvec *iov = rqst->rq_iov;
int n_vec = rqst->rq_nvec;
@@ -80,24 +99,23 @@ int __cifs_calc_signature(struct smb_rqst *rqst,
if (iov[i].iov_base == NULL) {
cifs_dbg(VFS, "null iovec entry\n");
return -EIO;
}
- rc = crypto_shash_update(shash,
- iov[i].iov_base, iov[i].iov_len);
+ rc = cifs_sig_update(ctx, iov[i].iov_base, iov[i].iov_len);
if (rc) {
cifs_dbg(VFS, "%s: Could not update with payload\n",
__func__);
return rc;
}
}
- rc = cifs_shash_iter(&rqst->rq_iter, iov_iter_count(&rqst->rq_iter), shash);
+ rc = cifs_sig_iter(&rqst->rq_iter, iov_iter_count(&rqst->rq_iter), ctx);
if (rc < 0)
return rc;
- rc = crypto_shash_final(shash, signature);
+ rc = cifs_sig_final(ctx, signature);
if (rc)
cifs_dbg(VFS, "%s: Could not generate hash\n", __func__);
return rc;
}
@@ -132,11 +150,13 @@ static int cifs_calc_signature(struct smb_rqst *rqst,
if (rc) {
cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
return rc;
}
- return __cifs_calc_signature(rqst, server, signature, server->secmech.md5);
+ return __cifs_calc_signature(
+ rqst, server, signature,
+ &(struct cifs_calc_sig_ctx){ .shash = server->secmech.md5 });
}
/* must be called with server->srv_mutex held */
int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
__u32 *pexpected_response_sequence_number)
diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
index e8fba98690ce3..3bb74eea0e4ff 100644
--- a/fs/smb/client/cifsproto.h
+++ b/fs/smb/client/cifsproto.h
@@ -630,13 +630,16 @@ int cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
unsigned int *pbytes_read);
int cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
struct cifs_sb_info *cifs_sb,
const unsigned char *path, char *pbuf,
unsigned int *pbytes_written);
-int __cifs_calc_signature(struct smb_rqst *rqst,
- struct TCP_Server_Info *server, char *signature,
- struct shash_desc *shash);
+struct cifs_calc_sig_ctx {
+ struct hmac_sha256_ctx *hmac;
+ struct shash_desc *shash;
+};
+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 *,
enum securityEnum);
int cifs_alloc_hash(const char *name, struct shash_desc **sdesc);
void cifs_free_hash(struct shash_desc **sdesc);
diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c
index bde96eace8c94..89258accc2203 100644
--- a/fs/smb/client/smb2transport.c
+++ b/fs/smb/client/smb2transport.c
@@ -252,14 +252,13 @@ int
smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
bool allocate_crypto)
{
int rc;
unsigned char smb2_signature[SMB2_HMACSHA256_SIZE];
- unsigned char *sigptr = smb2_signature;
struct kvec *iov = rqst->rq_iov;
struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base;
- struct shash_desc *shash = NULL;
+ struct hmac_sha256_ctx hmac_ctx;
struct smb_rqst drqst;
__u64 sid = le64_to_cpu(shdr->SessionId);
u8 key[SMB2_NTLMV2_SESSKEY_SIZE];
rc = smb2_get_sign_key(server, sid, key);
@@ -270,63 +269,32 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
}
memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
- if (allocate_crypto) {
- rc = cifs_alloc_hash("hmac(sha256)", &shash);
- if (rc) {
- cifs_server_dbg(VFS,
- "%s: sha256 alloc failed\n", __func__);
- goto out;
- }
- } else {
- shash = server->secmech.hmacsha256;
- }
-
- rc = crypto_shash_setkey(shash->tfm, key, sizeof(key));
- if (rc) {
- cifs_server_dbg(VFS,
- "%s: Could not update with response\n",
- __func__);
- goto out;
- }
-
- rc = crypto_shash_init(shash);
- if (rc) {
- cifs_server_dbg(VFS, "%s: Could not init sha256", __func__);
- goto out;
- }
+ hmac_sha256_init_usingrawkey(&hmac_ctx, key, sizeof(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;
- }
+ hmac_sha256_update(&hmac_ctx, iov[0].iov_base, iov[0].iov_len);
drqst.rq_iov++;
drqst.rq_nvec--;
}
- rc = __cifs_calc_signature(&drqst, server, sigptr, shash);
+ rc = __cifs_calc_signature(
+ &drqst, server, smb2_signature,
+ &(struct cifs_calc_sig_ctx){ .hmac = &hmac_ctx });
if (!rc)
- memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
+ memcpy(shdr->Signature, smb2_signature, SMB2_SIGNATURE_SIZE);
-out:
- if (allocate_crypto)
- cifs_free_hash(&shash);
return rc;
}
static int generate_key(struct cifs_ses *ses, struct kvec label,
struct kvec context, __u8 *key, unsigned int key_size)
@@ -540,11 +508,10 @@ int
smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
bool allocate_crypto)
{
int rc;
unsigned char smb3_signature[SMB2_CMACAES_SIZE];
- unsigned char *sigptr = smb3_signature;
struct kvec *iov = rqst->rq_iov;
struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base;
struct shash_desc *shash = NULL;
struct smb_rqst drqst;
u8 key[SMB3_SIGN_KEY_SIZE];
@@ -601,13 +568,15 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
}
drqst.rq_iov++;
drqst.rq_nvec--;
}
- rc = __cifs_calc_signature(&drqst, server, sigptr, shash);
+ rc = __cifs_calc_signature(
+ &drqst, server, smb3_signature,
+ &(struct cifs_calc_sig_ctx){ .shash = shash });
if (!rc)
- memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
+ memcpy(shdr->Signature, smb3_signature, SMB2_SIGNATURE_SIZE);
out:
if (allocate_crypto)
cifs_free_hash(&shash);
return rc;
--
2.51.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 4/8] smb: client: Use MD5 library for M-F symlink hashing
2025-10-12 1:57 [PATCH 0/8] smb: client: More crypto library conversions Eric Biggers
` (2 preceding siblings ...)
2025-10-12 1:57 ` [PATCH 3/8] smb: client: Use HMAC-SHA256 library for SMB2 signature calculation Eric Biggers
@ 2025-10-12 1:57 ` Eric Biggers
2025-10-12 1:57 ` [PATCH 5/8] smb: client: Use MD5 library for SMB1 signature calculation Eric Biggers
` (6 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Eric Biggers @ 2025-10-12 1:57 UTC (permalink / raw)
To: linux-cifs, Steve French
Cc: samba-technical, linux-crypto, linux-kernel, Paulo Alcantara,
Ronnie Sahlberg, Shyam Prasad N, Tom Talpey, Bharath SM,
Eric Biggers
Convert parse_mf_symlink() and format_mf_symlink() to use the MD5
library instead of a "md5" crypto_shash. This is simpler and faster.
With the library there's no need to allocate memory, no need to handle
errors, and the MD5 code is accessed directly without inefficient
indirect calls and other unnecessary API overhead.
This also fixes an issue where these functions did not work on kernels
booted in FIPS mode. The use of MD5 here is for data integrity rather
than a security purpose, so it can use a non-FIPS-approved algorithm.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
fs/smb/client/Kconfig | 1 +
fs/smb/client/link.c | 31 +++----------------------------
2 files changed, 4 insertions(+), 28 deletions(-)
diff --git a/fs/smb/client/Kconfig b/fs/smb/client/Kconfig
index f0c1ff8544f67..f5a980bdfc939 100644
--- a/fs/smb/client/Kconfig
+++ b/fs/smb/client/Kconfig
@@ -14,10 +14,11 @@ config CIFS
select CRYPTO_CCM
select CRYPTO_GCM
select CRYPTO_ECB
select CRYPTO_AES
select CRYPTO_LIB_ARC4
+ select CRYPTO_LIB_MD5
select CRYPTO_LIB_SHA256
select CRYPTO_LIB_SHA512
select KEYS
select DNS_RESOLVER
select ASN1
diff --git a/fs/smb/client/link.c b/fs/smb/client/link.c
index fe80e711cd756..70f3c0c67eebd 100644
--- a/fs/smb/client/link.c
+++ b/fs/smb/client/link.c
@@ -3,10 +3,11 @@
*
* Copyright (C) International Business Machines Corp., 2002,2008
* Author(s): Steve French (sfrench@us.ibm.com)
*
*/
+#include <crypto/md5.h>
#include <linux/fs.h>
#include <linux/stat.h>
#include <linux/slab.h>
#include <linux/namei.h>
#include "cifsfs.h"
@@ -34,27 +35,10 @@
#define CIFS_MF_SYMLINK_LEN_FORMAT "XSym\n%04u\n"
#define CIFS_MF_SYMLINK_MD5_FORMAT "%16phN\n"
#define CIFS_MF_SYMLINK_MD5_ARGS(md5_hash) md5_hash
-static int
-symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash)
-{
- int rc;
- struct shash_desc *md5 = NULL;
-
- rc = cifs_alloc_hash("md5", &md5);
- if (rc)
- return rc;
-
- rc = crypto_shash_digest(md5, link_str, link_len, md5_hash);
- if (rc)
- cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
- cifs_free_hash(&md5);
- return rc;
-}
-
static int
parse_mf_symlink(const u8 *buf, unsigned int buf_len, unsigned int *_link_len,
char **_link_str)
{
int rc;
@@ -75,15 +59,11 @@ parse_mf_symlink(const u8 *buf, unsigned int buf_len, unsigned int *_link_len,
return -EINVAL;
if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN)
return -EINVAL;
- rc = symlink_hash(link_len, link_str, md5_hash);
- if (rc) {
- cifs_dbg(FYI, "%s: MD5 hash failure: %d\n", __func__, rc);
- return rc;
- }
+ md5(link_str, link_len, md5_hash);
scnprintf(md5_str2, sizeof(md5_str2),
CIFS_MF_SYMLINK_MD5_FORMAT,
CIFS_MF_SYMLINK_MD5_ARGS(md5_hash));
@@ -101,11 +81,10 @@ parse_mf_symlink(const u8 *buf, unsigned int buf_len, unsigned int *_link_len,
}
static int
format_mf_symlink(u8 *buf, unsigned int buf_len, const char *link_str)
{
- int rc;
unsigned int link_len;
unsigned int ofs;
u8 md5_hash[16];
if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE)
@@ -114,15 +93,11 @@ format_mf_symlink(u8 *buf, unsigned int buf_len, const char *link_str)
link_len = strlen(link_str);
if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN)
return -ENAMETOOLONG;
- rc = symlink_hash(link_len, link_str, md5_hash);
- if (rc) {
- cifs_dbg(FYI, "%s: MD5 hash failure: %d\n", __func__, rc);
- return rc;
- }
+ md5(link_str, link_len, md5_hash);
scnprintf(buf, buf_len,
CIFS_MF_SYMLINK_LEN_FORMAT CIFS_MF_SYMLINK_MD5_FORMAT,
link_len,
CIFS_MF_SYMLINK_MD5_ARGS(md5_hash));
--
2.51.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 5/8] smb: client: Use MD5 library for SMB1 signature calculation
2025-10-12 1:57 [PATCH 0/8] smb: client: More crypto library conversions Eric Biggers
` (3 preceding siblings ...)
2025-10-12 1:57 ` [PATCH 4/8] smb: client: Use MD5 library for M-F symlink hashing Eric Biggers
@ 2025-10-12 1:57 ` Eric Biggers
2025-10-12 1:57 ` [PATCH 6/8] smb: client: Use HMAC-MD5 library for NTLMv2 Eric Biggers
` (5 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Eric Biggers @ 2025-10-12 1:57 UTC (permalink / raw)
To: linux-cifs, Steve French
Cc: samba-technical, linux-crypto, linux-kernel, Paulo Alcantara,
Ronnie Sahlberg, Shyam Prasad N, Tom Talpey, Bharath SM,
Eric Biggers
Convert cifs_calc_signature() to use the MD5 library instead of a "md5"
crypto_shash. This is simpler and faster. With the library there's no
need to allocate memory, no need to handle errors, and the MD5 code is
accessed directly without inefficient indirect calls and other
unnecessary API overhead.
To preserve the existing behavior of MD5 signature support being
disabled when the kernel is booted with "fips=1", make
cifs_calc_signature() check fips_enabled itself. Previously it relied
on the error from cifs_alloc_hash("md5", &server->secmech.md5).
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
fs/smb/client/cifsencrypt.c | 34 +++++++++++++++++-----------------
fs/smb/client/cifsproto.h | 1 +
2 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/fs/smb/client/cifsencrypt.c b/fs/smb/client/cifsencrypt.c
index 9522088a1cfb7..80215ba7a5744 100644
--- a/fs/smb/client/cifsencrypt.c
+++ b/fs/smb/client/cifsencrypt.c
@@ -22,24 +22,33 @@
#include <linux/highmem.h>
#include <linux/fips.h>
#include <linux/iov_iter.h>
#include <crypto/aead.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)
{
+ 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);
}
static int cifs_sig_final(struct cifs_calc_sig_ctx *ctx, u8 *out)
{
+ if (ctx->md5) {
+ md5_final(ctx->md5, out);
+ return 0;
+ }
if (ctx->hmac) {
hmac_sha256_final(ctx->hmac, out);
return 0;
}
return crypto_shash_final(ctx->shash, out);
@@ -128,35 +137,26 @@ int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
* should be called with the server->srv_mutex held.
*/
static int cifs_calc_signature(struct smb_rqst *rqst,
struct TCP_Server_Info *server, char *signature)
{
- int rc;
+ struct md5_ctx ctx;
if (!rqst->rq_iov || !signature || !server)
return -EINVAL;
-
- rc = cifs_alloc_hash("md5", &server->secmech.md5);
- if (rc)
- return -1;
-
- rc = crypto_shash_init(server->secmech.md5);
- if (rc) {
- cifs_dbg(VFS, "%s: Could not init md5\n", __func__);
- return rc;
+ if (fips_enabled) {
+ cifs_dbg(VFS,
+ "MD5 signature support is disabled due to FIPS\n");
+ return -EOPNOTSUPP;
}
- rc = crypto_shash_update(server->secmech.md5,
- server->session_key.response, server->session_key.len);
- if (rc) {
- cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
- return rc;
- }
+ md5_init(&ctx);
+ md5_update(&ctx, server->session_key.response, server->session_key.len);
return __cifs_calc_signature(
rqst, server, signature,
- &(struct cifs_calc_sig_ctx){ .shash = server->secmech.md5 });
+ &(struct cifs_calc_sig_ctx){ .md5 = &ctx });
}
/* must be called with server->srv_mutex held */
int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
__u32 *pexpected_response_sequence_number)
diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
index 3bb74eea0e4ff..4976be2c47c14 100644
--- a/fs/smb/client/cifsproto.h
+++ b/fs/smb/client/cifsproto.h
@@ -631,10 +631,11 @@ int cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
int cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
struct cifs_sb_info *cifs_sb,
const unsigned char *path, char *pbuf,
unsigned int *pbytes_written);
struct cifs_calc_sig_ctx {
+ struct md5_ctx *md5;
struct hmac_sha256_ctx *hmac;
struct shash_desc *shash;
};
int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
char *signature, struct cifs_calc_sig_ctx *ctx);
--
2.51.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 6/8] smb: client: Use HMAC-MD5 library for NTLMv2
2025-10-12 1:57 [PATCH 0/8] smb: client: More crypto library conversions Eric Biggers
` (4 preceding siblings ...)
2025-10-12 1:57 ` [PATCH 5/8] smb: client: Use MD5 library for SMB1 signature calculation Eric Biggers
@ 2025-10-12 1:57 ` Eric Biggers
2025-10-12 1:57 ` [PATCH 7/8] smb: client: Remove obsolete crypto_shash allocations Eric Biggers
` (4 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Eric Biggers @ 2025-10-12 1:57 UTC (permalink / raw)
To: linux-cifs, Steve French
Cc: samba-technical, linux-crypto, linux-kernel, Paulo Alcantara,
Ronnie Sahlberg, Shyam Prasad N, Tom Talpey, Bharath SM,
Eric Biggers
For the HMAC-MD5 computations in NTLMv2, use the HMAC-MD5 library
instead of a "hmac(md5)" crypto_shash. This is simpler and faster.
With the library there's no need to allocate memory, no need to handle
errors, and the HMAC-MD5 code is accessed directly without inefficient
indirect calls and other unnecessary API overhead.
To preserve the existing behavior of NTLMv2 support being disabled when
the kernel is booted with "fips=1", make setup_ntlmv2_rsp() check
fips_enabled itself. Previously it relied on the error from
cifs_alloc_hash("hmac(md5)", &hmacmd5).
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
fs/smb/client/cifsencrypt.c | 114 +++++++-----------------------------
1 file changed, 22 insertions(+), 92 deletions(-)
diff --git a/fs/smb/client/cifsencrypt.c b/fs/smb/client/cifsencrypt.c
index 80215ba7a5744..bbcf3b05c19ab 100644
--- a/fs/smb/client/cifsencrypt.c
+++ b/fs/smb/client/cifsencrypt.c
@@ -423,33 +423,23 @@ static __le64 find_timestamp(struct cifs_ses *ses)
ktime_get_real_ts64(&ts);
return cpu_to_le64(cifs_UnixTimeToNT(ts));
}
static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
- const struct nls_table *nls_cp, struct shash_desc *hmacmd5)
+ const struct nls_table *nls_cp)
{
- int rc = 0;
int len;
char nt_hash[CIFS_NTHASH_SIZE];
+ struct hmac_md5_ctx hmac_ctx;
__le16 *user;
wchar_t *domain;
wchar_t *server;
/* calculate md4 hash of password */
E_md4hash(ses->password, nt_hash, nls_cp);
- rc = crypto_shash_setkey(hmacmd5->tfm, nt_hash, CIFS_NTHASH_SIZE);
- if (rc) {
- cifs_dbg(VFS, "%s: Could not set NT hash as a key, rc=%d\n", __func__, rc);
- return rc;
- }
-
- rc = crypto_shash_init(hmacmd5);
- if (rc) {
- cifs_dbg(VFS, "%s: Could not init HMAC-MD5, rc=%d\n", __func__, rc);
- return rc;
- }
+ hmac_md5_init_usingrawkey(&hmac_ctx, nt_hash, CIFS_NTHASH_SIZE);
/* convert ses->user_name to unicode */
len = ses->user_name ? strlen(ses->user_name) : 0;
user = kmalloc(2 + (len * 2), GFP_KERNEL);
if (user == NULL)
@@ -460,16 +450,12 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
UniStrupr(user);
} else {
*(u16 *)user = 0;
}
- rc = crypto_shash_update(hmacmd5, (char *)user, 2 * len);
+ hmac_md5_update(&hmac_ctx, (const u8 *)user, 2 * len);
kfree(user);
- if (rc) {
- cifs_dbg(VFS, "%s: Could not update with user, rc=%d\n", __func__, rc);
- return rc;
- }
/* convert ses->domainName to unicode and uppercase */
if (ses->domainName) {
len = strlen(ses->domainName);
@@ -477,81 +463,48 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
if (domain == NULL)
return -ENOMEM;
len = cifs_strtoUTF16((__le16 *)domain, ses->domainName, len,
nls_cp);
- rc = crypto_shash_update(hmacmd5, (char *)domain, 2 * len);
+ hmac_md5_update(&hmac_ctx, (const u8 *)domain, 2 * len);
kfree(domain);
- if (rc) {
- cifs_dbg(VFS, "%s: Could not update with domain, rc=%d\n", __func__, rc);
- return rc;
- }
} else {
/* We use ses->ip_addr if no domain name available */
len = strlen(ses->ip_addr);
server = kmalloc(2 + (len * 2), GFP_KERNEL);
if (server == NULL)
return -ENOMEM;
len = cifs_strtoUTF16((__le16 *)server, ses->ip_addr, len, nls_cp);
- rc = crypto_shash_update(hmacmd5, (char *)server, 2 * len);
+ hmac_md5_update(&hmac_ctx, (const u8 *)server, 2 * len);
kfree(server);
- if (rc) {
- cifs_dbg(VFS, "%s: Could not update with server, rc=%d\n", __func__, rc);
- return rc;
- }
}
- rc = crypto_shash_final(hmacmd5, ntlmv2_hash);
- if (rc)
- cifs_dbg(VFS, "%s: Could not generate MD5 hash, rc=%d\n", __func__, rc);
-
- return rc;
+ hmac_md5_final(&hmac_ctx, ntlmv2_hash);
+ return 0;
}
-static int
-CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash, struct shash_desc *hmacmd5)
+static void CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
{
- int rc;
struct ntlmv2_resp *ntlmv2 = (struct ntlmv2_resp *)
(ses->auth_key.response + CIFS_SESS_KEY_SIZE);
unsigned int hash_len;
/* The MD5 hash starts at challenge_key.key */
hash_len = ses->auth_key.len - (CIFS_SESS_KEY_SIZE +
offsetof(struct ntlmv2_resp, challenge.key[0]));
- rc = crypto_shash_setkey(hmacmd5->tfm, ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
- if (rc) {
- cifs_dbg(VFS, "%s: Could not set NTLMv2 hash as a key, rc=%d\n", __func__, rc);
- return rc;
- }
-
- rc = crypto_shash_init(hmacmd5);
- if (rc) {
- cifs_dbg(VFS, "%s: Could not init HMAC-MD5, rc=%d\n", __func__, rc);
- return rc;
- }
-
if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED)
memcpy(ntlmv2->challenge.key, ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
else
memcpy(ntlmv2->challenge.key, ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
- rc = crypto_shash_update(hmacmd5, ntlmv2->challenge.key, hash_len);
- if (rc) {
- cifs_dbg(VFS, "%s: Could not update with response, rc=%d\n", __func__, rc);
- return rc;
- }
-
- /* Note that the MD5 digest over writes anon.challenge_key.key */
- rc = crypto_shash_final(hmacmd5, ntlmv2->ntlmv2_hash);
- if (rc)
- cifs_dbg(VFS, "%s: Could not generate MD5 hash, rc=%d\n", __func__, rc);
-
- return rc;
+ /* Note that the HMAC-MD5 value overwrites ntlmv2->challenge.key */
+ hmac_md5_usingrawkey(ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE,
+ ntlmv2->challenge.key, hash_len,
+ ntlmv2->ntlmv2_hash);
}
/*
* Set up NTLMv2 response blob with SPN (cifs/<hostname>) appended to the
* existing list of AV pairs.
@@ -604,11 +557,10 @@ static int set_auth_key_response(struct cifs_ses *ses)
}
int
setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
{
- struct shash_desc *hmacmd5 = NULL;
unsigned char *tiblob = NULL; /* target info blob */
struct ntlmv2_resp *ntlmv2;
char ntlmv2_hash[16];
__le64 rsp_timestamp;
__u64 cc;
@@ -675,55 +627,33 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
ntlmv2->reserved = 0;
ntlmv2->time = rsp_timestamp;
ntlmv2->client_chal = cc;
ntlmv2->reserved2 = 0;
- rc = cifs_alloc_hash("hmac(md5)", &hmacmd5);
- if (rc) {
- cifs_dbg(VFS, "Could not allocate HMAC-MD5, rc=%d\n", rc);
+ if (fips_enabled) {
+ cifs_dbg(VFS, "NTLMv2 support is disabled due to FIPS\n");
+ rc = -EOPNOTSUPP;
goto unlock;
}
/* calculate ntlmv2_hash */
- rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp, hmacmd5);
+ rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp);
if (rc) {
cifs_dbg(VFS, "Could not get NTLMv2 hash, rc=%d\n", rc);
goto unlock;
}
/* calculate first part of the client response (CR1) */
- rc = CalcNTLMv2_response(ses, ntlmv2_hash, hmacmd5);
- if (rc) {
- cifs_dbg(VFS, "Could not calculate CR1, rc=%d\n", rc);
- goto unlock;
- }
+ CalcNTLMv2_response(ses, ntlmv2_hash);
/* now calculate the session key for NTLMv2 */
- rc = crypto_shash_setkey(hmacmd5->tfm, ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
- if (rc) {
- cifs_dbg(VFS, "%s: Could not set NTLMv2 hash as a key, rc=%d\n", __func__, rc);
- goto unlock;
- }
-
- rc = crypto_shash_init(hmacmd5);
- if (rc) {
- cifs_dbg(VFS, "%s: Could not init HMAC-MD5, rc=%d\n", __func__, rc);
- goto unlock;
- }
-
- rc = crypto_shash_update(hmacmd5, ntlmv2->ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
- if (rc) {
- cifs_dbg(VFS, "%s: Could not update with response, rc=%d\n", __func__, rc);
- goto unlock;
- }
-
- rc = crypto_shash_final(hmacmd5, ses->auth_key.response);
- if (rc)
- cifs_dbg(VFS, "%s: Could not generate MD5 hash, rc=%d\n", __func__, rc);
+ hmac_md5_usingrawkey(ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE,
+ ntlmv2->ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE,
+ ses->auth_key.response);
+ rc = 0;
unlock:
cifs_server_unlock(ses->server);
- cifs_free_hash(&hmacmd5);
setup_ntlmv2_rsp_ret:
kfree_sensitive(tiblob);
return rc;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 7/8] smb: client: Remove obsolete crypto_shash allocations
2025-10-12 1:57 [PATCH 0/8] smb: client: More crypto library conversions Eric Biggers
` (5 preceding siblings ...)
2025-10-12 1:57 ` [PATCH 6/8] smb: client: Use HMAC-MD5 library for NTLMv2 Eric Biggers
@ 2025-10-12 1:57 ` Eric Biggers
2025-10-12 1:57 ` [PATCH 8/8] smb: client: Consolidate cmac(aes) shash allocation Eric Biggers
` (3 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Eric Biggers @ 2025-10-12 1:57 UTC (permalink / raw)
To: linux-cifs, Steve French
Cc: samba-technical, linux-crypto, linux-kernel, Paulo Alcantara,
Ronnie Sahlberg, Shyam Prasad N, Tom Talpey, Bharath SM,
Eric Biggers
Now that the SMB client accesses MD5, HMAC-MD5, HMAC-SHA256, and SHA-512
only via the library API and not via crypto_shash, allocating
crypto_shash objects for these algorithms is no longer necessary.
Remove all these allocations, their corresponding kconfig selections,
and their corresponding module soft dependencies.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
fs/smb/client/Kconfig | 4 ----
fs/smb/client/cifsencrypt.c | 3 ---
fs/smb/client/cifsfs.c | 4 ----
fs/smb/client/cifsglob.h | 3 ---
fs/smb/client/smb2transport.c | 35 ++---------------------------------
5 files changed, 2 insertions(+), 47 deletions(-)
diff --git a/fs/smb/client/Kconfig b/fs/smb/client/Kconfig
index f5a980bdfc939..17bd368574e94 100644
--- a/fs/smb/client/Kconfig
+++ b/fs/smb/client/Kconfig
@@ -3,15 +3,11 @@ config CIFS
tristate "SMB3 and CIFS support (advanced network filesystem)"
depends on INET
select NLS
select NLS_UCS2_UTILS
select CRYPTO
- select CRYPTO_MD5
- select CRYPTO_SHA256
- select CRYPTO_SHA512
select CRYPTO_CMAC
- select CRYPTO_HMAC
select CRYPTO_AEAD2
select CRYPTO_CCM
select CRYPTO_GCM
select CRYPTO_ECB
select CRYPTO_AES
diff --git a/fs/smb/client/cifsencrypt.c b/fs/smb/client/cifsencrypt.c
index bbcf3b05c19ab..801824825ecf2 100644
--- a/fs/smb/client/cifsencrypt.c
+++ b/fs/smb/client/cifsencrypt.c
@@ -691,13 +691,10 @@ calc_seckey(struct cifs_ses *ses)
void
cifs_crypto_secmech_release(struct TCP_Server_Info *server)
{
cifs_free_hash(&server->secmech.aes_cmac);
- cifs_free_hash(&server->secmech.hmacsha256);
- cifs_free_hash(&server->secmech.md5);
- cifs_free_hash(&server->secmech.sha512);
if (server->secmech.enc) {
crypto_free_aead(server->secmech.enc);
server->secmech.enc = NULL;
}
diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c
index 05b1fa76e8ccf..4f959f1e08d23 100644
--- a/fs/smb/client/cifsfs.c
+++ b/fs/smb/client/cifsfs.c
@@ -2137,17 +2137,13 @@ MODULE_LICENSE("GPL"); /* combination of LGPL + GPL source behaves as GPL */
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("ecb");
-MODULE_SOFTDEP("hmac");
-MODULE_SOFTDEP("md5");
MODULE_SOFTDEP("nls");
MODULE_SOFTDEP("aes");
MODULE_SOFTDEP("cmac");
-MODULE_SOFTDEP("sha256");
-MODULE_SOFTDEP("sha512");
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 8f6f567d7474f..8932aa612db4a 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -219,13 +219,10 @@ struct session_key {
char *response;
};
/* crypto hashing related structure/fields, not specific to a sec mech */
struct cifs_secmech {
- struct shash_desc *md5; /* md5 hash function, for CIFS/SMB1 signatures */
- struct shash_desc *hmacsha256; /* hmac-sha256 hash function, for SMB2 signatures */
- struct shash_desc *sha512; /* sha512 hash function, for SMB3.1.1 preauth hash */
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) */
};
diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c
index 89258accc2203..cd689bc27bfdc 100644
--- a/fs/smb/client/smb2transport.c
+++ b/fs/smb/client/smb2transport.c
@@ -29,53 +29,22 @@
static int
smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
{
struct cifs_secmech *p = &server->secmech;
- int rc;
-
- rc = cifs_alloc_hash("hmac(sha256)", &p->hmacsha256);
- if (rc)
- goto err;
-
- rc = cifs_alloc_hash("cmac(aes)", &p->aes_cmac);
- if (rc)
- goto err;
- return 0;
-err:
- cifs_free_hash(&p->hmacsha256);
- return rc;
+ return cifs_alloc_hash("cmac(aes)", &p->aes_cmac);
}
int
smb311_crypto_shash_allocate(struct TCP_Server_Info *server)
{
struct cifs_secmech *p = &server->secmech;
- int rc = 0;
- rc = cifs_alloc_hash("hmac(sha256)", &p->hmacsha256);
- if (rc)
- return rc;
-
- rc = cifs_alloc_hash("cmac(aes)", &p->aes_cmac);
- if (rc)
- goto err;
-
- rc = cifs_alloc_hash("sha512", &p->sha512);
- if (rc)
- goto err;
-
- return 0;
-
-err:
- cifs_free_hash(&p->aes_cmac);
- cifs_free_hash(&p->hmacsha256);
- return rc;
+ 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;
--
2.51.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 8/8] smb: client: Consolidate cmac(aes) shash allocation
2025-10-12 1:57 [PATCH 0/8] smb: client: More crypto library conversions Eric Biggers
` (6 preceding siblings ...)
2025-10-12 1:57 ` [PATCH 7/8] smb: client: Remove obsolete crypto_shash allocations Eric Biggers
@ 2025-10-12 1:57 ` Eric Biggers
2025-10-13 14:44 ` [PATCH 0/8] smb: client: More crypto library conversions Enzo Matsumiya
` (2 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Eric Biggers @ 2025-10-12 1:57 UTC (permalink / raw)
To: linux-cifs, Steve French
Cc: samba-technical, linux-crypto, linux-kernel, Paulo Alcantara,
Ronnie Sahlberg, Shyam Prasad N, Tom Talpey, Bharath SM,
Eric Biggers
Now that smb3_crypto_shash_allocate() and smb311_crypto_shash_allocate()
are identical and only allocate "cmac(aes)", delete the latter and
replace the call to it with the former.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
fs/smb/client/sess.c | 2 +-
fs/smb/client/smb2proto.h | 2 +-
fs/smb/client/smb2transport.c | 10 +---------
3 files changed, 3 insertions(+), 11 deletions(-)
diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c
index 0a8c2fcc9dedf..ef3b498b0a02a 100644
--- a/fs/smb/client/sess.c
+++ b/fs/smb/client/sess.c
@@ -582,11 +582,11 @@ cifs_ses_add_channel(struct cifs_ses *ses,
/*
* 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 = smb311_crypto_shash_allocate(chan->server);
+ 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;
}
diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h
index e7cda885c39f0..6eb86d134abcc 100644
--- a/fs/smb/client/smb2proto.h
+++ b/fs/smb/client/smb2proto.h
@@ -293,11 +293,11 @@ extern int smb2_validate_and_copy_iov(unsigned int offset,
struct kvec *iov,
unsigned int minbufsize, char *data);
extern void smb2_copy_fs_info_to_kstatfs(
struct smb2_fs_full_size_info *pfs_inf,
struct kstatfs *kst);
-extern int smb311_crypto_shash_allocate(struct TCP_Server_Info *server);
+extern int smb3_crypto_shash_allocate(struct TCP_Server_Info *server);
extern void smb311_update_preauth_hash(struct cifs_ses *ses,
struct TCP_Server_Info *server,
struct kvec *iov, int nvec);
extern int smb2_query_info_compound(const unsigned int xid,
struct cifs_tcon *tcon,
diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c
index cd689bc27bfdc..ad6068e17a2a9 100644
--- a/fs/smb/client/smb2transport.c
+++ b/fs/smb/client/smb2transport.c
@@ -25,20 +25,12 @@
#include "smb2proto.h"
#include "cifs_debug.h"
#include "../common/smb2status.h"
#include "smb2glob.h"
-static 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);
-}
-
int
-smb311_crypto_shash_allocate(struct TCP_Server_Info *server)
+smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
{
struct cifs_secmech *p = &server->secmech;
return cifs_alloc_hash("cmac(aes)", &p->aes_cmac);
}
--
2.51.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH 0/8] smb: client: More crypto library conversions
2025-10-12 1:57 [PATCH 0/8] smb: client: More crypto library conversions Eric Biggers
` (7 preceding siblings ...)
2025-10-12 1:57 ` [PATCH 8/8] smb: client: Consolidate cmac(aes) shash allocation Eric Biggers
@ 2025-10-13 14:44 ` Enzo Matsumiya
2025-10-14 6:07 ` Eric Biggers
2025-10-14 3:42 ` Eric Biggers
2025-10-14 7:55 ` Ard Biesheuvel
10 siblings, 1 reply; 15+ messages in thread
From: Enzo Matsumiya @ 2025-10-13 14:44 UTC (permalink / raw)
To: Eric Biggers
Cc: linux-cifs, Steve French, samba-technical, linux-crypto,
linux-kernel, Paulo Alcantara, Ronnie Sahlberg, Shyam Prasad N,
Tom Talpey, Bharath SM
Hi Eric,
On 10/11, Eric Biggers wrote:
>This series converts fs/smb/client/ to access SHA-512, HMAC-SHA256, MD5,
>and HMAC-MD5 using the library APIs instead of crypto_shash.
>
>This simplifies the code significantly. It also slightly improves
>performance, as it eliminates unnecessary overhead.
>
>Tested with Samba with all SMB versions, with mfsymlinks in the mount
>options, 'server min protocol = NT1' and 'server signing = required' in
>smb.conf, and doing a simple file data and symlink verification test.
>That seems to cover all the modified code paths.
>
>However, with SMB 1.0 I get "CIFS: VFS: SMB signature verification
>returned error = -13", regardless of whether this series is applied or
>not. Presumably, testing that case requires some other setting I
>couldn't find.
>
>Regardless, these are straightforward conversions and all the actual
>crypto is exactly the same as before, as far as I can tell.
I think the overall series looks good and do a great cleanup.
Just a minor nit about fips_enabled: since it's now being handled
explicitly (rather than an error on cifs_alloc_hash() currently), I
think it makes sense to move the check to mount code path when
'sectype == NTLMv2' (I don't particularly care about SMB1, but
something similar can be done for 'smb1 && sign' cases I guess).
>Eric Biggers (8):
> smb: client: Use SHA-512 library for SMB3.1.1 preauth hash
> smb: client: Use HMAC-SHA256 library for key generation
> smb: client: Use HMAC-SHA256 library for SMB2 signature calculation
> smb: client: Use MD5 library for M-F symlink hashing
> smb: client: Use MD5 library for SMB1 signature calculation
> smb: client: Use HMAC-MD5 library for NTLMv2
> smb: client: Remove obsolete crypto_shash allocations
> smb: client: Consolidate cmac(aes) shash allocation
>
> fs/smb/client/Kconfig | 7 +-
> fs/smb/client/cifsencrypt.c | 201 +++++++++++++---------------------
> fs/smb/client/cifsfs.c | 4 -
> fs/smb/client/cifsglob.h | 3 -
> fs/smb/client/cifsproto.h | 10 +-
> fs/smb/client/link.c | 31 +-----
> fs/smb/client/sess.c | 2 +-
> fs/smb/client/smb2misc.c | 53 ++-------
> fs/smb/client/smb2proto.h | 8 +-
> fs/smb/client/smb2transport.c | 164 +++++----------------------
> 10 files changed, 131 insertions(+), 352 deletions(-)
>
>
>base-commit: 67029a49db6c1f21106a1b5fcdd0ea234a6e0711
>--
>2.51.0
Cheers,
Enzo
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH 0/8] smb: client: More crypto library conversions
2025-10-13 14:44 ` [PATCH 0/8] smb: client: More crypto library conversions Enzo Matsumiya
@ 2025-10-14 6:07 ` Eric Biggers
0 siblings, 0 replies; 15+ messages in thread
From: Eric Biggers @ 2025-10-14 6:07 UTC (permalink / raw)
To: Enzo Matsumiya
Cc: linux-cifs, Steve French, samba-technical, linux-crypto,
linux-kernel, Paulo Alcantara, Ronnie Sahlberg, Shyam Prasad N,
Tom Talpey, Bharath SM
On Mon, Oct 13, 2025 at 11:44:37AM -0300, Enzo Matsumiya wrote:
> Hi Eric,
>
> On 10/11, Eric Biggers wrote:
> > This series converts fs/smb/client/ to access SHA-512, HMAC-SHA256, MD5,
> > and HMAC-MD5 using the library APIs instead of crypto_shash.
> >
> > This simplifies the code significantly. It also slightly improves
> > performance, as it eliminates unnecessary overhead.
> >
> > Tested with Samba with all SMB versions, with mfsymlinks in the mount
> > options, 'server min protocol = NT1' and 'server signing = required' in
> > smb.conf, and doing a simple file data and symlink verification test.
> > That seems to cover all the modified code paths.
> >
> > However, with SMB 1.0 I get "CIFS: VFS: SMB signature verification
> > returned error = -13", regardless of whether this series is applied or
> > not. Presumably, testing that case requires some other setting I
> > couldn't find.
> >
> > Regardless, these are straightforward conversions and all the actual
> > crypto is exactly the same as before, as far as I can tell.
>
> I think the overall series looks good and do a great cleanup.
>
> Just a minor nit about fips_enabled: since it's now being handled
> explicitly (rather than an error on cifs_alloc_hash() currently), I
> think it makes sense to move the check to mount code path when
> 'sectype == NTLMv2' (I don't particularly care about SMB1, but
> something similar can be done for 'smb1 && sign' cases I guess).
For MD5 message signing and NTLMv2, this series keeps the fips_enabled
checks where they were before. That is, they're inserted where the
calls to cifs_alloc_hash() were before. I think moving them to earlier
locations is best done in later patches, as it's not obvious (at least
to me) exactly how to do that.
I spent a while reading the code again, and this is what I came up with:
- For MD5 message signing: cifs_enable_signing() is probably the right
place to disallow it. However, it's called regardless of the signing
algorithm. So it needs a parameter passed in that tells it that the
signing algorithm will be MD5 (or equivalently the dialect is SMB1).
- For NTLMv2: select_sec() and SMB2_select_sec() are where the
authentication protocol is selected and are probably the right places
to disallow NTLMv2 and RawNTLMSSP. However, those are two places, not
one. We'd have to remember to put the fips_enabled check in both.
The nice thing about keeping the fips_enabled checks next to the actual
uses of the algorithms is that it ensures they stay in sync. So maybe
we should just stay with that here.
- Eric
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 0/8] smb: client: More crypto library conversions
2025-10-12 1:57 [PATCH 0/8] smb: client: More crypto library conversions Eric Biggers
` (8 preceding siblings ...)
2025-10-13 14:44 ` [PATCH 0/8] smb: client: More crypto library conversions Enzo Matsumiya
@ 2025-10-14 3:42 ` Eric Biggers
2025-10-17 16:12 ` Steve French
2025-10-14 7:55 ` Ard Biesheuvel
10 siblings, 1 reply; 15+ messages in thread
From: Eric Biggers @ 2025-10-14 3:42 UTC (permalink / raw)
To: linux-cifs, Steve French
Cc: samba-technical, linux-crypto, linux-kernel, Paulo Alcantara,
Ronnie Sahlberg, Shyam Prasad N, Tom Talpey, Bharath SM
On Sat, Oct 11, 2025 at 06:57:30PM -0700, Eric Biggers wrote:
> This series converts fs/smb/client/ to access SHA-512, HMAC-SHA256, MD5,
> and HMAC-MD5 using the library APIs instead of crypto_shash.
>
> This simplifies the code significantly. It also slightly improves
> performance, as it eliminates unnecessary overhead.
>
> Tested with Samba with all SMB versions, with mfsymlinks in the mount
> options, 'server min protocol = NT1' and 'server signing = required' in
> smb.conf, and doing a simple file data and symlink verification test.
> That seems to cover all the modified code paths.
>
> However, with SMB 1.0 I get "CIFS: VFS: SMB signature verification
> returned error = -13", regardless of whether this series is applied or
> not. Presumably, testing that case requires some other setting I
> couldn't find.
>
> Regardless, these are straightforward conversions and all the actual
> crypto is exactly the same as before, as far as I can tell.
>
> Eric Biggers (8):
> smb: client: Use SHA-512 library for SMB3.1.1 preauth hash
> smb: client: Use HMAC-SHA256 library for key generation
> smb: client: Use HMAC-SHA256 library for SMB2 signature calculation
> smb: client: Use MD5 library for M-F symlink hashing
> smb: client: Use MD5 library for SMB1 signature calculation
> smb: client: Use HMAC-MD5 library for NTLMv2
> smb: client: Remove obsolete crypto_shash allocations
> smb: client: Consolidate cmac(aes) shash allocation
As requested off-list, here are some (micro)benchmark results for this
series. The CPU was AMD Ryzen 9 9950X. The server was Samba running on
localhost. Message signing was enabled. A valid username and password
were given in the mount options. The "Improvement" column is the
percent change in throughput (reciprocal cycles):
Microbenchmark Before After Improvement
============== ====== ===== ===========
1. Total cycles spent in 44548 20081 122%
smb311_update_preauth_hash()
during SMB 3.1.1 mount
(4 calls total)
2. setup_ntlmv2_rsp() cycles 31777 22231 43%
3. Total cycles spent in 17802 22876 -22%
generate_key()
during SMB 3.1.1 mount
(3 calls total)
4. Total cycles spent in 205110 87204 135%
smb2_calc_signature()
during SMB 2.0 mount
(26 calls & 3316 bytes total)
5. Total cycles spent in 22689767 21043125 8%
smb2_calc_signature()
reading 10MB file using SMB 2.0
(316 calls & 10031077 bytes total)
6. Total cycles spent in 56803 37840 50%
cifs_calc_signature()
during SMB 1.0 mount
(18 calls & 1551 bytes total)
7. Total cycles spent in 52669066 51974573 1%
cifs_calc_signature()
reading 10MB file using SMB 1.0
(336 calls & 10021426 bytes total)
8. parse_mf_symlink() cycles 7654 4902 56%
Note: case 3 regressed because the "cmac(aes)" allocation moved from
smb311_update_preauth_hash (case 1) to generate_key (case 3). Excluding
that allocation, generate_key got faster. Likewise, the sum of cases 1,
2, and 3 (which all occurred at mount time) got faster.
There was a greater speedup in signature calculation than I expected.
It's probably because many SMB messages are short (especially the ones
exchanged at mount time), and also because the old code allocated new
crypto_shash objects more frequently than I had thought. The SMB 2.0
code allocated a new "hmac(sha256)" crypto_shash for every other message
signed. That overhead is all gone after switching to the library.
TLDR: all SMB crypto calculations (SHA-512, HMAC-SHA256, MD5, HMAC-MD5)
affected by this series are faster now. The library APIs fix the
unnecessary overhead that the traditional crypto API has. Of course,
it's also a lot easier to use as well.
- Eric
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH 0/8] smb: client: More crypto library conversions
2025-10-14 3:42 ` Eric Biggers
@ 2025-10-17 16:12 ` Steve French
2025-10-17 16:24 ` Eric Biggers
0 siblings, 1 reply; 15+ messages in thread
From: Steve French @ 2025-10-17 16:12 UTC (permalink / raw)
To: Eric Biggers
Cc: linux-cifs, Steve French, samba-technical, linux-crypto,
linux-kernel, Paulo Alcantara, Ronnie Sahlberg, Shyam Prasad N,
Tom Talpey, Bharath SM
> with SMB 1.0 I get "CIFS: VFS: SMB signature verification
> returned error = -13",
If testing SMB1 to Samba the server disabled signing unless I set
"server signing = mandatory"
in smb.conf. But with that, signing with your patches worked fine even to SMB1
Were you testing to Samba with SMB1?
On Mon, Oct 13, 2025 at 10:44 PM Eric Biggers <ebiggers@kernel.org> wrote:
>
> On Sat, Oct 11, 2025 at 06:57:30PM -0700, Eric Biggers wrote:
> > This series converts fs/smb/client/ to access SHA-512, HMAC-SHA256, MD5,
> > and HMAC-MD5 using the library APIs instead of crypto_shash.
> >
> > This simplifies the code significantly. It also slightly improves
> > performance, as it eliminates unnecessary overhead.
> >
> > Tested with Samba with all SMB versions, with mfsymlinks in the mount
> > options, 'server min protocol = NT1' and 'server signing = required' in
> > smb.conf, and doing a simple file data and symlink verification test.
> > That seems to cover all the modified code paths.
> >
> > However, with SMB 1.0 I get "CIFS: VFS: SMB signature verification
> > returned error = -13", regardless of whether this series is applied or
> > not. Presumably, testing that case requires some other setting I
> > couldn't find.
> >
> > Regardless, these are straightforward conversions and all the actual
> > crypto is exactly the same as before, as far as I can tell.
> >
> > Eric Biggers (8):
> > smb: client: Use SHA-512 library for SMB3.1.1 preauth hash
> > smb: client: Use HMAC-SHA256 library for key generation
> > smb: client: Use HMAC-SHA256 library for SMB2 signature calculation
> > smb: client: Use MD5 library for M-F symlink hashing
> > smb: client: Use MD5 library for SMB1 signature calculation
> > smb: client: Use HMAC-MD5 library for NTLMv2
> > smb: client: Remove obsolete crypto_shash allocations
> > smb: client: Consolidate cmac(aes) shash allocation
>
> As requested off-list, here are some (micro)benchmark results for this
> series. The CPU was AMD Ryzen 9 9950X. The server was Samba running on
> localhost. Message signing was enabled. A valid username and password
> were given in the mount options. The "Improvement" column is the
> percent change in throughput (reciprocal cycles):
>
> Microbenchmark Before After Improvement
> ============== ====== ===== ===========
>
> 1. Total cycles spent in 44548 20081 122%
> smb311_update_preauth_hash()
> during SMB 3.1.1 mount
> (4 calls total)
>
> 2. setup_ntlmv2_rsp() cycles 31777 22231 43%
>
> 3. Total cycles spent in 17802 22876 -22%
> generate_key()
> during SMB 3.1.1 mount
> (3 calls total)
>
> 4. Total cycles spent in 205110 87204 135%
> smb2_calc_signature()
> during SMB 2.0 mount
> (26 calls & 3316 bytes total)
>
> 5. Total cycles spent in 22689767 21043125 8%
> smb2_calc_signature()
> reading 10MB file using SMB 2.0
> (316 calls & 10031077 bytes total)
>
> 6. Total cycles spent in 56803 37840 50%
> cifs_calc_signature()
> during SMB 1.0 mount
> (18 calls & 1551 bytes total)
>
> 7. Total cycles spent in 52669066 51974573 1%
> cifs_calc_signature()
> reading 10MB file using SMB 1.0
> (336 calls & 10021426 bytes total)
>
> 8. parse_mf_symlink() cycles 7654 4902 56%
>
> Note: case 3 regressed because the "cmac(aes)" allocation moved from
> smb311_update_preauth_hash (case 1) to generate_key (case 3). Excluding
> that allocation, generate_key got faster. Likewise, the sum of cases 1,
> 2, and 3 (which all occurred at mount time) got faster.
>
> There was a greater speedup in signature calculation than I expected.
> It's probably because many SMB messages are short (especially the ones
> exchanged at mount time), and also because the old code allocated new
> crypto_shash objects more frequently than I had thought. The SMB 2.0
> code allocated a new "hmac(sha256)" crypto_shash for every other message
> signed. That overhead is all gone after switching to the library.
>
> TLDR: all SMB crypto calculations (SHA-512, HMAC-SHA256, MD5, HMAC-MD5)
> affected by this series are faster now. The library APIs fix the
> unnecessary overhead that the traditional crypto API has. Of course,
> it's also a lot easier to use as well.
>
> - Eric
>
--
Thanks,
Steve
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 0/8] smb: client: More crypto library conversions
2025-10-17 16:12 ` Steve French
@ 2025-10-17 16:24 ` Eric Biggers
0 siblings, 0 replies; 15+ messages in thread
From: Eric Biggers @ 2025-10-17 16:24 UTC (permalink / raw)
To: Steve French
Cc: linux-cifs, Steve French, samba-technical, linux-crypto,
linux-kernel, Paulo Alcantara, Ronnie Sahlberg, Shyam Prasad N,
Tom Talpey, Bharath SM
On Fri, Oct 17, 2025 at 11:12:58AM -0500, Steve French wrote:
> > with SMB 1.0 I get "CIFS: VFS: SMB signature verification
> > returned error = -13",
>
> If testing SMB1 to Samba the server disabled signing unless I set
> "server signing = mandatory"
> in smb.conf. But with that, signing with your patches worked fine even to SMB1
>
> Were you testing to Samba with SMB1?
As per my cover letter, these are the settings I used:
Tested with Samba with all SMB versions, with mfsymlinks in the
mount options, 'server min protocol = NT1' and 'server signing =
required' in smb.conf, and doing a simple file data and symlink
verification test. That seems to cover all the modified code paths.
This was with Samba 4.23.1.
I just tried 'server signing = mandatory' too (just in case that's
different from "required"), and I still get the error.
Anyway, it's not related to my patchset, as it happens regardless of it.
I also tried some much older kernels, and it still happens there too.
- Eric
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 0/8] smb: client: More crypto library conversions
2025-10-12 1:57 [PATCH 0/8] smb: client: More crypto library conversions Eric Biggers
` (9 preceding siblings ...)
2025-10-14 3:42 ` Eric Biggers
@ 2025-10-14 7:55 ` Ard Biesheuvel
10 siblings, 0 replies; 15+ messages in thread
From: Ard Biesheuvel @ 2025-10-14 7:55 UTC (permalink / raw)
To: Eric Biggers
Cc: linux-cifs, Steve French, samba-technical, linux-crypto,
linux-kernel, Paulo Alcantara, Ronnie Sahlberg, Shyam Prasad N,
Tom Talpey, Bharath SM
On Sun, 12 Oct 2025 at 03:59, Eric Biggers <ebiggers@kernel.org> wrote:
>
> This series converts fs/smb/client/ to access SHA-512, HMAC-SHA256, MD5,
> and HMAC-MD5 using the library APIs instead of crypto_shash.
>
> This simplifies the code significantly. It also slightly improves
> performance, as it eliminates unnecessary overhead.
>
> Tested with Samba with all SMB versions, with mfsymlinks in the mount
> options, 'server min protocol = NT1' and 'server signing = required' in
> smb.conf, and doing a simple file data and symlink verification test.
> That seems to cover all the modified code paths.
>
> However, with SMB 1.0 I get "CIFS: VFS: SMB signature verification
> returned error = -13", regardless of whether this series is applied or
> not. Presumably, testing that case requires some other setting I
> couldn't find.
>
> Regardless, these are straightforward conversions and all the actual
> crypto is exactly the same as before, as far as I can tell.
>
> Eric Biggers (8):
> smb: client: Use SHA-512 library for SMB3.1.1 preauth hash
> smb: client: Use HMAC-SHA256 library for key generation
> smb: client: Use HMAC-SHA256 library for SMB2 signature calculation
> smb: client: Use MD5 library for M-F symlink hashing
> smb: client: Use MD5 library for SMB1 signature calculation
> smb: client: Use HMAC-MD5 library for NTLMv2
> smb: client: Remove obsolete crypto_shash allocations
> smb: client: Consolidate cmac(aes) shash allocation
>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
^ permalink raw reply [flat|nested] 15+ messages in thread