From e73d4e55a9f5337bf5673339aaf301b64afd060a Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 7 Dec 2017 19:46:58 +0100 Subject: [PATCH] bcrypt: Added support for MD4 hashes. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/bcrypt/bcrypt_internal.h | 11 +++++++++++ dlls/bcrypt/bcrypt_main.c | 17 +++++++++++++++++ dlls/bcrypt/tests/bcrypt.c | 6 ++++++ include/bcrypt.h | 1 + 4 files changed, 35 insertions(+) diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h index c58ede8e152..a75f92a90b9 100644 --- a/dlls/bcrypt/bcrypt_internal.h +++ b/dlls/bcrypt/bcrypt_internal.h @@ -61,6 +61,17 @@ void md2_update(MD2_CTX *ctx, const unsigned char *buf, ULONG len) DECLSPEC_HIDD void md2_finalize(MD2_CTX *ctx, unsigned char *hash) DECLSPEC_HIDDEN; /* Definitions from advapi32 */ +typedef struct tagMD4_CTX { + unsigned int buf[4]; + unsigned int i[2]; + unsigned char in[64]; + unsigned char digest[16]; +} MD4_CTX; + +VOID WINAPI MD4Init(MD4_CTX *ctx); +VOID WINAPI MD4Update(MD4_CTX *ctx, const unsigned char *buf, unsigned int len); +VOID WINAPI MD4Final(MD4_CTX *ctx); + typedef struct { unsigned int i[2]; diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index b2021842cd9..931db2be999 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -146,6 +146,7 @@ enum alg_id { ALG_ID_AES, ALG_ID_MD2, + ALG_ID_MD4, ALG_ID_MD5, ALG_ID_RNG, ALG_ID_SHA1, @@ -165,6 +166,7 @@ static const struct { } alg_props[] = { /* ALG_ID_AES */ { 654, 0, 0, BCRYPT_AES_ALGORITHM }, /* ALG_ID_MD2 */ { 270, 16, 128, BCRYPT_MD2_ALGORITHM }, + /* ALG_ID_MD4 */ { 270, 16, 512, BCRYPT_MD4_ALGORITHM }, /* ALG_ID_MD5 */ { 274, 16, 512, BCRYPT_MD5_ALGORITHM }, /* ALG_ID_RNG */ { 0, 0, 0, BCRYPT_RNG_ALGORITHM }, /* ALG_ID_SHA1 */ { 278, 20, 512, BCRYPT_SHA1_ALGORITHM }, @@ -238,6 +240,7 @@ NTSTATUS WINAPI BCryptOpenAlgorithmProvider( BCRYPT_ALG_HANDLE *handle, LPCWSTR if (!strcmpW( id, BCRYPT_AES_ALGORITHM )) alg_id = ALG_ID_AES; else if (!strcmpW( id, BCRYPT_MD2_ALGORITHM )) alg_id = ALG_ID_MD2; + else if (!strcmpW( id, BCRYPT_MD4_ALGORITHM )) alg_id = ALG_ID_MD4; 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_SHA1_ALGORITHM )) alg_id = ALG_ID_SHA1; @@ -291,6 +294,7 @@ struct hash_impl union { MD2_CTX md2; + MD4_CTX md4; MD5_CTX md5; SHA_CTX sha1; SHA256_CTX sha256; @@ -306,6 +310,10 @@ static NTSTATUS hash_init( struct hash_impl *hash, enum alg_id alg_id ) md2_init( &hash->u.md2 ); break; + case ALG_ID_MD4: + MD4Init( &hash->u.md4 ); + break; + case ALG_ID_MD5: MD5Init( &hash->u.md5 ); break; @@ -342,6 +350,10 @@ static NTSTATUS hash_update( struct hash_impl *hash, enum alg_id alg_id, md2_update( &hash->u.md2, input, size ); break; + case ALG_ID_MD4: + MD4Update( &hash->u.md4, input, size ); + break; + case ALG_ID_MD5: MD5Update( &hash->u.md5, input, size ); break; @@ -378,6 +390,11 @@ static NTSTATUS hash_finish( struct hash_impl *hash, enum alg_id alg_id, md2_finalize( &hash->u.md2, output ); break; + case ALG_ID_MD4: + MD4Final( &hash->u.md4 ); + memcpy( output, hash->u.md4.digest, 16 ); + break; + case ALG_ID_MD5: MD5Final( &hash->u.md5 ); memcpy( output, hash->u.md5.digest, 16 ); diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index de0419058fc..6fa04b099a2 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -328,6 +328,12 @@ static void test_hashes(void) "1bb33606ba908912a84221109d29cd7e", "7f05b0638d77f4a27f3a9c4d353cd648" }, + { + "MD4", + 16, + "74b5db93c0b41e36ca7074338fc0b637", + "bc2e8ac4d8248ed21b8d26227a30ea3a" + }, { "MD5", 16, diff --git a/include/bcrypt.h b/include/bcrypt.h index 70928c5aded..7c3c8d0744d 100644 --- a/include/bcrypt.h +++ b/include/bcrypt.h @@ -65,6 +65,7 @@ typedef LONG NTSTATUS; #define BCRYPT_AES_ALGORITHM (const WCHAR []){'A','E','S',0} #define BCRYPT_MD2_ALGORITHM (const WCHAR []){'M','D','2',0} +#define BCRYPT_MD4_ALGORITHM (const WCHAR []){'M','D','4',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}