winex11.drv: Correct sizes in COMPOSITIONSTRING structure when updating fields.
[wine.git] / dlls / bcrypt / tests / bcrypt.c
blob9bd2cea9e3bbde96c3b574ccfaa3cb2a1bc894ce
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 *pBCryptHash)( BCRYPT_ALG_HANDLE algorithm, UCHAR *secret, ULONG secretlen,
30 UCHAR *input, ULONG inputlen, UCHAR *output, ULONG outputlen );
32 static void test_BCryptGenRandom(void)
34 NTSTATUS ret;
35 UCHAR buffer[256];
37 ret = BCryptGenRandom(NULL, NULL, 0, 0);
38 ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got 0x%x\n", ret);
39 ret = BCryptGenRandom(NULL, buffer, 0, 0);
40 ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got 0x%x\n", ret);
41 ret = BCryptGenRandom(NULL, buffer, sizeof(buffer), 0);
42 ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got 0x%x\n", ret);
43 ret = BCryptGenRandom(NULL, buffer, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
44 ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret);
45 ret = BCryptGenRandom(NULL, buffer, sizeof(buffer),
46 BCRYPT_USE_SYSTEM_PREFERRED_RNG|BCRYPT_RNG_USE_ENTROPY_IN_BUFFER);
47 ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret);
48 ret = BCryptGenRandom(NULL, NULL, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
49 ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got 0x%x\n", ret);
51 /* Zero sized buffer should work too */
52 ret = BCryptGenRandom(NULL, buffer, 0, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
53 ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret);
55 /* Test random number generation - It's impossible for a sane RNG to return 8 zeros */
56 memset(buffer, 0, 16);
57 ret = BCryptGenRandom(NULL, buffer, 8, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
58 ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret);
59 ok(memcmp(buffer, buffer + 8, 8), "Expected a random number, got 0\n");
62 static void test_BCryptGetFipsAlgorithmMode(void)
64 NTSTATUS ret;
65 BOOLEAN enabled;
67 ret = BCryptGetFipsAlgorithmMode(&enabled);
68 ok(ret == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got 0x%x\n", ret);
70 ret = BCryptGetFipsAlgorithmMode(NULL);
71 ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got 0x%x\n", ret);
74 static void format_hash(const UCHAR *bytes, ULONG size, char *buf)
76 ULONG i;
77 buf[0] = '\0';
78 for (i = 0; i < size; i++)
80 sprintf(buf + i * 2, "%02x", bytes[i]);
82 return;
85 static int strcmp_wa(const WCHAR *strw, const char *stra)
87 WCHAR buf[512];
88 MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, sizeof(buf)/sizeof(buf[0]));
89 return lstrcmpW(strw, buf);
92 #define test_hash_length(a,b) _test_hash_length(__LINE__,a,b)
93 static void _test_hash_length(unsigned line, void *handle, ULONG exlen)
95 ULONG len = 0xdeadbeef, size = 0xdeadbeef;
96 NTSTATUS status;
98 status = BCryptGetProperty(handle, BCRYPT_HASH_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
99 ok_(__FILE__,line)(status == STATUS_SUCCESS, "BCryptGetProperty failed: %08x\n", status);
100 ok_(__FILE__,line)(size == sizeof(len), "got %u\n", size);
101 ok_(__FILE__,line)(len == exlen, "len = %u, expected %u\n", len, exlen);
104 #define test_alg_name(a,b) _test_alg_name(__LINE__,a,b)
105 static void _test_alg_name(unsigned line, void *handle, const char *exname)
107 ULONG size = 0xdeadbeef;
108 UCHAR buf[256];
109 const WCHAR *name = (const WCHAR*)buf;
110 NTSTATUS status;
112 status = BCryptGetProperty(handle, BCRYPT_ALGORITHM_NAME, buf, sizeof(buf), &size, 0);
113 ok_(__FILE__,line)(status == STATUS_SUCCESS, "BCryptGetProperty failed: %08x\n", status);
114 ok_(__FILE__,line)(size == (strlen(exname)+1)*sizeof(WCHAR), "got %u\n", size);
115 ok_(__FILE__,line)(!strcmp_wa(name, exname), "alg name = %s, expected %s\n", wine_dbgstr_w(name), exname);
118 static void test_sha1(void)
120 static const char expected[] = "961fa64958818f767707072755d7018dcd278e94";
121 static const char expected_hmac[] = "2472cf65d0e090618d769d3e46f0d9446cf212da";
122 BCRYPT_ALG_HANDLE alg;
123 BCRYPT_HASH_HANDLE hash;
124 UCHAR buf[512], buf_hmac[1024], sha1[20], sha1_hmac[20];
125 ULONG size, len;
126 char str[41];
127 NTSTATUS ret;
129 alg = NULL;
130 ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
131 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
132 ok(alg != NULL, "alg not set\n");
134 len = size = 0xdeadbeef;
135 ret = BCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
136 ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret);
138 len = size = 0xdeadbeef;
139 ret = BCryptGetProperty(alg, NULL, (UCHAR *)&len, sizeof(len), &size, 0);
140 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
142 len = size = 0xdeadbeef;
143 ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0);
144 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
146 len = size = 0xdeadbeef;
147 ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0);
148 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
149 ok(size == sizeof(len), "got %u\n", size);
151 len = size = 0xdeadbeef;
152 ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0);
153 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
154 ok(len == 0xdeadbeef, "got %u\n", len);
155 ok(size == sizeof(len), "got %u\n", size);
157 len = size = 0xdeadbeef;
158 ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len , sizeof(len), &size, 0);
159 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
160 ok(len != 0xdeadbeef, "len not set\n");
161 ok(size == sizeof(len), "got %u\n", size);
163 test_hash_length(alg, 20);
164 test_alg_name(alg, "SHA1");
166 hash = NULL;
167 len = sizeof(buf);
168 ret = BCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0);
169 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
170 ok(hash != NULL, "hash not set\n");
172 ret = BCryptHashData(hash, NULL, 0, 0);
173 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
175 ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
176 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
178 test_hash_length(hash, 20);
179 test_alg_name(hash, "SHA1");
181 memset(sha1, 0, sizeof(sha1));
182 ret = BCryptFinishHash(hash, sha1, sizeof(sha1), 0);
183 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
184 format_hash( sha1, sizeof(sha1), str );
185 ok(!strcmp(str, expected), "got %s\n", str);
187 ret = BCryptDestroyHash(hash);
188 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
190 ret = BCryptCloseAlgorithmProvider(alg, 0);
191 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
193 alg = NULL;
194 ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
195 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
196 ok(alg != NULL, "alg not set\n");
198 hash = NULL;
199 len = sizeof(buf_hmac);
200 ret = BCryptCreateHash(alg, &hash, buf_hmac, len, (UCHAR *)"key", sizeof("key"), 0);
201 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
202 ok(hash != NULL, "hash not set\n");
204 ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
205 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
207 test_hash_length(hash, 20);
208 test_alg_name(hash, "SHA1");
210 memset(sha1_hmac, 0, sizeof(sha1_hmac));
211 ret = BCryptFinishHash(hash, sha1_hmac, sizeof(sha1_hmac), 0);
212 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
213 format_hash( sha1_hmac, sizeof(sha1_hmac), str );
214 ok(!strcmp(str, expected_hmac), "got %s\n", str);
216 ret = BCryptDestroyHash(hash);
217 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
219 ret = BCryptCloseAlgorithmProvider(alg, 0);
220 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
223 static void test_sha256(void)
225 static const char expected[] =
226 "ceb73749c899693706ede1e30c9929b3fd5dd926163831c2fb8bd41e6efb1126";
227 static const char expected_hmac[] =
228 "34c1aa473a4468a91d06e7cdbc75bc4f93b830ccfc2a47ffd74e8e6ed29e4c72";
229 BCRYPT_ALG_HANDLE alg;
230 BCRYPT_HASH_HANDLE hash;
231 UCHAR buf[512], buf_hmac[1024], sha256[32], sha256_hmac[32];
232 ULONG size, len;
233 char str[65];
234 NTSTATUS ret;
236 alg = NULL;
237 ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA256_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
238 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
239 ok(alg != NULL, "alg not set\n");
241 len = size = 0xdeadbeef;
242 ret = BCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
243 ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret);
245 len = size = 0xdeadbeef;
246 ret = BCryptGetProperty(alg, NULL, (UCHAR *)&len, sizeof(len), &size, 0);
247 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
249 len = size = 0xdeadbeef;
250 ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0);
251 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
253 len = size = 0xdeadbeef;
254 ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0);
255 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
256 ok(size == sizeof(len), "got %u\n", size);
258 len = size = 0xdeadbeef;
259 ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0);
260 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
261 ok(len == 0xdeadbeef, "got %u\n", len);
262 ok(size == sizeof(len), "got %u\n", size);
264 len = size = 0xdeadbeef;
265 ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len , sizeof(len), &size, 0);
266 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
267 ok(len != 0xdeadbeef, "len not set\n");
268 ok(size == sizeof(len), "got %u\n", size);
270 test_hash_length(alg, 32);
271 test_alg_name(alg, "SHA256");
273 hash = NULL;
274 len = sizeof(buf);
275 ret = BCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0);
276 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
277 ok(hash != NULL, "hash not set\n");
279 ret = BCryptHashData(hash, NULL, 0, 0);
280 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
282 ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
283 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
285 test_hash_length(hash, 32);
286 test_alg_name(hash, "SHA256");
288 memset(sha256, 0, sizeof(sha256));
289 ret = BCryptFinishHash(hash, sha256, sizeof(sha256), 0);
290 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
291 format_hash( sha256, sizeof(sha256), str );
292 ok(!strcmp(str, expected), "got %s\n", str);
294 ret = BCryptDestroyHash(hash);
295 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
297 ret = BCryptCloseAlgorithmProvider(alg, 0);
298 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
300 alg = NULL;
301 ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA256_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
302 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
303 ok(alg != NULL, "alg not set\n");
305 hash = NULL;
306 len = sizeof(buf_hmac);
307 ret = BCryptCreateHash(alg, &hash, buf_hmac, len, (UCHAR *)"key", sizeof("key"), 0);
308 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
309 ok(hash != NULL, "hash not set\n");
311 ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
312 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
314 test_hash_length(hash, 32);
315 test_alg_name(hash, "SHA256");
317 memset(sha256_hmac, 0, sizeof(sha256_hmac));
318 ret = BCryptFinishHash(hash, sha256_hmac, sizeof(sha256_hmac), 0);
319 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
320 format_hash( sha256_hmac, sizeof(sha256_hmac), str );
321 ok(!strcmp(str, expected_hmac), "got %s\n", str);
323 ret = BCryptDestroyHash(hash);
324 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
326 ret = BCryptCloseAlgorithmProvider(alg, 0);
327 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
330 static void test_sha384(void)
332 static const char expected[] =
333 "62b21e90c9022b101671ba1f808f8631a8149f0f12904055839a35c1ca78ae5363eed1e743a692d70e0504b0cfd12ef9";
334 static const char expected_hmac[] =
335 "4b3e6d6ff2da121790ab7e7b9247583e3a7eed2db5bd4dabc680303b1608f37dfdc836d96a704c03283bc05b4f6c5eb8";
336 BCRYPT_ALG_HANDLE alg;
337 BCRYPT_HASH_HANDLE hash;
338 UCHAR buf[512], buf_hmac[1024], sha384[48], sha384_hmac[48];
339 ULONG size, len;
340 char str[97];
341 NTSTATUS ret;
343 alg = NULL;
344 ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA384_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
345 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
346 ok(alg != NULL, "alg not set\n");
348 len = size = 0xdeadbeef;
349 ret = BCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
350 ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret);
352 len = size = 0xdeadbeef;
353 ret = BCryptGetProperty(alg, NULL, (UCHAR *)&len, sizeof(len), &size, 0);
354 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
356 len = size = 0xdeadbeef;
357 ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0);
358 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
360 len = size = 0xdeadbeef;
361 ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0);
362 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
363 ok(size == sizeof(len), "got %u\n", size);
365 len = size = 0xdeadbeef;
366 ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0);
367 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
368 ok(len == 0xdeadbeef, "got %u\n", len);
369 ok(size == sizeof(len), "got %u\n", size);
371 len = size = 0xdeadbeef;
372 ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len , sizeof(len), &size, 0);
373 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
374 ok(len != 0xdeadbeef, "len not set\n");
375 ok(size == sizeof(len), "got %u\n", size);
377 test_hash_length(alg, 48);
378 test_alg_name(alg, "SHA384");
380 hash = NULL;
381 len = sizeof(buf);
382 ret = BCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0);
383 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
384 ok(hash != NULL, "hash not set\n");
386 ret = BCryptHashData(hash, NULL, 0, 0);
387 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
389 ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
390 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
392 test_hash_length(hash, 48);
393 test_alg_name(hash, "SHA384");
395 memset(sha384, 0, sizeof(sha384));
396 ret = BCryptFinishHash(hash, sha384, sizeof(sha384), 0);
397 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
398 format_hash( sha384, sizeof(sha384), str );
399 ok(!strcmp(str, expected), "got %s\n", str);
401 ret = BCryptDestroyHash(hash);
402 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
404 ret = BCryptCloseAlgorithmProvider(alg, 0);
405 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
407 alg = NULL;
408 ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA384_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
409 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
410 ok(alg != NULL, "alg not set\n");
412 hash = NULL;
413 len = sizeof(buf_hmac);
414 ret = BCryptCreateHash(alg, &hash, buf_hmac, len, (UCHAR *)"key", sizeof("key"), 0);
415 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
416 ok(hash != NULL, "hash not set\n");
418 ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
419 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
421 test_hash_length(hash, 48);
422 test_alg_name(hash, "SHA384");
424 memset(sha384_hmac, 0, sizeof(sha384_hmac));
425 ret = BCryptFinishHash(hash, sha384_hmac, sizeof(sha384_hmac), 0);
426 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
427 format_hash( sha384_hmac, sizeof(sha384_hmac), str );
428 ok(!strcmp(str, expected_hmac), "got %s\n", str);
430 ret = BCryptDestroyHash(hash);
431 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
433 ret = BCryptCloseAlgorithmProvider(alg, 0);
434 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
437 static void test_sha512(void)
439 static const char expected[] =
440 "d55ced17163bf5386f2cd9ff21d6fd7fe576a915065c24744d09cfae4ec84ee1e"
441 "f6ef11bfbc5acce3639bab725b50a1fe2c204f8c820d6d7db0df0ecbc49c5ca";
442 static const char expected_hmac[] =
443 "415fb6b10018ca03b38a1b1399c42ac0be5e8aceddb9a73103f5e543bf2d888f2"
444 "eecf91373941f9315dd730a77937fa92444450fbece86f409d9cb5ec48c6513";
445 BCRYPT_ALG_HANDLE alg;
446 BCRYPT_HASH_HANDLE hash;
447 UCHAR buf[512], buf_hmac[1024], sha512[64], sha512_hmac[64];
448 ULONG size, len;
449 char str[129];
450 NTSTATUS ret;
452 alg = NULL;
453 ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA512_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
454 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
455 ok(alg != NULL, "alg not set\n");
457 len = size = 0xdeadbeef;
458 ret = BCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
459 ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret);
461 len = size = 0xdeadbeef;
462 ret = BCryptGetProperty(alg, NULL, (UCHAR *)&len, sizeof(len), &size, 0);
463 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
465 len = size = 0xdeadbeef;
466 ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0);
467 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
469 len = size = 0xdeadbeef;
470 ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0);
471 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
472 ok(size == sizeof(len), "got %u\n", size);
474 len = size = 0xdeadbeef;
475 ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0);
476 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
477 ok(len == 0xdeadbeef, "got %u\n", len);
478 ok(size == sizeof(len), "got %u\n", size);
480 len = size = 0xdeadbeef;
481 ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len , sizeof(len), &size, 0);
482 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
483 ok(len != 0xdeadbeef, "len not set\n");
484 ok(size == sizeof(len), "got %u\n", size);
486 test_hash_length(alg, 64);
487 test_alg_name(alg, "SHA512");
489 hash = NULL;
490 len = sizeof(buf);
491 ret = BCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0);
492 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
493 ok(hash != NULL, "hash not set\n");
495 ret = BCryptHashData(hash, NULL, 0, 0);
496 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
498 ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
499 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
501 test_hash_length(hash, 64);
502 test_alg_name(hash, "SHA512");
504 memset(sha512, 0, sizeof(sha512));
505 ret = BCryptFinishHash(hash, sha512, sizeof(sha512), 0);
506 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
507 format_hash( sha512, sizeof(sha512), str );
508 ok(!strcmp(str, expected), "got %s\n", str);
510 ret = BCryptDestroyHash(hash);
511 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
513 ret = BCryptCloseAlgorithmProvider(alg, 0);
514 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
516 alg = NULL;
517 ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA512_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
518 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
519 ok(alg != NULL, "alg not set\n");
521 hash = NULL;
522 len = sizeof(buf_hmac);
523 ret = BCryptCreateHash(alg, &hash, buf_hmac, len, (UCHAR *)"key", sizeof("key"), 0);
524 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
525 ok(hash != NULL, "hash not set\n");
527 ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
528 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
530 test_hash_length(hash, 64);
531 test_alg_name(hash, "SHA512");
533 memset(sha512_hmac, 0, sizeof(sha512_hmac));
534 ret = BCryptFinishHash(hash, sha512_hmac, sizeof(sha512_hmac), 0);
535 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
536 format_hash( sha512_hmac, sizeof(sha512_hmac), str );
537 ok(!strcmp(str, expected_hmac), "got %s\n", str);
539 ret = BCryptDestroyHash(hash);
540 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
542 ret = BCryptCloseAlgorithmProvider(alg, 0);
543 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
547 static void test_md5(void)
549 static const char expected[] =
550 "e2a3e68d23ce348b8f68b3079de3d4c9";
551 static const char expected_hmac[] =
552 "7bda029b93fa8d817fcc9e13d6bdf092";
553 BCRYPT_ALG_HANDLE alg;
554 BCRYPT_HASH_HANDLE hash;
555 UCHAR buf[512], buf_hmac[1024], md5[16], md5_hmac[16];
556 ULONG size, len;
557 char str[65];
558 NTSTATUS ret;
560 alg = NULL;
561 ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_MD5_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
562 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
563 ok(alg != NULL, "alg not set\n");
565 len = size = 0xdeadbeef;
566 ret = BCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
567 ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret);
569 len = size = 0xdeadbeef;
570 ret = BCryptGetProperty(alg, NULL, (UCHAR *)&len, sizeof(len), &size, 0);
571 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
573 len = size = 0xdeadbeef;
574 ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0);
575 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
577 len = size = 0xdeadbeef;
578 ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0);
579 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
580 ok(size == sizeof(len), "got %u\n", size);
582 len = size = 0xdeadbeef;
583 ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0);
584 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
585 ok(len == 0xdeadbeef, "got %u\n", len);
586 ok(size == sizeof(len), "got %u\n", size);
588 len = size = 0xdeadbeef;
589 ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len , sizeof(len), &size, 0);
590 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
591 ok(len != 0xdeadbeef, "len not set\n");
592 ok(size == sizeof(len), "got %u\n", size);
594 test_hash_length(alg, 16);
595 test_alg_name(alg, "MD5");
597 hash = NULL;
598 len = sizeof(buf);
599 ret = BCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0);
600 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
601 ok(hash != NULL, "hash not set\n");
603 ret = BCryptHashData(hash, NULL, 0, 0);
604 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
606 ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
607 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
609 test_hash_length(hash, 16);
610 test_alg_name(hash, "MD5");
612 memset(md5, 0, sizeof(md5));
613 ret = BCryptFinishHash(hash, md5, sizeof(md5), 0);
614 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
615 format_hash( md5, sizeof(md5), str );
616 ok(!strcmp(str, expected), "got %s\n", str);
618 ret = BCryptDestroyHash(hash);
619 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
621 ret = BCryptCloseAlgorithmProvider(alg, 0);
622 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
624 alg = NULL;
625 ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_MD5_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
626 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
627 ok(alg != NULL, "alg not set\n");
629 hash = NULL;
630 len = sizeof(buf_hmac);
631 ret = BCryptCreateHash(alg, &hash, buf_hmac, len, (UCHAR *)"key", sizeof("key"), 0);
632 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
633 ok(hash != NULL, "hash not set\n");
635 ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
636 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
638 test_hash_length(hash, 16);
639 test_alg_name(hash, "MD5");
641 memset(md5_hmac, 0, sizeof(md5_hmac));
642 ret = BCryptFinishHash(hash, md5_hmac, sizeof(md5_hmac), 0);
643 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
644 format_hash( md5_hmac, sizeof(md5_hmac), str );
645 ok(!strcmp(str, expected_hmac), "got %s\n", str);
647 ret = BCryptDestroyHash(hash);
648 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
650 ret = BCryptCloseAlgorithmProvider(alg, 0);
651 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
654 static void test_BcryptHash(void)
656 static const char expected[] =
657 "e2a3e68d23ce348b8f68b3079de3d4c9";
658 static const char expected_hmac[] =
659 "7bda029b93fa8d817fcc9e13d6bdf092";
660 BCRYPT_ALG_HANDLE alg;
661 UCHAR md5[16], md5_hmac[16];
662 char str[65];
663 NTSTATUS ret;
665 alg = NULL;
666 ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_MD5_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
667 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
668 ok(alg != NULL, "alg not set\n");
670 test_hash_length(alg, 16);
671 test_alg_name(alg, "MD5");
673 memset(md5, 0, sizeof(md5));
674 ret = pBCryptHash(alg, NULL, 0, (UCHAR *)"test", sizeof("test"), md5, sizeof(md5));
675 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
676 format_hash( md5, sizeof(md5), str );
677 ok(!strcmp(str, expected), "got %s\n", str);
679 ret = BCryptCloseAlgorithmProvider(alg, 0);
680 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
682 alg = NULL;
683 memset(md5_hmac, 0, sizeof(md5_hmac));
684 ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_MD5_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
685 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
686 ok(alg != NULL, "alg not set\n");
688 ret = pBCryptHash(alg, (UCHAR *)"key", sizeof("key"), (UCHAR *)"test", sizeof("test"), md5_hmac, sizeof(md5_hmac));
689 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
690 format_hash( md5_hmac, sizeof(md5_hmac), str );
691 ok(!strcmp(str, expected_hmac), "got %s\n", str);
693 ret = BCryptCloseAlgorithmProvider(alg, 0);
694 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
697 static void test_rng(void)
699 BCRYPT_ALG_HANDLE alg;
700 ULONG size, len;
701 UCHAR buf[16];
702 NTSTATUS ret;
704 alg = NULL;
705 ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
706 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
707 ok(alg != NULL, "alg not set\n");
709 len = size = 0xdeadbeef;
710 ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
711 ok(ret == STATUS_NOT_SUPPORTED, "got %08x\n", ret);
713 test_alg_name(alg, "RNG");
715 memset(buf, 0, 16);
716 ret = BCryptGenRandom(alg, buf, 8, 0);
717 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
718 ok(memcmp(buf, buf + 8, 8), "got zeroes\n");
720 ret = BCryptCloseAlgorithmProvider(alg, 0);
721 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
725 START_TEST(bcrypt)
727 HMODULE module;
729 module = GetModuleHandleA( "bcrypt.dll" );
731 test_BCryptGenRandom();
732 test_BCryptGetFipsAlgorithmMode();
733 test_sha1();
734 test_sha256();
735 test_sha384();
736 test_sha512();
737 test_md5();
738 test_rng();
740 pBCryptHash = (void *)GetProcAddress( module, "BCryptHash" );
742 if (pBCryptHash)
743 test_BcryptHash();
744 else
745 win_skip("BCryptHash is not available\n");