[ v2 5/8] bcrypt: Implement BCryptGenerateSymmetricKey and BCryptDestroyKey.
Hans Leidekker
hans at codeweavers.com
Wed Aug 16 04:23:46 CDT 2017
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
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 4a53df63fc..9ecd21d767 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 9f9c8c1283..b05130b00c 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 a4d98b28d3..d472b5cfd6 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);
--
2.11.0
More information about the wine-patches
mailing list