diff options
author | Pavel Shilovsky <pshilov@microsoft.com> | 2016-11-23 18:14:57 -0500 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2017-02-01 17:46:35 -0500 |
commit | 738f9de5cdb9175c19d24cfdf90b4543fc3b47bf (patch) | |
tree | 121fd4b54bec97e745cf6e6beb093b34408afd17 /fs/cifs/cifsencrypt.c | |
parent | fb2036d817584df42504910fe104f68517e8990e (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.c | 38 |
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, | |||
209 | int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, | 209 | int 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 | ||