diff options
author | Aurelien Aptel <aaptel@suse.com> | 2018-02-16 21:19:29 +0300 |
---|---|---|
committer | Steve French <stfrench@microsoft.com> | 2018-04-02 04:24:40 +0300 |
commit | 8bd68c6e47abff34e412a0c68cecb4a36bf0198b (patch) | |
tree | 843fb398bb4b5f6ee1e6a5235bb9ce57a8d4b477 /fs/cifs/smb2misc.c | |
parent | 5fcd7f3f966f37f3f9a215af4cc1597fe338d0d5 (diff) | |
download | linux-8bd68c6e47abff34e412a0c68cecb4a36bf0198b.tar.xz |
CIFS: implement v3.11 preauth integrity
SMB3.11 clients must implement pre-authentification integrity.
* new mechanism to certify requests/responses happening before Tree
Connect.
* supersedes VALIDATE_NEGOTIATE
* fixes signing for SMB3.11
Signed-off-by: Aurelien Aptel <aaptel@suse.com>
Signed-off-by: Steve French <smfrench@gmail.com>
CC: Stable <stable@vger.kernel.org>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
Diffstat (limited to 'fs/cifs/smb2misc.c')
-rw-r--r-- | fs/cifs/smb2misc.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c index 76d03abaa38c..da012c3ab700 100644 --- a/fs/cifs/smb2misc.c +++ b/fs/cifs/smb2misc.c @@ -706,3 +706,67 @@ smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server) return 0; } + +#ifdef CONFIG_CIFS_SMB311 +/** + * smb311_update_preauth_hash - update @ses hash with the packet data in @iov + * + * Assumes @iov does not contain the rfc1002 length and iov[0] has the + * SMB2 header. + */ +int +smb311_update_preauth_hash(struct cifs_ses *ses, struct kvec *iov, int nvec) +{ + int i, rc; + struct sdesc *d; + struct smb2_sync_hdr *hdr; + + if (ses->server->tcpStatus == CifsGood) { + /* skip non smb311 connections */ + if (ses->server->dialect != SMB311_PROT_ID) + return 0; + + /* skip last sess setup response */ + hdr = (struct smb2_sync_hdr *)iov[0].iov_base; + if (hdr->Flags & SMB2_FLAGS_SIGNED) + return 0; + } + + rc = smb311_crypto_shash_allocate(ses->server); + if (rc) + return rc; + + d = ses->server->secmech.sdescsha512; + rc = crypto_shash_init(&d->shash); + if (rc) { + cifs_dbg(VFS, "%s: could not init sha512 shash\n", __func__); + return rc; + } + + rc = crypto_shash_update(&d->shash, ses->preauth_sha_hash, + SMB2_PREAUTH_HASH_SIZE); + if (rc) { + cifs_dbg(VFS, "%s: could not update sha512 shash\n", __func__); + return rc; + } + + for (i = 0; i < nvec; i++) { + rc = crypto_shash_update(&d->shash, + iov[i].iov_base, iov[i].iov_len); + if (rc) { + cifs_dbg(VFS, "%s: could not update sha512 shash\n", + __func__); + return rc; + } + } + + rc = crypto_shash_final(&d->shash, ses->preauth_sha_hash); + if (rc) { + cifs_dbg(VFS, "%s: could not finalize sha512 shash\n", + __func__); + return rc; + } + + return 0; +} +#endif |