libcli:smb: Use smb2_signing_key in smb2_signing_encrypt_pdu()
authorAndreas Schneider <asn@samba.org>
Thu, 14 Mar 2019 09:27:06 +0000 (10:27 +0100)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 27 Aug 2019 04:44:41 +0000 (04:44 +0000)
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Adaped to remove Samba AES support

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
libcli/smb/smb2_signing.c
libcli/smb/smb2_signing.h
libcli/smb/smbXcli_base.c
source3/smbd/smb2_server.c

index 15dbf3d8b2a70714779fcbd2e4cc5e14f74ea7c7..682327bb21b843c6c4ac019e5507423239eedf06 100644 (file)
@@ -386,7 +386,7 @@ NTSTATUS smb2_key_derivation(const uint8_t *KI, size_t KI_len,
        return NT_STATUS_OK;
 }
 
-NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key,
+NTSTATUS smb2_signing_encrypt_pdu(struct smb2_signing_key *encryption_key,
                                  uint16_t cipher_id,
                                  struct iovec *vector,
                                  int count)
@@ -400,7 +400,6 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key,
        uint32_t tag_size = 0;
        uint8_t _key[16] = {0};
        gnutls_cipher_algorithm_t algo = 0;
-       gnutls_aead_cipher_hd_t cipher_hnd = NULL;
        gnutls_datum_t key;
        gnutls_datum_t iv;
        NTSTATUS status;
@@ -416,9 +415,9 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key,
 
        tf = (uint8_t *)vector[0].iov_base;
 
-       if (encryption_key.length == 0) {
-               DEBUG(2,("Wrong encryption key length %u for SMB2 signing\n",
-                        (unsigned)encryption_key.length));
+       if (!smb2_signing_key_valid(encryption_key)) {
+               DBG_WARNING("Wrong encryption key length %zu for SMB2 signing\n",
+                           encryption_key->blob.length);
                return NT_STATUS_ACCESS_DENIED;
        }
 
@@ -458,20 +457,22 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key,
        };
 
        memcpy(key.data,
-              encryption_key.data,
-              MIN(encryption_key.length, key.size));
+              encryption_key->blob.data,
+              MIN(encryption_key->blob.length, key.size));
 
        iv = (gnutls_datum_t) {
                .data = tf + SMB2_TF_NONCE,
                .size = iv_size,
        };
 
-       rc = gnutls_aead_cipher_init(&cipher_hnd,
-                               algo,
-                               &key);
-       if (rc < 0) {
-               status = NT_STATUS_NO_MEMORY;
-               goto out;
+       if (encryption_key->cipher_hnd == NULL) {
+               rc = gnutls_aead_cipher_init(&encryption_key->cipher_hnd,
+                                       algo,
+                                       &key);
+               if (rc < 0) {
+                       status = NT_STATUS_NO_MEMORY;
+                       goto out;
+               }
        }
 
        memset(tf + SMB2_TF_NONCE + iv_size,
@@ -487,14 +488,12 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key,
 
                ptext = talloc_size(talloc_tos(), ptext_size);
                if (ptext == NULL) {
-                       gnutls_aead_cipher_deinit(cipher_hnd);
                        status = NT_STATUS_NO_MEMORY;
                        goto out;
                }
 
                ctext = talloc_size(talloc_tos(), ctext_size);
                if (ctext == NULL) {
-                       gnutls_aead_cipher_deinit(cipher_hnd);
                        status = NT_STATUS_NO_MEMORY;
                        goto out;
                }
@@ -508,13 +507,12 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key,
                        if (len > ptext_size) {
                                TALLOC_FREE(ptext);
                                TALLOC_FREE(ctext);
-                               gnutls_aead_cipher_deinit(cipher_hnd);
                                status = NT_STATUS_INTERNAL_ERROR;
                                goto out;
                        }
                }
 
-               rc = gnutls_aead_cipher_encrypt(cipher_hnd,
+               rc = gnutls_aead_cipher_encrypt(encryption_key->cipher_hnd,
                                                iv.data,
                                                iv.size,
                                                tf + SMB2_TF_NONCE,
@@ -528,7 +526,6 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key,
                        DBG_ERR("ERROR: %s\n", gnutls_strerror(rc));
                        TALLOC_FREE(ptext);
                        TALLOC_FREE(ctext);
-                       gnutls_aead_cipher_deinit(cipher_hnd);
                        status = NT_STATUS_INTERNAL_ERROR;
                        goto out;
                }
@@ -547,7 +544,6 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key,
                TALLOC_FREE(ptext);
                TALLOC_FREE(ctext);
        }
-       gnutls_aead_cipher_deinit(cipher_hnd);
 
        DBG_INFO("Enencrypted SMB2 message\n");
 
index 7eefad93b3ebf92cc0e74f226481fe5c4f02f384..e28b5c8de9ac415ff3aba2eae269096d54320047 100644 (file)
@@ -53,7 +53,7 @@ NTSTATUS smb2_key_derivation(const uint8_t *KI, size_t KI_len,
                             const uint8_t *Context, size_t Context_len,
                             uint8_t KO[16]);
 
-NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key,
+NTSTATUS smb2_signing_encrypt_pdu(struct smb2_signing_key *encryption_key,
                                  uint16_t cipher_id,
                                  struct iovec *vector,
                                  int count);
index 22dd0ea219f1b45a95052d10f63d2a3e63182848..93cd936dde989c73aba93b282a782422862b263b 100644 (file)
@@ -3091,7 +3091,7 @@ NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs,
        struct iovec *iov;
        int i, num_iov, nbt_len;
        int tf_iov = -1;
-       const struct smb2_signing_key *encryption_key = NULL;
+       struct smb2_signing_key *encryption_key = NULL;
        uint64_t encryption_session_id = 0;
        uint64_t nonce_high = UINT64_MAX;
        uint64_t nonce_low = UINT64_MAX;
@@ -3380,7 +3380,7 @@ skip_credits:
                        buf += v->iov_len;
                }
 
