1 /*
2 * Unit test for bcrypt functions
3 *
4 * Copyright 2014 Bruno Jesus
5 *
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.
10 *
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.
15 *
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
19 */
20
21 #include <stdio.h>
22 #include <ntstatus.h>
23 #define WIN32_NO_STATUS
24 #include <windows.h>
25 #include <bcrypt.h>
26
27 #include "wine/test.h"
28
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, ULONG, ULONG);
33 static NTSTATUS (WINAPI *pBCryptHash)(BCRYPT_ALG_HANDLE, UCHAR *, ULONG, UCHAR *, ULONG, UCHAR *, ULONG);
34 static NTSTATUS (WINAPI *pBCryptHashData)(BCRYPT_HASH_HANDLE, PUCHAR, ULONG, ULONG);
35 static NTSTATUS (WINAPI *pBCryptFinishHash)(BCRYPT_HASH_HANDLE, PUCHAR, ULONG, ULONG);
36 static NTSTATUS (WINAPI *pBCryptDestroyHash)(BCRYPT_HASH_HANDLE);
37 static NTSTATUS (WINAPI *pBCryptGenRandom)(BCRYPT_ALG_HANDLE, PUCHAR, ULONG, ULONG);
38 static NTSTATUS (WINAPI *pBCryptGetProperty)(BCRYPT_HANDLE, LPCWSTR, PUCHAR, ULONG, ULONG *, ULONG);
39
test_BCryptGenRandom(void)40 static void test_BCryptGenRandom(void)
41 {
42 NTSTATUS ret;
43 UCHAR buffer[256];
44
45 ret = pBCryptGenRandom(NULL, NULL, 0, 0);
46 ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got 0x%x\n", ret);
47 ret = pBCryptGenRandom(NULL, buffer, 0, 0);
48 ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got 0x%x\n", ret);
49 ret = pBCryptGenRandom(NULL, buffer, sizeof(buffer), 0);
50 ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got 0x%x\n", ret);
51 ret = pBCryptGenRandom(NULL, buffer, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
52 ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret);
53 ret = pBCryptGenRandom(NULL, buffer, sizeof(buffer),
54 BCRYPT_USE_SYSTEM_PREFERRED_RNG|BCRYPT_RNG_USE_ENTROPY_IN_BUFFER);
55 ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret);
56 ret = pBCryptGenRandom(NULL, NULL, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
57 ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got 0x%x\n", ret);
58
59 /* Zero sized buffer should work too */
60 ret = pBCryptGenRandom(NULL, buffer, 0, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
61 ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret);
62
63 /* Test random number generation - It's impossible for a sane RNG to return 8 zeros */
64 memset(buffer, 0, 16);
65 ret = pBCryptGenRandom(NULL, buffer, 8, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
66 ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret);
67 ok(memcmp(buffer, buffer + 8, 8), "Expected a random number, got 0\n");
68 }
69
test_BCryptGetFipsAlgorithmMode(void)70 static void test_BCryptGetFipsAlgorithmMode(void)
71 {
72 static const WCHAR policyKeyVistaW[] = {
73 'S','y','s','t','e','m','\\',
74 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
75 'C','o','n','t','r','o','l','\\',
76 'L','s','a','\\',
77 'F','I','P','S','A','l','g','o','r','i','t','h','m','P','o','l','i','c','y',0};
78 static const WCHAR policyValueVistaW[] = {'E','n','a','b','l','e','d',0};
79 static const WCHAR policyKeyXPW[] = {
80 'S','y','s','t','e','m','\\',
81 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
82 'C','o','n','t','r','o','l','\\',
83 'L','s','a',0};
84 static const WCHAR policyValueXPW[] = {
85 'F','I','P','S','A','l','g','o','r','i','t','h','m','P','o','l','i','c','y',0};
86 HKEY hkey = NULL;
87 BOOLEAN expected;
88 BOOLEAN enabled;
89 DWORD value, count[2] = {sizeof(value), sizeof(value)};
90 NTSTATUS ret;
91
92 if (RegOpenKeyW(HKEY_LOCAL_MACHINE, policyKeyVistaW, &hkey) == ERROR_SUCCESS &&
93 RegQueryValueExW(hkey, policyValueVistaW, NULL, NULL, (void *)&value, &count[0]) == ERROR_SUCCESS)
94 {
95 expected = !!value;
96 }
97 else if (RegOpenKeyW(HKEY_LOCAL_MACHINE, policyKeyXPW, &hkey) == ERROR_SUCCESS &&
98 RegQueryValueExW(hkey, policyValueXPW, NULL, NULL, (void *)&value, &count[0]) == ERROR_SUCCESS)
99 {
100 expected = !!value;
101 }
102 else
103 {
104 expected = FALSE;
105 todo_wine
106 ok(0, "Neither XP or Vista key is present\n");
107 }
108 RegCloseKey(hkey);
109
110 ret = pBCryptGetFipsAlgorithmMode(&enabled);
111 ok(ret == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got 0x%x\n", ret);
112 ok(enabled == expected, "expected result %d, got %d\n", expected, enabled);
113
114 ret = pBCryptGetFipsAlgorithmMode(NULL);
115 ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got 0x%x\n", ret);
116 }
117
format_hash(const UCHAR * bytes,ULONG size,char * buf)118 static void format_hash(const UCHAR *bytes, ULONG size, char *buf)
119 {
120 ULONG i;
121 buf[0] = '\0';
122 for (i = 0; i < size; i++)
123 {
124 sprintf(buf + i * 2, "%02x", bytes[i]);
125 }
126 return;
127 }
128
strcmp_wa(const WCHAR * strw,const char * stra)129 static int strcmp_wa(const WCHAR *strw, const char *stra)
130 {
131 WCHAR buf[512];
132 MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, sizeof(buf)/sizeof(buf[0]));
133 return lstrcmpW(strw, buf);
134 }
135
136 #define test_hash_length(a,b) _test_hash_length(__LINE__,a,b)
_test_hash_length(unsigned line,void * handle,ULONG exlen)137 static void _test_hash_length(unsigned line, void *handle, ULONG exlen)
138 {
139 ULONG len = 0xdeadbeef, size = 0xdeadbeef;
140 NTSTATUS status;
141
142 status = pBCryptGetProperty(handle, BCRYPT_HASH_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
143 ok_(__FILE__,line)(status == STATUS_SUCCESS, "BCryptGetProperty failed: %08x\n", status);
144 ok_(__FILE__,line)(size == sizeof(len), "got %u\n", size);
145 ok_(__FILE__,line)(len == exlen, "len = %u, expected %u\n", len, exlen);
146 }
147
148 #define test_alg_name(a,b) _test_alg_name(__LINE__,a,b)
_test_alg_name(unsigned line,void * handle,const char * exname)149 static void _test_alg_name(unsigned line, void *handle, const char *exname)
150 {
151 ULONG size = 0xdeadbeef;
152 UCHAR buf[256];
153 const WCHAR *name = (const WCHAR*)buf;
154 NTSTATUS status;
155
156 status = pBCryptGetProperty(handle, BCRYPT_ALGORITHM_NAME, buf, sizeof(buf), &size, 0);
157 ok_(__FILE__,line)(status == STATUS_SUCCESS, "BCryptGetProperty failed: %08x\n", status);
158 ok_(__FILE__,line)(size == (strlen(exname)+1)*sizeof(WCHAR), "got %u\n", size);
159 ok_(__FILE__,line)(!strcmp_wa(name, exname), "alg name = %s, expected %s\n", wine_dbgstr_w(name), exname);
160 }
161
test_sha1(void)162 static void test_sha1(void)
163 {
164 static const char expected[] = "961fa64958818f767707072755d7018dcd278e94";
165 static const char expected_hmac[] = "2472cf65d0e090618d769d3e46f0d9446cf212da";
166 BCRYPT_ALG_HANDLE alg;
167 BCRYPT_HASH_HANDLE hash;
168 UCHAR buf[512], buf_hmac[1024], sha1[20], sha1_hmac[20];
169 ULONG size, len;
170 char str[41];
171 NTSTATUS ret;
172
173 alg = NULL;
174 ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
175 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
176 ok(alg != NULL, "alg not set\n");
177
178 len = size = 0xdeadbeef;
179 ret = pBCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
180 ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret);
181
182 len = size = 0xdeadbeef;
183 ret = pBCryptGetProperty(alg, NULL, (UCHAR *)&len, sizeof(len), &size, 0);
184 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
185
186 len = size = 0xdeadbeef;
187 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0);
188 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
189
190 len = size = 0xdeadbeef;
191 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0);
192 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
193 ok(size == sizeof(len), "got %u\n", size);
194
195 len = size = 0xdeadbeef;
196 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0);
197 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
198 ok(len == 0xdeadbeef, "got %u\n", len);
199 ok(size == sizeof(len), "got %u\n", size);
200
201 len = size = 0xdeadbeef;
202 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len , sizeof(len), &size, 0);
203 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
204 ok(len != 0xdeadbeef, "len not set\n");
205 ok(size == sizeof(len), "got %u\n", size);
206
207 test_hash_length(alg, 20);
208 test_alg_name(alg, "SHA1");
209
210 hash = NULL;
211 len = sizeof(buf);
212 ret = pBCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0);
213 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
214 ok(hash != NULL, "hash not set\n");
215
216 ret = pBCryptHashData(hash, NULL, 0, 0);
217 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
218
219 ret = pBCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
220 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
221
222 test_hash_length(hash, 20);
223 test_alg_name(hash, "SHA1");
224
225 memset(sha1, 0, sizeof(sha1));
226 ret = pBCryptFinishHash(hash, sha1, sizeof(sha1), 0);
227 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
228 format_hash( sha1, sizeof(sha1), str );
229 ok(!strcmp(str, expected), "got %s\n", str);
230
231 ret = pBCryptDestroyHash(hash);
232 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
233
234 ret = pBCryptCloseAlgorithmProvider(alg, 0);
235 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
236
237 alg = NULL;
238 ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
239 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
240 ok(alg != NULL, "alg not set\n");
241
242 hash = NULL;
243 len = sizeof(buf_hmac);
244 ret = pBCryptCreateHash(alg, &hash, buf_hmac, len, (UCHAR *)"key", sizeof("key"), 0);
245 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
246 ok(hash != NULL, "hash not set\n");
247
248 ret = pBCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
249 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
250
251 test_hash_length(hash, 20);
252 test_alg_name(hash, "SHA1");
253
254 memset(sha1_hmac, 0, sizeof(sha1_hmac));
255 ret = pBCryptFinishHash(hash, sha1_hmac, sizeof(sha1_hmac), 0);
256 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
257 format_hash( sha1_hmac, sizeof(sha1_hmac), str );
258 ok(!strcmp(str, expected_hmac), "got %s\n", str);
259
260 ret = pBCryptDestroyHash(hash);
261 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
262
263 ret = pBCryptCloseAlgorithmProvider(alg, 0);
264 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
265 }
266
test_sha256(void)267 static void test_sha256(void)
268 {
269 static const char expected[] =
270 "ceb73749c899693706ede1e30c9929b3fd5dd926163831c2fb8bd41e6efb1126";
271 static const char expected_hmac[] =
272 "34c1aa473a4468a91d06e7cdbc75bc4f93b830ccfc2a47ffd74e8e6ed29e4c72";
273 BCRYPT_ALG_HANDLE alg;
274 BCRYPT_HASH_HANDLE hash;
275 UCHAR buf[512], buf_hmac[1024], sha256[32], sha256_hmac[32];
276 ULONG size, len;
277 char str[65];
278 NTSTATUS ret;
279
280 alg = NULL;
281 ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA256_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
282 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
283 ok(alg != NULL, "alg not set\n");
284
285 len = size = 0xdeadbeef;
286 ret = pBCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
287 ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret);
288
289 len = size = 0xdeadbeef;
290 ret = pBCryptGetProperty(alg, NULL, (UCHAR *)&len, sizeof(len), &size, 0);
291 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
292
293 len = size = 0xdeadbeef;
294 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0);
295 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
296
297 len = size = 0xdeadbeef;
298 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0);
299 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
300 ok(size == sizeof(len), "got %u\n", size);
301
302 len = size = 0xdeadbeef;
303 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0);
304 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
305 ok(len == 0xdeadbeef, "got %u\n", len);
306 ok(size == sizeof(len), "got %u\n", size);
307
308 len = size = 0xdeadbeef;
309 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len , sizeof(len), &size, 0);
310 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
311 ok(len != 0xdeadbeef, "len not set\n");
312 ok(size == sizeof(len), "got %u\n", size);
313
314 test_hash_length(alg, 32);
315 test_alg_name(alg, "SHA256");
316
317 hash = NULL;
318 len = sizeof(buf);
319 ret = pBCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0);
320 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
321 ok(hash != NULL, "hash not set\n");
322
323 ret = pBCryptHashData(hash, NULL, 0, 0);
324 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
325
326 ret = pBCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
327 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
328
329 test_hash_length(hash, 32);
330 test_alg_name(hash, "SHA256");
331
332 memset(sha256, 0, sizeof(sha256));
333 ret = pBCryptFinishHash(hash, sha256, sizeof(sha256), 0);
334 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
335 format_hash( sha256, sizeof(sha256), str );
336 ok(!strcmp(str, expected), "got %s\n", str);
337
338 ret = pBCryptDestroyHash(hash);
339 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
340
341 ret = pBCryptCloseAlgorithmProvider(alg, 0);
342 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
343
344 alg = NULL;
345 ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA256_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
346 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
347 ok(alg != NULL, "alg not set\n");
348
349 hash = NULL;
350 len = sizeof(buf_hmac);
351 ret = pBCryptCreateHash(alg, &hash, buf_hmac, len, (UCHAR *)"key", sizeof("key"), 0);
352 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
353 ok(hash != NULL, "hash not set\n");
354
355 ret = pBCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
356 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
357
358 test_hash_length(hash, 32);
359 test_alg_name(hash, "SHA256");
360
361 memset(sha256_hmac, 0, sizeof(sha256_hmac));
362 ret = pBCryptFinishHash(hash, sha256_hmac, sizeof(sha256_hmac), 0);
363 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
364 format_hash( sha256_hmac, sizeof(sha256_hmac), str );
365 ok(!strcmp(str, expected_hmac), "got %s\n", str);
366
367 ret = pBCryptDestroyHash(hash);
368 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
369
370 ret = pBCryptCloseAlgorithmProvider(alg, 0);
371 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
372 }
373
test_sha384(void)374 static void test_sha384(void)
375 {
376 static const char expected[] =
377 "62b21e90c9022b101671ba1f808f8631a8149f0f12904055839a35c1ca78ae5363eed1e743a692d70e0504b0cfd12ef9";
378 static const char expected_hmac[] =
379 "4b3e6d6ff2da121790ab7e7b9247583e3a7eed2db5bd4dabc680303b1608f37dfdc836d96a704c03283bc05b4f6c5eb8";
380 BCRYPT_ALG_HANDLE alg;
381 BCRYPT_HASH_HANDLE hash;
382 UCHAR buf[512], buf_hmac[1024], sha384[48], sha384_hmac[48];
383 ULONG size, len;
384 char str[97];
385 NTSTATUS ret;
386
387 alg = NULL;
388 ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA384_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
389 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
390 ok(alg != NULL, "alg not set\n");
391
392 len = size = 0xdeadbeef;
393 ret = pBCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
394 ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret);
395
396 len = size = 0xdeadbeef;
397 ret = pBCryptGetProperty(alg, NULL, (UCHAR *)&len, sizeof(len), &size, 0);
398 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
399
400 len = size = 0xdeadbeef;
401 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0);
402 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
403
404 len = size = 0xdeadbeef;
405 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0);
406 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
407 ok(size == sizeof(len), "got %u\n", size);
408
409 len = size = 0xdeadbeef;
410 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0);
411 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
412 ok(len == 0xdeadbeef, "got %u\n", len);
413 ok(size == sizeof(len), "got %u\n", size);
414
415 len = size = 0xdeadbeef;
416 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len , sizeof(len), &size, 0);
417 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
418 ok(len != 0xdeadbeef, "len not set\n");
419 ok(size == sizeof(len), "got %u\n", size);
420
421 test_hash_length(alg, 48);
422 test_alg_name(alg, "SHA384");
423
424 hash = NULL;
425 len = sizeof(buf);
426 ret = pBCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0);
427 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
428 ok(hash != NULL, "hash not set\n");
429
430 ret = pBCryptHashData(hash, NULL, 0, 0);
431 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
432
433 ret = pBCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
434 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
435
436 test_hash_length(hash, 48);
437 test_alg_name(hash, "SHA384");
438
439 memset(sha384, 0, sizeof(sha384));
440 ret = pBCryptFinishHash(hash, sha384, sizeof(sha384), 0);
441 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
442 format_hash( sha384, sizeof(sha384), str );
443 ok(!strcmp(str, expected), "got %s\n", str);
444
445 ret = pBCryptDestroyHash(hash);
446 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
447
448 ret = pBCryptCloseAlgorithmProvider(alg, 0);
449 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
450
451 alg = NULL;
452 ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA384_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
453 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
454 ok(alg != NULL, "alg not set\n");
455
456 hash = NULL;
457 len = sizeof(buf_hmac);
458 ret = pBCryptCreateHash(alg, &hash, buf_hmac, len, (UCHAR *)"key", sizeof("key"), 0);
459 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
460 ok(hash != NULL, "hash not set\n");
461
462 ret = pBCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
463 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
464
465 test_hash_length(hash, 48);
466 test_alg_name(hash, "SHA384");
467
468 memset(sha384_hmac, 0, sizeof(sha384_hmac));
469 ret = pBCryptFinishHash(hash, sha384_hmac, sizeof(sha384_hmac), 0);
470 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
471 format_hash( sha384_hmac, sizeof(sha384_hmac), str );
472 ok(!strcmp(str, expected_hmac), "got %s\n", str);
473
474 ret = pBCryptDestroyHash(hash);
475 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
476
477 ret = pBCryptCloseAlgorithmProvider(alg, 0);
478 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
479 }
480
test_sha512(void)481 static void test_sha512(void)
482 {
483 static const char expected[] =
484 "d55ced17163bf5386f2cd9ff21d6fd7fe576a915065c24744d09cfae4ec84ee1e"
485 "f6ef11bfbc5acce3639bab725b50a1fe2c204f8c820d6d7db0df0ecbc49c5ca";
486 static const char expected_hmac[] =
487 "415fb6b10018ca03b38a1b1399c42ac0be5e8aceddb9a73103f5e543bf2d888f2"
488 "eecf91373941f9315dd730a77937fa92444450fbece86f409d9cb5ec48c6513";
489 BCRYPT_ALG_HANDLE alg;
490 BCRYPT_HASH_HANDLE hash;
491 UCHAR buf[512], buf_hmac[1024], sha512[64], sha512_hmac[64];
492 ULONG size, len;
493 char str[129];
494 NTSTATUS ret;
495
496 alg = NULL;
497 ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA512_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
498 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
499 ok(alg != NULL, "alg not set\n");
500
501 len = size = 0xdeadbeef;
502 ret = pBCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
503 ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret);
504
505 len = size = 0xdeadbeef;
506 ret = pBCryptGetProperty(alg, NULL, (UCHAR *)&len, sizeof(len), &size, 0);
507 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
508
509 len = size = 0xdeadbeef;
510 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0);
511 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
512
513 len = size = 0xdeadbeef;
514 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0);
515 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
516 ok(size == sizeof(len), "got %u\n", size);
517
518 len = size = 0xdeadbeef;
519 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0);
520 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
521 ok(len == 0xdeadbeef, "got %u\n", len);
522 ok(size == sizeof(len), "got %u\n", size);
523
524 len = size = 0xdeadbeef;
525 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len , sizeof(len), &size, 0);
526 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
527 ok(len != 0xdeadbeef, "len not set\n");
528 ok(size == sizeof(len), "got %u\n", size);
529
530 test_hash_length(alg, 64);
531 test_alg_name(alg, "SHA512");
532
533 hash = NULL;
534 len = sizeof(buf);
535 ret = pBCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0);
536 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
537 ok(hash != NULL, "hash not set\n");
538
539 ret = pBCryptHashData(hash, NULL, 0, 0);
540 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
541
542 ret = pBCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
543 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
544
545 test_hash_length(hash, 64);
546 test_alg_name(hash, "SHA512");
547
548 memset(sha512, 0, sizeof(sha512));
549 ret = pBCryptFinishHash(hash, sha512, sizeof(sha512), 0);
550 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
551 format_hash( sha512, sizeof(sha512), str );
552 ok(!strcmp(str, expected), "got %s\n", str);
553
554 ret = pBCryptDestroyHash(hash);
555 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
556
557 ret = pBCryptCloseAlgorithmProvider(alg, 0);
558 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
559
560 alg = NULL;
561 ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA512_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
562 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
563 ok(alg != NULL, "alg not set\n");
564
565 hash = NULL;
566 len = sizeof(buf_hmac);
567 ret = pBCryptCreateHash(alg, &hash, buf_hmac, len, (UCHAR *)"key", sizeof("key"), 0);
568 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
569 ok(hash != NULL, "hash not set\n");
570
571 ret = pBCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
572 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
573
574 test_hash_length(hash, 64);
575 test_alg_name(hash, "SHA512");
576
577 memset(sha512_hmac, 0, sizeof(sha512_hmac));
578 ret = pBCryptFinishHash(hash, sha512_hmac, sizeof(sha512_hmac), 0);
579 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
580 format_hash( sha512_hmac, sizeof(sha512_hmac), str );
581 ok(!strcmp(str, expected_hmac), "got %s\n", str);
582
583 ret = pBCryptDestroyHash(hash);
584 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
585
586 ret = pBCryptCloseAlgorithmProvider(alg, 0);
587 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
588
589 }
590
test_md5(void)591 static void test_md5(void)
592 {
593 static const char expected[] =
594 "e2a3e68d23ce348b8f68b3079de3d4c9";
595 static const char expected_hmac[] =
596 "7bda029b93fa8d817fcc9e13d6bdf092";
597 BCRYPT_ALG_HANDLE alg;
598 BCRYPT_HASH_HANDLE hash;
599 UCHAR buf[512], buf_hmac[1024], md5[16], md5_hmac[16];
600 ULONG size, len;
601 char str[65];
602 NTSTATUS ret;
603
604 alg = NULL;
605 ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_MD5_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
606 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
607 ok(alg != NULL, "alg not set\n");
608
609 len = size = 0xdeadbeef;
610 ret = pBCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
611 ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret);
612
613 len = size = 0xdeadbeef;
614 ret = pBCryptGetProperty(alg, NULL, (UCHAR *)&len, sizeof(len), &size, 0);
615 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
616
617 len = size = 0xdeadbeef;
618 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0);
619 ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
620
621 len = size = 0xdeadbeef;
622 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0);
623 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
624 ok(size == sizeof(len), "got %u\n", size);
625
626 len = size = 0xdeadbeef;
627 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0);
628 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
629 ok(len == 0xdeadbeef, "got %u\n", len);
630 ok(size == sizeof(len), "got %u\n", size);
631
632 len = size = 0xdeadbeef;
633 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len , sizeof(len), &size, 0);
634 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
635 ok(len != 0xdeadbeef, "len not set\n");
636 ok(size == sizeof(len), "got %u\n", size);
637
638 test_hash_length(alg, 16);
639 test_alg_name(alg, "MD5");
640
641 hash = NULL;
642 len = sizeof(buf);
643 ret = pBCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0);
644 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
645 ok(hash != NULL, "hash not set\n");
646
647 ret = pBCryptHashData(hash, NULL, 0, 0);
648 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
649
650 ret = pBCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
651 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
652
653 test_hash_length(hash, 16);
654 test_alg_name(hash, "MD5");
655
656 memset(md5, 0, sizeof(md5));
657 ret = pBCryptFinishHash(hash, md5, sizeof(md5), 0);
658 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
659 format_hash( md5, sizeof(md5), str );
660 ok(!strcmp(str, expected), "got %s\n", str);
661
662 ret = pBCryptDestroyHash(hash);
663 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
664
665 ret = pBCryptCloseAlgorithmProvider(alg, 0);
666 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
667
668 alg = NULL;
669 ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_MD5_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
670 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
671 ok(alg != NULL, "alg not set\n");
672
673 hash = NULL;
674 len = sizeof(buf_hmac);
675 ret = pBCryptCreateHash(alg, &hash, buf_hmac, len, (UCHAR *)"key", sizeof("key"), 0);
676 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
677 ok(hash != NULL, "hash not set\n");
678
679 ret = pBCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
680 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
681
682 test_hash_length(hash, 16);
683 test_alg_name(hash, "MD5");
684
685 memset(md5_hmac, 0, sizeof(md5_hmac));
686 ret = pBCryptFinishHash(hash, md5_hmac, sizeof(md5_hmac), 0);
687 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
688 format_hash( md5_hmac, sizeof(md5_hmac), str );
689 ok(!strcmp(str, expected_hmac), "got %s\n", str);
690
691 ret = pBCryptDestroyHash(hash);
692 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
693
694 ret = pBCryptCloseAlgorithmProvider(alg, 0);
695 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
696 }
697
test_BcryptHash(void)698 static void test_BcryptHash(void)
699 {
700 static const char expected[] =
701 "e2a3e68d23ce348b8f68b3079de3d4c9";
702 static const char expected_hmac[] =
703 "7bda029b93fa8d817fcc9e13d6bdf092";
704 BCRYPT_ALG_HANDLE alg;
705 UCHAR md5[16], md5_hmac[16];
706 char str[65];
707 NTSTATUS ret;
708
709 alg = NULL;
710 ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_MD5_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
711 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
712 ok(alg != NULL, "alg not set\n");
713
714 test_hash_length(alg, 16);
715 test_alg_name(alg, "MD5");
716
717 memset(md5, 0, sizeof(md5));
718 ret = pBCryptHash(alg, NULL, 0, (UCHAR *)"test", sizeof("test"), md5, sizeof(md5));
719 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
720 format_hash( md5, sizeof(md5), str );
721 ok(!strcmp(str, expected), "got %s\n", str);
722
723 ret = pBCryptCloseAlgorithmProvider(alg, 0);
724 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
725
726 alg = NULL;
727 memset(md5_hmac, 0, sizeof(md5_hmac));
728 ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_MD5_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
729 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
730 ok(alg != NULL, "alg not set\n");
731
732 ret = pBCryptHash(alg, (UCHAR *)"key", sizeof("key"), (UCHAR *)"test", sizeof("test"), md5_hmac, sizeof(md5_hmac));
733 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
734 format_hash( md5_hmac, sizeof(md5_hmac), str );
735 ok(!strcmp(str, expected_hmac), "got %s\n", str);
736
737 ret = pBCryptCloseAlgorithmProvider(alg, 0);
738 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
739 }
740
test_rng(void)741 static void test_rng(void)
742 {
743 BCRYPT_ALG_HANDLE alg;
744 ULONG size, len;
745 UCHAR buf[16];
746 NTSTATUS ret;
747
748 alg = NULL;
749 ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
750 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
751 ok(alg != NULL, "alg not set\n");
752
753 len = size = 0xdeadbeef;
754 ret = pBCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
755 ok(ret == STATUS_NOT_SUPPORTED, "got %08x\n", ret);
756
757 test_alg_name(alg, "RNG");
758
759 memset(buf, 0, 16);
760 ret = pBCryptGenRandom(alg, buf, 8, 0);
761 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
762 ok(memcmp(buf, buf + 8, 8), "got zeroes\n");
763
764 ret = pBCryptCloseAlgorithmProvider(alg, 0);
765 ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
766 }
767
START_TEST(bcrypt)768 START_TEST(bcrypt)
769 {
770 HMODULE module;
771
772 module = LoadLibraryA("bcrypt.dll");
773 if (!module)
774 {
775 win_skip("bcrypt.dll not found\n");
776 return;
777 }
778
779 pBCryptOpenAlgorithmProvider = (void *)GetProcAddress(module, "BCryptOpenAlgorithmProvider");
780 pBCryptCloseAlgorithmProvider = (void *)GetProcAddress(module, "BCryptCloseAlgorithmProvider");
781 pBCryptGetFipsAlgorithmMode = (void *)GetProcAddress(module, "BCryptGetFipsAlgorithmMode");
782 pBCryptCreateHash = (void *)GetProcAddress(module, "BCryptCreateHash");
783 pBCryptHash = (void *)GetProcAddress(module, "BCryptHash");
784 pBCryptHashData = (void *)GetProcAddress(module, "BCryptHashData");
785 pBCryptFinishHash = (void *)GetProcAddress(module, "BCryptFinishHash");
786 pBCryptDestroyHash = (void *)GetProcAddress(module, "BCryptDestroyHash");
787 pBCryptGenRandom = (void *)GetProcAddress(module, "BCryptGenRandom");
788 pBCryptGetProperty = (void *)GetProcAddress(module, "BCryptGetProperty");
789
790 test_BCryptGenRandom();
791 test_BCryptGetFipsAlgorithmMode();
792 test_sha1();
793 test_sha256();
794 test_sha384();
795 test_sha512();
796 test_md5();
797 test_rng();
798
799 if (pBCryptHash) /* >= Win 10 */
800 test_BcryptHash();
801 else
802 win_skip("BCryptHash is not available\n");
803
804 FreeLibrary(module);
805 }
806