Linux cryptographic layer development
 help / color / mirror / Atom feed
* [PATCH 0/3] ksmbd: More crypto library conversions
@ 2025-10-14 23:17 Eric Biggers
  2025-10-14 23:17 ` [PATCH 1/3] ksmbd: Use SHA-512 library for SMB3.1.1 preauth hash Eric Biggers
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Eric Biggers @ 2025-10-14 23:17 UTC (permalink / raw)
  To: linux-cifs, Namjae Jeon, Steve French
  Cc: Sergey Senozhatsky, Tom Talpey, linux-crypto, linux-kernel,
	Eric Biggers

This series converts fs/smb/server/ to access SHA-512, HMAC-SHA256, 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.  I haven't done
server-specific benchmarks, but you can get an idea of what to expect by
looking at the numbers I gave for the similar client-side series:
https://lore.kernel.org/linux-cifs/20251014034230.GC2763@sol/

No change in behavior intended.  All the crypto computations should be
the same as before.  I haven't tested this series (I did test the
similar client-side series), but everything should still work.

Eric Biggers (3):
  ksmbd: Use SHA-512 library for SMB3.1.1 preauth hash
  ksmbd: Use HMAC-SHA256 library for message signing and key generation
  ksmbd: Use HMAC-MD5 library for NTLMv2

 fs/smb/server/Kconfig      |   6 +-
 fs/smb/server/auth.c       | 390 +++++++------------------------------
 fs/smb/server/auth.h       |  10 +-
 fs/smb/server/crypto_ctx.c |  24 ---
 fs/smb/server/crypto_ctx.h |  15 +-
 fs/smb/server/server.c     |   4 -
 fs/smb/server/smb2pdu.c    |  26 +--
 fs/smb/server/smb_common.h |   2 +-
 8 files changed, 87 insertions(+), 390 deletions(-)


base-commit: 3a8660878839faadb4f1a6dd72c3179c1df56787
-- 
2.51.0


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

* [PATCH 1/3] ksmbd: Use SHA-512 library for SMB3.1.1 preauth hash
  2025-10-14 23:17 [PATCH 0/3] ksmbd: More crypto library conversions Eric Biggers
@ 2025-10-14 23:17 ` Eric Biggers
  2025-10-14 23:17 ` [PATCH 2/3] ksmbd: Use HMAC-SHA256 library for message signing and key generation Eric Biggers
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Eric Biggers @ 2025-10-14 23:17 UTC (permalink / raw)
  To: linux-cifs, Namjae Jeon, Steve French
  Cc: Sergey Senozhatsky, Tom Talpey, linux-crypto, linux-kernel,
	Eric Biggers

Convert ksmbd_gen_preauth_integrity_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.

Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
 fs/smb/server/Kconfig      |  2 +-
 fs/smb/server/auth.c       | 41 +++++++-------------------------------
 fs/smb/server/crypto_ctx.c |  8 --------
 fs/smb/server/crypto_ctx.h |  4 ----
 fs/smb/server/server.c     |  1 -
 5 files changed, 8 insertions(+), 48 deletions(-)

diff --git a/fs/smb/server/Kconfig b/fs/smb/server/Kconfig
index 098cac98d31e6..d5f3a417246d4 100644
--- a/fs/smb/server/Kconfig
+++ b/fs/smb/server/Kconfig
@@ -11,13 +11,13 @@ config SMB_SERVER
 	select CRYPTO_HMAC
 	select CRYPTO_ECB
 	select CRYPTO_LIB_ARC4
 	select CRYPTO_LIB_DES
 	select CRYPTO_LIB_SHA256
+	select CRYPTO_LIB_SHA512
 	select CRYPTO_SHA256
 	select CRYPTO_CMAC
-	select CRYPTO_SHA512
 	select CRYPTO_AEAD2
 	select CRYPTO_CCM
 	select CRYPTO_GCM
 	select ASN1
 	select OID_REGISTRY
diff --git a/fs/smb/server/auth.c b/fs/smb/server/auth.c
index b4020bb55a268..b7f2feede221f 100644
--- a/fs/smb/server/auth.c
+++ b/fs/smb/server/auth.c
@@ -11,10 +11,11 @@
 #include <linux/writeback.h>
 #include <linux/uio.h>
 #include <linux/xattr.h>
 #include <crypto/hash.h>
 #include <crypto/aead.h>
+#include <crypto/sha2.h>
 #include <linux/random.h>
 #include <linux/scatterlist.h>
 
 #include "auth.h"
 #include "glob.h"
@@ -932,52 +933,24 @@ int ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn *conn,
 }
 
 int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
 				     __u8 *pi_hash)
 {
-	int rc;
 	struct smb2_hdr *rcv_hdr = smb2_get_msg(buf);
 	char *all_bytes_msg = (char *)&rcv_hdr->ProtocolId;
 	int msg_size = get_rfc1002_len(buf);
-	struct ksmbd_crypto_ctx *ctx = NULL;
+	struct sha512_ctx sha_ctx;
 
 	if (conn->preauth_info->Preauth_HashId !=
 	    SMB2_PREAUTH_INTEGRITY_SHA512)
 		return -EINVAL;
 
-	ctx = ksmbd_crypto_ctx_find_sha512();
-	if (!ctx) {
-		ksmbd_debug(AUTH, "could not alloc sha512\n");
-		return -ENOMEM;
-	}
-
-	rc = crypto_shash_init(CRYPTO_SHA512(ctx));
-	if (rc) {
-		ksmbd_debug(AUTH, "could not init shashn");
-		goto out;
-	}
-
-	rc = crypto_shash_update(CRYPTO_SHA512(ctx), pi_hash, 64);
-	if (rc) {
-		ksmbd_debug(AUTH, "could not update with n\n");
-		goto out;
-	}
-
-	rc = crypto_shash_update(CRYPTO_SHA512(ctx), all_bytes_msg, msg_size);
-	if (rc) {
-		ksmbd_debug(AUTH, "could not update with n\n");
-		goto out;
-	}
-
-	rc = crypto_shash_final(CRYPTO_SHA512(ctx), pi_hash);
-	if (rc) {
-		ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
-		goto out;
-	}
-out:
-	ksmbd_release_crypto_ctx(ctx);
-	return rc;
+	sha512_init(&sha_ctx);
+	sha512_update(&sha_ctx, pi_hash, 64);
+	sha512_update(&sha_ctx, all_bytes_msg, msg_size);
+	sha512_final(&sha_ctx, pi_hash);
+	return 0;
 }
 
 static int ksmbd_get_encryption_key(struct ksmbd_work *work, __u64 ses_id,
 				    int enc, u8 *key)
 {
diff --git a/fs/smb/server/crypto_ctx.c b/fs/smb/server/crypto_ctx.c
index 80bd68c8635ea..1de41b10528bc 100644
--- a/fs/smb/server/crypto_ctx.c
+++ b/fs/smb/server/crypto_ctx.c
@@ -73,13 +73,10 @@ static struct shash_desc *alloc_shash_desc(int id)
 		tfm = crypto_alloc_shash("hmac(sha256)", 0, 0);
 		break;
 	case CRYPTO_SHASH_CMACAES:
 		tfm = crypto_alloc_shash("cmac(aes)", 0, 0);
 		break;
-	case CRYPTO_SHASH_SHA512:
-		tfm = crypto_alloc_shash("sha512", 0, 0);
-		break;
 	default:
 		return NULL;
 	}
 
 	if (IS_ERR(tfm))
@@ -193,15 +190,10 @@ struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_hmacsha256(void)
 struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_cmacaes(void)
 {
 	return ____crypto_shash_ctx_find(CRYPTO_SHASH_CMACAES);
 }
 
-struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_sha512(void)
-{
-	return ____crypto_shash_ctx_find(CRYPTO_SHASH_SHA512);
-}
-
 static struct ksmbd_crypto_ctx *____crypto_aead_ctx_find(int id)
 {
 	struct ksmbd_crypto_ctx *ctx;
 
 	if (id >= CRYPTO_AEAD_MAX)
diff --git a/fs/smb/server/crypto_ctx.h b/fs/smb/server/crypto_ctx.h
index ac64801d52d38..4e8954acd8b8b 100644
--- a/fs/smb/server/crypto_ctx.h
+++ b/fs/smb/server/crypto_ctx.h
@@ -11,11 +11,10 @@
 
 enum {
 	CRYPTO_SHASH_HMACMD5	= 0,
 	CRYPTO_SHASH_HMACSHA256,
 	CRYPTO_SHASH_CMACAES,
-	CRYPTO_SHASH_SHA512,
 	CRYPTO_SHASH_MAX,
 };
 
 enum {
 	CRYPTO_AEAD_AES_GCM = 16,
@@ -36,26 +35,23 @@ struct ksmbd_crypto_ctx {
 };
 
 #define CRYPTO_HMACMD5(c)	((c)->desc[CRYPTO_SHASH_HMACMD5])
 #define CRYPTO_HMACSHA256(c)	((c)->desc[CRYPTO_SHASH_HMACSHA256])
 #define CRYPTO_CMACAES(c)	((c)->desc[CRYPTO_SHASH_CMACAES])
-#define CRYPTO_SHA512(c)	((c)->desc[CRYPTO_SHASH_SHA512])
 
 #define CRYPTO_HMACMD5_TFM(c)	((c)->desc[CRYPTO_SHASH_HMACMD5]->tfm)
 #define CRYPTO_HMACSHA256_TFM(c)\
 				((c)->desc[CRYPTO_SHASH_HMACSHA256]->tfm)
 #define CRYPTO_CMACAES_TFM(c)	((c)->desc[CRYPTO_SHASH_CMACAES]->tfm)
-#define CRYPTO_SHA512_TFM(c)	((c)->desc[CRYPTO_SHASH_SHA512]->tfm)
 
 #define CRYPTO_GCM(c)		((c)->ccmaes[CRYPTO_AEAD_AES_GCM])
 #define CRYPTO_CCM(c)		((c)->ccmaes[CRYPTO_AEAD_AES_CCM])
 
 void ksmbd_release_crypto_ctx(struct ksmbd_crypto_ctx *ctx);
 struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_hmacmd5(void);
 struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_hmacsha256(void);
 struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_cmacaes(void);
-struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_sha512(void);
 struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_gcm(void);
 struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_ccm(void);
 void ksmbd_crypto_destroy(void);
 int ksmbd_crypto_create(void);
 
diff --git a/fs/smb/server/server.c b/fs/smb/server/server.c
index 40420544cc25a..51e2aee2a6985 100644
--- a/fs/smb/server/server.c
+++ b/fs/smb/server/server.c
@@ -626,11 +626,10 @@ MODULE_SOFTDEP("pre: hmac");
 MODULE_SOFTDEP("pre: md5");
 MODULE_SOFTDEP("pre: nls");
 MODULE_SOFTDEP("pre: aes");
 MODULE_SOFTDEP("pre: cmac");
 MODULE_SOFTDEP("pre: sha256");
-MODULE_SOFTDEP("pre: sha512");
 MODULE_SOFTDEP("pre: aead2");
 MODULE_SOFTDEP("pre: ccm");
 MODULE_SOFTDEP("pre: gcm");
 module_init(ksmbd_server_init)
 module_exit(ksmbd_server_exit)
-- 
2.51.0


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

* [PATCH 2/3] ksmbd: Use HMAC-SHA256 library for message signing and key generation
  2025-10-14 23:17 [PATCH 0/3] ksmbd: More crypto library conversions Eric Biggers
  2025-10-14 23:17 ` [PATCH 1/3] ksmbd: Use SHA-512 library for SMB3.1.1 preauth hash Eric Biggers
