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)
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;
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;
}
};
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,
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;
}
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,
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;
}
TALLOC_FREE(ptext);
TALLOC_FREE(ctext);
}
- gnutls_aead_cipher_deinit(cipher_hnd);
DBG_INFO("Enencrypted SMB2 message\n");
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);
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;
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)) {
* 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;
}
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);
* 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;
}
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);