bcrypt: Add support for BCRYPT_RNG_ALGORITHM.
Hans Leidekker
hans at codeweavers.com
Mon Apr 4 04:07:05 CDT 2016
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
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}
--
2.1.4
More information about the wine-patches
mailing list