@ 2025-10-14 23:17 ` Eric Biggers
  2025-10-16  5:00   ` Namjae Jeon
  2025-10-14 23:17 ` [PATCH 3/3] ksmbd: Use HMAC-MD5 library for NTLMv2 Eric Biggers
  2025-10-16  5:03 ` [PATCH 0/3] ksmbd: More crypto library conversions Namjae Jeon
  3 siblings, 1 reply; 7+ messages in thread
From: Eric Biggers @ 2025-10-14 23:17 UTC (permalink / raw)
  To: linux-cifs, Namjae Jeon, Steve French
  Cc: Sergey Senozhatsky, Tom Talpey, linux-crypto, linux-kernel,
	Eric Biggers

Convert ksmbd_sign_smb2_pdu() and 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.

Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
 fs/smb/server/Kconfig      |   1 -
 fs/smb/server/auth.c       | 176 ++++++++-----------------------------
 fs/smb/server/auth.h       |  10 +--
 fs/smb/server/crypto_ctx.c |   8 --
 fs/smb/server/crypto_ctx.h |   5 --
 fs/smb/server/server.c     |   1 -
 fs/smb/server/smb2pdu.c    |  26 ++----
 fs/smb/server/smb_common.h |   2 +-
 8 files changed, 52 insertions(+), 177 deletions(-)

diff --git a/fs/smb/server/Kconfig b/fs/smb/server/Kconfig
index d5f3a417246d4..788104cfb082f 100644
--- a/fs/smb/server/Kconfig
+++ b/fs/smb/server/Kconfig
@@ -12,11 +12,10 @@ config SMB_SERVER
 	select CRYPTO_ECB
 	select CRYPTO_LIB_ARC4
 	select CRYPTO_LIB_DES
 	select CRYPTO_LIB_SHA256
 	select CRYPTO_LIB_SHA512
-	select CRYPTO_SHA256
 	select CRYPTO_CMAC
 	select CRYPTO_AEAD2
 	select CRYPTO_CCM
 	select CRYPTO_GCM
 	select ASN1
diff --git a/fs/smb/server/auth.c b/fs/smb/server/auth.c
index b7f2feede221f..54918f43d2c6b 100644
--- a/fs/smb/server/auth.c
+++ b/fs/smb/server/auth.c
@@ -588,50 +588,20 @@ int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
  * @iov:        buffer iov array
  * @n_vec:	number of iovecs
  * @sig:	signature value generated for client request packet
  *
  */
