From 7831d346b72e1f0b8e65c597a52bf1fc4befb2c5 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Thu, 17 Nov 2016 22:13:28 +0000 Subject: [PATCH] [BCRYPT] Sync with Wine Staging 1.9.23. The mbedtls code paths are brought to you by Peter Hater. CORE-12409 svn path=/trunk/; revision=73261 --- reactos/dll/win32/bcrypt/bcrypt.spec | 1 + reactos/dll/win32/bcrypt/bcrypt_main.c | 445 +++++++++++++++++++++---- reactos/media/doc/README.WINE | 2 +- 3 files changed, 381 insertions(+), 67 deletions(-) diff --git a/reactos/dll/win32/bcrypt/bcrypt.spec b/reactos/dll/win32/bcrypt/bcrypt.spec index c52d89ffbcd..e299fe0cce8 100644 --- a/reactos/dll/win32/bcrypt/bcrypt.spec +++ b/reactos/dll/win32/bcrypt/bcrypt.spec @@ -29,6 +29,7 @@ @ stub BCryptGenerateSymmetricKey @ stdcall BCryptGetFipsAlgorithmMode(ptr) @ stdcall BCryptGetProperty(ptr wstr ptr long ptr long) +@ stdcall BCryptHash(ptr ptr long ptr long ptr long) @ stdcall BCryptHashData(ptr ptr long long) @ stub BCryptImportKey @ stub BCryptImportKeyPair diff --git a/reactos/dll/win32/bcrypt/bcrypt_main.c b/reactos/dll/win32/bcrypt/bcrypt_main.c index 5212af96391..14523136440 100644 --- a/reactos/dll/win32/bcrypt/bcrypt_main.c +++ b/reactos/dll/win32/bcrypt/bcrypt_main.c @@ -32,6 +32,8 @@ #include #ifdef SONAME_LIBMBEDTLS +#include +#include #include #include #include @@ -53,6 +55,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 @@ -85,6 +90,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 @@ -120,6 +128,17 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag); void *libmbedtls_handle; #define MAKE_FUNCPTR(f) static typeof(f) * p##f +MAKE_FUNCPTR(mbedtls_md_init); +MAKE_FUNCPTR(mbedtls_md_setup); +MAKE_FUNCPTR(mbedtls_md_update); +MAKE_FUNCPTR(mbedtls_md_hmac_starts); +MAKE_FUNCPTR(mbedtls_md_hmac_finish); +MAKE_FUNCPTR(mbedtls_md_free); +MAKE_FUNCPTR(mbedtls_md5_init); +MAKE_FUNCPTR(mbedtls_md5_starts); +MAKE_FUNCPTR(mbedtls_md5_update); +MAKE_FUNCPTR(mbedtls_md5_finish); +MAKE_FUNCPTR(mbedtls_md5_free); MAKE_FUNCPTR(mbedtls_sha1_init); MAKE_FUNCPTR(mbedtls_sha1_starts); MAKE_FUNCPTR(mbedtls_sha1_update); @@ -137,6 +156,17 @@ MAKE_FUNCPTR(mbedtls_sha512_finish); MAKE_FUNCPTR(mbedtls_sha512_free); #undef MAKE_FUNCPTR +#define mbedtls_md_init pmbedtls_md_init +#define mbedtls_md_setup pmbedtls_md_setup +#define mbedtls_md_update pmbedtls_md_update +#define mbedtls_md_hmac_starts pmbedtls_md_hmac_starts +#define mbedtls_md_hmac_finish pmbedtls_md_hmac_finish +#define mbedtls_md_free pmbedtls_md_free +#define mbedtls_md5_init pmbedtls_md5_init +#define mbedtls_md5_starts pmbedtls_md5_starts +#define mbedtls_md5_update pmbedtls_md5_update +#define mbedtls_md5_finish pmbedtls_md5_finish +#define mbedtls_md5_free pmbedtls_md5_free #define mbedtls_sha1_init pmbedtls_sha1_init #define mbedtls_sha1_starts pmbedtls_sha1_starts #define mbedtls_sha1_update pmbedtls_sha1_update @@ -168,6 +198,17 @@ static BOOL mbedtls_initialize(void) goto fail; \ } + LOAD_FUNCPTR(mbedtls_md_init) + LOAD_FUNCPTR(mbedtls_md_setup) + LOAD_FUNCPTR(mbedtls_md_update) + LOAD_FUNCPTR(mbedtls_md_hmac_starts) + LOAD_FUNCPTR(mbedtls_md_hmac_finish) + LOAD_FUNCPTR(mbedtls_md_free); + LOAD_FUNCPTR(mbedtls_md5_init) + LOAD_FUNCPTR(mbedtls_md5_starts) + LOAD_FUNCPTR(mbedtls_md5_update) + LOAD_FUNCPTR(mbedtls_md5_finish) + LOAD_FUNCPTR(mbedtls_md5_free); LOAD_FUNCPTR(mbedtls_sha1_init) LOAD_FUNCPTR(mbedtls_sha1_starts) LOAD_FUNCPTR(mbedtls_sha1_update) @@ -211,10 +252,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) { @@ -224,6 +303,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; @@ -237,7 +319,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; @@ -247,52 +329,25 @@ 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_SHA1, - ALG_ID_SHA256, - ALG_ID_SHA384, - ALG_ID_SHA512 -}; - -static const struct { - ULONG hash_length; - const WCHAR *alg_name; -} alg_props[] = { - /* 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; -}; - NTSTATUS WINAPI BCryptOpenAlgorithmProvider( BCRYPT_ALG_HANDLE *handle, LPCWSTR id, LPCWSTR implementation, DWORD flags ) { 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; } 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; @@ -310,6 +365,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; @@ -342,11 +398,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; }; @@ -354,6 +413,10 @@ static NTSTATUS hash_init( struct hash *hash ) { switch (hash->alg_id) { + case ALG_ID_MD5: + CC_MD5_Init( &hash->u.md5_ctx ); + break; + case ALG_ID_SHA1: CC_SHA1_Init( &hash->u.sha1_ctx ); break; @@ -377,10 +440,49 @@ 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) { + case ALG_ID_MD5: + CC_MD5_Update( &hash->u.md5_ctx, input, size ); + break; + case ALG_ID_SHA1: CC_SHA1_Update( &hash->u.sha1_ctx, input, size ); break; @@ -404,10 +506,20 @@ 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) { + case ALG_ID_MD5: + CC_MD5_Final( output, &hash->u.md5_ctx ); + break; + case ALG_ID_SHA1: CC_SHA1_Final( output, &hash->u.sha1_ctx ); break; @@ -430,12 +542,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 ) @@ -446,6 +570,9 @@ static NTSTATUS hash_init( struct hash *hash ) switch (hash->alg_id) { + case ALG_ID_MD5: + alg = GNUTLS_DIG_MD5; + break; case ALG_ID_SHA1: alg = GNUTLS_DIG_SHA1; break; @@ -467,31 +594,82 @@ 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; } #elif defined(SONAME_LIBMBEDTLS) struct hash { - struct object hdr; - enum alg_id alg_id; + struct object hdr; + BOOL hmac; + enum alg_id alg_id; union { + mbedtls_md5_context md5_ctx; mbedtls_sha1_context sha1_ctx; mbedtls_sha256_context sha256_ctx; mbedtls_sha512_context sha512_ctx; + mbedtls_md_context_t hmac_ctx; } u; }; @@ -502,6 +680,11 @@ static NTSTATUS hash_init( struct hash *hash ) #endif switch (hash->alg_id) { + case ALG_ID_MD5: + mbedtls_md5_init(&hash->u.md5_ctx); + mbedtls_md5_starts(&hash->u.md5_ctx); + break; + case ALG_ID_SHA1: mbedtls_sha1_init(&hash->u.sha1_ctx); mbedtls_sha1_starts(&hash->u.sha1_ctx); @@ -526,6 +709,58 @@ static NTSTATUS hash_init( struct hash *hash ) return STATUS_SUCCESS; } +static NTSTATUS hmac_init( struct hash *hash, UCHAR *key, ULONG key_size ) +{ + const mbedtls_md_info_t *md_info; + mbedtls_md_type_t md_type; + int ret; +#ifndef __REACTOS__ + if (!libmbedtls_handle) return STATUS_INTERNAL_ERROR; +#endif + mbedtls_md_init(&hash->u.hmac_ctx); + switch (hash->alg_id) + { + case ALG_ID_MD5: + md_type = MBEDTLS_MD_MD5; + break; + + case ALG_ID_SHA1: + md_type = MBEDTLS_MD_SHA1; + break; + + case ALG_ID_SHA256: + md_type = MBEDTLS_MD_SHA256; + break; + + case ALG_ID_SHA384: + md_type = MBEDTLS_MD_SHA384; + break; + + case ALG_ID_SHA512: + md_type = MBEDTLS_MD_SHA512; + break; + + default: + ERR("unhandled id %u\n", hash->alg_id); + return STATUS_NOT_IMPLEMENTED; + } + if ((md_info = mbedtls_md_info_from_type(md_type)) == NULL) + { + mbedtls_md_free(&hash->u.hmac_ctx); + return STATUS_INTERNAL_ERROR; + } + + if ((ret = mbedtls_md_setup(&hash->u.hmac_ctx, md_info, 1)) != 0) + { + mbedtls_md_free(&hash->u.hmac_ctx); + return STATUS_INTERNAL_ERROR; + } + + mbedtls_md_hmac_starts(&hash->u.hmac_ctx, key, key_size); + + return STATUS_SUCCESS; +} + static NTSTATUS hash_update( struct hash *hash, UCHAR *input, ULONG size ) { #ifndef __REACTOS__ @@ -533,6 +768,10 @@ static NTSTATUS hash_update( struct hash *hash, UCHAR *input, ULONG size ) #endif switch (hash->alg_id) { + case ALG_ID_MD5: + mbedtls_md5_update(&hash->u.md5_ctx, input, size); + break; + case ALG_ID_SHA1: mbedtls_sha1_update(&hash->u.sha1_ctx, input, size); break; @@ -554,6 +793,16 @@ 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 ) +{ +#ifndef __REACTOS__ + if (!libmbedtls_handle) return STATUS_INTERNAL_ERROR; +#endif + mbedtls_md_update(&hash->u.hmac_ctx, input, size); + + return STATUS_SUCCESS; +} + static NTSTATUS hash_finish( struct hash *hash, UCHAR *output, ULONG size ) { #ifndef __REACTOS__ @@ -561,6 +810,11 @@ static NTSTATUS hash_finish( struct hash *hash, UCHAR *output, ULONG size ) #endif switch (hash->alg_id) { + case ALG_ID_MD5: + mbedtls_md5_finish(&hash->u.md5_ctx, output); + mbedtls_md5_free(&hash->u.md5_ctx); + break; + case ALG_ID_SHA1: mbedtls_sha1_finish(&hash->u.sha1_ctx, output); mbedtls_sha1_free(&hash->u.sha1_ctx); @@ -584,32 +838,20 @@ static NTSTATUS hash_finish( struct hash *hash, UCHAR *output, ULONG size ) return STATUS_SUCCESS; } -#else -struct hash -{ - struct object hdr; - enum alg_id alg_id; -}; -static NTSTATUS hash_init( struct hash *hash ) +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; -} - -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; -} +#ifndef __REACTOS__ + if (!libmbedtls_handle) return STATUS_INTERNAL_ERROR; +#endif + mbedtls_md_hmac_finish(&hash->u.hmac_ctx, output); + mbedtls_md_free(&hash->u.hmac_ctx); -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; + return STATUS_SUCCESS; } #endif +#define OBJECT_LENGTH_MD5 274 #define OBJECT_LENGTH_SHA1 278 #define OBJECT_LENGTH_SHA256 286 #define OBJECT_LENGTH_SHA384 382 @@ -651,6 +893,20 @@ static NTSTATUS get_alg_property( enum alg_id id, const WCHAR *prop, UCHAR *buf, switch (id) { + case ALG_ID_MD5: + if (!strcmpW( prop, BCRYPT_OBJECT_LENGTH )) + { + value = OBJECT_LENGTH_MD5; + break; + } + 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 )) { @@ -761,7 +1017,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; @@ -789,9 +1056,16 @@ NTSTATUS WINAPI BCryptHashData( BCRYPT_HASH_HANDLE handle, UCHAR *input, ULONG s TRACE( "%p, %p, %u, %08x\n", handle, input, size, flags ); if (!hash || hash->hdr.magic != MAGIC_HASH) return STATUS_INVALID_HANDLE; - if (!input) return STATUS_INVALID_PARAMETER; + 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 ) @@ -803,7 +1077,46 @@ 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 ); + } +} + +NTSTATUS WINAPI BCryptHash( BCRYPT_ALG_HANDLE algorithm, UCHAR *secret, ULONG secretlen, + UCHAR *input, ULONG inputlen, UCHAR *output, ULONG outputlen ) +{ + NTSTATUS status; + BCRYPT_HASH_HANDLE handle; + + TRACE( "%p, %p, %u, %p, %u, %p, %u\n", algorithm, secret, secretlen, + input, inputlen, output, outputlen ); + + status = BCryptCreateHash( algorithm, &handle, NULL, 0, secret, secretlen, 0); + if (status != STATUS_SUCCESS) + { + return status; + } + + status = BCryptHashData( handle, input, inputlen, 0 ); + if (status != STATUS_SUCCESS) + { + BCryptDestroyHash( handle ); + return status; + } + + status = BCryptFinishHash( handle, output, outputlen, 0 ); + if (status != STATUS_SUCCESS) + { + BCryptDestroyHash( handle ); + return status; + } + + return BCryptDestroyHash( handle ); } BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 543b883141f..6f611fcd337 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -49,7 +49,7 @@ reactos/dll/win32/atl # Synced to WineStaging-1.9.16 reactos/dll/win32/atl80 # Synced to WineStaging-1.9.11 reactos/dll/win32/atl100 # Synced to WineStaging-1.9.11 reactos/dll/win32/avifil32 # Synced to WineStaging-1.9.23 -reactos/dll/win32/bcrypt # Synced to WineStaging-1.9.4 +reactos/dll/win32/bcrypt # Synced to WineStaging-1.9.23 reactos/dll/win32/browseui # Out of sync reactos/dll/win32/cabinet # Synced to WineStaging-1.9.16 reactos/dll/win32/clusapi # Synced to WineStaging-1.9.11 -- 2.17.1