[PATCH 5/7] bcrypt: Beginnings of the AES provider

Bruno Jesus 00cpxxx at gmail.com
Fri Dec 2 16:28:35 CST 2016


From: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Bruno Jesus <00cpxxx at gmail.com>
---
 dlls/bcrypt/bcrypt_main.c  | 40 +++++++++++++++++++++++++++++++++++++++-
 dlls/bcrypt/tests/bcrypt.c | 27 +++++++--------------------
 2 files changed, 46 insertions(+), 21 deletions(-)

diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
index 5657264..21df85d 100644
--- a/dlls/bcrypt/bcrypt_main.c
+++ b/dlls/bcrypt/bcrypt_main.c
@@ -149,8 +149,10 @@ struct object
     ULONG magic;
 };
 
+/* Sorted by name, next struct must be completed too */
 enum alg_id
 {
+    ALG_ID_AES,
     ALG_ID_MD5,
     ALG_ID_RNG,
     ALG_ID_SHA1,
@@ -163,6 +165,7 @@ static const struct {
     ULONG hash_length;
     const WCHAR *alg_name;
 } alg_props[] = {
+    /* ALG_ID_AES    */ { 16, BCRYPT_AES_ALGORITHM },
     /* ALG_ID_MD5    */ { 16, BCRYPT_MD5_ALGORITHM },
     /* ALG_ID_RNG    */ {  0, BCRYPT_RNG_ALGORITHM },
     /* ALG_ID_SHA1   */ { 20, BCRYPT_SHA1_ALGORITHM },
@@ -237,9 +240,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;
@@ -566,6 +570,9 @@ static NTSTATUS key_init( struct key *key, enum alg_id id, UCHAR *secret, ULONG
 
     switch (id)
     {
+    case ALG_ID_AES:
+        break;
+
     default:
         FIXME( "algorithm %u not supported\n", id );
         return STATUS_NOT_SUPPORTED;
@@ -650,12 +657,15 @@ static NTSTATUS key_destroy( struct key *key )
 }
 #endif
 
+#define OBJECT_LENGTH_AES       618 /* FIXME: This is the 32 bits value */
 #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 ))
@@ -692,6 +702,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 ))
         {
diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c
index 3e41335..723b58e 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;
@@ -868,6 +862,7 @@ static void test_BCryptGenerateSymmetricKey(void)
                             sizeof(BCRYPT_CHAIN_MODE_CBC), 0);
     todo_wine ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
 
+todo_wine {
     size = 0xdeadbeef;
     ret = pBCryptEncrypt(key, NULL, 0, NULL, NULL, 0, NULL, 0, &size, 0);
     ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
@@ -907,7 +902,7 @@ static void test_BCryptGenerateSymmetricKey(void)
     ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
     ok(size == 16, "got %u\n", size);
     ok(!memcmp(plaintext, data, sizeof(data)), "wrong data\n");
-
+}
     ret = pBCryptDestroyKey(key);
     ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
     HeapFree(GetProcessHeap(), 0, buf);
@@ -936,11 +931,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;
@@ -953,6 +943,7 @@ static void test_BCryptEncrypt(void)
     ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
 
     /* input size is a multiple of block size */
+todo_wine {
     size = 0;
     memcpy(ivbuf, iv, sizeof(iv));
     ret = pBCryptEncrypt(key, data, 16, NULL, ivbuf, 16, NULL, 0, &size, 0);
@@ -1000,7 +991,7 @@ static void test_BCryptEncrypt(void)
     ret = pBCryptEncrypt(key, data, 17, NULL, ivbuf, 16, ciphertext, 31, &size, BCRYPT_BLOCK_PADDING);
     ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
     ok(size == 32, "got %u\n", size);
-
+}
     ret = pBCryptDestroyKey(key);
     ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
     HeapFree(GetProcessHeap(), 0, buf);
@@ -1027,11 +1018,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;
@@ -1043,6 +1029,7 @@ static void test_BCryptDecrypt(void)
     ret = pBCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0);
     ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
 
+todo_wine {
     /* input size is a multiple of block size */
     size = 0;
     memcpy(ivbuf, iv, sizeof(iv));
@@ -1078,7 +1065,7 @@ static void test_BCryptDecrypt(void)
     ret = pBCryptDecrypt(key, ciphertext, 17, NULL, ivbuf, 16, NULL, 0, &size, BCRYPT_BLOCK_PADDING);
     ok(ret == STATUS_INVALID_BUFFER_SIZE, "got %08x\n", ret);
     ok(size == 17 || broken(size == 0 /* Win < 7 */), "got %u\n", size);
-
+}
     ret = pBCryptDestroyKey(key);
     ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
     HeapFree(GetProcessHeap(), 0, buf);
-- 
2.9.3




More information about the wine-patches mailing list