-int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
-			int n_vec, char *sig)
+void ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
+			 int n_vec, char *sig)
 {
-	struct ksmbd_crypto_ctx *ctx;
-	int rc, i;
-
-	ctx = ksmbd_crypto_ctx_find_hmacsha256();
-	if (!ctx) {
-		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
-		return -ENOMEM;
-	}
+	struct hmac_sha256_ctx ctx;
+	int i;
 
-	rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
-				 key,
-				 SMB2_NTLMV2_SESSKEY_SIZE);
-	if (rc)
-		goto out;
-
-	rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
-	if (rc) {
-		ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
-		goto out;
-	}
-
-	for (i = 0; i < n_vec; i++) {
-		rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
-					 iov[i].iov_base,
-					 iov[i].iov_len);
-		if (rc) {
-			ksmbd_debug(AUTH, "hmacsha256 update error %d\n", rc);
-			goto out;
-		}
-	}
-
-	rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), sig);
-	if (rc)
-		ksmbd_debug(AUTH, "hmacsha256 generation error %d\n", rc);
-out:
-	ksmbd_release_crypto_ctx(ctx);
-	return rc;
+	hmac_sha256_init_usingrawkey(&ctx, key, SMB2_NTLMV2_SESSKEY_SIZE);
+	for (i = 0; i < n_vec; i++)
+		hmac_sha256_update(&ctx, iov[i].iov_base, iov[i].iov_len);
+	hmac_sha256_final(&ctx, sig);
 }
 
 /**
  * ksmbd_sign_smb3_pdu() - function to generate packet signing
  * @conn:	connection
@@ -687,102 +657,43 @@ struct derivation {
 	struct kvec label;
 	struct kvec context;
 	bool binding;
 };
 
-static int generate_key(struct ksmbd_conn *conn, struct ksmbd_session *sess,
-			struct kvec label, struct kvec context, __u8 *key,
-			unsigned int key_size)
+static void generate_key(struct ksmbd_conn *conn, struct ksmbd_session *sess,
+			 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};
-	int rc;
 	unsigned char prfhash[SMB2_HMACSHA256_SIZE];
-	unsigned char *hashptr = prfhash;
-	struct ksmbd_crypto_ctx *ctx;
-
-	memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
-	memset(key, 0x0, key_size);
-
-	ctx = ksmbd_crypto_ctx_find_hmacsha256();
-	if (!ctx) {
-		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
-		return -ENOMEM;
-	}
+	struct hmac_sha256_ctx ctx;
 
-	rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
-				 sess->sess_key,
-				 SMB2_NTLMV2_SESSKEY_SIZE);
-	if (rc)
-		goto smb3signkey_ret;
-
-	rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
-	if (rc) {
-		ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
-		goto smb3signkey_ret;
-	}
-
-	rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), i, 4);
-	if (rc) {
-		ksmbd_debug(AUTH, "could not update with n\n");
-		goto smb3signkey_ret;
-	}
-
-	rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
-				 label.iov_base,
-				 label.iov_len);
-	if (rc) {
-		ksmbd_debug(AUTH, "could not update with label\n");
-		goto smb3signkey_ret;
-	}
-
-	rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), &zero, 1);
-	if (rc) {
-		ksmbd_debug(AUTH, "could not update with zero\n");
-		goto smb3signkey_ret;
-	}
-
-	rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
-				 context.iov_base,
-				 context.iov_len);
-	if (rc) {
-		ksmbd_debug(AUTH, "could not update with context\n");
-		goto smb3signkey_ret;
-	}
+	hmac_sha256_init_usingrawkey(&ctx, sess->sess_key,
+				     SMB2_NTLMV2_SESSKEY_SIZE);
+	hmac_sha256_update(&ctx, i, 4);
+	hmac_sha256_update(&ctx, label.iov_base, label.iov_len);
+	hmac_sha256_update(&ctx, &zero, 1);
+	hmac_sha256_update(&ctx, context.iov_base, context.iov_len);
 
 	if (key_size == SMB3_ENC_DEC_KEY_SIZE &&
 	    (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
 	     conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
-		rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L256, 4);
+		hmac_sha256_update(&ctx, L256, 4);
 	else
-		rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L128, 4);
-	if (rc) {
-		ksmbd_debug(AUTH, "could not update with L\n");
-		goto smb3signkey_ret;
-	}
+		hmac_sha256_update(&ctx, L128, 4);
 
-	rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), hashptr);
-	if (rc) {
-		ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n",
-			    rc);
-		goto smb3signkey_ret;
-	}
-
-	memcpy(key, hashptr, key_size);
-
-smb3signkey_ret:
-	ksmbd_release_crypto_ctx(ctx);
-	return rc;
+	hmac_sha256_final(&ctx, prfhash);
+	memcpy(key, prfhash, key_size);
 }
 
 static int generate_smb3signingkey(struct ksmbd_session *sess,
 				   struct ksmbd_conn *conn,
 				   const struct derivation *signing)
 {
-	int rc;
 	struct channel *chann;
 	char *key;
 
 	chann = lookup_chann_list(sess, conn);
 	if (!chann)
@@ -791,14 +702,12 @@ static int generate_smb3signingkey(struct ksmbd_session *sess,
 	if (conn->dialect >= SMB30_PROT_ID && signing->binding)
 		key = chann->smb3signingkey;
 	else
 		key = sess->smb3signingkey;
 
-	rc = generate_key(conn, sess, signing->label, signing->context, key,
-			  SMB3_SIGN_KEY_SIZE);
-	if (rc)
-		return rc;
+	generate_key(conn, sess, signing->label, signing->context, key,
+		     SMB3_SIGN_KEY_SIZE);
 
 	if (!(conn->dialect >= SMB30_PROT_ID && signing->binding))
 		memcpy(chann->smb3signingkey, key, SMB3_SIGN_KEY_SIZE);
 
 	ksmbd_debug(AUTH, "dumping generated AES signing keys\n");
@@ -850,27 +759,21 @@ int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess,
 struct derivation_twin {
 	struct derivation encryption;
 	struct derivation decryption;
 };
 
-static int generate_smb3encryptionkey(struct ksmbd_conn *conn,
-				      struct ksmbd_session *sess,
-				      const struct derivation_twin *ptwin)
+static void generate_smb3encryptionkey(struct ksmbd_conn *conn,
+				       struct ksmbd_session *sess,
+				       const struct derivation_twin *ptwin)
 {
-	int rc;
+	generate_key(conn, sess, ptwin->encryption.label,
+		     ptwin->encryption.context, sess->smb3encryptionkey,
+		     SMB3_ENC_DEC_KEY_SIZE);
 
-	rc = generate_key(conn, sess, ptwin->encryption.label,
-			  ptwin->encryption.context, sess->smb3encryptionkey,
-			  SMB3_ENC_DEC_KEY_SIZE);
-	if (rc)
-		return rc;
-
-	rc = generate_key(conn, sess, ptwin->decryption.label,
-			  ptwin->decryption.context,
-			  sess->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE);
-	if (rc)
-		return rc;
+	generate_key(conn, sess, ptwin->decryption.label,
+		     ptwin->decryption.context,
+		     sess->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE);
 
 	ksmbd_debug(AUTH, "dumping generated AES encryption keys\n");
 	ksmbd_debug(AUTH, "Cipher type   %d\n", conn->cipher_type);
 	ksmbd_debug(AUTH, "Session Id    %llu\n", sess->id);
 	ksmbd_debug(AUTH, "Session Key   %*ph\n",
@@ -885,15 +788,14 @@ static int generate_smb3encryptionkey(struct ksmbd_conn *conn,
 		ksmbd_debug(AUTH, "ServerIn Key  %*ph\n",
 			    SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3encryptionkey);
 		ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
 			    SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3decryptionkey);
 	}
-	return 0;
 }
 
-int ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn *conn,
-				  struct ksmbd_session *sess)
+void ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn *conn,
+				   struct ksmbd_session *sess)
 {
 	struct derivation_twin twin;
 	struct derivation *d;
 
 	d = &twin.encryption;
@@ -906,15 +808,15 @@ int ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn *conn,
 	d->label.iov_base = "SMB2AESCCM";
 	d->label.iov_len = 11;
 	d->context.iov_base = "ServerIn ";
 	d->context.iov_len = 10;
 
-	return generate_smb3encryptionkey(conn, sess, &twin);
+	generate_smb3encryptionkey(conn, sess, &twin);
 }
 
-int ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn *conn,
-				   struct ksmbd_session *sess)
+void ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn *conn,
+				    struct ksmbd_session *sess)
 {
 	struct derivation_twin twin;
 	struct derivation *d;
 
 	d = &twin.encryption;
@@ -927,11 +829,11 @@ int ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn *conn,
 	d->label.iov_base = "SMBC2SCipherKey";
 	d->label.iov_len = 16;
 	d->context.iov_base = sess->Preauth_HashValue;
 	d->context.iov_len = 64;
 
-	return generate_smb3encryptionkey(conn, sess, &twin);
+	generate_smb3encryptionkey(conn, sess, &twin);
 }
 
 int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
 				     __u8 *pi_hash)
 {
diff --git a/fs/smb/server/auth.h b/fs/smb/server/auth.h
index 6879a1bd1b91f..6d351d61b0e57 100644
--- a/fs/smb/server/auth.h
+++ b/fs/smb/server/auth.h
@@ -50,20 +50,20 @@ int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
 unsigned int
 ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
 				   struct ksmbd_conn *conn);
 int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
 			    int in_len,	char *out_blob, int *out_len);
-int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
-			int n_vec, char *sig);
+void ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
+			 int n_vec, char *sig);
 int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
 			int n_vec, char *sig);
 int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess,
 			       struct ksmbd_conn *conn);
 int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess,
 				struct ksmbd_conn *conn);
-int ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn *conn,
-				  struct ksmbd_session *sess);
-int ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn *conn,
+void ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn *conn,
 				   struct ksmbd_session *sess);
+void ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn *conn,
+				    struct ksmbd_session *sess);
 int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
 				     __u8 *pi_hash);
 #endif
diff --git a/fs/smb/server/crypto_ctx.c b/fs/smb/server/crypto_ctx.c
index 1de41b10528bc..a5ec22ba8ae37 100644
--- a/fs/smb/server/crypto_ctx.c
+++ b/fs/smb/server/crypto_ctx.c
@@ -67,13 +67,10 @@ static struct shash_desc *alloc_shash_desc(int id)
 
 	switch (id) {
 	case CRYPTO_SHASH_HMACMD5:
 		tfm = crypto_alloc_shash("hmac(md5)", 0, 0);
 		break;
-	case CRYPTO_SHASH_HMACSHA256:
-		tfm = crypto_alloc_shash("hmac(sha256)", 0, 0);
-		break;
 	case CRYPTO_SHASH_CMACAES:
 		tfm = crypto_alloc_shash("cmac(aes)", 0, 0);
 		break;
 	default:
 		return NULL;
@@ -180,15 +177,10 @@ static struct ksmbd_crypto_ctx *____crypto_shash_ctx_find(int id)
 struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_hmacmd5(void)
 {
 	return ____crypto_shash_ctx_find(CRYPTO_SHASH_HMACMD5);
 }
 
-struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_hmacsha256(void)
-{
-	return ____crypto_shash_ctx_find(CRYPTO_SHASH_HMACSHA256);
-}
-
 struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_cmacaes(void)
 {
 	return ____crypto_shash_ctx_find(CRYPTO_SHASH_CMACAES);
 }
 
diff --git a/fs/smb/server/crypto_ctx.h b/fs/smb/server/crypto_ctx.h
index 4e8954acd8b8b..c571d65a16f3e 100644
--- a/fs/smb/server/crypto_ctx.h
+++ b/fs/smb/server/crypto_ctx.h
@@ -9,11 +9,10 @@
 #include <crypto/hash.h>
 #include <crypto/aead.h>
 
 enum {
 	CRYPTO_SHASH_HMACMD5	= 0,
-	CRYPTO_SHASH_HMACSHA256,
 	CRYPTO_SHASH_CMACAES,
 	CRYPTO_SHASH_MAX,
 };
 
 enum {
@@ -33,24 +32,20 @@ struct ksmbd_crypto_ctx {
 	struct shash_desc		*desc[CRYPTO_SHASH_MAX];
 	struct crypto_aead		*ccmaes[CRYPTO_AEAD_MAX];
 };
 
 #define CRYPTO_HMACMD5(c)	((c)->desc[CRYPTO_SHASH_HMACMD5])
-#define CRYPTO_HMACSHA256(c)	((c)->desc[CRYPTO_SHASH_HMACSHA256])
 #define CRYPTO_CMACAES(c)	((c)->desc[CRYPTO_SHASH_CMACAES])
 
 #define CRYPTO_HMACMD5_TFM(c)	((c)->desc[CRYPTO_SHASH_HMACMD5]->tfm)
-#define CRYPTO_HMACSHA256_TFM(c)\
-				((c)->desc[CRYPTO_SHASH_HMACSHA256]->tfm)
 #define CRYPTO_CMACAES_TFM(c)	((c)->desc[CRYPTO_SHASH_CMACAES]->tfm)
 
 #define CRYPTO_GCM(c)		((c)->ccmaes[CRYPTO_AEAD_AES_GCM])
 #define CRYPTO_CCM(c)		((c)->ccmaes[CRYPTO_AEAD_AES_CCM])
 
 void ksmbd_release_crypto_ctx(struct ksmbd_crypto_ctx *ctx);
 struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_hmacmd5(void);
-struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_hmacsha256(void);
 struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_cmacaes(void);
 struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_gcm(void);
 struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_ccm(void);
 void ksmbd_crypto_destroy(void);
 int ksmbd_crypto_create(void);
diff --git a/fs/smb/server/server.c b/fs/smb/server/server.c
index 51e2aee2a6985..8bce97633e01a 100644
--- a/fs/smb/server/server.c
+++ b/fs/smb/server/server.c
@@ -625,11 +625,10 @@ MODULE_SOFTDEP("pre: ecb");
 MODULE_SOFTDEP("pre: hmac");
 MODULE_SOFTDEP("pre: md5");
 MODULE_SOFTDEP("pre: nls");
 MODULE_SOFTDEP("pre: aes");
 MODULE_SOFTDEP("pre: cmac");
-MODULE_SOFTDEP("pre: sha256");
 MODULE_SOFTDEP("pre: aead2");
 MODULE_SOFTDEP("pre: ccm");
 MODULE_SOFTDEP("pre: gcm");
 module_init(ksmbd_server_init)
 module_exit(ksmbd_server_exit)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index ab1d45fcebdef..b315b07bc4043 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -1536,16 +1536,11 @@ static int ntlm_authenticate(struct ksmbd_work *work,
 	    (req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
 		sess->sign = true;
 
 	if (smb3_encryption_negotiated(conn) &&
 			!(req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) {
-		rc = conn->ops->generate_encryptionkey(conn, sess);
-		if (rc) {
-			ksmbd_debug(SMB,
-					"SMB3 encryption key generation failed\n");
-			return -EINVAL;
-		}
+		conn->ops->generate_encryptionkey(conn, sess);
 		sess->enc = true;
 		if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION)
 			rsp->SessionFlags = SMB2_SESSION_FLAG_ENCRYPT_DATA_LE;
 		/*
 		 * signing is disable if encryption is enable
@@ -1638,16 +1633,11 @@ static int krb5_authenticate(struct ksmbd_work *work,
 	    (req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
 		sess->sign = true;
 
 	if (smb3_encryption_negotiated(conn) &&
 	    !(req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) {
-		retval = conn->ops->generate_encryptionkey(conn, sess);
-		if (retval) {
-			ksmbd_debug(SMB,
-				    "SMB3 encryption key generation failed\n");
-			return -EINVAL;
-		}
+		conn->ops->generate_encryptionkey(conn, sess);
 		sess->enc = true;
 		if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION)
 			rsp->SessionFlags = SMB2_SESSION_FLAG_ENCRYPT_DATA_LE;
 		sess->sign = false;
 	}
@@ -8850,13 +8840,12 @@ int smb2_check_sign_req(struct ksmbd_work *work)
 	memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE);
 
 	iov[0].iov_base = (char *)&hdr->ProtocolId;
 	iov[0].iov_len = len;
 
-	if (ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, 1,
-				signature))
-		return 0;
+	ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, 1,
+			    signature);
 
 	if (memcmp(signature, signature_req, SMB2_SIGNATURE_SIZE)) {
 		pr_err("bad smb2 signature\n");
 		return 0;
 	}
@@ -8876,22 +8865,21 @@ void smb2_set_sign_rsp(struct ksmbd_work *work)
 	struct kvec *iov;
 	int n_vec = 1;
 
 	hdr = ksmbd_resp_buf_curr(work);
 	hdr->Flags |= SMB2_FLAGS_SIGNED;
-	memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE);
 
 	if (hdr->Command == SMB2_READ) {
 		iov = &work->iov[work->iov_idx - 1];
 		n_vec++;
 	} else {
 		iov = &work->iov[work->iov_idx];
 	}
 
-	if (!ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, n_vec,
-				 signature))
-		memcpy(hdr->Signature, signature, SMB2_SIGNATURE_SIZE);
+	ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, n_vec,
+			    signature);
+	memcpy(hdr->Signature, signature, SMB2_SIGNATURE_SIZE);
 }
 
 /**
  * smb3_check_sign_req() - handler for req packet sign processing
  * @work:   smb work containing notify command buffer
diff --git a/fs/smb/server/smb_common.h b/fs/smb/server/smb_common.h
index d742ba754348b..b6e0659a7e414 100644
--- a/fs/smb/server/smb_common.h
+++ b/fs/smb/server/smb_common.h
@@ -407,11 +407,11 @@ struct smb_version_ops {
 	int (*get_ksmbd_tcon)(struct ksmbd_work *work);
 	bool (*is_sign_req)(struct ksmbd_work *work, unsigned int command);
 	int (*check_sign_req)(struct ksmbd_work *work);
 	void (*set_sign_rsp)(struct ksmbd_work *work);
 	int (*generate_signingkey)(struct ksmbd_session *sess, struct ksmbd_conn *conn);
-	int (*generate_encryptionkey)(struct ksmbd_conn *conn, struct ksmbd_session *sess);
+	void (*generate_encryptionkey)(struct ksmbd_conn *conn, struct ksmbd_session *sess);
 	bool (*is_transform_hdr)(void *buf);
 	int (*decrypt_req)(struct ksmbd_work *work);
 	int (*encrypt_resp)(struct ksmbd_work *work);
 };
 
-- 
2.51.0


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

* [PATCH 3/3] ksmbd: Use HMAC-MD5 library for NTLMv2
  2025-10-14 23:17 [PATCH 0/3] ksmbd: More crypto library conversions Eric Biggers
  2025-10-14 23:17 ` [PATCH 1/3] ksmbd: Use SHA-512 library for SMB3.1.1 preauth hash Eric Biggers
  2025-10-14 23:17 ` [PATCH 2/3] ksmbd: Use HMAC-SHA256 library for message signing and key generation Eric Biggers
@ 2025-10-14 23:17 ` Eric Biggers
  2025-10-16  5:03 ` [PATCH 0/3] ksmbd: More crypto library conversions Namjae Jeon
  3 siblings, 0 replies; 7+ messages in thread
From: Eric Biggers @ 2025-10-14 23:17 UTC (permalink / raw)
  To: linux-cifs, Namjae Jeon, Steve French
  Cc: Sergey Senozhatsky, Tom Talpey, linux-crypto, linux-kernel,
	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 ksmbd_auth_ntlmv2() check
fips_enabled itself.  Previously it relied on the error from
crypto_alloc_shash("hmac(md5)") being bubbled up.  I don't know for sure
that this is actually needed, but this preserves the existing behavior.

Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
 fs/smb/server/Kconfig      |   3 +-
 fs/smb/server/auth.c       | 173 ++++++-------------------------------
 fs/smb/server/crypto_ctx.c |   8 --
 fs/smb/server/crypto_ctx.h |   6 +-
 fs/smb/server/server.c     |   2 -
 5 files changed, 27 insertions(+), 165 deletions(-)

diff --git a/fs/smb/server/Kconfig b/fs/smb/server/Kconfig
index 788104cfb082f..2775162c535c6 100644
--- a/fs/smb/server/Kconfig
+++ b/fs/smb/server/Kconfig
@@ -5,15 +5,14 @@ config SMB_SERVER
 	depends on FILE_LOCKING
 	select NLS
 	select NLS_UTF8
 	select NLS_UCS2_UTILS
 	select CRYPTO
-	select CRYPTO_MD5
-	select CRYPTO_HMAC
 	select CRYPTO_ECB
 	select CRYPTO_LIB_ARC4
 	select CRYPTO_LIB_DES
+	select CRYPTO_LIB_MD5
 	select CRYPTO_LIB_SHA256
 	select CRYPTO_LIB_SHA512
 	select CRYPTO_CMAC
 	select CRYPTO_AEAD2
 	select CRYPTO_CCM
diff --git a/fs/smb/server/auth.c b/fs/smb/server/auth.c
index 54918f43d2c6b..f2767c4b51326 100644
--- a/fs/smb/server/auth.c
+++ b/fs/smb/server/auth.c
@@ -11,10 +11,11 @@
 #include <linux/writeback.h>
 #include <linux/uio.h>
 #include <linux/xattr.h>
 #include <crypto/hash.h>
 #include <crypto/aead.h>
+#include <crypto/md5.h>
 #include <crypto/sha2.h>
 #include <linux/random.h>
 #include <linux/scatterlist.h>
 
 #include "auth.h"
@@ -68,89 +69,20 @@ static char NEGOTIATE_GSS_HEADER[AUTH_GSS_LENGTH] = {
 void ksmbd_copy_gss_neg_header(void *buf)
 {
 	memcpy(buf, NEGOTIATE_GSS_HEADER, AUTH_GSS_LENGTH);
 }
 
-/**
- * ksmbd_gen_sess_key() - function to generate session key
- * @sess:	session of connection
- * @hash:	source hash value to be used for find session key
- * @hmac:	source hmac value to be used for finding session key
- *
- */
-static int ksmbd_gen_sess_key(struct ksmbd_session *sess, char *hash,
-			      char *hmac)
-{
-	struct ksmbd_crypto_ctx *ctx;
-	int rc;
-
-	ctx = ksmbd_crypto_ctx_find_hmacmd5();
-	if (!ctx) {
-		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
-		return -ENOMEM;
-	}
-
-	rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
-				 hash,
-				 CIFS_HMAC_MD5_HASH_SIZE);
-	if (rc) {
-		ksmbd_debug(AUTH, "hmacmd5 set key fail error %d\n", rc);
-		goto out;
-	}
-
-	rc = crypto_shash_init(CRYPTO_HMACMD5(ctx));
-	if (rc) {
-		ksmbd_debug(AUTH, "could not init hmacmd5 error %d\n", rc);
-		goto out;
-	}
-
-	rc = crypto_shash_update(CRYPTO_HMACMD5(ctx),
-				 hmac,
-				 SMB2_NTLMV2_SESSKEY_SIZE);
-	if (rc) {
-		ksmbd_debug(AUTH, "Could not update with response error %d\n", rc);
-		goto out;
-	}
-
-	rc = crypto_shash_final(CRYPTO_HMACMD5(ctx), sess->sess_key);
-	if (rc) {
-		ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n", rc);
-		goto out;
-	}
-
-out:
-	ksmbd_release_crypto_ctx(ctx);
-	return rc;
-}
-
 static int calc_ntlmv2_hash(struct ksmbd_conn *conn, struct ksmbd_session *sess,
 			    char *ntlmv2_hash, char *dname)
 {
 	int ret, len, conv_len;
 	wchar_t *domain = NULL;
 	__le16 *uniname = NULL;
-	struct ksmbd_crypto_ctx *ctx;
-
-	ctx = ksmbd_crypto_ctx_find_hmacmd5();
-	if (!ctx) {
-		ksmbd_debug(AUTH, "can't generate ntlmv2 hash\n");
-		return -ENOMEM;
-	}
+	struct hmac_md5_ctx ctx;
 
-	ret = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
-				  user_passkey(sess->user),
+	hmac_md5_init_usingrawkey(&ctx, user_passkey(sess->user),
 				  CIFS_ENCPWD_SIZE);
-	if (ret) {
-		ksmbd_debug(AUTH, "Could not set NT Hash as a key\n");
-		goto out;
-	}
-
-	ret = crypto_shash_init(CRYPTO_HMACMD5(ctx));
-	if (ret) {
-		ksmbd_debug(AUTH, "could not init hmacmd5\n");
-		goto out;
-	}
 
 	/* convert user_name to unicode */
 	len = strlen(user_name(sess->user));
 	uniname = kzalloc(2 + UNICODE_LEN(len), KSMBD_DEFAULT_GFP);
 	if (!uniname) {
@@ -164,17 +96,11 @@ static int calc_ntlmv2_hash(struct ksmbd_conn *conn, struct ksmbd_session *sess,
 		ret = -EINVAL;
 		goto out;
 	}
 	UniStrupr(uniname);
 
-	ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
-				  (char *)uniname,
-				  UNICODE_LEN(conv_len));
-	if (ret) {
-		ksmbd_debug(AUTH, "Could not update with user\n");
-		goto out;
-	}
+	hmac_md5_update(&ctx, (const u8 *)uniname, UNICODE_LEN(conv_len));
 
 	/* Convert domain name or conn name to unicode and uppercase */
 	len = strlen(dname);
 	domain = kzalloc(2 + UNICODE_LEN(len), KSMBD_DEFAULT_GFP);
 	if (!domain) {
@@ -187,25 +113,16 @@ static int calc_ntlmv2_hash(struct ksmbd_conn *conn, struct ksmbd_session *sess,
 	if (conv_len < 0 || conv_len > len) {
 		ret = -EINVAL;
 		goto out;
 	}
 
-	ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
-				  (char *)domain,
-				  UNICODE_LEN(conv_len));
-	if (ret) {
-		ksmbd_debug(AUTH, "Could not update with domain\n");
-		goto out;
-	}
-
-	ret = crypto_shash_final(CRYPTO_HMACMD5(ctx), ntlmv2_hash);
-	if (ret)
-		ksmbd_debug(AUTH, "Could not generate md5 hash\n");
+	hmac_md5_update(&ctx, (const u8 *)domain, UNICODE_LEN(conv_len));
+	hmac_md5_final(&ctx, ntlmv2_hash);
+	ret = 0;
 out:
 	kfree(uniname);
 	kfree(domain);
-	ksmbd_release_crypto_ctx(ctx);
 	return ret;
 }
 
 /**
  * ksmbd_auth_ntlmv2() - NTLMv2 authentication handler
@@ -222,77 +139,37 @@ int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
 		      struct ntlmv2_resp *ntlmv2, int blen, char *domain_name,
 		      char *cryptkey)
 {
 	char ntlmv2_hash[CIFS_ENCPWD_SIZE];
 	char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE];
-	struct ksmbd_crypto_ctx *ctx = NULL;
-	char *construct = NULL;
-	int rc, len;
-
-	rc = calc_ntlmv2_hash(conn, sess, ntlmv2_hash, domain_name);
-	if (rc) {
-		ksmbd_debug(AUTH, "could not get v2 hash rc %d\n", rc);
-		goto out;
-	}
-
-	ctx = ksmbd_crypto_ctx_find_hmacmd5();
-	if (!ctx) {
-		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
-		return -ENOMEM;
-	}
-
-	rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
-				 ntlmv2_hash,
-				 CIFS_HMAC_MD5_HASH_SIZE);
-	if (rc) {
-		ksmbd_debug(AUTH, "Could not set NTLMV2 Hash as a key\n");
-		goto out;
-	}
-
-	rc = crypto_shash_init(CRYPTO_HMACMD5(ctx));
-	if (rc) {
-		ksmbd_debug(AUTH, "Could not init hmacmd5\n");
-		goto out;
-	}
+	struct hmac_md5_ctx ctx;
+	int rc;
 
-	len = CIFS_CRYPTO_KEY_SIZE + blen;
-	construct = kzalloc(len, KSMBD_DEFAULT_GFP);
-	if (!construct) {
-		rc = -ENOMEM;
-		goto out;
+	if (fips_enabled) {
+		ksmbd_debug(AUTH, "NTLMv2 support is disabled due to FIPS\n");
+		return -EOPNOTSUPP;
 	}
 
-	memcpy(construct, cryptkey, CIFS_CRYPTO_KEY_SIZE);
-	memcpy(construct + CIFS_CRYPTO_KEY_SIZE, &ntlmv2->blob_signature, blen);
-
-	rc = crypto_shash_update(CRYPTO_HMACMD5(ctx), construct, len);
+	rc = calc_ntlmv2_hash(conn, sess, ntlmv2_hash, domain_name);
 	if (rc) {
-		ksmbd_debug(AUTH, "Could not update with response\n");
-		goto out;
+		ksmbd_debug(AUTH, "could not get v2 hash rc %d\n", rc);
+		return rc;
 	}
 
-	rc = crypto_shash_final(CRYPTO_HMACMD5(ctx), ntlmv2_rsp);
-	if (rc) {
-		ksmbd_debug(AUTH, "Could not generate md5 hash\n");
-		goto out;
-	}
-	ksmbd_release_crypto_ctx(ctx);
-	ctx = NULL;
+	hmac_md5_init_usingrawkey(&ctx, ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
+	hmac_md5_update(&ctx, cryptkey, CIFS_CRYPTO_KEY_SIZE);
+	hmac_md5_update(&ctx, (const u8 *)&ntlmv2->blob_signature, blen);
+	hmac_md5_final(&ctx, ntlmv2_rsp);
 
-	rc = ksmbd_gen_sess_key(sess, ntlmv2_hash, ntlmv2_rsp);
-	if (rc) {
-		ksmbd_debug(AUTH, "Could not generate sess key\n");
-		goto out;
-	}
+	/* Generate the session key */
+	hmac_md5_usingrawkey(ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE,
+			     ntlmv2_rsp, CIFS_HMAC_MD5_HASH_SIZE,
+			     sess->sess_key);
 
 	if (memcmp(ntlmv2->ntlmv2_hash, ntlmv2_rsp, CIFS_HMAC_MD5_HASH_SIZE) != 0)
-		rc = -EINVAL;
-out:
-	if (ctx)
-		ksmbd_release_crypto_ctx(ctx);
-	kfree(construct);
-	return rc;
+		return -EINVAL;
+	return 0;
 }
 
 /**
  * ksmbd_decode_ntlmssp_auth_blob() - helper function to construct
  * authenticate blob
diff --git a/fs/smb/server/crypto_ctx.c b/fs/smb/server/crypto_ctx.c
index a5ec22ba8ae37..fe29d186baf68 100644
--- a/fs/smb/server/crypto_ctx.c
+++ b/fs/smb/server/crypto_ctx.c
@@ -64,13 +64,10 @@ static struct shash_desc *alloc_shash_desc(int id)
 {
 	struct crypto_shash *tfm = NULL;
 	struct shash_desc *shash;
 
 	switch (id) {
-	case CRYPTO_SHASH_HMACMD5:
-		tfm = crypto_alloc_shash("hmac(md5)", 0, 0);
-		break;
 	case CRYPTO_SHASH_CMACAES:
 		tfm = crypto_alloc_shash("cmac(aes)", 0, 0);
 		break;
 	default:
 		return NULL;
@@ -172,15 +169,10 @@ static struct ksmbd_crypto_ctx *____crypto_shash_ctx_find(int id)
 		return ctx;
 	ksmbd_release_crypto_ctx(ctx);
 	return NULL;
 }
 
-struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_hmacmd5(void)
-{
-	return ____crypto_shash_ctx_find(CRYPTO_SHASH_HMACMD5);
-}
-
 struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_cmacaes(void)
 {
 	return ____crypto_shash_ctx_find(CRYPTO_SHASH_CMACAES);
 }
 
diff --git a/fs/smb/server/crypto_ctx.h b/fs/smb/server/crypto_ctx.h
index c571d65a16f3e..b9476ed520ae4 100644
--- a/fs/smb/server/crypto_ctx.h
+++ b/fs/smb/server/crypto_ctx.h
@@ -8,12 +8,11 @@
 
 #include <crypto/hash.h>
 #include <crypto/aead.h>
 
 enum {
-	CRYPTO_SHASH_HMACMD5	= 0,
-	CRYPTO_SHASH_CMACAES,
+	CRYPTO_SHASH_CMACAES	= 0,
 	CRYPTO_SHASH_MAX,
 };
 
 enum {
 	CRYPTO_AEAD_AES_GCM = 16,
@@ -31,21 +30,18 @@ struct ksmbd_crypto_ctx {
 
 	struct shash_desc		*desc[CRYPTO_SHASH_MAX];
 	struct crypto_aead		*ccmaes[CRYPTO_AEAD_MAX];
 };
 
-#define CRYPTO_HMACMD5(c)	((c)->desc[CRYPTO_SHASH_HMACMD5])
 #define CRYPTO_CMACAES(c)	((c)->desc[CRYPTO_SHASH_CMACAES])
 
-#define CRYPTO_HMACMD5_TFM(c)	((c)->desc[CRYPTO_SHASH_HMACMD5]->tfm)
 #define CRYPTO_CMACAES_TFM(c)	((c)->desc[CRYPTO_SHASH_CMACAES]->tfm)
 
 #define CRYPTO_GCM(c)		((c)->ccmaes[CRYPTO_AEAD_AES_GCM])
 #define CRYPTO_CCM(c)		((c)->ccmaes[CRYPTO_AEAD_AES_CCM])
 
 void ksmbd_release_crypto_ctx(struct ksmbd_crypto_ctx *ctx);
-struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_hmacmd5(void);
 struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_cmacaes(void);
 struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_gcm(void);
 struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_ccm(void);
 void ksmbd_crypto_destroy(void);
 int ksmbd_crypto_create(void);
diff --git a/fs/smb/server/server.c b/fs/smb/server/server.c
index 8bce97633e01a..3cea16050e4f7 100644
--- a/fs/smb/server/server.c
+++ b/fs/smb/server/server.c
@@ -620,12 +620,10 @@ static void __exit ksmbd_server_exit(void)
 
 MODULE_AUTHOR("Namjae Jeon <linkinjeon@kernel.org>");
 MODULE_DESCRIPTION("Linux kernel CIFS/SMB SERVER");
 MODULE_LICENSE("GPL");
 MODULE_SOFTDEP("pre: ecb");
-MODULE_SOFTDEP("pre: hmac");
-MODULE_SOFTDEP("pre: md5");
 MODULE_SOFTDEP("pre: nls");
 MODULE_SOFTDEP("pre: aes");
 MODULE_SOFTDEP("pre: cmac");
 MODULE_SOFTDEP("pre: aead2");
 MODULE_SOFTDEP("pre: ccm");
-- 
2.51.0


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

* Re: [PATCH 2/3] ksmbd: Use HMAC-SHA256 library for message signing and key generation
  2025-10-14 23:17 ` [PATCH 2/3] ksmbd: Use HMAC-SHA256 library for message signing and key generation Eric Biggers
@ 2025-10-16  5:00   ` Namjae Jeon
  2025-10-16 17:54     ` Eric Biggers
  0 siblings, 1 reply; 7+ messages in thread
From: Namjae Jeon @ 2025-10-16  5:00 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-cifs, Steve French, Sergey Senozhatsky, Tom Talpey,
	linux-crypto, linux-kernel

[snip]
> @@ -8876,22 +8865,21 @@ void smb2_set_sign_rsp(struct ksmbd_work *work)
>         struct kvec *iov;
>         int n_vec = 1;
>
>         hdr = ksmbd_resp_buf_curr(work);
>         hdr->Flags |= SMB2_FLAGS_SIGNED;
> -       memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE);
By deleting this line, the following error occurs.

[162118.260693] CIFS: VFS: sign fail cmd 0x3 message id 0x3
[162118.260707] CIFS: VFS: \\10.177.110.57 SMB signature verification
returned error = -13
[162118.261473] CIFS: VFS: sign fail cmd 0xb message id 0x4
[162118.261482] CIFS: VFS: \\10.177.110.57 SMB signature verification
returned error = -13
[162118.262437] CIFS: VFS: sign fail cmd 0x3 message id 0x5
[162118.262449] CIFS: VFS: \\10.177.110.57 SMB signature verification
returned error = -13
[162118.262892] CIFS: VFS: sign fail cmd 0x5 message id 0x6
[162118.262900] CIFS: VFS: \\10.177.110.57 SMB signature verification
returned error = -13
[162118.263301] CIFS: VFS: sign fail cmd 0x10 message id 0x7
[162118.263314] CIFS: VFS: \\10.177.110.57 SMB signature verification
returned error = -13
[162118.263724] CIFS: VFS: sign fail cmd 0x10 message id 0x8
[162118.263736] CIFS: VFS: \\10.177.110.57 SMB signature verification
returned error = -13
[162118.264142] CIFS: VFS: sign fail cmd 0x6 message id 0x9
[162118.264154] CIFS: VFS: \\10.177.110.57 SMB signature verification
returned error = -13
[162118.264591] CIFS: VFS: sign fail cmd 0x5 message id 0xa
[162118.264603] CIFS: VFS: \\10.177.110.57 SMB signature verification
returned error = -13
[162118.264912] CIFS: VFS: sign fail cmd 0x6 message id 0xb
[162118.264925] CIFS: VFS: \\10.177.110.57 SMB signature verification
returned error = -13
[162118.265244] CIFS: VFS: sign fail cmd 0x5 message id 0xc
[162118.265257] CIFS: VFS: \\10.177.110.57 SMB signature verification
returned error = -13
[162119.831575] CIFS: VFS: \\10.177.110.57\homes2 SMB signature
verification returned error = -13

I have directly restored this line manually and then applied this
patch to #ksmbd-for-next-next.
Thanks!
>
>         if (hdr->Command == SMB2_READ) {
>                 iov = &work->iov[work->iov_idx - 1];
>                 n_vec++;
>         } else {
>                 iov = &work->iov[work->iov_idx];
>         }
>
> -       if (!ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, n_vec,
> -                                signature))
> -               memcpy(hdr->Signature, signature, SMB2_SIGNATURE_SIZE);
> +       ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, n_vec,
> +                           signature);
> +       memcpy(hdr->Signature, signature, SMB2_SIGNATURE_SIZE);
>  }
>
>  /**
>   * smb3_check_sign_req() - handler for req packet sign processing
>   * @work:   smb work containing notify command buffer
> diff --git a/fs/smb/server/smb_common.h b/fs/smb/server/smb_common.h
> index d742ba754348b..b6e0659a7e414 100644
> --- a/fs/smb/server/smb_common.h
> +++ b/fs/smb/server/smb_common.h
> @@ -407,11 +407,11 @@ struct smb_version_ops {
>         int (*get_ksmbd_tcon)(struct ksmbd_work *work);
>         bool (*is_sign_req)(struct ksmbd_work *work, unsigned int command);
>         int (*check_sign_req)(struct ksmbd_work *work);
>         void (*set_sign_rsp)(struct ksmbd_work *work);
>         int (*generate_signingkey)(struct ksmbd_session *sess, struct ksmbd_conn *conn);
> -       int (*generate_encryptionkey)(struct ksmbd_conn *conn, struct ksmbd_session *sess);
> +       void (*generate_encryptionkey)(struct ksmbd_conn *conn, struct ksmbd_session *sess);
>         bool (*is_transform_hdr)(void *buf);
>         int (*decrypt_req)(struct ksmbd_work *work);
>         int (*encrypt_resp)(struct ksmbd_work *work);
>  };
>
> --
> 2.51.0
>

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

* Re: [PATCH 0/3] ksmbd: More crypto library conversions
  2025-10-14 23:17 [PATCH 0/3] ksmbd: More crypto library conversions Eric Biggers
                   ` (2 preceding siblings ...)
  2025-10-14 23:17 ` [PATCH 3/3] ksmbd: Use HMAC-MD5 library for NTLMv2 Eric Biggers
@ 2025-10-16  5:03 ` Namjae Jeon
  3 siblings, 0 replies; 7+ messages in thread
From: Namjae Jeon @ 2025-10-16  5:03 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-cifs, Steve French, Sergey Senozhatsky, Tom Talpey,
	linux-crypto, linux-kernel

On Wed, Oct 15, 2025 at 8:18 AM Eric Biggers <ebiggers@kernel.org> wrote:
>
> This series converts fs/smb/server/ to access SHA-512, HMAC-SHA256, 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.  I haven't done
> server-specific benchmarks, but you can get an idea of what to expect by
> looking at the numbers I gave for the similar client-side series:
> https://lore.kernel.org/linux-cifs/20251014034230.GC2763@sol/
>
> No change in behavior intended.  All the crypto computations should be
> the same as before.  I haven't tested this series (I did test the
> similar client-side series), but everything should still work.
>
> Eric Biggers (3):
>   ksmbd: Use SHA-512 library for SMB3.1.1 preauth hash
>   ksmbd: Use HMAC-SHA256 library for message signing and key generation
>   ksmbd: Use HMAC-MD5 library for NTLMv2
Applied them to #ksmbd-for-next-next.
Thanks!
>
>  fs/smb/server/Kconfig      |   6 +-
>  fs/smb/server/auth.c       | 390 +++++++------------------------------
>  fs/smb/server/auth.h       |  10 +-
>  fs/smb/server/crypto_ctx.c |  24 ---
>  fs/smb/server/crypto_ctx.h |  15 +-
>  fs/smb/server/server.c     |   4 -
>  fs/smb/server/smb2pdu.c    |  26 +--
>  fs/smb/server/smb_common.h |   2 +-
>  8 files changed, 87 insertions(+), 390 deletions(-)
>
>
> base-commit: 3a8660878839faadb4f1a6dd72c3179c1df56787
> --
> 2.51.0
>

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

* Re: [PATCH 2/3] ksmbd: Use HMAC-SHA256 library for message signing and key generation
  2025-10-16  5:00   ` Namjae Jeon
@ 2025-10-16 17:54     ` Eric Biggers
  0 siblings, 0 replies; 7+ messages in thread
From: Eric Biggers @ 2025-10-16 17:54 UTC (permalink / raw)
  To: Namjae Jeon
  Cc: linux-cifs, Steve French, Sergey Senozhatsky, Tom Talpey,
	linux-crypto, linux-kernel

On Thu, Oct 16, 2025 at 02:00:37PM +0900, Namjae Jeon wrote:
> [snip]
> > @@ -8876,22 +8865,21 @@ void smb2_set_sign_rsp(struct ksmbd_work *work)
> >         struct kvec *iov;
> >         int n_vec = 1;
> >
> >         hdr = ksmbd_resp_buf_curr(work);
> >         hdr->Flags |= SMB2_FLAGS_SIGNED;
> > -       memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE);
> By deleting this line, the following error occurs.
> 
> [162118.260693] CIFS: VFS: sign fail cmd 0x3 message id 0x3
> [162118.260707] CIFS: VFS: \\10.177.110.57 SMB signature verification
> returned error = -13
> [162118.261473] CIFS: VFS: sign fail cmd 0xb message id 0x4
> [162118.261482] CIFS: VFS: \\10.177.110.57 SMB signature verification
> returned error = -13
> [162118.262437] CIFS: VFS: sign fail cmd 0x3 message id 0x5
> [162118.262449] CIFS: VFS: \\10.177.110.57 SMB signature verification
> returned error = -13
> [162118.262892] CIFS: VFS: sign fail cmd 0x5 message id 0x6
> [162118.262900] CIFS: VFS: \\10.177.110.57 SMB signature verification
> returned error = -13
> [162118.263301] CIFS: VFS: sign fail cmd 0x10 message id 0x7
> [162118.263314] CIFS: VFS: \\10.177.110.57 SMB signature verification
> returned error = -13
> [162118.263724] CIFS: VFS: sign fail cmd 0x10 message id 0x8
> [162118.263736] CIFS: VFS: \\10.177.110.57 SMB signature verification
> returned error = -13
> [162118.264142] CIFS: VFS: sign fail cmd 0x6 message id 0x9
> [162118.264154] CIFS: VFS: \\10.177.110.57 SMB signature verification
> returned error = -13
> [162118.264591] CIFS: VFS: sign fail cmd 0x5 message id 0xa
> [162118.264603] CIFS: VFS: \\10.177.110.57 SMB signature verification
> returned error = -13
> [162118.264912] CIFS: VFS: sign fail cmd 0x6 message id 0xb
> [162118.264925] CIFS: VFS: \\10.177.110.57 SMB signature verification
> returned error = -13
> [162118.265244] CIFS: VFS: sign fail cmd 0x5 message id 0xc
> [162118.265257] CIFS: VFS: \\10.177.110.57 SMB signature verification
> returned error = -13
> [162119.831575] CIFS: VFS: \\10.177.110.57\homes2 SMB signature
> verification returned error = -13
> 
> I have directly restored this line manually and then applied this
> patch to #ksmbd-for-next-next.
> Thanks!

Thanks for catching that!  It looked like zeroizing 'hdr->Signature' was
only needed for when ksmbd_sign_smb2_pdu() failed.  But it must be part
of the HMAC input data as well, i.e. 'hdr' must point to the same memory
as one of the iovecs.  So restoring the line is fine.  Thanks,

- Eric

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

end of thread, other threads:[~2025-10-16 17:56 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-14 23:17 [PATCH 0/3] ksmbd: More crypto library conversions Eric Biggers
2025-10-14 23:17 ` [PATCH 1/3] ksmbd: Use SHA-512 library for SMB3.1.1 preauth hash Eric Biggers
2025-10-14 23:17 ` [PATCH 2/3] ksmbd: Use HMAC-SHA256 library for message signing and key generation Eric Biggers
2025-10-16  5:00   ` Namjae Jeon
2025-10-16 17:54     ` Eric Biggers
2025-10-14 23:17 ` [PATCH 3/3] ksmbd: Use HMAC-MD5 library for NTLMv2 Eric Biggers
2025-10-16  5:03 ` [PATCH 0/3] ksmbd: More crypto library conversions Namjae Jeon

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