-               status = smb2_signing_encrypt_pdu(encryption_key->blob,
+               status = smb2_signing_encrypt_pdu(encryption_key,
                                        state->conn->smb2.server.cipher,
                                        &iov[tf_iov], num_iov - tf_iov);
                if (!NT_STATUS_IS_OK(status)) {
index 9df22b5a6ac10bc2b69a12ec538f03571f597279..0776fa2bdd2156a7fdcaaaba5e46fd7c7421612a 100644 (file)
@@ -1336,10 +1336,14 @@ static NTSTATUS smb2_send_async_interim_response(const struct smbd_smb2_request
         * we need to sign/encrypt here with the last/first key we remembered
         */
        if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
-               status = smb2_signing_encrypt_pdu(req->first_key,
+               struct smb2_signing_key key = {
+                       .blob = req->first_key,
+               };
+               status = smb2_signing_encrypt_pdu(&key,
                                        xconn->smb2.server.cipher,
                                        firsttf,
                                        nreq->out.vector_count - first_idx);
+               smb2_signing_key_destructor(&key);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
@@ -1739,7 +1743,7 @@ static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
                struct smbXsrv_session *x = req->session;
                struct smb2_signing_key *encryption_key = x->global->encryption_key;
 
-               status = smb2_signing_encrypt_pdu(encryption_key->blob,
+               status = smb2_signing_encrypt_pdu(encryption_key,
                                        xconn->smb2.server.cipher,
                                        &state->vector[1+SMBD_SMB2_TF_IOV_OFS],
                                        SMBD_SMB2_NUM_IOV_PER_REQ);
@@ -2994,10 +2998,14 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
         * now check if we need to sign the current response
         */
        if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
-               status = smb2_signing_encrypt_pdu(req->first_key,
+               struct smb2_signing_key key = {
+                       .blob = req->first_key,
+               };
+               status = smb2_signing_encrypt_pdu(&key,
                                        xconn->smb2.server.cipher,
                                        firsttf,
                                        req->out.vector_count - first_idx);
+               smb2_signing_key_destructor(&key);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
@@ -3419,7 +3427,7 @@ static NTSTATUS smbd_smb2_send_break(struct smbXsrv_connection *xconn,
                struct smb2_signing_key *encryption_key =
                        session->global->encryption_key;
 
-               status = smb2_signing_encrypt_pdu(encryption_key->blob,
+               status = smb2_signing_encrypt_pdu(encryption_key,
                                        xconn->smb2.server.cipher,
                                        &state->vector[1+SMBD_SMB2_TF_IOV_OFS],
                                        SMBD_SMB2_NUM_IOV_PER_REQ);