summaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifsencrypt.c
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilov@microsoft.com>2016-11-23 18:14:57 -0500
committerSteve French <smfrench@gmail.com>2017-02-01 17:46:35 -0500
commit738f9de5cdb9175c19d24cfdf90b4543fc3b47bf (patch)
tree121fd4b54bec97e745cf6e6beb093b34408afd17 /fs/cifs/cifsencrypt.c
parentfb2036d817584df42504910fe104f68517e8990e (diff)
CIFS: Send RFC1001 length in a separate iov
In order to simplify further encryption support we need to separate RFC1001 length and SMB2 header when sending a request. Put the length field in iov[0] and the rest of the packet into following iovs. Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
Diffstat (limited to 'fs/cifs/cifsencrypt.c')
-rw-r--r--fs/cifs/cifsencrypt.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 66bd7fa9b7a6..d8af15f19dd8 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -75,24 +75,20 @@ int __cifs_calc_signature(struct smb_rqst *rqst,
75 struct kvec *iov = rqst->rq_iov; 75 struct kvec *iov = rqst->rq_iov;
76 int n_vec = rqst->rq_nvec; 76 int n_vec = rqst->rq_nvec;
77 77
78 for (i = 0; i < n_vec; i++) { 78 if (n_vec < 2 || iov[0].iov_len != 4)
79 return -EIO;
80
81 for (i = 1; i < n_vec; i++) {
79 if (iov[i].iov_len == 0) 82 if (iov[i].iov_len == 0)
80 continue; 83 continue;
81 if (iov[i].iov_base == NULL) { 84 if (iov[i].iov_base == NULL) {
82 cifs_dbg(VFS, "null iovec entry\n"); 85 cifs_dbg(VFS, "null iovec entry\n");
83 return -EIO; 86 return -EIO;
84 } 87 }
85 /* The first entry includes a length field (which does not get 88 if (i == 1 && iov[1].iov_len <= 4)
86 signed that occupies the first 4 bytes before the header */ 89 break; /* nothing to sign or corrupt header */
87 if (i == 0) { 90 rc = crypto_shash_update(shash,
88 if (iov[0].iov_len <= 8) /* cmd field at offset 9 */ 91 iov[i].iov_base, iov[i].iov_len);
89 break; /* nothing to sign or corrupt header */
90 rc = crypto_shash_update(shash,
91 iov[i].iov_base + 4, iov[i].iov_len - 4);
92 } else {
93 rc = crypto_shash_update(shash,
94 iov[i].iov_base, iov[i].iov_len);
95 }
96 if (rc) { 92 if (rc) {
97 cifs_dbg(VFS, "%s: Could not update with payload\n", 93 cifs_dbg(VFS, "%s: Could not update with payload\n",
98 __func__); 94 __func__);
@@ -168,6 +164,10 @@ int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
168 char smb_signature[20]; 164 char smb_signature[20];
169 struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base; 165 struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
170 166
167 if (rqst->rq_iov[0].iov_len != 4 ||
168 rqst->rq_iov[0].iov_base + 4 != rqst->rq_iov[1].iov_base)
169 return -EIO;
170
171 if ((cifs_pdu == NULL) || (server == NULL)) 171 if ((cifs_pdu == NULL) || (server == NULL))
172 return -EINVAL; 172 return -EINVAL;
173 173
@@ -209,12 +209,14 @@ int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
209int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, 209int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
210 __u32 *pexpected_response_sequence_number) 210 __u32 *pexpected_response_sequence_number)
211{ 211{
212 struct kvec iov; 212 struct kvec iov[2];
213 213
214 iov.iov_base = cifs_pdu; 214 iov[0].iov_base = cifs_pdu;
215 iov.iov_len = be32_to_cpu(cifs_pdu->smb_buf_length) + 4; 215 iov[0].iov_len = 4;
216 iov[1].iov_base = (char *)cifs_pdu + 4;
217 iov[1].iov_len = be32_to_cpu(cifs_pdu->smb_buf_length);
216 218
217 return cifs_sign_smbv(&iov, 1, server, 219 return cifs_sign_smbv(iov, 2, server,
218 pexpected_response_sequence_number); 220 pexpected_response_sequence_number);
219} 221}
220 222
@@ -227,6 +229,10 @@ int cifs_verify_signature(struct smb_rqst *rqst,
227 char what_we_think_sig_should_be[20]; 229 char what_we_think_sig_should_be[20];
228 struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base; 230 struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
229 231
232 if (rqst->rq_iov[0].iov_len != 4 ||
233 rqst->rq_iov[0].iov_base + 4 != rqst->rq_iov[1].iov_base)
234 return -EIO;
235
230 if (cifs_pdu == NULL || server == NULL) 236 if (cifs_pdu == NULL || server == NULL)
231 return -EINVAL; 237 return -EINVAL;
232 238