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
23 #define WIN32_NO_STATUS
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)
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 static const WCHAR policyKeyVistaW
[] = {
65 'S','y','s','t','e','m','\\',
66 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
67 'C','o','n','t','r','o','l','\\',
69 'F','I','P','S','A','l','g','o','r','i','t','h','m','P','o','l','i','c','y',0};
70 static const WCHAR policyValueVistaW
[] = {'E','n','a','b','l','e','d',0};
71 static const WCHAR policyKeyXPW
[] = {
72 'S','y','s','t','e','m','\\',
73 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
74 'C','o','n','t','r','o','l','\\',
76 static const WCHAR policyValueXPW
[] = {
77 'F','I','P','S','A','l','g','o','r','i','t','h','m','P','o','l','i','c','y',0};
80 DWORD value
, count
[2] = {sizeof(value
), sizeof(value
)};
83 if (!RegGetValueW(HKEY_LOCAL_MACHINE
, policyKeyVistaW
, policyValueVistaW
,
84 RRF_RT_REG_DWORD
, NULL
, &value
, &count
[0]))
88 else if (!RegGetValueW(HKEY_LOCAL_MACHINE
, policyKeyXPW
, policyValueXPW
,
89 RRF_RT_REG_DWORD
, NULL
, &value
, &count
[1]))
97 ok(0, "Neither XP or Vista key is present\n");
100 ret
= BCryptGetFipsAlgorithmMode(&enabled
);
101 ok(ret
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got 0x%x\n", ret
);
102 ok(enabled
== expected
, "expected result %d, got %d\n", expected
, enabled
);
104 ret
= BCryptGetFipsAlgorithmMode(NULL
);
105 ok(ret
== STATUS_INVALID_PARAMETER
, "Expected STATUS_INVALID_PARAMETER, got 0x%x\n", ret
);
108 static void format_hash(const UCHAR
*bytes
, ULONG size
, char *buf
)
112 for (i
= 0; i
< size
; i
++)
114 sprintf(buf
+ i
* 2, "%02x", bytes
[i
]);
119 static int strcmp_wa(const WCHAR
*strw
, const char *stra
)
122 MultiByteToWideChar(CP_ACP
, 0, stra
, -1, buf
, sizeof(buf
)/sizeof(buf
[0]));
123 return lstrcmpW(strw
, buf
);
126 #define test_hash_length(a,b) _test_hash_length(__LINE__,a,b)
127 static void _test_hash_length(unsigned line
, void *handle
, ULONG exlen
)
129 ULONG len
= 0xdeadbeef, size
= 0xdeadbeef;
132 status
= BCryptGetProperty(handle
, BCRYPT_HASH_LENGTH
, (UCHAR
*)&len
, sizeof(len
), &size
, 0);
133 ok_(__FILE__
,line
)(status
== STATUS_SUCCESS
, "BCryptGetProperty failed: %08x\n", status
);
134 ok_(__FILE__
,line
)(size
== sizeof(len
), "got %u\n", size
);
135 ok_(__FILE__
,line
)(len
== exlen
, "len = %u, expected %u\n", len
, exlen
);
138 #define test_alg_name(a,b) _test_alg_name(__LINE__,a,b)
139 static void _test_alg_name(unsigned line
, void *handle
, const char *exname
)
141 ULONG size
= 0xdeadbeef;
143 const WCHAR
*name
= (const WCHAR
*)buf
;
146 status
= BCryptGetProperty(handle
, BCRYPT_ALGORITHM_NAME
, buf
, sizeof(buf
), &size
, 0);
147 ok_(__FILE__
,line
)(status
== STATUS_SUCCESS
, "BCryptGetProperty failed: %08x\n", status
);
148 ok_(__FILE__
,line
)(size
== (strlen(exname
)+1)*sizeof(WCHAR
), "got %u\n", size
);
149 ok_(__FILE__
,line
)(!strcmp_wa(name
, exname
), "alg name = %s, expected %s\n", wine_dbgstr_w(name
), exname
);
152 static void test_sha1(void)
154 static const char expected
[] = "961fa64958818f767707072755d7018dcd278e94";
155 static const char expected_hmac
[] = "2472cf65d0e090618d769d3e46f0d9446cf212da";
156 BCRYPT_ALG_HANDLE alg
;
157 BCRYPT_HASH_HANDLE hash
;
158 UCHAR buf
[512], buf_hmac
[1024], sha1
[20], sha1_hmac
[20];
164 ret
= BCryptOpenAlgorithmProvider(&alg
, BCRYPT_SHA1_ALGORITHM
, MS_PRIMITIVE_PROVIDER
, 0);
165 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
166 ok(alg
!= NULL
, "alg not set\n");
168 len
= size
= 0xdeadbeef;
169 ret
= BCryptGetProperty(NULL
, BCRYPT_OBJECT_LENGTH
, (UCHAR
*)&len
, sizeof(len
), &size
, 0);
170 ok(ret
== STATUS_INVALID_HANDLE
, "got %08x\n", ret
);
172 len
= size
= 0xdeadbeef;
173 ret
= BCryptGetProperty(alg
, NULL
, (UCHAR
*)&len
, sizeof(len
), &size
, 0);
174 ok(ret
== STATUS_INVALID_PARAMETER
, "got %08x\n", ret
);
176 len
= size
= 0xdeadbeef;
177 ret
= BCryptGetProperty(alg
, BCRYPT_OBJECT_LENGTH
, (UCHAR
*)&len
, sizeof(len
), NULL
, 0);
178 ok(ret
== STATUS_INVALID_PARAMETER
, "got %08x\n", ret
);
180 len
= size
= 0xdeadbeef;
181 ret
= BCryptGetProperty(alg
, BCRYPT_OBJECT_LENGTH
, NULL
, sizeof(len
), &size
, 0);
182 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
183 ok(size
== sizeof(len
), "got %u\n", size
);
185 len
= size
= 0xdeadbeef;
186 ret
= BCryptGetProperty(alg
, BCRYPT_OBJECT_LENGTH
, (UCHAR
*)&len
, 0, &size
, 0);
187 ok(ret
== STATUS_BUFFER_TOO_SMALL
, "got %08x\n", ret
);
188 ok(len
== 0xdeadbeef, "got %u\n", len
);
189 ok(size
== sizeof(len
), "got %u\n", size
);
191 len
= size
= 0xdeadbeef;
192 ret
= BCryptGetProperty(alg
, BCRYPT_OBJECT_LENGTH
, (UCHAR
*)&len
, sizeof(len
), &size
, 0);
193 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
194 ok(len
!= 0xdeadbeef, "len not set\n");
195 ok(size
== sizeof(len
), "got %u\n", size
);
197 test_hash_length(alg
, 20);
198 test_alg_name(alg
, "SHA1");
202 ret
= BCryptCreateHash(alg
, &hash
, buf
, len
, NULL
, 0, 0);
203 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
204 ok(hash
!= NULL
, "hash not set\n");
206 ret
= BCryptHashData(hash
, NULL
, 0, 0);
207 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
209 ret
= BCryptHashData(hash
, (UCHAR
*)"test", sizeof("test"), 0);
210 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
212 test_hash_length(hash
, 20);
213 test_alg_name(hash
, "SHA1");
215 memset(sha1
, 0, sizeof(sha1
));
216 ret
= BCryptFinishHash(hash
, sha1
, sizeof(sha1
), 0);
217 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
218 format_hash( sha1
, sizeof(sha1
), str
);
219 ok(!strcmp(str
, expected
), "got %s\n", str
);
221 ret
= BCryptDestroyHash(hash
);
222 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
224 ret
= BCryptCloseAlgorithmProvider(alg
, 0);
225 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
228 ret
= BCryptOpenAlgorithmProvider(&alg
, BCRYPT_SHA1_ALGORITHM
, MS_PRIMITIVE_PROVIDER
, BCRYPT_ALG_HANDLE_HMAC_FLAG
);
229 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
230 ok(alg
!= NULL
, "alg not set\n");
233 len
= sizeof(buf_hmac
);
234 ret
= BCryptCreateHash(alg
, &hash
, buf_hmac
, len
, (UCHAR
*)"key", sizeof("key"), 0);
235 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
236 ok(hash
!= NULL
, "hash not set\n");
238 ret
= BCryptHashData(hash
, (UCHAR
*)"test", sizeof("test"), 0);
239 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
241 test_hash_length(hash
, 20);
242 test_alg_name(hash
, "SHA1");
244 memset(sha1_hmac
, 0, sizeof(sha1_hmac
));
245 ret
= BCryptFinishHash(hash
, sha1_hmac
, sizeof(sha1_hmac
), 0);
246 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
247 format_hash( sha1_hmac
, sizeof(sha1_hmac
), str
);
248 ok(!strcmp(str
, expected_hmac
), "got %s\n", str
);
250 ret
= BCryptDestroyHash(hash
);
251 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
253 ret
= BCryptCloseAlgorithmProvider(alg
, 0);
254 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
257 static void test_sha256(void)
259 static const char expected
[] =
260 "ceb73749c899693706ede1e30c9929b3fd5dd926163831c2fb8bd41e6efb1126";
261 static const char expected_hmac
[] =
262 "34c1aa473a4468a91d06e7cdbc75bc4f93b830ccfc2a47ffd74e8e6ed29e4c72";
263 BCRYPT_ALG_HANDLE alg
;
264 BCRYPT_HASH_HANDLE hash
;
265 UCHAR buf
[512], buf_hmac
[1024], sha256
[32], sha256_hmac
[32];
271 ret
= BCryptOpenAlgorithmProvider(&alg
, BCRYPT_SHA256_ALGORITHM
, MS_PRIMITIVE_PROVIDER
, 0);
272 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
273 ok(alg
!= NULL
, "alg not set\n");
275 len
= size
= 0xdeadbeef;
276 ret
= BCryptGetProperty(NULL
, BCRYPT_OBJECT_LENGTH
, (UCHAR
*)&len
, sizeof(len
), &size
, 0);
277 ok(ret
== STATUS_INVALID_HANDLE
, "got %08x\n", ret
);
279 len
= size
= 0xdeadbeef;
280 ret
= BCryptGetProperty(alg
, NULL
, (UCHAR
*)&len
, sizeof(len
), &size
, 0);
281 ok(ret
== STATUS_INVALID_PARAMETER
, "got %08x\n", ret
);
283 len
= size
= 0xdeadbeef;
284 ret
= BCryptGetProperty(alg
, BCRYPT_OBJECT_LENGTH
, (UCHAR
*)&len
, sizeof(len
), NULL
, 0);
285 ok(ret
== STATUS_INVALID_PARAMETER
, "got %08x\n", ret
);
287 len
= size
= 0xdeadbeef;
288 ret
= BCryptGetProperty(alg
, BCRYPT_OBJECT_LENGTH
, NULL
, sizeof(len
), &size
, 0);
289 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
290 ok(size
== sizeof(len
), "got %u\n", size
);
292 len
= size
= 0xdeadbeef;
293 ret
= BCryptGetProperty(alg
, BCRYPT_OBJECT_LENGTH
, (UCHAR
*)&len
, 0, &size
, 0);
294 ok(ret
== STATUS_BUFFER_TOO_SMALL
, "got %08x\n", ret
);
295 ok(len
== 0xdeadbeef, "got %u\n", len
);
296 ok(size
== sizeof(len
), "got %u\n", size
);
298 len
= size
= 0xdeadbeef;
299 ret
= BCryptGetProperty(alg
, BCRYPT_OBJECT_LENGTH
, (UCHAR
*)&len
, sizeof(len
), &size
, 0);
300 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
301 ok(len
!= 0xdeadbeef, "len not set\n");
302 ok(size
== sizeof(len
), "got %u\n", size
);
304 test_hash_length(alg
, 32);
305 test_alg_name(alg
, "SHA256");
309 ret
= BCryptCreateHash(alg
, &hash
, buf
, len
, NULL
, 0, 0);
310 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
311 ok(hash
!= NULL
, "hash not set\n");
313 ret
= BCryptHashData(hash
, NULL
, 0, 0);
314 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
316 ret
= BCryptHashData(hash
, (UCHAR
*)"test", sizeof("test"), 0);
317 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
319 test_hash_length(hash
, 32);
320 test_alg_name(hash
, "SHA256");
322 memset(sha256
, 0, sizeof(sha256
));
323 ret
= BCryptFinishHash(hash
, sha256
, sizeof(sha256
), 0);
324 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
325 format_hash( sha256
, sizeof(sha256
), str
);
326 ok(!strcmp(str
, expected
), "got %s\n", str
);
328 ret
= BCryptDestroyHash(hash
);
329 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
331 ret
= BCryptCloseAlgorithmProvider(alg
, 0);
332 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
335 ret
= BCryptOpenAlgorithmProvider(&alg
, BCRYPT_SHA256_ALGORITHM
, MS_PRIMITIVE_PROVIDER
, BCRYPT_ALG_HANDLE_HMAC_FLAG
);
336 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
337 ok(alg
!= NULL
, "alg not set\n");
340 len
= sizeof(buf_hmac
);
341 ret
= BCryptCreateHash(alg
, &hash
, buf_hmac
, len
, (UCHAR
*)"key", sizeof("key"), 0);
342 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
343 ok(hash
!= NULL
, "hash not set\n");
345 ret
= BCryptHashData(hash
, (UCHAR
*)"test", sizeof("test"), 0);
346 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
348 test_hash_length(hash
, 32);
349 test_alg_name(hash
, "SHA256");
351 memset(sha256_hmac
, 0, sizeof(sha256_hmac
));
352 ret
= BCryptFinishHash(hash
, sha256_hmac
, sizeof(sha256_hmac
), 0);
353 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
354 format_hash( sha256_hmac
, sizeof(sha256_hmac
), str
);
355 ok(!strcmp(str
, expected_hmac
), "got %s\n", str
);
357 ret
= BCryptDestroyHash(hash
);
358 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
360 ret
= BCryptCloseAlgorithmProvider(alg
, 0);
361 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
364 static void test_sha384(void)
366 static const char expected
[] =
367 "62b21e90c9022b101671ba1f808f8631a8149f0f12904055839a35c1ca78ae5363eed1e743a692d70e0504b0cfd12ef9";
368 static const char expected_hmac
[] =
369 "4b3e6d6ff2da121790ab7e7b9247583e3a7eed2db5bd4dabc680303b1608f37dfdc836d96a704c03283bc05b4f6c5eb8";
370 BCRYPT_ALG_HANDLE alg
;
371 BCRYPT_HASH_HANDLE hash
;
372 UCHAR buf
[512], buf_hmac
[1024], sha384
[48], sha384_hmac
[48];
378 ret
= BCryptOpenAlgorithmProvider(&alg
, BCRYPT_SHA384_ALGORITHM
, MS_PRIMITIVE_PROVIDER
, 0);
379 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
380 ok(alg
!= NULL
, "alg not set\n");
382 len
= size
= 0xdeadbeef;
383 ret
= BCryptGetProperty(NULL
, BCRYPT_OBJECT_LENGTH
, (UCHAR
*)&len
, sizeof(len
), &size
, 0);
384 ok(ret
== STATUS_INVALID_HANDLE
, "got %08x\n", ret
);
386 len
= size
= 0xdeadbeef;
387 ret
= BCryptGetProperty(alg
, NULL
, (UCHAR
*)&len
, sizeof(len
), &size
, 0);
388 ok(ret
== STATUS_INVALID_PARAMETER
, "got %08x\n", ret
);
390 len
= size
= 0xdeadbeef;
391 ret
= BCryptGetProperty(alg
, BCRYPT_OBJECT_LENGTH
, (UCHAR
*)&len
, sizeof(len
), NULL
, 0);
392 ok(ret
== STATUS_INVALID_PARAMETER
, "got %08x\n", ret
);
394 len
= size
= 0xdeadbeef;
395 ret
= BCryptGetProperty(alg
, BCRYPT_OBJECT_LENGTH
, NULL
, sizeof(len
), &size
, 0);
396 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
397 ok(size
== sizeof(len
), "got %u\n", size
);
399 len
= size
= 0xdeadbeef;
400 ret
= BCryptGetProperty(alg
, BCRYPT_OBJECT_LENGTH
, (UCHAR
*)&len
, 0, &size
, 0);
401 ok(ret
== STATUS_BUFFER_TOO_SMALL
, "got %08x\n", ret
);
402 ok(len
== 0xdeadbeef, "got %u\n", len
);
403 ok(size
== sizeof(len
), "got %u\n", size
);
405 len
= size
= 0xdeadbeef;
406 ret
= BCryptGetProperty(alg
, BCRYPT_OBJECT_LENGTH
, (UCHAR
*)&len
, sizeof(len
), &size
, 0);
407 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
408 ok(len
!= 0xdeadbeef, "len not set\n");
409 ok(size
== sizeof(len
), "got %u\n", size
);
411 test_hash_length(alg
, 48);
412 test_alg_name(alg
, "SHA384");
416 ret
= BCryptCreateHash(alg
, &hash
, buf
, len
, NULL
, 0, 0);
417 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
418 ok(hash
!= NULL
, "hash not set\n");
420 ret
= BCryptHashData(hash
, NULL
, 0, 0);
421 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
423 ret
= BCryptHashData(hash
, (UCHAR
*)"test", sizeof("test"), 0);
424 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
426 test_hash_length(hash
, 48);
427 test_alg_name(hash
, "SHA384");
429 memset(sha384
, 0, sizeof(sha384
));
430 ret
= BCryptFinishHash(hash
, sha384
, sizeof(sha384
), 0);
431 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
432 format_hash( sha384
, sizeof(sha384
), str
);
433 ok(!strcmp(str
, expected
), "got %s\n", str
);
435 ret
= BCryptDestroyHash(hash
);
436 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
438 ret
= BCryptCloseAlgorithmProvider(alg
, 0);
439 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
442 ret
= BCryptOpenAlgorithmProvider(&alg
, BCRYPT_SHA384_ALGORITHM
, MS_PRIMITIVE_PROVIDER
, BCRYPT_ALG_HANDLE_HMAC_FLAG
);
443 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
444 ok(alg
!= NULL
, "alg not set\n");
447 len
= sizeof(buf_hmac
);
448 ret
= BCryptCreateHash(alg
, &hash
, buf_hmac
, len
, (UCHAR
*)"key", sizeof("key"), 0);
449 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
450 ok(hash
!= NULL
, "hash not set\n");
452 ret
= BCryptHashData(hash
, (UCHAR
*)"test", sizeof("test"), 0);
453 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
455 test_hash_length(hash
, 48);
456 test_alg_name(hash
, "SHA384");
458 memset(sha384_hmac
, 0, sizeof(sha384_hmac
));
459 ret
= BCryptFinishHash(hash
, sha384_hmac
, sizeof(sha384_hmac
), 0);
460 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
461 format_hash( sha384_hmac
, sizeof(sha384_hmac
), str
);
462 ok(!strcmp(str
, expected_hmac
), "got %s\n", str
);
464 ret
= BCryptDestroyHash(hash
);
465 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
467 ret
= BCryptCloseAlgorithmProvider(alg
, 0);
468 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
471 static void test_sha512(void)
473 static const char expected
[] =
474 "d55ced17163bf5386f2cd9ff21d6fd7fe576a915065c24744d09cfae4ec84ee1e"
475 "f6ef11bfbc5acce3639bab725b50a1fe2c204f8c820d6d7db0df0ecbc49c5ca";
476 static const char expected_hmac
[] =
477 "415fb6b10018ca03b38a1b1399c42ac0be5e8aceddb9a73103f5e543bf2d888f2"
478 "eecf91373941f9315dd730a77937fa92444450fbece86f409d9cb5ec48c6513";
479 BCRYPT_ALG_HANDLE alg
;
480 BCRYPT_HASH_HANDLE hash
;
481 UCHAR buf
[512], buf_hmac
[1024], sha512
[64], sha512_hmac
[64];
487 ret
= BCryptOpenAlgorithmProvider(&alg
, BCRYPT_SHA512_ALGORITHM
, MS_PRIMITIVE_PROVIDER
, 0);
488 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
489 ok(alg
!= NULL
, "alg not set\n");
491 len
= size
= 0xdeadbeef;
492 ret
= BCryptGetProperty(NULL
, BCRYPT_OBJECT_LENGTH
, (UCHAR
*)&len
, sizeof(len
), &size
, 0);
493 ok(ret
== STATUS_INVALID_HANDLE
, "got %08x\n", ret
);
495 len
= size
= 0xdeadbeef;
496 ret
= BCryptGetProperty(alg
, NULL
, (UCHAR
*)&len
, sizeof(len
), &size
, 0);
497 ok(ret
== STATUS_INVALID_PARAMETER
, "got %08x\n", ret
);
499 len
= size
= 0xdeadbeef;
500 ret
= BCryptGetProperty(alg
, BCRYPT_OBJECT_LENGTH
, (UCHAR
*)&len
, sizeof(len
), NULL
, 0);
501 ok(ret
== STATUS_INVALID_PARAMETER
, "got %08x\n", ret
);
503 len
= size
= 0xdeadbeef;
504 ret
= BCryptGetProperty(alg
, BCRYPT_OBJECT_LENGTH
, NULL
, sizeof(len
), &size
, 0);
505 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
506 ok(size
== sizeof(len
), "got %u\n", size
);
508 len
= size
= 0xdeadbeef;
509 ret
= BCryptGetProperty(alg
, BCRYPT_OBJECT_LENGTH
, (UCHAR
*)&len
, 0, &size
, 0);
510 ok(ret
== STATUS_BUFFER_TOO_SMALL
, "got %08x\n", ret
);
511 ok(len
== 0xdeadbeef, "got %u\n", len
);
512 ok(size
== sizeof(len
), "got %u\n", size
);
514 len
= size
= 0xdeadbeef;
515 ret
= BCryptGetProperty(alg
, BCRYPT_OBJECT_LENGTH
, (UCHAR
*)&len
, sizeof(len
), &size
, 0);
516 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
517 ok(len
!= 0xdeadbeef, "len not set\n");
518 ok(size
== sizeof(len
), "got %u\n", size
);
520 test_hash_length(alg
, 64);
521 test_alg_name(alg
, "SHA512");
525 ret
= BCryptCreateHash(alg
, &hash
, buf
, len
, NULL
, 0, 0);
526 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
527 ok(hash
!= NULL
, "hash not set\n");
529 ret
= BCryptHashData(hash
, NULL
, 0, 0);
530 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
532 ret
= BCryptHashData(hash
, (UCHAR
*)"test", sizeof("test"), 0);
533 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
535 test_hash_length(hash
, 64);
536 test_alg_name(hash
, "SHA512");
538 memset(sha512
, 0, sizeof(sha512
));
539 ret
= BCryptFinishHash(hash
, sha512
, sizeof(sha512
), 0);
540 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
541 format_hash( sha512
, sizeof(sha512
), str
);
542 ok(!strcmp(str
, expected
), "got %s\n", str
);
544 ret
= BCryptDestroyHash(hash
);
545 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
547 ret
= BCryptCloseAlgorithmProvider(alg
, 0);
548 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
551 ret
= BCryptOpenAlgorithmProvider(&alg
, BCRYPT_SHA512_ALGORITHM
, MS_PRIMITIVE_PROVIDER
, BCRYPT_ALG_HANDLE_HMAC_FLAG
);
552 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
553 ok(alg
!= NULL
, "alg not set\n");
556 len
= sizeof(buf_hmac
);
557 ret
= BCryptCreateHash(alg
, &hash
, buf_hmac
, len
, (UCHAR
*)"key", sizeof("key"), 0);
558 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
559 ok(hash
!= NULL
, "hash not set\n");
561 ret
= BCryptHashData(hash
, (UCHAR
*)"test", sizeof("test"), 0);
562 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
564 test_hash_length(hash
, 64);
565 test_alg_name(hash
, "SHA512");
567 memset(sha512_hmac
, 0, sizeof(sha512_hmac
));
568 ret
= BCryptFinishHash(hash
, sha512_hmac
, sizeof(sha512_hmac
), 0);
569 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
570 format_hash( sha512_hmac
, sizeof(sha512_hmac
), str
);
571 ok(!strcmp(str
, expected_hmac
), "got %s\n", str
);
573 ret
= BCryptDestroyHash(hash
);
574 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
576 ret
= BCryptCloseAlgorithmProvider(alg
, 0);
577 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
581 static void test_md5(void)
583 static const char expected
[] =
584 "e2a3e68d23ce348b8f68b3079de3d4c9";
585 static const char expected_hmac
[] =
586 "7bda029b93fa8d817fcc9e13d6bdf092";
587 BCRYPT_ALG_HANDLE alg
;
588 BCRYPT_HASH_HANDLE hash
;
589 UCHAR buf
[512], buf_hmac
[1024], md5
[16], md5_hmac
[16];
595 ret
= BCryptOpenAlgorithmProvider(&alg
, BCRYPT_MD5_ALGORITHM
, MS_PRIMITIVE_PROVIDER
, 0);
596 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
597 ok(alg
!= NULL
, "alg not set\n");
599 len
= size
= 0xdeadbeef;
600 ret
= BCryptGetProperty(NULL
, BCRYPT_OBJECT_LENGTH
, (UCHAR
*)&len
, sizeof(len
), &size
, 0);
601 ok(ret
== STATUS_INVALID_HANDLE
, "got %08x\n", ret
);
603 len
= size
= 0xdeadbeef;
604 ret
= BCryptGetProperty(alg
, NULL
, (UCHAR
*)&len
, sizeof(len
), &size
, 0);
605 ok(ret
== STATUS_INVALID_PARAMETER
, "got %08x\n", ret
);
607 len
= size
= 0xdeadbeef;
608 ret
= BCryptGetProperty(alg
, BCRYPT_OBJECT_LENGTH
, (UCHAR
*)&len
, sizeof(len
), NULL
, 0);
609 ok(ret
== STATUS_INVALID_PARAMETER
, "got %08x\n", ret
);
611 len
= size
= 0xdeadbeef;
612 ret
= BCryptGetProperty(alg
, BCRYPT_OBJECT_LENGTH
, NULL
, sizeof(len
), &size
, 0);
613 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
614 ok(size
== sizeof(len
), "got %u\n", size
);
616 len
= size
= 0xdeadbeef;
617 ret
= BCryptGetProperty(alg
, BCRYPT_OBJECT_LENGTH
, (UCHAR
*)&len
, 0, &size
, 0);
618 ok(ret
== STATUS_BUFFER_TOO_SMALL
, "got %08x\n", ret
);
619 ok(len
== 0xdeadbeef, "got %u\n", len
);
620 ok(size
== sizeof(len
), "got %u\n", size
);
622 len
= size
= 0xdeadbeef;
623 ret
= BCryptGetProperty(alg
, BCRYPT_OBJECT_LENGTH
, (UCHAR
*)&len
, sizeof(len
), &size
, 0);
624 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
625 ok(len
!= 0xdeadbeef, "len not set\n");
626 ok(size
== sizeof(len
), "got %u\n", size
);
628 test_hash_length(alg
, 16);
629 test_alg_name(alg
, "MD5");
633 ret
= BCryptCreateHash(alg
, &hash
, buf
, len
, NULL
, 0, 0);
634 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
635 ok(hash
!= NULL
, "hash not set\n");
637 ret
= BCryptHashData(hash
, NULL
, 0, 0);
638 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
640 ret
= BCryptHashData(hash
, (UCHAR
*)"test", sizeof("test"), 0);
641 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
643 test_hash_length(hash
, 16);
644 test_alg_name(hash
, "MD5");
646 memset(md5
, 0, sizeof(md5
));
647 ret
= BCryptFinishHash(hash
, md5
, sizeof(md5
), 0);
648 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
649 format_hash( md5
, sizeof(md5
), str
);
650 ok(!strcmp(str
, expected
), "got %s\n", str
);
652 ret
= BCryptDestroyHash(hash
);
653 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
655 ret
= BCryptCloseAlgorithmProvider(alg
, 0);
656 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
659 ret
= BCryptOpenAlgorithmProvider(&alg
, BCRYPT_MD5_ALGORITHM
, MS_PRIMITIVE_PROVIDER
, BCRYPT_ALG_HANDLE_HMAC_FLAG
);
660 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
661 ok(alg
!= NULL
, "alg not set\n");
664 len
= sizeof(buf_hmac
);
665 ret
= BCryptCreateHash(alg
, &hash
, buf_hmac
, len
, (UCHAR
*)"key", sizeof("key"), 0);
666 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
667 ok(hash
!= NULL
, "hash not set\n");
669 ret
= BCryptHashData(hash
, (UCHAR
*)"test", sizeof("test"), 0);
670 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
672 test_hash_length(hash
, 16);
673 test_alg_name(hash
, "MD5");
675 memset(md5_hmac
, 0, sizeof(md5_hmac
));
676 ret
= BCryptFinishHash(hash
, md5_hmac
, sizeof(md5_hmac
), 0);
677 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
678 format_hash( md5_hmac
, sizeof(md5_hmac
), str
);
679 ok(!strcmp(str
, expected_hmac
), "got %s\n", str
);
681 ret
= BCryptDestroyHash(hash
);
682 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
684 ret
= BCryptCloseAlgorithmProvider(alg
, 0);
685 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
688 static void test_BcryptHash(void)
690 static const char expected
[] =
691 "e2a3e68d23ce348b8f68b3079de3d4c9";
692 static const char expected_hmac
[] =
693 "7bda029b93fa8d817fcc9e13d6bdf092";
694 BCRYPT_ALG_HANDLE alg
;
695 UCHAR md5
[16], md5_hmac
[16];
700 ret
= BCryptOpenAlgorithmProvider(&alg
, BCRYPT_MD5_ALGORITHM
, MS_PRIMITIVE_PROVIDER
, 0);
701 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
702 ok(alg
!= NULL
, "alg not set\n");
704 test_hash_length(alg
, 16);
705 test_alg_name(alg
, "MD5");
707 memset(md5
, 0, sizeof(md5
));
708 ret
= pBCryptHash(alg
, NULL
, 0, (UCHAR
*)"test", sizeof("test"), md5
, sizeof(md5
));
709 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
710 format_hash( md5
, sizeof(md5
), str
);
711 ok(!strcmp(str
, expected
), "got %s\n", str
);
713 ret
= BCryptCloseAlgorithmProvider(alg
, 0);
714 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
717 memset(md5_hmac
, 0, sizeof(md5_hmac
));
718 ret
= BCryptOpenAlgorithmProvider(&alg
, BCRYPT_MD5_ALGORITHM
, MS_PRIMITIVE_PROVIDER
, BCRYPT_ALG_HANDLE_HMAC_FLAG
);
719 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
720 ok(alg
!= NULL
, "alg not set\n");
722 ret
= pBCryptHash(alg
, (UCHAR
*)"key", sizeof("key"), (UCHAR
*)"test", sizeof("test"), md5_hmac
, sizeof(md5_hmac
));
723 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
724 format_hash( md5_hmac
, sizeof(md5_hmac
), str
);
725 ok(!strcmp(str
, expected_hmac
), "got %s\n", str
);
727 ret
= BCryptCloseAlgorithmProvider(alg
, 0);
728 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
731 static void test_rng(void)
733 BCRYPT_ALG_HANDLE alg
;
739 ret
= BCryptOpenAlgorithmProvider(&alg
, BCRYPT_RNG_ALGORITHM
, MS_PRIMITIVE_PROVIDER
, 0);
740 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
741 ok(alg
!= NULL
, "alg not set\n");
743 len
= size
= 0xdeadbeef;
744 ret
= BCryptGetProperty(alg
, BCRYPT_OBJECT_LENGTH
, (UCHAR
*)&len
, sizeof(len
), &size
, 0);
745 ok(ret
== STATUS_NOT_SUPPORTED
, "got %08x\n", ret
);
747 test_alg_name(alg
, "RNG");
750 ret
= BCryptGenRandom(alg
, buf
, 8, 0);
751 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
752 ok(memcmp(buf
, buf
+ 8, 8), "got zeroes\n");
754 ret
= BCryptCloseAlgorithmProvider(alg
, 0);
755 ok(ret
== STATUS_SUCCESS
, "got %08x\n", ret
);
763 module
= GetModuleHandleA( "bcrypt.dll" );
765 test_BCryptGenRandom();
766 test_BCryptGetFipsAlgorithmMode();
774 pBCryptHash
= (void *)GetProcAddress( module
, "BCryptHash" );
779 win_skip("BCryptHash is not available\n");