From: Derek Lesho Subject: [PATCH v3 4/4] bcrypt: Implement BCRYPT_KDF_HASH. Message-Id: <20200107202250.2277241-4-dlesho@codeweavers.com> Date: Tue, 7 Jan 2020 14:22:50 -0600 In-Reply-To: <20200107202250.2277241-1-dlesho@codeweavers.com> References: <20200107202250.2277241-1-dlesho@codeweavers.com> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47699 Signed-off-by: Derek Lesho --- dlls/bcrypt/bcrypt_main.c | 100 +++++++++++++++++++++++++++++++++++++ dlls/bcrypt/tests/bcrypt.c | 2 +- 2 files changed, 101 insertions(+), 1 deletion(-) diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index ed64cd1965..ed09ffafb3 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -1744,6 +1744,106 @@ NTSTATUS WINAPI BCryptDeriveKey(BCRYPT_SECRET_HANDLE hSecret, LPCWSTR deriv_func TRACE( "%p, %s, %p, %p, %d, %p, %08x\n", secret, debugstr_w(deriv_func), parameter, derived, derived_size, result, flags ); + if (flags) + { + FIXME("flags ignored: %08x\n", flags); + } + + if (!(strcmpW(deriv_func, BCRYPT_KDF_HASH))) + { + unsigned int i; + BCryptBuffer *hash_algorithm = NULL; + BCryptBuffer *secret_prepend = NULL; + BCryptBuffer *secret_append = NULL; + enum alg_id hash_alg_id; + ULONG hash_length; + struct hash_impl hash; + NTSTATUS status; + + if (parameter) + { + for (i = 0; i < parameter->cBuffers; i++) + { + BCryptBuffer *cur_buffer = ¶meter->pBuffers[i]; + switch(cur_buffer->BufferType) + { + case KDF_HASH_ALGORITHM: + hash_algorithm = cur_buffer; + break; + case KDF_SECRET_PREPEND: + secret_prepend = cur_buffer; + break; + case KDF_SECRET_APPEND: + secret_append = cur_buffer; + break; + } + } + } + + if (!(hash_algorithm)) + hash_alg_id = ALG_ID_SHA1; + else + { + for (i = 0; i < ARRAY_SIZE( builtin_algorithms ); i++) + { + if (!strcmpW( hash_algorithm->pvBuffer, builtin_algorithms[i].name)) + { + hash_alg_id = i; + break; + } + } + if (i == ARRAY_SIZE(builtin_algorithms)) + { + return STATUS_NOT_SUPPORTED; + } + if (builtin_algorithms[hash_alg_id].class != BCRYPT_HASH_INTERFACE) + { + return STATUS_NOT_SUPPORTED; + } + } + + hash_length = builtin_algorithms[hash_alg_id].hash_length; + + if (!derived) + { + *result = hash_length; + return STATUS_SUCCESS; + } + + if ((status = hash_init(&hash, hash_alg_id))) + { + return status; + } + + if (secret_prepend) + { + hash_update(&hash, hash_alg_id, secret_prepend->pvBuffer, secret_prepend->cbBuffer); + } + + hash_update(&hash, hash_alg_id, secret->data, secret->len); + + if (secret_append) + { + hash_update(&hash, hash_alg_id, secret_append->pvBuffer, secret_append->cbBuffer); + } + + if (derived_size >= hash_length) + { + hash_finish(&hash, hash_alg_id, derived, derived_size); + *result = hash_length; + } + else + { + UCHAR *output = heap_alloc(hash_length); + hash_finish(&hash, hash_alg_id, output, hash_length); + memcpy(derived, output, derived_size); + heap_free(output); + *result = derived_size; + } + + return STATUS_SUCCESS; + } + else if (!(strcmpW(deriv_func, BCRYPT_KDF_RAW_SECRET))) { ULONG n; diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index 0f0771bedc..214ac92b44 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -2087,7 +2087,7 @@ static void test_ECDH(void) raw_secret_end: status = pBCryptDeriveKey(secret, BCRYPT_KDF_HASH, &hash_params, NULL, 0, &size, 0); - todo_wine ok (status == STATUS_SUCCESS, "got %08x\n", status); + ok (status == STATUS_SUCCESS, "got %08x\n", status); if (status != STATUS_SUCCESS) { -- 2.24.1