From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 64EB1405C31 for ; Sat, 16 May 2026 19:09:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778958589; cv=none; b=rRcVrrE3FqM4eM8hii9ct4QP6BfzziMV7RqDyuyQplqrR/y5hAX9eOQI1mRWJ7+ei7l/0xeb0Y+aPP0KUHiAdBDM+ixgDstBFQmoXx6SjahpwiwhFTlQhB6r81QPYybrMcwClqzTMOCjNnagKyrIFcyHvJAXD+Yb3wEpebi8vxM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778958589; c=relaxed/simple; bh=RVfBS1yr/CqQPkI+zxMHlAmt39OrLloHtS1rLDjIrdA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nAE612YVrpA+8Gn5+shiml2q8YfQ7XObXhfLNKBYaiZ0ChrT5QPNA0sLjDA4gwZhFeDfDtEBiGfI74JrZYkbUQYxU8TsmC5oUQ+J9+eKweebK8E/BhfIzW6KBDABu3Uv5+sAAa1tw+d0HBxa0+Ws7ukGdx9u6/uKrJedSfDVa68= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nVc1gfGh; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="nVc1gfGh" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6BD25C19425; Sat, 16 May 2026 19:09:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1778958589; bh=RVfBS1yr/CqQPkI+zxMHlAmt39OrLloHtS1rLDjIrdA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nVc1gfGhXbPSKIZFZFkmaxYUK5H4QmKqJ5noyq+befhAEEei055tvRfHJwAkPHxlg yiuVvKFxcJqZ3YFrvLuP7BpV2DmR+gNUlWbmmqK0k0y9JTikBtidBe45VJK8N+uLk3 A1m3GCcUFIxWYqhXcmwaEYL+RRnKP3UQrn+sG7g/Je3QQ1fLjZrsILaxlh1n2c2H4z 8e5yUlHmiwnMaNvc0oAV4IcPnRC0tt8uxg8cldxSsTuzbHdWmVeB4wBkgx4SnduD9x j49VZGsEW7q4jQVfIrrnCaElCz5fMw9tRPcvPYoQv4w2Bpz+uoM80yHOKk7X2n+abZ +Ek+TmOxRuMlA== From: Sasha Levin To: stable@vger.kernel.org Cc: Piyush Sachdeva , Bharath SM , Piyush Sachdeva , Steve French , Sasha Levin Subject: [PATCH 6.12.y] smb: client: Use FullSessionKey for AES-256 encryption key derivation Date: Sat, 16 May 2026 15:09:46 -0400 Message-ID: <20260516190946.4018100-1-sashal@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <2026051202-broiling-reptile-02dc@gregkh> References: <2026051202-broiling-reptile-02dc@gregkh> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Piyush Sachdeva [ 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: Reviewed-by: Bharath SM Signed-off-by: Piyush Sachdeva Signed-off-by: Piyush Sachdeva Signed-off-by: Steve French [ adapted upstream's void/hmac_sha256_init_usingrawkey-based generate_key() to 6.12's int-return crypto_shash_* form while threading full_key_size through all callers. ] Signed-off-by: Sasha Levin --- 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 2ce193609d8b2..200af8bad57d1 100644 --- a/fs/smb/client/ioctl.c +++ b/fs/smb/client/ioctl.c @@ -300,7 +300,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 87f189894b1e1..6d7e1b4d2d558 100644 --- a/fs/smb/client/smb2transport.c +++ b/fs/smb/client/smb2transport.c @@ -334,7 +334,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}; @@ -355,7 +356,7 @@ static int generate_key(struct cifs_ses *ses, struct kvec label, } rc = crypto_shash_setkey(server->secmech.hmacsha256->tfm, - ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE); + ses->auth_key.response, full_key_size); if (rc) { cifs_server_dbg(VFS, "%s: Could not set with session key\n", __func__); goto smb3signkey_ret; @@ -430,6 +431,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; @@ -464,17 +466,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, @@ -484,13 +500,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; } @@ -505,7 +523,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