Commit af5fea51 authored by Eric Biggers's avatar Eric Biggers Committed by Steve French
Browse files

smb: client: Use SHA-512 library for SMB3.1.1 preauth hash



Convert smb311_update_preauth_hash() to use the SHA-512 library instead
of a "sha512" crypto_shash.  This is simpler and faster.  With the
library there's no need to allocate memory, no need to handle errors,
and the SHA-512 code is accessed directly without inefficient indirect
calls and other unnecessary API overhead.

Remove the call to smb311_crypto_shash_allocate() from
smb311_update_preauth_hash(), since it appears to have been needed only
to allocate the "sha512" crypto_shash.  (It also had the side effect of
allocating the "cmac(aes)" crypto_shash, but that's also done in
generate_key() which is where the AES-CMAC key is initialized.)

For now the "sha512" crypto_shash is still being allocated elsewhere.
It will be removed in a later commit.

Reviewed-by: default avatarStefan Metzmacher <metze@samba.org>
Acked-by: default avatarArd Biesheuvel <ardb@kernel.org>
Signed-off-by: default avatarEric Biggers <ebiggers@kernel.org>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 6447b0e3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ config CIFS
	select CRYPTO_ECB
	select CRYPTO_AES
	select CRYPTO_LIB_ARC4
	select CRYPTO_LIB_SHA512
	select KEYS
	select DNS_RESOLVER
	select ASN1
+12 −41
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
 *              Pavel Shilovsky (pshilovsky@samba.org) 2012
 *
 */
#include <crypto/sha2.h>
#include <linux/ctype.h>
#include "cifsglob.h"
#include "cifsproto.h"
@@ -888,13 +889,13 @@ smb2_handle_cancelled_mid(struct mid_q_entry *mid, struct TCP_Server_Info *serve
 * @iov:	array containing the SMB request we will send to the server
 * @nvec:	number of array entries for the iov
 */
int
void
smb311_update_preauth_hash(struct cifs_ses *ses, struct TCP_Server_Info *server,
			   struct kvec *iov, int nvec)
{
	int i, rc;
	int i;
	struct smb2_hdr *hdr;
	struct shash_desc *sha512 = NULL;
	struct sha512_ctx sha_ctx;

	hdr = (struct smb2_hdr *)iov[0].iov_base;
	/* neg prot are always taken */
@@ -907,52 +908,22 @@ smb311_update_preauth_hash(struct cifs_ses *ses, struct TCP_Server_Info *server,
	 * and we can test it. Preauth requires 3.1.1 for now.
	 */
	if (server->dialect != SMB311_PROT_ID)
		return 0;
		return;

	if (hdr->Command != SMB2_SESSION_SETUP)
		return 0;
		return;

	/* skip last sess setup response */
	if ((hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
	    && (hdr->Status == NT_STATUS_OK
		|| (hdr->Status !=
		    cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))))
		return 0;
		return;

ok:
	rc = smb311_crypto_shash_allocate(server);
	if (rc)
		return rc;

	sha512 = server->secmech.sha512;
	rc = crypto_shash_init(sha512);
	if (rc) {
		cifs_dbg(VFS, "%s: Could not init sha512 shash\n", __func__);
		return rc;
	}

	rc = crypto_shash_update(sha512, 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(sha512, 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(sha512, ses->preauth_sha_hash);
	if (rc) {
		cifs_dbg(VFS, "%s: Could not finalize sha512 shash\n",
			 __func__);
		return rc;
	}

	return 0;
	sha512_init(&sha_ctx);
	sha512_update(&sha_ctx, ses->preauth_sha_hash, SMB2_PREAUTH_HASH_SIZE);
	for (i = 0; i < nvec; i++)
		sha512_update(&sha_ctx, iov[i].iov_base, iov[i].iov_len);
	sha512_final(&sha_ctx, ses->preauth_sha_hash);
}
+3 −3
Original line number Diff line number Diff line
@@ -296,7 +296,7 @@ extern void smb2_copy_fs_info_to_kstatfs(
	 struct smb2_fs_full_size_info *pfs_inf,
	 struct kstatfs *kst);
extern int smb311_crypto_shash_allocate(struct TCP_Server_Info *server);
extern int smb311_update_preauth_hash(struct cifs_ses *ses,
extern void smb311_update_preauth_hash(struct cifs_ses *ses,
				       struct TCP_Server_Info *server,
				       struct kvec *iov, int nvec);
extern int smb2_query_info_compound(const unsigned int xid,