diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index 2de1bb379b1..ae7432e917c 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -29,13 +29,22 @@ static NTSTATUS (WINAPI *pBCryptOpenAlgorithmProvider)(BCRYPT_ALG_HANDLE *, LPCWSTR, LPCWSTR, ULONG); static NTSTATUS (WINAPI *pBCryptCloseAlgorithmProvider)(BCRYPT_ALG_HANDLE, ULONG); static NTSTATUS (WINAPI *pBCryptGetFipsAlgorithmMode)(BOOLEAN *); -static NTSTATUS (WINAPI *pBCryptCreateHash)(BCRYPT_ALG_HANDLE, BCRYPT_HASH_HANDLE *, PUCHAR, ULONG, PUCHAR, ULONG, ULONG); +static NTSTATUS (WINAPI *pBCryptCreateHash)(BCRYPT_ALG_HANDLE, BCRYPT_HASH_HANDLE *, PUCHAR, ULONG, PUCHAR, + ULONG, ULONG); static NTSTATUS (WINAPI *pBCryptHash)(BCRYPT_ALG_HANDLE, UCHAR *, ULONG, UCHAR *, ULONG, UCHAR *, ULONG); static NTSTATUS (WINAPI *pBCryptHashData)(BCRYPT_HASH_HANDLE, PUCHAR, ULONG, ULONG); static NTSTATUS (WINAPI *pBCryptFinishHash)(BCRYPT_HASH_HANDLE, PUCHAR, ULONG, ULONG); static NTSTATUS (WINAPI *pBCryptDestroyHash)(BCRYPT_HASH_HANDLE); static NTSTATUS (WINAPI *pBCryptGenRandom)(BCRYPT_ALG_HANDLE, PUCHAR, ULONG, ULONG); static NTSTATUS (WINAPI *pBCryptGetProperty)(BCRYPT_HANDLE, LPCWSTR, PUCHAR, ULONG, ULONG *, ULONG); +static NTSTATUS (WINAPI *pBCryptSetProperty)(BCRYPT_HANDLE, LPCWSTR, PUCHAR, ULONG, ULONG); +static NTSTATUS (WINAPI *pBCryptGenerateSymmetricKey)(BCRYPT_ALG_HANDLE, BCRYPT_KEY_HANDLE *, PUCHAR, ULONG, + PUCHAR, ULONG, ULONG); +static NTSTATUS (WINAPI *pBCryptEncrypt)(BCRYPT_KEY_HANDLE, PUCHAR, ULONG, VOID *, PUCHAR, ULONG, PUCHAR, ULONG, + ULONG *, ULONG); +static NTSTATUS (WINAPI *pBCryptDecrypt)(BCRYPT_KEY_HANDLE, PUCHAR, ULONG, VOID *, PUCHAR, ULONG, PUCHAR, ULONG, + ULONG *, ULONG); +static NTSTATUS (WINAPI *pBCryptDestroyKey)(BCRYPT_KEY_HANDLE); static void test_BCryptGenRandom(void) { @@ -821,6 +830,92 @@ todo_wine { } } +static void test_BCryptGenerateSymmetricKey(void) +{ + static UCHAR secret[] = + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; + static UCHAR iv[] = + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; + static UCHAR data[] = + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; + static UCHAR expected[] = + {0xc6,0xa1,0x3b,0x37,0x87,0x8f,0x5b,0x82,0x6f,0x4f,0x81,0x62,0xa1,0xc8,0xd8,0x79}; + BCRYPT_ALG_HANDLE aes; + BCRYPT_KEY_HANDLE key; + UCHAR *buf, ciphertext[16], plaintext[16], ivbuf[16]; + ULONG size, len, i; + NTSTATUS ret; + + ret = pBCryptOpenAlgorithmProvider(&aes, BCRYPT_AES_ALGORITHM, NULL, 0); + if (ret != STATUS_SUCCESS) /* remove whole IF when Wine is fixed */ + { + todo_wine ok(0, "AES provider not available\n"); + return; + } + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + + len = size = 0xdeadbeef; + ret = pBCryptGetProperty(aes, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + + key = NULL; + buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); + ret = pBCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(key != NULL, "key not set\n"); + + ret = pBCryptSetProperty(aes, BCRYPT_CHAINING_MODE, (UCHAR *)BCRYPT_CHAIN_MODE_CBC, + sizeof(BCRYPT_CHAIN_MODE_CBC), 0); + todo_wine ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + + size = 0xdeadbeef; + ret = pBCryptEncrypt(key, NULL, 0, NULL, NULL, 0, NULL, 0, &size, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(!size, "got %u\n", size); + + size = 0; + memcpy(ivbuf, iv, sizeof(iv)); + ret = pBCryptEncrypt(key, data, 16, NULL, ivbuf, 16, NULL, 0, &size, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(size == 16, "got %u\n", size); + + size = 0; + memcpy(ivbuf, iv, sizeof(iv)); + memset(ciphertext, 0, sizeof(ciphertext)); + ret = pBCryptEncrypt(key, data, 16, NULL, ivbuf, 16, ciphertext, 16, &size, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(size == 16, "got %u\n", size); + ok(!memcmp(ciphertext, expected, sizeof(expected)), "wrong data\n"); + for (i = 0; i < 16; i++) + ok(ciphertext[i] == expected[i], "%u: %02x != %02x\n", i, ciphertext[i], expected[i]); + + size = 0xdeadbeef; + ret = pBCryptDecrypt(key, NULL, 0, NULL, NULL, 0, NULL, 0, &size, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(!size, "got %u\n", size); + + size = 0; + memcpy(ivbuf, iv, sizeof(iv)); + ret = pBCryptDecrypt(key, ciphertext, 16, NULL, ivbuf, 16, NULL, 0, &size, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(size == 16, "got %u\n", size); + + size = 0; + memcpy(ivbuf, iv, sizeof(iv)); + memset(plaintext, 0, sizeof(plaintext)); + ret = pBCryptDecrypt(key, ciphertext, 16, NULL, ivbuf, 16, plaintext, 16, &size, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(size == 16, "got %u\n", size); + ok(!memcmp(plaintext, data, sizeof(data)), "wrong data\n"); + + ret = pBCryptDestroyKey(key); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + HeapFree(GetProcessHeap(), 0, buf); + + ret = pBCryptCloseAlgorithmProvider(aes, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); +} + START_TEST(bcrypt) { HMODULE module; @@ -842,6 +937,11 @@ START_TEST(bcrypt) pBCryptDestroyHash = (void *)GetProcAddress(module, "BCryptDestroyHash"); pBCryptGenRandom = (void *)GetProcAddress(module, "BCryptGenRandom"); pBCryptGetProperty = (void *)GetProcAddress(module, "BCryptGetProperty"); + pBCryptSetProperty = (void *)GetProcAddress(module, "BCryptSetProperty"); + pBCryptGenerateSymmetricKey = (void *)GetProcAddress(module, "BCryptGenerateSymmetricKey"); + pBCryptEncrypt = (void *)GetProcAddress(module, "BCryptEncrypt"); + pBCryptDecrypt = (void *)GetProcAddress(module, "BCryptDecrypt"); + pBCryptDestroyKey = (void *)GetProcAddress(module, "BCryptDestroyKey"); test_BCryptGenRandom(); test_BCryptGetFipsAlgorithmMode(); @@ -852,6 +952,7 @@ START_TEST(bcrypt) test_md5(); test_rng(); test_aes(); + test_BCryptGenerateSymmetricKey(); if (pBCryptHash) /* >= Win 10 */ test_BcryptHash(); diff --git a/include/bcrypt.h b/include/bcrypt.h index e7c62808565..e327a652027 100644 --- a/include/bcrypt.h +++ b/include/bcrypt.h @@ -83,23 +83,32 @@ typedef struct _BCRYPT_ALGORITHM_IDENTIFIER } BCRYPT_ALGORITHM_IDENTIFIER; typedef PVOID BCRYPT_ALG_HANDLE; +typedef PVOID BCRYPT_KEY_HANDLE; typedef PVOID BCRYPT_HANDLE; typedef PVOID BCRYPT_HASH_HANDLE; +/* Flags for BCryptGenRandom */ #define BCRYPT_RNG_USE_ENTROPY_IN_BUFFER 0x00000001 #define BCRYPT_USE_SYSTEM_PREFERRED_RNG 0x00000002 + +/* Flags for BCryptOpenAlgorithmProvider */ #define BCRYPT_ALG_HANDLE_HMAC_FLAG 0x00000008 NTSTATUS WINAPI BCryptCloseAlgorithmProvider(BCRYPT_ALG_HANDLE, ULONG); NTSTATUS WINAPI BCryptCreateHash(BCRYPT_ALG_HANDLE, BCRYPT_HASH_HANDLE *, PUCHAR, ULONG, PUCHAR, ULONG, ULONG); +NTSTATUS WINAPI BCryptDecrypt(BCRYPT_KEY_HANDLE, PUCHAR, ULONG, VOID *, PUCHAR, ULONG, PUCHAR, ULONG, ULONG *, ULONG); NTSTATUS WINAPI BCryptDestroyHash(BCRYPT_HASH_HANDLE); +NTSTATUS WINAPI BCryptDestroyKey(BCRYPT_KEY_HANDLE); +NTSTATUS WINAPI BCryptEncrypt(BCRYPT_KEY_HANDLE, PUCHAR, ULONG, VOID *, PUCHAR, ULONG, PUCHAR, ULONG, ULONG *, ULONG); NTSTATUS WINAPI BCryptEnumAlgorithms(ULONG, ULONG *, BCRYPT_ALGORITHM_IDENTIFIER **, ULONG); NTSTATUS WINAPI BCryptFinishHash(BCRYPT_HASH_HANDLE, PUCHAR, ULONG, ULONG); +NTSTATUS WINAPI BCryptGenerateSymmetricKey(BCRYPT_ALG_HANDLE, BCRYPT_KEY_HANDLE *, PUCHAR, ULONG, PUCHAR, ULONG, ULONG); NTSTATUS WINAPI BCryptGenRandom(BCRYPT_ALG_HANDLE, PUCHAR, ULONG, ULONG); NTSTATUS WINAPI BCryptGetFipsAlgorithmMode(BOOLEAN *); NTSTATUS WINAPI BCryptGetProperty(BCRYPT_HANDLE, LPCWSTR, PUCHAR, ULONG, ULONG *, ULONG); NTSTATUS WINAPI BCryptHash(BCRYPT_ALG_HANDLE, PUCHAR, ULONG, PUCHAR, ULONG, PUCHAR, ULONG); NTSTATUS WINAPI BCryptHashData(BCRYPT_HASH_HANDLE, PUCHAR, ULONG, ULONG); NTSTATUS WINAPI BCryptOpenAlgorithmProvider(BCRYPT_ALG_HANDLE *, LPCWSTR, LPCWSTR, ULONG); +NTSTATUS WINAPI BCryptSetProperty(BCRYPT_HANDLE, LPCWSTR, PUCHAR, ULONG, ULONG); #endif /* __WINE_BCRYPT_H */