Hans Leidekker : dssenh: Implement CPCreateHash and CPDestroyHash.

Alexandre Julliard julliard at winehq.org
Fri Oct 9 16:00:44 CDT 2020


Module: wine
Branch: master
Commit: e7a79ce4266751a44234da1f657015eae17106b6
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=e7a79ce4266751a44234da1f657015eae17106b6

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Fri Oct  9 12:45:57 2020 +0200

dssenh: Implement CPCreateHash and CPDestroyHash.

Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/dssenh/main.c         | 90 ++++++++++++++++++++++++++++++++++++++++++++--
 dlls/dssenh/tests/dssenh.c | 18 +++++-----
 2 files changed, 97 insertions(+), 11 deletions(-)

diff --git a/dlls/dssenh/main.c b/dlls/dssenh/main.c
index 32c31a48a8..66f3456d78 100644
--- a/dlls/dssenh/main.c
+++ b/dlls/dssenh/main.c
@@ -54,6 +54,17 @@ struct container
     char        name[MAX_PATH];
 };
 
+#define MAGIC_HASH (('H' << 24) | ('A' << 16) | ('S' << 8) | 'H')
+struct hash
+{
+    DWORD              magic;
+    BCRYPT_ALG_HANDLE  alg_handle;
+    BCRYPT_HASH_HANDLE handle;
+    DWORD              len;
+    UCHAR              value[64];
+    BOOL               finished;
+};
+
 static const char dss_path_fmt[] = "Software\\Wine\\Crypto\\DSS\\%s";
 
 static BOOL create_container_regkey( struct container *container, REGSAM sam, HKEY *hkey )
@@ -320,14 +331,89 @@ BOOL WINAPI CPExportKey( HCRYPTPROV hprov, HCRYPTKEY hkey, HCRYPTKEY hexpkey, DW
     return FALSE;
 }
 
+static struct hash *create_hash( ALG_ID algid )
+{
+    struct hash *ret;
+    const WCHAR *alg;
+    DWORD len;
+
+    switch (algid)
+    {
+    case CALG_MD5:
+        alg = BCRYPT_MD5_ALGORITHM;
+        len = 16;
+        break;
+
+    case CALG_SHA1:
+        alg = BCRYPT_SHA1_ALGORITHM;
+        len = 20;
+        break;
+
+    default:
+        FIXME( "unhandled algorithm %u\n", algid );
+        return 0;
+    }
+
+    if (!(ret = heap_alloc_zero( sizeof(*ret) ))) return 0;
+
+    ret->magic = MAGIC_HASH;
+    ret->len   = len;
+    if (BCryptOpenAlgorithmProvider( &ret->alg_handle, alg, MS_PRIMITIVE_PROVIDER, 0 ))
+    {
+        heap_free( ret );
+        return 0;
+    }
+    if (BCryptCreateHash( ret->alg_handle, &ret->handle, NULL, 0, NULL, 0, 0 ))
+    {
+        BCryptCloseAlgorithmProvider( ret->alg_handle, 0 );
+        heap_free( ret );
+        return 0;
+    }
+    return ret;
+}
+
 BOOL WINAPI CPCreateHash( HCRYPTPROV hprov, ALG_ID algid, HCRYPTKEY hkey, DWORD flags, HCRYPTHASH *ret_hash )
 {
-    return FALSE;
+    struct hash *hash;
+
+    TRACE( "%p, %08x, %p, %08x, %p\n", (void *)hprov, algid, (void *)hkey, flags, ret_hash );
+
+    switch (algid)
+    {
+    case CALG_MD5:
+    case CALG_SHA1:
+        break;
+
+    default:
+        FIXME( "algorithm %u not supported\n", algid );
+        SetLastError( NTE_BAD_ALGID );
+        return FALSE;
+    }
+
+    if (!(hash = create_hash( algid ))) return FALSE;
+
+    *ret_hash = (HCRYPTHASH)hash;
+    return TRUE;
 }
 
 BOOL WINAPI CPDestroyHash( HCRYPTPROV hprov, HCRYPTHASH hhash )
 {
-    return FALSE;
+    struct hash *hash = (struct hash *)hhash;
+
+    TRACE( "%p, %p\n", (void *)hprov, (void *)hhash);
+
+    if (hash->magic != MAGIC_HASH)
+    {
+        SetLastError( NTE_BAD_HASH );
+        return FALSE;
+    }
+
+    BCryptDestroyHash( hash->handle );
+    BCryptCloseAlgorithmProvider( hash->alg_handle, 0 );
+
+    hash->magic = 0;
+    heap_free( hash );
+    return TRUE;
 }
 
 BOOL WINAPI CPHashData( HCRYPTPROV hprov, HCRYPTHASH hhash, const BYTE *data, DWORD len, DWORD flags )
diff --git a/dlls/dssenh/tests/dssenh.c b/dlls/dssenh/tests/dssenh.c
index d549b985d6..f06cdd1433 100644
--- a/dlls/dssenh/tests/dssenh.c
+++ b/dlls/dssenh/tests/dssenh.c
@@ -446,14 +446,14 @@ static void test_hash(const struct hash_test *tests, int testLen)
 
         /* test algid hash */
         result = CryptCreateHash(hProv, tests[i].algid, 0, 0, &hHash);
+        ok(result, "Expected creation of a hash.\n");
+
+        result = CryptHashData(hHash, data, dataLen, 0);
         if (!result)
         {
             skip("skipping hash tests\n");
             return;
         }
-        ok(result, "Expected creation of a hash.\n");
-
-        result = CryptHashData(hHash, data, dataLen, 0);
         ok(result, "Expected data to be added to hash.\n");
 
         dataLen = sizeof(DWORD);
@@ -605,14 +605,14 @@ static void test_data_encryption(const struct encrypt_test *tests, int testLen)
 
         SetLastError(0xdeadbeef);
         result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
+        ok(result, "Expected creation of a MD5 hash for key derivation.\n");
+
+        result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
         if (!result)
         {
             skip("skipping encryption tests\n");
             return;
         }
-        ok(result, "Expected creation of a MD5 hash for key derivation.\n");
-
-        result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
         ok(result, "Expected data to be added to hash for key derivation.\n");
 
         /* Derive key */
@@ -695,14 +695,14 @@ static void test_cipher_modes(const struct ciphermode_test *tests, int testLen)
 
     SetLastError(0xdeadbeef);
     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
+    ok(result, "Expected creation of a MD5 hash for key derivation.\n");
+
+    result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
     if (!result)
     {
         skip("skipping ciper modes tests\n");
         return;
     }
-    ok(result, "Expected creation of a MD5 hash for key derivation.\n");
-
-    result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
     ok(result, "Expected data to be added to hash for key derivation.\n");
 
     /* Derive a CALG_RC2 key, but could be any other encryption cipher */




More information about the wine-cvs mailing list