b6b438
From fcbef176770dc8531ab9eb8bb091b44b3923f405 Mon Sep 17 00:00:00 2001
b6b438
From: Andreas Schneider <asn@samba.org>
b6b438
Date: Thu, 14 Mar 2019 10:53:23 +0100
b6b438
Subject: [PATCH 126/187] libcli:smb: Use smb2_signing_key in
b6b438
 smb2_signing_decrypt_pdu()
b6b438
b6b438
Signed-off-by: Andreas Schneider <asn@samba.org>
b6b438
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
b6b438
b6b438
Adaped to remove Samba AES support
b6b438
b6b438
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
b6b438
(cherry picked from commit 7f56e91dbe404bc1ee40e4843c4046336945b057)
b6b438
---
b6b438
 libcli/smb/smb2_signing.c  | 34 +++++++++++++++-------------------
b6b438
 libcli/smb/smb2_signing.h  |  2 +-
b6b438
 libcli/smb/smbXcli_base.c  |  2 +-
b6b438
 source3/smbd/smb2_server.c |  2 +-
b6b438
 4 files changed, 18 insertions(+), 22 deletions(-)
b6b438
b6b438
diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c
b6b438
index 1d9c99337d8..9f40e8bbea5 100644
b6b438
--- a/libcli/smb/smb2_signing.c
b6b438
+++ b/libcli/smb/smb2_signing.c
b6b438
@@ -558,7 +558,7 @@ out:
b6b438
 	return status;
b6b438
 }
b6b438
 
b6b438
-NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key,
b6b438
+NTSTATUS smb2_signing_decrypt_pdu(struct smb2_signing_key *decryption_key,
b6b438
 				  uint16_t cipher_id,
b6b438
 				  struct iovec *vector,
b6b438
 				  int count)
b6b438
@@ -574,7 +574,6 @@ NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key,
b6b438
 	uint32_t tag_size = 0;
b6b438
 	uint8_t _key[16] = {0};
b6b438
 	gnutls_cipher_algorithm_t algo = 0;
b6b438
-	gnutls_aead_cipher_hd_t cipher_hnd = NULL;
b6b438
 	gnutls_datum_t key;
b6b438
 	gnutls_datum_t iv;
b6b438
 	NTSTATUS status;
b6b438
@@ -590,9 +589,9 @@ NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key,
b6b438
 
b6b438
 	tf = (uint8_t *)vector[0].iov_base;
b6b438
 
b6b438
-	if (decryption_key.length == 0) {
b6b438
-		DEBUG(2,("Wrong decryption key length %u for SMB2 signing\n",
b6b438
-			 (unsigned)decryption_key.length));
b6b438
+	if (!smb2_signing_key_valid(decryption_key)) {
b6b438
+		DBG_WARNING("Wrong decryption key length %zu for SMB2 signing\n",
b6b438
+			    decryption_key->blob.length);
b6b438
 		return NT_STATUS_ACCESS_DENIED;
b6b438
 	}
b6b438
 
b6b438
@@ -640,20 +639,22 @@ NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key,
b6b438
 	};
b6b438
 
b6b438
 	memcpy(key.data,
b6b438
-	       decryption_key.data,
b6b438
-	       MIN(decryption_key.length, key.size));
b6b438
+	       decryption_key->blob.data,
b6b438
+	       MIN(decryption_key->blob.length, key.size));
b6b438
 
b6b438
 	iv = (gnutls_datum_t) {
b6b438
 		.data = tf + SMB2_TF_NONCE,
b6b438
 		.size = iv_size,
b6b438
 	};
b6b438
 
