bcrypt: Add semi-stub implementation of BCryptGenRandom (try 2)
Bruno Jesus
00cpxxx at gmail.com
Sun Feb 9 19:36:36 CST 2014
try 2:
Better error handling, more tests, comments.
If advapi is not a good approach please point me another as it was the
only way I found to generate random numbers, thanks =)
-------------- next part --------------
diff --git a/dlls/bcrypt/Makefile.in b/dlls/bcrypt/Makefile.in
index f9aacec..6f39a49 100644
--- a/dlls/bcrypt/Makefile.in
+++ b/dlls/bcrypt/Makefile.in
@@ -1,4 +1,5 @@
MODULE = bcrypt.dll
+IMPORTLIB = advapi32
C_SRCS = \
bcrypt_main.c
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
index 02d0a7d..22da0dd 100644
--- a/dlls/bcrypt/bcrypt_main.c
+++ b/dlls/bcrypt/bcrypt_main.c
@@ -25,6 +25,7 @@
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
+#include "ntsecapi.h"
#include "bcrypt.h"
#include "wine/debug.h"
@@ -57,7 +58,36 @@ NTSTATUS WINAPI BCryptEnumAlgorithms(ULONG dwAlgOperations, ULONG *pAlgCount,
NTSTATUS WINAPI BCryptGenRandom(BCRYPT_ALG_HANDLE algorithm, UCHAR *buffer, ULONG count, ULONG flags)
{
- FIXME("%p, %p, %u, %08x - stub\n", algorithm, buffer, count, flags);
+ const DWORD supported_flags = BCRYPT_USE_SYSTEM_PREFERRED_RNG;
+ TRACE("%p, %p, %u, %08x - semi-stub\n", algorithm, buffer, count, flags);
+ if (!algorithm)
+ {
+ /* It's valid to call without an algorithm if BCRYPT_USE_SYSTEM_PREFERRED_RNG
+ * is set. In this case the preferred system RNG is used.
+ */
+ if (!(flags & BCRYPT_USE_SYSTEM_PREFERRED_RNG))
+ return STATUS_INVALID_HANDLE;
+ }
+ if (!buffer)
+ return STATUS_INVALID_PARAMETER;
+
+ if (flags & ~supported_flags)
+ FIXME("unsupported flags %08x\n", flags & ~supported_flags);
+
+ if (algorithm)
+ FIXME("ignoring selected algorithm\n");
+
+ /* When zero bytes are requested the function returns success too. */
+ if (!count)
+ return STATUS_SUCCESS;
+
+ if (flags & BCRYPT_USE_SYSTEM_PREFERRED_RNG)
+ {
+ if (RtlGenRandom(buffer, count))
+ return STATUS_SUCCESS;
+ }
+
+ FIXME("called with unsupported parameters, returning error\n");
return STATUS_NOT_IMPLEMENTED;
}
diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c
index 1d18634..41208ed 100644
--- a/dlls/bcrypt/tests/bcrypt.c
+++ b/dlls/bcrypt/tests/bcrypt.c
@@ -46,6 +46,7 @@ static void test_BCryptGenRandom(void)
{
NTSTATUS ret;
UCHAR buffer[256];
+ DWORD *rnd = (DWORD*) buffer;
if (!pBCryptGenRandom)
{
@@ -53,7 +54,6 @@ static void test_BCryptGenRandom(void)
return;
}
- todo_wine {
ret = pBCryptGenRandom(NULL, NULL, 0, 0);
ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got 0x%x\n", ret);
ret = pBCryptGenRandom(NULL, buffer, 0, 0);
@@ -62,9 +62,23 @@ static void test_BCryptGenRandom(void)
ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got 0x%x\n", ret);
ret = pBCryptGenRandom(NULL, buffer, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret);
+ ret = pBCryptGenRandom(NULL, buffer, sizeof(buffer),
+ BCRYPT_USE_SYSTEM_PREFERRED_RNG|BCRYPT_RNG_USE_ENTROPY_IN_BUFFER);
+ ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret);
ret = pBCryptGenRandom(NULL, NULL, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got 0x%x\n", ret);
- }
+
+ /* Zero sized buffer should work too */
+ ret = pBCryptGenRandom(NULL, buffer, 0, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
+ ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret);
+
+ /* Test random number generation - It's impossible for a sane RNG to return 8 zeros */
+ rnd[0] = 0;
+ rnd[1] = 0;
+ ret = pBCryptGenRandom(NULL, buffer, sizeof(DWORD) * 2, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
+ ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret);
+ ok(rnd[0] || rnd[1], "Expected a random number, got 0\n");
+ trace("BCryptGenRandom : %08X%08X\n", rnd[0], rnd[1]);
}
START_TEST(bcrypt)
More information about the wine-patches
mailing list