1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

SMB2 signing now works. The spec was wrong (and will be fixed in the

next version)
This commit is contained in:
Andrew Tridgell 2008-06-03 14:29:27 +10:00
parent b8f2e6321d
commit 436cb17b86
5 changed files with 142 additions and 13 deletions

View File

@ -6,7 +6,7 @@
LIBCRYPTO_OBJ_FILES = $(addprefix $(libcryptosrcdir)/, \
crc32.o md5.o hmacmd5.o md4.o \
arcfour.o sha1.o hmacsha1.o)
arcfour.o sha1.o hmacsha1.o hmacsha256.o)
[MODULE::TORTURE_LIBCRYPTO]

View File

@ -23,6 +23,8 @@
#include "lib/crypto/hmacmd5.h"
#include "lib/crypto/sha1.h"
#include "lib/crypto/hmacsha1.h"
#include "heimdal/lib/hcrypto/sha.h"
#include "lib/crypto/hmacsha256.h"
struct arcfour_state {
uint8_t sbox[256];

View File

@ -0,0 +1,92 @@
/*
Unix SMB/CIFS implementation.
Interface header: HMAC SHA-256 code
Copyright (C) Andrew Tridgell 2008
based in hmacsha1.c which is:
Copyright (C) Stefan Metzmacher
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/>.
*/
/*
taken direct from rfc2202 implementation and modified for suitable use
*/
#include "includes.h"
#include "lib/crypto/crypto.h"
#include "heimdal/lib/hcrypto/sha.h"
/***********************************************************************
the rfc 2104/2202 version of hmac_sha256 initialisation.
***********************************************************************/
_PUBLIC_ void hmac_sha256_init(const uint8_t *key, size_t key_len, struct HMACSHA256Context *ctx)
{
int i;
uint8_t tk[SHA256_DIGEST_LENGTH];
/* if key is longer than 64 bytes reset it to key=HASH(key) */
if (key_len > 64)
{
SHA256_CTX tctx;
SHA256_Init(&tctx);
SHA256_Update(&tctx, key, key_len);
SHA256_Final(tk, &tctx);
key = tk;
key_len = SHA256_DIGEST_LENGTH;
}
/* start out by storing key in pads */
ZERO_STRUCT(ctx->k_ipad);
ZERO_STRUCT(ctx->k_opad);
memcpy( ctx->k_ipad, key, key_len);
memcpy( ctx->k_opad, key, key_len);
/* XOR key with ipad and opad values */
for (i=0; i<64; i++)
{
ctx->k_ipad[i] ^= 0x36;
ctx->k_opad[i] ^= 0x5c;
}
SHA256_Init(&ctx->ctx);
SHA256_Update(&ctx->ctx, ctx->k_ipad, 64);
}
/***********************************************************************
update hmac_sha256 "inner" buffer
***********************************************************************/
_PUBLIC_ void hmac_sha256_update(const uint8_t *data, size_t data_len, struct HMACSHA256Context *ctx)
{
SHA256_Update(&ctx->ctx, data, data_len); /* then text of datagram */
}
/***********************************************************************
finish off hmac_sha256 "inner" buffer and generate outer one.
***********************************************************************/
_PUBLIC_ void hmac_sha256_final(uint8_t digest[SHA256_DIGEST_LENGTH], struct HMACSHA256Context *ctx)
{
SHA256_CTX ctx_o;
SHA256_Final(digest, &ctx->ctx);
SHA256_Init(&ctx_o);
SHA256_Update(&ctx_o, ctx->k_opad, 64);
SHA256_Update(&ctx_o, digest, SHA256_DIGEST_LENGTH);
SHA256_Final(digest, &ctx_o);
}

View File

@ -0,0 +1,38 @@
/*
Unix SMB/CIFS implementation.
Interface header: HMAC SHA256 code
Copyright (C) Andrew Tridgell 2008
based on hmacsha1.h which is:
Copyright (C) Stefan Metzmacher 2006
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 _HMAC_SHA256_H
struct HMACSHA256Context {
SHA256_CTX ctx;
uint8_t k_ipad[65];
uint8_t k_opad[65];
};
void hmac_sha256_init(const uint8_t *key, size_t key_len, struct HMACSHA256Context *ctx);
void hmac_sha256_update(const uint8_t *data, size_t data_len, struct HMACSHA256Context *ctx);
void hmac_sha256_final(uint8_t digest[20], struct HMACSHA256Context *ctx);
#endif /* _HMAC_SHA256_H */

View File

@ -23,7 +23,7 @@
#include "libcli/raw/libcliraw.h"
#include "libcli/smb2/smb2.h"
#include "libcli/smb2/smb2_calls.h"
#include "heimdal/lib/hcrypto/sha.h"
#include "lib/crypto/crypto.h"
/*
NOTE: this code does not yet interoperate with the windows SMB2
@ -54,7 +54,7 @@ NTSTATUS smb2_sign_message(struct smb2_request *req)
{
struct smb2_request_buffer *buf = &req->out;
uint64_t session_id;
SHA256_CTX m;
struct HMACSHA256Context m;
uint8_t res[32];
if (!req->transport->signing.doing_signing ||
@ -85,11 +85,9 @@ NTSTATUS smb2_sign_message(struct smb2_request *req)
SIVAL(buf->hdr, SMB2_HDR_FLAGS, IVAL(buf->hdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_SIGNED);
ZERO_STRUCT(m);
SHA256_Init(&m);
SHA256_Update(&m, req->transport->signing.session_key.data,
req->transport->signing.session_key.length);
SHA256_Update(&m, buf->buffer+NBT_HDR_SIZE, buf->size-NBT_HDR_SIZE);
SHA256_Final(res, &m);
hmac_sha256_init(req->transport->signing.session_key.data, 16, &m);
hmac_sha256_update(buf->buffer+NBT_HDR_SIZE, buf->size-NBT_HDR_SIZE, &m);
hmac_sha256_final(res, &m);
DEBUG(5,("signed SMB2 message of size %u\n", (unsigned)buf->size - NBT_HDR_SIZE));
@ -110,7 +108,7 @@ NTSTATUS smb2_check_signature(struct smb2_transport *transport,
uint8_t *buffer, uint_t length)
{
uint64_t session_id;
SHA256_CTX m;
struct HMACSHA256Context m;
uint8_t res[SHA256_DIGEST_LENGTH];
uint8_t sig[16];
@ -147,10 +145,9 @@ NTSTATUS smb2_check_signature(struct smb2_transport *transport,
memset(buffer + NBT_HDR_SIZE + SMB2_HDR_SIGNATURE, 0, 16);
ZERO_STRUCT(m);
SHA256_Init(&m);
SHA256_Update(&m, transport->signing.session_key.data, 16);
SHA256_Update(&m, buffer+NBT_HDR_SIZE, length-NBT_HDR_SIZE);
SHA256_Final(res, &m);
hmac_sha256_init(transport->signing.session_key.data, 16, &m);
hmac_sha256_update(buffer+NBT_HDR_SIZE, length-NBT_HDR_SIZE, &m);
hmac_sha256_final(res, &m);
memcpy(buffer+NBT_HDR_SIZE+SMB2_HDR_SIGNATURE, sig, 16);