From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/bcrypt/bcrypt_main.c | 27 ++++++++++++++++++++++++++- dlls/bcrypt/tests/bcrypt.c | 2 -- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index db7eec4dace..30dddadee57 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -4168,6 +4168,7 @@ static const struct algorithm *get_hash_from_desc( const BCryptBufferDesc *desc return NULL; } } + else if (desc->pBuffers[i].BufferType == KDF_SECRET_PREPEND) continue; else FIXME( "buffer type %lu not supported\n", desc->pBuffers[i].BufferType ); } return alg; @@ -4176,6 +4177,9 @@ static const struct algorithm *get_hash_from_desc( const BCryptBufferDesc *desc static NTSTATUS derive_key_hash( const struct secret *secret, const BCryptBufferDesc *desc, UCHAR *output, ULONG output_len, ULONG *ret_len ) { + ULONG derived_key_len = secret->derived_key_len, secret_len = 0; + ULONG i, buffer_count = desc ? desc->cBuffers : 0; + UCHAR *derived_key = secret->derived_key; const struct algorithm *alg; ULONG len; UCHAR hash[MAX_HASH_OUTPUT_BYTES]; @@ -4190,7 +4194,28 @@ static NTSTATUS derive_key_hash( const struct secret *secret, const BCryptBuffer return STATUS_SUCCESS; } - if ((status = hash_single( alg, NULL, 0, secret->derived_key, secret->derived_key_len, hash ))) return status; + for (i = 0; i < buffer_count; i++) + if (desc->pBuffers[i].BufferType == KDF_SECRET_PREPEND) secret_len += desc->pBuffers[i].cbBuffer; + + if (secret_len) + { + if (!(derived_key = malloc( secret_len + derived_key_len ))) return STATUS_NO_MEMORY; + + derived_key_len = 0; + for (i = 0; i < buffer_count; i++) + { + if (desc->pBuffers[i].BufferType != KDF_SECRET_PREPEND) continue; + memcpy( derived_key + derived_key_len, desc->pBuffers[i].pvBuffer, desc->pBuffers[i].cbBuffer ); + derived_key_len += desc->pBuffers[i].cbBuffer; + } + + memcpy( derived_key + derived_key_len, secret->derived_key, secret->derived_key_len ); + derived_key_len += secret->derived_key_len; + } + + status = hash_single( alg, NULL, 0, derived_key, derived_key_len, hash ); + if (derived_key != secret->derived_key) free( derived_key ); + if (status) return status; len = min( len, output_len ); memcpy( output, hash, len ); diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index 6c43445b575..fb7760a4d35 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -3522,7 +3522,6 @@ raw_secret_end: buf = malloc(size); status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &hash_params_prepended, buf, size, &size, 0); ok(status == STATUS_SUCCESS, "got %#lx\n", status); - todo_wine ok(!(memcmp(t->hashed_secret_prepended, buf, size)), "wrong data\n"); free(buf); @@ -4077,7 +4076,6 @@ static void test_DH(void) buf = calloc(1, size); status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &dh_hash_params_prepended, buf, size, &size, 0); ok(status == STATUS_SUCCESS, "got %#lx\n", status); - todo_wine ok(!memcmp(dh_hashed_secret_prepended, buf, size), "wrong data\n"); ok(size == 20, "got %lu\n", size); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11635