Skip to content

Commit 7e7db86

Browse files
committed
smb3: allow decryption keys to be dumped by admin for debugging
In order to debug certain problems it is important to be able to decrypt network traces (e.g. wireshark) but to do this we need to be able to dump out the encryption/decryption keys. Dumping them to an ioctl is safer than dumping then to dmesg, (and better than showing all keys in a pseudofile). Restrict this to root (CAP_SYS_ADMIN), and only for a mount that this admin has access to. Sample smbinfo output: SMB3.0 encryption Session Id: 0x82d2ec52 Session Key: a5 6d 81 d0 e c1 ca e1 d8 13 aa 20 e8 f2 cc 71 Server Encryption Key: 1a c3 be ba 3d fc dc 3c e bc 93 9e 50 9e 19 c1 Server Decryption Key: e0 d4 d9 43 1b a2 1b e3 d8 76 77 49 56 f7 20 88 Reviewed-by: Aurelien Aptel <[email protected]> Pavel Shilovsky <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 4d6bcba commit 7e7db86

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

fs/cifs/cifs_ioctl.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,18 @@ struct smb_query_info {
5757
/* char buffer[]; */
5858
} __packed;
5959

60+
struct smb3_key_debug_info {
61+
__u64 Suid;
62+
__u16 cipher_type;
63+
__u8 auth_key[16]; /* SMB2_NTLMV2_SESSKEY_SIZE */
64+
__u8 smb3encryptionkey[SMB3_SIGN_KEY_SIZE];
65+
__u8 smb3decryptionkey[SMB3_SIGN_KEY_SIZE];
66+
} __packed;
67+
6068
#define CIFS_IOCTL_MAGIC 0xCF
6169
#define CIFS_IOC_COPYCHUNK_FILE _IOW(CIFS_IOCTL_MAGIC, 3, int)
6270
#define CIFS_IOC_SET_INTEGRITY _IO(CIFS_IOCTL_MAGIC, 4)
6371
#define CIFS_IOC_GET_MNT_INFO _IOR(CIFS_IOCTL_MAGIC, 5, struct smb_mnt_fs_info)
6472
#define CIFS_ENUMERATE_SNAPSHOTS _IOR(CIFS_IOCTL_MAGIC, 6, struct smb_snapshot_array)
6573
#define CIFS_QUERY_INFO _IOWR(CIFS_IOCTL_MAGIC, 7, struct smb_query_info)
74+
#define CIFS_DUMP_KEY _IOWR(CIFS_IOCTL_MAGIC, 8, struct smb3_key_debug_info)

fs/cifs/ioctl.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ static long smb_mnt_get_fsinfo(unsigned int xid, struct cifs_tcon *tcon,
164164
long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
165165
{
166166
struct inode *inode = file_inode(filep);
167+
struct smb3_key_debug_info pkey_inf;
167168
int rc = -ENOTTY; /* strange error - but the precedent */
168169
unsigned int xid;
169170
struct cifsFileInfo *pSMBFile = filep->private_data;
@@ -270,6 +271,34 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
270271
else
271272
rc = -EOPNOTSUPP;
272273
break;
274+
case CIFS_DUMP_KEY:
275+
if (pSMBFile == NULL)
276+
break;
277+
if (!capable(CAP_SYS_ADMIN)) {
278+
rc = -EACCES;
279+
break;
280+
}
281+
282+
tcon = tlink_tcon(pSMBFile->tlink);
283+
if (!smb3_encryption_required(tcon)) {
284+
rc = -EOPNOTSUPP;
285+
break;
286+
}
287+
pkey_inf.cipher_type =
288+
le16_to_cpu(tcon->ses->server->cipher_type);
289+
pkey_inf.Suid = tcon->ses->Suid;
290+
memcpy(pkey_inf.auth_key, tcon->ses->auth_key.response,
291+
16 /* SMB2_NTLMV2_SESSKEY_SIZE */);
292+
memcpy(pkey_inf.smb3decryptionkey,
293+
tcon->ses->smb3decryptionkey, SMB3_SIGN_KEY_SIZE);
294+
memcpy(pkey_inf.smb3encryptionkey,
295+
tcon->ses->smb3encryptionkey, SMB3_SIGN_KEY_SIZE);
296+
if (copy_to_user((void __user *)arg, &pkey_inf,
297+
sizeof(struct smb3_key_debug_info)))
298+
rc = -EFAULT;
299+
else
300+
rc = 0;
301+
break;
273302
default:
274303
cifs_dbg(FYI, "unsupported ioctl\n");
275304
break;

0 commit comments

Comments
 (0)