[5/8] bcrypt: Implement BCryptGenerateSymmetricKey and BCryptDestroyKey.

Hans Leidekker hans at codeweavers.com
Tue Aug 15 07:51:41 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