Skip to content

Commit b6fe923

Browse files
dhowellssmfrench
authored andcommitted
cifs: SMB1 split: cifsencrypt.c
Split SMB1-specific message signing into smb1encrypt.c. Signed-off-by: David Howells <dhowells@redhat.com> cc: Steve French <sfrench@samba.org> cc: Paulo Alcantara <pc@manguebit.org> cc: Enzo Matsumiya <ematsumiya@suse.de> cc: linux-cifs@vger.kernel.org cc: linux-fsdevel@vger.kernel.org cc: linux-kernel@vger.kernel.org Acked-by: Enzo Matsumiya <ematsumiya@suse.de> Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent 6fb4e46 commit b6fe923

5 files changed

Lines changed: 149 additions & 128 deletions

File tree

fs/smb/client/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ cifs-$(CONFIG_CIFS_ROOT) += cifsroot.o
3535
cifs-$(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) += \
3636
cifssmb.o \
3737
smb1debug.o \
38+
smb1encrypt.o \
3839
smb1maperror.o \
3940
smb1misc.o \
4041
smb1ops.o \

fs/smb/client/cifsencrypt.c

Lines changed: 0 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -115,129 +115,6 @@ int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
115115
return rc;
116116
}
117117

118-
/*
119-
* Calculate and return the CIFS signature based on the mac key and SMB PDU.
120-
* The 16 byte signature must be allocated by the caller. Note we only use the
121-
* 1st eight bytes and that the smb header signature field on input contains
122-
* the sequence number before this function is called. Also, this function
123-
* should be called with the server->srv_mutex held.
124-
*/
125-
static int cifs_calc_signature(struct smb_rqst *rqst,
126-
struct TCP_Server_Info *server, char *signature)
127-
{
128-
struct md5_ctx ctx;
129-
130-
if (!rqst->rq_iov || !signature || !server)
131-
return -EINVAL;
132-
if (fips_enabled) {
133-
cifs_dbg(VFS,
134-
"MD5 signature support is disabled due to FIPS\n");
135-
return -EOPNOTSUPP;
136-
}
137-
138-
md5_init(&ctx);
139-
md5_update(&ctx, server->session_key.response, server->session_key.len);
140-
141-
return __cifs_calc_signature(
142-
rqst, server, signature,
143-
&(struct cifs_calc_sig_ctx){ .md5 = &ctx });
144-
}
145-
146-
/* must be called with server->srv_mutex held */
147-
int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
148-
__u32 *pexpected_response_sequence_number)
149-
{
150-
int rc = 0;
151-
char smb_signature[20];
152-
struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
153-
154-
if ((cifs_pdu == NULL) || (server == NULL))
155-
return -EINVAL;
156-
157-
spin_lock(&server->srv_lock);
158-
if (!(cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) ||
159-
server->tcpStatus == CifsNeedNegotiate) {
160-
spin_unlock(&server->srv_lock);
161-
return rc;
162-
}
163-
spin_unlock(&server->srv_lock);
164-
165-
if (!server->session_estab) {
166-
memcpy(cifs_pdu->Signature.SecuritySignature, "BSRSPYL", 8);
167-
return rc;
168-
}
169-
170-
cifs_pdu->Signature.Sequence.SequenceNumber =
171-
cpu_to_le32(server->sequence_number);
172-
cifs_pdu->Signature.Sequence.Reserved = 0;
173-
174-
*pexpected_response_sequence_number = ++server->sequence_number;
175-
++server->sequence_number;
176-
177-
rc = cifs_calc_signature(rqst, server, smb_signature);
178-
if (rc)
179-
memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
180-
else
181-
memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
182-
183-
return rc;
184-
}
185-
186-
int cifs_verify_signature(struct smb_rqst *rqst,
187-
struct TCP_Server_Info *server,
188-
__u32 expected_sequence_number)
189-
{
190-
unsigned int rc;
191-
char server_response_sig[8];
192-
char what_we_think_sig_should_be[20];
193-
struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
194-
195-
if (cifs_pdu == NULL || server == NULL)
196-
return -EINVAL;
197-
198-
if (!server->session_estab)
199-
return 0;
200-
201-
if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) {
202-
struct smb_com_lock_req *pSMB =
203-
(struct smb_com_lock_req *)cifs_pdu;
204-
if (pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)
205-
return 0;
206-
}
207-
208-
/* BB what if signatures are supposed to be on for session but
209-
server does not send one? BB */
210-
211-
/* Do not need to verify session setups with signature "BSRSPYL " */
212-
if (memcmp(cifs_pdu->Signature.SecuritySignature, "BSRSPYL ", 8) == 0)
213-
cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
214-
cifs_pdu->Command);
215-
216-
/* save off the original signature so we can modify the smb and check
217-
its signature against what the server sent */
218-
memcpy(server_response_sig, cifs_pdu->Signature.SecuritySignature, 8);
219-
220-
cifs_pdu->Signature.Sequence.SequenceNumber =
221-
cpu_to_le32(expected_sequence_number);
222-
cifs_pdu->Signature.Sequence.Reserved = 0;
223-
224-
cifs_server_lock(server);
225-
rc = cifs_calc_signature(rqst, server, what_we_think_sig_should_be);
226-
cifs_server_unlock(server);
227-
228-
if (rc)
229-
return rc;
230-
231-
/* cifs_dump_mem("what we think it should be: ",
232-
what_we_think_sig_should_be, 16); */
233-
234-
if (memcmp(server_response_sig, what_we_think_sig_should_be, 8))
235-
return -EACCES;
236-
else
237-
return 0;
238-
239-
}
240-
241118
/* Build a proper attribute value/target info pairs blob.
242119
* Fill in netbios and dns domain name and workstation name
243120
* and client time (total five av pairs and + one end of fields indicator.

fs/smb/client/cifsproto.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -326,11 +326,6 @@ struct cifs_tcon *tcon_info_alloc(bool dir_leases_enabled,
326326
enum smb3_tcon_ref_trace trace);
327327
void tconInfoFree(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace);
328328

329-
int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
330-
__u32 *pexpected_response_sequence_number);
331-
int cifs_verify_signature(struct smb_rqst *rqst,
332-
struct TCP_Server_Info *server,
333-
__u32 expected_sequence_number);
334329
int setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp);
335330
void cifs_crypto_secmech_release(struct TCP_Server_Info *server);
336331
int calc_seckey(struct cifs_ses *ses);

fs/smb/client/smb1encrypt.c

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
// SPDX-License-Identifier: LGPL-2.1
2+
/*
3+
*
4+
* Encryption and hashing operations relating to NTLM, NTLMv2. See MS-NLMP
5+
* for more detailed information
6+
*
7+
* Copyright (C) International Business Machines Corp., 2005,2013
8+
* Author(s): Steve French (sfrench@us.ibm.com)
9+
*
10+
*/
11+
12+
#include <linux/fips.h>
13+
#include <crypto/md5.h>
14+
#include "cifsproto.h"
15+
#include "smb1proto.h"
16+
#include "cifs_debug.h"
17+
18+
/*
19+
* Calculate and return the CIFS signature based on the mac key and SMB PDU.
20+
* The 16 byte signature must be allocated by the caller. Note we only use the
21+
* 1st eight bytes and that the smb header signature field on input contains
22+
* the sequence number before this function is called. Also, this function
23+
* should be called with the server->srv_mutex held.
24+
*/
25+
static int cifs_calc_signature(struct smb_rqst *rqst,
26+
struct TCP_Server_Info *server, char *signature)
27+
{
28+
struct md5_ctx ctx;
29+
30+
if (!rqst->rq_iov || !signature || !server)
31+
return -EINVAL;
32+
if (fips_enabled) {
33+
cifs_dbg(VFS,
34+
"MD5 signature support is disabled due to FIPS\n");
35+
return -EOPNOTSUPP;
36+
}
37+
38+
md5_init(&ctx);
39+
md5_update(&ctx, server->session_key.response, server->session_key.len);
40+
41+
return __cifs_calc_signature(
42+
rqst, server, signature,
43+
&(struct cifs_calc_sig_ctx){ .md5 = &ctx });
44+
}
45+
46+
/* must be called with server->srv_mutex held */
47+
int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
48+
__u32 *pexpected_response_sequence_number)
49+
{
50+
int rc = 0;
51+
char smb_signature[20];
52+
struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
53+
54+
if ((cifs_pdu == NULL) || (server == NULL))
55+
return -EINVAL;
56+
57+
spin_lock(&server->srv_lock);
58+
if (!(cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) ||
59+
server->tcpStatus == CifsNeedNegotiate) {
60+
spin_unlock(&server->srv_lock);
61+
return rc;
62+
}
63+
spin_unlock(&server->srv_lock);
64+
65+
if (!server->session_estab) {
66+
memcpy(cifs_pdu->Signature.SecuritySignature, "BSRSPYL", 8);
67+
return rc;
68+
}
69+
70+
cifs_pdu->Signature.Sequence.SequenceNumber =
71+
cpu_to_le32(server->sequence_number);
72+
cifs_pdu->Signature.Sequence.Reserved = 0;
73+
74+
*pexpected_response_sequence_number = ++server->sequence_number;
75+
++server->sequence_number;
76+
77+
rc = cifs_calc_signature(rqst, server, smb_signature);
78+
if (rc)
79+
memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
80+
else
81+
memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
82+
83+
return rc;
84+
}
85+
86+
int cifs_verify_signature(struct smb_rqst *rqst,
87+
struct TCP_Server_Info *server,
88+
__u32 expected_sequence_number)
89+
{
90+
unsigned int rc;
91+
char server_response_sig[8];
92+
char what_we_think_sig_should_be[20];
93+
struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
94+
95+
if (cifs_pdu == NULL || server == NULL)
96+
return -EINVAL;
97+
98+
if (!server->session_estab)
99+
return 0;
100+
101+
if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) {
102+
struct smb_com_lock_req *pSMB =
103+
(struct smb_com_lock_req *)cifs_pdu;
104+
if (pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)
105+
return 0;
106+
}
107+
108+
/* BB what if signatures are supposed to be on for session but
109+
server does not send one? BB */
110+
111+
/* Do not need to verify session setups with signature "BSRSPYL " */
112+
if (memcmp(cifs_pdu->Signature.SecuritySignature, "BSRSPYL ", 8) == 0)
113+
cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
114+
cifs_pdu->Command);
115+
116+
/* save off the original signature so we can modify the smb and check
117+
its signature against what the server sent */
118+
memcpy(server_response_sig, cifs_pdu->Signature.SecuritySignature, 8);
119+
120+
cifs_pdu->Signature.Sequence.SequenceNumber =
121+
cpu_to_le32(expected_sequence_number);
122+
cifs_pdu->Signature.Sequence.Reserved = 0;
123+
124+
cifs_server_lock(server);
125+
rc = cifs_calc_signature(rqst, server, what_we_think_sig_should_be);
126+
cifs_server_unlock(server);
127+
128+
if (rc)
129+
return rc;
130+
131+
/* cifs_dump_mem("what we think it should be: ",
132+
what_we_think_sig_should_be, 16); */
133+
134+
if (memcmp(server_response_sig, what_we_think_sig_should_be, 8))
135+
return -EACCES;
136+
else
137+
return 0;
138+
139+
}

fs/smb/client/smb1proto.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,15 @@ int CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
219219
void cifs_dump_detail(void *buf, size_t buf_len,
220220
struct TCP_Server_Info *server);
221221

222+
/*
223+
* smb1encrypt.c
224+
*/
225+
int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
226+
__u32 *pexpected_response_sequence_number);
227+
int cifs_verify_signature(struct smb_rqst *rqst,
228+
struct TCP_Server_Info *server,
229+
__u32 expected_sequence_number);
230+
222231
/*
223232
* smb1maperror.c
224233
*/

0 commit comments

Comments
 (0)