Module: wine Branch: master Commit: a7578c7ae7ef1aa7bc2e8d0846a0bfc60bc664a2 URL: http://source.winehq.org/git/wine.git/?a=commit;h=a7578c7ae7ef1aa7bc2e8d0846...
Author: Bruno Jesus 00cpxxx@gmail.com Date: Mon Feb 10 20:12:15 2014 -0200
bcrypt: Add semi-stub implementation of BCryptGenRandom.
---
dlls/bcrypt/Makefile.in | 1 + dlls/bcrypt/bcrypt_main.c | 32 +++++++++++++++++++++++++++++++- dlls/bcrypt/tests/bcrypt.c | 15 +++++++++++++-- 3 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/dlls/bcrypt/Makefile.in b/dlls/bcrypt/Makefile.in index f9aacec..87e1429 100644 --- a/dlls/bcrypt/Makefile.in +++ b/dlls/bcrypt/Makefile.in @@ -1,4 +1,5 @@ MODULE = bcrypt.dll +IMPORTS = 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..288e745 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -53,7 +53,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 +61,21 @@ 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 */ + memset(buffer, 0, 16); + ret = pBCryptGenRandom(NULL, buffer, 8, BCRYPT_USE_SYSTEM_PREFERRED_RNG); + ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret); + ok(memcmp(buffer, buffer + 8, 8), "Expected a random number, got 0\n"); }
START_TEST(bcrypt)