|
|
b6b438 |
From 89fa1828d7b01416da929c234ec8612f113d6d60 Mon Sep 17 00:00:00 2001
|
|
|
b6b438 |
From: Andreas Schneider <asn@samba.org>
|
|
|
b6b438 |
Date: Thu, 14 Mar 2019 10:27:06 +0100
|
|
|
b6b438 |
Subject: [PATCH 128/187] libcli:smb: Use smb2_signing_key in
|
|
|
b6b438 |
smb2_signing_encrypt_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 eb65fe5505e32f451d4cf5d0203abce77c05dae4)
|
|
|
b6b438 |
---
|
|
|
b6b438 |
libcli/smb/smb2_signing.c | 34 +++++++++++++++-------------------
|
|
|
b6b438 |
libcli/smb/smb2_signing.h | 2 +-
|
|
|
b6b438 |
libcli/smb/smbXcli_base.c | 4 ++--
|
|
|
b6b438 |
source3/smbd/smb2_server.c | 16 ++++++++++++----
|
|
|
b6b438 |
4 files changed, 30 insertions(+), 26 deletions(-)
|
|
|
b6b438 |
|
|
|
b6b438 |
diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c
|
|
|
b6b438 |
index 15dbf3d8b2a..682327bb21b 100644
|
|
|
b6b438 |
--- a/libcli/smb/smb2_signing.c
|
|
|
b6b438 |
+++ b/libcli/smb/smb2_signing.c
|
|
|
b6b438 |
@@ -386,7 +386,7 @@ NTSTATUS smb2_key_derivation(const uint8_t *KI, size_t KI_len,
|
|
|
b6b438 |
return NT_STATUS_OK;
|
|
|
b6b438 |
}
|
|
|
b6b438 |
|
|
|
b6b438 |
-NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key,
|
|
|
b6b438 |
+NTSTATUS smb2_signing_encrypt_pdu(struct smb2_signing_key *encryption_key,
|
|
|
b6b438 |
uint16_t cipher_id,
|
|
|
b6b438 |
struct iovec *vector,
|
|
|
b6b438 |
int count)
|
|
|
b6b438 |
@@ -400,7 +400,6 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_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 |
@@ -416,9 +415,9 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key,
|
|
|
b6b438 |
|
|
|
b6b438 |
tf = (uint8_t *)vector[0].iov_base;
|
|
|
b6b438 |
|
|
|
b6b438 |
- if (encryption_key.length == 0) {
|
|
|
b6b438 |
- DEBUG(2,("Wrong encryption key length %u for SMB2 signing\n",
|
|
|
b6b438 |
- (unsigned)encryption_key.length));
|
|
|
b6b438 |
+ if (!smb2_signing_key_valid(encryption_key)) {
|
|
|
b6b438 |
+ DBG_WARNING("Wrong encryption key length %zu for SMB2 signing\n",
|
|
|
b6b438 |
+ encryption_key->blob.length);
|
|
|
b6b438 |
return NT_STATUS_ACCESS_DENIED;
|
|
|
b6b438 |
}
|
|
|
b6b438 |
|
|
|
b6b438 |
@@ -458,20 +457,22 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key,
|
|
|
b6b438 |
};
|
|
|
b6b438 |
|
|
|
b6b438 |
memcpy(key.data,
|
|
|
b6b438 |
- encryption_key.data,
|
|
|
b6b438 |
- MIN(encryption_key.length, key.size));
|
|
|
b6b438 |
+ encryption_key->blob.data,
|
|
|
b6b438 |
+ MIN(encryption_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 (encryption_key->cipher_hnd == NULL) {
|
|
|
b6b438 |
+ rc = gnutls_aead_cipher_init(&encryption_key->cipher_hnd,
|
|
|
b6b438 |
+ algo,
|
|
|
b6b438 |
+ &key);
|
|
|
b6b438 |
+ if (rc < 0) {
|
|
|
b6b438 |
+ status = NT_STATUS_NO_MEMORY;
|
|
|
b6b438 |
+ goto out;
|
|
|
b6b438 |
+ }
|
|
|
b6b438 |
}
|
|
|
b6b438 |
|
|
|
b6b438 |
memset(tf + SMB2_TF_NONCE + iv_size,
|
|
|
b6b438 |
@@ -487,14 +488,12 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_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 |
|
|
|
b6b438 |
ctext = talloc_size(talloc_tos(), ctext_size);
|
|
|
b6b438 |
if (ctext == NULL) {
|
|
|
b6b438 |
- gnutls_aead_cipher_deinit(cipher_hnd);
|
|
|
b6b438 |
status = NT_STATUS_NO_MEMORY;
|
|
|
b6b438 |
goto out;
|
|
|
b6b438 |
}
|
|
|
b6b438 |
@@ -508,13 +507,12 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key,
|
|
|
b6b438 |
if (len > ptext_size) {
|
|
|
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 |
}
|
|
|
b6b438 |
|
|
|
b6b438 |
- rc = gnutls_aead_cipher_encrypt(cipher_hnd,
|
|
|
b6b438 |
+ rc = gnutls_aead_cipher_encrypt(encryption_key->cipher_hnd,
|
|
|
b6b438 |
iv.data,
|
|
|
b6b438 |
iv.size,
|
|
|
b6b438 |
tf + SMB2_TF_NONCE,
|
|
|
b6b438 |
@@ -528,7 +526,6 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_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 |
@@ -547,7 +544,6 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key,
|
|
|
b6b438 |
TALLOC_FREE(ptext);
|
|
|
b6b438 |
TALLOC_FREE(ctext);
|
|
|
b6b438 |
}
|
|
|
b6b438 |
- gnutls_aead_cipher_deinit(cipher_hnd);
|
|
|
b6b438 |
|
|
|
b6b438 |
DBG_INFO("Enencrypted SMB2 message\n");
|
|
|
b6b438 |
|
|
|
b6b438 |
diff --git a/libcli/smb/smb2_signing.h b/libcli/smb/smb2_signing.h
|
|
|
b6b438 |
index 7eefad93b3e..e28b5c8de9a 100644
|
|
|
b6b438 |
--- a/libcli/smb/smb2_signing.h
|
|
|
b6b438 |
+++ b/libcli/smb/smb2_signing.h
|
|
|
b6b438 |
@@ -53,7 +53,7 @@ NTSTATUS smb2_key_derivation(const uint8_t *KI, size_t KI_len,
|
|
|
b6b438 |
const uint8_t *Context, size_t Context_len,
|
|
|
b6b438 |
uint8_t KO[16]);
|
|
|
b6b438 |
|
|
|
b6b438 |
-NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key,
|
|
|
b6b438 |
+NTSTATUS smb2_signing_encrypt_pdu(struct smb2_signing_key *encryption_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 421fc434305..d9837d48083 100644
|
|
|
b6b438 |
--- a/libcli/smb/smbXcli_base.c
|
|
|
b6b438 |
+++ b/libcli/smb/smbXcli_base.c
|
|
|
b6b438 |
@@ -3090,7 +3090,7 @@ NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs,
|
|
|
b6b438 |
struct iovec *iov;
|
|
|
b6b438 |
int i, num_iov, nbt_len;
|
|
|
b6b438 |
int tf_iov = -1;
|
|
|
b6b438 |
- const struct smb2_signing_key *encryption_key = NULL;
|
|
|
b6b438 |
+ struct smb2_signing_key *encryption_key = NULL;
|
|
|
b6b438 |
uint64_t encryption_session_id = 0;
|
|
|
b6b438 |
uint64_t nonce_high = UINT64_MAX;
|
|
|
b6b438 |
uint64_t nonce_low = UINT64_MAX;
|
|
|
b6b438 |
@@ -3379,7 +3379,7 @@ skip_credits:
|
|
|
b6b438 |
buf += v->iov_len;
|
|
|
b6b438 |
}
|
|
|
b6b438 |
|
|
|
b6b438 |
- status = smb2_signing_encrypt_pdu(encryption_key->blob,
|
|
|
b6b438 |
+ status = smb2_signing_encrypt_pdu(encryption_key,
|
|
|
b6b438 |
state->conn->smb2.server.cipher,
|
|
|
b6b438 |
&iov[tf_iov], num_iov - tf_iov);
|
|
|
b6b438 |
if (!NT_STATUS_IS_OK(status)) {
|
|
|
b6b438 |
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
|
|
|
b6b438 |
index 9df22b5a6ac..0776fa2bdd2 100644
|
|
|
b6b438 |
--- a/source3/smbd/smb2_server.c
|
|
|
b6b438 |
+++ b/source3/smbd/smb2_server.c
|
|
|
b6b438 |
@@ -1336,10 +1336,14 @@ static NTSTATUS smb2_send_async_interim_response(const struct smbd_smb2_request
|
|
|
b6b438 |
* we need to sign/encrypt here with the last/first key we remembered
|
|
|
b6b438 |
*/
|
|
|
b6b438 |
if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
|
|
|
b6b438 |
- status = smb2_signing_encrypt_pdu(req->first_key,
|
|
|
b6b438 |
+ struct smb2_signing_key key = {
|
|
|
b6b438 |
+ .blob = req->first_key,
|
|
|
b6b438 |
+ };
|
|
|
b6b438 |
+ status = smb2_signing_encrypt_pdu(&key,
|
|
|
b6b438 |
xconn->smb2.server.cipher,
|
|
|
b6b438 |
firsttf,
|
|
|
b6b438 |
nreq->out.vector_count - first_idx);
|
|
|
b6b438 |
+ smb2_signing_key_destructor(&key);
|
|
|
b6b438 |
if (!NT_STATUS_IS_OK(status)) {
|
|
|
b6b438 |
return status;
|
|
|
b6b438 |
}
|
|
|
b6b438 |
@@ -1739,7 +1743,7 @@ static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
|
|
|
b6b438 |
struct smbXsrv_session *x = req->session;
|
|
|
b6b438 |
struct smb2_signing_key *encryption_key = x->global->encryption_key;
|
|
|
b6b438 |
|
|
|
b6b438 |
- status = smb2_signing_encrypt_pdu(encryption_key->blob,
|
|
|
b6b438 |
+ status = smb2_signing_encrypt_pdu(encryption_key,
|
|
|
b6b438 |
xconn->smb2.server.cipher,
|
|
|
b6b438 |
&state->vector[1+SMBD_SMB2_TF_IOV_OFS],
|
|
|
b6b438 |
SMBD_SMB2_NUM_IOV_PER_REQ);
|
|
|
b6b438 |
@@ -2994,10 +2998,14 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
|
|
|
b6b438 |
* now check if we need to sign the current response
|
|
|
b6b438 |
*/
|
|
|
b6b438 |
if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
|
|
|
b6b438 |
- status = smb2_signing_encrypt_pdu(req->first_key,
|
|
|
b6b438 |
+ struct smb2_signing_key key = {
|
|
|
b6b438 |
+ .blob = req->first_key,
|
|
|
b6b438 |
+ };
|
|
|
b6b438 |
+ status = smb2_signing_encrypt_pdu(&key,
|
|
|
b6b438 |
xconn->smb2.server.cipher,
|
|
|
b6b438 |
firsttf,
|
|
|
b6b438 |
req->out.vector_count - first_idx);
|
|
|
b6b438 |
+ smb2_signing_key_destructor(&key);
|
|
|
b6b438 |
if (!NT_STATUS_IS_OK(status)) {
|
|
|
b6b438 |
return status;
|
|
|
b6b438 |
}
|
|
|
b6b438 |
@@ -3419,7 +3427,7 @@ static NTSTATUS smbd_smb2_send_break(struct smbXsrv_connection *xconn,
|
|
|
b6b438 |
struct smb2_signing_key *encryption_key =
|
|
|
b6b438 |
session->global->encryption_key;
|
|
|
b6b438 |
|
|
|
b6b438 |
- status = smb2_signing_encrypt_pdu(encryption_key->blob,
|
|
|
b6b438 |
+ status = smb2_signing_encrypt_pdu(encryption_key,
|
|
|
b6b438 |
xconn->smb2.server.cipher,
|
|
|
b6b438 |
&state->vector[1+SMBD_SMB2_TF_IOV_OFS],
|
|
|
b6b438 |
SMBD_SMB2_NUM_IOV_PER_REQ);
|
|
|
b6b438 |
--
|
|
|
b6b438 |
2.23.0
|
|
|
b6b438 |
|