From: Derek Lesho Subject: [PATCH v3 1/4] bcrypt/tests: Add test for BCryptSecretAgreement. Message-Id: <20200107202250.2277241-1-dlesho@codeweavers.com> Date: Tue, 7 Jan 2020 14:22:47 -0600 Signed-off-by: Derek Lesho --- dlls/bcrypt/tests/bcrypt.c | 75 ++++++++++++++++++++++++++++++++++---- include/bcrypt.h | 12 ++++++ 2 files changed, 80 insertions(+), 7 deletions(-) diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index 198acbf721..47bb58d3d1 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -62,6 +62,9 @@ static NTSTATUS (WINAPI *pBCryptOpenAlgorithmProvider)(BCRYPT_ALG_HANDLE *, LPCW static NTSTATUS (WINAPI *pBCryptSetProperty)(BCRYPT_HANDLE, LPCWSTR, PUCHAR, ULONG, ULONG); static NTSTATUS (WINAPI *pBCryptSignHash)(BCRYPT_KEY_HANDLE, void *, UCHAR *, ULONG, UCHAR *, ULONG, ULONG *, ULONG); static NTSTATUS (WINAPI *pBCryptVerifySignature)(BCRYPT_KEY_HANDLE, VOID *, UCHAR *, ULONG, UCHAR *, ULONG, ULONG); +static NTSTATUS (WINAPI *pBCryptSecretAgreement)(BCRYPT_KEY_HANDLE, BCRYPT_KEY_HANDLE, BCRYPT_SECRET_HANDLE *, ULONG); +static NTSTATUS (WINAPI *pBCryptDestroySecret)(BCRYPT_SECRET_HANDLE); +static NTSTATUS (WINAPI *pBCryptDeriveKey)(BCRYPT_SECRET_HANDLE, LPCWSTR, BCryptBufferDesc *, PUCHAR, ULONG, ULONG *, ULONG); static void test_BCryptGenRandom(void) { @@ -1923,13 +1926,29 @@ static void test_RSA_SIGN(void) static BYTE eccprivkey[] = { - 0x45, 0x43, 0x4b, 0x32, 0x20, 0x00, 0x00, 0x00, 0xfb, 0xbd, 0x3d, 0x20, 0x1b, 0x6d, 0x66, 0xb3, - 0x7c, 0x9f, 0x89, 0xf3, 0xe4, 0x41, 0x16, 0xa5, 0x68, 0x52, 0x77, 0xac, 0xab, 0x55, 0xb2, 0x6c, - 0xb0, 0x23, 0x55, 0xcb, 0x96, 0x14, 0xfd, 0x0b, 0x1c, 0xef, 0xdf, 0x07, 0x6d, 0x31, 0xaf, 0x39, - 0xce, 0x8c, 0x8f, 0x9d, 0x75, 0xd0, 0x7b, 0xea, 0x81, 0xdc, 0x40, 0x21, 0x1f, 0x58, 0x22, 0x5f, - 0x72, 0x55, 0xfc, 0x58, 0x8a, 0xeb, 0x88, 0x5d, 0x02, 0x09, 0x90, 0xd2, 0xe3, 0x36, 0xac, 0xfe, - 0x83, 0x13, 0x6c, 0x88, 0x1a, 0xab, 0x9b, 0xdd, 0xaa, 0x8a, 0xee, 0x69, 0x9a, 0x6a, 0x62, 0x86, - 0x6a, 0x13, 0x69, 0x88, 0xb7, 0xd5, 0xa3, 0xcd + 0x45, 0x43, 0x4b, 0x32, 0x20, 0x00, 0x00, 0x00, + 0xfb, 0xbd, 0x3d, 0x20, 0x1b, 0x6d, 0x66, 0xb3, 0x7c, 0x9f, 0x89, 0xf3, 0xe4, 0x41, 0x16, 0xa5, + 0x68, 0x52, 0x77, 0xac, 0xab, 0x55, 0xb2, 0x6c, 0xb0, 0x23, 0x55, 0xcb, 0x96, 0x14, 0xfd, 0x0b, + 0x1c, 0xef, 0xdf, 0x07, 0x6d, 0x31, 0xaf, 0x39, 0xce, 0x8c, 0x8f, 0x9d, 0x75, 0xd0, 0x7b, 0xea, + 0x81, 0xdc, 0x40, 0x21, 0x1f, 0x58, 0x22, 0x5f, 0x72, 0x55, 0xfc, 0x58, 0x8a, 0xeb, 0x88, 0x5d, + 0x02, 0x09, 0x90, 0xd2, 0xe3, 0x36, 0xac, 0xfe, 0x83, 0x13, 0x6c, 0x88, 0x1a, 0xab, 0x9b, 0xdd, + 0xaa, 0x8a, 0xee, 0x69, 0x9a, 0x6a, 0x62, 0x86, 0x6a, 0x13, 0x69, 0x88, 0xb7, 0xd5, 0xa3, 0xcd +}; + +static BYTE ecdh_pubkey[] = +{ + 0x45, 0x43, 0x4b, 0x31, 0x20, 0x00, 0x00, 0x00, + 0x07, 0x61, 0x9d, 0x49, 0x63, 0x6b, 0x96, 0x94, 0xd1, 0x8f, 0xd1, 0x48, 0xcc, 0xcf, 0x72, 0x4d, + 0xff, 0x43, 0xf4, 0x97, 0x0f, 0xa3, 0x8a, 0x72, 0xe9, 0xe0, 0xba, 0x87, 0x6d, 0xc3, 0x62, 0x15, + 0xae, 0x65, 0xdd, 0x31, 0x51, 0xfc, 0x3b, 0xc9, 0x59, 0xa1, 0x0a, 0x92, 0x17, 0x2b, 0x64, 0x55, + 0x03, 0x3e, 0x62, 0x1d, 0xac, 0x3e, 0x37, 0x40, 0x6a, 0x4c, 0xb6, 0x21, 0x3f, 0x73, 0x5c, 0xf5 +}; + +/* little endian */ +static BYTE ecdh_secret[] = +{ + 0x48, 0xb0, 0x11, 0xdb, 0x69, 0x4e, 0xb4, 0xf4, 0xf5, 0x3e, 0xe1, 0x9b, 0xca, 0x00, 0x04, 0xc8, + 0x9b, 0x69, 0xaf, 0xd1, 0xaf, 0x1f, 0xc2, 0xd7, 0x83, 0x0a, 0xb7, 0xf8, 0x4f, 0x24, 0x32, 0x8e, }; static void test_ECDH(void) @@ -1938,6 +1957,7 @@ static void test_ECDH(void) BCRYPT_ECCKEY_BLOB *ecckey; BCRYPT_ALG_HANDLE alg; BCRYPT_KEY_HANDLE key, privkey, pubkey; + BCRYPT_SECRET_HANDLE secret; NTSTATUS status; ULONG size; @@ -2008,6 +2028,44 @@ static void test_ECDH(void) ok(!memcmp(buf, eccprivkey, size), "wrong data\n"); HeapFree(GetProcessHeap(), 0, buf); + status = pBCryptImportKeyPair(alg, NULL, BCRYPT_ECCPUBLIC_BLOB, &pubkey, ecdh_pubkey, sizeof(ecdh_pubkey), 0); + ok(status == STATUS_SUCCESS, "got %08x\n", status); + + status = pBCryptSecretAgreement(privkey, pubkey, &secret, 0); + ok(status == STATUS_SUCCESS, "got %08x\n", status); + + if (status != STATUS_SUCCESS) + { + goto derive_end; + } + + /* verify result on windows 10 */ + status = pBCryptDeriveKey(secret, BCRYPT_KDF_RAW_SECRET, NULL, NULL, 0, &size, 0); + + if (status == STATUS_NOT_SUPPORTED) + { + win_skip("BCRYPT_KDF_RAW_SECRET not supported\n"); + goto derive_end; + } + + todo_wine ok(status == STATUS_SUCCESS, "got %08x\n", status); + + if (status != STATUS_SUCCESS) + { + goto derive_end; + } + + ok(size == 32, "size of secret key incorrect, got %u, expected 32\n", size); + buf = HeapAlloc(GetProcessHeap(), 0, size); + status = pBCryptDeriveKey(secret, BCRYPT_KDF_RAW_SECRET, NULL, buf, size, &size, 0); + ok(status == STATUS_SUCCESS, "got %08x\n", status); + ok(!(memcmp(ecdh_secret, buf, size)), "wrong data\n"); + HeapFree(GetProcessHeap(), 0, buf); + + derive_end: + + pBCryptDestroySecret(secret); + pBCryptDestroyKey(pubkey); pBCryptDestroyKey(privkey); pBCryptCloseAlgorithmProvider(alg, 0); } @@ -2284,6 +2342,9 @@ START_TEST(bcrypt) pBCryptSetProperty = (void *)GetProcAddress(module, "BCryptSetProperty"); pBCryptSignHash = (void *)GetProcAddress(module, "BCryptSignHash"); pBCryptVerifySignature = (void *)GetProcAddress(module, "BCryptVerifySignature"); + pBCryptSecretAgreement = (void *)GetProcAddress(module, "BCryptSecretAgreement"); + pBCryptDestroySecret = (void *)GetProcAddress(module, "BCryptDestroySecret"); + pBCryptDeriveKey = (void *)GetProcAddress(module, "BCryptDeriveKey"); test_BCryptGenRandom(); test_BCryptGetFipsAlgorithmMode(); diff --git a/include/bcrypt.h b/include/bcrypt.h index 4546aea394..f393dc6e5c 100644 --- a/include/bcrypt.h +++ b/include/bcrypt.h @@ -92,6 +92,12 @@ typedef LONG NTSTATUS; #define BCRYPT_CHAIN_MODE_CFB L"ChainingModeCFB" #define BCRYPT_CHAIN_MODE_CCM L"ChainingModeCCM" #define BCRYPT_CHAIN_MODE_GCM L"ChainingModeGCM" + +#define BCRYPT_KDF_HASH L"HASH" +#define BCRYPT_KDF_HMAC L"HMAC" +#define BCRYPT_KDF_TLS_PRF L"TLS_PRF" +#define BCRYPT_KDF_SP80056A_CONCAT L"SP800_56A_CONCAT" +#define BCRYPT_KDF_RAW_SECRET L"TRUNCATE" #else static const WCHAR BCRYPT_ALGORITHM_NAME[] = {'A','l','g','o','r','i','t','h','m','N','a','m','e',0}; static const WCHAR BCRYPT_AUTH_TAG_LENGTH[] = {'A','u','t','h','T','a','g','L','e','n','g','t','h',0}; @@ -146,6 +152,12 @@ static const WCHAR BCRYPT_CHAIN_MODE_ECB[] = {'C','h','a','i','n','i','n','g','M static const WCHAR BCRYPT_CHAIN_MODE_CFB[] = {'C','h','a','i','n','i','n','g','M','o','d','e','C','F','B',0}; static const WCHAR BCRYPT_CHAIN_MODE_CCM[] = {'C','h','a','i','n','i','n','g','M','o','d','e','C','C','M',0}; static const WCHAR BCRYPT_CHAIN_MODE_GCM[] = {'C','h','a','i','n','i','n','g','M','o','d','e','G','C','M',0}; + +static const WCHAR BCRYPT_KDF_HASH[] = {'H','A','S','H',0}; +static const WCHAR BCRYPT_KDF_HMAC[] = {'H','M','A','C',0}; +static const WCHAR BCRYPT_KDF_TLS_PRF[] = {'T','L','S','_','P','R','F',0}; +static const WCHAR BCRYPT_KDF_SP80056A_CONCAT[] = {'S','P','8','0','0','_','5','6','A','_','C','O','N','C','A','T',0}; +static const WCHAR BCRYPT_KDF_RAW_SECRET[] = {'T','R','U','N','C','A','T','E',0}; #endif #define BCRYPT_ECDSA_PUBLIC_P256_MAGIC 0x31534345 -- 2.24.1