bcrypt: Added BCryptHash function.

Patrick Armstrong pat at triplefox.com
Fri Mar 18 11:26:11 CDT 2016


This is a new all-in-one function added in Windows 10 and Windows Server
2016.

Tested on OS X 10.11, Windows 10, and Ubuntu Linux 14.04.

Signed-off-by: Patrick Armstrong <pat at oldpatricka.com>
---
 dlls/bcrypt/bcrypt.spec    |  1 +
 dlls/bcrypt/bcrypt_main.c  | 36 +++++++++++++++++++++++++++++
 dlls/bcrypt/tests/bcrypt.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++
 include/bcrypt.h           |  1 +
 4 files changed, 95 insertions(+)

diff --git a/dlls/bcrypt/bcrypt.spec b/dlls/bcrypt/bcrypt.spec
index c52d89f..e299fe0 100644
--- a/dlls/bcrypt/bcrypt.spec
+++ b/dlls/bcrypt/bcrypt.spec
@@ -29,6 +29,7 @@
 @ stub BCryptGenerateSymmetricKey
 @ stdcall BCryptGetFipsAlgorithmMode(ptr)
 @ stdcall BCryptGetProperty(ptr wstr ptr long ptr long)
+@ stdcall BCryptHash(ptr ptr long ptr long ptr long)
 @ stdcall BCryptHashData(ptr ptr long long)
 @ stub BCryptImportKey
 @ stub BCryptImportKeyPair
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
index ed1cab0..b9d81e3 100644
--- a/dlls/bcrypt/bcrypt_main.c
+++ b/dlls/bcrypt/bcrypt_main.c
@@ -808,6 +808,42 @@ NTSTATUS WINAPI BCryptFinishHash( BCRYPT_HASH_HANDLE handle, UCHAR *output, ULON
     }
 }
 
+NTSTATUS WINAPI BCryptHash( BCRYPT_ALG_HANDLE algorithm, UCHAR *secret, ULONG secretlen,
+                            UCHAR *input, ULONG inputlen, UCHAR *output, ULONG outputlen )
+{
+    NTSTATUS status;
+    BCRYPT_ALG_HANDLE handle;
+
+    TRACE( "%p, %p, %u, %p, %u, %p, %u\n", algorithm, secret, secretlen,
+           input, inputlen, output, outputlen );
+
+    status = BCryptCreateHash( algorithm, &handle, NULL, 0, secret, secretlen, 0);
+    if (status != STATUS_SUCCESS)
+    {
+        goto cleanup_bcrypt_hash;
+    }
+
+    status = BCryptHashData( handle, input, inputlen, 0 );
+    if (status != STATUS_SUCCESS)
+    {
+        goto cleanup_bcrypt_hash;
+    }
+
+    status = BCryptFinishHash( handle, output, outputlen, 0 );
+    if (status != STATUS_SUCCESS)
+    {
+        goto cleanup_bcrypt_hash;
+    }
+
+    return BCryptDestroyHash( handle );
+
+cleanup_bcrypt_hash:
+
+    BCryptDestroyHash( handle );
+
+    return status;
+}
+
 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
 {
     switch (reason)
diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c
index 447861e..e2318c4 100644
--- a/dlls/bcrypt/tests/bcrypt.c
+++ b/dlls/bcrypt/tests/bcrypt.c
@@ -26,6 +26,9 @@
 
 #include "wine/test.h"
 
+static NTSTATUS (WINAPI *pBCryptHash)( BCRYPT_ALG_HANDLE algorithm, UCHAR *secret, ULONG secretlen,
+                                     UCHAR *input, ULONG inputlen, UCHAR *output, ULONG outputlen );
+
 static void test_BCryptGenRandom(void)
 {
     NTSTATUS ret;
@@ -648,8 +651,55 @@ static void test_md5(void)
     ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
 }
 
+static void test_BcryptHash(void)
+{
+    static const char expected[] =
+        "e2a3e68d23ce348b8f68b3079de3d4c9";
+    static const char expected_hmac[] =
+        "7bda029b93fa8d817fcc9e13d6bdf092";
+    BCRYPT_ALG_HANDLE alg;
+    UCHAR md5[16], md5_hmac[16];
+    char str[65];
+    NTSTATUS ret;
+
+    alg = NULL;
+    ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_MD5_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
+    ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
+    ok(alg != NULL, "alg not set\n");
+
+    test_hash_length(alg, 16);
+    test_alg_name(alg, "MD5");
+
+    memset(md5, 0, sizeof(md5));
+    ret = pBCryptHash(alg, NULL, 0, (UCHAR *)"test", sizeof("test"), md5, sizeof(md5));
+    ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
+    format_hash( md5, sizeof(md5), str );
+    ok(!strcmp(str, expected), "got %s\n", str);
+
+    ret = BCryptCloseAlgorithmProvider(alg, 0);
+    ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
+
+    alg = NULL;
+    memset(md5_hmac, 0, sizeof(md5_hmac));
+    ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_MD5_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
+    ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
+    ok(alg != NULL, "alg not set\n");
+
+    ret = pBCryptHash(alg, (UCHAR *)"key", sizeof("key"), (UCHAR *)"test", sizeof("test"), md5_hmac, sizeof(md5_hmac));
+    ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
+    format_hash( md5_hmac, sizeof(md5_hmac), str );
+    ok(!strcmp(str, expected_hmac), "got %s\n", str);
+
+    ret = BCryptCloseAlgorithmProvider(alg, 0);
+    ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
+}
+
 START_TEST(bcrypt)
 {
+    HMODULE module;
+
+    module = GetModuleHandleA( "bcrypt.dll" );
+
     test_BCryptGenRandom();
     test_BCryptGetFipsAlgorithmMode();
     test_sha1();
@@ -657,4 +707,11 @@ START_TEST(bcrypt)
     test_sha384();
     test_sha512();
     test_md5();
+
+    pBCryptHash = (void *)GetProcAddress( module, "BCryptHash" );
+
+    if (pBCryptHash)
+        test_BcryptHash();
+    else
+        win_skip("BCryptHash is not available\n");
 }
diff --git a/include/bcrypt.h b/include/bcrypt.h
index ddfd66e..95ee4c7 100644
--- a/include/bcrypt.h
+++ b/include/bcrypt.h
@@ -87,6 +87,7 @@ typedef PVOID BCRYPT_HASH_HANDLE;
 NTSTATUS WINAPI BCryptCloseAlgorithmProvider(BCRYPT_ALG_HANDLE, ULONG);
 NTSTATUS WINAPI BCryptCreateHash(BCRYPT_ALG_HANDLE, BCRYPT_HASH_HANDLE *, PUCHAR, ULONG, PUCHAR, ULONG, ULONG);
 NTSTATUS WINAPI BCryptDestroyHash(BCRYPT_HASH_HANDLE);
+NTSTATUS WINAPI BCryptHash(BCRYPT_ALG_HANDLE, PUCHAR, ULONG, PUCHAR, ULONG, PUCHAR, ULONG);
 NTSTATUS WINAPI BCryptEnumAlgorithms(ULONG, ULONG *, BCRYPT_ALGORITHM_IDENTIFIER **, ULONG);
 NTSTATUS WINAPI BCryptFinishHash(BCRYPT_HASH_HANDLE, PUCHAR, ULONG, ULONG);
 NTSTATUS WINAPI BCryptGenRandom(BCRYPT_ALG_HANDLE, PUCHAR, ULONG, ULONG);
-- 
2.5.4 (Apple Git-61)




More information about the wine-patches mailing list