Signed-off-by: Brendan Shanks bshanks@codeweavers.com --- dlls/bcrypt/bcrypt_internal.h | 6 ++++++ dlls/bcrypt/bcrypt_main.c | 35 ++++++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h index 18343a6c749..43be170d77f 100644 --- a/dlls/bcrypt/bcrypt_internal.h +++ b/dlls/bcrypt/bcrypt_internal.h @@ -111,6 +111,7 @@ VOID WINAPI A_SHAFinal(SHA_CTX *ctx, PULONG result); #define MAGIC_ALG (('A' << 24) | ('L' << 16) | ('G' << 8) | '0') #define MAGIC_HASH (('H' << 24) | ('A' << 16) | ('S' << 8) | 'H') #define MAGIC_KEY (('K' << 24) | ('E' << 16) | ('Y' << 8) | '0') +#define MAGIC_SECRET (('S' << 24) | ('C' << 16) | ('R' << 8) | 'T') struct object { ULONG magic; @@ -239,6 +240,11 @@ struct key }; #endif
+struct secret +{ + struct object hdr; +}; + NTSTATUS get_alg_property( const struct algorithm *, const WCHAR *, UCHAR *, ULONG, ULONG * ) DECLSPEC_HIDDEN;
NTSTATUS key_set_property( struct key *, const WCHAR *, UCHAR *, ULONG, ULONG ) DECLSPEC_HIDDEN; diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index fee40ebe8d7..bea2001a677 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -1833,26 +1833,47 @@ NTSTATUS WINAPI BCryptDeriveKeyPBKDF2( BCRYPT_ALG_HANDLE handle, UCHAR *pwd, ULO return STATUS_SUCCESS; }
-NTSTATUS WINAPI BCryptSecretAgreement(BCRYPT_KEY_HANDLE handle, BCRYPT_KEY_HANDLE key, BCRYPT_SECRET_HANDLE *secret, ULONG flags) +NTSTATUS WINAPI BCryptSecretAgreement(BCRYPT_KEY_HANDLE privatekey, BCRYPT_KEY_HANDLE publickey, BCRYPT_SECRET_HANDLE *handle, ULONG flags) { - FIXME( "%p, %p, %p, %08x\n", handle, key, secret, flags ); + struct key *privkey = privatekey; + struct key *pubkey = publickey; + struct secret *secret;
- if(secret) - *secret = (BCRYPT_SECRET_HANDLE *)0xDEADFEED; + FIXME( "%p, %p, %p, %08x\n", privatekey, publickey, handle, flags );
+ if (!privkey || privkey->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE; + if (!pubkey || pubkey->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE; + if (!handle) return STATUS_INVALID_PARAMETER; + + if (!(secret = heap_alloc_zero( sizeof(*secret) ))) return STATUS_NO_MEMORY; + secret->hdr.magic = MAGIC_SECRET; + + *handle = secret; return STATUS_SUCCESS; }
-NTSTATUS WINAPI BCryptDestroySecret(BCRYPT_SECRET_HANDLE secret) +NTSTATUS WINAPI BCryptDestroySecret(BCRYPT_SECRET_HANDLE handle) { - FIXME( "%p\n", secret ); + struct secret *secret = handle; + + FIXME( "%p\n", handle ); + + if (!secret || secret->hdr.magic != MAGIC_SECRET) return STATUS_INVALID_HANDLE; + secret->hdr.magic = 0; + heap_free( secret ); return STATUS_SUCCESS; }
-NTSTATUS WINAPI BCryptDeriveKey(BCRYPT_SECRET_HANDLE secret, LPCWSTR kdf, BCryptBufferDesc *parameter, +NTSTATUS WINAPI BCryptDeriveKey(BCRYPT_SECRET_HANDLE handle, LPCWSTR kdf, BCryptBufferDesc *parameter, PUCHAR derived, ULONG derived_size, ULONG *result, ULONG flags) { + struct secret *secret = handle; + FIXME( "%p, %s, %p, %p, %d, %p, %08x\n", secret, debugstr_w(kdf), parameter, derived, derived_size, result, flags ); + + if (!secret || secret->hdr.magic != MAGIC_SECRET) return STATUS_INVALID_HANDLE; + if (!kdf) return STATUS_INVALID_PARAMETER; + return STATUS_INTERNAL_ERROR; }
Signed-off-by: Brendan Shanks bshanks@codeweavers.com --- dlls/bcrypt/tests/bcrypt.c | 71 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+)
diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index f6e5c84e8d2..eb7a72e0ff4 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -2574,6 +2574,76 @@ static void test_DSA(void) ok(!ret, "got %08x\n", ret); }
+static void test_SecretAgreement(void) +{ + BCRYPT_SECRET_HANDLE secret; + BCRYPT_ALG_HANDLE alg; + BCRYPT_KEY_HANDLE key; + NTSTATUS status; + ULONG size; + + status = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_ECDH_P256_ALGORITHM, NULL, 0); + if (status) + { + skip("Failed to open BCRYPT_ECDH_P256_ALGORITHM provider %08x\n", status); + return; + } + + key = NULL; + status = pBCryptGenerateKeyPair(alg, &key, 256, 0); + ok(status == STATUS_SUCCESS, "got %08x\n", status); + ok(key != NULL, "key not set\n"); + + status = pBCryptFinalizeKeyPair(key, 0); + ok(status == STATUS_SUCCESS, "got %08x\n", status); + + status = pBCryptSecretAgreement(NULL, key, &secret, 0); + ok(status == STATUS_INVALID_HANDLE, "got %08x\n", status); + + status = pBCryptSecretAgreement(key, NULL, &secret, 0); + ok(status == STATUS_INVALID_HANDLE, "got %08x\n", status); + + status = pBCryptSecretAgreement(key, key, NULL, 0); + ok(status == STATUS_INVALID_PARAMETER, "got %08x\n", status); + + status = pBCryptSecretAgreement(key, key, &secret, 0); + ok(status == STATUS_SUCCESS, "got %08x\n", status); + + status = pBCryptDeriveKey(NULL, L"HASH", NULL, NULL, 0, &size, 0); + ok(status == STATUS_INVALID_HANDLE, "got %08x\n", status); + + status = pBCryptDeriveKey(key, L"HASH", NULL, NULL, 0, &size, 0); + ok(status == STATUS_INVALID_HANDLE, "got %08x\n", status); + + status = pBCryptDeriveKey(secret, NULL, NULL, NULL, 0, &size, 0); + ok(status == STATUS_INVALID_PARAMETER, "got %08x\n", status); + + status = pBCryptDeriveKey(secret, L"HASH", NULL, NULL, 0, &size, 0); + todo_wine + ok(status == STATUS_SUCCESS, "got %08x\n", status); + + status = pBCryptDestroyHash(secret); + ok(status == STATUS_INVALID_PARAMETER, "got %08x\n", status); + + status = pBCryptDestroyKey(secret); + ok(status == STATUS_INVALID_HANDLE, "got %08x\n", status); + + status = pBCryptDestroySecret(NULL); + ok(status == STATUS_INVALID_HANDLE, "got %08x\n", status); + + status = pBCryptDestroySecret(alg); + ok(status == STATUS_INVALID_HANDLE, "got %08x\n", status); + + status = pBCryptDestroySecret(secret); + ok(status == STATUS_SUCCESS, "got %08x\n", status); + + status = pBCryptDestroyKey(key); + ok(status == STATUS_SUCCESS, "got %08x\n", status); + + status = pBCryptCloseAlgorithmProvider(alg, 0); + ok(status == STATUS_SUCCESS, "got %08x\n", status); +} + START_TEST(bcrypt) { HMODULE module; @@ -2639,6 +2709,7 @@ START_TEST(bcrypt) test_aes_vector(); test_BcryptDeriveKeyCapi(); test_DSA(); + test_SecretAgreement();
FreeLibrary(module); }