* FAILED: patch "[PATCH] smb: client: Use FullSessionKey for AES-256 encryption key" failed to apply to 6.18-stable tree
@ 2026-05-12 14:05 gregkh
2026-05-15 21:35 ` [PATCH 6.18.y] smb: client: Use FullSessionKey for AES-256 encryption key derivation Sasha Levin
0 siblings, 1 reply; 2+ messages in thread
From: gregkh @ 2026-05-12 14:05 UTC (permalink / raw)
To: s.piyush1024, bharathsm, psachdeva, stable, stfrench; +Cc: stable
The patch below does not apply to the 6.18-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.18.y
git checkout FETCH_HEAD
git cherry-pick -x 5be7a0cef3229fb3b63a07c0d289daf752545424
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026051201-matching-contently-a8c4@gregkh' --subject-prefix 'PATCH 6.18.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 5be7a0cef3229fb3b63a07c0d289daf752545424 Mon Sep 17 00:00:00 2001
From: Piyush Sachdeva <s.piyush1024@gmail.com>
Date: Thu, 7 May 2026 22:22:13 +0530
Subject: [PATCH] smb: client: Use FullSessionKey for AES-256 encryption key
derivation
When Kerberos authentication is used with AES-256 encryption (AES-256-CCM
or AES-256-GCM), the SMB3 encryption and decryption keys must be derived
using the full session key (Session.FullSessionKey) rather than just the
first 16 bytes (Session.SessionKey).
Per MS-SMB2 section 3.2.5.3.1, when Connection.Dialect is "3.1.1" and
Connection.CipherId is AES-256-CCM or AES-256-GCM, Session.FullSessionKey
must be set to the full cryptographic key from the GSS authentication
context. The encryption and decryption key derivation (SMBC2SCipherKey,
SMBS2CCipherKey) must use this FullSessionKey as the KDF input. The
signing key derivation continues to use Session.SessionKey (first 16
bytes) in all cases.
Previously, generate_key() hardcoded SMB2_NTLMV2_SESSKEY_SIZE (16) as the
HMAC-SHA256 key input length for all derivations. When Kerberos with
AES-256 provides a 32-byte session key, the KDF for encryption/decryption
was using only the first 16 bytes, producing keys that did not match the
server's, causing mount failures with sec=krb5 and require_gcm_256=1.
Add a full_key_size parameter to generate_key() and pass the appropriate
size from generate_smb3signingkey():
- Signing: always SMB2_NTLMV2_SESSKEY_SIZE (16 bytes)
- Encryption/Decryption: ses->auth_key.len when AES-256, otherwise 16
Also fix cifs_dump_full_key() to report the actual session key length for
AES-256 instead of hardcoded CIFS_SESS_KEY_SIZE, so that userspace tools
like Wireshark receive the correct key for decryption.
Cc: <stable@vger.kernel.org>
Reviewed-by: Bharath SM <bharathsm@microsoft.com>
Signed-off-by: Piyush Sachdeva <psachdeva@microsoft.com>
Signed-off-by: Piyush Sachdeva <s.piyush1024@gmail.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
diff --git a/fs/smb/client/ioctl.c b/fs/smb/client/ioctl.c
index 9afab3237e54..17408bb8ab65 100644
--- a/fs/smb/client/ioctl.c
+++ b/fs/smb/client/ioctl.c
@@ -296,7 +296,7 @@ static int cifs_dump_full_key(struct cifs_tcon *tcon, struct smb3_full_key_debug
break;
case SMB2_ENCRYPTION_AES256_CCM:
case SMB2_ENCRYPTION_AES256_GCM:
- out.session_key_length = CIFS_SESS_KEY_SIZE;
+ out.session_key_length = ses->auth_key.len;
out.server_in_key_length = out.server_out_key_length = SMB3_GCM256_CRYPTKEY_SIZE;
break;
default:
diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c
index 41009039b4cb..e8eeff9e50d6 100644
--- a/fs/smb/client/smb2transport.c
+++ b/fs/smb/client/smb2transport.c
@@ -251,7 +251,8 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
}
static void generate_key(struct cifs_ses *ses, struct kvec label,
- struct kvec context, __u8 *key, unsigned int key_size)
+ struct kvec context, __u8 *key, unsigned int key_size,
+ unsigned int full_key_size)
{
unsigned char zero = 0x0;
__u8 i[4] = {0, 0, 0, 1};
@@ -265,7 +266,7 @@ static void generate_key(struct cifs_ses *ses, struct kvec label,
memset(key, 0x0, key_size);
hmac_sha256_init_usingrawkey(&hmac_ctx, ses->auth_key.response,
- SMB2_NTLMV2_SESSKEY_SIZE);
+ full_key_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);
@@ -298,6 +299,7 @@ generate_smb3signingkey(struct cifs_ses *ses,
struct TCP_Server_Info *server,
const struct derivation_triplet *ptriplet)
{
+ unsigned int full_key_size = SMB2_NTLMV2_SESSKEY_SIZE;
bool is_binding = false;
int chan_index = 0;
@@ -330,12 +332,24 @@ generate_smb3signingkey(struct cifs_ses *ses,
if (is_binding) {
generate_key(ses, ptriplet->signing.label,
ptriplet->signing.context,
- ses->chans[chan_index].signkey,
- SMB3_SIGN_KEY_SIZE);
+ ses->chans[chan_index].signkey, SMB3_SIGN_KEY_SIZE,
+ SMB2_NTLMV2_SESSKEY_SIZE);
} else {
generate_key(ses, ptriplet->signing.label,
- ptriplet->signing.context,
- ses->smb3signingkey, SMB3_SIGN_KEY_SIZE);
+ ptriplet->signing.context, ses->smb3signingkey,
+ SMB3_SIGN_KEY_SIZE, SMB2_NTLMV2_SESSKEY_SIZE);
+
+ /*
+ * Per MS-SMB2 3.2.5.3.1, signing key always uses Session.SessionKey
+ * (first 16 bytes). Encryption/decryption keys use
+ * Session.FullSessionKey when dialect is 3.1.1 and cipher is
+ * AES-256-CCM or AES-256-GCM, otherwise Session.SessionKey.
+ */
+
+ if (server->dialect == SMB311_PROT_ID &&
+ (server->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
+ server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
+ full_key_size = ses->auth_key.len;
/* safe to access primary channel, since it will never go away */
spin_lock(&ses->chan_lock);
@@ -345,10 +359,13 @@ generate_smb3signingkey(struct cifs_ses *ses,
generate_key(ses, ptriplet->encryption.label,
ptriplet->encryption.context,
- ses->smb3encryptionkey, SMB3_ENC_DEC_KEY_SIZE);
+ ses->smb3encryptionkey, SMB3_ENC_DEC_KEY_SIZE,
+ full_key_size);
+
generate_key(ses, ptriplet->decryption.label,
ptriplet->decryption.context,
- ses->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE);
+ ses->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE,
+ full_key_size);
}
#ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS
@@ -361,7 +378,7 @@ generate_smb3signingkey(struct cifs_ses *ses,
&ses->Suid);
cifs_dbg(VFS, "Cipher type %d\n", server->cipher_type);
cifs_dbg(VFS, "Session Key %*ph\n",
- SMB2_NTLMV2_SESSKEY_SIZE, ses->auth_key.response);
+ (int)ses->auth_key.len, ses->auth_key.response);
cifs_dbg(VFS, "Signing Key %*ph\n",
SMB3_SIGN_KEY_SIZE, ses->smb3signingkey);
if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH 6.18.y] smb: client: Use FullSessionKey for AES-256 encryption key derivation
2026-05-12 14:05 FAILED: patch "[PATCH] smb: client: Use FullSessionKey for AES-256 encryption key" failed to apply to 6.18-stable tree gregkh
@ 2026-05-15 21:35 ` Sasha Levin
0 siblings, 0 replies; 2+ messages in thread
From: Sasha Levin @ 2026-05-15 21:35 UTC (permalink / raw)
To: stable
Cc: Piyush Sachdeva, Bharath SM, Piyush Sachdeva, Steve French,
Sasha Levin
From: Piyush Sachdeva <s.piyush1024@gmail.com>
[ Upstream commit 5be7a0cef3229fb3b63a07c0d289daf752545424 ]
When Kerberos authentication is used with AES-256 encryption (AES-256-CCM
or AES-256-GCM), the SMB3 encryption and decryption keys must be derived
using the full session key (Session.FullSessionKey) rather than just the
first 16 bytes (Session.SessionKey).
Per MS-SMB2 section 3.2.5.3.1, when Connection.Dialect is "3.1.1" and
Connection.CipherId is AES-256-CCM or AES-256-GCM, Session.FullSessionKey
must be set to the full cryptographic key from the GSS authentication
context. The encryption and decryption key derivation (SMBC2SCipherKey,
SMBS2CCipherKey) must use this FullSessionKey as the KDF input. The
signing key derivation continues to use Session.SessionKey (first 16
bytes) in all cases.
Previously, generate_key() hardcoded SMB2_NTLMV2_SESSKEY_SIZE (16) as the
HMAC-SHA256 key input length for all derivations. When Kerberos with
AES-256 provides a 32-byte session key, the KDF for encryption/decryption
was using only the first 16 bytes, producing keys that did not match the
server's, causing mount failures with sec=krb5 and require_gcm_256=1.
Add a full_key_size parameter to generate_key() and pass the appropriate
size from generate_smb3signingkey():
- Signing: always SMB2_NTLMV2_SESSKEY_SIZE (16 bytes)
- Encryption/Decryption: ses->auth_key.len when AES-256, otherwise 16
Also fix cifs_dump_full_key() to report the actual session key length for
AES-256 instead of hardcoded CIFS_SESS_KEY_SIZE, so that userspace tools
like Wireshark receive the correct key for decryption.
Cc: <stable@vger.kernel.org>
Reviewed-by: Bharath SM <bharathsm@microsoft.com>
Signed-off-by: Piyush Sachdeva <psachdeva@microsoft.com>
Signed-off-by: Piyush Sachdeva <s.piyush1024@gmail.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/ioctl.c | 2 +-
fs/smb/client/smb2transport.c | 32 +++++++++++++++++++++++++-------
2 files changed, 26 insertions(+), 8 deletions(-)
diff --git a/fs/smb/client/ioctl.c b/fs/smb/client/ioctl.c
index 0a9935ce05a5a..1a6ce837e26af 100644
--- a/fs/smb/client/ioctl.c
+++ b/fs/smb/client/ioctl.c
@@ -297,7 +297,7 @@ static int cifs_dump_full_key(struct cifs_tcon *tcon, struct smb3_full_key_debug
break;
case SMB2_ENCRYPTION_AES256_CCM:
case SMB2_ENCRYPTION_AES256_GCM:
- out.session_key_length = CIFS_SESS_KEY_SIZE;
+ out.session_key_length = ses->auth_key.len;
out.server_in_key_length = out.server_out_key_length = SMB3_GCM256_CRYPTKEY_SIZE;
break;
default:
diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c
index 211305d43f8d4..db98ced541baa 100644
--- a/fs/smb/client/smb2transport.c
+++ b/fs/smb/client/smb2transport.c
@@ -259,7 +259,8 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
}
static int generate_key(struct cifs_ses *ses, struct kvec label,
- struct kvec context, __u8 *key, unsigned int key_size)
+ struct kvec context, __u8 *key, unsigned int key_size,
+ unsigned int full_key_size)
{
unsigned char zero = 0x0;
__u8 i[4] = {0, 0, 0, 1};
@@ -280,7 +281,7 @@ static int generate_key(struct cifs_ses *ses, struct kvec label,
}
hmac_sha256_init_usingrawkey(&hmac_ctx, ses->auth_key.response,
- SMB2_NTLMV2_SESSKEY_SIZE);
+ full_key_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);
@@ -314,6 +315,7 @@ generate_smb3signingkey(struct cifs_ses *ses,
struct TCP_Server_Info *server,
const struct derivation_triplet *ptriplet)
{
+ unsigned int full_key_size = SMB2_NTLMV2_SESSKEY_SIZE;
int rc;
bool is_binding = false;
int chan_index = 0;
@@ -348,17 +350,31 @@ generate_smb3signingkey(struct cifs_ses *ses,
rc = generate_key(ses, ptriplet->signing.label,
ptriplet->signing.context,
ses->chans[chan_index].signkey,
- SMB3_SIGN_KEY_SIZE);
+ SMB3_SIGN_KEY_SIZE,
+ SMB2_NTLMV2_SESSKEY_SIZE);
if (rc)
return rc;
} else {
rc = generate_key(ses, ptriplet->signing.label,
ptriplet->signing.context,
ses->smb3signingkey,
- SMB3_SIGN_KEY_SIZE);
+ SMB3_SIGN_KEY_SIZE,
+ SMB2_NTLMV2_SESSKEY_SIZE);
if (rc)
return rc;
+ /*
+ * Per MS-SMB2 3.2.5.3.1, signing key always uses Session.SessionKey
+ * (first 16 bytes). Encryption/decryption keys use
+ * Session.FullSessionKey when dialect is 3.1.1 and cipher is
+ * AES-256-CCM or AES-256-GCM, otherwise Session.SessionKey.
+ */
+
+ if (server->dialect == SMB311_PROT_ID &&
+ (server->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
+ server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
+ full_key_size = ses->auth_key.len;
+
/* safe to access primary channel, since it will never go away */
spin_lock(&ses->chan_lock);
memcpy(ses->chans[chan_index].signkey, ses->smb3signingkey,
@@ -368,13 +384,15 @@ generate_smb3signingkey(struct cifs_ses *ses,
rc = generate_key(ses, ptriplet->encryption.label,
ptriplet->encryption.context,
ses->smb3encryptionkey,
- SMB3_ENC_DEC_KEY_SIZE);
+ SMB3_ENC_DEC_KEY_SIZE,
+ full_key_size);
if (rc)
return rc;
rc = generate_key(ses, ptriplet->decryption.label,
ptriplet->decryption.context,
ses->smb3decryptionkey,
- SMB3_ENC_DEC_KEY_SIZE);
+ SMB3_ENC_DEC_KEY_SIZE,
+ full_key_size);
if (rc)
return rc;
}
@@ -389,7 +407,7 @@ generate_smb3signingkey(struct cifs_ses *ses,
&ses->Suid);
cifs_dbg(VFS, "Cipher type %d\n", server->cipher_type);
cifs_dbg(VFS, "Session Key %*ph\n",
- SMB2_NTLMV2_SESSKEY_SIZE, ses->auth_key.response);
+ (int)ses->auth_key.len, ses->auth_key.response);
cifs_dbg(VFS, "Signing Key %*ph\n",
SMB3_SIGN_KEY_SIZE, ses->smb3signingkey);
if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
--
2.53.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-05-15 21:35 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-12 14:05 FAILED: patch "[PATCH] smb: client: Use FullSessionKey for AES-256 encryption key" failed to apply to 6.18-stable tree gregkh
2026-05-15 21:35 ` [PATCH 6.18.y] smb: client: Use FullSessionKey for AES-256 encryption key derivation Sasha Levin
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.