b6b438
-	rc = gnutls_aead_cipher_init(&cipher_hnd,
b6b438
-				     algo,
b6b438
-				     &key);
b6b438
-	if (rc < 0) {
b6b438
-		status = NT_STATUS_NO_MEMORY;
b6b438
-		goto out;
b6b438
+	if (decryption_key->cipher_hnd == NULL) {
b6b438
+		rc = gnutls_aead_cipher_init(&decryption_key->cipher_hnd,
b6b438
+					     algo,
b6b438
+					     &key);
b6b438
+		if (rc < 0) {
b6b438
+			status = NT_STATUS_NO_MEMORY;
b6b438
+			goto out;
b6b438
+		}
b6b438
 	}
b6b438
 
b6b438
 	{
b6b438
@@ -667,7 +668,6 @@ NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key,
b6b438
 
b6b438
 		ptext = talloc_size(talloc_tos(), ptext_size);
b6b438
 		if (ptext == NULL) {
b6b438
-			gnutls_aead_cipher_deinit(cipher_hnd);
b6b438
 			status = NT_STATUS_NO_MEMORY;
b6b438
 			goto out;
b6b438
 		}
b6b438
@@ -675,7 +675,6 @@ NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key,
b6b438
 		ctext = talloc_size(talloc_tos(), ctext_size);
b6b438
 		if (ctext == NULL) {
b6b438
 			TALLOC_FREE(ptext);
b6b438
-			gnutls_aead_cipher_deinit(cipher_hnd);
b6b438
 			status = NT_STATUS_NO_MEMORY;
b6b438
 			goto out;
b6b438
 		}
b6b438
@@ -691,7 +690,6 @@ NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key,
b6b438
 		if (len != m_total) {
b6b438
 			TALLOC_FREE(ptext);
b6b438
 			TALLOC_FREE(ctext);
b6b438
-			gnutls_aead_cipher_deinit(cipher_hnd);
b6b438
 			status = NT_STATUS_INTERNAL_ERROR;
b6b438
 			goto out;
b6b438
 		}
b6b438
@@ -701,7 +699,7 @@ NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key,
b6b438
 		       tag_size);
b6b438
 
b6b438
 		/* This function will verify the tag */
b6b438
-		rc = gnutls_aead_cipher_decrypt(cipher_hnd,
b6b438
+		rc = gnutls_aead_cipher_decrypt(decryption_key->cipher_hnd,
b6b438
 						iv.data,
b6b438
 						iv.size,
b6b438
 						tf + SMB2_TF_NONCE,
b6b438
@@ -715,7 +713,6 @@ NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key,
b6b438
 			DBG_ERR("ERROR: %s\n", gnutls_strerror(rc));
b6b438
 			TALLOC_FREE(ptext);
b6b438
 			TALLOC_FREE(ctext);
b6b438
-			gnutls_aead_cipher_deinit(cipher_hnd);
b6b438
 			status = NT_STATUS_INTERNAL_ERROR;
b6b438
 			goto out;
b6b438
 		}
b6b438
@@ -732,7 +729,6 @@ NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key,
b6b438
 		TALLOC_FREE(ptext);
b6b438
 		TALLOC_FREE(ctext);
b6b438
 	}
b6b438
-	gnutls_aead_cipher_deinit(cipher_hnd);
b6b438
 
b6b438
 	DBG_INFO("Decrypted SMB2 message\n");
b6b438
 
b6b438
diff --git a/libcli/smb/smb2_signing.h b/libcli/smb/smb2_signing.h
b6b438
index 13fb54e4e4e..7eefad93b3e 100644
b6b438
--- a/libcli/smb/smb2_signing.h
b6b438
+++ b/libcli/smb/smb2_signing.h
b6b438
@@ -57,7 +57,7 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key,
b6b438
 				  uint16_t cipher_id,
b6b438
 				  struct iovec *vector,
b6b438
 				  int count);
b6b438
-NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key,
b6b438
+NTSTATUS smb2_signing_decrypt_pdu(struct smb2_signing_key *decryption_key,
b6b438
 				  uint16_t cipher_id,
b6b438
 				  struct iovec *vector,
b6b438
 				  int count);
b6b438
diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
b6b438
index aa69c374d49..421fc434305 100644
b6b438
--- a/libcli/smb/smbXcli_base.c
b6b438
+++ b/libcli/smb/smbXcli_base.c
b6b438
@@ -3567,7 +3567,7 @@ static NTSTATUS smb2cli_inbuf_parse_compound(struct smbXcli_conn *conn,
b6b438
 			tf_iov[1].iov_base = (void *)hdr;
b6b438
 			tf_iov[1].iov_len = enc_len;
b6b438
 
b6b438
-			status = smb2_signing_decrypt_pdu(s->smb2->decryption_key->blob,
b6b438
+			status = smb2_signing_decrypt_pdu(s->smb2->decryption_key,
b6b438
 							  conn->smb2.server.cipher,
b6b438
 							  tf_iov, 2);
b6b438
 			if (!NT_STATUS_IS_OK(status)) {
b6b438
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
b6b438
index 56e7b70696b..9df22b5a6ac 100644
b6b438
--- a/source3/smbd/smb2_server.c
b6b438
+++ b/source3/smbd/smb2_server.c
b6b438
@@ -432,7 +432,7 @@ static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *xconn,
b6b438
 			tf_iov[1].iov_base = (void *)hdr;
b6b438
 			tf_iov[1].iov_len = enc_len;
b6b438
 
b6b438
-			status = smb2_signing_decrypt_pdu(s->global->decryption_key->blob,
b6b438
+			status = smb2_signing_decrypt_pdu(s->global->decryption_key,
b6b438
 							  xconn->smb2.server.cipher,
b6b438
 							  tf_iov, 2);
b6b438
 			if (!NT_STATUS_IS_OK(status)) {
b6b438
-- 
b6b438
2.23.0
b6b438