Module: wine Branch: master Commit: 8bd3e4cc2e38f7655cc1badcf0aa3ff8c4974a0e URL: http://source.winehq.org/git/wine.git/?a=commit;h=8bd3e4cc2e38f7655cc1badcf0...
Author: Patrick Armstrong pat@triplefox.com Date: Mon Mar 7 19:45:27 2016 -0800
bcrypt: Implement MD5 algorithm and add tests.
Signed-off-by: Patrick Armstrong pat@oldpatricka.com Signed-off-by: Hans Leidekker hans@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/bcrypt/bcrypt_main.c | 27 +++++++++++++++++ dlls/bcrypt/tests/bcrypt.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++ include/bcrypt.h | 1 + 3 files changed, 102 insertions(+)
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index ede37e3..957efdd 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -174,6 +174,7 @@ struct object
enum alg_id { + ALG_ID_MD5, ALG_ID_SHA1, ALG_ID_SHA256, ALG_ID_SHA384, @@ -184,6 +185,7 @@ 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 }, @@ -211,6 +213,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_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; @@ -262,6 +265,7 @@ struct hash enum alg_id alg_id; union { + CC_MD5_CTX md5_ctx; CC_SHA1_CTX sha1_ctx; CC_SHA256_CTX sha256_ctx; CC_SHA512_CTX sha512_ctx; @@ -272,6 +276,9 @@ 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; @@ -299,6 +306,10 @@ 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; @@ -326,6 +337,10 @@ 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; @@ -364,6 +379,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; @@ -426,6 +444,7 @@ static NTSTATUS hash_finish( struct hash *hash, UCHAR *output, ULONG size ) } #endif
+#define OBJECT_LENGTH_MD5 274 #define OBJECT_LENGTH_SHA1 278 #define OBJECT_LENGTH_SHA256 286 #define OBJECT_LENGTH_SHA384 382 @@ -467,6 +486,14 @@ 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_SHA1: if (!strcmpW( prop, BCRYPT_OBJECT_LENGTH )) { diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index 2613a07..bcb287b 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -404,6 +404,79 @@ static void test_sha512(void) ok(ret == STATUS_SUCCESS, "got %08x\n", ret); }
+static void test_md5(void) +{ + static const char expected[] = + "e2a3e68d23ce348b8f68b3079de3d4c9"; + BCRYPT_ALG_HANDLE alg; + BCRYPT_HASH_HANDLE hash; + UCHAR buf[512], md5[16]; + ULONG size, len; + char str[65]; + NTSTATUS ret; + + alg = NULL; + ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_MD5_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(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0); + ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, NULL, (UCHAR *)&len, sizeof(len), &size, 0); + ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0); + ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(size == sizeof(len), "got %u\n", size); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0); + ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret); + ok(len == 0xdeadbeef, "got %u\n", len); + ok(size == sizeof(len), "got %u\n", size); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len , sizeof(len), &size, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(len != 0xdeadbeef, "len not set\n"); + ok(size == sizeof(len), "got %u\n", size); + + test_hash_length(alg, 16); + test_alg_name(alg, "MD5"); + + hash = NULL; + len = sizeof(buf); + ret = BCryptCreateHash(alg, &hash, buf, len, NULL, 0, 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, 0, sizeof(md5)); + ret = BCryptFinishHash(hash, md5, sizeof(md5), 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + format_hash( md5, sizeof(md5), str ); + ok(!strcmp(str, expected), "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) { test_BCryptGenRandom(); @@ -412,4 +485,5 @@ START_TEST(bcrypt) test_sha256(); test_sha384(); test_sha512(); + test_md5(); } diff --git a/include/bcrypt.h b/include/bcrypt.h index 30988be..3cd14d2 100644 --- a/include/bcrypt.h +++ b/include/bcrypt.h @@ -63,6 +63,7 @@ typedef LONG NTSTATUS; #define MS_PLATFORM_CRYPTO_PROVIDER (const WCHAR [])\ {'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_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}