[SCM] Samba Shared Repository - branch master updated
Stefan Metzmacher
metze at samba.org
Mon Jul 23 12:15:02 MDT 2012
The branch, master has been updated
via 4b64ec5 libcli/smb: set should_encrypt = true if we got SMB2_SESSION_FLAG_ENCRYPT_DATA
via 6b93210 libcli/smb: encrypt SMB2 traffic if nedded/desired.
via 6e651df libcli/smb: increment nbt_len, when we have the fully created the SMB2 PDU
via f08adbb libcli/smb: maintain smb2.should_sign on smbXcli_req_state
via 92811c6 libcli/smb: make use of SMB2_HDR_BODY as header size
via be8e33e libcli/smb: parse the SMB2_TRANSFORM header and decrypt the SMB2 pdu
via c2b0a48 libcli/smb: create 4 iovecs per request in smb2cli_inbuf_parse_compound()
via 5863107 libcli/smb: prepare [en|de]cryption_key for SMB3
via d333edb libcli/smb: copy the application_key in smb2cli_session_create_channel()
via 077eb57 libcli/smb: check the buffer length in smbXcli_negprot_dispatch_incoming()
via 1c144b0 libcli/smb: only pass the smb2 buffer to smb2cli_inbuf_parse_compound()
via fd736f7 libcli/smb: add smb2_signing_[en|e]crypt_pdu()
via 7e09824 libcli/smb: construct the signing_key before forming the message
via 5adf63f lib/crypto: add aes_ccm_128
via 4628e28 libcli/smb: add SMB2_SESSION_FLAG_ENCRYPT_DATA
via d728567 libcli/smb: add SMB2_TRANSFORM macros
via a41a1d1 s3:test_smb2: copy the session_channel from the primary channel.
via 88f326a s3:smb2_tcon: reject access to shares mark as "smb encrypt = required"
from 3fe601a s3-winbind: Fix idmap initialization debug message.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 4b64ec546f0cb982866b1f66aa8f8844f25c91c9
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Jul 23 11:38:31 2012 +0200
libcli/smb: set should_encrypt = true if we got SMB2_SESSION_FLAG_ENCRYPT_DATA
metze
Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
Autobuild-Date(master): Mon Jul 23 20:14:07 CEST 2012 on sn-devel-104
commit 6b9321071c97f740689a36ecf48d9d66f4a19e8e
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Jul 23 10:14:53 2012 +0200
libcli/smb: encrypt SMB2 traffic if nedded/desired.
metze
commit 6e651dfdc0af9805827ad2ea7fc29675ab6fe74b
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Jul 23 10:07:19 2012 +0200
libcli/smb: increment nbt_len, when we have the fully created the SMB2 PDU
metze
commit f08adbb4d63f2cb50de29aff44e7539e76bb87cc
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Jul 23 10:00:50 2012 +0200
libcli/smb: maintain smb2.should_sign on smbXcli_req_state
metze
commit 92811c6f5f3d3807ab70a8acfd25795c7c0556b1
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Jul 23 09:44:06 2012 +0200
libcli/smb: make use of SMB2_HDR_BODY as header size
metze
commit be8e33ec5416ebc57114dd2c1472ed0faffd05bb
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Jul 23 09:16:05 2012 +0200
libcli/smb: parse the SMB2_TRANSFORM header and decrypt the SMB2 pdu
metze
commit c2b0a485136925ba8c9661d2b97b69dfeed5d5de
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Jul 23 08:11:59 2012 +0200
libcli/smb: create 4 iovecs per request in smb2cli_inbuf_parse_compound()
The first one might hold the SMB2_TRANSFORM Header later.
metze
commit 5863107cd3a37585272ee2186a0103f94932b063
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jul 20 09:30:05 2012 +0200
libcli/smb: prepare [en|de]cryption_key for SMB3
metze
commit d333edbe14a35bc1b0c2a0518c2e412f56ffda70
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jul 20 09:22:17 2012 +0200
libcli/smb: copy the application_key in smb2cli_session_create_channel()
metze
commit 077eb578be1bc9865fc5b32816f8230737e76100
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jul 20 09:20:43 2012 +0200
libcli/smb: check the buffer length in smbXcli_negprot_dispatch_incoming()
metze
commit 1c144b07f658723a9ae28c61b2e66c33630b573a
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jul 20 09:19:24 2012 +0200
libcli/smb: only pass the smb2 buffer to smb2cli_inbuf_parse_compound()
We should hide the transport as much as possible.
metze
commit fd736f7f18294aa1589aacd495b2a48bbaf8715c
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jul 20 09:16:08 2012 +0200
libcli/smb: add smb2_signing_[en|e]crypt_pdu()
metze
commit 7e0982421b1e8b6a73ef67cdb085ffc60cd3b59b
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Jul 19 11:16:16 2012 +0200
libcli/smb: construct the signing_key before forming the message
metze
commit 5adf63fe301e812f5776448f9560af9d6d842554
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jul 20 07:37:48 2012 +0200
lib/crypto: add aes_ccm_128
metze
commit 4628e2878f844ea95fb678a07dcb017edd46cc1f
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Jul 23 10:46:21 2012 +0200
libcli/smb: add SMB2_SESSION_FLAG_ENCRYPT_DATA
metze
commit d7285672b4990696a61fef3d1129d7ee45e530a2
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jul 20 09:11:30 2012 +0200
libcli/smb: add SMB2_TRANSFORM macros
metze
commit a41a1d176f31cbbd011309041c6865487a7be9c6
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Jul 23 13:34:05 2012 +0200
s3:test_smb2: copy the session_channel from the primary channel.
metze
commit 88f326a2c0be88bf1eb6fb7ae5348c69544815de
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Jul 23 13:47:24 2012 +0200
s3:smb2_tcon: reject access to shares mark as "smb encrypt = required"
We do not support SMB2 transport encryption yet.
metze
-----------------------------------------------------------------------
Summary of changes:
lib/crypto/aes_ccm_128.c | 170 ++++++++++++++++++++
lib/crypto/aes_ccm_128.h | 54 +++++++
lib/crypto/crypto.h | 1 +
lib/crypto/wscript_build | 2 +-
libcli/smb/smb2_constants.h | 16 ++
libcli/smb/smb2_signing.c | 132 ++++++++++++++++
libcli/smb/smb2_signing.h | 9 +
libcli/smb/smbXcli_base.c | 363 ++++++++++++++++++++++++++++++++++--------
source3/Makefile.in | 2 +-
source3/smbd/smb2_tcon.c | 8 +
source3/torture/test_smb2.c | 2 +-
11 files changed, 687 insertions(+), 72 deletions(-)
create mode 100644 lib/crypto/aes_ccm_128.c
create mode 100644 lib/crypto/aes_ccm_128.h
Changeset truncated at 500 lines:
diff --git a/lib/crypto/aes_ccm_128.c b/lib/crypto/aes_ccm_128.c
new file mode 100644
index 0000000..ac8e01f
--- /dev/null
+++ b/lib/crypto/aes_ccm_128.c
@@ -0,0 +1,170 @@
+/*
+ AES-CCM-128 (rfc 3610)
+
+ Copyright (C) Stefan Metzmacher 2012
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "../lib/crypto/crypto.h"
+#include "lib/util/byteorder.h"
+
+#define M_ ((AES_CCM_128_M - 2) / 2)
+#define L_ (AES_CCM_128_L - 1)
+
+static inline void aes_ccm_128_xor(const uint8_t in1[AES_BLOCK_SIZE],
+ const uint8_t in2[AES_BLOCK_SIZE],
+ uint8_t out[AES_BLOCK_SIZE])
+{
+ uint8_t i;
+
+ for (i = 0; i < AES_BLOCK_SIZE; i++) {
+ out[i] = in1[i] ^ in2[i];
+ }
+}
+
+void aes_ccm_128_init(struct aes_ccm_128_context *ctx,
+ const uint8_t K[AES_BLOCK_SIZE],
+ const uint8_t N[AES_CCM_128_NONCE_SIZE],
+ size_t a_total, size_t m_total)
+{
+ uint8_t B_0[AES_BLOCK_SIZE];
+
+ ZERO_STRUCTP(ctx);
+
+ AES_set_encrypt_key(K, 128, &ctx->aes_key);
+ memcpy(ctx->nonce, N, AES_CCM_128_NONCE_SIZE);
+ ctx->a_remain = a_total;
+ ctx->m_remain = m_total;
+
+ /*
+ * prepare B_0
+ */
+ B_0[0] = L_;
+ B_0[0] += 8 * M_;
+ if (a_total > 0) {
+ B_0[0] += 64;
+ }
+ memcpy(&B_0[1], ctx->nonce, AES_CCM_128_NONCE_SIZE);
+ RSIVAL(B_0, (AES_BLOCK_SIZE - AES_CCM_128_L), m_total);
+
+ /*
+ * prepare X_1
+ */
+ AES_encrypt(B_0, ctx->X_i, &ctx->aes_key);
+
+ /*
+ * prepare B_1
+ */
+ if (a_total >= UINT32_MAX) {
+ RSSVAL(ctx->B_i, 0, 0xFFFF);
+ RSBVAL(ctx->B_i, 2, a_total);
+ ctx->B_i_ofs = 10;
+ } else if (a_total >= 0xFF00) {
+ RSSVAL(ctx->B_i, 0, 0xFFFE);
+ RSIVAL(ctx->B_i, 2, a_total);
+ ctx->B_i_ofs = 6;
+ } else if (a_total > 0) {
+ RSSVAL(ctx->B_i, 0, a_total);
+ ctx->B_i_ofs = 2;
+ }
+
+ ctx->S_i_ofs = AES_BLOCK_SIZE;
+}
+
+void aes_ccm_128_update(struct aes_ccm_128_context *ctx,
+ const uint8_t *v, size_t v_len)
+{
+ size_t *remain;
+
+ if (ctx->a_remain > 0) {
+ remain = &ctx->a_remain;
+ } else {
+ remain = &ctx->m_remain;
+ }
+
+ while (v_len > 0) {
+ size_t n = MIN(AES_BLOCK_SIZE - ctx->B_i_ofs, v_len);
+ bool more = true;
+
+ memcpy(&ctx->B_i[ctx->B_i_ofs], v, n);
+ v += n;
+ v_len -= n;
+ ctx->B_i_ofs += n;
+ *remain -= n;
+
+ if (ctx->B_i_ofs == AES_BLOCK_SIZE) {
+ more = false;
+ } else if (*remain == 0) {
+ more = false;
+ }
+
+ if (more) {
+ continue;
+ }
+
+ aes_ccm_128_xor(ctx->X_i, ctx->B_i, ctx->B_i);
+ AES_encrypt(ctx->B_i, ctx->X_i, &ctx->aes_key);
+
+ ZERO_STRUCT(ctx->B_i);
+ ctx->B_i_ofs = 0;
+ }
+}
+
+static void aes_ccm_128_S_i(struct aes_ccm_128_context *ctx,
+ uint8_t S_i[AES_BLOCK_SIZE],
+ size_t i)
+{
+ uint8_t A_i[AES_BLOCK_SIZE];
+
+ A_i[0] = L_;
+ memcpy(&A_i[1], ctx->nonce, AES_CCM_128_NONCE_SIZE);
+ RSIVAL(A_i, (AES_BLOCK_SIZE - AES_CCM_128_L), i);
+
+ AES_encrypt(A_i, S_i, &ctx->aes_key);
+}
+
+void aes_ccm_128_crypt(struct aes_ccm_128_context *ctx,
+ uint8_t *m, size_t m_len)
+{
+ while (m_len > 0) {
+ if (ctx->S_i_ofs == AES_BLOCK_SIZE) {
+ ctx->S_i_ctr += 1;
+ aes_ccm_128_S_i(ctx, ctx->S_i, ctx->S_i_ctr);
+ ctx->S_i_ofs = 0;
+ }
+
+ m[0] ^= ctx->S_i[ctx->S_i_ofs];
+ m += 1;
+ m_len -= 1;
+ ctx->S_i_ofs += 1;
+ }
+}
+
+void aes_ccm_128_digest(struct aes_ccm_128_context *ctx,
+ uint8_t digest[AES_BLOCK_SIZE])
+{
+ uint8_t S_0[AES_BLOCK_SIZE];
+
+ aes_ccm_128_S_i(ctx, S_0, 0);
+
+ /*
+ * note X_i is T here
+ */
+ aes_ccm_128_xor(ctx->X_i, S_0, digest);
+
+ ZERO_STRUCT(S_0);
+ ZERO_STRUCTP(ctx);
+}
diff --git a/lib/crypto/aes_ccm_128.h b/lib/crypto/aes_ccm_128.h
new file mode 100644
index 0000000..a98c754
--- /dev/null
+++ b/lib/crypto/aes_ccm_128.h
@@ -0,0 +1,54 @@
+/*
+ AES-CCM-128 (rfc 3610)
+
+ Copyright (C) Stefan Metzmacher 2012
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef LIB_CRYPTO_AES_CCM_128_H
+#define LIB_CRYPTO_AES_CCM_128_H
+
+#define AES_CCM_128_M 16
+#define AES_CCM_128_L 4
+#define AES_CCM_128_NONCE_SIZE (15 - AES_CCM_128_L)
+
+struct aes_ccm_128_context {
+ AES_KEY aes_key;
+ uint8_t nonce[AES_CCM_128_NONCE_SIZE];
+
+ size_t a_remain;
+ size_t m_remain;
+
+ uint8_t X_i[AES_BLOCK_SIZE];
+ uint8_t B_i[AES_BLOCK_SIZE];
+ size_t B_i_ofs;
+
+ uint8_t S_i[AES_BLOCK_SIZE];
+ size_t S_i_ofs;
+ size_t S_i_ctr;
+};
+
+void aes_ccm_128_init(struct aes_ccm_128_context *ctx,
+ const uint8_t K[AES_BLOCK_SIZE],
+ const uint8_t N[AES_CCM_128_NONCE_SIZE],
+ size_t a_total, size_t m_total);
+void aes_ccm_128_update(struct aes_ccm_128_context *ctx,
+ const uint8_t *v, size_t v_len);
+void aes_ccm_128_crypt(struct aes_ccm_128_context *ctx,
+ uint8_t *m, size_t m_len);
+void aes_ccm_128_digest(struct aes_ccm_128_context *ctx,
+ uint8_t digest[AES_BLOCK_SIZE]);
+
+#endif /* LIB_CRYPTO_AES_CCM_128_H */
diff --git a/lib/crypto/crypto.h b/lib/crypto/crypto.h
index c0d85c8..1f5a1b7 100644
--- a/lib/crypto/crypto.h
+++ b/lib/crypto/crypto.h
@@ -26,4 +26,5 @@
#include "../lib/crypto/arcfour.h"
#include "../lib/crypto/aes.h"
#include "../lib/crypto/aes_cmac_128.h"
+#include "../lib/crypto/aes_ccm_128.h"
diff --git a/lib/crypto/wscript_build b/lib/crypto/wscript_build
index 849bf16..cd7a466 100644
--- a/lib/crypto/wscript_build
+++ b/lib/crypto/wscript_build
@@ -9,7 +9,7 @@ elif not bld.CONFIG_SET('HAVE_COMMONCRYPTO_COMMONDIGEST_H'):
bld.SAMBA_SUBSYSTEM('LIBCRYPTO',
source='''crc32.c hmacmd5.c md4.c arcfour.c sha256.c hmacsha256.c
- aes.c rijndael-alg-fst.c aes_cmac_128.c
+ aes.c rijndael-alg-fst.c aes_cmac_128.c aes_ccm_128.c
''' + extra_source,
deps='talloc' + extra_deps
)
diff --git a/libcli/smb/smb2_constants.h b/libcli/smb/smb2_constants.h
index 9b60345..f2f28f8 100644
--- a/libcli/smb/smb2_constants.h
+++ b/libcli/smb/smb2_constants.h
@@ -22,6 +22,21 @@
#ifndef __LIBCLI_SMB2_SMB2_CONSTANTS_H__
#define __LIBCLI_SMB2_SMB2_CONSTANTS_H__
+/* offsets into SMB2_TRANSFORM header elements */
+#define SMB2_TF_PROTOCOL_ID 0x00 /* 4 bytes */
+#define SMB2_TF_SIGNATURE 0x04 /* 16 bytes */
+#define SMB2_TF_NONCE 0x14 /* 16 bytes */
+#define SMB2_TF_MSG_SIZE 0x24 /* 4 bytes */
+#define SMB2_TF_RESERVED 0x28 /* 2 bytes */
+#define SMB2_TF_ALGORITHM 0x2A /* 2 bytes */
+#define SMB2_TF_SESSION_ID 0x2C /* 8 bytes */
+
+#define SMB2_TF_HDR_SIZE 0x34 /* 52 bytes */
+
+#define SMB2_TF_MAGIC 0x424D53FD /* 0xFD 'S' 'M' 'B' */
+
+#define SMB2_ENCRYPTION_AES128_CCM 0x0001
+
/* offsets into header elements for a sync SMB2 request */
#define SMB2_HDR_PROTOCOL_ID 0x00
#define SMB2_HDR_LENGTH 0x04
@@ -109,6 +124,7 @@
/* SMB2 session flags */
#define SMB2_SESSION_FLAG_IS_GUEST 0x0001
#define SMB2_SESSION_FLAG_IS_NULL 0x0002
+#define SMB2_SESSION_FLAG_ENCRYPT_DATA 0x0004 /* in dialect >= 0x224 */
/* SMB2 sharetype flags */
#define SMB2_SHARE_TYPE_DISK 0x1
diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c
index 43c9ba5..bb621fd 100644
--- a/libcli/smb/smb2_signing.c
+++ b/libcli/smb/smb2_signing.c
@@ -207,3 +207,135 @@ void smb2_key_derivation(const uint8_t *KI, size_t KI_len,
memcpy(KO, digest, 16);
}
+
+NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key,
+ enum protocol_types protocol,
+ struct iovec *vector,
+ int count)
+{
+ uint8_t *tf;
+ uint16_t alg;
+ uint8_t sig[16];
+ int i;
+ size_t a_total;
+ size_t m_total = 0;
+ struct aes_ccm_128_context ctx;
+ uint8_t key[AES_BLOCK_SIZE];
+
+ if (count < 1) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (vector[0].iov_len != SMB2_TF_HDR_SIZE) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ 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));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ alg = SMB2_ENCRYPTION_AES128_CCM;
+ SSVAL(tf, SMB2_TF_ALGORITHM, alg);
+
+ a_total = SMB2_TF_HDR_SIZE - SMB2_TF_NONCE;
+ for (i=1; i < count; i++) {
+ m_total += vector[i].iov_len;
+ }
+ ZERO_STRUCT(key);
+ memcpy(key, encryption_key.data,
+ MIN(encryption_key.length, AES_BLOCK_SIZE));
+ aes_ccm_128_init(&ctx, key,
+ tf + SMB2_TF_NONCE,
+ a_total, m_total);
+ aes_ccm_128_update(&ctx, tf + SMB2_TF_NONCE, a_total);
+ for (i=1; i < count; i++) {
+ aes_ccm_128_update(&ctx,
+ (const uint8_t *)vector[i].iov_base,
+ vector[i].iov_len);
+ }
+ for (i=1; i < count; i++) {
+ aes_ccm_128_crypt(&ctx,
+ (uint8_t *)vector[i].iov_base,
+ vector[i].iov_len);
+ }
+ aes_ccm_128_digest(&ctx, sig);
+
+ memcpy(tf + SMB2_TF_SIGNATURE, sig, 16);
+
+ DEBUG(5,("encrypt SMB2 message\n"));
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key,
+ enum protocol_types protocol,
+ struct iovec *vector,
+ int count)
+{
+ uint8_t *tf;
+ uint16_t alg;
+ uint8_t *sig_ptr = NULL;
+ uint8_t sig[16];
+ int i;
+ size_t a_total;
+ size_t m_total = 0;
+ struct aes_ccm_128_context ctx;
+ uint8_t key[AES_BLOCK_SIZE];
+
+ if (count < 1) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (vector[0].iov_len != SMB2_TF_HDR_SIZE) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ tf = (uint8_t *)vector[0].iov_base;
+
+ if (decryption_key.length == 0) {
+ DEBUG(2,("Wrong decryption key length %u for SMB2 signing\n",
+ (unsigned)decryption_key.length));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ alg = SVAL(tf, SMB2_TF_ALGORITHM);
+ if (alg != SMB2_ENCRYPTION_AES128_CCM) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ a_total = SMB2_TF_HDR_SIZE - SMB2_TF_NONCE;
+ for (i=1; i < count; i++) {
+ m_total += vector[i].iov_len;
+ }
+ ZERO_STRUCT(key);
+ memcpy(key, decryption_key.data,
+ MIN(decryption_key.length, AES_BLOCK_SIZE));
+ aes_ccm_128_init(&ctx, key,
+ tf + SMB2_TF_NONCE,
+ a_total, m_total);
+ for (i=1; i < count; i++) {
+ aes_ccm_128_crypt(&ctx,
+ (uint8_t *)vector[i].iov_base,
+ vector[i].iov_len);
+ }
+ aes_ccm_128_update(&ctx, tf + SMB2_TF_NONCE, a_total);
+ for (i=1; i < count; i++) {
+ aes_ccm_128_update(&ctx,
+ ( uint8_t *)vector[i].iov_base,
+ vector[i].iov_len);
+ }
+ aes_ccm_128_digest(&ctx, sig);
+
+ sig_ptr = tf + SMB2_TF_SIGNATURE;
+ if (memcmp(sig_ptr, sig, 16) != 0) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ DEBUG(5,("decrypt SMB2 message\n"));
+
+ return NT_STATUS_OK;
+}
diff --git a/libcli/smb/smb2_signing.h b/libcli/smb/smb2_signing.h
index 200274b..e8e2e6a 100644
--- a/libcli/smb/smb2_signing.h
+++ b/libcli/smb/smb2_signing.h
@@ -38,4 +38,13 @@ void 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,
+ enum protocol_types protocol,
+ struct iovec *vector,
+ int count);
+NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key,
+ enum protocol_types protocol,
+ struct iovec *vector,
+ int count);
+
#endif /* _LIBCLI_SMB_SMB2_SIGNING_H_ */
diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
index eb9e7d5..326a43d 100644
--- a/libcli/smb/smbXcli_base.c
+++ b/libcli/smb/smbXcli_base.c
@@ -137,6 +137,11 @@ struct smbXcli_session {
DATA_BLOB application_key;
DATA_BLOB signing_key;
bool should_sign;
+ bool should_encrypt;
+ DATA_BLOB encryption_key;
+ DATA_BLOB decryption_key;
+ uint64_t channel_nonce;
+ uint64_t channel_next;
DATA_BLOB channel_signing_key;
} smb2;
};
@@ -188,14 +193,23 @@ struct smbXcli_req_state {
const uint8_t *dyn;
uint32_t dyn_len;
- uint8_t hdr[64];
+ uint8_t transform[SMB2_TF_HDR_SIZE];
+ uint8_t hdr[SMB2_HDR_BODY];
uint8_t pad[7]; /* padding space for compounding */
- /* always an array of 3 talloc elements */
+ /*
+ * always an array of 3 talloc elements
+ * (without a SMB2_TRANSFORM header!)
+ *
+ * HDR, BODY, DYN
+ */
struct iovec *recv_iov;
uint16_t credit_charge;
+ bool should_sign;
+ bool should_encrypt;
+
bool signing_skipped;
bool notify_async;
bool got_async;
@@ -2402,6 +2416,25 @@ struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
if (session) {
uid = session->smb2.session_id;
+
+ state->smb2.should_sign = session->smb2.should_sign;
+ state->smb2.should_encrypt = session->smb2.should_encrypt;
--
Samba Shared Repository
More information about the samba-cvs
mailing list