Module: wine Branch: master Commit: 9c5a200de51b6773930f6f97a22d5ec23aae3434 URL: http://source.winehq.org/git/wine.git/?a=commit;h=9c5a200de51b6773930f6f97a2...
Author: Hans Leidekker hans@codeweavers.com Date: Wed Aug 16 11:23:46 2017 +0200
bcrypt: Implement BCryptGenerateSymmetricKey and BCryptDestroyKey.
Signed-off-by: Hans Leidekker hans@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/bcrypt/bcrypt.spec | 2 +- dlls/bcrypt/bcrypt_main.c | 105 ++++++++++++++++++++++++++++++++++++++++++++- dlls/bcrypt/tests/bcrypt.c | 30 ++++++------- 3 files changed, 119 insertions(+), 18 deletions(-)
diff --git a/dlls/bcrypt/bcrypt.spec b/dlls/bcrypt/bcrypt.spec index 4a53df6..9ecd21d 100644 --- a/dlls/bcrypt/bcrypt.spec +++ b/dlls/bcrypt/bcrypt.spec @@ -9,7 +9,7 @@ @ stub BCryptDeleteContext @ stub BCryptDeriveKey @ stdcall BCryptDestroyHash(ptr) -@ stub BCryptDestroyKey +@ stdcall BCryptDestroyKey(ptr) @ stub BCryptDestroySecret @ stdcall BCryptDuplicateHash(ptr ptr ptr long long) @ stub BCryptDuplicateKey diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index 9f9c8c1..b05130b 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -128,6 +128,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; @@ -676,12 +677,112 @@ NTSTATUS WINAPI BCryptHash( BCRYPT_ALG_HANDLE algorithm, UCHAR *secret, ULONG se return BCryptDestroyHash( handle ); }
+#if defined(HAVE_GNUTLS_HASH) && !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H) +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, const UCHAR *secret, ULONG secret_len ) +{ + UCHAR *buffer; + + 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; + if (!(buffer = HeapAlloc( GetProcessHeap(), 0, secret_len ))) return STATUS_NO_MEMORY; + memcpy( buffer, secret, secret_len ); + + key->alg_id = id; + key->handle = 0; /* initialized on first use */ + key->secret = buffer; + key->secret_len = secret_len; + + return STATUS_SUCCESS; +} + +static NTSTATUS key_destroy( struct key *key ) +{ + 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_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 ) { - FIXME( "%p, %p, %p, %u, %p, %u, %08x\n", algorithm, handle, object, object_len, secret, secret_len, flags ); - return STATUS_NOT_IMPLEMENTED; + struct algorithm *alg = algorithm; + struct key *key; + NTSTATUS status; + + TRACE( "%p, %p, %p, %u, %p, %u, %08x\n", algorithm, 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, diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index a4d98b2..d472b5c 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -765,11 +765,6 @@ static void test_BCryptGenerateSymmetricKey(void) key = NULL; buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); ret = pBCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0); - if (ret == STATUS_NOT_IMPLEMENTED) /* remove whole IF when Wine is fixed */ - { - todo_wine ok(0, "BCryptGenerateSymmetricKey not implemented\n"); - return; - } ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(key != NULL, "key not set\n");
@@ -779,6 +774,11 @@ static void test_BCryptGenerateSymmetricKey(void)
size = 0xdeadbeef; ret = pBCryptEncrypt(key, NULL, 0, NULL, NULL, 0, NULL, 0, &size, 0); + if (ret == STATUS_NOT_IMPLEMENTED) /* remove whole IF when Wine is fixed */ + { + todo_wine ok(0, "BCryptEncrypt not implemented\n"); + return; + } ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(!size, "got %u\n", size);
@@ -854,17 +854,17 @@ static void test_BCryptEncrypt(void)
buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); ret = pBCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0); - if (ret == STATUS_NOT_IMPLEMENTED) /* remove whole IF when Wine is fixed */ - { - todo_wine ok(0, "BCryptGenerateSymmetricKey not implemented\n"); - return; - } ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
/* input size is a multiple of block size */ size = 0; memcpy(ivbuf, iv, sizeof(iv)); ret = pBCryptEncrypt(key, data, 16, NULL, ivbuf, 16, NULL, 0, &size, 0); + if (ret == STATUS_NOT_IMPLEMENTED) /* remove whole IF when Wine is fixed */ + { + todo_wine ok(0, "BCryptEncrypt not implemented\n"); + return; + } ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(size == 16, "got %u\n", size);
@@ -945,17 +945,17 @@ static void test_BCryptDecrypt(void)
buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); ret = pBCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0); - if (ret == STATUS_NOT_IMPLEMENTED) /* remove whole IF when Wine is fixed */ - { - todo_wine ok(0, "BCryptGenerateSymmetricKey not implemented\n"); - return; - } ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
/* input size is a multiple of block size */ size = 0; memcpy(ivbuf, iv, sizeof(iv)); ret = pBCryptDecrypt(key, ciphertext, 32, NULL, ivbuf, 16, NULL, 0, &size, 0); + if (ret == STATUS_NOT_IMPLEMENTED) /* remove whole IF when Wine is fixed */ + { + todo_wine ok(0, "BCryptDecrypt not implemented\n"); + return; + } ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(size == 32, "got %u\n", size);