bcrypt: Implement BCryptVerifySignature for ECDSA signatures.
[wine.git] / dlls / bcrypt / tests / bcrypt.c
blob57d04882b5488f15c1fb6555314e34e75bb60b1f
1 /*
2 * Unit test for bcrypt functions
4 * Copyright 2014 Bruno Jesus
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdio.h>
22 #include <ntstatus.h>
23 #define WIN32_NO_STATUS
24 #include <windows.h>
25 #include <bcrypt.h>
27 #include "wine/test.h"
29 static NTSTATUS (WINAPI *pBCryptOpenAlgorithmProvider)(BCRYPT_ALG_HANDLE *, LPCWSTR, LPCWSTR, ULONG);
30 static NTSTATUS (WINAPI *pBCryptCloseAlgorithmProvider)(BCRYPT_ALG_HANDLE, ULONG);
31 static NTSTATUS (WINAPI *pBCryptGetFipsAlgorithmMode)(BOOLEAN *);
32 static NTSTATUS (WINAPI *pBCryptCreateHash)(BCRYPT_ALG_HANDLE, BCRYPT_HASH_HANDLE *, PUCHAR, ULONG, PUCHAR,
33 ULONG, ULONG);
34 static NTSTATUS (WINAPI *pBCryptHash)(BCRYPT_ALG_HANDLE, UCHAR *, ULONG, UCHAR *, ULONG, UCHAR *, ULONG);
35 static NTSTATUS (WINAPI *pBCryptHashData)(BCRYPT_HASH_HANDLE, PUCHAR, ULONG, ULONG);
36 static NTSTATUS (WINAPI *pBCryptDuplicateHash)(BCRYPT_HASH_HANDLE, BCRYPT_HASH_HANDLE *, UCHAR *, ULONG, ULONG);
37 static NTSTATUS (WINAPI *pBCryptFinishHash)(BCRYPT_HASH_HANDLE, PUCHAR, ULONG, ULONG);
38 static NTSTATUS (WINAPI *pBCryptDestroyHash)(BCRYPT_HASH_HANDLE);
39 static NTSTATUS (WINAPI *pBCryptGenRandom)(BCRYPT_ALG_HANDLE, PUCHAR, ULONG, ULONG);
40 static NTSTATUS (WINAPI *pBCryptGetProperty)(BCRYPT_HANDLE, LPCWSTR, PUCHAR, ULONG, ULONG *, ULONG);
41 static NTSTATUS (WINAPI *pBCryptSetProperty)(BCRYPT_HANDLE, LPCWSTR, PUCHAR, ULONG, ULONG);
42 static NTSTATUS (WINAPI *pBCryptGenerateSymmetricKey)(BCRYPT_ALG_HANDLE, BCRYPT_KEY_HANDLE *, PUCHAR, ULONG,
43 PUCHAR, ULONG, ULONG);
44 static NTSTATUS (WINAPI *pBCryptEncrypt)(BCRYPT_KEY_HANDLE, PUCHAR, ULONG, VOID *, PUCHAR, ULONG, PUCHAR, ULONG,
45 ULONG *, ULONG);
46 static NTSTATUS (WINAPI *pBCryptDecrypt)(BCRYPT_KEY_HANDLE, PUCHAR, ULONG, VOID *, PUCHAR, ULONG, PUCHAR, ULONG,
47 ULONG *, ULONG);
48 static NTSTATUS (WINAPI *pBCryptDuplicateKey)(BCRYPT_KEY_HANDLE, BCRYPT_KEY_HANDLE *, UCHAR *, ULONG, ULONG);
49 static NTSTATUS (WINAPI *pBCryptDestroyKey)(BCRYPT_KEY_HANDLE);
50 static NTSTATUS (WINAPI *pBCryptImportKey)(BCRYPT_ALG_HANDLE, BCRYPT_KEY_HANDLE, LPCWSTR, BCRYPT_KEY_HANDLE *,
51 PUCHAR, ULONG, PUCHAR, ULONG, ULONG);
52 static NTSTATUS (WINAPI *pBCryptExportKey)(BCRYPT_KEY_HANDLE, BCRYPT_KEY_HANDLE, LPCWSTR, PUCHAR, ULONG, ULONG *, ULONG);
53 static NTSTATUS (WINAPI *pBCryptImportKeyPair)(BCRYPT_ALG_HANDLE, BCRYPT_KEY_HANDLE, LPCWSTR, BCRYPT_KEY_HANDLE *, UCHAR *, ULONG, ULONG);
54 static NTSTATUS (WINAPI *pBCryptVerifySignature)(BCRYPT_KEY_HANDLE, VOID *, UCHAR *, ULONG, UCHAR *, ULONG, ULONG);
56 static void test_BCryptGenRandom(void)
58 NTSTATUS ret;
59 UCHAR buffer[256];
61 ret = pBCryptGenRandom(NULL, NULL, 0, 0);
62 ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got 0x%x\n", ret);
63 ret = pBCryptGenRandom(NULL, buffer, 0, 0);
64 ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got 0x%x\n", ret);
65 ret = pBCryptGenRandom(NULL, buffer, sizeof(buffer), 0);
66 ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got 0x%x\n", ret);
67 ret = pBCryptGenRandom(NULL, buffer, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
68 ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret);
69 ret = pBCryptGenRandom(NULL, buffer, sizeof(buffer),
70 BCRYPT_USE_SYSTEM_PREFERRED_RNG|BCRYPT_RNG_USE_ENTROPY_IN_BUFFER);
71 ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret);
72 ret = pBCryptGenRandom(NULL, NULL, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
73 ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got 0x%x\n", ret);
75 /* Zero sized buffer should work too */
76 ret = pBCryptGenRandom(NULL, buffer, 0, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
77 ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret);
79 /* Test random number generation - It's impossible for a sane RNG to return 8 zeros */
80 memset(buffer, 0, 16);
81 ret = pBCryptGenRandom(NULL, buffer, 8, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
82 ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret);
83 ok(memcmp(buffer, buffer + 8, 8), "Expected a random number, got 0\n");
86 static void test_BCryptGetFipsAlgorithmMode(void)
88 static const WCHAR policyKeyVistaW[] = {
89 'S','y','s','t','e','m','\\',
90 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
91 'C','o','n','t','r','o','l','\\',
92 'L','s','a','\\',
93 'F','I','P','S','A','l','g','o','r','i','t','h','m','P','o','l','i','c','y',0};
94 static const WCHAR policyValueVistaW[] = {'E','n','a','b','l','e','d',0};
95 static const WCHAR policyKeyXPW[] = {
96 'S','y','s','t','e','m','\\',
97 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
98 'C','o','n','t','r','o','l','\\',
99 'L','s','a',0};
100 static const WCHAR policyValueXPW[] = {
101 'F','I','P','S','A','l','g','o','r','i','t','h','m','P','o','l','i','c','y',0};
102 HKEY hkey = NULL;
103 BOOLEAN expected;
104 BOOLEAN enabled;
105 DWORD value, count[2] = {sizeof(value), sizeof(value)};
106 NTSTATUS ret;
108 if (RegOpenKeyW(HKEY_LOCAL_MACHINE, policyKeyVistaW, &hkey) == ERROR_SUCCESS &&
109 RegQueryValueExW(hkey, policyValueVistaW, NULL, NULL, (void *)&value, &count[0]) == ERROR_SUCCESS)
111 expected = !!value;
113 else if (RegOpenKeyW(HKEY_LOCAL_MACHINE, policyKeyXPW, &hkey) == ERROR_SUCCESS &&
114 RegQueryValueExW(hkey, policyValueXPW, NULL, NULL, (void *)&value, &count[0]) == ERROR_SUCCESS)
116 expected = !!value;
118 else
120 expected = FALSE;
121 todo_wine
122 ok(0, "Neither XP or Vista key is present\n");
124 RegCloseKey(hkey);
126 ret = pBCryptGetFipsAlgorithmMode(&enabled);
127 ok(ret == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got 0x%x\n", ret);
128 ok(enabled == expected, "expected result %d, got %d\n", expected, enabled);
130 ret = pBCryptGetFipsAlgorithmMode(NULL);
131 ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got 0x%x\n", ret);
134 static void format_hash(const UCHAR *bytes, ULONG size, char *buf)
136 ULONG i;
137 buf[0] = '\0';
138 for (i = 0; i < size; i++)
140 sprintf(buf + i * 2, "%02x", bytes[i]);
142 return;
145 static int strcmp_wa(const WCHAR *strw, const char *stra)
147 WCHAR buf[512];
148 MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, sizeof(buf)/sizeof(buf[0]));
149 return lstrcmpW(strw, buf);
152 #define test_object_length(a) _test_object_length(__LINE__,a)
153 static void _test_object_length(unsigned line, void *handle)
155 NTSTATUS status;
156 ULONG len, size;
158 len = size = 0xdeadbeef;
159 status = pBCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
160 ok_(__FILE__,line)(status == STATUS_INVALID_HANDLE, "BCryptGetProperty failed: %08x\n", status);
162 len = size = 0xdeadbeef;
163 status = pBCryptGetProperty(handle, NULL, (UCHAR *)&len, sizeof(len), &size, 0);
164 ok_(__FILE__,line)(status == STATUS_INVALID_PARAMETER, "BCryptGetProperty failed: %08x\n", status);
166 len = size = 0xdeadbeef;
167 status = pBCryptGetProperty(handle, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0);
168 ok_(__FILE__,line)(status == STATUS_INVALID_PARAMETER, "BCryptGetProperty failed: %08x\n", status);
170 len = size = 0xdeadbeef;
171 status = pBCryptGetProperty(handle, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0);
172 ok_(__FILE__,line)(status == STATUS_SUCCESS, "BCryptGetProperty failed: %08x\n", status);
173 ok_(__FILE__,line)(size == sizeof(len), "got %u\n", size);
175 len = size = 0xdeadbeef;
176 status = pBCryptGetProperty(handle, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0);
177 ok_(__FILE__,line)(status == STATUS_BUFFER_TOO_SMALL, "BCryptGetProperty failed: %08x\n", status);
178 ok_(__FILE__,line)(len == 0xdeadbeef, "got %u\n", len);
179 ok_(__FILE__,line)(size == sizeof(len), "got %u\n", size);
181 len = size = 0xdeadbeef;
182 status = pBCryptGetProperty(handle, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
183 ok_(__FILE__,line)(status == STATUS_SUCCESS, "BCryptGetProperty failed: %08x\n", status);
184 ok_(__FILE__,line)(len != 0xdeadbeef, "len not set\n");
185 ok_(__FILE__,line)(size == sizeof(len), "got %u\n", size);
188 #define test_hash_length(a,b) _test_hash_length(__LINE__,a,b)
189 static void _test_hash_length(unsigned line, void *handle, ULONG exlen)
191 ULONG len = 0xdeadbeef, size = 0xdeadbeef;
192 NTSTATUS status;
194 status = pBCryptGetProperty(handle, BCRYPT_HASH_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
195 ok_(__FILE__,line)(status == STATUS_SUCCESS, "BCryptGetProperty failed: %08x\n", status);
196 ok_(__FILE__,line)(size == sizeof(len), "got %u\n", size);
197 ok_(__FILE__,line)(len == exlen, "len = %u, expected %u\n", len, exlen);
200 #define test_alg_name(a,b) _test_alg_name(__LINE__,a,b)
201 static void _test_alg_name(unsigned line, void *handle, const char *exname)
203 ULONG size = 0xdeadbeef;
204 UCHAR buf[256];
205 const WCHAR *name = (const WCHAR*)buf;
206 NTSTATUS status;
208 status = pBCryptGetProperty(handle, BCRYPT_ALGORITHM_NAME, buf, sizeof(buf), &size, 0);
209 ok_(__FILE__,line)(status == STATUS_SUCCESS, "BCryptGetProperty failed: %08x\n", status);
210 ok_(__FILE__,line)(size == (strlen(exname)+1)*sizeof(WCHAR), "got %u\n", size);
211 ok_(__FILE__,line)(!strcmp_wa(name, exname), "alg name = %s, expected %s\n", wine_dbgstr_w(name), exname);
214 struct hash_test
216 const char *alg;
217 unsigned hash_size;
218 const char *hash;
219 const char *hmac_hash;
222 static void test_hash(const struct hash_test *test)
224 BCRYPT_ALG_HANDLE alg;
225 BCRYPT_HASH_HANDLE hash;
226 UCHAR buf[512], buf_hmac[1024], hash_buf[128], hmac_hash[128];
227 WCHAR alg_name[64];
228 char str[512];
229 NTSTATUS ret;
230 ULONG len;
232 MultiByteToWideChar(CP_ACP, 0, test->alg, -1, alg_name, sizeof(alg_name)/sizeof(WCHAR));
234 alg = NULL;
235 ret = pBCryptOpenAlgorithmProvider(&alg, alg_name, MS_PRIMITIVE_PROVIDER, 0);
236 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
237 ok(alg != NULL, "alg not set\n");
239 test_object_length(alg);
240 test_hash_length(alg, test->hash_size);
241 test_alg_name(alg, test->alg);
243 hash = NULL;
244 len = sizeof(buf);
245 ret = pBCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0);
246 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
247 ok(hash != NULL, "hash not set\n");
249 ret = pBCryptHashData(hash, NULL, 0, 0);
250 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
252 ret = pBCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
253 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
255 test_hash_length(hash, test->hash_size);
256 test_alg_name(hash, test->alg);
258 memset(hash_buf, 0, sizeof(hash_buf));
259 ret = pBCryptFinishHash(hash, hash_buf, test->hash_size, 0);
260 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
261 format_hash( hash_buf, test->hash_size, str );
262 ok(!strcmp(str, test->hash), "got %s\n", str);
264 ret = pBCryptDestroyHash(hash);
265 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
267 ret = pBCryptCloseAlgorithmProvider(alg, 0);
268 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
270 alg = NULL;
271 ret = pBCryptOpenAlgorithmProvider(&alg, alg_name, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
272 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
273 ok(alg != NULL, "alg not set\n");
275 hash = NULL;
276 len = sizeof(buf_hmac);
277 ret = pBCryptCreateHash(alg, &hash, buf_hmac, len, (UCHAR *)"key", sizeof("key"), 0);
278 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
279 ok(hash != NULL, "hash not set\n");
281 ret = pBCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
282 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
284 test_hash_length(hash, test->hash_size);
285 test_alg_name(hash, test->alg);
287 memset(hmac_hash, 0, sizeof(hmac_hash));
288 ret = pBCryptFinishHash(hash, hmac_hash, test->hash_size, 0);
289 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
290 format_hash( hmac_hash, test->hash_size, str );
291 ok(!strcmp(str, test->hmac_hash), "got %s\n", str);
293 ret = pBCryptDestroyHash(hash);
294 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
296 ret = pBCryptCloseAlgorithmProvider(alg, 0);
297 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
300 static void test_hashes(void)
302 static const struct hash_test tests[] = {
304 "SHA1",
306 "961fa64958818f767707072755d7018dcd278e94",
307 "2472cf65d0e090618d769d3e46f0d9446cf212da"
310 "SHA256",
312 "ceb73749c899693706ede1e30c9929b3fd5dd926163831c2fb8bd41e6efb1126",
313 "34c1aa473a4468a91d06e7cdbc75bc4f93b830ccfc2a47ffd74e8e6ed29e4c72"
316 "SHA384",
318 "62b21e90c9022b101671ba1f808f8631a8149f0f12904055839a35c1ca78ae53"
319 "63eed1e743a692d70e0504b0cfd12ef9",
320 "4b3e6d6ff2da121790ab7e7b9247583e3a7eed2db5bd4dabc680303b1608f37d"
321 "fdc836d96a704c03283bc05b4f6c5eb8"
324 "SHA512",
326 "d55ced17163bf5386f2cd9ff21d6fd7fe576a915065c24744d09cfae4ec84ee1"
327 "ef6ef11bfbc5acce3639bab725b50a1fe2c204f8c820d6d7db0df0ecbc49c5ca",
328 "415fb6b10018ca03b38a1b1399c42ac0be5e8aceddb9a73103f5e543bf2d888f"
329 "2eecf91373941f9315dd730a77937fa92444450fbece86f409d9cb5ec48c6513"
332 "MD2",
334 "1bb33606ba908912a84221109d29cd7e",
335 "7f05b0638d77f4a27f3a9c4d353cd648"
338 "MD4",
340 "74b5db93c0b41e36ca7074338fc0b637",
341 "bc2e8ac4d8248ed21b8d26227a30ea3a"
344 "MD5",
346 "e2a3e68d23ce348b8f68b3079de3d4c9",
347 "7bda029b93fa8d817fcc9e13d6bdf092"
350 unsigned i;
352 for(i = 0; i < sizeof(tests)/sizeof(*tests); i++)
353 test_hash(tests+i);
356 static void test_BcryptHash(void)
358 static const char expected[] =
359 "e2a3e68d23ce348b8f68b3079de3d4c9";
360 static const char expected_hmac[] =
361 "7bda029b93fa8d817fcc9e13d6bdf092";
362 BCRYPT_ALG_HANDLE alg;
363 UCHAR md5[16], md5_hmac[16];
364 char str[65];
365 NTSTATUS ret;
367 alg = NULL;
368 ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_MD5_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
369 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
370 ok(alg != NULL, "alg not set\n");
372 test_hash_length(alg, 16);
373 test_alg_name(alg, "MD5");
375 memset(md5, 0, sizeof(md5));
376 ret = pBCryptHash(alg, NULL, 0, (UCHAR *)"test", sizeof("test"), md5, sizeof(md5));
377 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
378 format_hash( md5, sizeof(md5), str );
379 ok(!strcmp(str, expected), "got %s\n", str);
381 ret = pBCryptCloseAlgorithmProvider(alg, 0);
382 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
384 alg = NULL;
385 memset(md5_hmac, 0, sizeof(md5_hmac));
386 ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_MD5_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
387 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
388 ok(alg != NULL, "alg not set\n");
390 ret = pBCryptHash(alg, (UCHAR *)"key", sizeof("key"), (UCHAR *)"test", sizeof("test"), md5_hmac, sizeof(md5_hmac));
391 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
392 format_hash( md5_hmac, sizeof(md5_hmac), str );
393 ok(!strcmp(str, expected_hmac), "got %s\n", str);
395 ret = pBCryptCloseAlgorithmProvider(alg, 0);
396 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
399 static void test_rng(void)
401 BCRYPT_ALG_HANDLE alg;
402 ULONG size, len;
403 UCHAR buf[16];
404 NTSTATUS ret;
406 alg = NULL;
407 ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
408 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
409 ok(alg != NULL, "alg not set\n");
411 len = size = 0xdeadbeef;
412 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
413 ok(ret == STATUS_NOT_SUPPORTED, "got %08x\n", ret);
415 len = size = 0xdeadbeef;
416 ret = pBCryptGetProperty(alg, BCRYPT_HASH_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
417 ok(ret == STATUS_NOT_SUPPORTED, "got %08x\n", ret);
419 test_alg_name(alg, "RNG");
421 memset(buf, 0, 16);
422 ret = pBCryptGenRandom(alg, buf, 8, 0);
423 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
424 ok(memcmp(buf, buf + 8, 8), "got zeroes\n");
426 ret = pBCryptCloseAlgorithmProvider(alg, 0);
427 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
430 static void test_aes(void)
432 BCRYPT_KEY_LENGTHS_STRUCT key_lengths;
433 BCRYPT_ALG_HANDLE alg;
434 ULONG size, len;
435 UCHAR mode[64];
436 NTSTATUS ret;
438 alg = NULL;
439 ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_AES_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
440 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
441 ok(alg != NULL, "alg not set\n");
443 len = size = 0;
444 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
445 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
446 ok(len, "expected non-zero len\n");
447 ok(size == sizeof(len), "got %u\n", size);
449 len = size = 0;
450 ret = pBCryptGetProperty(alg, BCRYPT_BLOCK_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
451 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
452 ok(len == 16, "got %u\n", len);
453 ok(size == sizeof(len), "got %u\n", size);
455 size = 0;
456 ret = pBCryptGetProperty(alg, BCRYPT_CHAINING_MODE, mode, 0, &size, 0);
457 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
458 ok(size == 64, "got %u\n", size);
460 size = 0;
461 ret = pBCryptGetProperty(alg, BCRYPT_CHAINING_MODE, mode, sizeof(mode) - 1, &size, 0);
462 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
463 ok(size == 64, "got %u\n", size);
465 size = 0;
466 memset(mode, 0, sizeof(mode));
467 ret = pBCryptGetProperty(alg, BCRYPT_CHAINING_MODE, mode, sizeof(mode), &size, 0);
468 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
469 ok(!lstrcmpW((const WCHAR *)mode, BCRYPT_CHAIN_MODE_CBC), "got %s\n", wine_dbgstr_w((const WCHAR *)mode));
470 ok(size == 64, "got %u\n", size);
472 size = 0;
473 memset(&key_lengths, 0, sizeof(key_lengths));
474 ret = pBCryptGetProperty(alg, BCRYPT_KEY_LENGTHS, (UCHAR*)&key_lengths, sizeof(key_lengths), &size, 0);
475 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
476 ok(size == sizeof(key_lengths), "got %u\n", size);
477 ok(key_lengths.dwMinLength == 128, "Expected 128, got %d\n", key_lengths.dwMinLength);
478 ok(key_lengths.dwMaxLength == 256, "Expected 256, got %d\n", key_lengths.dwMaxLength);
479 ok(key_lengths.dwIncrement == 64, "Expected 64, got %d\n", key_lengths.dwIncrement);
481 memcpy(mode, BCRYPT_CHAIN_MODE_GCM, sizeof(BCRYPT_CHAIN_MODE_GCM));
482 ret = pBCryptSetProperty(alg, BCRYPT_CHAINING_MODE, mode, sizeof(mode), 0);
483 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
485 size = 0;
486 memset(mode, 0, sizeof(mode));
487 ret = pBCryptGetProperty(alg, BCRYPT_CHAINING_MODE, mode, sizeof(mode), &size, 0);
488 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
489 ok(!lstrcmpW((const WCHAR *)mode, BCRYPT_CHAIN_MODE_GCM), "got %s\n", wine_dbgstr_w((const WCHAR *)mode));
490 ok(size == 64, "got %u\n", size);
492 test_alg_name(alg, "AES");
494 ret = pBCryptCloseAlgorithmProvider(alg, 0);
495 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
498 static void test_BCryptGenerateSymmetricKey(void)
500 static UCHAR secret[] =
501 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
502 static UCHAR iv[] =
503 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
504 static UCHAR data[] =
505 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
506 static UCHAR expected[] =
507 {0xc6,0xa1,0x3b,0x37,0x87,0x8f,0x5b,0x82,0x6f,0x4f,0x81,0x62,0xa1,0xc8,0xd8,0x79};
508 BCRYPT_ALG_HANDLE aes;
509 BCRYPT_KEY_HANDLE key, key2;
510 UCHAR *buf, ciphertext[16], plaintext[16], ivbuf[16];
511 ULONG size, len, i;
512 NTSTATUS ret;
514 ret = pBCryptOpenAlgorithmProvider(&aes, BCRYPT_AES_ALGORITHM, NULL, 0);
515 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
517 len = size = 0xdeadbeef;
518 ret = pBCryptGetProperty(aes, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
519 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
521 key = (void *)0xdeadbeef;
522 ret = pBCryptGenerateSymmetricKey(NULL, &key, NULL, 0, secret, sizeof(secret), 0);
523 ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret);
524 ok(key == (void *)0xdeadbeef, "got %p\n", key);
526 key = NULL;
527 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
528 ret = pBCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0);
529 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
530 ok(key != NULL, "key not set\n");
532 ret = pBCryptSetProperty(aes, BCRYPT_CHAINING_MODE, (UCHAR *)BCRYPT_CHAIN_MODE_CBC,
533 sizeof(BCRYPT_CHAIN_MODE_CBC), 0);
534 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
536 ret = pBCryptSetProperty(key, BCRYPT_CHAINING_MODE, (UCHAR *)BCRYPT_CHAIN_MODE_CBC,
537 sizeof(BCRYPT_CHAIN_MODE_CBC), 0);
538 ok(ret == STATUS_SUCCESS || broken(ret == STATUS_NOT_SUPPORTED) /* < Win 8 */, "got %08x\n", ret);
540 size = 0xdeadbeef;
541 ret = pBCryptEncrypt(key, NULL, 0, NULL, NULL, 0, NULL, 0, &size, 0);
542 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
543 ok(!size, "got %u\n", size);
545 size = 0;
546 memcpy(ivbuf, iv, sizeof(iv));
547 ret = pBCryptEncrypt(key, data, 16, NULL, ivbuf, 16, NULL, 0, &size, 0);
548 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
549 ok(size == 16, "got %u\n", size);
551 size = 0;
552 memcpy(ivbuf, iv, sizeof(iv));
553 memset(ciphertext, 0, sizeof(ciphertext));
554 ret = pBCryptEncrypt(key, data, 16, NULL, ivbuf, 16, ciphertext, 16, &size, 0);
555 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
556 ok(size == 16, "got %u\n", size);
557 ok(!memcmp(ciphertext, expected, sizeof(expected)), "wrong data\n");
558 for (i = 0; i < 16; i++)
559 ok(ciphertext[i] == expected[i], "%u: %02x != %02x\n", i, ciphertext[i], expected[i]);
561 key2 = (void *)0xdeadbeef;
562 ret = pBCryptDuplicateKey(NULL, &key2, NULL, 0, 0);
563 ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret);
564 ok(key2 == (void *)0xdeadbeef, "got %p\n", key2);
566 if (0) /* crashes on some Windows versions */
568 ret = pBCryptDuplicateKey(key, NULL, NULL, 0, 0);
569 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
572 key2 = (void *)0xdeadbeef;
573 ret = pBCryptDuplicateKey(key, &key2, NULL, 0, 0);
574 ok(ret == STATUS_SUCCESS || broken(ret == STATUS_INVALID_PARAMETER), "got %08x\n", ret);
576 if (ret == STATUS_SUCCESS)
578 size = 0;
579 memcpy(ivbuf, iv, sizeof(iv));
580 memset(ciphertext, 0, sizeof(ciphertext));
581 ret = pBCryptEncrypt(key2, data, 16, NULL, ivbuf, 16, ciphertext, 16, &size, 0);
582 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
583 ok(size == 16, "got %u\n", size);
584 ok(!memcmp(ciphertext, expected, sizeof(expected)), "wrong data\n");
585 for (i = 0; i < 16; i++)
586 ok(ciphertext[i] == expected[i], "%u: %02x != %02x\n", i, ciphertext[i], expected[i]);
588 ret = pBCryptDestroyKey(key2);
589 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
592 size = 0xdeadbeef;
593 ret = pBCryptDecrypt(key, NULL, 0, NULL, NULL, 0, NULL, 0, &size, 0);
594 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
595 ok(!size, "got %u\n", size);
597 size = 0;
598 memcpy(ivbuf, iv, sizeof(iv));
599 ret = pBCryptDecrypt(key, ciphertext, 16, NULL, ivbuf, 16, NULL, 0, &size, 0);
600 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
601 ok(size == 16, "got %u\n", size);
603 size = 0;
604 memcpy(ivbuf, iv, sizeof(iv));
605 memset(plaintext, 0, sizeof(plaintext));
606 ret = pBCryptDecrypt(key, ciphertext, 16, NULL, ivbuf, 16, plaintext, 16, &size, 0);
607 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
608 ok(size == 16, "got %u\n", size);
609 ok(!memcmp(plaintext, data, sizeof(data)), "wrong data\n");
611 ret = pBCryptDestroyKey(key);
612 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
613 HeapFree(GetProcessHeap(), 0, buf);
615 ret = pBCryptCloseAlgorithmProvider(aes, 0);
616 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
619 static void test_BCryptEncrypt(void)
621 static UCHAR nonce[] =
622 {0x10,0x20,0x30,0x40,0x50,0x60,0x10,0x20,0x30,0x40,0x50,0x60};
623 static UCHAR auth_data[] =
624 {0x60,0x50,0x40,0x30,0x20,0x10,0x60,0x50,0x40,0x30,0x20,0x10};
625 static UCHAR secret[] =
626 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
627 static UCHAR secret256[] =
628 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
629 0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00};
630 static UCHAR iv[] =
631 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
632 static UCHAR data[] =
633 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10};
634 static UCHAR data2[] =
635 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
636 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10};
637 static UCHAR expected[] =
638 {0xc6,0xa1,0x3b,0x37,0x87,0x8f,0x5b,0x82,0x6f,0x4f,0x81,0x62,0xa1,0xc8,0xd8,0x79};
639 static UCHAR expected2[] =
640 {0xc6,0xa1,0x3b,0x37,0x87,0x8f,0x5b,0x82,0x6f,0x4f,0x81,0x62,0xa1,0xc8,0xd8,0x79,
641 0x28,0x73,0x3d,0xef,0x84,0x8f,0xb0,0xa6,0x5d,0x1a,0x51,0xb7,0xec,0x8f,0xea,0xe9};
642 static UCHAR expected3[] =
643 {0xc6,0xa1,0x3b,0x37,0x87,0x8f,0x5b,0x82,0x6f,0x4f,0x81,0x62,0xa1,0xc8,0xd8,0x79,
644 0xb1,0xa2,0x92,0x73,0xbe,0x2c,0x42,0x07,0xa5,0xac,0xe3,0x93,0x39,0x8c,0xb6,0xfb,
645 0x87,0x5d,0xea,0xa3,0x7e,0x0f,0xde,0xfa,0xd9,0xec,0x6c,0x4e,0x3c,0x76,0x86,0xe4};
646 static UCHAR expected4[] =
647 {0xe1,0x82,0xc3,0xc0,0x24,0xfb,0x86,0x85,0xf3,0xf1,0x2b,0x7d,0x09,0xb4,0x73,0x67,
648 0x86,0x64,0xc3,0xfe,0xa3,0x07,0x61,0xf8,0x16,0xc9,0x78,0x7f,0xe7,0xb1,0xc4,0x94};
649 static UCHAR expected5[] =
650 {0x0a,0x94,0x0b,0xb5,0x41,0x6e,0xf0,0x45,0xf1,0xc3,0x94,0x58,0xc6,0x53,0xea,0x5a};
651 static UCHAR expected6[] =
652 {0x0a,0x94,0x0b,0xb5,0x41,0x6e,0xf0,0x45,0xf1,0xc3,0x94,0x58,0xc6,0x53,0xea,0x5a,
653 0x84,0x07,0x66,0xb7,0x49,0xc0,0x9b,0x49,0x74,0x28,0x8c,0x10,0xb9,0xc2,0x09,0x70};
654 static UCHAR expected7[] =
655 {0x0a,0x94,0x0b,0xb5,0x41,0x6e,0xf0,0x45,0xf1,0xc3,0x94,0x58,0xc6,0x53,0xea,0x5a,
656 0x95,0x4f,0x64,0xf2,0xe4,0xe8,0x6e,0x9e,0xee,0x82,0xd2,0x02,0x16,0x68,0x48,0x99,
657 0x95,0x4f,0x64,0xf2,0xe4,0xe8,0x6e,0x9e,0xee,0x82,0xd2,0x02,0x16,0x68,0x48,0x99};
658 static UCHAR expected8[] =
659 {0xb5,0x8a,0x10,0x64,0xd8,0xac,0xa9,0x9b,0xd9,0xb0,0x40,0x5b,0x85,0x45,0xf5,0xbb};
660 static UCHAR expected9[] =
661 {0x0a,0x94,0x0b,0xb5,0x41,0x6e,0xf0,0x45,0xf1,0xc3,0x94,0x58,0xc6,0x53,0xea,0x5a};
662 static UCHAR expected10[] =
663 {0x66,0xb8,0xbd,0xe5,0x90,0x6c,0xec,0xdf,0xfa,0x8a,0xb2,0xfd,0x92,0x84,0xeb,0xf0,
664 0x95,0xc4,0xdf,0xa7,0x7a,0x62,0xe4,0xab,0xd4,0x0e,0x94,0x4e,0xd7,0x6e,0xa1,0x47,
665 0x29,0x4b,0x37,0xfe,0x28,0x6d,0x5f,0x69,0x46,0x30,0x73,0xc0,0xaa,0x42,0xe4,0x46};
666 static UCHAR expected_tag[] =
667 {0x89,0xb3,0x92,0x00,0x39,0x20,0x09,0xb4,0x6a,0xd6,0xaf,0xca,0x4b,0x5b,0xfd,0xd0};
668 static UCHAR expected_tag2[] =
669 {0x9a,0x92,0x32,0x2c,0x61,0x2a,0xae,0xef,0x66,0x2a,0xfb,0x55,0xe9,0x48,0xdf,0xbd};
670 static UCHAR expected_tag3[] =
671 {0x17,0x9d,0xc0,0x7a,0xf0,0xcf,0xaa,0xd5,0x1c,0x11,0xc4,0x4b,0xd6,0xa3,0x3e,0x77};
672 static UCHAR expected_tag4[] =
673 {0x4c,0x42,0x83,0x9e,0x8d,0x40,0xf1,0x19,0xd6,0x2b,0x1c,0x66,0x03,0x2b,0x39,0x63};
675 BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO auth_info;
676 UCHAR *buf, ciphertext[48], ivbuf[16], tag[16];
677 BCRYPT_AUTH_TAG_LENGTHS_STRUCT tag_length;
678 BCRYPT_ALG_HANDLE aes;
679 BCRYPT_KEY_HANDLE key;
680 ULONG size, len, i;
681 NTSTATUS ret;
683 ret = pBCryptOpenAlgorithmProvider(&aes, BCRYPT_AES_ALGORITHM, NULL, 0);
684 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
686 /******************
687 * AES - CBC mode *
688 ******************/
690 len = 0xdeadbeef;
691 size = sizeof(len);
692 ret = pBCryptGetProperty(aes, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
693 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
695 key = NULL;
696 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
697 ret = pBCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0);
698 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
699 ok(key != NULL, "key not set\n");
701 /* input size is a multiple of block size */
702 size = 0;
703 memcpy(ivbuf, iv, sizeof(iv));
704 ret = pBCryptEncrypt(key, data, 16, NULL, ivbuf, 16, NULL, 0, &size, 0);
705 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
706 ok(size == 16, "got %u\n", size);
708 size = 0;
709 memcpy(ivbuf, iv, sizeof(iv));
710 memset(ciphertext, 0, sizeof(ciphertext));
711 ret = pBCryptEncrypt(key, data, 16, NULL, ivbuf, 16, ciphertext, 16, &size, 0);
712 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
713 ok(size == 16, "got %u\n", size);
714 ok(!memcmp(ciphertext, expected, sizeof(expected)), "wrong data\n");
715 for (i = 0; i < 16; i++)
716 ok(ciphertext[i] == expected[i], "%u: %02x != %02x\n", i, ciphertext[i], expected[i]);
718 /* NULL initialization vector */
719 size = 0;
720 memset(ciphertext, 0, sizeof(ciphertext));
721 ret = pBCryptEncrypt(key, data, 16, NULL, NULL, 0, ciphertext, 16, &size, 0);
722 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
723 ok(size == 16, "got %u\n", size);
724 todo_wine ok(!memcmp(ciphertext, expected8, sizeof(expected8)), "wrong data\n");
726 /* all zero initialization vector */
727 size = 0;
728 memset(ciphertext, 0, sizeof(ciphertext));
729 memset(ivbuf, 0, sizeof(ivbuf));
730 ret = pBCryptEncrypt(key, data, 16, NULL, ivbuf, 16, ciphertext, 16, &size, 0);
731 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
732 ok(size == 16, "got %u\n", size);
733 ok(!memcmp(ciphertext, expected9, sizeof(expected9)), "wrong data\n");
734 for (i = 0; i < 16; i++)
735 ok(ciphertext[i] == expected9[i], "%u: %02x != %02x\n", i, ciphertext[i], expected9[i]);
737 /* input size is not a multiple of block size */
738 size = 0;
739 memcpy(ivbuf, iv, sizeof(iv));
740 ret = pBCryptEncrypt(key, data, 17, NULL, ivbuf, 16, NULL, 0, &size, 0);
741 ok(ret == STATUS_INVALID_BUFFER_SIZE, "got %08x\n", ret);
742 ok(size == 17, "got %u\n", size);
744 /* input size is not a multiple of block size, block padding set */
745 size = 0;
746 memcpy(ivbuf, iv, sizeof(iv));
747 ret = pBCryptEncrypt(key, data, 17, NULL, ivbuf, 16, NULL, 0, &size, BCRYPT_BLOCK_PADDING);
748 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
749 ok(size == 32, "got %u\n", size);
751 size = 0;
752 memcpy(ivbuf, iv, sizeof(iv));
753 memset(ciphertext, 0, sizeof(ciphertext));
754 ret = pBCryptEncrypt(key, data, 17, NULL, ivbuf, 16, ciphertext, 32, &size, BCRYPT_BLOCK_PADDING);
755 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
756 ok(size == 32, "got %u\n", size);
757 ok(!memcmp(ciphertext, expected2, sizeof(expected2)), "wrong data\n");
758 for (i = 0; i < 32; i++)
759 ok(ciphertext[i] == expected2[i], "%u: %02x != %02x\n", i, ciphertext[i], expected2[i]);
761 /* input size is a multiple of block size, block padding set */
762 size = 0;
763 memcpy(ivbuf, iv, sizeof(iv));
764 ret = pBCryptEncrypt(key, data2, 32, NULL, ivbuf, 16, NULL, 0, &size, BCRYPT_BLOCK_PADDING);
765 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
766 ok(size == 48, "got %u\n", size);
768 size = 0;
769 memcpy(ivbuf, iv, sizeof(iv));
770 memset(ciphertext, 0, sizeof(ciphertext));
771 ret = pBCryptEncrypt(key, data2, 32, NULL, ivbuf, 16, ciphertext, 48, &size, BCRYPT_BLOCK_PADDING);
772 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
773 ok(size == 48, "got %u\n", size);
774 ok(!memcmp(ciphertext, expected3, sizeof(expected3)), "wrong data\n");
775 for (i = 0; i < 48; i++)
776 ok(ciphertext[i] == expected3[i], "%u: %02x != %02x\n", i, ciphertext[i], expected3[i]);
778 /* output size too small */
779 size = 0;
780 memcpy(ivbuf, iv, sizeof(iv));
781 memset(ciphertext, 0, sizeof(ciphertext));
782 ret = pBCryptEncrypt(key, data, 17, NULL, ivbuf, 16, ciphertext, 31, &size, BCRYPT_BLOCK_PADDING);
783 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
784 ok(size == 32, "got %u\n", size);
786 size = 0;
787 memcpy(ivbuf, iv, sizeof(iv));
788 memset(ciphertext, 0, sizeof(ciphertext));
789 ret = pBCryptEncrypt(key, data2, 32, NULL, ivbuf, 16, ciphertext, 32, &size, BCRYPT_BLOCK_PADDING);
790 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
791 ok(size == 48, "got %u\n", size);
793 ret = pBCryptDestroyKey(key);
794 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
795 HeapFree(GetProcessHeap(), 0, buf);
797 /* 256 bit key */
798 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
799 ret = pBCryptGenerateSymmetricKey(aes, &key, buf, len, secret256, sizeof(secret256), 0);
800 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
802 size = 0;
803 memcpy(ivbuf, iv, sizeof(iv));
804 ret = pBCryptEncrypt(key, data2, 32, NULL, ivbuf, 16, NULL, 0, &size, BCRYPT_BLOCK_PADDING);
805 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
806 ok(size == 48, "got %u\n", size);
808 size = 0;
809 memcpy(ivbuf, iv, sizeof(iv));
810 memset(ciphertext, 0, sizeof(ciphertext));
811 ret = pBCryptEncrypt(key, data2, 32, NULL, ivbuf, 16, ciphertext, 48, &size, BCRYPT_BLOCK_PADDING);
812 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
813 ok(size == 48, "got %u\n", size);
814 ok(!memcmp(ciphertext, expected10, sizeof(expected10)), "wrong data\n");
815 for (i = 0; i < 48; i++)
816 ok(ciphertext[i] == expected10[i], "%u: %02x != %02x\n", i, ciphertext[i], expected10[i]);
818 ret = pBCryptDestroyKey(key);
819 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
820 HeapFree(GetProcessHeap(), 0, buf);
822 /******************
823 * AES - GCM mode *
824 ******************/
826 size = 0;
827 ret = pBCryptGetProperty(aes, BCRYPT_AUTH_TAG_LENGTH, NULL, 0, &size, 0);
828 ok(ret == STATUS_NOT_SUPPORTED, "got %08x\n", ret);
830 ret = pBCryptSetProperty(aes, BCRYPT_CHAINING_MODE, (UCHAR*)BCRYPT_CHAIN_MODE_GCM, sizeof(BCRYPT_CHAIN_MODE_GCM), 0);
831 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
833 size = 0;
834 ret = pBCryptGetProperty(aes, BCRYPT_AUTH_TAG_LENGTH, NULL, 0, &size, 0);
835 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
836 ok(size == sizeof(tag_length), "got %u\n", size);
838 size = 0;
839 memset(&tag_length, 0, sizeof(tag_length));
840 ret = pBCryptGetProperty(aes, BCRYPT_AUTH_TAG_LENGTH, (UCHAR*)&tag_length, sizeof(tag_length), &size, 0);
841 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
842 ok(size == sizeof(tag_length), "got %u\n", size);
843 ok(tag_length.dwMinLength == 12, "Expected 12, got %d\n", tag_length.dwMinLength);
844 ok(tag_length.dwMaxLength == 16, "Expected 16, got %d\n", tag_length.dwMaxLength);
845 ok(tag_length.dwIncrement == 1, "Expected 1, got %d\n", tag_length.dwIncrement);
847 len = 0xdeadbeef;
848 size = sizeof(len);
849 ret = pBCryptGetProperty(aes, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
850 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
852 key = NULL;
853 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
854 ret = pBCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0);
855 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
856 ok(key != NULL, "key not set\n");
858 memset(&auth_info, 0, sizeof(auth_info));
859 auth_info.cbSize = sizeof(auth_info);
860 auth_info.dwInfoVersion = 1;
861 auth_info.pbNonce = nonce;
862 auth_info.cbNonce = sizeof(nonce);
863 auth_info.pbTag = tag;
864 auth_info.cbTag = sizeof(tag);
866 /* input size is a multiple of block size */
867 size = 0;
868 memcpy(ivbuf, iv, sizeof(iv));
869 memset(ciphertext, 0xff, sizeof(ciphertext));
870 memset(tag, 0xff, sizeof(tag));
871 ret = pBCryptEncrypt(key, data2, 32, &auth_info, ivbuf, 16, ciphertext, 32, &size, 0);
872 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
873 ok(size == 32, "got %u\n", size);
874 ok(!memcmp(ciphertext, expected4, sizeof(expected4)), "wrong data\n");
875 ok(!memcmp(tag, expected_tag, sizeof(expected_tag)), "wrong tag\n");
876 for (i = 0; i < 32; i++)
877 ok(ciphertext[i] == expected4[i], "%u: %02x != %02x\n", i, ciphertext[i], expected4[i]);
878 for (i = 0; i < 16; i++)
879 ok(tag[i] == expected_tag[i], "%u: %02x != %02x\n", i, tag[i], expected_tag[i]);
881 /* NULL initialization vector */
882 size = 0;
883 memset(ciphertext, 0xff, sizeof(ciphertext));
884 memset(tag, 0xff, sizeof(tag));
885 ret = pBCryptEncrypt(key, data2, 32, &auth_info, NULL, 0, ciphertext, 32, &size, 0);
886 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
887 ok(size == 32, "got %u\n", size);
888 ok(!memcmp(ciphertext, expected4, sizeof(expected4)), "wrong data\n");
889 ok(!memcmp(tag, expected_tag, sizeof(expected_tag)), "wrong tag\n");
890 for (i = 0; i < 32; i++)
891 ok(ciphertext[i] == expected4[i], "%u: %02x != %02x\n", i, ciphertext[i], expected4[i]);
892 for (i = 0; i < 16; i++)
893 ok(tag[i] == expected_tag[i], "%u: %02x != %02x\n", i, tag[i], expected_tag[i]);
895 /* all zero initialization vector */
896 size = 0;
897 memset(ciphertext, 0xff, sizeof(ciphertext));
898 memset(tag, 0xff, sizeof(tag));
899 memset(ivbuf, 0, sizeof(ivbuf));
900 ret = pBCryptEncrypt(key, data2, 32, &auth_info, ivbuf, 16, ciphertext, 32, &size, 0);
901 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
902 ok(size == 32, "got %u\n", size);
903 ok(!memcmp(ciphertext, expected4, sizeof(expected4)), "wrong data\n");
904 ok(!memcmp(tag, expected_tag, sizeof(expected_tag)), "wrong tag\n");
905 for (i = 0; i < 32; i++)
906 ok(ciphertext[i] == expected4[i], "%u: %02x != %02x\n", i, ciphertext[i], expected4[i]);
907 for (i = 0; i < 16; i++)
908 ok(tag[i] == expected_tag[i], "%u: %02x != %02x\n", i, tag[i], expected_tag[i]);
910 /* input size is not multiple of block size */
911 size = 0;
912 memcpy(ivbuf, iv, sizeof(iv));
913 memset(ciphertext, 0xff, sizeof(ciphertext));
914 memset(tag, 0xff, sizeof(tag));
915 ret = pBCryptEncrypt(key, data2, 24, &auth_info, ivbuf, 16, ciphertext, 24, &size, 0);
916 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
917 ok(size == 24, "got %u\n", size);
918 ok(!memcmp(ciphertext, expected4, 24), "wrong data\n");
919 ok(!memcmp(tag, expected_tag2, sizeof(expected_tag2)), "wrong tag\n");
920 for (i = 0; i < 24; i++)
921 ok(ciphertext[i] == expected4[i], "%u: %02x != %02x\n", i, ciphertext[i], expected4[i]);
922 for (i = 0; i < 16; i++)
923 ok(tag[i] == expected_tag2[i], "%u: %02x != %02x\n", i, tag[i], expected_tag2[i]);
925 /* test with auth data */
926 auth_info.pbAuthData = auth_data;
927 auth_info.cbAuthData = sizeof(auth_data);
929 size = 0;
930 memcpy(ivbuf, iv, sizeof(iv));
931 memset(ciphertext, 0xff, sizeof(ciphertext));
932 memset(tag, 0xff, sizeof(tag));
933 ret = pBCryptEncrypt(key, data2, 32, &auth_info, ivbuf, 16, ciphertext, 32, &size, 0);
934 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
935 ok(size == 32, "got %u\n", size);
936 ok(!memcmp(ciphertext, expected4, sizeof(expected4)), "wrong data\n");
937 ok(!memcmp(tag, expected_tag3, sizeof(expected_tag3)), "wrong tag\n");
938 for (i = 0; i < 32; i++)
939 ok(ciphertext[i] == expected4[i], "%u: %02x != %02x\n", i, ciphertext[i], expected4[i]);
940 for (i = 0; i < 16; i++)
941 ok(tag[i] == expected_tag3[i], "%u: %02x != %02x\n", i, tag[i], expected_tag3[i]);
943 memset(tag, 0xff, sizeof(tag));
944 ret = pBCryptEncrypt(key, data2, 0, &auth_info, ivbuf, 16, NULL, 0, &size, 0);
945 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
946 ok(!size, "got %u\n", size);
947 for (i = 0; i < 16; i++)
948 ok(tag[i] == 0xff, "%u: %02x != %02x\n", i, tag[i], 0xff);
950 memset(tag, 0xff, sizeof(tag));
951 ret = pBCryptEncrypt(key, NULL, 0, &auth_info, ivbuf, 16, NULL, 0, &size, 0);
952 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
953 ok(!size, "got %u\n", size);
954 ok(!memcmp(tag, expected_tag4, sizeof(expected_tag4)), "wrong tag\n");
955 for (i = 0; i < 16; i++)
956 ok(tag[i] == expected_tag4[i], "%u: %02x != %02x\n", i, tag[i], expected_tag4[i]);
958 /* test with padding */
959 memcpy(ivbuf, iv, sizeof(iv));
960 memset(ciphertext, 0, sizeof(ciphertext));
961 ret = pBCryptEncrypt(key, data2, 32, &auth_info, ivbuf, 16, ciphertext, 32, &size, BCRYPT_BLOCK_PADDING);
962 todo_wine ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
964 memcpy(ivbuf, iv, sizeof(iv));
965 memset(ciphertext, 0, sizeof(ciphertext));
966 ret = pBCryptEncrypt(key, data2, 32, &auth_info, ivbuf, 16, ciphertext, 48, &size, BCRYPT_BLOCK_PADDING);
967 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
969 ret = pBCryptDestroyKey(key);
970 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
971 HeapFree(GetProcessHeap(), 0, buf);
973 /******************
974 * AES - ECB mode *
975 ******************/
977 ret = pBCryptSetProperty(aes, BCRYPT_CHAINING_MODE, (UCHAR*)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0);
978 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
980 len = 0xdeadbeef;
981 size = sizeof(len);
982 ret = pBCryptGetProperty(aes, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
983 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
985 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
986 ret = pBCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0);
987 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
989 /* initialization vector is not allowed */
990 size = 0;
991 memcpy(ivbuf, iv, sizeof(iv));
992 ret = pBCryptEncrypt(key, data, 16, NULL, ivbuf, 16, ciphertext, 16, &size, 0);
993 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
994 ok(size == 16, "got %u\n", size);
996 /* input size is a multiple of block size */
997 size = 0;
998 ret = pBCryptEncrypt(key, data, 16, NULL, NULL, 16, NULL, 0, &size, 0);
999 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1000 ok(size == 16, "got %u\n", size);
1002 size = 0;
1003 memset(ciphertext, 0, sizeof(ciphertext));
1004 ret = pBCryptEncrypt(key, data, 16, NULL, NULL, 16, ciphertext, 16, &size, 0);
1005 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1006 ok(size == 16, "got %u\n", size);
1007 ok(!memcmp(ciphertext, expected5, sizeof(expected5)), "wrong data\n");
1008 for (i = 0; i < 16; i++)
1009 ok(ciphertext[i] == expected5[i], "%u: %02x != %02x\n", i, ciphertext[i], expected5[i]);
1011 /* input size is not a multiple of block size */
1012 size = 0;
1013 ret = pBCryptEncrypt(key, data, 17, NULL, NULL, 16, NULL, 0, &size, 0);
1014 ok(ret == STATUS_INVALID_BUFFER_SIZE, "got %08x\n", ret);
1015 ok(size == 17, "got %u\n", size);
1017 /* input size is not a multiple of block size, block padding set */
1018 size = 0;
1019 ret = pBCryptEncrypt(key, data, 17, NULL, NULL, 16, NULL, 0, &size, BCRYPT_BLOCK_PADDING);
1020 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1021 ok(size == 32, "got %u\n", size);
1023 size = 0;
1024 memset(ciphertext, 0, sizeof(ciphertext));
1025 ret = pBCryptEncrypt(key, data, 17, NULL, NULL, 16, ciphertext, 32, &size, BCRYPT_BLOCK_PADDING);
1026 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1027 ok(size == 32, "got %u\n", size);
1028 ok(!memcmp(ciphertext, expected6, sizeof(expected6)), "wrong data\n");
1029 for (i = 0; i < 32; i++)
1030 ok(ciphertext[i] == expected6[i], "%u: %02x != %02x\n", i, ciphertext[i], expected6[i]);
1032 /* input size is a multiple of block size, block padding set */
1033 size = 0;
1034 ret = pBCryptEncrypt(key, data2, 32, NULL, NULL, 16, NULL, 0, &size, BCRYPT_BLOCK_PADDING);
1035 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1036 ok(size == 48, "got %u\n", size);
1038 size = 0;
1039 memset(ciphertext, 0, sizeof(ciphertext));
1040 ret = pBCryptEncrypt(key, data2, 32, NULL, NULL, 16, ciphertext, 48, &size, BCRYPT_BLOCK_PADDING);
1041 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1042 ok(size == 48, "got %u\n", size);
1043 ok(!memcmp(ciphertext, expected7, sizeof(expected7)), "wrong data\n");
1044 for (i = 0; i < 48; i++)
1045 ok(ciphertext[i] == expected7[i], "%u: %02x != %02x\n", i, ciphertext[i], expected7[i]);
1047 /* output size too small */
1048 size = 0;
1049 memset(ciphertext, 0, sizeof(ciphertext));
1050 ret = pBCryptEncrypt(key, data, 17, NULL, NULL, 16, ciphertext, 31, &size, BCRYPT_BLOCK_PADDING);
1051 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
1052 ok(size == 32, "got %u\n", size);
1054 size = 0;
1055 memset(ciphertext, 0, sizeof(ciphertext));
1056 ret = pBCryptEncrypt(key, data2, 32, NULL, NULL, 16, ciphertext, 32, &size, BCRYPT_BLOCK_PADDING);
1057 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
1058 ok(size == 48, "got %u\n", size);
1060 ret = pBCryptDestroyKey(key);
1061 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1062 HeapFree(GetProcessHeap(), 0, buf);
1064 ret = pBCryptCloseAlgorithmProvider(aes, 0);
1065 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1068 static void test_BCryptDecrypt(void)
1070 static UCHAR nonce[] =
1071 {0x10,0x20,0x30,0x40,0x50,0x60,0x10,0x20,0x30,0x40,0x50,0x60};
1072 static UCHAR auth_data[] =
1073 {0x60,0x50,0x40,0x30,0x20,0x10,0x60,0x50,0x40,0x30,0x20,0x10};
1074 static UCHAR secret[] =
1075 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
1076 static UCHAR iv[] =
1077 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
1078 static UCHAR expected[] =
1079 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
1080 static UCHAR expected2[] =
1081 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10};
1082 static UCHAR expected3[] =
1083 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
1084 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10};
1085 static UCHAR ciphertext[32] =
1086 {0xc6,0xa1,0x3b,0x37,0x87,0x8f,0x5b,0x82,0x6f,0x4f,0x81,0x62,0xa1,0xc8,0xd8,0x79,
1087 0x28,0x73,0x3d,0xef,0x84,0x8f,0xb0,0xa6,0x5d,0x1a,0x51,0xb7,0xec,0x8f,0xea,0xe9};
1088 static UCHAR ciphertext2[] =
1089 {0xc6,0xa1,0x3b,0x37,0x87,0x8f,0x5b,0x82,0x6f,0x4f,0x81,0x62,0xa1,0xc8,0xd8,0x79,
1090 0x28,0x73,0x3d,0xef,0x84,0x8f,0xb0,0xa6,0x5d,0x1a,0x51,0xb7,0xec,0x8f,0xea,0xe9};
1091 static UCHAR ciphertext3[] =
1092 {0xc6,0xa1,0x3b,0x37,0x87,0x8f,0x5b,0x82,0x6f,0x4f,0x81,0x62,0xa1,0xc8,0xd8,0x79,
1093 0xb1,0xa2,0x92,0x73,0xbe,0x2c,0x42,0x07,0xa5,0xac,0xe3,0x93,0x39,0x8c,0xb6,0xfb,
1094 0x87,0x5d,0xea,0xa3,0x7e,0x0f,0xde,0xfa,0xd9,0xec,0x6c,0x4e,0x3c,0x76,0x86,0xe4};
1095 static UCHAR ciphertext4[] =
1096 {0xe1,0x82,0xc3,0xc0,0x24,0xfb,0x86,0x85,0xf3,0xf1,0x2b,0x7d,0x09,0xb4,0x73,0x67,
1097 0x86,0x64,0xc3,0xfe,0xa3,0x07,0x61,0xf8,0x16,0xc9,0x78,0x7f,0xe7,0xb1,0xc4,0x94};
1098 static UCHAR ciphertext5[] =
1099 {0x0a,0x94,0x0b,0xb5,0x41,0x6e,0xf0,0x45,0xf1,0xc3,0x94,0x58,0xc6,0x53,0xea,0x5a,
1100 0x84,0x07,0x66,0xb7,0x49,0xc0,0x9b,0x49,0x74,0x28,0x8c,0x10,0xb9,0xc2,0x09,0x70};
1101 static UCHAR ciphertext6[] =
1102 {0x0a,0x94,0x0b,0xb5,0x41,0x6e,0xf0,0x45,0xf1,0xc3,0x94,0x58,0xc6,0x53,0xea,0x5a,
1103 0x95,0x4f,0x64,0xf2,0xe4,0xe8,0x6e,0x9e,0xee,0x82,0xd2,0x02,0x16,0x68,0x48,0x99,
1104 0x95,0x4f,0x64,0xf2,0xe4,0xe8,0x6e,0x9e,0xee,0x82,0xd2,0x02,0x16,0x68,0x48,0x99};
1105 static UCHAR tag[] =
1106 {0x89,0xb3,0x92,0x00,0x39,0x20,0x09,0xb4,0x6a,0xd6,0xaf,0xca,0x4b,0x5b,0xfd,0xd0};
1107 static UCHAR tag2[] =
1108 {0x17,0x9d,0xc0,0x7a,0xf0,0xcf,0xaa,0xd5,0x1c,0x11,0xc4,0x4b,0xd6,0xa3,0x3e,0x77};
1109 BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO auth_info;
1110 BCRYPT_KEY_LENGTHS_STRUCT key_lengths;
1111 BCRYPT_ALG_HANDLE aes;
1112 BCRYPT_KEY_HANDLE key;
1113 UCHAR *buf, plaintext[48], ivbuf[16];
1114 ULONG size, len;
1115 NTSTATUS ret;
1117 ret = pBCryptOpenAlgorithmProvider(&aes, BCRYPT_AES_ALGORITHM, NULL, 0);
1118 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1120 size = 0;
1121 memset(&key_lengths, 0, sizeof(key_lengths));
1122 ret = pBCryptGetProperty(aes, BCRYPT_KEY_LENGTHS, (UCHAR*)&key_lengths, sizeof(key_lengths), &size, 0);
1123 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1124 ok(size == sizeof(key_lengths), "got %u\n", size);
1125 ok(key_lengths.dwMinLength == 128, "Expected 128, got %d\n", key_lengths.dwMinLength);
1126 ok(key_lengths.dwMaxLength == 256, "Expected 256, got %d\n", key_lengths.dwMaxLength);
1127 ok(key_lengths.dwIncrement == 64, "Expected 64, got %d\n", key_lengths.dwIncrement);
1129 /******************
1130 * AES - CBC mode *
1131 ******************/
1133 len = 0xdeadbeef;
1134 size = sizeof(len);
1135 ret = pBCryptGetProperty(aes, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
1136 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1138 key = NULL;
1139 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
1140 ret = pBCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0);
1141 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1142 ok(key != NULL, "key not set\n");
1144 /* input size is a multiple of block size */
1145 size = 0;
1146 memcpy(ivbuf, iv, sizeof(iv));
1147 ret = pBCryptDecrypt(key, ciphertext, 32, NULL, ivbuf, 16, NULL, 0, &size, 0);
1148 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1149 ok(size == 32, "got %u\n", size);
1151 size = 0;
1152 memcpy(ivbuf, iv, sizeof(iv));
1153 memset(plaintext, 0, sizeof(plaintext));
1154 ret = pBCryptDecrypt(key, ciphertext, 32, NULL, ivbuf, 16, plaintext, 32, &size, 0);
1155 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1156 ok(size == 32, "got %u\n", size);
1157 ok(!memcmp(plaintext, expected, sizeof(expected)), "wrong data\n");
1159 /* test with padding smaller than block size */
1160 size = 0;
1161 memcpy(ivbuf, iv, sizeof(iv));
1162 ret = pBCryptDecrypt(key, ciphertext2, 32, NULL, ivbuf, 16, NULL, 0, &size, 0);
1163 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1164 ok(size == 32, "got %u\n", size);
1166 size = 0;
1167 memcpy(ivbuf, iv, sizeof(iv));
1168 memset(plaintext, 0, sizeof(plaintext));
1169 ret = pBCryptDecrypt(key, ciphertext2, 32, NULL, ivbuf, 16, plaintext, 17, &size, BCRYPT_BLOCK_PADDING);
1170 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1171 ok(size == 17, "got %u\n", size);
1172 ok(!memcmp(plaintext, expected2, sizeof(expected2)), "wrong data\n");
1174 /* test with padding of block size */
1175 size = 0;
1176 memcpy(ivbuf, iv, sizeof(iv));
1177 ret = pBCryptDecrypt(key, ciphertext3, 48, NULL, ivbuf, 16, NULL, 0, &size, 0);
1178 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1179 ok(size == 48, "got %u\n", size);
1181 size = 0;
1182 memcpy(ivbuf, iv, sizeof(iv));
1183 memset(plaintext, 0, sizeof(plaintext));
1184 ret = pBCryptDecrypt(key, ciphertext3, 48, NULL, ivbuf, 16, plaintext, 32, &size, BCRYPT_BLOCK_PADDING);
1185 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1186 ok(size == 32, "got %u\n", size);
1187 ok(!memcmp(plaintext, expected3, sizeof(expected3)), "wrong data\n");
1189 /* output size too small */
1190 size = 0;
1191 memcpy(ivbuf, iv, sizeof(iv));
1192 ret = pBCryptDecrypt(key, ciphertext, 32, NULL, ivbuf, 16, plaintext, 31, &size, 0);
1193 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
1194 ok(size == 32, "got %u\n", size);
1196 size = 0;
1197 memcpy(ivbuf, iv, sizeof(iv));
1198 ret = pBCryptDecrypt(key, ciphertext2, 32, NULL, ivbuf, 16, plaintext, 15, &size, BCRYPT_BLOCK_PADDING);
1199 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
1200 ok(size == 32, "got %u\n", size);
1202 size = 0;
1203 memcpy(ivbuf, iv, sizeof(iv));
1204 ret = pBCryptDecrypt(key, ciphertext2, 32, NULL, ivbuf, 16, plaintext, 16, &size, BCRYPT_BLOCK_PADDING);
1205 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
1206 ok(size == 17, "got %u\n", size);
1208 size = 0;
1209 memcpy(ivbuf, iv, sizeof(iv));
1210 ret = pBCryptDecrypt(key, ciphertext3, 48, NULL, ivbuf, 16, plaintext, 31, &size, BCRYPT_BLOCK_PADDING);
1211 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
1212 ok(size == 48, "got %u\n", size);
1214 /* input size is not a multiple of block size */
1215 size = 0;
1216 memcpy(ivbuf, iv, sizeof(iv));
1217 ret = pBCryptDecrypt(key, ciphertext, 17, NULL, ivbuf, 16, NULL, 0, &size, 0);
1218 ok(ret == STATUS_INVALID_BUFFER_SIZE, "got %08x\n", ret);
1219 ok(size == 17 || broken(size == 0 /* Win < 7 */), "got %u\n", size);
1221 /* input size is not a multiple of block size, block padding set */
1222 size = 0;
1223 memcpy(ivbuf, iv, sizeof(iv));
1224 ret = pBCryptDecrypt(key, ciphertext, 17, NULL, ivbuf, 16, NULL, 0, &size, BCRYPT_BLOCK_PADDING);
1225 ok(ret == STATUS_INVALID_BUFFER_SIZE, "got %08x\n", ret);
1226 ok(size == 17 || broken(size == 0 /* Win < 7 */), "got %u\n", size);
1228 ret = pBCryptDestroyKey(key);
1229 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1230 HeapFree(GetProcessHeap(), 0, buf);
1232 /******************
1233 * AES - GCM mode *
1234 ******************/
1236 ret = pBCryptSetProperty(aes, BCRYPT_CHAINING_MODE, (UCHAR*)BCRYPT_CHAIN_MODE_GCM, sizeof(BCRYPT_CHAIN_MODE_GCM), 0);
1237 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1239 key = NULL;
1240 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
1241 ret = pBCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0);
1242 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1243 ok(key != NULL, "key not set\n");
1245 memset(&auth_info, 0, sizeof(auth_info));
1246 auth_info.cbSize = sizeof(auth_info);
1247 auth_info.dwInfoVersion = 1;
1248 auth_info.pbNonce = nonce;
1249 auth_info.cbNonce = sizeof(nonce);
1250 auth_info.pbTag = tag;
1251 auth_info.cbTag = sizeof(tag);
1253 /* input size is a multiple of block size */
1254 size = 0;
1255 memcpy(ivbuf, iv, sizeof(iv));
1256 memset(plaintext, 0, sizeof(plaintext));
1257 ret = pBCryptDecrypt(key, ciphertext4, 32, &auth_info, ivbuf, 16, plaintext, 32, &size, 0);
1258 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1259 ok(size == 32, "got %u\n", size);
1260 ok(!memcmp(plaintext, expected3, sizeof(expected3)), "wrong data\n");
1262 /* test with auth data */
1263 auth_info.pbAuthData = auth_data;
1264 auth_info.cbAuthData = sizeof(auth_data);
1265 auth_info.pbTag = tag2;
1266 auth_info.cbTag = sizeof(tag2);
1268 size = 0;
1269 memcpy(ivbuf, iv, sizeof(iv));
1270 memset(plaintext, 0, sizeof(plaintext));
1271 ret = pBCryptDecrypt(key, ciphertext4, 32, &auth_info, ivbuf, 16, plaintext, 32, &size, 0);
1272 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1273 ok(size == 32, "got %u\n", size);
1274 ok(!memcmp(plaintext, expected3, sizeof(expected3)), "wrong data\n");
1276 /* test with wrong tag */
1277 memcpy(ivbuf, iv, sizeof(iv));
1278 auth_info.pbTag = iv; /* wrong tag */
1279 ret = pBCryptDecrypt(key, ciphertext4, 32, &auth_info, ivbuf, 16, plaintext, 32, &size, 0);
1280 ok(ret == STATUS_AUTH_TAG_MISMATCH, "got %08x\n", ret);
1281 ok(size == 32, "got %u\n", size);
1283 ret = pBCryptDestroyKey(key);
1284 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1285 HeapFree(GetProcessHeap(), 0, buf);
1287 /******************
1288 * AES - ECB mode *
1289 ******************/
1291 ret = pBCryptSetProperty(aes, BCRYPT_CHAINING_MODE, (UCHAR*)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0);
1292 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1294 len = 0xdeadbeef;
1295 size = sizeof(len);
1296 ret = pBCryptGetProperty(aes, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
1297 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1299 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
1300 ret = pBCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0);
1301 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1303 /* initialization vector is not allowed */
1304 size = 0;
1305 memcpy(ivbuf, iv, sizeof(iv));
1306 ret = pBCryptDecrypt(key, ciphertext5, 32, NULL, ivbuf, 16, plaintext, 32, &size, 0);
1307 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
1308 ok(size == 32, "got %u\n", size);
1310 /* input size is a multiple of block size */
1311 size = 0;
1312 ret = pBCryptDecrypt(key, ciphertext5, 32, NULL, NULL, 16, NULL, 0, &size, 0);
1313 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1314 ok(size == 32, "got %u\n", size);
1316 size = 0;
1317 memset(plaintext, 0, sizeof(plaintext));
1318 ret = pBCryptDecrypt(key, ciphertext5, 32, NULL, NULL, 16, plaintext, 32, &size, 0);
1319 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1320 ok(size == 32, "got %u\n", size);
1321 ok(!memcmp(plaintext, expected, sizeof(expected)), "wrong data\n");
1323 /* test with padding smaller than block size */
1324 size = 0;
1325 ret = pBCryptDecrypt(key, ciphertext5, 32, NULL, NULL, 16, NULL, 0, &size, 0);
1326 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1327 ok(size == 32, "got %u\n", size);
1329 size = 0;
1330 memset(plaintext, 0, sizeof(plaintext));
1331 ret = pBCryptDecrypt(key, ciphertext5, 32, NULL, NULL, 16, plaintext, 17, &size, BCRYPT_BLOCK_PADDING);
1332 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1333 ok(size == 17, "got %u\n", size);
1334 ok(!memcmp(plaintext, expected2, sizeof(expected2)), "wrong data\n");
1336 /* test with padding of block size */
1337 size = 0;
1338 ret = pBCryptDecrypt(key, ciphertext6, 48, NULL, NULL, 16, NULL, 0, &size, 0);
1339 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1340 ok(size == 48, "got %u\n", size);
1342 size = 0;
1343 memset(plaintext, 0, sizeof(plaintext));
1344 ret = pBCryptDecrypt(key, ciphertext6, 48, NULL, NULL, 16, plaintext, 32, &size, BCRYPT_BLOCK_PADDING);
1345 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1346 ok(size == 32, "got %u\n", size);
1347 ok(!memcmp(plaintext, expected3, sizeof(expected3)), "wrong data\n");
1349 /* output size too small */
1350 size = 0;
1351 ret = pBCryptDecrypt(key, ciphertext4, 32, NULL, NULL, 16, plaintext, 31, &size, 0);
1352 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
1353 ok(size == 32, "got %u\n", size);
1355 size = 0;
1356 ret = pBCryptDecrypt(key, ciphertext5, 32, NULL, NULL, 16, plaintext, 15, &size, BCRYPT_BLOCK_PADDING);
1357 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
1358 ok(size == 32, "got %u\n", size);
1360 size = 0;
1361 ret = pBCryptDecrypt(key, ciphertext5, 32, NULL, NULL, 16, plaintext, 16, &size, BCRYPT_BLOCK_PADDING);
1362 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
1363 ok(size == 17, "got %u\n", size);
1365 size = 0;
1366 ret = pBCryptDecrypt(key, ciphertext6, 48, NULL, NULL, 16, plaintext, 31, &size, BCRYPT_BLOCK_PADDING);
1367 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
1368 ok(size == 48, "got %u\n", size);
1370 /* input size is not a multiple of block size */
1371 size = 0;
1372 ret = pBCryptDecrypt(key, ciphertext4, 17, NULL, NULL, 16, NULL, 0, &size, 0);
1373 ok(ret == STATUS_INVALID_BUFFER_SIZE, "got %08x\n", ret);
1374 ok(size == 17 || broken(size == 0 /* Win < 7 */), "got %u\n", size);
1376 /* input size is not a multiple of block size, block padding set */
1377 size = 0;
1378 ret = pBCryptDecrypt(key, ciphertext4, 17, NULL, NULL, 16, NULL, 0, &size, BCRYPT_BLOCK_PADDING);
1379 ok(ret == STATUS_INVALID_BUFFER_SIZE, "got %08x\n", ret);
1380 ok(size == 17 || broken(size == 0 /* Win < 7 */), "got %u\n", size);
1382 ret = pBCryptDestroyKey(key);
1383 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1385 ret = pBCryptDestroyKey(key);
1386 ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret);
1387 HeapFree(GetProcessHeap(), 0, buf);
1389 ret = pBCryptCloseAlgorithmProvider(aes, 0);
1390 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1393 static void test_key_import_export(void)
1395 UCHAR buffer1[sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + 16];
1396 UCHAR buffer2[sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + 16];
1397 BCRYPT_KEY_DATA_BLOB_HEADER *key_data1 = (void*)buffer1;
1398 BCRYPT_ALG_HANDLE aes;
1399 BCRYPT_KEY_HANDLE key;
1400 NTSTATUS ret;
1401 ULONG size;
1403 ret = pBCryptOpenAlgorithmProvider(&aes, BCRYPT_AES_ALGORITHM, NULL, 0);
1404 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1406 key_data1->dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC;
1407 key_data1->dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1;
1408 key_data1->cbKeyData = 16;
1409 memset(&key_data1[1], 0x11, 16);
1411 ret = pBCryptImportKey(aes, NULL, BCRYPT_KEY_DATA_BLOB, &key, NULL, 0, buffer1, sizeof(buffer1), 0);
1412 ok(ret == STATUS_SUCCESS || broken(ret == STATUS_INVALID_PARAMETER) /* vista */, "got %08x\n", ret);
1413 if (ret == STATUS_INVALID_PARAMETER)
1415 win_skip("broken BCryptImportKey\n");
1416 return;
1419 size = 0;
1420 ret = pBCryptExportKey(key, NULL, BCRYPT_KEY_DATA_BLOB, buffer2, 1, &size, 0);
1421 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
1422 ok(size == sizeof(buffer2), "Got %u\n", size);
1424 size = 0;
1425 memset(buffer2, 0xff, sizeof(buffer2));
1426 ret = pBCryptExportKey(key, NULL, BCRYPT_KEY_DATA_BLOB, buffer2, sizeof(buffer2), &size, 0);
1427 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1428 ok(size == sizeof(buffer2), "Got %u\n", size);
1429 ok(!memcmp(buffer1, buffer2, sizeof(buffer1)), "Expected exported key to match imported key\n");
1431 ret = pBCryptDestroyKey(key);
1432 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1434 ret = pBCryptCloseAlgorithmProvider(aes, 0);
1435 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
1438 static BYTE eccPubkey[] =
1440 /* X */
1441 0x3b, 0x3c, 0x34, 0xc8, 0x3f, 0x15, 0xea, 0x02, 0x68, 0x46, 0x69, 0xdf, 0x0c, 0xa6, 0xee, 0x7a,
1442 0xd9, 0x82, 0x08, 0x9b, 0x37, 0x53, 0x42, 0xf3, 0x13, 0x63, 0xda, 0x65, 0x79, 0xe8, 0x04, 0x9e,
1443 /* Y */
1444 0x8c, 0x77, 0xc4, 0x33, 0x77, 0xd9, 0x5a, 0x7f, 0x60, 0x7b, 0x98, 0xce, 0xf3, 0x96, 0x56, 0xd6,
1445 0xb5, 0x8d, 0x87, 0x7a, 0x00, 0x2b, 0xf3, 0x70, 0xb3, 0x90, 0x73, 0xa0, 0x56, 0x06, 0x3b, 0x22,
1447 static BYTE certHash[] =
1449 0x28, 0x19, 0x0f, 0x15, 0x6d, 0x75, 0xcc, 0xcf, 0x62, 0xf1, 0x5e, 0xe6, 0x8a, 0xc3, 0xf0, 0x5d,
1450 0x89, 0x28, 0x2d, 0x48, 0xd8, 0x73, 0x7c, 0x05, 0x05, 0x8e, 0xbc, 0xce, 0x28, 0xb7, 0xba, 0xc9,
1452 static BYTE certSignature[] =
1454 /* r */
1455 0xd7, 0x29, 0xce, 0x5a, 0xef, 0x74, 0x85, 0xd1, 0x18, 0x5f, 0x6e, 0xf1, 0xba, 0x53, 0xd4, 0xcd,
1456 0xdd, 0xe0, 0x5d, 0xf1, 0x5e, 0x48, 0x51, 0xea, 0x63, 0xc0, 0xe8, 0xe2, 0xf6, 0xfa, 0x4c, 0xaf,
1457 /* s */
1458 0xe3, 0x94, 0x15, 0x3b, 0x6c, 0x71, 0x6e, 0x44, 0x22, 0xcb, 0xa0, 0x88, 0xcd, 0x0a, 0x5a, 0x50,
1459 0x29, 0x7c, 0x5c, 0xd6, 0x6c, 0xd2, 0xe0, 0x7f, 0xcd, 0x02, 0x92, 0x21, 0x4c, 0x2c, 0x92, 0xee,
1462 static void test_ECDSA(void)
1464 BYTE buffer[sizeof(BCRYPT_ECCKEY_BLOB) + sizeof(eccPubkey)];
1465 BCRYPT_ECCKEY_BLOB *ecckey = (void *)buffer;
1466 BCRYPT_ALG_HANDLE alg = NULL;
1467 BCRYPT_KEY_HANDLE key = NULL;
1468 NTSTATUS status;
1470 status = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_ECDSA_P256_ALGORITHM, NULL, 0);
1471 if (status)
1473 skip("Failed to open ECDSA provider: %08x, skipping test\n", status);
1474 return;
1477 ecckey->dwMagic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
1478 memcpy(ecckey + 1, eccPubkey, sizeof(eccPubkey));
1480 ecckey->cbKey = 2;
1481 status = pBCryptImportKeyPair(alg, NULL, BCRYPT_ECCPUBLIC_BLOB, &key, buffer, sizeof(buffer), 0);
1482 ok(status == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %08x\n", status);
1484 ecckey->cbKey = sizeof(eccPubkey) / 2;
1485 status = pBCryptImportKeyPair(alg, NULL, BCRYPT_ECCPUBLIC_BLOB, &key, buffer, sizeof(buffer), 0);
1486 ok(!status, "BCryptImportKeyPair failed: %08x\n", status);
1488 status = pBCryptVerifySignature(key, NULL, certHash, sizeof(certHash) - 1, certSignature, sizeof(certSignature), 0);
1489 ok(status == STATUS_INVALID_SIGNATURE, "Expected STATUS_INVALID_SIGNATURE, got %08x\n", status);
1491 status = pBCryptVerifySignature(key, NULL, certHash, sizeof(certHash), certSignature, sizeof(certSignature), 0);
1492 ok(!status, "BCryptVerifySignature failed: %08x\n", status);
1494 pBCryptDestroyKey(key);
1495 pBCryptCloseAlgorithmProvider(alg, 0);
1498 START_TEST(bcrypt)
1500 HMODULE module;
1502 module = LoadLibraryA("bcrypt.dll");
1503 if (!module)
1505 win_skip("bcrypt.dll not found\n");
1506 return;
1509 pBCryptOpenAlgorithmProvider = (void *)GetProcAddress(module, "BCryptOpenAlgorithmProvider");
1510 pBCryptCloseAlgorithmProvider = (void *)GetProcAddress(module, "BCryptCloseAlgorithmProvider");
1511 pBCryptGetFipsAlgorithmMode = (void *)GetProcAddress(module, "BCryptGetFipsAlgorithmMode");
1512 pBCryptCreateHash = (void *)GetProcAddress(module, "BCryptCreateHash");
1513 pBCryptHash = (void *)GetProcAddress(module, "BCryptHash");
1514 pBCryptHashData = (void *)GetProcAddress(module, "BCryptHashData");
1515 pBCryptDuplicateHash = (void *)GetProcAddress(module, "BCryptDuplicateHash");
1516 pBCryptFinishHash = (void *)GetProcAddress(module, "BCryptFinishHash");
1517 pBCryptDestroyHash = (void *)GetProcAddress(module, "BCryptDestroyHash");
1518 pBCryptGenRandom = (void *)GetProcAddress(module, "BCryptGenRandom");
1519 pBCryptGetProperty = (void *)GetProcAddress(module, "BCryptGetProperty");
1520 pBCryptSetProperty = (void *)GetProcAddress(module, "BCryptSetProperty");
1521 pBCryptGenerateSymmetricKey = (void *)GetProcAddress(module, "BCryptGenerateSymmetricKey");
1522 pBCryptEncrypt = (void *)GetProcAddress(module, "BCryptEncrypt");
1523 pBCryptDecrypt = (void *)GetProcAddress(module, "BCryptDecrypt");
1524 pBCryptDuplicateKey = (void *)GetProcAddress(module, "BCryptDuplicateKey");
1525 pBCryptDestroyKey = (void *)GetProcAddress(module, "BCryptDestroyKey");
1526 pBCryptImportKey = (void *)GetProcAddress(module, "BCryptImportKey");
1527 pBCryptExportKey = (void *)GetProcAddress(module, "BCryptExportKey");
1528 pBCryptImportKeyPair = (void *)GetProcAddress(module, "BCryptImportKeyPair");
1529 pBCryptVerifySignature = (void *)GetProcAddress(module, "BCryptVerifySignature");
1531 test_BCryptGenRandom();
1532 test_BCryptGetFipsAlgorithmMode();
1533 test_hashes();
1534 test_rng();
1535 test_aes();
1536 test_BCryptGenerateSymmetricKey();
1537 test_BCryptEncrypt();
1538 test_BCryptDecrypt();
1539 test_key_import_export();
1540 test_ECDSA();
1542 if (pBCryptHash) /* >= Win 10 */
1543 test_BcryptHash();
1544 else
1545 win_skip("BCryptHash is not available\n");
1547 FreeLibrary(module);