bcrypt: Add support for BCRYPT_RNG_ALGORITHM.

Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
oldstable
Hans Leidekker 2016-04-04 11:07:05 +02:00 committed by Alexandre Julliard
parent c52e4b6551
commit 6415947e09
3 changed files with 81 additions and 37 deletions

View File

@ -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 ))
{

View File

@ -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" );

View File

@ -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}