mirror of
https://github.com/reactos/reactos.git
synced 2025-05-17 16:27:00 +00:00
[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
This commit is contained in:
parent
7d40a4c98e
commit
7831d346b7
3 changed files with 381 additions and 67 deletions
|
@ -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
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include <wine/library.h>
|
||||
|
||||
#ifdef SONAME_LIBMBEDTLS
|
||||
#include <mbedtls/md.h>
|
||||
#include <mbedtls/md5.h>
|
||||
#include <mbedtls/sha1.h>
|
||||
#include <mbedtls/sha256.h>
|
||||
#include <mbedtls/sha512.h>
|
||||
|
@ -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;
|
||||
}
|
||||
#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_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;
|
||||
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 )
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue