[v2 PATCH 3/5] bcrypt: Implement BCryptSetProperty for algorithms.

Alistair Leslie-Hughes leslie_alistair at hotmail.com
Mon Mar 19 06:16:11 CDT 2018


From: Michael Müller <michael at fds-team.de>

Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
---
 dlls/bcrypt/bcrypt_main.c  | 64 ++++++++++++++++++++++++++++++++++++++++++++--
 dlls/bcrypt/tests/bcrypt.c | 17 +++++++++---
 2 files changed, 76 insertions(+), 5 deletions(-)

diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
index 8af43c8725..2f56604873 100644
--- a/dlls/bcrypt/bcrypt_main.c
+++ b/dlls/bcrypt/bcrypt_main.c
@@ -192,6 +192,12 @@ enum alg_id
     ALG_ID_SHA512
 };
 
+enum mode_id
+{
+    MODE_ID_CBC,
+    MODE_ID_GCM
+};
+
 #define MAX_HASH_OUTPUT_BYTES 64
 #define MAX_HASH_BLOCK_BITS 1024
 
@@ -216,6 +222,7 @@ struct algorithm
 {
     struct object hdr;
     enum alg_id   id;
+    enum mode_id  mode;
     BOOL hmac;
 };
 
@@ -298,6 +305,7 @@ NTSTATUS WINAPI BCryptOpenAlgorithmProvider( BCRYPT_ALG_HANDLE *handle, LPCWSTR
     if (!(alg = heap_alloc( sizeof(*alg) ))) return STATUS_NO_MEMORY;
     alg->hdr.magic = MAGIC_ALG;
     alg->id        = alg_id;
+    alg->mode      = MODE_ID_CBC;
     alg->hmac      = flags & BCRYPT_ALG_HANDLE_HMAC_FLAG;
 
     *handle = alg;
@@ -567,6 +575,38 @@ static NTSTATUS get_alg_property( const struct algorithm *alg, const WCHAR *prop
     return STATUS_NOT_IMPLEMENTED;
 }
 
+static NTSTATUS set_alg_property( struct algorithm *alg, const WCHAR *prop, UCHAR *value, ULONG size, ULONG flags )
+{
+    switch (alg->id)
+    {
+    case ALG_ID_AES:
+        if (!strcmpW( prop, BCRYPT_CHAINING_MODE ))
+        {
+            if (!strncmpW( (WCHAR *)value, BCRYPT_CHAIN_MODE_CBC, size ))
+            {
+                alg->mode = MODE_ID_CBC;
+                return STATUS_SUCCESS;
+            }
+            else if (!strncmpW( (WCHAR *)value, BCRYPT_CHAIN_MODE_GCM, size ))
+            {
+                alg->mode = MODE_ID_GCM;
+                return STATUS_SUCCESS;
+            }
+            else
+            {
+                FIXME( "unsupported mode %s\n", debugstr_wn( (WCHAR *)value, size ) );
+                return STATUS_NOT_IMPLEMENTED;
+            }
+        }
+        FIXME( "unsupported aes algorithm property %s\n", debugstr_w(prop) );
+        return STATUS_NOT_IMPLEMENTED;
+
+    default:
+        FIXME( "unsupported algorithm %u\n", alg->id );
+        return STATUS_NOT_IMPLEMENTED;
+    }
+}
+
 static NTSTATUS get_hash_property( const struct hash *hash, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size )
 {
     NTSTATUS status;
@@ -606,8 +646,28 @@ 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;
+    struct object *object = handle;
+
+    TRACE( "%p, %s, %p, %u, %08x\n", handle, debugstr_w(prop), value, size, flags );
+
+    if (!object) return STATUS_INVALID_HANDLE;
+
+    switch (object->magic)
+    {
+    case MAGIC_ALG:
+    {
+        struct algorithm *alg = (struct algorithm *)object;
+        return set_alg_property( alg, prop, value, size, flags );
+    }
+    case MAGIC_KEY:
+    {
+        FIXME( "keys not implemented yet\n" );
+        return STATUS_NOT_IMPLEMENTED;
+    }
+    default:
+        WARN( "unknown magic %08x\n", object->magic );
+        return STATUS_INVALID_HANDLE;
+    }
 }
 
 NTSTATUS WINAPI BCryptCreateHash( BCRYPT_ALG_HANDLE algorithm, BCRYPT_HASH_HANDLE *handle, UCHAR *object, ULONG objectlen,
diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c
index 6cefe13226..1a362f3fbc 100644
--- a/dlls/bcrypt/tests/bcrypt.c
+++ b/dlls/bcrypt/tests/bcrypt.c
@@ -475,6 +475,17 @@ static void test_aes(void)
     ok(key_lengths.dwMaxLength == 256, "Expected 256, got %d\n", key_lengths.dwMaxLength);
     ok(key_lengths.dwIncrement == 64, "Expected 64, got %d\n", key_lengths.dwIncrement);
 
+    memcpy(mode, BCRYPT_CHAIN_MODE_GCM, sizeof(BCRYPT_CHAIN_MODE_GCM));
+    ret = pBCryptSetProperty(alg, BCRYPT_CHAINING_MODE, mode, sizeof(mode), 0);
+    ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
+
+    size = 0;
+    memset(mode, 0, sizeof(mode));
+    ret = pBCryptGetProperty(alg, BCRYPT_CHAINING_MODE, mode, sizeof(mode), &size, 0);
+    ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
+    todo_wine ok(!lstrcmpW((const WCHAR *)mode, BCRYPT_CHAIN_MODE_GCM), "got %s\n", wine_dbgstr_w((const WCHAR *)mode));
+    ok(size == 64, "got %u\n", size);
+
     test_alg_name(alg, "AES");
 
     ret = pBCryptCloseAlgorithmProvider(alg, 0);
@@ -512,7 +523,7 @@ static void test_BCryptGenerateSymmetricKey(void)
 
     ret = pBCryptSetProperty(aes, BCRYPT_CHAINING_MODE, (UCHAR *)BCRYPT_CHAIN_MODE_CBC,
                             sizeof(BCRYPT_CHAIN_MODE_CBC), 0);
-    todo_wine ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
+    ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
 
     size = 0xdeadbeef;
     ret = pBCryptEncrypt(key, NULL, 0, NULL, NULL, 0, NULL, 0, &size, 0);
@@ -701,7 +712,7 @@ static void test_BCryptEncrypt(void)
     todo_wine ok(ret == STATUS_NOT_SUPPORTED, "got %08x\n", ret);
 
     ret = BCryptSetProperty(aes, BCRYPT_CHAINING_MODE, (UCHAR*)BCRYPT_CHAIN_MODE_GCM, sizeof(BCRYPT_CHAIN_MODE_GCM), 0);
-    todo_wine ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
+    ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
 
     size = 0;
     ret = BCryptGetProperty(aes, BCRYPT_AUTH_TAG_LENGTH, NULL, 0, &size, 0);
@@ -939,7 +950,7 @@ static void test_BCryptDecrypt(void)
      ******************/
 
     ret = BCryptSetProperty(aes, BCRYPT_CHAINING_MODE, (UCHAR*)BCRYPT_CHAIN_MODE_GCM, sizeof(BCRYPT_CHAIN_MODE_GCM), 0);
-    todo_wine ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
+    ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
 
     buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
     ret = pBCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0);
-- 
2.16.2



More information about the wine-devel mailing list