From 6415947e09fd4ac9cc7e80f82a0e95cf24126423 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Mon, 4 Apr 2016 11:07:05 +0200 Subject: [PATCH] bcrypt: Add support for BCRYPT_RNG_ALGORITHM. Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- dlls/bcrypt/bcrypt_main.c | 88 ++++++++++++++++++++++---------------- dlls/bcrypt/tests/bcrypt.c | 29 +++++++++++++ include/bcrypt.h | 1 + 3 files changed, 81 insertions(+), 37 deletions(-) diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index 43d4688a1e9..6023c942e49 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -136,10 +136,48 @@ NTSTATUS WINAPI BCryptEnumAlgorithms(ULONG dwAlgOperations, ULONG *pAlgCount, return STATUS_NOT_IMPLEMENTED; } -NTSTATUS WINAPI BCryptGenRandom(BCRYPT_ALG_HANDLE algorithm, UCHAR *buffer, ULONG count, ULONG flags) +#define MAGIC_ALG (('A' << 24) | ('L' << 16) | ('G' << 8) | '0') +#define MAGIC_HASH (('H' << 24) | ('A' << 16) | ('S' << 8) | 'H') +struct object +{ + ULONG magic; +}; + +enum alg_id +{ + ALG_ID_MD5, + ALG_ID_RNG, + ALG_ID_SHA1, + ALG_ID_SHA256, + ALG_ID_SHA384, + ALG_ID_SHA512 +}; + +static const struct { + ULONG hash_length; + 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 }, + /* ALG_ID_SHA512 */ { 64, BCRYPT_SHA512_ALGORITHM } +}; + +struct algorithm +{ + struct object hdr; + enum alg_id id; + BOOL hmac; +}; + +NTSTATUS WINAPI BCryptGenRandom(BCRYPT_ALG_HANDLE handle, 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); + struct algorithm *algorithm = handle; + + TRACE("%p, %p, %u, %08x - semi-stub\n", handle, buffer, count, flags); if (!algorithm) { @@ -149,6 +187,9 @@ NTSTATUS WINAPI BCryptGenRandom(BCRYPT_ALG_HANDLE algorithm, UCHAR *buffer, ULON 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; @@ -162,7 +203,7 @@ NTSTATUS WINAPI BCryptGenRandom(BCRYPT_ALG_HANDLE algorithm, UCHAR *buffer, ULON if (!count) return STATUS_SUCCESS; - if (flags & BCRYPT_USE_SYSTEM_PREFERRED_RNG) + if (algorithm || (flags & BCRYPT_USE_SYSTEM_PREFERRED_RNG)) { if (RtlGenRandom(buffer, count)) return STATUS_SUCCESS; @@ -172,40 +213,6 @@ NTSTATUS WINAPI BCryptGenRandom(BCRYPT_ALG_HANDLE algorithm, UCHAR *buffer, ULON 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 -{ - ULONG magic; -}; - -enum alg_id -{ - ALG_ID_MD5, - ALG_ID_SHA1, - ALG_ID_SHA256, - ALG_ID_SHA384, - ALG_ID_SHA512 -}; - -static const struct { - ULONG hash_length; - const WCHAR *alg_name; -} alg_props[] = { - /* ALG_ID_MD5 */ { 16, BCRYPT_MD5_ALGORITHM }, - /* ALG_ID_SHA1 */ { 20, BCRYPT_SHA1_ALGORITHM }, - /* ALG_ID_SHA256 */ { 32, BCRYPT_SHA256_ALGORITHM }, - /* ALG_ID_SHA384 */ { 48, BCRYPT_SHA384_ALGORITHM }, - /* ALG_ID_SHA512 */ { 64, BCRYPT_SHA512_ALGORITHM } -}; - -struct algorithm -{ - struct object hdr; - enum alg_id id; - BOOL hmac; -}; - 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 e2318c49e76..9bd2cea9e3b 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 93f432634f1..c521bcc8ce4 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}