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 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 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 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 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) 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) 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 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 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 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 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 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 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 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 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