From d61601d44f67da9cf671dbef6f2f8d9afa0700b7 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 11 Jun 2019 12:03:33 +0200 Subject: [PATCH] libcli:smb: Return NSTATUS for smb2_signing_check_pdu() Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett --- libcli/smb/smb2_signing.c | 32 ++++++++++++-------- libcli/smb/smb2_signing.h | 8 ++--- libcli/smb/smbXcli_base.c | 55 ++++++++++++++++++++++------------- source3/smbd/smb2_sesssetup.c | 55 ++++++++++++++++++++++------------- 4 files changed, 94 insertions(+), 56 deletions(-) diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c index 62b53ccbe48..240a939b422 100644 --- a/libcli/smb/smb2_signing.c +++ b/libcli/smb/smb2_signing.c @@ -24,6 +24,7 @@ #include "../lib/crypto/crypto.h" #include "lib/util/iov_buf.h" +#include "libcli/util/gnutls_error.h" #include #include @@ -241,10 +242,10 @@ NTSTATUS smb2_signing_check_pdu(struct smb2_signing_key *signing_key, 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]; @@ -263,36 +264,41 @@ void smb2_key_derivation(const uint8_t *KI, size_t KI_len, 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); @@ -300,6 +306,8 @@ void smb2_key_derivation(const uint8_t *KI, size_t KI_len, memcpy(KO, digest, 16); ZERO_ARRAY(digest); + + return NT_STATUS_OK; } NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key, diff --git a/libcli/smb/smb2_signing.h b/libcli/smb/smb2_signing.h index 646567c9d75..6e1682955c9 100644 --- a/libcli/smb/smb2_signing.h +++ b/libcli/smb/smb2_signing.h @@ -45,10 +45,10 @@ NTSTATUS smb2_signing_check_pdu(struct smb2_signing_key *signing_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, diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index 1af550d9cdd..40e9e721fb1 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -6096,10 +6096,13 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session, 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 = @@ -6113,10 +6116,13 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session, 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 = @@ -6130,10 +6136,13 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session, 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 = @@ -6147,10 +6156,13 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session, 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); @@ -6348,10 +6360,13 @@ NTSTATUS smb2cli_session_set_channel_key(struct smbXcli_session *session, 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); diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c index 692f22cadbe..c302929335c 100644 --- a/source3/smbd/smb2_sesssetup.c +++ b/source3/smbd/smb2_sesssetup.c @@ -360,10 +360,13 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, 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) { @@ -377,10 +380,13 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, 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) { @@ -395,10 +401,13 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, 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 @@ -438,10 +447,13 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, 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()) { @@ -748,10 +760,13 @@ static NTSTATUS smbd_smb2_bind_auth_return(struct smbXsrv_session *session, 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);