Signed-off-by: Hans Leidekker hans@codeweavers.com --- 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 ea082b29e3..e406117e97 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 ) @@ -315,14 +326,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", hprov, algid, 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", hprov, 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 */