#include "../lib/crypto/crypto.h"
#include "lib/util/iov_buf.h"
+#include "libcli/util/gnutls_error.h"
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
return NT_STATUS_OK;
}
-void smb2_key_derivation(const uint8_t *KI, size_t KI_len,
- const uint8_t *Label, size_t Label_len,
- const uint8_t *Context, size_t Context_len,
- uint8_t KO[16])
+NTSTATUS smb2_key_derivation(const uint8_t *KI, size_t KI_len,
+ const uint8_t *Label, size_t Label_len,
+ const uint8_t *Context, size_t Context_len,
+ uint8_t KO[16])
{
gnutls_hmac_hd_t hmac_hnd = NULL;
uint8_t buf[4];
GNUTLS_MAC_SHA256,
KI,
KI_len);
- if (rc != 0) {
- return;
+ if (rc < 0) {
+ return gnutls_error_to_ntstatus(rc,
+ NT_STATUS_HMAC_NOT_SUPPORTED);
}
RSIVAL(buf, 0, i);
rc = gnutls_hmac(hmac_hnd, buf, sizeof(buf));
if (rc < 0) {
- gnutls_hmac_deinit(hmac_hnd, NULL);
- return;
+ return gnutls_error_to_ntstatus(rc,
+ NT_STATUS_HMAC_NOT_SUPPORTED);
}
rc = gnutls_hmac(hmac_hnd, Label, Label_len);
if (rc < 0) {
gnutls_hmac_deinit(hmac_hnd, NULL);
- return;
+ return gnutls_error_to_ntstatus(rc,
+ NT_STATUS_HMAC_NOT_SUPPORTED);
}
rc = gnutls_hmac(hmac_hnd, &zero, 1);
if (rc < 0) {
gnutls_hmac_deinit(hmac_hnd, NULL);
- return;
+ return gnutls_error_to_ntstatus(rc,
+ NT_STATUS_HMAC_NOT_SUPPORTED);
}
rc = gnutls_hmac(hmac_hnd, Context, Context_len);
if (rc < 0) {
gnutls_hmac_deinit(hmac_hnd, NULL);
- return;
+ return gnutls_error_to_ntstatus(rc,
+ NT_STATUS_HMAC_NOT_SUPPORTED);
}
RSIVAL(buf, 0, L);
rc = gnutls_hmac(hmac_hnd, buf, sizeof(buf));
if (rc < 0) {
gnutls_hmac_deinit(hmac_hnd, NULL);
- return;
+ return gnutls_error_to_ntstatus(rc,
+ NT_STATUS_HMAC_NOT_SUPPORTED);
}
gnutls_hmac_deinit(hmac_hnd, digest);
memcpy(KO, digest, 16);
ZERO_ARRAY(digest);
+
+ return NT_STATUS_OK;
}
NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key,
const struct iovec *vector,
int count);
-void smb2_key_derivation(const uint8_t *KI, size_t KI_len,
- const uint8_t *Label, size_t Label_len,
- const uint8_t *Context, size_t Context_len,
- uint8_t KO[16]);
+NTSTATUS smb2_key_derivation(const uint8_t *KI, size_t KI_len,
+ const uint8_t *Label, size_t Label_len,
+ const uint8_t *Context, size_t Context_len,
+ uint8_t KO[16]);
NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key,
uint16_t cipher_id,
if (conn->protocol >= PROTOCOL_SMB2_24) {
struct _derivation *d = &derivation.signing;
- smb2_key_derivation(session_key, sizeof(session_key),
- d->label.data, d->label.length,
- d->context.data, d->context.length,
- session->smb2->signing_key->blob.data);
+ status = smb2_key_derivation(session_key, sizeof(session_key),
+ d->label.data, d->label.length,
+ d->context.data, d->context.length,
+ session->smb2->signing_key->blob.data);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
}
session->smb2->encryption_key =
if (conn->protocol >= PROTOCOL_SMB2_24) {
struct _derivation *d = &derivation.encryption;
- smb2_key_derivation(session_key, sizeof(session_key),
- d->label.data, d->label.length,
- d->context.data, d->context.length,
- session->smb2->encryption_key.data);
+ status = smb2_key_derivation(session_key, sizeof(session_key),
+ d->label.data, d->label.length,
+ d->context.data, d->context.length,
+ session->smb2->encryption_key.data);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
}
session->smb2->decryption_key =
if (conn->protocol >= PROTOCOL_SMB2_24) {
struct _derivation *d = &derivation.decryption;
- smb2_key_derivation(session_key, sizeof(session_key),
- d->label.data, d->label.length,
- d->context.data, d->context.length,
- session->smb2->decryption_key.data);
+ status = smb2_key_derivation(session_key, sizeof(session_key),
+ d->label.data, d->label.length,
+ d->context.data, d->context.length,
+ session->smb2->decryption_key.data);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
}
session->smb2->application_key =
if (conn->protocol >= PROTOCOL_SMB2_24) {
struct _derivation *d = &derivation.application;
- smb2_key_derivation(session_key, sizeof(session_key),
- d->label.data, d->label.length,
- d->context.data, d->context.length,
- session->smb2->application_key.data);
+ status = smb2_key_derivation(session_key, sizeof(session_key),
+ d->label.data, d->label.length,
+ d->context.data, d->context.length,
+ session->smb2->application_key.data);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
}
ZERO_STRUCT(session_key);
if (conn->protocol >= PROTOCOL_SMB2_24) {
struct _derivation *d = &derivation.signing;
- smb2_key_derivation(channel_key, sizeof(channel_key),
- d->label.data, d->label.length,
- d->context.data, d->context.length,
- session->smb2_channel.signing_key->blob.data);
+ status = smb2_key_derivation(channel_key, sizeof(channel_key),
+ d->label.data, d->label.length,
+ d->context.data, d->context.length,
+ session->smb2_channel.signing_key->blob.data);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
}
ZERO_STRUCT(channel_key);
if (xconn->protocol >= PROTOCOL_SMB2_24) {
struct _derivation *d = &derivation.signing;
- smb2_key_derivation(session_key, sizeof(session_key),
- d->label.data, d->label.length,
- d->context.data, d->context.length,
- x->global->signing_key->blob.data);
+ status = smb2_key_derivation(session_key, sizeof(session_key),
+ d->label.data, d->label.length,
+ d->context.data, d->context.length,
+ x->global->signing_key->blob.data);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
}
if (xconn->protocol >= PROTOCOL_SMB2_24) {
return NT_STATUS_NO_MEMORY;
}
- smb2_key_derivation(session_key, sizeof(session_key),
- d->label.data, d->label.length,
- d->context.data, d->context.length,
- x->global->decryption_key_blob.data);
+ status = smb2_key_derivation(session_key, sizeof(session_key),
+ d->label.data, d->label.length,
+ d->context.data, d->context.length,
+ x->global->decryption_key_blob.data);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
}
if (xconn->protocol >= PROTOCOL_SMB2_24) {
return NT_STATUS_NO_MEMORY;
}
- smb2_key_derivation(session_key, sizeof(session_key),
- d->label.data, d->label.length,
- d->context.data, d->context.length,
- x->global->encryption_key_blob.data);
+ status = smb2_key_derivation(session_key, sizeof(session_key),
+ d->label.data, d->label.length,
+ d->context.data, d->context.length,
+ x->global->encryption_key_blob.data);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
/*
* CCM and GCM algorithms must never have their
if (xconn->protocol >= PROTOCOL_SMB2_24) {
struct _derivation *d = &derivation.application;
- smb2_key_derivation(session_key, sizeof(session_key),
- d->label.data, d->label.length,
- d->context.data, d->context.length,
- x->global->application_key.data);
+ status = smb2_key_derivation(session_key, sizeof(session_key),
+ d->label.data, d->label.length,
+ d->context.data, d->context.length,
+ x->global->application_key.data);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
}
if (xconn->protocol >= PROTOCOL_SMB3_00 && lp_debug_encryption()) {
if (xconn->protocol >= PROTOCOL_SMB2_24) {
struct _derivation *d = &derivation.signing;
- smb2_key_derivation(session_key, sizeof(session_key),
- d->label.data, d->label.length,
- d->context.data, d->context.length,
- c->signing_key->blob.data);
+ status = smb2_key_derivation(session_key, sizeof(session_key),
+ d->label.data, d->label.length,
+ d->context.data, d->context.length,
+ c->signing_key->blob.data);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
}
ZERO_STRUCT(session_key);