mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-01 15:43:37 +00:00
bcrypt: Implement support for HMAC.
Signed-off-by: Patrick Armstrong <pat@oldpatricka.com> Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
48d183dbc2
commit
630f5e97b1
|
@ -23,6 +23,7 @@
|
|||
#include <stdarg.h>
|
||||
#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
|
||||
#include <CommonCrypto/CommonDigest.h>
|
||||
#include <CommonCrypto/CommonHMAC.h>
|
||||
#elif defined(SONAME_LIBGNUTLS)
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/crypto.h>
|
||||
|
@ -55,6 +56,9 @@ MAKE_FUNCPTR(gnutls_global_set_log_level);
|
|||
MAKE_FUNCPTR(gnutls_hash);
|
||||
MAKE_FUNCPTR(gnutls_hash_deinit);
|
||||
MAKE_FUNCPTR(gnutls_hash_init);
|
||||
MAKE_FUNCPTR(gnutls_hmac);
|
||||
MAKE_FUNCPTR(gnutls_hmac_deinit);
|
||||
MAKE_FUNCPTR(gnutls_hmac_init);
|
||||
MAKE_FUNCPTR(gnutls_perror);
|
||||
#undef MAKE_FUNCPTR
|
||||
|
||||
|
@ -87,6 +91,9 @@ static BOOL gnutls_initialize(void)
|
|||
LOAD_FUNCPTR(gnutls_hash);
|
||||
LOAD_FUNCPTR(gnutls_hash_deinit);
|
||||
LOAD_FUNCPTR(gnutls_hash_init);
|
||||
LOAD_FUNCPTR(gnutls_hmac);
|
||||
LOAD_FUNCPTR(gnutls_hmac_deinit);
|
||||
LOAD_FUNCPTR(gnutls_hmac_init);
|
||||
LOAD_FUNCPTR(gnutls_perror)
|
||||
#undef LOAD_FUNCPTR
|
||||
|
||||
|
@ -196,6 +203,7 @@ struct algorithm
|
|||
{
|
||||
struct object hdr;
|
||||
enum alg_id id;
|
||||
BOOL hmac;
|
||||
};
|
||||
|
||||
NTSTATUS WINAPI BCryptOpenAlgorithmProvider( BCRYPT_ALG_HANDLE *handle, LPCWSTR id, LPCWSTR implementation, DWORD flags )
|
||||
|
@ -203,12 +211,14 @@ NTSTATUS WINAPI BCryptOpenAlgorithmProvider( BCRYPT_ALG_HANDLE *handle, LPCWSTR
|
|||
struct algorithm *alg;
|
||||
enum alg_id alg_id;
|
||||
|
||||
const DWORD supported_flags = BCRYPT_ALG_HANDLE_HMAC_FLAG;
|
||||
|
||||
TRACE( "%p, %s, %s, %08x\n", handle, wine_dbgstr_w(id), wine_dbgstr_w(implementation), flags );
|
||||
|
||||
if (!handle || !id) return STATUS_INVALID_PARAMETER;
|
||||
if (flags)
|
||||
if (flags & ~supported_flags)
|
||||
{
|
||||
FIXME( "unimplemented flags %08x\n", flags );
|
||||
FIXME( "unsupported flags %08x\n", flags & ~supported_flags);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
@ -231,6 +241,7 @@ NTSTATUS WINAPI BCryptOpenAlgorithmProvider( BCRYPT_ALG_HANDLE *handle, LPCWSTR
|
|||
if (!(alg = HeapAlloc( GetProcessHeap(), 0, sizeof(*alg) ))) return STATUS_NO_MEMORY;
|
||||
alg->hdr.magic = MAGIC_ALG;
|
||||
alg->id = alg_id;
|
||||
alg->hmac = flags & BCRYPT_ALG_HANDLE_HMAC_FLAG;
|
||||
|
||||
*handle = alg;
|
||||
return STATUS_SUCCESS;
|
||||
|
@ -263,12 +274,14 @@ struct hash
|
|||
{
|
||||
struct object hdr;
|
||||
enum alg_id alg_id;
|
||||
BOOL hmac;
|
||||
union
|
||||
{
|
||||
CC_MD5_CTX md5_ctx;
|
||||
CC_SHA1_CTX sha1_ctx;
|
||||
CC_SHA256_CTX sha256_ctx;
|
||||
CC_SHA512_CTX sha512_ctx;
|
||||
CCHmacContext hmac_ctx;
|
||||
} u;
|
||||
};
|
||||
|
||||
|
@ -279,6 +292,7 @@ static NTSTATUS hash_init( struct hash *hash )
|
|||
case ALG_ID_MD5:
|
||||
CC_MD5_Init( &hash->u.md5_ctx );
|
||||
break;
|
||||
|
||||
case ALG_ID_SHA1:
|
||||
CC_SHA1_Init( &hash->u.sha1_ctx );
|
||||
break;
|
||||
|
@ -302,6 +316,41 @@ static NTSTATUS hash_init( struct hash *hash )
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS hmac_init( struct hash *hash, UCHAR *key, ULONG key_size )
|
||||
{
|
||||
CCHmacAlgorithm cc_algorithm;
|
||||
switch (hash->alg_id)
|
||||
{
|
||||
case ALG_ID_MD5:
|
||||
cc_algorithm = kCCHmacAlgMD5;
|
||||
break;
|
||||
|
||||
case ALG_ID_SHA1:
|
||||
cc_algorithm = kCCHmacAlgSHA1;
|
||||
break;
|
||||
|
||||
case ALG_ID_SHA256:
|
||||
cc_algorithm = kCCHmacAlgSHA256;
|
||||
break;
|
||||
|
||||
case ALG_ID_SHA384:
|
||||
cc_algorithm = kCCHmacAlgSHA384;
|
||||
break;
|
||||
|
||||
case ALG_ID_SHA512:
|
||||
cc_algorithm = kCCHmacAlgSHA512;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERR( "unhandled id %u\n", hash->alg_id );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
CCHmacInit( &hash->u.hmac_ctx, cc_algorithm, key, key_size );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS hash_update( struct hash *hash, UCHAR *input, ULONG size )
|
||||
{
|
||||
switch (hash->alg_id)
|
||||
|
@ -333,6 +382,12 @@ static NTSTATUS hash_update( struct hash *hash, UCHAR *input, ULONG size )
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS hmac_update( struct hash *hash, UCHAR *input, ULONG size )
|
||||
{
|
||||
CCHmacUpdate( &hash->u.hmac_ctx, input, size );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS hash_finish( struct hash *hash, UCHAR *output, ULONG size )
|
||||
{
|
||||
switch (hash->alg_id)
|
||||
|
@ -363,12 +418,24 @@ static NTSTATUS hash_finish( struct hash *hash, UCHAR *output, ULONG size )
|
|||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS hmac_finish( struct hash *hash, UCHAR *output, ULONG size )
|
||||
{
|
||||
CCHmacFinal( &hash->u.hmac_ctx, output );
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
#elif defined(HAVE_GNUTLS_HASH)
|
||||
struct hash
|
||||
{
|
||||
struct object hdr;
|
||||
enum alg_id alg_id;
|
||||
gnutls_hash_hd_t handle;
|
||||
BOOL hmac;
|
||||
union
|
||||
{
|
||||
gnutls_hash_hd_t hash_handle;
|
||||
gnutls_hmac_hd_t hmac_handle;
|
||||
} u;
|
||||
};
|
||||
|
||||
static NTSTATUS hash_init( struct hash *hash )
|
||||
|
@ -403,25 +470,74 @@ static NTSTATUS hash_init( struct hash *hash )
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (pgnutls_hash_init( &hash->handle, alg )) return STATUS_INTERNAL_ERROR;
|
||||
if (pgnutls_hash_init( &hash->u.hash_handle, alg )) return STATUS_INTERNAL_ERROR;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS hmac_init( struct hash *hash, UCHAR *key, ULONG key_size )
|
||||
{
|
||||
gnutls_mac_algorithm_t alg;
|
||||
|
||||
if (!libgnutls_handle) return STATUS_INTERNAL_ERROR;
|
||||
|
||||
switch (hash->alg_id)
|
||||
{
|
||||
case ALG_ID_MD5:
|
||||
alg = GNUTLS_MAC_MD5;
|
||||
break;
|
||||
case ALG_ID_SHA1:
|
||||
alg = GNUTLS_MAC_SHA1;
|
||||
break;
|
||||
|
||||
case ALG_ID_SHA256:
|
||||
alg = GNUTLS_MAC_SHA256;
|
||||
break;
|
||||
|
||||
case ALG_ID_SHA384:
|
||||
alg = GNUTLS_MAC_SHA384;
|
||||
break;
|
||||
|
||||
case ALG_ID_SHA512:
|
||||
alg = GNUTLS_MAC_SHA512;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERR( "unhandled id %u\n", hash->alg_id );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (pgnutls_hmac_init( &hash->u.hmac_handle, alg, key, key_size )) return STATUS_INTERNAL_ERROR;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS hash_update( struct hash *hash, UCHAR *input, ULONG size )
|
||||
{
|
||||
if (pgnutls_hash( hash->handle, input, size )) return STATUS_INTERNAL_ERROR;
|
||||
if (pgnutls_hash( hash->u.hash_handle, input, size )) return STATUS_INTERNAL_ERROR;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS hmac_update( struct hash *hash, UCHAR *input, ULONG size )
|
||||
{
|
||||
if (pgnutls_hmac( hash->u.hmac_handle, input, size )) return STATUS_INTERNAL_ERROR;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS hash_finish( struct hash *hash, UCHAR *output, ULONG size )
|
||||
{
|
||||
pgnutls_hash_deinit( hash->handle, output );
|
||||
pgnutls_hash_deinit( hash->u.hash_handle, output );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS hmac_finish( struct hash *hash, UCHAR *output, ULONG size )
|
||||
{
|
||||
pgnutls_hmac_deinit( hash->u.hmac_handle, output );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
#else
|
||||
struct hash
|
||||
{
|
||||
struct object hdr;
|
||||
BOOL hmac;
|
||||
enum alg_id alg_id;
|
||||
};
|
||||
|
||||
|
@ -431,17 +547,35 @@ static NTSTATUS hash_init( struct hash *hash )
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static NTSTATUS hmac_init( struct hash *hash, UCHAR *key, ULONG key_size )
|
||||
{
|
||||
ERR( "support for hashes not available at build time\n" );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static NTSTATUS hash_update( struct hash *hash, UCHAR *input, ULONG size )
|
||||
{
|
||||
ERR( "support for hashes not available at build time\n" );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static NTSTATUS hmac_update( struct hash *hash, UCHAR *input, ULONG size )
|
||||
{
|
||||
ERR( "support for hashes not available at build time\n" );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static NTSTATUS hash_finish( struct hash *hash, UCHAR *output, ULONG size )
|
||||
{
|
||||
ERR( "support for hashes not available at build time\n" );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static NTSTATUS hmac_finish( struct hash *hash, UCHAR *output, ULONG size )
|
||||
{
|
||||
ERR( "support for hashes not available at build time\n" );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define OBJECT_LENGTH_MD5 274
|
||||
|
@ -604,7 +738,18 @@ NTSTATUS WINAPI BCryptCreateHash( BCRYPT_ALG_HANDLE algorithm, BCRYPT_HASH_HANDL
|
|||
if (!(hash = HeapAlloc( GetProcessHeap(), 0, sizeof(*hash) ))) return STATUS_NO_MEMORY;
|
||||
hash->hdr.magic = MAGIC_HASH;
|
||||
hash->alg_id = alg->id;
|
||||
if ((status = hash_init( hash )) != STATUS_SUCCESS)
|
||||
hash->hmac = alg->hmac;
|
||||
|
||||
if (hash->hmac)
|
||||
{
|
||||
status = hmac_init( hash, secret, secretlen );
|
||||
}
|
||||
else
|
||||
{
|
||||
status = hash_init( hash );
|
||||
}
|
||||
|
||||
if (status != STATUS_SUCCESS)
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, hash );
|
||||
return status;
|
||||
|
@ -634,7 +779,14 @@ NTSTATUS WINAPI BCryptHashData( BCRYPT_HASH_HANDLE handle, UCHAR *input, ULONG s
|
|||
if (!hash || hash->hdr.magic != MAGIC_HASH) return STATUS_INVALID_HANDLE;
|
||||
if (!input) return STATUS_SUCCESS;
|
||||
|
||||
return hash_update( hash, input, size );
|
||||
if (hash->hmac)
|
||||
{
|
||||
return hmac_update( hash, input, size );
|
||||
}
|
||||
else
|
||||
{
|
||||
return hash_update( hash, input, size );
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI BCryptFinishHash( BCRYPT_HASH_HANDLE handle, UCHAR *output, ULONG size, ULONG flags )
|
||||
|
@ -646,7 +798,14 @@ NTSTATUS WINAPI BCryptFinishHash( BCRYPT_HASH_HANDLE handle, UCHAR *output, ULON
|
|||
if (!hash || hash->hdr.magic != MAGIC_HASH) return STATUS_INVALID_HANDLE;
|
||||
if (!output) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
return hash_finish( hash, output, size );
|
||||
if (hash->hmac)
|
||||
{
|
||||
return hmac_finish( hash, output, size );
|
||||
}
|
||||
else
|
||||
{
|
||||
return hash_finish( hash, output, size );
|
||||
}
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
|
||||
|
|
|
@ -115,9 +115,10 @@ static void _test_alg_name(unsigned line, void *handle, const char *exname)
|
|||
static void test_sha1(void)
|
||||
{
|
||||
static const char expected[] = "961fa64958818f767707072755d7018dcd278e94";
|
||||
static const char expected_hmac[] = "2472cf65d0e090618d769d3e46f0d9446cf212da";
|
||||
BCRYPT_ALG_HANDLE alg;
|
||||
BCRYPT_HASH_HANDLE hash;
|
||||
UCHAR buf[512], sha1[20];
|
||||
UCHAR buf[512], buf_hmac[1024], sha1[20], sha1_hmac[20];
|
||||
ULONG size, len;
|
||||
char str[41];
|
||||
NTSTATUS ret;
|
||||
|
@ -185,15 +186,46 @@ static void test_sha1(void)
|
|||
|
||||
ret = BCryptCloseAlgorithmProvider(alg, 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
|
||||
alg = NULL;
|
||||
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
ok(alg != NULL, "alg not set\n");
|
||||
|
||||
hash = NULL;
|
||||
len = sizeof(buf_hmac);
|
||||
ret = BCryptCreateHash(alg, &hash, buf_hmac, len, (UCHAR *)"key", sizeof("key"), 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
ok(hash != NULL, "hash not set\n");
|
||||
|
||||
ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
|
||||
test_hash_length(hash, 20);
|
||||
test_alg_name(hash, "SHA1");
|
||||
|
||||
memset(sha1_hmac, 0, sizeof(sha1_hmac));
|
||||
ret = BCryptFinishHash(hash, sha1_hmac, sizeof(sha1_hmac), 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
format_hash( sha1_hmac, sizeof(sha1_hmac), str );
|
||||
ok(!strcmp(str, expected_hmac), "got %s\n", str);
|
||||
|
||||
ret = BCryptDestroyHash(hash);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
|
||||
ret = BCryptCloseAlgorithmProvider(alg, 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
}
|
||||
|
||||
static void test_sha256(void)
|
||||
{
|
||||
static const char expected[] =
|
||||
"ceb73749c899693706ede1e30c9929b3fd5dd926163831c2fb8bd41e6efb1126";
|
||||
static const char expected_hmac[] =
|
||||
"34c1aa473a4468a91d06e7cdbc75bc4f93b830ccfc2a47ffd74e8e6ed29e4c72";
|
||||
BCRYPT_ALG_HANDLE alg;
|
||||
BCRYPT_HASH_HANDLE hash;
|
||||
UCHAR buf[512], sha256[32];
|
||||
UCHAR buf[512], buf_hmac[1024], sha256[32], sha256_hmac[32];
|
||||
ULONG size, len;
|
||||
char str[65];
|
||||
NTSTATUS ret;
|
||||
|
@ -261,15 +293,46 @@ static void test_sha256(void)
|
|||
|
||||
ret = BCryptCloseAlgorithmProvider(alg, 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
|
||||
alg = NULL;
|
||||
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA256_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
ok(alg != NULL, "alg not set\n");
|
||||
|
||||
hash = NULL;
|
||||
len = sizeof(buf_hmac);
|
||||
ret = BCryptCreateHash(alg, &hash, buf_hmac, len, (UCHAR *)"key", sizeof("key"), 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
ok(hash != NULL, "hash not set\n");
|
||||
|
||||
ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
|
||||
test_hash_length(hash, 32);
|
||||
test_alg_name(hash, "SHA256");
|
||||
|
||||
memset(sha256_hmac, 0, sizeof(sha256_hmac));
|
||||
ret = BCryptFinishHash(hash, sha256_hmac, sizeof(sha256_hmac), 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
format_hash( sha256_hmac, sizeof(sha256_hmac), str );
|
||||
ok(!strcmp(str, expected_hmac), "got %s\n", str);
|
||||
|
||||
ret = BCryptDestroyHash(hash);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
|
||||
ret = BCryptCloseAlgorithmProvider(alg, 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
}
|
||||
|
||||
static void test_sha384(void)
|
||||
{
|
||||
static const char expected[] =
|
||||
"62b21e90c9022b101671ba1f808f8631a8149f0f12904055839a35c1ca78ae5363eed1e743a692d70e0504b0cfd12ef9";
|
||||
static const char expected_hmac[] =
|
||||
"4b3e6d6ff2da121790ab7e7b9247583e3a7eed2db5bd4dabc680303b1608f37dfdc836d96a704c03283bc05b4f6c5eb8";
|
||||
BCRYPT_ALG_HANDLE alg;
|
||||
BCRYPT_HASH_HANDLE hash;
|
||||
UCHAR buf[512], sha384[48];
|
||||
UCHAR buf[512], buf_hmac[1024], sha384[48], sha384_hmac[48];
|
||||
ULONG size, len;
|
||||
char str[97];
|
||||
NTSTATUS ret;
|
||||
|
@ -337,6 +400,35 @@ static void test_sha384(void)
|
|||
|
||||
ret = BCryptCloseAlgorithmProvider(alg, 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
|
||||
alg = NULL;
|
||||
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA384_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
ok(alg != NULL, "alg not set\n");
|
||||
|
||||
hash = NULL;
|
||||
len = sizeof(buf_hmac);
|
||||
ret = BCryptCreateHash(alg, &hash, buf_hmac, len, (UCHAR *)"key", sizeof("key"), 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
ok(hash != NULL, "hash not set\n");
|
||||
|
||||
ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
|
||||
test_hash_length(hash, 48);
|
||||
test_alg_name(hash, "SHA384");
|
||||
|
||||
memset(sha384_hmac, 0, sizeof(sha384_hmac));
|
||||
ret = BCryptFinishHash(hash, sha384_hmac, sizeof(sha384_hmac), 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
format_hash( sha384_hmac, sizeof(sha384_hmac), str );
|
||||
ok(!strcmp(str, expected_hmac), "got %s\n", str);
|
||||
|
||||
ret = BCryptDestroyHash(hash);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
|
||||
ret = BCryptCloseAlgorithmProvider(alg, 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
}
|
||||
|
||||
static void test_sha512(void)
|
||||
|
@ -344,9 +436,12 @@ static void test_sha512(void)
|
|||
static const char expected[] =
|
||||
"d55ced17163bf5386f2cd9ff21d6fd7fe576a915065c24744d09cfae4ec84ee1e"
|
||||
"f6ef11bfbc5acce3639bab725b50a1fe2c204f8c820d6d7db0df0ecbc49c5ca";
|
||||
static const char expected_hmac[] =
|
||||
"415fb6b10018ca03b38a1b1399c42ac0be5e8aceddb9a73103f5e543bf2d888f2"
|
||||
"eecf91373941f9315dd730a77937fa92444450fbece86f409d9cb5ec48c6513";
|
||||
BCRYPT_ALG_HANDLE alg;
|
||||
BCRYPT_HASH_HANDLE hash;
|
||||
UCHAR buf[512], sha512[64];
|
||||
UCHAR buf[512], buf_hmac[1024], sha512[64], sha512_hmac[64];
|
||||
ULONG size, len;
|
||||
char str[129];
|
||||
NTSTATUS ret;
|
||||
|
@ -414,15 +509,47 @@ static void test_sha512(void)
|
|||
|
||||
ret = BCryptCloseAlgorithmProvider(alg, 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
|
||||
alg = NULL;
|
||||
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA512_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
ok(alg != NULL, "alg not set\n");
|
||||
|
||||
hash = NULL;
|
||||
len = sizeof(buf_hmac);
|
||||
ret = BCryptCreateHash(alg, &hash, buf_hmac, len, (UCHAR *)"key", sizeof("key"), 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
ok(hash != NULL, "hash not set\n");
|
||||
|
||||
ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
|
||||
test_hash_length(hash, 64);
|
||||
test_alg_name(hash, "SHA512");
|
||||
|
||||
memset(sha512_hmac, 0, sizeof(sha512_hmac));
|
||||
ret = BCryptFinishHash(hash, sha512_hmac, sizeof(sha512_hmac), 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
format_hash( sha512_hmac, sizeof(sha512_hmac), str );
|
||||
ok(!strcmp(str, expected_hmac), "got %s\n", str);
|
||||
|
||||
ret = BCryptDestroyHash(hash);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
|
||||
ret = BCryptCloseAlgorithmProvider(alg, 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
|
||||
}
|
||||
|
||||
static void test_md5(void)
|
||||
{
|
||||
static const char expected[] =
|
||||
"e2a3e68d23ce348b8f68b3079de3d4c9";
|
||||
static const char expected_hmac[] =
|
||||
"7bda029b93fa8d817fcc9e13d6bdf092";
|
||||
BCRYPT_ALG_HANDLE alg;
|
||||
BCRYPT_HASH_HANDLE hash;
|
||||
UCHAR buf[512], md5[16];
|
||||
UCHAR buf[512], buf_hmac[1024], md5[16], md5_hmac[16];
|
||||
ULONG size, len;
|
||||
char str[65];
|
||||
NTSTATUS ret;
|
||||
|
@ -490,6 +617,35 @@ static void test_md5(void)
|
|||
|
||||
ret = BCryptCloseAlgorithmProvider(alg, 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
|
||||
alg = NULL;
|
||||
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_MD5_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
ok(alg != NULL, "alg not set\n");
|
||||
|
||||
hash = NULL;
|
||||
len = sizeof(buf_hmac);
|
||||
ret = BCryptCreateHash(alg, &hash, buf_hmac, len, (UCHAR *)"key", sizeof("key"), 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
ok(hash != NULL, "hash not set\n");
|
||||
|
||||
ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
|
||||
test_hash_length(hash, 16);
|
||||
test_alg_name(hash, "MD5");
|
||||
|
||||
memset(md5_hmac, 0, sizeof(md5_hmac));
|
||||
ret = BCryptFinishHash(hash, md5_hmac, sizeof(md5_hmac), 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
format_hash( md5_hmac, sizeof(md5_hmac), str );
|
||||
ok(!strcmp(str, expected_hmac), "got %s\n", str);
|
||||
|
||||
ret = BCryptDestroyHash(hash);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
|
||||
ret = BCryptCloseAlgorithmProvider(alg, 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
}
|
||||
|
||||
START_TEST(bcrypt)
|
||||
|
|
|
@ -82,6 +82,7 @@ typedef PVOID BCRYPT_HASH_HANDLE;
|
|||
|
||||
#define BCRYPT_RNG_USE_ENTROPY_IN_BUFFER 0x00000001
|
||||
#define BCRYPT_USE_SYSTEM_PREFERRED_RNG 0x00000002
|
||||
#define BCRYPT_ALG_HANDLE_HMAC_FLAG 0x00000008
|
||||
|
||||
NTSTATUS WINAPI BCryptCloseAlgorithmProvider(BCRYPT_ALG_HANDLE, ULONG);
|
||||
NTSTATUS WINAPI BCryptCreateHash(BCRYPT_ALG_HANDLE, BCRYPT_HASH_HANDLE *, PUCHAR, ULONG, PUCHAR, ULONG, ULONG);
|
||||
|
|
Loading…
Reference in a new issue