Module: wine Branch: master Commit: 6415947e09fd4ac9cc7e80f82a0e95cf24126423 URL: http://source.winehq.org/git/wine.git/?a=commit;h=6415947e09fd4ac9cc7e80f82a...
Author: Hans Leidekker hans@codeweavers.com Date: Mon Apr 4 11:07:05 2016 +0200
bcrypt: Add support for BCRYPT_RNG_ALGORITHM.
Signed-off-by: Hans Leidekker hans@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/bcrypt/bcrypt_main.c | 86 +++++++++++++++++++++++++++------------------- dlls/bcrypt/tests/bcrypt.c | 29 ++++++++++++++++ include/bcrypt.h | 1 + 3 files changed, 80 insertions(+), 36 deletions(-)
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index 43d4688..6023c94 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -136,42 +136,6 @@ NTSTATUS WINAPI BCryptEnumAlgorithms(ULONG dwAlgOperations, ULONG *pAlgCount, return STATUS_NOT_IMPLEMENTED; }
-NTSTATUS WINAPI BCryptGenRandom(BCRYPT_ALG_HANDLE algorithm, UCHAR *buffer, ULONG count, ULONG 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; -} - #define MAGIC_ALG (('A' << 24) | ('L' << 16) | ('G' << 8) | '0') #define MAGIC_HASH (('H' << 24) | ('A' << 16) | ('S' << 8) | 'H') struct object @@ -182,6 +146,7 @@ struct object enum alg_id { ALG_ID_MD5, + ALG_ID_RNG, ALG_ID_SHA1, ALG_ID_SHA256, ALG_ID_SHA384, @@ -193,6 +158,7 @@ static const struct { const WCHAR *alg_name; } alg_props[] = { /* ALG_ID_MD5 */ { 16, BCRYPT_MD5_ALGORITHM }, + /* ALG_ID_RNG */ { 0, BCRYPT_RNG_ALGORITHM }, /* ALG_ID_SHA1 */ { 20, BCRYPT_SHA1_ALGORITHM }, /* ALG_ID_SHA256 */ { 32, BCRYPT_SHA256_ALGORITHM }, /* ALG_ID_SHA384 */ { 48, BCRYPT_SHA384_ALGORITHM }, @@ -206,6 +172,47 @@ struct algorithm BOOL hmac; };
+NTSTATUS WINAPI BCryptGenRandom(BCRYPT_ALG_HANDLE handle, UCHAR *buffer, ULONG count, ULONG flags) +{ + const DWORD supported_flags = BCRYPT_USE_SYSTEM_PREFERRED_RNG; + struct algorithm *algorithm = handle; + + TRACE("%p, %p, %u, %08x - semi-stub\n", handle, 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; + } + else if (algorithm->hdr.magic != MAGIC_ALG || algorithm->id != ALG_ID_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 (algorithm || (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; +} + NTSTATUS WINAPI BCryptOpenAlgorithmProvider( BCRYPT_ALG_HANDLE *handle, LPCWSTR id, LPCWSTR implementation, DWORD flags ) { struct algorithm *alg; @@ -224,6 +231,7 @@ NTSTATUS WINAPI BCryptOpenAlgorithmProvider( BCRYPT_ALG_HANDLE *handle, LPCWSTR
if (!strcmpW( id, BCRYPT_SHA1_ALGORITHM )) alg_id = ALG_ID_SHA1; else if (!strcmpW( id, BCRYPT_MD5_ALGORITHM )) alg_id = ALG_ID_MD5; + else if (!strcmpW( id, BCRYPT_RNG_ALGORITHM )) alg_id = ALG_ID_RNG; else if (!strcmpW( id, BCRYPT_SHA256_ALGORITHM )) alg_id = ALG_ID_SHA256; else if (!strcmpW( id, BCRYPT_SHA384_ALGORITHM )) alg_id = ALG_ID_SHA384; else if (!strcmpW( id, BCRYPT_SHA512_ALGORITHM )) alg_id = ALG_ID_SHA512; @@ -628,6 +636,12 @@ static NTSTATUS get_alg_property( enum alg_id id, const WCHAR *prop, UCHAR *buf, } FIXME( "unsupported md5 algorithm property %s\n", debugstr_w(prop) ); return STATUS_NOT_IMPLEMENTED; + + case ALG_ID_RNG: + if (!strcmpW( prop, BCRYPT_OBJECT_LENGTH )) return STATUS_NOT_SUPPORTED; + FIXME( "unsupported rng algorithm property %s\n", debugstr_w(prop) ); + return STATUS_NOT_IMPLEMENTED; + case ALG_ID_SHA1: if (!strcmpW( prop, BCRYPT_OBJECT_LENGTH )) { diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index e2318c4..9bd2cea 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -694,6 +694,34 @@ static void test_BcryptHash(void) ok(ret == STATUS_SUCCESS, "got %08x\n", ret); }
+static void test_rng(void) +{ + BCRYPT_ALG_HANDLE alg; + ULONG size, len; + UCHAR buf[16]; + NTSTATUS ret; + + alg = NULL; + ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(alg != NULL, "alg not set\n"); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0); + ok(ret == STATUS_NOT_SUPPORTED, "got %08x\n", ret); + + test_alg_name(alg, "RNG"); + + memset(buf, 0, 16); + ret = BCryptGenRandom(alg, buf, 8, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(memcmp(buf, buf + 8, 8), "got zeroes\n"); + + ret = BCryptCloseAlgorithmProvider(alg, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); +} + + START_TEST(bcrypt) { HMODULE module; @@ -707,6 +735,7 @@ START_TEST(bcrypt) test_sha384(); test_sha512(); test_md5(); + test_rng();
pBCryptHash = (void *)GetProcAddress( module, "BCryptHash" );
diff --git a/include/bcrypt.h b/include/bcrypt.h index 93f4326..c521bcc 100644 --- a/include/bcrypt.h +++ b/include/bcrypt.h @@ -64,6 +64,7 @@ typedef LONG NTSTATUS; {'M','i','c','r','o','s','o','f','t',' ','P','l','a','t','f','o','r','m',' ','C','r','y','p','t','o',' ','P','r','o','v','i','d','e','r',0}
#define BCRYPT_MD5_ALGORITHM (const WCHAR []){'M','D','5',0} +#define BCRYPT_RNG_ALGORITHM (const WCHAR []){'R','N','G',0} #define BCRYPT_SHA1_ALGORITHM (const WCHAR []){'S','H','A','1',0} #define BCRYPT_SHA256_ALGORITHM (const WCHAR []){'S','H','A','2','5','6',0} #define BCRYPT_SHA384_ALGORITHM (const WCHAR []){'S','H','A','3','8','4',0}