Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 429b46f4 authored by Steve French's avatar Steve French
Browse files

[CIFS] SMB3 Signing enablement



SMB3 uses a much faster method of signing (which is also better in other ways),
AES-CMAC.  With the kernel now supporting AES-CMAC since last release, we
are overdue to allow SMB3 signing (today only CIFS and SMB2 and SMB2.1,
but not SMB3 and SMB3.1 can sign) - and we need this also for checking
secure negotation and also per-share encryption (two other new SMB3 features
which we need to implement).

This patch needs some work in a few areas - for example we need to
move signing for SMB2/SMB3 from per-socket to per-user (we may be able to
use the "nosharesock" mount option in the interim for the multiuser case),
and Shirish found a bug in the earlier authentication overhaul
(setting signing flags properly) - but those can be done in followon
patches.

Signed-off-by: default avatarShirish Pargaonkar <shirishpargaonkar@gmail.com>
Signed-off-by: default avatarSteve French <smfrench@gmail.com>
parent f87ab88b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ config CIFS
	select CRYPTO_ECB
	select CRYPTO_DES
	select CRYPTO_SHA256
	select CRYPTO_CMAC
	help
	  This is the client VFS module for the Common Internet File System
	  (CIFS) protocol which is the successor to the Server Message Block
+29 −0
Original line number Diff line number Diff line
@@ -705,6 +705,9 @@ calc_seckey(struct cifs_ses *ses)
void
cifs_crypto_shash_release(struct TCP_Server_Info *server)
{
	if (server->secmech.cmacaes)
		crypto_free_shash(server->secmech.cmacaes);

	if (server->secmech.hmacsha256)
		crypto_free_shash(server->secmech.hmacsha256);

@@ -714,6 +717,8 @@ cifs_crypto_shash_release(struct TCP_Server_Info *server)
	if (server->secmech.hmacmd5)
		crypto_free_shash(server->secmech.hmacmd5);

	kfree(server->secmech.sdesccmacaes);

	kfree(server->secmech.sdeschmacsha256);

	kfree(server->secmech.sdeschmacmd5);
@@ -747,6 +752,13 @@ cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
		goto crypto_allocate_hmacsha256_fail;
	}

	server->secmech.cmacaes = crypto_alloc_shash("cmac(aes)", 0, 0);
	if (IS_ERR(server->secmech.cmacaes)) {
		cifs_dbg(VFS, "could not allocate crypto cmac-aes");
		rc = PTR_ERR(server->secmech.cmacaes);
		goto crypto_allocate_cmacaes_fail;
	}

	size = sizeof(struct shash_desc) +
			crypto_shash_descsize(server->secmech.hmacmd5);
	server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
@@ -777,8 +789,22 @@ cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
	server->secmech.sdeschmacsha256->shash.tfm = server->secmech.hmacsha256;
	server->secmech.sdeschmacsha256->shash.flags = 0x0;

	size = sizeof(struct shash_desc) +
			crypto_shash_descsize(server->secmech.cmacaes);
	server->secmech.sdesccmacaes = kmalloc(size, GFP_KERNEL);
	if (!server->secmech.sdesccmacaes) {
		cifs_dbg(VFS, "%s: Can't alloc cmacaes\n", __func__);
		rc = -ENOMEM;
		goto crypto_allocate_cmacaes_sdesc_fail;
	}
	server->secmech.sdesccmacaes->shash.tfm = server->secmech.cmacaes;
	server->secmech.sdesccmacaes->shash.flags = 0x0;

	return 0;

crypto_allocate_cmacaes_sdesc_fail:
	kfree(server->secmech.sdeschmacsha256);

crypto_allocate_hmacsha256_sdesc_fail:
	kfree(server->secmech.sdescmd5);

@@ -786,6 +812,9 @@ crypto_allocate_md5_sdesc_fail:
	kfree(server->secmech.sdeschmacmd5);

crypto_allocate_hmacmd5_sdesc_fail:
	crypto_free_shash(server->secmech.cmacaes);

crypto_allocate_cmacaes_fail:
	crypto_free_shash(server->secmech.hmacsha256);

crypto_allocate_hmacsha256_fail:
+3 −0
Original line number Diff line number Diff line
@@ -125,9 +125,11 @@ struct cifs_secmech {
	struct crypto_shash *hmacmd5; /* hmac-md5 hash function */
	struct crypto_shash *md5; /* md5 hash function */
	struct crypto_shash *hmacsha256; /* hmac-sha256 hash function */
	struct crypto_shash *cmacaes; /* block-cipher based MAC function */
	struct sdesc *sdeschmacmd5;  /* ctxt to generate ntlmv2 hash, CR1 */
	struct sdesc *sdescmd5; /* ctxt to generate cifs/smb signature */
	struct sdesc *sdeschmacsha256;  /* ctxt to generate smb2 signature */
	struct sdesc *sdesccmacaes;  /* ctxt to generate smb3 signature */
};

/* per smb session structure/fields */
@@ -538,6 +540,7 @@ struct TCP_Server_Info {
	int timeAdj;  /* Adjust for difference in server time zone in sec */
	__u64 CurrentMid;         /* multiplex id - rotating counter */
	char cryptkey[CIFS_CRYPTO_KEY_SIZE]; /* used by ntlm, ntlmv2 etc */
	char smb3signingkey[SMB3_SIGN_KEY_SIZE]; /* for signing smb3 packets */
	/* 16th byte of RFC1001 workstation name is always null */
	char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
	__u32 sequence_number; /* for signing, protected by srv_mutex */
+5 −0
Original line number Diff line number Diff line
@@ -142,6 +142,11 @@
 */
#define CIFS_SESS_KEY_SIZE (16)

/*
 * Size of the smb3 signing key
 */
#define SMB3_SIGN_KEY_SIZE (16)

#define CIFS_CLIENT_CHALLENGE_SIZE (8)
#define CIFS_SERVER_CHALLENGE_SIZE (8)
#define CIFS_HMAC_MD5_HASH_SIZE (16)
+1 −0
Original line number Diff line number Diff line
@@ -436,6 +436,7 @@ extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *);
extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *);
extern void cifs_crypto_shash_release(struct TCP_Server_Info *);
extern int calc_seckey(struct cifs_ses *);
extern int generate_smb3signingkey(struct TCP_Server_Info *);

#ifdef CONFIG_CIFS_WEAK_PW_HASH
extern int calc_lanman_hash(const char *password, const char *cryptkey,
Loading