[PATCH 0/2] ksmbd: AES-GMAC signing support

From: Michail Andreas Michalopoulos

Date: Tue Nov 03 2026 - 06:27:37 EST


SMB 3.1.1 clients choose the signing algorithm in the
SMB2_SIGNING_CAPABILITIES negotiate context. ksmbd parses the client's
list, but init_smb3_11_server() then overwrites the choice with
AES-CMAC, so a client that does not offer AES-CMAC cannot connect.
Patch 1 fixes that and keeps each signing key paired with the
algorithm it was created for. Patch 2 adds AES-GMAC, which Windows and
macOS offer first, using the lib/crypto AES-GCM API.

Discussion:
https://lore.kernel.org/linux-cifs/D0F05F9A-5097-4A2D-9235-AE395961F456@xxxxxxxxx/

Testing:
- smbtorture 4.19 with each algorithm forced
(clientsmb3signingalgorithms): without the series an HMAC-SHA256
only client fails smb2.connect with NT_STATUS_INVALID_NETWORK_RESPONSE
and an AES-GMAC only client cannot negotiate. With it, all three
connect and sign with the forced algorithm; smb2.connect then stops
at its tree disconnect check (STATUS_ACCESS_DENIED instead of
STATUS_NETWORK_NAME_DELETED), as it does for AES-CMAC without the
series.
- smb2.session (smbtorture 4.19, multichannel off): 21 tests pass
instead of 12. signing-hmac-sha-256, signing-aes-128-cmac,
signing-aes-128-gmac, encryption-aes-{128,256}-{ccm,gcm} and
bind_negative_smb3signGtoH2X{d,s} need signing negotiation and now
run and pass instead of being skipped. 26 other
bind_negative_smb3sign*/smb3sne* tests now run too and fail with
STATUS_USER_SESSION_DELETED, because binding needs multichannel;
see the next item for them with multichannel enabled. No test that
passed before fails.
- smb2.bench.echo and smb2.bench.read with each algorithm forced,
smbtorture 4.19 (x86) and 4.23 (arm64).
- smb2.session.bind_negative* with multichannel enabled (smbtorture
4.19): all tests involving AES-GMAC pass. Without the series most
smb3sign* tests were skipped, as ksmbd could not negotiate anything
but AES-CMAC. The four AES-CMAC <-> HMAC-SHA256 tests now run and
fail on existing binding behaviour that this series does not touch:
the *d variants because ksmbd rejects binding from a different
ClientGUID (Windows accepts it), the *s variants because a session
setup without the binding flag on an already bound connection
succeeds instead of failing with STATUS_ACCESS_DENIED.
- Windows Server 2025: offered AES-GMAC, AES-CMAC, HMAC-SHA256 and
ksmbd answered AES-GMAC (checked in a packet capture). A 1 GiB copy
to and from the share came back identical (SHA256), with signing
required and encryption off.
- macOS 26: negotiated AES-GMAC, 256 MiB copy identical.
- No "bad smb2 signature" messages in any of these runs.

End to end, smbtorture smb2.bench.read with 1 MiB reads, MB/s:

HMAC-SHA256 AES-CMAC AES-GMAC
arm64, Apple M4 VM, loopback 1354 924 797
x86, AMD EPYC VMs, 3.56 Gbit/s 449 341 469

On arm64 AES-GMAC is currently the slowest because the arm64 GHASH
library code does not use PMULL for bulk data; I'll send a separate
lib/crypto series for that, as discussed in the thread above.

Not tested: multichannel with Windows or macOS clients (binding was
only tested with smbtorture), and SMB over RDMA.

An AI assistant was used to draft the patches and as an independent
reviewer. I ran the Windows, macOS and benchmark tests; the smbtorture
runs were done by the assistant under UML.

Michail Andreas Michalopoulos (2):
ksmbd: sign with the negotiated SMB 3.1.1 signing algorithm
ksmbd: add AES-GMAC signing support

Documentation/filesystems/smb/ksmbd.rst | 2 +-
fs/smb/server/Kconfig | 1 +
fs/smb/server/auth.c | 60 ++++++++++++++++++++++++-
fs/smb/server/auth.h | 4 +-
fs/smb/server/mgmt/user_session.c | 1 +
fs/smb/server/mgmt/user_session.h | 2 +
fs/smb/server/smb2ops.c | 4 +-
fs/smb/server/smb2pdu.c | 53 +++++++++++++++++++---
8 files changed, 116 insertions(+), 11 deletions(-)


base-commit: af8c72f6550744fe948ef2dbc7ab8739c149aab2
--
2.43.0