mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
Added patchset with various BCrypt improvements.
This commit is contained in:
parent
e4679ff7ce
commit
1740d793d8
573
patches/bcrypt-Improvements/0001-bcrypt-Add-AES-provider.patch
Normal file
573
patches/bcrypt-Improvements/0001-bcrypt-Add-AES-provider.patch
Normal file
@ -0,0 +1,573 @@
|
||||
From b6efa0b8bb1bba73863ca985c13d46a5eaec4198 Mon Sep 17 00:00:00 2001
|
||||
From: Hans Leidekker <hans@codeweavers.com>
|
||||
Date: Mon, 19 Dec 2016 19:38:52 +0100
|
||||
Subject: bcrypt: Add AES provider.
|
||||
|
||||
---
|
||||
dlls/bcrypt/bcrypt.spec | 10 +-
|
||||
dlls/bcrypt/bcrypt_main.c | 347 ++++++++++++++++++++++++++++++++++++++++++++-
|
||||
dlls/bcrypt/tests/bcrypt.c | 18 +--
|
||||
include/bcrypt.h | 3 +
|
||||
4 files changed, 352 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/dlls/bcrypt/bcrypt.spec b/dlls/bcrypt/bcrypt.spec
|
||||
index e299fe0..962953e 100644
|
||||
--- a/dlls/bcrypt/bcrypt.spec
|
||||
+++ b/dlls/bcrypt/bcrypt.spec
|
||||
@@ -5,15 +5,15 @@
|
||||
@ stub BCryptConfigureContextFunction
|
||||
@ stub BCryptCreateContext
|
||||
@ stdcall BCryptCreateHash(ptr ptr ptr long ptr long long)
|
||||
-@ stub BCryptDecrypt
|
||||
+@ stdcall BCryptDecrypt(ptr ptr long ptr ptr long ptr long ptr long)
|
||||
@ stub BCryptDeleteContext
|
||||
@ stub BCryptDeriveKey
|
||||
@ stdcall BCryptDestroyHash(ptr)
|
||||
-@ stub BCryptDestroyKey
|
||||
+@ stdcall BCryptDestroyKey(ptr)
|
||||
@ stub BCryptDestroySecret
|
||||
@ stub BCryptDuplicateHash
|
||||
@ stub BCryptDuplicateKey
|
||||
-@ stub BCryptEncrypt
|
||||
+@ stdcall BCryptEncrypt(ptr ptr long ptr ptr long ptr long ptr long)
|
||||
@ stdcall BCryptEnumAlgorithms(long ptr ptr long)
|
||||
@ stub BCryptEnumContextFunctionProviders
|
||||
@ stub BCryptEnumContextFunctions
|
||||
@@ -26,7 +26,7 @@
|
||||
@ stub BCryptFreeBuffer
|
||||
@ stdcall BCryptGenRandom(ptr ptr long long)
|
||||
@ stub BCryptGenerateKeyPair
|
||||
-@ stub BCryptGenerateSymmetricKey
|
||||
+@ stdcall BCryptGenerateSymmetricKey(ptr ptr ptr long ptr long long)
|
||||
@ stdcall BCryptGetFipsAlgorithmMode(ptr)
|
||||
@ stdcall BCryptGetProperty(ptr wstr ptr long ptr long)
|
||||
@ stdcall BCryptHash(ptr ptr long ptr long ptr long)
|
||||
@@ -46,7 +46,7 @@
|
||||
@ stub BCryptSecretAgreement
|
||||
@ stub BCryptSetAuditingInterface
|
||||
@ stub BCryptSetContextFunctionProperty
|
||||
-@ stub BCryptSetProperty
|
||||
+@ stdcall BCryptSetProperty(ptr wstr ptr long long)
|
||||
@ stub BCryptSignHash
|
||||
@ stub BCryptUnregisterConfigChangeNotify
|
||||
@ stub BCryptUnregisterProvider
|
||||
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
|
||||
index 6023c94..937bdf7 100644
|
||||
--- a/dlls/bcrypt/bcrypt_main.c
|
||||
+++ b/dlls/bcrypt/bcrypt_main.c
|
||||
@@ -49,6 +49,10 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag);
|
||||
|
||||
static void *libgnutls_handle;
|
||||
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
|
||||
+MAKE_FUNCPTR(gnutls_cipher_init);
|
||||
+MAKE_FUNCPTR(gnutls_cipher_deinit);
|
||||
+MAKE_FUNCPTR(gnutls_cipher_encrypt2);
|
||||
+MAKE_FUNCPTR(gnutls_cipher_decrypt2);
|
||||
MAKE_FUNCPTR(gnutls_global_deinit);
|
||||
MAKE_FUNCPTR(gnutls_global_init);
|
||||
MAKE_FUNCPTR(gnutls_global_set_log_function);
|
||||
@@ -84,6 +88,10 @@ static BOOL gnutls_initialize(void)
|
||||
goto fail; \
|
||||
}
|
||||
|
||||
+ LOAD_FUNCPTR(gnutls_cipher_init)
|
||||
+ LOAD_FUNCPTR(gnutls_cipher_deinit)
|
||||
+ LOAD_FUNCPTR(gnutls_cipher_encrypt2)
|
||||
+ LOAD_FUNCPTR(gnutls_cipher_decrypt2)
|
||||
LOAD_FUNCPTR(gnutls_global_deinit)
|
||||
LOAD_FUNCPTR(gnutls_global_init)
|
||||
LOAD_FUNCPTR(gnutls_global_set_log_function)
|
||||
@@ -138,6 +146,7 @@ NTSTATUS WINAPI BCryptEnumAlgorithms(ULONG dwAlgOperations, ULONG *pAlgCount,
|
||||
|
||||
#define MAGIC_ALG (('A' << 24) | ('L' << 16) | ('G' << 8) | '0')
|
||||
#define MAGIC_HASH (('H' << 24) | ('A' << 16) | ('S' << 8) | 'H')
|
||||
+#define MAGIC_KEY (('K' << 24) | ('E' << 16) | ('Y' << 8) | '0')
|
||||
struct object
|
||||
{
|
||||
ULONG magic;
|
||||
@@ -145,6 +154,7 @@ struct object
|
||||
|
||||
enum alg_id
|
||||
{
|
||||
+ ALG_ID_AES,
|
||||
ALG_ID_MD5,
|
||||
ALG_ID_RNG,
|
||||
ALG_ID_SHA1,
|
||||
@@ -157,6 +167,7 @@ static const struct {
|
||||
ULONG hash_length;
|
||||
const WCHAR *alg_name;
|
||||
} alg_props[] = {
|
||||
+ /* ALG_ID_AES */ { 0, BCRYPT_AES_ALGORITHM },
|
||||
/* ALG_ID_MD5 */ { 16, BCRYPT_MD5_ALGORITHM },
|
||||
/* ALG_ID_RNG */ { 0, BCRYPT_RNG_ALGORITHM },
|
||||
/* ALG_ID_SHA1 */ { 20, BCRYPT_SHA1_ALGORITHM },
|
||||
@@ -215,11 +226,10 @@ NTSTATUS WINAPI BCryptGenRandom(BCRYPT_ALG_HANDLE handle, UCHAR *buffer, ULONG c
|
||||
|
||||
NTSTATUS WINAPI BCryptOpenAlgorithmProvider( BCRYPT_ALG_HANDLE *handle, LPCWSTR id, LPCWSTR implementation, DWORD flags )
|
||||
{
|
||||
+ const DWORD supported_flags = BCRYPT_ALG_HANDLE_HMAC_FLAG;
|
||||
struct algorithm *alg;
|
||||
enum alg_id alg_id;
|
||||
|
||||
- const DWORD supported_flags = BCRYPT_ALG_HANDLE_HMAC_FLAG;
|
||||
-
|
||||
TRACE( "%p, %s, %s, %08x\n", handle, wine_dbgstr_w(id), wine_dbgstr_w(implementation), flags );
|
||||
|
||||
if (!handle || !id) return STATUS_INVALID_PARAMETER;
|
||||
@@ -229,9 +239,10 @@ NTSTATUS WINAPI BCryptOpenAlgorithmProvider( BCRYPT_ALG_HANDLE *handle, LPCWSTR
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
- if (!strcmpW( id, BCRYPT_SHA1_ALGORITHM )) alg_id = ALG_ID_SHA1;
|
||||
+ if (!strcmpW( id, BCRYPT_AES_ALGORITHM )) alg_id = ALG_ID_AES;
|
||||
else if (!strcmpW( id, BCRYPT_MD5_ALGORITHM )) alg_id = ALG_ID_MD5;
|
||||
else if (!strcmpW( id, BCRYPT_RNG_ALGORITHM )) alg_id = ALG_ID_RNG;
|
||||
+ else if (!strcmpW( id, BCRYPT_SHA1_ALGORITHM )) alg_id = ALG_ID_SHA1;
|
||||
else if (!strcmpW( id, BCRYPT_SHA256_ALGORITHM )) alg_id = ALG_ID_SHA256;
|
||||
else if (!strcmpW( id, BCRYPT_SHA384_ALGORITHM )) alg_id = ALG_ID_SHA384;
|
||||
else if (!strcmpW( id, BCRYPT_SHA512_ALGORITHM )) alg_id = ALG_ID_SHA512;
|
||||
@@ -430,7 +441,6 @@ static NTSTATUS hash_finish( struct hash *hash, UCHAR *output, ULONG size )
|
||||
static NTSTATUS hmac_finish( struct hash *hash, UCHAR *output, ULONG size )
|
||||
{
|
||||
CCHmacFinal( &hash->u.hmac_ctx, output );
|
||||
-
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
#elif defined(HAVE_GNUTLS_HASH)
|
||||
@@ -586,12 +596,19 @@ static NTSTATUS hmac_finish( struct hash *hash, UCHAR *output, ULONG size )
|
||||
}
|
||||
#endif
|
||||
|
||||
+#ifdef _WIN64
|
||||
+#define OBJECT_LENGTH_AES 654
|
||||
+#else
|
||||
+#define OBJECT_LENGTH_AES 618
|
||||
+#endif
|
||||
#define OBJECT_LENGTH_MD5 274
|
||||
#define OBJECT_LENGTH_SHA1 278
|
||||
#define OBJECT_LENGTH_SHA256 286
|
||||
#define OBJECT_LENGTH_SHA384 382
|
||||
#define OBJECT_LENGTH_SHA512 382
|
||||
|
||||
+#define BLOCK_LENGTH_AES 16
|
||||
+
|
||||
static NTSTATUS generic_alg_property( enum alg_id id, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size )
|
||||
{
|
||||
if (!strcmpW( prop, BCRYPT_HASH_LENGTH ))
|
||||
@@ -628,6 +645,34 @@ static NTSTATUS get_alg_property( enum alg_id id, const WCHAR *prop, UCHAR *buf,
|
||||
|
||||
switch (id)
|
||||
{
|
||||
+ case ALG_ID_AES:
|
||||
+ if (!strcmpW( prop, BCRYPT_BLOCK_LENGTH ))
|
||||
+ {
|
||||
+ value = BLOCK_LENGTH_AES;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (!strcmpW( prop, BCRYPT_OBJECT_LENGTH ))
|
||||
+ {
|
||||
+ value = OBJECT_LENGTH_AES;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (!strcmpW( prop, BCRYPT_CHAINING_MODE ))
|
||||
+ {
|
||||
+ if (size >= sizeof(BCRYPT_CHAIN_MODE_CBC))
|
||||
+ {
|
||||
+ memcpy(buf, BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC));
|
||||
+ *ret_size = sizeof(BCRYPT_CHAIN_MODE_CBC) * sizeof(WCHAR);
|
||||
+ return STATUS_SUCCESS;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ *ret_size = sizeof(BCRYPT_CHAIN_MODE_CBC) * sizeof(WCHAR);
|
||||
+ return STATUS_BUFFER_TOO_SMALL;
|
||||
+ }
|
||||
+ }
|
||||
+ FIXME( "unsupported aes algorithm property %s\n", debugstr_w(prop) );
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
+
|
||||
case ALG_ID_MD5:
|
||||
if (!strcmpW( prop, BCRYPT_OBJECT_LENGTH ))
|
||||
{
|
||||
@@ -731,6 +776,13 @@ NTSTATUS WINAPI BCryptGetProperty( BCRYPT_HANDLE handle, LPCWSTR prop, UCHAR *bu
|
||||
}
|
||||
}
|
||||
|
||||
+NTSTATUS WINAPI BCryptSetProperty( BCRYPT_HANDLE handle, const WCHAR *prop, UCHAR *value,
|
||||
+ ULONG size, ULONG flags )
|
||||
+{
|
||||
+ FIXME( "%p, %s, %p, %u, %08x\n", handle, debugstr_w(prop), value, size, flags );
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
+}
|
||||
+
|
||||
NTSTATUS WINAPI BCryptCreateHash( BCRYPT_ALG_HANDLE algorithm, BCRYPT_HASH_HANDLE *handle, UCHAR *object, ULONG objectlen,
|
||||
UCHAR *secret, ULONG secretlen, ULONG flags )
|
||||
{
|
||||
@@ -854,6 +906,293 @@ NTSTATUS WINAPI BCryptHash( BCRYPT_ALG_HANDLE algorithm, UCHAR *secret, ULONG se
|
||||
return BCryptDestroyHash( handle );
|
||||
}
|
||||
|
||||
+#if defined(HAVE_GNUTLS_HASH)
|
||||
+struct key
|
||||
+{
|
||||
+ struct object hdr;
|
||||
+ enum alg_id alg_id;
|
||||
+ ULONG block_size;
|
||||
+ gnutls_cipher_hd_t handle;
|
||||
+ UCHAR *secret;
|
||||
+ ULONG secret_len;
|
||||
+};
|
||||
+
|
||||
+static ULONG get_block_size( enum alg_id alg )
|
||||
+{
|
||||
+ ULONG ret = 0, size = sizeof(ret);
|
||||
+ get_alg_property( alg, BCRYPT_BLOCK_LENGTH, (UCHAR *)&ret, sizeof(ret), &size );
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static NTSTATUS key_init( struct key *key, enum alg_id id, UCHAR *secret, ULONG secret_len )
|
||||
+{
|
||||
+ if (!libgnutls_handle) return STATUS_INTERNAL_ERROR;
|
||||
+
|
||||
+ switch (id)
|
||||
+ {
|
||||
+ case ALG_ID_AES:
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ FIXME( "algorithm %u not supported\n", id );
|
||||
+ return STATUS_NOT_SUPPORTED;
|
||||
+ }
|
||||
+
|
||||
+ if (!(key->block_size = get_block_size( id ))) return STATUS_INVALID_PARAMETER;
|
||||
+
|
||||
+ key->alg_id = id;
|
||||
+ key->handle = 0; /* initialized on first use */
|
||||
+ key->secret = secret;
|
||||
+ key->secret_len = secret_len;
|
||||
+
|
||||
+ return STATUS_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static gnutls_cipher_algorithm_t get_gnutls_cipher( const struct key *key )
|
||||
+{
|
||||
+ switch (key->alg_id)
|
||||
+ {
|
||||
+ case ALG_ID_AES:
|
||||
+ FIXME( "handle block size and chaining mode\n" );
|
||||
+ return GNUTLS_CIPHER_AES_128_CBC;
|
||||
+
|
||||
+ default:
|
||||
+ FIXME( "algorithm %u not supported\n", key->alg_id );
|
||||
+ return GNUTLS_CIPHER_UNKNOWN;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static NTSTATUS key_set_params( struct key *key, UCHAR *iv, ULONG iv_len )
|
||||
+{
|
||||
+ gnutls_cipher_algorithm_t cipher;
|
||||
+ gnutls_datum_t secret, vector;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (key->handle)
|
||||
+ {
|
||||
+ pgnutls_cipher_deinit( key->handle );
|
||||
+ key->handle = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if ((cipher = get_gnutls_cipher( key )) == GNUTLS_CIPHER_UNKNOWN)
|
||||
+ return STATUS_NOT_SUPPORTED;
|
||||
+
|
||||
+ secret.data = key->secret;
|
||||
+ secret.size = key->secret_len;
|
||||
+ if (iv)
|
||||
+ {
|
||||
+ vector.data = iv;
|
||||
+ vector.size = iv_len;
|
||||
+ }
|
||||
+
|
||||
+ if ((ret = pgnutls_cipher_init( &key->handle, cipher, &secret, iv ? &vector : NULL )))
|
||||
+ {
|
||||
+ pgnutls_perror( ret );
|
||||
+ return STATUS_INTERNAL_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ return STATUS_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static NTSTATUS key_encrypt( struct key *key, const UCHAR *input, ULONG input_len, UCHAR *output,
|
||||
+ ULONG output_len )
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ if ((ret = pgnutls_cipher_encrypt2( key->handle, input, input_len, output, output_len )))
|
||||
+ {
|
||||
+ pgnutls_perror( ret );
|
||||
+ return STATUS_INTERNAL_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ return STATUS_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static NTSTATUS key_decrypt( struct key *key, const UCHAR *input, ULONG input_len, UCHAR *output,
|
||||
+ ULONG output_len )
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ if ((ret = pgnutls_cipher_decrypt2( key->handle, input, input_len, output, output_len )))
|
||||
+ {
|
||||
+ pgnutls_perror( ret );
|
||||
+ return STATUS_INTERNAL_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ return STATUS_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static NTSTATUS key_destroy( struct key *key )
|
||||
+{
|
||||
+ if (key->handle) pgnutls_cipher_deinit( key->handle );
|
||||
+ HeapFree( GetProcessHeap(), 0, key->secret );
|
||||
+ HeapFree( GetProcessHeap(), 0, key );
|
||||
+ return STATUS_SUCCESS;
|
||||
+}
|
||||
+#else
|
||||
+struct key
|
||||
+{
|
||||
+ struct object hdr;
|
||||
+ ULONG block_size;
|
||||
+};
|
||||
+
|
||||
+static NTSTATUS key_init( struct key *key, enum alg_id id, const UCHAR *secret, ULONG secret_len )
|
||||
+{
|
||||
+ ERR( "support for keys not available at build time\n" );
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
+}
|
||||
+
|
||||
+static NTSTATUS key_set_params( struct key *key, UCHAR *iv, ULONG iv_len )
|
||||
+{
|
||||
+ ERR( "support for keys not available at build time\n" );
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
+}
|
||||
+
|
||||
+static NTSTATUS key_encrypt( struct key *key, const UCHAR *input, ULONG input_len, UCHAR *output,
|
||||
+ ULONG output_len )
|
||||
+{
|
||||
+ ERR( "support for keys not available at build time\n" );
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
+}
|
||||
+
|
||||
+static NTSTATUS key_decrypt( struct key *key, const UCHAR *input, ULONG input_len, UCHAR *output,
|
||||
+ ULONG output_len )
|
||||
+{
|
||||
+ ERR( "support for keys not available at build time\n" );
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
+}
|
||||
+
|
||||
+static NTSTATUS key_destroy( struct key *key )
|
||||
+{
|
||||
+ ERR( "support for keys not available at build time\n" );
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+NTSTATUS WINAPI BCryptGenerateSymmetricKey( BCRYPT_ALG_HANDLE algorithm, BCRYPT_KEY_HANDLE *handle,
|
||||
+ UCHAR *object, ULONG object_len, UCHAR *secret, ULONG secret_len,
|
||||
+ ULONG flags )
|
||||
+{
|
||||
+ struct algorithm *alg = algorithm;
|
||||
+ struct key *key;
|
||||
+ NTSTATUS status;
|
||||
+
|
||||
+ TRACE( "%p, %p, %p, %u, %p, %u, %08x\n", alg, handle, object, object_len, secret, secret_len, flags );
|
||||
+
|
||||
+ if (!alg || alg->hdr.magic != MAGIC_ALG) return STATUS_INVALID_HANDLE;
|
||||
+ if (object) FIXME( "ignoring object buffer\n" );
|
||||
+
|
||||
+ if (!(key = HeapAlloc( GetProcessHeap(), 0, sizeof(*key) ))) return STATUS_NO_MEMORY;
|
||||
+ key->hdr.magic = MAGIC_KEY;
|
||||
+
|
||||
+ if ((status = key_init( key, alg->id, secret, secret_len )))
|
||||
+ {
|
||||
+ HeapFree( GetProcessHeap(), 0, key );
|
||||
+ return status;
|
||||
+ }
|
||||
+
|
||||
+ *handle = key;
|
||||
+ return STATUS_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+NTSTATUS WINAPI BCryptDestroyKey( BCRYPT_KEY_HANDLE handle )
|
||||
+{
|
||||
+ struct key *key = handle;
|
||||
+
|
||||
+ TRACE( "%p\n", handle );
|
||||
+
|
||||
+ if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE;
|
||||
+ return key_destroy( key );
|
||||
+}
|
||||
+
|
||||
+NTSTATUS WINAPI BCryptEncrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG input_len,
|
||||
+ void *padding, UCHAR *iv, ULONG iv_len, UCHAR *output,
|
||||
+ ULONG output_len, ULONG *ret_len, ULONG flags )
|
||||
+{
|
||||
+ struct key *key = handle;
|
||||
+ ULONG bytes_left = input_len;
|
||||
+ UCHAR *buf, *src, *dst;
|
||||
+ NTSTATUS status;
|
||||
+
|
||||
+ TRACE( "%p, %p, %u, %p, %p, %u, %p, %u, %p, %08x\n", handle, input, input_len,
|
||||
+ padding, iv, iv_len, output, output_len, ret_len, flags );
|
||||
+
|
||||
+ if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE;
|
||||
+ if (padding)
|
||||
+ {
|
||||
+ FIXME( "padding info not implemented\n" );
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
+ }
|
||||
+ if (flags & ~BCRYPT_BLOCK_PADDING)
|
||||
+ {
|
||||
+ FIXME( "flags %08x not implemented\n", flags );
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
+ }
|
||||
+
|
||||
+ if ((status = key_set_params( key, iv, iv_len ))) return status;
|
||||
+
|
||||
+ *ret_len = input_len;
|
||||
+ if (input_len & (key->block_size - 1))
|
||||
+ {
|
||||
+ if (!(flags & BCRYPT_BLOCK_PADDING)) return STATUS_INVALID_BUFFER_SIZE;
|
||||
+ *ret_len = (input_len + key->block_size - 1) & ~(key->block_size - 1);
|
||||
+ }
|
||||
+ if (!output) return STATUS_SUCCESS;
|
||||
+ if (output_len < *ret_len) return STATUS_BUFFER_TOO_SMALL;
|
||||
+
|
||||
+ src = input;
|
||||
+ dst = output;
|
||||
+ while (bytes_left >= key->block_size)
|
||||
+ {
|
||||
+ if ((status = key_encrypt( key, src, key->block_size, dst, key->block_size ))) return status;
|
||||
+ bytes_left -= key->block_size;
|
||||
+ src += key->block_size;
|
||||
+ dst += key->block_size;
|
||||
+ }
|
||||
+ if (bytes_left)
|
||||
+ {
|
||||
+ if (!(buf = HeapAlloc( GetProcessHeap(), 0, key->block_size ))) return STATUS_NO_MEMORY;
|
||||
+ memcpy( buf, src, bytes_left );
|
||||
+ memset( buf + bytes_left, key->block_size - bytes_left, key->block_size - bytes_left );
|
||||
+ status = key_encrypt( key, buf, key->block_size, dst, key->block_size );
|
||||
+ HeapFree( GetProcessHeap(), 0, buf );
|
||||
+ }
|
||||
+
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
+NTSTATUS WINAPI BCryptDecrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG input_len,
|
||||
+ void *padding, UCHAR *iv, ULONG iv_len, UCHAR *output,
|
||||
+ ULONG output_len, ULONG *ret_len, ULONG flags )
|
||||
+{
|
||||
+ struct key *key = handle;
|
||||
+ NTSTATUS status;
|
||||
+
|
||||
+ FIXME( "%p, %p, %u, %p, %p, %u, %p, %u, %p, %08x\n", handle, input, input_len,
|
||||
+ padding, iv, iv_len, output, output_len, ret_len, flags );
|
||||
+
|
||||
+ if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE;
|
||||
+ if (padding)
|
||||
+ {
|
||||
+ FIXME( "padding info not implemented\n" );
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
+ }
|
||||
+ if (flags & ~BCRYPT_BLOCK_PADDING)
|
||||
+ {
|
||||
+ FIXME( "flags %08x not supported\n", flags );
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
+ }
|
||||
+
|
||||
+ if ((status = key_set_params( key, iv, iv_len ))) return status;
|
||||
+
|
||||
+ *ret_len = input_len;
|
||||
+ if (input_len & (key->block_size - 1)) return STATUS_INVALID_BUFFER_SIZE;
|
||||
+ if (!output) return STATUS_SUCCESS;
|
||||
+ if (output_len < *ret_len) return STATUS_BUFFER_TOO_SMALL;
|
||||
+
|
||||
+ return key_decrypt( key, input, input_len, output, output_len );
|
||||
+}
|
||||
+
|
||||
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
|
||||
{
|
||||
switch (reason)
|
||||
diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c
|
||||
index 3e41335..2668153 100644
|
||||
--- a/dlls/bcrypt/tests/bcrypt.c
|
||||
+++ b/dlls/bcrypt/tests/bcrypt.c
|
||||
@@ -780,7 +780,7 @@ static void test_aes(void)
|
||||
ULONG size, len;
|
||||
UCHAR mode[64];
|
||||
NTSTATUS ret;
|
||||
-todo_wine {
|
||||
+
|
||||
alg = NULL;
|
||||
ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_AES_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
@@ -828,7 +828,6 @@ todo_wine {
|
||||
ret = pBCryptCloseAlgorithmProvider(alg, 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
}
|
||||
-}
|
||||
|
||||
static void test_BCryptGenerateSymmetricKey(void)
|
||||
{
|
||||
@@ -847,11 +846,6 @@ static void test_BCryptGenerateSymmetricKey(void)
|
||||
NTSTATUS ret;
|
||||
|
||||
ret = pBCryptOpenAlgorithmProvider(&aes, BCRYPT_AES_ALGORITHM, NULL, 0);
|
||||
- if (ret != STATUS_SUCCESS) /* remove whole IF when Wine is fixed */
|
||||
- {
|
||||
- todo_wine ok(0, "AES provider not available\n");
|
||||
- return;
|
||||
- }
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
|
||||
len = size = 0xdeadbeef;
|
||||
@@ -936,11 +930,6 @@ static void test_BCryptEncrypt(void)
|
||||
NTSTATUS ret;
|
||||
|
||||
ret = pBCryptOpenAlgorithmProvider(&aes, BCRYPT_AES_ALGORITHM, NULL, 0);
|
||||
- if (ret != STATUS_SUCCESS) /* remove whole IF when Wine is fixed */
|
||||
- {
|
||||
- todo_wine ok(0, "AES provider not available\n");
|
||||
- return;
|
||||
- }
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
|
||||
len = 0xdeadbeef;
|
||||
@@ -1027,11 +1016,6 @@ static void test_BCryptDecrypt(void)
|
||||
NTSTATUS ret;
|
||||
|
||||
ret = pBCryptOpenAlgorithmProvider(&aes, BCRYPT_AES_ALGORITHM, NULL, 0);
|
||||
- if (ret != STATUS_SUCCESS) /* remove whole IF when Wine is fixed */
|
||||
- {
|
||||
- todo_wine ok(0, "AES provider not available\n");
|
||||
- return;
|
||||
- }
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
|
||||
len = 0xdeadbeef;
|
||||
diff --git a/include/bcrypt.h b/include/bcrypt.h
|
||||
index 05d0691..6af85e3 100644
|
||||
--- a/include/bcrypt.h
|
||||
+++ b/include/bcrypt.h
|
||||
@@ -74,6 +74,9 @@ typedef LONG NTSTATUS;
|
||||
#define BCRYPT_CHAIN_MODE_NA (const WCHAR []){'C','h','a','i','n','i','n','g','M','o','d','e','N','/','A',0}
|
||||
#define BCRYPT_CHAIN_MODE_CBC (const WCHAR []){'C','h','a','i','n','i','n','g','M','o','d','e','C','B','C',0}
|
||||
#define BCRYPT_CHAIN_MODE_ECB (const WCHAR []){'C','h','a','i','n','i','n','g','M','o','d','e','E','C','B',0}
|
||||
+#define BCRYPT_CHAIN_MODE_CFB (const WCHAR []){'C','h','a','i','n','i','n','g','M','o','d','e','C','F','B',0}
|
||||
+#define BCRYPT_CHAIN_MODE_CCM (const WCHAR []){'C','h','a','i','n','i','n','g','M','o','d','e','C','C','M',0}
|
||||
+#define BCRYPT_CHAIN_MODE_GCM (const WCHAR []){'C','h','a','i','n','i','n','g','M','o','d','e','G','C','M',0}
|
||||
|
||||
typedef struct _BCRYPT_ALGORITHM_IDENTIFIER
|
||||
{
|
||||
--
|
||||
2.9.0
|
||||
|
@ -0,0 +1,469 @@
|
||||
From f527689b793100c79654ac5d6c1376d128ca3175 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Mon, 19 Dec 2016 23:58:52 +0100
|
||||
Subject: bcrypt: Directly implement hmac computation.
|
||||
|
||||
---
|
||||
dlls/bcrypt/bcrypt_main.c | 277 +++++++++++++++++-----------------------------
|
||||
1 file changed, 104 insertions(+), 173 deletions(-)
|
||||
|
||||
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
|
||||
index 937bdf7..af2314a 100644
|
||||
--- a/dlls/bcrypt/bcrypt_main.c
|
||||
+++ b/dlls/bcrypt/bcrypt_main.c
|
||||
@@ -60,9 +60,6 @@ MAKE_FUNCPTR(gnutls_global_set_log_level);
|
||||
MAKE_FUNCPTR(gnutls_hash);
|
||||
MAKE_FUNCPTR(gnutls_hash_deinit);
|
||||
MAKE_FUNCPTR(gnutls_hash_init);
|
||||
-MAKE_FUNCPTR(gnutls_hmac);
|
||||
-MAKE_FUNCPTR(gnutls_hmac_deinit);
|
||||
-MAKE_FUNCPTR(gnutls_hmac_init);
|
||||
MAKE_FUNCPTR(gnutls_perror);
|
||||
#undef MAKE_FUNCPTR
|
||||
|
||||
@@ -99,9 +96,6 @@ static BOOL gnutls_initialize(void)
|
||||
LOAD_FUNCPTR(gnutls_hash);
|
||||
LOAD_FUNCPTR(gnutls_hash_deinit);
|
||||
LOAD_FUNCPTR(gnutls_hash_init);
|
||||
- LOAD_FUNCPTR(gnutls_hmac);
|
||||
- LOAD_FUNCPTR(gnutls_hmac_deinit);
|
||||
- LOAD_FUNCPTR(gnutls_hmac_init);
|
||||
LOAD_FUNCPTR(gnutls_perror)
|
||||
#undef LOAD_FUNCPTR
|
||||
|
||||
@@ -163,6 +157,8 @@ enum alg_id
|
||||
ALG_ID_SHA512
|
||||
};
|
||||
|
||||
+#define MAX_HASH_OUTPUT_BYTES 64
|
||||
+
|
||||
static const struct {
|
||||
ULONG hash_length;
|
||||
const WCHAR *alg_name;
|
||||
@@ -183,6 +179,19 @@ struct algorithm
|
||||
BOOL hmac;
|
||||
};
|
||||
|
||||
+#define MAX_HASH_BLOCK_BITS 1024
|
||||
+
|
||||
+int alg_block_bits[] =
|
||||
+{
|
||||
+ /* ALG_ID_AES */ 0,
|
||||
+ /* ALG_ID_MD5 */ 512,
|
||||
+ /* ALG_ID_RNG */ 0,
|
||||
+ /* ALG_ID_SHA1 */ 512,
|
||||
+ /* ALG_ID_SHA256 */ 512,
|
||||
+ /* ALG_ID_SHA384 */ 1024,
|
||||
+ /* ALG_ID_SHA512 */ 1024
|
||||
+};
|
||||
+
|
||||
NTSTATUS WINAPI BCryptGenRandom(BCRYPT_ALG_HANDLE handle, UCHAR *buffer, ULONG count, ULONG flags)
|
||||
{
|
||||
const DWORD supported_flags = BCRYPT_USE_SYSTEM_PREFERRED_RNG;
|
||||
@@ -289,24 +298,20 @@ NTSTATUS WINAPI BCryptGetFipsAlgorithmMode(BOOLEAN *enabled)
|
||||
}
|
||||
|
||||
#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
|
||||
-struct hash
|
||||
+struct hash_impl
|
||||
{
|
||||
- struct object hdr;
|
||||
- enum alg_id alg_id;
|
||||
- BOOL hmac;
|
||||
union
|
||||
{
|
||||
CC_MD5_CTX md5_ctx;
|
||||
CC_SHA1_CTX sha1_ctx;
|
||||
CC_SHA256_CTX sha256_ctx;
|
||||
CC_SHA512_CTX sha512_ctx;
|
||||
- CCHmacContext hmac_ctx;
|
||||
} u;
|
||||
};
|
||||
|
||||
-static NTSTATUS hash_init( struct hash *hash )
|
||||
+static NTSTATUS hash_init( struct hash_impl *hash, enum alg_id alg_id )
|
||||
{
|
||||
- switch (hash->alg_id)
|
||||
+ switch (alg_id)
|
||||
{
|
||||
case ALG_ID_MD5:
|
||||
CC_MD5_Init( &hash->u.md5_ctx );
|
||||
@@ -329,50 +334,16 @@ static NTSTATUS hash_init( struct hash *hash )
|
||||
break;
|
||||
|
||||
default:
|
||||
- ERR( "unhandled id %u\n", hash->alg_id );
|
||||
+ ERR( "unhandled id %u\n", alg_id );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
-static NTSTATUS hmac_init( struct hash *hash, UCHAR *key, ULONG key_size )
|
||||
+static NTSTATUS hash_update( struct hash_impl *hash, enum alg_id alg_id,
|
||||
+ UCHAR *input, ULONG size )
|
||||
{
|
||||
- CCHmacAlgorithm cc_algorithm;
|
||||
- switch (hash->alg_id)
|
||||
- {
|
||||
- case ALG_ID_MD5:
|
||||
- cc_algorithm = kCCHmacAlgMD5;
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA1:
|
||||
- cc_algorithm = kCCHmacAlgSHA1;
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA256:
|
||||
- cc_algorithm = kCCHmacAlgSHA256;
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA384:
|
||||
- cc_algorithm = kCCHmacAlgSHA384;
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA512:
|
||||
- cc_algorithm = kCCHmacAlgSHA512;
|
||||
- break;
|
||||
-
|
||||
- default:
|
||||
- ERR( "unhandled id %u\n", hash->alg_id );
|
||||
- return STATUS_NOT_IMPLEMENTED;
|
||||
- }
|
||||
-
|
||||
- CCHmacInit( &hash->u.hmac_ctx, cc_algorithm, key, key_size );
|
||||
- return STATUS_SUCCESS;
|
||||
-}
|
||||
-
|
||||
-
|
||||
-static NTSTATUS hash_update( struct hash *hash, UCHAR *input, ULONG size )
|
||||
-{
|
||||
- switch (hash->alg_id)
|
||||
+ switch (alg_id)
|
||||
{
|
||||
case ALG_ID_MD5:
|
||||
CC_MD5_Update( &hash->u.md5_ctx, input, size );
|
||||
@@ -395,21 +366,16 @@ static NTSTATUS hash_update( struct hash *hash, UCHAR *input, ULONG size )
|
||||
break;
|
||||
|
||||
default:
|
||||
- ERR( "unhandled id %u\n", hash->alg_id );
|
||||
+ ERR( "unhandled id %u\n", alg_id );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
-static NTSTATUS hmac_update( struct hash *hash, UCHAR *input, ULONG size )
|
||||
-{
|
||||
- CCHmacUpdate( &hash->u.hmac_ctx, input, size );
|
||||
- return STATUS_SUCCESS;
|
||||
-}
|
||||
-
|
||||
-static NTSTATUS hash_finish( struct hash *hash, UCHAR *output, ULONG size )
|
||||
+static NTSTATUS hash_finish( struct hash_impl *hash, enum alg_id alg_id,
|
||||
+ UCHAR *output, ULONG size )
|
||||
{
|
||||
- switch (hash->alg_id)
|
||||
+ switch (alg_id)
|
||||
{
|
||||
case ALG_ID_MD5:
|
||||
CC_MD5_Final( output, &hash->u.md5_ctx );
|
||||
@@ -432,37 +398,25 @@ static NTSTATUS hash_finish( struct hash *hash, UCHAR *output, ULONG size )
|
||||
break;
|
||||
|
||||
default:
|
||||
- ERR( "unhandled id %u\n", hash->alg_id );
|
||||
+ ERR( "unhandled id %u\n", alg_id );
|
||||
break;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
-static NTSTATUS hmac_finish( struct hash *hash, UCHAR *output, ULONG size )
|
||||
-{
|
||||
- CCHmacFinal( &hash->u.hmac_ctx, output );
|
||||
- return STATUS_SUCCESS;
|
||||
-}
|
||||
#elif defined(HAVE_GNUTLS_HASH)
|
||||
-struct hash
|
||||
+struct hash_impl
|
||||
{
|
||||
- struct object hdr;
|
||||
- enum alg_id alg_id;
|
||||
- BOOL hmac;
|
||||
- union
|
||||
- {
|
||||
- gnutls_hash_hd_t hash_handle;
|
||||
- gnutls_hmac_hd_t hmac_handle;
|
||||
- } u;
|
||||
+ gnutls_hash_hd_t hash_handle;
|
||||
};
|
||||
|
||||
-static NTSTATUS hash_init( struct hash *hash )
|
||||
+static NTSTATUS hash_init( struct hash_impl *hash, enum alg_id alg_id )
|
||||
{
|
||||
gnutls_digest_algorithm_t alg;
|
||||
|
||||
if (!libgnutls_handle) return STATUS_INTERNAL_ERROR;
|
||||
|
||||
- switch (hash->alg_id)
|
||||
+ switch (alg_id)
|
||||
{
|
||||
case ALG_ID_MD5:
|
||||
alg = GNUTLS_DIG_MD5;
|
||||
@@ -484,117 +438,63 @@ static NTSTATUS hash_init( struct hash *hash )
|
||||
break;
|
||||
|
||||
default:
|
||||
- ERR( "unhandled id %u\n", hash->alg_id );
|
||||
- return STATUS_NOT_IMPLEMENTED;
|
||||
- }
|
||||
-
|
||||
- if (pgnutls_hash_init( &hash->u.hash_handle, alg )) return STATUS_INTERNAL_ERROR;
|
||||
- return STATUS_SUCCESS;
|
||||
-}
|
||||
-
|
||||
-static NTSTATUS hmac_init( struct hash *hash, UCHAR *key, ULONG key_size )
|
||||
-{
|
||||
- gnutls_mac_algorithm_t alg;
|
||||
-
|
||||
- if (!libgnutls_handle) return STATUS_INTERNAL_ERROR;
|
||||
-
|
||||
- switch (hash->alg_id)
|
||||
- {
|
||||
- case ALG_ID_MD5:
|
||||
- alg = GNUTLS_MAC_MD5;
|
||||
- break;
|
||||
- case ALG_ID_SHA1:
|
||||
- alg = GNUTLS_MAC_SHA1;
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA256:
|
||||
- alg = GNUTLS_MAC_SHA256;
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA384:
|
||||
- alg = GNUTLS_MAC_SHA384;
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA512:
|
||||
- alg = GNUTLS_MAC_SHA512;
|
||||
- break;
|
||||
-
|
||||
- default:
|
||||
- ERR( "unhandled id %u\n", hash->alg_id );
|
||||
+ ERR( "unhandled id %u\n", alg_id );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
- if (pgnutls_hmac_init( &hash->u.hmac_handle, alg, key, key_size )) return STATUS_INTERNAL_ERROR;
|
||||
- return STATUS_SUCCESS;
|
||||
-}
|
||||
-
|
||||
-static NTSTATUS hash_update( struct hash *hash, UCHAR *input, ULONG size )
|
||||
-{
|
||||
- if (pgnutls_hash( hash->u.hash_handle, input, size )) return STATUS_INTERNAL_ERROR;
|
||||
+ if (pgnutls_hash_init( &hash->hash_handle, alg )) return STATUS_INTERNAL_ERROR;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
-static NTSTATUS hmac_update( struct hash *hash, UCHAR *input, ULONG size )
|
||||
+static NTSTATUS hash_update( struct hash_impl *hash, enum alg_id alg_id,
|
||||
+ UCHAR *input, ULONG size )
|
||||
{
|
||||
- if (pgnutls_hmac( hash->u.hmac_handle, input, size )) return STATUS_INTERNAL_ERROR;
|
||||
+ if (pgnutls_hash( hash->hash_handle, input, size )) return STATUS_INTERNAL_ERROR;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
-static NTSTATUS hash_finish( struct hash *hash, UCHAR *output, ULONG size )
|
||||
+static NTSTATUS hash_finish( struct hash_impl *hash, enum alg_id alg_id,
|
||||
+ UCHAR *output, ULONG size )
|
||||
{
|
||||
- pgnutls_hash_deinit( hash->u.hash_handle, output );
|
||||
+ pgnutls_hash_deinit( hash->hash_handle, output );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
-static NTSTATUS hmac_finish( struct hash *hash, UCHAR *output, ULONG size )
|
||||
-{
|
||||
- pgnutls_hmac_deinit( hash->u.hmac_handle, output );
|
||||
- return STATUS_SUCCESS;
|
||||
-}
|
||||
#else
|
||||
-struct hash
|
||||
+struct hash_impl
|
||||
{
|
||||
- struct object hdr;
|
||||
- BOOL hmac;
|
||||
- enum alg_id alg_id;
|
||||
-};
|
||||
|
||||
-static NTSTATUS hash_init( struct hash *hash )
|
||||
-{
|
||||
- ERR( "support for hashes not available at build time\n" );
|
||||
- return STATUS_NOT_IMPLEMENTED;
|
||||
-}
|
||||
-
|
||||
-static NTSTATUS hmac_init( struct hash *hash, UCHAR *key, ULONG key_size )
|
||||
-{
|
||||
- ERR( "support for hashes not available at build time\n" );
|
||||
- return STATUS_NOT_IMPLEMENTED;
|
||||
-}
|
||||
+};
|
||||
|
||||
-static NTSTATUS hash_update( struct hash *hash, UCHAR *input, ULONG size )
|
||||
+static NTSTATUS hash_init( struct hash_impl *hash, enum alg_id alg_id )
|
||||
{
|
||||
ERR( "support for hashes not available at build time\n" );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
-static NTSTATUS hmac_update( struct hash *hash, UCHAR *input, ULONG size )
|
||||
+static NTSTATUS hash_update( struct hash_impl *hash, enum alg_id alg_id,
|
||||
+ UCHAR *input, ULONG size )
|
||||
{
|
||||
ERR( "support for hashes not available at build time\n" );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
-static NTSTATUS hash_finish( struct hash *hash, UCHAR *output, ULONG size )
|
||||
+static NTSTATUS hash_finish( struct hash_impl *hash, enum alg_id alg_id,
|
||||
+ UCHAR *output, ULONG size )
|
||||
{
|
||||
ERR( "support for hashes not available at build time\n" );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
+#endif
|
||||
|
||||
-static NTSTATUS hmac_finish( struct hash *hash, UCHAR *output, ULONG size )
|
||||
+struct hash
|
||||
{
|
||||
- ERR( "support for hashes not available at build time\n" );
|
||||
- return STATUS_NOT_IMPLEMENTED;
|
||||
-}
|
||||
-#endif
|
||||
+ struct object hdr;
|
||||
+ enum alg_id alg_id;
|
||||
+ BOOL hmac;
|
||||
+ struct hash_impl outer;
|
||||
+ struct hash_impl inner;
|
||||
+};
|
||||
|
||||
#ifdef _WIN64
|
||||
#define OBJECT_LENGTH_AES 654
|
||||
@@ -787,8 +687,11 @@ NTSTATUS WINAPI BCryptCreateHash( BCRYPT_ALG_HANDLE algorithm, BCRYPT_HASH_HANDL
|
||||
UCHAR *secret, ULONG secretlen, ULONG flags )
|
||||
{
|
||||
struct algorithm *alg = algorithm;
|
||||
+ UCHAR buffer[MAX_HASH_BLOCK_BITS / 8];
|
||||
struct hash *hash;
|
||||
+ int block_bytes;
|
||||
NTSTATUS status;
|
||||
+ int i;
|
||||
|
||||
TRACE( "%p, %p, %p, %u, %p, %u, %08x - stub\n", algorithm, handle, object, objectlen,
|
||||
secret, secretlen, flags );
|
||||
@@ -806,17 +709,45 @@ NTSTATUS WINAPI BCryptCreateHash( BCRYPT_ALG_HANDLE algorithm, BCRYPT_HASH_HANDL
|
||||
hash->alg_id = alg->id;
|
||||
hash->hmac = alg->hmac;
|
||||
|
||||
- if (hash->hmac)
|
||||
+ status = hash_init( &hash->inner, hash->alg_id );
|
||||
+ if (status || !hash->hmac) goto end;
|
||||
+ status = hash_init( &hash->outer, hash->alg_id );
|
||||
+ if (status) goto end;
|
||||
+
|
||||
+ /* reduce key size if too big */
|
||||
+ block_bytes = alg_block_bits[hash->alg_id] / 8;
|
||||
+ if (secretlen > block_bytes)
|
||||
{
|
||||
- status = hmac_init( hash, secret, secretlen );
|
||||
+ struct hash_impl temp;
|
||||
+ status = hash_init( &temp, hash->alg_id );
|
||||
+ if (status) goto end;
|
||||
+ status = hash_update( &temp, hash->alg_id, secret, secretlen );
|
||||
+ if (status) goto end;
|
||||
+ memset( buffer, 0, block_bytes );
|
||||
+ status = hash_finish( &temp, hash->alg_id, buffer, alg_props[hash->alg_id].hash_length );
|
||||
+ if (status) goto end;
|
||||
}
|
||||
else
|
||||
{
|
||||
- status = hash_init( hash );
|
||||
+ memset( buffer, 0, block_bytes );
|
||||
+ memcpy( buffer, secret, secretlen );
|
||||
}
|
||||
|
||||
+ /* initialize outer hash */
|
||||
+ for (i = 0; i < block_bytes; i++)
|
||||
+ buffer[i] ^= 0x5c;
|
||||
+ status = hash_update( &hash->outer, hash->alg_id, buffer, block_bytes );
|
||||
+ if (status) goto end;
|
||||
+
|
||||
+ /* initialize inner hash */
|
||||
+ for (i = 0; i < block_bytes; i++)
|
||||
+ buffer[i] ^= (0x5c ^ 0x36);
|
||||
+ status = hash_update( &hash->inner, hash->alg_id, buffer, block_bytes );
|
||||
+
|
||||
+end:
|
||||
if (status != STATUS_SUCCESS)
|
||||
{
|
||||
+ /* FIXME: call hash_finish to release resources */
|
||||
HeapFree( GetProcessHeap(), 0, hash );
|
||||
return status;
|
||||
}
|
||||
@@ -845,33 +776,33 @@ NTSTATUS WINAPI BCryptHashData( BCRYPT_HASH_HANDLE handle, UCHAR *input, ULONG s
|
||||
if (!hash || hash->hdr.magic != MAGIC_HASH) return STATUS_INVALID_HANDLE;
|
||||
if (!input) return STATUS_SUCCESS;
|
||||
|
||||
- if (hash->hmac)
|
||||
- {
|
||||
- return hmac_update( hash, input, size );
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- return hash_update( hash, input, size );
|
||||
- }
|
||||
+ return hash_update( &hash->inner, hash->alg_id, input, size );
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI BCryptFinishHash( BCRYPT_HASH_HANDLE handle, UCHAR *output, ULONG size, ULONG flags )
|
||||
{
|
||||
+ UCHAR buffer[MAX_HASH_OUTPUT_BYTES];
|
||||
struct hash *hash = handle;
|
||||
+ NTSTATUS status;
|
||||
+ int hash_size;
|
||||
|
||||
TRACE( "%p, %p, %u, %08x\n", handle, output, size, flags );
|
||||
|
||||
if (!hash || hash->hdr.magic != MAGIC_HASH) return STATUS_INVALID_HANDLE;
|
||||
if (!output) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
- if (hash->hmac)
|
||||
- {
|
||||
- return hmac_finish( hash, output, size );
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- return hash_finish( hash, output, size );
|
||||
- }
|
||||
+ if (!hash->hmac)
|
||||
+ return hash_finish( &hash->inner, hash->alg_id, output, size );
|
||||
+
|
||||
+ hash_size = alg_props[hash->alg_id].hash_length;
|
||||
+
|
||||
+ status = hash_finish( &hash->inner, hash->alg_id, buffer, hash_size);
|
||||
+ if (status) return status;
|
||||
+
|
||||
+ status = hash_update( &hash->outer, hash->alg_id, buffer, hash_size);
|
||||
+ if (status) return status;
|
||||
+
|
||||
+ return hash_finish( &hash->outer, hash->alg_id, output, size);
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI BCryptHash( BCRYPT_ALG_HANDLE algorithm, UCHAR *secret, ULONG secretlen,
|
||||
--
|
||||
2.9.0
|
||||
|
@ -0,0 +1,673 @@
|
||||
From ecff30df4deadc0df006a880a5528343a4ab788f Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Tue, 20 Dec 2016 02:36:57 +0100
|
||||
Subject: bcrypt: Add internal fallback implementation for hash calculations.
|
||||
|
||||
---
|
||||
dlls/bcrypt/Makefile.in | 5 +-
|
||||
dlls/bcrypt/bcrypt_internal.h | 79 +++++++++++++++++
|
||||
dlls/bcrypt/bcrypt_main.c | 101 ++++++++++++++++++++--
|
||||
dlls/bcrypt/sha256.c | 169 +++++++++++++++++++++++++++++++++++++
|
||||
dlls/bcrypt/sha384.c | 41 +++++++++
|
||||
dlls/bcrypt/sha512.c | 191 ++++++++++++++++++++++++++++++++++++++++++
|
||||
6 files changed, 578 insertions(+), 8 deletions(-)
|
||||
create mode 100644 dlls/bcrypt/bcrypt_internal.h
|
||||
create mode 100644 dlls/bcrypt/sha256.c
|
||||
create mode 100644 dlls/bcrypt/sha384.c
|
||||
create mode 100644 dlls/bcrypt/sha512.c
|
||||
|
||||
diff --git a/dlls/bcrypt/Makefile.in b/dlls/bcrypt/Makefile.in
|
||||
index ef9d7ea..38753bd 100644
|
||||
--- a/dlls/bcrypt/Makefile.in
|
||||
+++ b/dlls/bcrypt/Makefile.in
|
||||
@@ -4,6 +4,9 @@ IMPORTLIB = bcrypt
|
||||
EXTRAINCL = $(GNUTLS_CFLAGS)
|
||||
|
||||
C_SRCS = \
|
||||
- bcrypt_main.c
|
||||
+ bcrypt_main.c \
|
||||
+ sha256.c \
|
||||
+ sha512.c \
|
||||
+ sha384.c
|
||||
|
||||
RC_SRCS = version.rc
|
||||
diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h
|
||||
new file mode 100644
|
||||
index 0000000..8a8f6d1
|
||||
--- /dev/null
|
||||
+++ b/dlls/bcrypt/bcrypt_internal.h
|
||||
@@ -0,0 +1,79 @@
|
||||
+/*
|
||||
+ * Copyright 2016 Michael Müller
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library 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
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef __BCRYPT_INTERNAL_H
|
||||
+#define __BCRYPT_INTERNAL_H
|
||||
+
|
||||
+#include <stdarg.h>
|
||||
+
|
||||
+#include "windef.h"
|
||||
+#include "winbase.h"
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ ULONG64 len;
|
||||
+ DWORD h[8];
|
||||
+ UCHAR buf[64];
|
||||
+} SHA256_CTX;
|
||||
+
|
||||
+void sha256_init(SHA256_CTX *ctx);
|
||||
+void sha256_update(SHA256_CTX *ctx, const UCHAR *buffer, ULONG len);
|
||||
+void sha256_finalize(SHA256_CTX *ctx, UCHAR *buffer);
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ ULONG64 len;
|
||||
+ ULONG64 h[8];
|
||||
+ UCHAR buf[128];
|
||||
+} SHA512_CTX;
|
||||
+
|
||||
+void sha512_init(SHA512_CTX *ctx);
|
||||
+void sha512_update(SHA512_CTX *ctx, const UCHAR *buffer, ULONG len);
|
||||
+void sha512_finalize(SHA512_CTX *ctx, UCHAR *buffer);
|
||||
+
|
||||
+void sha384_init(SHA512_CTX *ctx);
|
||||
+#define sha384_update sha512_update
|
||||
+void sha384_finalize(SHA512_CTX *ctx, UCHAR *buffer);
|
||||
+
|
||||
+/* Definitions from advapi32 */
|
||||
+typedef struct
|
||||
+{
|
||||
+ unsigned int i[2];
|
||||
+ unsigned int buf[4];
|
||||
+ unsigned char in[64];
|
||||
+ unsigned char digest[16];
|
||||
+} MD5_CTX;
|
||||
+
|
||||
+VOID WINAPI MD5Init(MD5_CTX *ctx);
|
||||
+VOID WINAPI MD5Update(MD5_CTX *ctx, const unsigned char *buf, unsigned int len);
|
||||
+VOID WINAPI MD5Final(MD5_CTX *ctx);
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ ULONG Unknown[6];
|
||||
+ ULONG State[5];
|
||||
+ ULONG Count[2];
|
||||
+ UCHAR Buffer[64];
|
||||
+} SHA_CTX;
|
||||
+
|
||||
+VOID WINAPI A_SHAInit(SHA_CTX *ctx);
|
||||
+VOID WINAPI A_SHAUpdate(SHA_CTX *ctx, const UCHAR *buffer, UINT size);
|
||||
+VOID WINAPI A_SHAFinal(SHA_CTX *ctx, PULONG result);
|
||||
+
|
||||
+#endif /* __BCRYPT_INTERNAL_H */
|
||||
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
|
||||
index af2314a..9441cf0 100644
|
||||
--- a/dlls/bcrypt/bcrypt_main.c
|
||||
+++ b/dlls/bcrypt/bcrypt_main.c
|
||||
@@ -36,6 +36,8 @@
|
||||
#include "ntsecapi.h"
|
||||
#include "bcrypt.h"
|
||||
|
||||
+#include "bcrypt_internal.h"
|
||||
+
|
||||
#include "wine/debug.h"
|
||||
#include "wine/library.h"
|
||||
#include "wine/unicode.h"
|
||||
@@ -463,27 +465,112 @@ static NTSTATUS hash_finish( struct hash_impl *hash, enum alg_id alg_id,
|
||||
#else
|
||||
struct hash_impl
|
||||
{
|
||||
-
|
||||
+ union
|
||||
+ {
|
||||
+ MD5_CTX md5;
|
||||
+ SHA_CTX sha1;
|
||||
+ SHA256_CTX sha256;
|
||||
+ SHA512_CTX sha512;
|
||||
+ } u;
|
||||
};
|
||||
|
||||
static NTSTATUS hash_init( struct hash_impl *hash, enum alg_id alg_id )
|
||||
{
|
||||
- ERR( "support for hashes not available at build time\n" );
|
||||
- return STATUS_NOT_IMPLEMENTED;
|
||||
+ switch (alg_id)
|
||||
+ {
|
||||
+ case ALG_ID_MD5:
|
||||
+ MD5Init(&hash->u.md5);
|
||||
+ break;
|
||||
+
|
||||
+ case ALG_ID_SHA1:
|
||||
+ A_SHAInit(&hash->u.sha1);
|
||||
+ break;
|
||||
+
|
||||
+ case ALG_ID_SHA256:
|
||||
+ sha256_init(&hash->u.sha256);
|
||||
+ break;
|
||||
+
|
||||
+ case ALG_ID_SHA384:
|
||||
+ sha384_init(&hash->u.sha512);
|
||||
+ break;
|
||||
+
|
||||
+ case ALG_ID_SHA512:
|
||||
+ sha512_init(&hash->u.sha512);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ ERR( "unhandled id %u\n", alg_id );
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
+ }
|
||||
+
|
||||
+ return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS hash_update( struct hash_impl *hash, enum alg_id alg_id,
|
||||
UCHAR *input, ULONG size )
|
||||
{
|
||||
- ERR( "support for hashes not available at build time\n" );
|
||||
- return STATUS_NOT_IMPLEMENTED;
|
||||
+ switch (alg_id)
|
||||
+ {
|
||||
+ case ALG_ID_MD5:
|
||||
+ MD5Update(&hash->u.md5, input, size);
|
||||
+ break;
|
||||
+
|
||||
+ case ALG_ID_SHA1:
|
||||
+ A_SHAUpdate(&hash->u.sha1, input, size);
|
||||
+ break;
|
||||
+
|
||||
+ case ALG_ID_SHA256:
|
||||
+ sha256_update(&hash->u.sha256, input, size);
|
||||
+ break;
|
||||
+
|
||||
+ case ALG_ID_SHA384:
|
||||
+ sha384_update(&hash->u.sha512, input, size);
|
||||
+ break;
|
||||
+
|
||||
+ case ALG_ID_SHA512:
|
||||
+ sha512_update(&hash->u.sha512, input, size);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ ERR( "unhandled id %u\n", alg_id );
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
+ }
|
||||
+
|
||||
+ return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS hash_finish( struct hash_impl *hash, enum alg_id alg_id,
|
||||
UCHAR *output, ULONG size )
|
||||
{
|
||||
- ERR( "support for hashes not available at build time\n" );
|
||||
- return STATUS_NOT_IMPLEMENTED;
|
||||
+ switch (alg_id)
|
||||
+ {
|
||||
+ case ALG_ID_MD5:
|
||||
+ MD5Final(&hash->u.md5);
|
||||
+ memcpy(output, hash->u.md5.digest, 16);
|
||||
+ break;
|
||||
+
|
||||
+ case ALG_ID_SHA1:
|
||||
+ A_SHAFinal(&hash->u.sha1, (ULONG*)output);
|
||||
+ break;
|
||||
+
|
||||
+ case ALG_ID_SHA256:
|
||||
+ sha256_finalize(&hash->u.sha256, output);
|
||||
+ break;
|
||||
+
|
||||
+ case ALG_ID_SHA384:
|
||||
+ sha384_finalize(&hash->u.sha512, output);
|
||||
+ break;
|
||||
+
|
||||
+ case ALG_ID_SHA512:
|
||||
+ sha512_finalize(&hash->u.sha512, output);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ ERR( "unhandled id %u\n", alg_id );
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
+ }
|
||||
+
|
||||
+ return STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
diff --git a/dlls/bcrypt/sha256.c b/dlls/bcrypt/sha256.c
|
||||
new file mode 100644
|
||||
index 0000000..48c4a48
|
||||
--- /dev/null
|
||||
+++ b/dlls/bcrypt/sha256.c
|
||||
@@ -0,0 +1,169 @@
|
||||
+/*
|
||||
+ * Copyright 2016 Michael Müller
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library 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
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+/* Based on public domain implementation from
|
||||
+ https://git.musl-libc.org/cgit/musl/tree/src/crypt/crypt_sha256.c */
|
||||
+
|
||||
+#include "bcrypt_internal.h"
|
||||
+
|
||||
+static DWORD ror(DWORD n, int k) { return (n >> k) | (n << (32-k)); }
|
||||
+#define Ch(x,y,z) (z ^ (x & (y ^ z)))
|
||||
+#define Maj(x,y,z) ((x & y) | (z & (x | y)))
|
||||
+#define S0(x) (ror(x,2) ^ ror(x,13) ^ ror(x,22))
|
||||
+#define S1(x) (ror(x,6) ^ ror(x,11) ^ ror(x,25))
|
||||
+#define R0(x) (ror(x,7) ^ ror(x,18) ^ (x>>3))
|
||||
+#define R1(x) (ror(x,17) ^ ror(x,19) ^ (x>>10))
|
||||
+
|
||||
+static const DWORD K[64] =
|
||||
+{
|
||||
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||
+};
|
||||
+
|
||||
+static void processblock(SHA256_CTX *ctx, const UCHAR *buffer)
|
||||
+{
|
||||
+ DWORD W[64], t1, t2, a, b, c, d, e, f, g, h;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < 16; i++)
|
||||
+ {
|
||||
+ W[i] = (DWORD)buffer[4*i]<<24;
|
||||
+ W[i] |= (DWORD)buffer[4*i+1]<<16;
|
||||
+ W[i] |= (DWORD)buffer[4*i+2]<<8;
|
||||
+ W[i] |= buffer[4*i+3];
|
||||
+ }
|
||||
+
|
||||
+ for (; i < 64; i++)
|
||||
+ W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16];
|
||||
+
|
||||
+ a = ctx->h[0];
|
||||
+ b = ctx->h[1];
|
||||
+ c = ctx->h[2];
|
||||
+ d = ctx->h[3];
|
||||
+ e = ctx->h[4];
|
||||
+ f = ctx->h[5];
|
||||
+ g = ctx->h[6];
|
||||
+ h = ctx->h[7];
|
||||
+
|
||||
+ for (i = 0; i < 64; i++)
|
||||
+ {
|
||||
+ t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i];
|
||||
+ t2 = S0(a) + Maj(a,b,c);
|
||||
+ h = g;
|
||||
+ g = f;
|
||||
+ f = e;
|
||||
+ e = d + t1;
|
||||
+ d = c;
|
||||
+ c = b;
|
||||
+ b = a;
|
||||
+ a = t1 + t2;
|
||||
+ }
|
||||
+
|
||||
+ ctx->h[0] += a;
|
||||
+ ctx->h[1] += b;
|
||||
+ ctx->h[2] += c;
|
||||
+ ctx->h[3] += d;
|
||||
+ ctx->h[4] += e;
|
||||
+ ctx->h[5] += f;
|
||||
+ ctx->h[6] += g;
|
||||
+ ctx->h[7] += h;
|
||||
+}
|
||||
+
|
||||
+static void pad(SHA256_CTX *ctx)
|
||||
+{
|
||||
+ ULONG64 r = ctx->len % 64;
|
||||
+
|
||||
+ ctx->buf[r++] = 0x80;
|
||||
+
|
||||
+ if (r > 56)
|
||||
+ {
|
||||
+ memset(ctx->buf + r, 0, 64 - r);
|
||||
+ r = 0;
|
||||
+ processblock(ctx, ctx->buf);
|
||||
+ }
|
||||
+
|
||||
+ memset(ctx->buf + r, 0, 56 - r);
|
||||
+ ctx->len *= 8;
|
||||
+ ctx->buf[56] = ctx->len >> 56;
|
||||
+ ctx->buf[57] = ctx->len >> 48;
|
||||
+ ctx->buf[58] = ctx->len >> 40;
|
||||
+ ctx->buf[59] = ctx->len >> 32;
|
||||
+ ctx->buf[60] = ctx->len >> 24;
|
||||
+ ctx->buf[61] = ctx->len >> 16;
|
||||
+ ctx->buf[62] = ctx->len >> 8;
|
||||
+ ctx->buf[63] = ctx->len;
|
||||
+
|
||||
+ processblock(ctx, ctx->buf);
|
||||
+}
|
||||
+
|
||||
+void sha256_init(SHA256_CTX *ctx)
|
||||
+{
|
||||
+ ctx->len = 0;
|
||||
+ ctx->h[0] = 0x6a09e667;
|
||||
+ ctx->h[1] = 0xbb67ae85;
|
||||
+ ctx->h[2] = 0x3c6ef372;
|
||||
+ ctx->h[3] = 0xa54ff53a;
|
||||
+ ctx->h[4] = 0x510e527f;
|
||||
+ ctx->h[5] = 0x9b05688c;
|
||||
+ ctx->h[6] = 0x1f83d9ab;
|
||||
+ ctx->h[7] = 0x5be0cd19;
|
||||
+}
|
||||
+
|
||||
+void sha256_update(SHA256_CTX *ctx, const UCHAR *buffer, ULONG len)
|
||||
+{
|
||||
+ const UCHAR *p = buffer;
|
||||
+ ULONG64 r = ctx->len % 64;
|
||||
+
|
||||
+ ctx->len += len;
|
||||
+ if (r)
|
||||
+ {
|
||||
+ if (len < 64 - r)
|
||||
+ {
|
||||
+ memcpy(ctx->buf + r, p, len);
|
||||
+ return;
|
||||
+ }
|
||||
+ memcpy(ctx->buf + r, p, 64 - r);
|
||||
+ len -= 64 - r;
|
||||
+ p += 64 - r;
|
||||
+ processblock(ctx, ctx->buf);
|
||||
+ }
|
||||
+ for (; len >= 64; len -= 64, p += 64)
|
||||
+ processblock(ctx, p);
|
||||
+ memcpy(ctx->buf, p, len);
|
||||
+}
|
||||
+
|
||||
+void sha256_finalize(SHA256_CTX *ctx, UCHAR *buffer)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ pad(ctx);
|
||||
+ for (i = 0; i < 8; i++)
|
||||
+ {
|
||||
+ buffer[4*i] = ctx->h[i] >> 24;
|
||||
+ buffer[4*i+1] = ctx->h[i] >> 16;
|
||||
+ buffer[4*i+2] = ctx->h[i] >> 8;
|
||||
+ buffer[4*i+3] = ctx->h[i];
|
||||
+ }
|
||||
+}
|
||||
diff --git a/dlls/bcrypt/sha384.c b/dlls/bcrypt/sha384.c
|
||||
new file mode 100644
|
||||
index 0000000..81e7e08
|
||||
--- /dev/null
|
||||
+++ b/dlls/bcrypt/sha384.c
|
||||
@@ -0,0 +1,41 @@
|
||||
+/*
|
||||
+ * Copyright 2016 Michael Müller
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library 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
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include "bcrypt_internal.h"
|
||||
+
|
||||
+void sha384_init(SHA512_CTX *ctx)
|
||||
+{
|
||||
+ ctx->len = 0;
|
||||
+ ctx->h[0] = 0xcbbb9d5dc1059ed8ULL;
|
||||
+ ctx->h[1] = 0x629a292a367cd507ULL;
|
||||
+ ctx->h[2] = 0x9159015a3070dd17ULL;
|
||||
+ ctx->h[3] = 0x152fecd8f70e5939ULL;
|
||||
+ ctx->h[4] = 0x67332667ffc00b31ULL;
|
||||
+ ctx->h[5] = 0x8eb44a8768581511ULL;
|
||||
+ ctx->h[6] = 0xdb0c2e0d64f98fa7ULL;
|
||||
+ ctx->h[7] = 0x47b5481dbefa4fa4ULL;
|
||||
+}
|
||||
+
|
||||
+void sha384_finalize(SHA512_CTX *ctx, UCHAR *buffer)
|
||||
+{
|
||||
+ UCHAR buffer512[64];
|
||||
+
|
||||
+ sha512_finalize(ctx, buffer512);
|
||||
+ memcpy(buffer, buffer512, 48);
|
||||
+}
|
||||
diff --git a/dlls/bcrypt/sha512.c b/dlls/bcrypt/sha512.c
|
||||
new file mode 100644
|
||||
index 0000000..fdd7867
|
||||
--- /dev/null
|
||||
+++ b/dlls/bcrypt/sha512.c
|
||||
@@ -0,0 +1,191 @@
|
||||
+/*
|
||||
+ * Copyright 2016 Michael Müller
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library 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
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+/* Based on public domain implementation from
|
||||
+ https://git.musl-libc.org/cgit/musl/tree/src/crypt/crypt_sha512.c */
|
||||
+
|
||||
+#include "bcrypt_internal.h"
|
||||
+
|
||||
+static ULONG64 ror(ULONG64 n, int k) { return (n >> k) | (n << (64-k)); }
|
||||
+#define Ch(x,y,z) (z ^ (x & (y ^ z)))
|
||||
+#define Maj(x,y,z) ((x & y) | (z & (x | y)))
|
||||
+#define S0(x) (ror(x,28) ^ ror(x,34) ^ ror(x,39))
|
||||
+#define S1(x) (ror(x,14) ^ ror(x,18) ^ ror(x,41))
|
||||
+#define R0(x) (ror(x,1) ^ ror(x,8) ^ (x>>7))
|
||||
+#define R1(x) (ror(x,19) ^ ror(x,61) ^ (x>>6))
|
||||
+
|
||||
+static const ULONG64 K[80] =
|
||||
+{
|
||||
+ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
|
||||
+ 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
|
||||
+ 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
|
||||
+ 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
|
||||
+ 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
|
||||
+ 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
|
||||
+ 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
|
||||
+ 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
|
||||
+ 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
|
||||
+ 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
|
||||
+ 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
|
||||
+ 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
|
||||
+ 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
|
||||
+ 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
|
||||
+ 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
|
||||
+ 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
|
||||
+ 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
|
||||
+ 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
|
||||
+ 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
|
||||
+ 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
|
||||
+};
|
||||
+
|
||||
+static void processblock(SHA512_CTX *ctx, const UCHAR *buffer)
|
||||
+{
|
||||
+ ULONG64 W[80], t1, t2, a, b, c, d, e, f, g, h;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < 16; i++)
|
||||
+ {
|
||||
+ W[i] = (ULONG64)buffer[8*i]<<56;
|
||||
+ W[i] |= (ULONG64)buffer[8*i+1]<<48;
|
||||
+ W[i] |= (ULONG64)buffer[8*i+2]<<40;
|
||||
+ W[i] |= (ULONG64)buffer[8*i+3]<<32;
|
||||
+ W[i] |= (ULONG64)buffer[8*i+4]<<24;
|
||||
+ W[i] |= (ULONG64)buffer[8*i+5]<<16;
|
||||
+ W[i] |= (ULONG64)buffer[8*i+6]<<8;
|
||||
+ W[i] |= buffer[8*i+7];
|
||||
+ }
|
||||
+
|
||||
+ for (; i < 80; i++)
|
||||
+ W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16];
|
||||
+
|
||||
+ a = ctx->h[0];
|
||||
+ b = ctx->h[1];
|
||||
+ c = ctx->h[2];
|
||||
+ d = ctx->h[3];
|
||||
+ e = ctx->h[4];
|
||||
+ f = ctx->h[5];
|
||||
+ g = ctx->h[6];
|
||||
+ h = ctx->h[7];
|
||||
+
|
||||
+ for (i = 0; i < 80; i++)
|
||||
+ {
|
||||
+ t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i];
|
||||
+ t2 = S0(a) + Maj(a,b,c);
|
||||
+ h = g;
|
||||
+ g = f;
|
||||
+ f = e;
|
||||
+ e = d + t1;
|
||||
+ d = c;
|
||||
+ c = b;
|
||||
+ b = a;
|
||||
+ a = t1 + t2;
|
||||
+ }
|
||||
+
|
||||
+ ctx->h[0] += a;
|
||||
+ ctx->h[1] += b;
|
||||
+ ctx->h[2] += c;
|
||||
+ ctx->h[3] += d;
|
||||
+ ctx->h[4] += e;
|
||||
+ ctx->h[5] += f;
|
||||
+ ctx->h[6] += g;
|
||||
+ ctx->h[7] += h;
|
||||
+}
|
||||
+
|
||||
+static void pad(SHA512_CTX *ctx)
|
||||
+{
|
||||
+ ULONG64 r = ctx->len % 128;
|
||||
+
|
||||
+ ctx->buf[r++] = 0x80;
|
||||
+ if (r > 112)
|
||||
+ {
|
||||
+ memset(ctx->buf + r, 0, 128 - r);
|
||||
+ r = 0;
|
||||
+ processblock(ctx, ctx->buf);
|
||||
+ }
|
||||
+
|
||||
+ memset(ctx->buf + r, 0, 120 - r);
|
||||
+ ctx->len *= 8;
|
||||
+ ctx->buf[120] = ctx->len >> 56;
|
||||
+ ctx->buf[121] = ctx->len >> 48;
|
||||
+ ctx->buf[122] = ctx->len >> 40;
|
||||
+ ctx->buf[123] = ctx->len >> 32;
|
||||
+ ctx->buf[124] = ctx->len >> 24;
|
||||
+ ctx->buf[125] = ctx->len >> 16;
|
||||
+ ctx->buf[126] = ctx->len >> 8;
|
||||
+ ctx->buf[127] = ctx->len;
|
||||
+
|
||||
+ processblock(ctx, ctx->buf);
|
||||
+}
|
||||
+
|
||||
+void sha512_init(SHA512_CTX *ctx)
|
||||
+{
|
||||
+ ctx->len = 0;
|
||||
+ ctx->h[0] = 0x6a09e667f3bcc908ULL;
|
||||
+ ctx->h[1] = 0xbb67ae8584caa73bULL;
|
||||
+ ctx->h[2] = 0x3c6ef372fe94f82bULL;
|
||||
+ ctx->h[3] = 0xa54ff53a5f1d36f1ULL;
|
||||
+ ctx->h[4] = 0x510e527fade682d1ULL;
|
||||
+ ctx->h[5] = 0x9b05688c2b3e6c1fULL;
|
||||
+ ctx->h[6] = 0x1f83d9abfb41bd6bULL;
|
||||
+ ctx->h[7] = 0x5be0cd19137e2179ULL;
|
||||
+}
|
||||
+
|
||||
+void sha512_update(SHA512_CTX *ctx, const UCHAR *buffer, ULONG len)
|
||||
+{
|
||||
+ const UCHAR *p = buffer;
|
||||
+ unsigned r = ctx->len % 128;
|
||||
+
|
||||
+ ctx->len += len;
|
||||
+ if (r)
|
||||
+ {
|
||||
+ if (len < 128 - r)
|
||||
+ {
|
||||
+ memcpy(ctx->buf + r, p, len);
|
||||
+ return;
|
||||
+ }
|
||||
+ memcpy(ctx->buf + r, p, 128 - r);
|
||||
+ len -= 128 - r;
|
||||
+ p += 128 - r;
|
||||
+ processblock(ctx, ctx->buf);
|
||||
+ }
|
||||
+
|
||||
+ for (; len >= 128; len -= 128, p += 128)
|
||||
+ processblock(ctx, p);
|
||||
+
|
||||
+ memcpy(ctx->buf, p, len);
|
||||
+}
|
||||
+
|
||||
+void sha512_finalize(SHA512_CTX *ctx, UCHAR *buffer)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ pad(ctx);
|
||||
+
|
||||
+ for (i = 0; i < 8; i++)
|
||||
+ {
|
||||
+ buffer[8*i] = ctx->h[i] >> 56;
|
||||
+ buffer[8*i+1] = ctx->h[i] >> 48;
|
||||
+ buffer[8*i+2] = ctx->h[i] >> 40;
|
||||
+ buffer[8*i+3] = ctx->h[i] >> 32;
|
||||
+ buffer[8*i+4] = ctx->h[i] >> 24;
|
||||
+ buffer[8*i+5] = ctx->h[i] >> 16;
|
||||
+ buffer[8*i+6] = ctx->h[i] >> 8;
|
||||
+ buffer[8*i+7] = ctx->h[i];
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.9.0
|
||||
|
@ -0,0 +1,216 @@
|
||||
From ae04ece5f64a29a67e187d5aa32c6b8d3e399d61 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Tue, 20 Dec 2016 02:39:26 +0100
|
||||
Subject: bcrypt: Use hash fallback implementation as default and remove gnutls
|
||||
/ commoncrypto hash implemetation.
|
||||
|
||||
---
|
||||
dlls/bcrypt/bcrypt_main.c | 171 ----------------------------------------------
|
||||
1 file changed, 171 deletions(-)
|
||||
|
||||
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
|
||||
index 9441cf0..3e2b22d 100644
|
||||
--- a/dlls/bcrypt/bcrypt_main.c
|
||||
+++ b/dlls/bcrypt/bcrypt_main.c
|
||||
@@ -59,9 +59,6 @@ MAKE_FUNCPTR(gnutls_global_deinit);
|
||||
MAKE_FUNCPTR(gnutls_global_init);
|
||||
MAKE_FUNCPTR(gnutls_global_set_log_function);
|
||||
MAKE_FUNCPTR(gnutls_global_set_log_level);
|
||||
-MAKE_FUNCPTR(gnutls_hash);
|
||||
-MAKE_FUNCPTR(gnutls_hash_deinit);
|
||||
-MAKE_FUNCPTR(gnutls_hash_init);
|
||||
MAKE_FUNCPTR(gnutls_perror);
|
||||
#undef MAKE_FUNCPTR
|
||||
|
||||
@@ -95,9 +92,6 @@ static BOOL gnutls_initialize(void)
|
||||
LOAD_FUNCPTR(gnutls_global_init)
|
||||
LOAD_FUNCPTR(gnutls_global_set_log_function)
|
||||
LOAD_FUNCPTR(gnutls_global_set_log_level)
|
||||
- LOAD_FUNCPTR(gnutls_hash);
|
||||
- LOAD_FUNCPTR(gnutls_hash_deinit);
|
||||
- LOAD_FUNCPTR(gnutls_hash_init);
|
||||
LOAD_FUNCPTR(gnutls_perror)
|
||||
#undef LOAD_FUNCPTR
|
||||
|
||||
@@ -299,170 +293,6 @@ NTSTATUS WINAPI BCryptGetFipsAlgorithmMode(BOOLEAN *enabled)
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
-#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
|
||||
-struct hash_impl
|
||||
-{
|
||||
- union
|
||||
- {
|
||||
- CC_MD5_CTX md5_ctx;
|
||||
- CC_SHA1_CTX sha1_ctx;
|
||||
- CC_SHA256_CTX sha256_ctx;
|
||||
- CC_SHA512_CTX sha512_ctx;
|
||||
- } u;
|
||||
-};
|
||||
-
|
||||
-static NTSTATUS hash_init( struct hash_impl *hash, enum alg_id alg_id )
|
||||
-{
|
||||
- switch (alg_id)
|
||||
- {
|
||||
- case ALG_ID_MD5:
|
||||
- CC_MD5_Init( &hash->u.md5_ctx );
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA1:
|
||||
- CC_SHA1_Init( &hash->u.sha1_ctx );
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA256:
|
||||
- CC_SHA256_Init( &hash->u.sha256_ctx );
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA384:
|
||||
- CC_SHA384_Init( &hash->u.sha512_ctx );
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA512:
|
||||
- CC_SHA512_Init( &hash->u.sha512_ctx );
|
||||
- break;
|
||||
-
|
||||
- default:
|
||||
- ERR( "unhandled id %u\n", alg_id );
|
||||
- return STATUS_NOT_IMPLEMENTED;
|
||||
- }
|
||||
- return STATUS_SUCCESS;
|
||||
-}
|
||||
-
|
||||
-static NTSTATUS hash_update( struct hash_impl *hash, enum alg_id alg_id,
|
||||
- UCHAR *input, ULONG size )
|
||||
-{
|
||||
- switch (alg_id)
|
||||
- {
|
||||
- case ALG_ID_MD5:
|
||||
- CC_MD5_Update( &hash->u.md5_ctx, input, size );
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA1:
|
||||
- CC_SHA1_Update( &hash->u.sha1_ctx, input, size );
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA256:
|
||||
- CC_SHA256_Update( &hash->u.sha256_ctx, input, size );
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA384:
|
||||
- CC_SHA384_Update( &hash->u.sha512_ctx, input, size );
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA512:
|
||||
- CC_SHA512_Update( &hash->u.sha512_ctx, input, size );
|
||||
- break;
|
||||
-
|
||||
- default:
|
||||
- ERR( "unhandled id %u\n", alg_id );
|
||||
- return STATUS_NOT_IMPLEMENTED;
|
||||
- }
|
||||
- return STATUS_SUCCESS;
|
||||
-}
|
||||
-
|
||||
-static NTSTATUS hash_finish( struct hash_impl *hash, enum alg_id alg_id,
|
||||
- UCHAR *output, ULONG size )
|
||||
-{
|
||||
- switch (alg_id)
|
||||
- {
|
||||
- case ALG_ID_MD5:
|
||||
- CC_MD5_Final( output, &hash->u.md5_ctx );
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA1:
|
||||
- CC_SHA1_Final( output, &hash->u.sha1_ctx );
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA256:
|
||||
- CC_SHA256_Final( output, &hash->u.sha256_ctx );
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA384:
|
||||
- CC_SHA384_Final( output, &hash->u.sha512_ctx );
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA512:
|
||||
- CC_SHA512_Final( output, &hash->u.sha512_ctx );
|
||||
- break;
|
||||
-
|
||||
- default:
|
||||
- ERR( "unhandled id %u\n", alg_id );
|
||||
- break;
|
||||
- }
|
||||
- return STATUS_SUCCESS;
|
||||
-}
|
||||
-
|
||||
-#elif defined(HAVE_GNUTLS_HASH)
|
||||
-struct hash_impl
|
||||
-{
|
||||
- gnutls_hash_hd_t hash_handle;
|
||||
-};
|
||||
-
|
||||
-static NTSTATUS hash_init( struct hash_impl *hash, enum alg_id alg_id )
|
||||
-{
|
||||
- gnutls_digest_algorithm_t alg;
|
||||
-
|
||||
- if (!libgnutls_handle) return STATUS_INTERNAL_ERROR;
|
||||
-
|
||||
- switch (alg_id)
|
||||
- {
|
||||
- case ALG_ID_MD5:
|
||||
- alg = GNUTLS_DIG_MD5;
|
||||
- break;
|
||||
- case ALG_ID_SHA1:
|
||||
- alg = GNUTLS_DIG_SHA1;
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA256:
|
||||
- alg = GNUTLS_DIG_SHA256;
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA384:
|
||||
- alg = GNUTLS_DIG_SHA384;
|
||||
- break;
|
||||
-
|
||||
- case ALG_ID_SHA512:
|
||||
- alg = GNUTLS_DIG_SHA512;
|
||||
- break;
|
||||
-
|
||||
- default:
|
||||
- ERR( "unhandled id %u\n", alg_id );
|
||||
- return STATUS_NOT_IMPLEMENTED;
|
||||
- }
|
||||
-
|
||||
- if (pgnutls_hash_init( &hash->hash_handle, alg )) return STATUS_INTERNAL_ERROR;
|
||||
- return STATUS_SUCCESS;
|
||||
-}
|
||||
-
|
||||
-static NTSTATUS hash_update( struct hash_impl *hash, enum alg_id alg_id,
|
||||
- UCHAR *input, ULONG size )
|
||||
-{
|
||||
- if (pgnutls_hash( hash->hash_handle, input, size )) return STATUS_INTERNAL_ERROR;
|
||||
- return STATUS_SUCCESS;
|
||||
-}
|
||||
-
|
||||
-static NTSTATUS hash_finish( struct hash_impl *hash, enum alg_id alg_id,
|
||||
- UCHAR *output, ULONG size )
|
||||
-{
|
||||
- pgnutls_hash_deinit( hash->hash_handle, output );
|
||||
- return STATUS_SUCCESS;
|
||||
-}
|
||||
-
|
||||
-#else
|
||||
struct hash_impl
|
||||
{
|
||||
union
|
||||
@@ -572,7 +402,6 @@ static NTSTATUS hash_finish( struct hash_impl *hash, enum alg_id alg_id,
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
-#endif
|
||||
|
||||
struct hash
|
||||
{
|
||||
--
|
||||
2.9.0
|
||||
|
@ -0,0 +1,56 @@
|
||||
From 9331e2a78e8ec0ba29ed1041a9f851ffd39cc249 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Tue, 20 Dec 2016 03:59:19 +0100
|
||||
Subject: bcrypt: Implement BCryptDuplicateHash.
|
||||
|
||||
FIXME: Should we check for NULL pointers?
|
||||
---
|
||||
dlls/bcrypt/bcrypt.spec | 2 +-
|
||||
dlls/bcrypt/bcrypt_main.c | 18 ++++++++++++++++++
|
||||
2 files changed, 19 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/bcrypt/bcrypt.spec b/dlls/bcrypt/bcrypt.spec
|
||||
index 962953e..9ecd21d 100644
|
||||
--- a/dlls/bcrypt/bcrypt.spec
|
||||
+++ b/dlls/bcrypt/bcrypt.spec
|
||||
@@ -11,7 +11,7 @@
|
||||
@ stdcall BCryptDestroyHash(ptr)
|
||||
@ stdcall BCryptDestroyKey(ptr)
|
||||
@ stub BCryptDestroySecret
|
||||
-@ stub BCryptDuplicateHash
|
||||
+@ stdcall BCryptDuplicateHash(ptr ptr ptr long long)
|
||||
@ stub BCryptDuplicateKey
|
||||
@ stdcall BCryptEncrypt(ptr ptr long ptr ptr long ptr long ptr long)
|
||||
@ stdcall BCryptEnumAlgorithms(long ptr ptr long)
|
||||
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
|
||||
index 3e2b22d..944a9ea 100644
|
||||
--- a/dlls/bcrypt/bcrypt_main.c
|
||||
+++ b/dlls/bcrypt/bcrypt_main.c
|
||||
@@ -672,6 +672,24 @@ end:
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
+NTSTATUS WINAPI BCryptDuplicateHash( BCRYPT_HASH_HANDLE handle, BCRYPT_HASH_HANDLE *handle_copy,
|
||||
+ UCHAR *object, ULONG object_count, ULONG flags )
|
||||
+{
|
||||
+ struct hash *hash_orig = handle;
|
||||
+ struct hash *hash_copy;
|
||||
+
|
||||
+ TRACE( "%p, %p, %p, %u, %u\n", handle, handle_copy, object, object_count, flags );
|
||||
+
|
||||
+ if (!hash_orig || hash_orig->hdr.magic != MAGIC_HASH) return STATUS_INVALID_HANDLE;
|
||||
+ if (!(hash_copy = HeapAlloc( GetProcessHeap(), 0, sizeof(*hash_copy) )))
|
||||
+ return STATUS_NO_MEMORY;
|
||||
+
|
||||
+ memcpy( hash_copy, hash_orig, sizeof(*hash_orig) );
|
||||
+
|
||||
+ *handle_copy = hash_copy;
|
||||
+ return STATUS_SUCCESS;
|
||||
+}
|
||||
+
|
||||
NTSTATUS WINAPI BCryptDestroyHash( BCRYPT_HASH_HANDLE handle )
|
||||
{
|
||||
struct hash *hash = handle;
|
||||
--
|
||||
2.9.0
|
||||
|
2
patches/bcrypt-Improvements/definition
Normal file
2
patches/bcrypt-Improvements/definition
Normal file
@ -0,0 +1,2 @@
|
||||
Fixes: [41951] Implement bcrypt.BCryptDuplicateHash
|
||||
Fixes: [40418] Implement BCrypt AES provider
|
@ -95,6 +95,7 @@ patch_enable_all ()
|
||||
enable_avifil32_AVIFile_Proxies="$1"
|
||||
enable_avifil32_IGetFrame_fnSetFormat="$1"
|
||||
enable_avifile_dll16_AVIStreamGetFrame="$1"
|
||||
enable_bcrypt_Improvements="$1"
|
||||
enable_browseui_Progress_Dialog="$1"
|
||||
enable_cabinet_iFolder="$1"
|
||||
enable_combase_RoApi="$1"
|
||||
@ -463,6 +464,9 @@ patch_enable ()
|
||||
avifile.dll16-AVIStreamGetFrame)
|
||||
enable_avifile_dll16_AVIStreamGetFrame="$2"
|
||||
;;
|
||||
bcrypt-Improvements)
|
||||
enable_bcrypt_Improvements="$2"
|
||||
;;
|
||||
browseui-Progress_Dialog)
|
||||
enable_browseui_Progress_Dialog="$2"
|
||||
;;
|
||||
@ -2802,6 +2806,31 @@ if test "$enable_avifile_dll16_AVIStreamGetFrame" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset bcrypt-Improvements
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#41951] Implement bcrypt.BCryptDuplicateHash
|
||||
# | * [#40418] Implement BCrypt AES provider
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/bcrypt/Makefile.in, dlls/bcrypt/bcrypt.spec, dlls/bcrypt/bcrypt_internal.h, dlls/bcrypt/bcrypt_main.c,
|
||||
# | dlls/bcrypt/sha256.c, dlls/bcrypt/sha384.c, dlls/bcrypt/sha512.c, dlls/bcrypt/tests/bcrypt.c, include/bcrypt.h
|
||||
# |
|
||||
if test "$enable_bcrypt_Improvements" -eq 1; then
|
||||
patch_apply bcrypt-Improvements/0001-bcrypt-Add-AES-provider.patch
|
||||
patch_apply bcrypt-Improvements/0002-bcrypt-Directly-implement-hmac-computation.patch
|
||||
patch_apply bcrypt-Improvements/0003-bcrypt-Add-internal-fallback-implementation-for-hash.patch
|
||||
patch_apply bcrypt-Improvements/0004-bcrypt-Use-hash-fallback-implementation-as-default-a.patch
|
||||
patch_apply bcrypt-Improvements/0005-bcrypt-Implement-BCryptDuplicateHash.patch
|
||||
(
|
||||
echo '+ { "Hans Leidekker", "bcrypt: Add AES provider.", 1 },';
|
||||
echo '+ { "Michael Müller", "bcrypt: Directly implement hmac computation.", 1 },';
|
||||
echo '+ { "Michael Müller", "bcrypt: Add internal fallback implementation for hash calculations.", 1 },';
|
||||
echo '+ { "Michael Müller", "bcrypt: Use hash fallback implementation as default and remove gnutls / commoncrypto hash implemetation.", 1 },';
|
||||
echo '+ { "Michael Müller", "bcrypt: Implement BCryptDuplicateHash.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset browseui-Progress_Dialog
|
||||
# |
|
||||
# | Modified files:
|
||||
|
Loading…
Reference in New Issue
Block a user