Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/bcrypt/tests/bcrypt.c
4396 views
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
#include <ncrypt.h>
27
#include <wincrypt.h>
28
29
#include "wine/test.h"
30
31
static NTSTATUS (WINAPI *pBCryptHash)(BCRYPT_ALG_HANDLE, UCHAR *, ULONG, UCHAR *, ULONG, UCHAR *, ULONG);
32
static NTSTATUS (WINAPI *pBCryptKeyDerivation)(BCRYPT_KEY_HANDLE,
33
BCryptBufferDesc *, UCHAR *, ULONG, ULONG *, ULONG);
34
35
static void test_BCryptGenRandom(void)
36
{
37
NTSTATUS ret;
38
UCHAR buffer[256];
39
40
ret = BCryptGenRandom(NULL, NULL, 0, 0);
41
ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %#lx\n", ret);
42
ret = BCryptGenRandom(NULL, buffer, 0, 0);
43
ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %#lx\n", ret);
44
ret = BCryptGenRandom(NULL, buffer, sizeof(buffer), 0);
45
ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %#lx\n", ret);
46
ret = BCryptGenRandom(NULL, buffer, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
47
ok(ret == STATUS_SUCCESS, "Expected success, got %#lx\n", ret);
48
ret = BCryptGenRandom(NULL, buffer, sizeof(buffer),
49
BCRYPT_USE_SYSTEM_PREFERRED_RNG|BCRYPT_RNG_USE_ENTROPY_IN_BUFFER);
50
ok(ret == STATUS_SUCCESS, "Expected success, got %#lx\n", ret);
51
ret = BCryptGenRandom(NULL, NULL, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
52
ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %#lx\n", ret);
53
54
/* Zero sized buffer should work too */
55
ret = BCryptGenRandom(NULL, buffer, 0, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
56
ok(ret == STATUS_SUCCESS, "Expected success, got %#lx\n", ret);
57
58
/* Test random number generation - It's impossible for a sane RNG to return 8 zeros */
59
memset(buffer, 0, 16);
60
ret = BCryptGenRandom(NULL, buffer, 8, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
61
ok(ret == STATUS_SUCCESS, "Expected success, got %#lx\n", ret);
62
ok(memcmp(buffer, buffer + 8, 8), "Expected a random number, got 0\n");
63
64
/* Test pseudo handle, which was introduced at the same time as BCryptHash */
65
if (pBCryptHash)
66
{
67
ret = BCryptGenRandom(BCRYPT_RNG_ALG_HANDLE, buffer, sizeof(buffer), 0);
68
ok(ret == STATUS_SUCCESS, "Expected success, got %#lx\n", ret);
69
70
ret = BCryptCloseAlgorithmProvider(BCRYPT_RNG_ALG_HANDLE, 0);
71
ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret);
72
}
73
else win_skip("BCryptGenRandom pseudo handles are not available\n");
74
75
}
76
77
static void test_BCryptGetFipsAlgorithmMode(void)
78
{
79
HKEY hkey = NULL;
80
BOOLEAN expected;
81
BOOLEAN enabled;
82
DWORD value, count[2] = {sizeof(value), sizeof(value)};
83
NTSTATUS ret;
84
85
if (RegOpenKeyW(HKEY_LOCAL_MACHINE,
86
L"System\\CurrentControlSet\\Control\\Lsa\\FIPSAlgorithmPolicy", &hkey) == ERROR_SUCCESS &&
87
RegQueryValueExW(hkey, L"Enabled", NULL, NULL, (void *)&value, &count[0]) == ERROR_SUCCESS)
88
{
89
expected = !!value;
90
}
91
else if (RegOpenKeyW(HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Control\\Lsa", &hkey) == ERROR_SUCCESS &&
92
RegQueryValueExW(hkey, L"FIPSAlgorithmPolicy", NULL, NULL, (void *)&value, &count[0]) == ERROR_SUCCESS)
93
{
94
expected = !!value;
95
}
96
else
97
{
98
expected = FALSE;
99
todo_wine
100
ok(0, "Neither XP or Vista key is present\n");
101
}
102
RegCloseKey(hkey);
103
104
ret = BCryptGetFipsAlgorithmMode(&enabled);
105
ok(ret == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %#lx\n", ret);
106
ok(enabled == expected, "expected result %d, got %d\n", expected, enabled);
107
108
ret = BCryptGetFipsAlgorithmMode(NULL);
109
ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %#lx\n", ret);
110
}
111
112
static void format_hash(const UCHAR *bytes, ULONG size, char *buf)
113
{
114
ULONG i;
115
buf[0] = '\0';
116
for (i = 0; i < size; i++)
117
{
118
sprintf(buf + i * 2, "%02x", bytes[i]);
119
}
120
return;
121
}
122
123
#define test_object_length(a) _test_object_length(__LINE__,a)
124
static void _test_object_length(unsigned line, void *handle)
125
{
126
NTSTATUS status;
127
ULONG len, size;
128
129
len = size = 0xdeadbeef;
130
status = BCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
131
ok_(__FILE__,line)(status == STATUS_INVALID_HANDLE, "BCryptGetProperty failed: %#lx\n", status);
132
133
len = size = 0xdeadbeef;
134
status = BCryptGetProperty(handle, NULL, (UCHAR *)&len, sizeof(len), &size, 0);
135
ok_(__FILE__,line)(status == STATUS_INVALID_PARAMETER, "BCryptGetProperty failed: %#lx\n", status);
136
137
len = size = 0xdeadbeef;
138
status = BCryptGetProperty(handle, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0);
139
ok_(__FILE__,line)(status == STATUS_INVALID_PARAMETER, "BCryptGetProperty failed: %#lx\n", status);
140
141
len = size = 0xdeadbeef;
142
status = BCryptGetProperty(handle, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0);
143
ok_(__FILE__,line)(status == STATUS_SUCCESS, "BCryptGetProperty failed: %#lx\n", status);
144
ok_(__FILE__,line)(size == sizeof(len), "got %lu\n", size);
145
146
len = size = 0xdeadbeef;
147
status = BCryptGetProperty(handle, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0);
148
ok_(__FILE__,line)(status == STATUS_BUFFER_TOO_SMALL, "BCryptGetProperty failed: %#lx\n", status);
149
ok_(__FILE__,line)(len == 0xdeadbeef, "got %lu\n", len);
150
ok_(__FILE__,line)(size == sizeof(len), "got %lu\n", size);
151
152
len = size = 0xdeadbeef;
153
status = BCryptGetProperty(handle, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
154
ok_(__FILE__,line)(status == STATUS_SUCCESS, "BCryptGetProperty failed: %#lx\n", status);
155
ok_(__FILE__,line)(len != 0xdeadbeef, "len not set\n");
156
ok_(__FILE__,line)(size == sizeof(len), "got %lu\n", size);
157
}
158
159
#define test_hash_length(a,b) _test_hash_length(__LINE__,a,b)
160
static void _test_hash_length(unsigned line, void *handle, ULONG exlen)
161
{
162
ULONG len = 0xdeadbeef, size = 0xdeadbeef;
163
NTSTATUS status;
164
165
status = BCryptGetProperty(handle, BCRYPT_HASH_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
166
ok_(__FILE__,line)(status == STATUS_SUCCESS, "BCryptGetProperty failed: %#lx\n", status);
167
ok_(__FILE__,line)(size == sizeof(len), "got %lu\n", size);
168
ok_(__FILE__,line)(len == exlen, "len = %lu, expected %lu\n", len, exlen);
169
}
170
171
#define test_alg_name(a,b) _test_alg_name(__LINE__,a,b)
172
static void _test_alg_name(unsigned line, void *handle, const WCHAR *exname)
173
{
174
ULONG size = 0xdeadbeef;
175
UCHAR buf[256];
176
const WCHAR *name = (const WCHAR*)buf;
177
NTSTATUS status;
178
179
status = BCryptGetProperty(handle, BCRYPT_ALGORITHM_NAME, buf, sizeof(buf), &size, 0);
180
ok_(__FILE__,line)(status == STATUS_SUCCESS, "BCryptGetProperty failed: %#lx\n", status);
181
ok_(__FILE__,line)(size == (lstrlenW(exname) + 1) * sizeof(WCHAR), "got %lu\n", size);
182
ok_(__FILE__,line)(!lstrcmpW(name, exname), "alg name = %s, expected %s\n", wine_dbgstr_w(name),
183
wine_dbgstr_w(exname));
184
}
185
186
struct hash_test
187
{
188
const WCHAR *alg;
189
unsigned hash_size;
190
const char *hash;
191
const char *hash2;
192
const char *hmac_hash;
193
const char *hmac_hash2;
194
};
195
196
static void test_hash(const struct hash_test *test)
197
{
198
BCRYPT_ALG_HANDLE alg;
199
BCRYPT_HASH_HANDLE hash;
200
UCHAR buf[512], buf_hmac[1024], hash_buf[128], hmac_hash[128];
201
char str[512];
202
NTSTATUS ret;
203
ULONG len;
204
205
alg = NULL;
206
ret = BCryptOpenAlgorithmProvider(&alg, test->alg, MS_PRIMITIVE_PROVIDER, 0);
207
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
208
ok(alg != NULL, "alg not set\n");
209
210
test_object_length(alg);
211
test_hash_length(alg, test->hash_size);
212
test_alg_name(alg, test->alg);
213
214
hash = NULL;
215
len = sizeof(buf);
216
ret = BCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0);
217
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
218
ok(hash != NULL, "hash not set\n");
219
220
ret = BCryptHashData(hash, NULL, 0, 0);
221
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
222
223
ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
224
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
225
226
test_hash_length(hash, test->hash_size);
227
test_alg_name(hash, test->alg);
228
229
memset(hash_buf, 0, sizeof(hash_buf));
230
ret = BCryptFinishHash(hash, hash_buf, test->hash_size, 0);
231
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
232
format_hash( hash_buf, test->hash_size, str );
233
ok(!strcmp(str, test->hash), "got %s\n", str);
234
235
ret = BCryptDestroyHash(hash);
236
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
237
238
hash = NULL;
239
len = sizeof(buf);
240
ret = BCryptCreateHash(alg, &hash, buf, len, NULL, 0, BCRYPT_HASH_REUSABLE_FLAG);
241
ok(ret == STATUS_SUCCESS || broken(ret == STATUS_INVALID_PARAMETER) /* < win8 */, "got %#lx\n", ret);
242
if (ret == STATUS_SUCCESS)
243
{
244
ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
245
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
246
247
memset(hash_buf, 0, sizeof(hash_buf));
248
ret = BCryptFinishHash(hash, hash_buf, test->hash_size, 0);
249
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
250
format_hash( hash_buf, test->hash_size, str );
251
ok(!strcmp(str, test->hash), "got %s\n", str);
252
253
/* reuse it */
254
ret = BCryptHashData(hash, (UCHAR *)"tset", sizeof("tset"), 0);
255
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
256
257
memset(hash_buf, 0, sizeof(hash_buf));
258
ret = BCryptFinishHash(hash, hash_buf, test->hash_size, 0);
259
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
260
format_hash( hash_buf, test->hash_size, str );
261
ok(!strcmp(str, test->hash2), "got %s\n", str);
262
263
ret = BCryptDestroyHash(hash);
264
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
265
}
266
267
ret = BCryptCloseAlgorithmProvider(alg, 0);
268
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
269
270
alg = NULL;
271
ret = BCryptOpenAlgorithmProvider(&alg, test->alg, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
272
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
273
ok(alg != NULL, "alg not set\n");
274
275
hash = NULL;
276
len = sizeof(buf_hmac);
277
ret = BCryptCreateHash(alg, &hash, buf_hmac, len, (UCHAR *)"key", sizeof("key"), 0);
278
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
279
ok(hash != NULL, "hash not set\n");
280
281
ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
282
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
283
284
test_hash_length(hash, test->hash_size);
285
test_alg_name(hash, test->alg);
286
287
memset(hmac_hash, 0, sizeof(hmac_hash));
288
ret = BCryptFinishHash(hash, hmac_hash, test->hash_size, 0);
289
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
290
format_hash( hmac_hash, test->hash_size, str );
291
ok(!strcmp(str, test->hmac_hash), "got %s\n", str);
292
293
ret = BCryptDestroyHash(hash);
294
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
295
296
hash = NULL;
297
len = sizeof(buf_hmac);
298
ret = BCryptCreateHash(alg, &hash, buf_hmac, len, (UCHAR *)"key", sizeof("key"), BCRYPT_HASH_REUSABLE_FLAG);
299
ok(ret == STATUS_SUCCESS || broken(ret == STATUS_INVALID_PARAMETER) /* < win8 */, "got %#lx\n", ret);
300
if (ret == STATUS_SUCCESS)
301
{
302
ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
303
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
304
305
memset(hmac_hash, 0, sizeof(hmac_hash));
306
ret = BCryptFinishHash(hash, hmac_hash, test->hash_size, 0);
307
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
308
format_hash( hmac_hash, test->hash_size, str );
309
ok(!strcmp(str, test->hmac_hash), "got %s\n", str);
310
311
/* reuse it */
312
ret = BCryptHashData(hash, (UCHAR *)"tset", sizeof("tset"), 0);
313
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
314
315
memset(hmac_hash, 0, sizeof(hmac_hash));
316
ret = BCryptFinishHash(hash, hmac_hash, test->hash_size, 0);
317
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
318
format_hash( hmac_hash, test->hash_size, str );
319
ok(!strcmp(str, test->hmac_hash2), "got %s\n", str);
320
321
ret = BCryptDestroyHash(hash);
322
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
323
}
324
325
ret = BCryptDestroyHash(hash);
326
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
327
328
ret = BCryptDestroyHash(NULL);
329
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
330
331
ret = BCryptCloseAlgorithmProvider(alg, 0);
332
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
333
334
if (pBCryptHash)
335
{
336
ret = pBCryptHash(BCRYPT_SHA1_ALG_HANDLE, NULL, 0, NULL, 0, hash_buf, 20);
337
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
338
ret = pBCryptHash(BCRYPT_SHA1_ALG_HANDLE, NULL, 0, (UCHAR *)"test", sizeof("test"), NULL, 20);
339
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
340
ret = pBCryptHash(BCRYPT_SHA1_ALG_HANDLE, NULL, 0, (UCHAR *)"test", sizeof("test"), hash_buf, 21);
341
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
342
ret = pBCryptHash(BCRYPT_SHA1_ALG_HANDLE, NULL, 0, (UCHAR *)"test", sizeof("test"), hash_buf, 20);
343
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
344
345
ret = BCryptCreateHash(BCRYPT_SHA1_ALG_HANDLE, &hash, NULL, 0, NULL, 0, 0);
346
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
347
ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0);
348
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
349
ret = BCryptFinishHash(hash, hash_buf, 21, 0);
350
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
351
ret = BCryptFinishHash(hash, hash_buf, 20, 0);
352
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
353
ret = BCryptDestroyHash(hash);
354
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
355
}
356
}
357
358
static void test_hashes(void)
359
{
360
static const struct hash_test tests[] =
361
{
362
{ L"SHA1", 20,
363
"961fa64958818f767707072755d7018dcd278e94",
364
"9314f62ff64197143c91fc86de37e9ae776a3fb8",
365
"2472cf65d0e090618d769d3e46f0d9446cf212da",
366
"b2d2ba8cfd714d474cf0d9622cc5d15e1f53d53f",
367
},
368
{ L"SHA256", 32,
369
"ceb73749c899693706ede1e30c9929b3fd5dd926163831c2fb8bd41e6efb1126",
370
"ea0938c118a7b15954f41b85195f2b42aec3a9429c63f593cfa65c137ffaa986",
371
"34c1aa473a4468a91d06e7cdbc75bc4f93b830ccfc2a47ffd74e8e6ed29e4c72",
372
"55feb7052060bd99e33f36eb0982c7f4856eb6a84fbefe19a1afd9faafc3af6f",
373
},
374
{ L"SHA384", 48,
375
"62b21e90c9022b101671ba1f808f8631a8149f0f12904055839a35c1ca78ae53"
376
"63eed1e743a692d70e0504b0cfd12ef9",
377
"724db7c0bbc51ef1ac3fc793083fc54c0e5c423faec9b11378c01c236b19aaaf"
378
"a45177ad055feaf003968cc40ece44c7",
379
"4b3e6d6ff2da121790ab7e7b9247583e3a7eed2db5bd4dabc680303b1608f37d"
380
"fdc836d96a704c03283bc05b4f6c5eb8",
381
"03e1818e5c165a0e54619e513acb06c393e1a6cb0ddbb4036b5f29617b334642"
382
"e6e0be8b214d8508595b17a8c4b4e7db",
383
},
384
{ L"SHA512", 64,
385
"d55ced17163bf5386f2cd9ff21d6fd7fe576a915065c24744d09cfae4ec84ee1"
386
"ef6ef11bfbc5acce3639bab725b50a1fe2c204f8c820d6d7db0df0ecbc49c5ca",
387
"7752d707b54d2b00e7d1c09120d189475b0fd2e31ebb988cf0a01fc8492ddc0b"
388
"3ca9c9ca61d9d7d1fb65ca7665e87f043c1d5bc9f786f8345e951c2d91ac594f",
389
"415fb6b10018ca03b38a1b1399c42ac0be5e8aceddb9a73103f5e543bf2d888f"
390
"2eecf91373941f9315dd730a77937fa92444450fbece86f409d9cb5ec48c6513",
391
"1487bcecba46ae677622fa499e4cb2f0fdf92f6f3427cba76382d537a06e49c3"
392
"3e70a2fc1fc730092bf21128c3704cc6387f6dfbf7e2f9f315bbb894505a1205",
393
},
394
{ L"MD2", 16,
395
"1bb33606ba908912a84221109d29cd7e",
396
"b9a6ad9323b17e2d0cd389dddd6ef78a",
397
"7f05b0638d77f4a27f3a9c4d353cd648",
398
"05980873e6bfdd05dd7b30078de7e42a",
399
},
400
{ L"MD4", 16,
401
"74b5db93c0b41e36ca7074338fc0b637",
402
"a14a9ff2059a8c28f47b01e6bc48a1bf",
403
"bc2e8ac4d8248ed21b8d26227a30ea3a",
404
"b609db0eb4b8669db74f2c20099701e4",
405
},
406
{ L"MD5", 16,
407
"e2a3e68d23ce348b8f68b3079de3d4c9",
408
"bcdd7ca574342aa9db0e212348eacb16",
409
"7bda029b93fa8d817fcc9e13d6bdf092",
410
"dd636ab8e9592c5088e57c37d44c5bb3",
411
}
412
};
413
unsigned i;
414
415
for(i = 0; i < ARRAY_SIZE(tests); i++)
416
test_hash(tests+i);
417
}
418
419
static void test_BcryptHash(void)
420
{
421
static const char expected[] =
422
"e2a3e68d23ce348b8f68b3079de3d4c9";
423
static const char expected_hmac[] =
424
"7bda029b93fa8d817fcc9e13d6bdf092";
425
BCRYPT_ALG_HANDLE alg;
426
UCHAR md5[16], md5_hmac[16];
427
char str[65];
428
NTSTATUS ret;
429
430
if (!pBCryptHash) /* < Win10 */
431
{
432
win_skip("BCryptHash is not available\n");
433
return;
434
}
435
436
alg = NULL;
437
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_MD5_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
438
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
439
ok(alg != NULL, "alg not set\n");
440
441
test_hash_length(alg, 16);
442
test_alg_name(alg, L"MD5");
443
444
memset(md5, 0, sizeof(md5));
445
ret = pBCryptHash(alg, NULL, 0, (UCHAR *)"test", sizeof("test"), md5, sizeof(md5));
446
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
447
format_hash( md5, sizeof(md5), str );
448
ok(!strcmp(str, expected), "got %s\n", str);
449
450
ret = BCryptCloseAlgorithmProvider(alg, 0);
451
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
452
453
alg = NULL;
454
memset(md5_hmac, 0, sizeof(md5_hmac));
455
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_MD5_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
456
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
457
ok(alg != NULL, "alg not set\n");
458
459
ret = pBCryptHash(alg, (UCHAR *)"key", sizeof("key"), (UCHAR *)"test", sizeof("test"), md5_hmac, sizeof(md5_hmac));
460
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
461
format_hash( md5_hmac, sizeof(md5_hmac), str );
462
ok(!strcmp(str, expected_hmac), "got %s\n", str);
463
464
ret = BCryptCloseAlgorithmProvider(alg, 0);
465
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
466
467
if (pBCryptHash)
468
{
469
memset(md5, 0, sizeof(md5));
470
ret = pBCryptHash(BCRYPT_MD5_ALG_HANDLE, NULL, 0, (UCHAR *)"test", sizeof("test"), md5, sizeof(md5));
471
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
472
format_hash( md5, sizeof(md5), str );
473
ok(!strcmp(str, expected), "got %s\n", str);
474
}
475
}
476
477
/* test vectors from RFC 6070 */
478
static UCHAR password[] = "password";
479
static UCHAR salt[] = "salt";
480
static UCHAR long_password[] = "passwordPASSWORDpassword";
481
static UCHAR long_salt[] = "saltSALTsaltSALTsaltSALTsaltSALTsalt";
482
static UCHAR password_NUL[] = "pass\0word";
483
static UCHAR salt_NUL[] = "sa\0lt";
484
485
static UCHAR dk1[] = "0c60c80f961f0e71f3a9b524af6012062fe037a6";
486
static UCHAR dk2[] = "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957";
487
static UCHAR dk3[] = "4b007901b765489abead49d926f721d065a429c1";
488
static UCHAR dk4[] = "364dd6bc200ec7d197f1b85f4a61769010717124";
489
static UCHAR dk5[] = "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038";
490
static UCHAR dk6[] = "56fa6aa75548099dcc37d7f03425e0c3";
491
static UCHAR dk7[] = "8754c32c64b0f524fc50c00f788135de";
492
493
static const struct
494
{
495
ULONG pwd_len;
496
ULONG salt_len;
497
ULONGLONG iterations;
498
ULONG dk_len;
499
UCHAR *pwd;
500
UCHAR *salt;
501
const UCHAR *dk;
502
} rfc6070[] =
503
{
504
{ 8, 4, 1, 20, password, salt, dk1 },
505
{ 8, 4, 2, 20, password, salt, dk2 },
506
{ 8, 4, 4096, 20, password, salt, dk3 },
507
{ 8, 4, 1000000, 20, password, salt, dk4 },
508
{ 24, 36, 4096, 25, long_password, long_salt, dk5 },
509
{ 9, 5, 4096, 16, password_NUL, salt_NUL, dk6 },
510
{ 8, 0, 1, 16, password, NULL, dk7 }
511
};
512
513
static void test_BcryptDeriveKeyPBKDF2(void)
514
{
515
BCRYPT_ALG_HANDLE alg;
516
UCHAR buf[25];
517
char str[51];
518
NTSTATUS ret;
519
ULONG i;
520
521
alg = NULL;
522
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER,
523
BCRYPT_ALG_HANDLE_HMAC_FLAG);
524
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
525
ok(alg != NULL, "alg not set\n");
526
527
test_hash_length(alg, 20);
528
test_alg_name(alg, L"SHA1");
529
530
ret = BCryptDeriveKeyPBKDF2(alg, rfc6070[0].pwd, rfc6070[0].pwd_len, rfc6070[0].salt, rfc6070[0].salt_len,
531
0, buf, rfc6070[0].dk_len, 0);
532
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
533
534
for (i = 0; i < ARRAY_SIZE(rfc6070); i++)
535
{
536
memset(buf, 0, sizeof(buf));
537
ret = BCryptDeriveKeyPBKDF2(alg, rfc6070[i].pwd, rfc6070[i].pwd_len, rfc6070[i].salt, rfc6070[i].salt_len,
538
rfc6070[i].iterations, buf, rfc6070[i].dk_len, 0);
539
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
540
format_hash(buf, rfc6070[i].dk_len, str);
541
ok(!memcmp(str, rfc6070[i].dk, rfc6070[i].dk_len), "got %s\n", str);
542
}
543
544
ret = BCryptCloseAlgorithmProvider(alg, 0);
545
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
546
547
if (pBCryptHash)
548
{
549
ret = BCryptDeriveKeyPBKDF2(BCRYPT_HMAC_SHA1_ALG_HANDLE, rfc6070[0].pwd, rfc6070[0].pwd_len, rfc6070[0].salt,
550
rfc6070[0].salt_len, 1, buf, rfc6070[0].dk_len, 0);
551
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
552
}
553
}
554
555
static void test_rng(void)
556
{
557
BCRYPT_ALG_HANDLE alg;
558
ULONG size, len;
559
UCHAR buf[16];
560
NTSTATUS ret;
561
562
alg = NULL;
563
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
564
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
565
ok(alg != NULL, "alg not set\n");
566
567
len = size = 0xdeadbeef;
568
ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
569
ok(ret == STATUS_NOT_SUPPORTED, "got %#lx\n", ret);
570
571
len = size = 0xdeadbeef;
572
ret = BCryptGetProperty(alg, BCRYPT_HASH_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
573
ok(ret == STATUS_NOT_SUPPORTED, "got %#lx\n", ret);
574
575
test_alg_name(alg, L"RNG");
576
577
memset(buf, 0, 16);
578
ret = BCryptGenRandom(alg, buf, 8, 0);
579
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
580
ok(memcmp(buf, buf + 8, 8), "got zeroes\n");
581
582
ret = BCryptCloseAlgorithmProvider(alg, 0);
583
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
584
}
585
586
static void test_aes(void)
587
{
588
BCRYPT_KEY_LENGTHS_STRUCT key_lengths;
589
BCRYPT_ALG_HANDLE alg;
590
ULONG size, len;
591
UCHAR mode[64];
592
NTSTATUS ret;
593
594
alg = NULL;
595
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_AES_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
596
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
597
ok(alg != NULL, "alg not set\n");
598
599
len = size = 0;
600
ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
601
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
602
ok(len, "expected non-zero len\n");
603
ok(size == sizeof(len), "got %lu\n", size);
604
605
len = size = 0;
606
ret = BCryptGetProperty(alg, BCRYPT_BLOCK_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
607
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
608
ok(len == 16, "got %lu\n", len);
609
ok(size == sizeof(len), "got %lu\n", size);
610
611
size = 0;
612
ret = BCryptGetProperty(alg, BCRYPT_CHAINING_MODE, mode, 0, &size, 0);
613
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
614
ok(size == 64, "got %lu\n", size);
615
616
size = 0;
617
ret = BCryptGetProperty(alg, BCRYPT_CHAINING_MODE, mode, sizeof(mode) - 1, &size, 0);
618
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
619
ok(size == 64, "got %lu\n", size);
620
621
size = 0;
622
memset(mode, 0, sizeof(mode));
623
ret = BCryptGetProperty(alg, BCRYPT_CHAINING_MODE, mode, sizeof(mode), &size, 0);
624
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
625
ok(!lstrcmpW((const WCHAR *)mode, BCRYPT_CHAIN_MODE_CBC), "got %s\n", wine_dbgstr_w((const WCHAR *)mode));
626
ok(size == 64, "got %lu\n", size);
627
628
size = 0;
629
memset(&key_lengths, 0, sizeof(key_lengths));
630
ret = BCryptGetProperty(alg, BCRYPT_KEY_LENGTHS, (UCHAR*)&key_lengths, sizeof(key_lengths), &size, 0);
631
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
632
ok(size == sizeof(key_lengths), "got %lu\n", size);
633
ok(key_lengths.dwMinLength == 128, "Expected 128, got %lu\n", key_lengths.dwMinLength);
634
ok(key_lengths.dwMaxLength == 256, "Expected 256, got %lu\n", key_lengths.dwMaxLength);
635
ok(key_lengths.dwIncrement == 64, "Expected 64, got %lu\n", key_lengths.dwIncrement);
636
637
ret = BCryptSetProperty(alg, BCRYPT_CHAINING_MODE, (UCHAR *)BCRYPT_CHAIN_MODE_GCM, 0, 0);
638
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
639
640
size = 0;
641
memset(mode, 0, sizeof(mode));
642
ret = BCryptGetProperty(alg, BCRYPT_CHAINING_MODE, mode, sizeof(mode), &size, 0);
643
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
644
ok(!lstrcmpW((const WCHAR *)mode, BCRYPT_CHAIN_MODE_GCM), "got %s\n", wine_dbgstr_w((const WCHAR *)mode));
645
ok(size == 64, "got %lu\n", size);
646
647
ret = BCryptSetProperty(alg, BCRYPT_CHAINING_MODE, (UCHAR *)BCRYPT_CHAIN_MODE_CFB, 0, 0);
648
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
649
650
size = 0;
651
memset(mode, 0, sizeof(mode));
652
ret = BCryptGetProperty(alg, BCRYPT_CHAINING_MODE, mode, sizeof(mode), &size, 0);
653
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
654
ok(!lstrcmpW((const WCHAR *)mode, BCRYPT_CHAIN_MODE_CFB), "got %s\n", wine_dbgstr_w((const WCHAR *)mode));
655
ok(size == 64, "got %lu\n", size);
656
657
test_alg_name(alg, L"AES");
658
659
ret = BCryptCloseAlgorithmProvider(alg, 0);
660
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
661
662
if (pBCryptHash)
663
{
664
ret = BCryptSetProperty(BCRYPT_AES_CBC_ALG_HANDLE, BCRYPT_CHAINING_MODE, (UCHAR *)BCRYPT_CHAIN_MODE_GCM, 0, 0);
665
ok(ret == STATUS_ACCESS_DENIED, "got %#lx\n", ret);
666
667
size = 0;
668
memset(mode, 0, sizeof(mode));
669
ret = BCryptGetProperty(BCRYPT_AES_CBC_ALG_HANDLE, BCRYPT_CHAINING_MODE, mode, sizeof(mode), &size, 0);
670
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
671
ok(!lstrcmpW((const WCHAR *)mode, BCRYPT_CHAIN_MODE_CBC), "got %s\n", wine_dbgstr_w((const WCHAR *)mode));
672
ok(size == 64, "got %lu\n", size);
673
}
674
}
675
676
static void test_3des(void)
677
{
678
BCRYPT_KEY_LENGTHS_STRUCT key_lengths;
679
BCRYPT_ALG_HANDLE alg;
680
ULONG size, len;
681
UCHAR mode[64];
682
NTSTATUS ret;
683
684
alg = NULL;
685
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_3DES_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
686
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
687
ok(alg != NULL, "alg not set\n");
688
689
len = size = 0;
690
ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
691
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
692
ok(len, "expected non-zero len\n");
693
ok(size == sizeof(len), "got %lu\n", size);
694
695
len = size = 0;
696
ret = BCryptGetProperty(alg, BCRYPT_BLOCK_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
697
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
698
ok(len == 8, "got %lu\n", len);
699
ok(size == sizeof(len), "got %lu\n", size);
700
701
size = 0;
702
ret = BCryptGetProperty(alg, BCRYPT_CHAINING_MODE, mode, 0, &size, 0);
703
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
704
ok(size == 64, "got %lu\n", size);
705
706
size = 0;
707
ret = BCryptGetProperty(alg, BCRYPT_CHAINING_MODE, mode, sizeof(mode) - 1, &size, 0);
708
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
709
ok(size == 64, "got %lu\n", size);
710
711
size = 0;
712
memset(mode, 0, sizeof(mode));
713
ret = BCryptGetProperty(alg, BCRYPT_CHAINING_MODE, mode, sizeof(mode), &size, 0);
714
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
715
ok(!lstrcmpW((const WCHAR *)mode, BCRYPT_CHAIN_MODE_CBC), "got %s\n", wine_dbgstr_w((const WCHAR *)mode));
716
ok(size == 64, "got %lu\n", size);
717
718
size = 0;
719
memset(&key_lengths, 0, sizeof(key_lengths));
720
ret = BCryptGetProperty(alg, BCRYPT_KEY_LENGTHS, (UCHAR*)&key_lengths, sizeof(key_lengths), &size, 0);
721
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
722
ok(size == sizeof(key_lengths), "got %lu\n", size);
723
ok(key_lengths.dwMinLength == 192, "Expected 192, got %lu\n", key_lengths.dwMinLength);
724
ok(key_lengths.dwMaxLength == 192, "Expected 192, got %lu\n", key_lengths.dwMaxLength);
725
ok(key_lengths.dwIncrement == 0, "Expected 0, got %lu\n", key_lengths.dwIncrement);
726
727
memcpy(mode, BCRYPT_CHAIN_MODE_GCM, sizeof(BCRYPT_CHAIN_MODE_GCM));
728
ret = BCryptSetProperty(alg, BCRYPT_CHAINING_MODE, mode, 0, 0);
729
ok(ret == STATUS_NOT_SUPPORTED, "got %#lx\n", ret);
730
731
test_alg_name(alg, L"3DES");
732
733
ret = BCryptCloseAlgorithmProvider(alg, 0);
734
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
735
}
736
737
static void test_BCryptGenerateSymmetricKey(void)
738
{
739
static UCHAR secret[] =
740
{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
741
static UCHAR iv[] =
742
{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
743
static UCHAR data[] =
744
{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
745
static UCHAR expected[] =
746
{0xc6,0xa1,0x3b,0x37,0x87,0x8f,0x5b,0x82,0x6f,0x4f,0x81,0x62,0xa1,0xc8,0xd8,0x79};
747
static UCHAR expected2[] =
748
{0xb5,0x8a,0x10,0x64,0xd8,0xac,0xa9,0x9b,0xd9,0xb0,0x40,0x5b,0x85,0x45,0xf5,0xbb};
749
static UCHAR expected3[] =
750
{0xe3,0x7c,0xd3,0x63,0xdd,0x7c,0x87,0xa0,0x9a,0xff,0x0e,0x3e,0x60,0xe0,0x9c,0x82};
751
BCRYPT_ALG_HANDLE aes;
752
BCRYPT_KEY_HANDLE key, key2;
753
UCHAR *buf, ciphertext[16], plaintext[16], ivbuf[16], mode[64];
754
BCRYPT_KEY_LENGTHS_STRUCT key_lengths;
755
ULONG size, len, len2, i;
756
NTSTATUS ret;
757
DWORD keylen;
758
759
ret = BCryptOpenAlgorithmProvider(&aes, BCRYPT_AES_ALGORITHM, NULL, 0);
760
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
761
762
len = size = 0xdeadbeef;
763
ret = BCryptGetProperty(aes, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
764
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
765
len2 = len;
766
767
key = (void *)0xdeadbeef;
768
ret = BCryptGenerateSymmetricKey(NULL, &key, NULL, 0, secret, sizeof(secret), 0);
769
ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret);
770
ok(key == (void *)0xdeadbeef, "got %p\n", key);
771
772
key = NULL;
773
buf = calloc(1, len);
774
775
key = (BCRYPT_KEY_HANDLE)0xdeadbeef;
776
ret = BCryptGenerateSymmetricKey(aes, &key, buf, len, secret, 1, 0);
777
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
778
ok(key == (HANDLE)0xdeadbeef, "got unexpected key %p.\n", key);
779
780
key = (BCRYPT_KEY_HANDLE)0xdeadbeef;
781
ret = BCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret) + 1, 0);
782
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
783
ok(key == (HANDLE)0xdeadbeef, "got unexpected key %p.\n", key);
784
785
ret = BCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0);
786
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
787
ok(key != NULL, "key not set\n");
788
789
keylen = 0;
790
ret = BCryptGetProperty(key, BCRYPT_KEY_STRENGTH, (UCHAR *)&keylen, sizeof(keylen), &size, 0);
791
ok(!ret, "got %#lx\n", ret);
792
ok(size == sizeof(keylen), "got %lu\n", size);
793
ok(keylen == 128, "got %lu\n", keylen);
794
795
ret = BCryptSetProperty(aes, BCRYPT_CHAINING_MODE, (UCHAR *)BCRYPT_CHAIN_MODE_CBC,
796
sizeof(BCRYPT_CHAIN_MODE_CBC), 0);
797
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
798
799
todo_wine
800
{
801
keylen = 512;
802
ret = BCryptSetProperty(aes, BCRYPT_KEY_LENGTH, (UCHAR *)&keylen, sizeof(keylen), 0);
803
ok(ret == STATUS_NOT_SUPPORTED, "got %#lx\n", ret);
804
}
805
806
size = 0;
807
memset(mode, 0, sizeof(mode));
808
ret = BCryptGetProperty(key, BCRYPT_CHAINING_MODE, mode, sizeof(mode), &size, 0);
809
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
810
ok(!lstrcmpW((const WCHAR *)mode, BCRYPT_CHAIN_MODE_CBC), "got %s\n", wine_dbgstr_w((const WCHAR *)mode));
811
ok(size == 64, "got %lu\n", size);
812
813
ret = BCryptSetProperty(key, BCRYPT_CHAINING_MODE, (UCHAR *)BCRYPT_CHAIN_MODE_ECB, 0, 0);
814
ok(ret == STATUS_SUCCESS || broken(ret == STATUS_NOT_SUPPORTED) /* < Win 8 */, "got %#lx\n", ret);
815
if (ret == STATUS_SUCCESS)
816
{
817
size = 0;
818
memset(mode, 0, sizeof(mode));
819
ret = BCryptGetProperty(key, BCRYPT_CHAINING_MODE, mode, sizeof(mode), &size, 0);
820
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
821
ok(!lstrcmpW((const WCHAR *)mode, BCRYPT_CHAIN_MODE_ECB), "got %s\n", wine_dbgstr_w((const WCHAR *)mode));
822
ok(size == 64, "got %lu\n", size);
823
}
824
825
ret = BCryptSetProperty(key, BCRYPT_CHAINING_MODE, (UCHAR *)BCRYPT_CHAIN_MODE_CBC,
826
sizeof(BCRYPT_CHAIN_MODE_CBC), 0);
827
ok(ret == STATUS_SUCCESS || broken(ret == STATUS_NOT_SUPPORTED) /* < Win 8 */, "got %#lx\n", ret);
828
829
size = 0xdeadbeef;
830
ret = BCryptEncrypt(key, NULL, 0, NULL, NULL, 0, NULL, 0, &size, 0);
831
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
832
ok(!size, "got %lu\n", size);
833
834
size = 0;
835
memcpy(ivbuf, iv, sizeof(iv));
836
ret = BCryptEncrypt(key, data, 16, NULL, ivbuf, 16, NULL, 0, &size, 0);
837
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
838
ok(size == 16, "got %lu\n", size);
839
ok(!memcmp(ivbuf, iv, sizeof(iv)), "wrong iv data.\n");
840
841
size = 0;
842
memcpy(ivbuf, iv, sizeof(iv));
843
memset(ciphertext, 0, sizeof(ciphertext));
844
ret = BCryptEncrypt(key, data, 16, NULL, ivbuf, 16, ciphertext, 16, &size, 0);
845
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
846
ok(size == 16, "got %lu\n", size);
847
ok(!memcmp(ciphertext, expected, sizeof(expected)), "wrong data\n");
848
for (i = 0; i < 16; i++)
849
ok(ciphertext[i] == expected[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected[i]);
850
ok(!memcmp(ivbuf, ciphertext, sizeof(iv)), "wrong iv data.\n");
851
852
size = 0;
853
memset(ciphertext, 0, sizeof(ciphertext));
854
ret = BCryptEncrypt(key, data, 16, NULL, NULL, 0, ciphertext, 16, &size, 0);
855
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
856
ok(size == 16, "got %lu\n", size);
857
ok(!memcmp(ciphertext, expected2, sizeof(expected2)), "wrong data\n");
858
859
size = 0;
860
memcpy(ivbuf, iv, sizeof(iv));
861
++ivbuf[0];
862
memset(ciphertext, 0, sizeof(ciphertext));
863
ret = BCryptEncrypt(key, data, 16, NULL, ivbuf, 16, ciphertext, 16, &size, 0);
864
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
865
ok(size == 16, "got %lu\n", size);
866
ok(!memcmp(ciphertext, expected3, sizeof(expected3)), "wrong data\n");
867
for (i = 0; i < 16; i++)
868
ok(ciphertext[i] == expected3[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected3[i]);
869
ok(!memcmp(ivbuf, ciphertext, sizeof(iv)), "wrong iv data.\n");
870
871
key2 = (void *)0xdeadbeef;
872
ret = BCryptDuplicateKey(NULL, &key2, NULL, 0, 0);
873
ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret);
874
ok(key2 == (void *)0xdeadbeef, "got %p\n", key2);
875
876
if (0) /* crashes on some Windows versions */
877
{
878
ret = BCryptDuplicateKey(key, NULL, NULL, 0, 0);
879
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
880
}
881
882
key2 = (void *)0xdeadbeef;
883
ret = BCryptDuplicateKey(key, &key2, NULL, 0, 0);
884
ok(ret == STATUS_SUCCESS || broken(ret == STATUS_INVALID_PARAMETER), "got %#lx\n", ret);
885
886
if (ret == STATUS_SUCCESS)
887
{
888
size = 0;
889
memcpy(ivbuf, iv, sizeof(iv));
890
memset(ciphertext, 0, sizeof(ciphertext));
891
ret = BCryptEncrypt(key2, data, 16, NULL, ivbuf, 16, ciphertext, 16, &size, 0);
892
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
893
ok(size == 16, "got %lu\n", size);
894
ok(!memcmp(ciphertext, expected, sizeof(expected)), "wrong data\n");
895
for (i = 0; i < 16; i++)
896
ok(ciphertext[i] == expected[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected[i]);
897
ok(!memcmp(ivbuf, ciphertext, sizeof(iv)), "wrong iv data.\n");
898
899
ret = BCryptDestroyKey(key2);
900
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
901
}
902
903
size = 0xdeadbeef;
904
ret = BCryptDecrypt(key, NULL, 0, NULL, NULL, 0, NULL, 0, &size, 0);
905
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
906
ok(!size, "got %lu\n", size);
907
908
size = 0;
909
memcpy(ivbuf, iv, sizeof(iv));
910
ret = BCryptDecrypt(key, ciphertext, 16, NULL, ivbuf, 16, NULL, 0, &size, 0);
911
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
912
ok(size == 16, "got %lu\n", size);
913
914
size = 0;
915
memcpy(ivbuf, iv, sizeof(iv));
916
memset(plaintext, 0, sizeof(plaintext));
917
ret = BCryptDecrypt(key, ciphertext, 16, NULL, ivbuf, 16, plaintext, 16, &size, 0);
918
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
919
ok(size == 16, "got %lu\n", size);
920
ok(!memcmp(plaintext, data, sizeof(data)), "wrong data\n");
921
ok(!memcmp(ivbuf, ciphertext, sizeof(iv)), "wrong iv data.\n");
922
923
memset(mode, 0, sizeof(mode));
924
ret = BCryptGetProperty(key, BCRYPT_CHAINING_MODE, mode, sizeof(mode), &size, 0);
925
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
926
ok(!lstrcmpW((const WCHAR *)mode, BCRYPT_CHAIN_MODE_CBC), "wrong mode\n");
927
928
len = 0;
929
size = 0;
930
ret = BCryptGetProperty(key, BCRYPT_BLOCK_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
931
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
932
ok(len == 16, "got %lu\n", len);
933
ok(size == sizeof(len), "got %lu\n", size);
934
935
size = 0;
936
memset(&key_lengths, 0, sizeof(key_lengths));
937
ret = BCryptGetProperty(aes, BCRYPT_KEY_LENGTHS, (UCHAR*)&key_lengths, sizeof(key_lengths), &size, 0);
938
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
939
ok(size == sizeof(key_lengths), "got %lu\n", size);
940
ok(key_lengths.dwMinLength == 128, "Expected 128, got %lu\n", key_lengths.dwMinLength);
941
ok(key_lengths.dwMaxLength == 256, "Expected 256, got %lu\n", key_lengths.dwMaxLength);
942
ok(key_lengths.dwIncrement == 64, "Expected 64, got %lu\n", key_lengths.dwIncrement);
943
944
ret = BCryptDestroyKey(key);
945
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
946
947
if (pBCryptHash)
948
{
949
ret = BCryptGenerateSymmetricKey(BCRYPT_AES_CBC_ALG_HANDLE, &key, buf, len2, secret, sizeof(secret), 0);
950
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
951
ret = BCryptDestroyKey(key);
952
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
953
}
954
955
free(buf);
956
ret = BCryptCloseAlgorithmProvider(aes, 0);
957
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
958
}
959
960
#define RACE_TEST_COUNT 200
961
static LONG encrypt_race_start_barrier;
962
963
static DWORD WINAPI encrypt_race_thread(void *parameter)
964
{
965
static UCHAR nonce[] =
966
{0x11,0x20,0x30,0x40,0x50,0x60,0x10,0x20,0x30,0x40,0x50,0x60};
967
static UCHAR auth_data[] =
968
{0x61,0x50,0x40,0x30,0x20,0x10,0x60,0x50,0x40,0x30,0x20,0x10};
969
static UCHAR data2[] =
970
{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
971
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10};
972
static UCHAR expected4[] =
973
{0xb2,0x27,0x19,0x09,0xc7,0x89,0xdc,0x52,0x24,0x83,0x3a,0x55,0x34,0x76,0x2c,0xbf,
974
0x15,0xa1,0xcb,0x40,0x78,0x11,0xba,0xbc,0xa4,0x76,0x69,0x7c,0x75,0x4f,0x11,0xba};
975
static UCHAR expected_tag3[] =
976
{0xef,0xee,0x75,0x99,0xb8,0x12,0xe9,0xf0,0xb4,0xcc,0x65,0x11,0x67,0x60,0x2d,0xe6};
977
978
BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO auth_info;
979
BCRYPT_KEY_HANDLE key = parameter;
980
UCHAR ciphertext[48], tag[16];
981
unsigned int i, test;
982
NTSTATUS ret;
983
ULONG size;
984
985
memset(&auth_info, 0, sizeof(auth_info));
986
auth_info.cbSize = sizeof(auth_info);
987
auth_info.dwInfoVersion = 1;
988
auth_info.pbNonce = nonce;
989
auth_info.cbNonce = sizeof(nonce);
990
auth_info.pbTag = tag;
991
auth_info.cbTag = sizeof(tag);
992
auth_info.pbAuthData = auth_data;
993
auth_info.cbAuthData = sizeof(auth_data);
994
995
InterlockedIncrement(&encrypt_race_start_barrier);
996
while (InterlockedCompareExchange(&encrypt_race_start_barrier, 3, 2) != 2)
997
;
998
999
for (test = 0; test < RACE_TEST_COUNT; ++test)
1000
{
1001
size = 0;
1002
memset(ciphertext, 0xff, sizeof(ciphertext));
1003
memset(tag, 0xff, sizeof(tag));
1004
ret = BCryptEncrypt(key, data2, 32, &auth_info, NULL, 0, ciphertext, 32, &size, 0);
1005
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1006
ok(size == 32, "got %lu\n", size);
1007
ok(!memcmp(ciphertext, expected4, sizeof(expected4)), "wrong data\n");
1008
ok(!memcmp(tag, expected_tag3, sizeof(expected_tag3)), "wrong tag\n");
1009
for (i = 0; i < 32; i++)
1010
ok(ciphertext[i] == expected4[i], "%u: %02x != %02x\n", i, ciphertext[i], expected4[i]);
1011
for (i = 0; i < 16; i++)
1012
ok(tag[i] == expected_tag3[i], "%u: %02x != %02x\n", i, tag[i], expected_tag3[i]);
1013
}
1014
1015
return 0;
1016
}
1017
1018
static void test_BCryptEncrypt(void)
1019
{
1020
static UCHAR nonce[] =
1021
{0x10,0x20,0x30,0x40,0x50,0x60,0x10,0x20,0x30,0x40,0x50,0x60};
1022
static UCHAR auth_data[] =
1023
{0x60,0x50,0x40,0x30,0x20,0x10,0x60,0x50,0x40,0x30,0x20,0x10};
1024
static UCHAR secret[] =
1025
{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
1026
static UCHAR secret256[] =
1027
{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
1028
0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00};
1029
static UCHAR iv[] =
1030
{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
1031
static UCHAR data[] =
1032
{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10};
1033
static UCHAR data2[] =
1034
{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
1035
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10};
1036
static UCHAR expected[] =
1037
{0xc6,0xa1,0x3b,0x37,0x87,0x8f,0x5b,0x82,0x6f,0x4f,0x81,0x62,0xa1,0xc8,0xd8,0x79};
1038
static UCHAR expected2[] =
1039
{0xc6,0xa1,0x3b,0x37,0x87,0x8f,0x5b,0x82,0x6f,0x4f,0x81,0x62,0xa1,0xc8,0xd8,0x79,
1040
0x28,0x73,0x3d,0xef,0x84,0x8f,0xb0,0xa6,0x5d,0x1a,0x51,0xb7,0xec,0x8f,0xea,0xe9};
1041
static UCHAR expected3[] =
1042
{0xc6,0xa1,0x3b,0x37,0x87,0x8f,0x5b,0x82,0x6f,0x4f,0x81,0x62,0xa1,0xc8,0xd8,0x79,
1043
0xb1,0xa2,0x92,0x73,0xbe,0x2c,0x42,0x07,0xa5,0xac,0xe3,0x93,0x39,0x8c,0xb6,0xfb,
1044
0x87,0x5d,0xea,0xa3,0x7e,0x0f,0xde,0xfa,0xd9,0xec,0x6c,0x4e,0x3c,0x76,0x86,0xe4};
1045
static UCHAR expected4[] =
1046
{0xe1,0x82,0xc3,0xc0,0x24,0xfb,0x86,0x85,0xf3,0xf1,0x2b,0x7d,0x09,0xb4,0x73,0x67,
1047
0x86,0x64,0xc3,0xfe,0xa3,0x07,0x61,0xf8,0x16,0xc9,0x78,0x7f,0xe7,0xb1,0xc4,0x94};
1048
static UCHAR expected5[] =
1049
{0x0a,0x94,0x0b,0xb5,0x41,0x6e,0xf0,0x45,0xf1,0xc3,0x94,0x58,0xc6,0x53,0xea,0x5a};
1050
static UCHAR expected6[] =
1051
{0x0a,0x94,0x0b,0xb5,0x41,0x6e,0xf0,0x45,0xf1,0xc3,0x94,0x58,0xc6,0x53,0xea,0x5a,
1052
0x84,0x07,0x66,0xb7,0x49,0xc0,0x9b,0x49,0x74,0x28,0x8c,0x10,0xb9,0xc2,0x09,0x70};
1053
static UCHAR expected7[] =
1054
{0x0a,0x94,0x0b,0xb5,0x41,0x6e,0xf0,0x45,0xf1,0xc3,0x94,0x58,0xc6,0x53,0xea,0x5a,
1055
0x95,0x4f,0x64,0xf2,0xe4,0xe8,0x6e,0x9e,0xee,0x82,0xd2,0x02,0x16,0x68,0x48,0x99,
1056
0x95,0x4f,0x64,0xf2,0xe4,0xe8,0x6e,0x9e,0xee,0x82,0xd2,0x02,0x16,0x68,0x48,0x99};
1057
static UCHAR expected8[] =
1058
{0xb5,0x8a,0x10,0x64,0xd8,0xac,0xa9,0x9b,0xd9,0xb0,0x40,0x5b,0x85,0x45,0xf5,0xbb};
1059
static UCHAR expected9[] =
1060
{0x0a,0x94,0x0b,0xb5,0x41,0x6e,0xf0,0x45,0xf1,0xc3,0x94,0x58,0xc6,0x53,0xea,0x5a};
1061
static UCHAR expected10[] =
1062
{0x66,0xb8,0xbd,0xe5,0x90,0x6c,0xec,0xdf,0xfa,0x8a,0xb2,0xfd,0x92,0x84,0xeb,0xf0,
1063
0x95,0xc4,0xdf,0xa7,0x7a,0x62,0xe4,0xab,0xd4,0x0e,0x94,0x4e,0xd7,0x6e,0xa1,0x47,
1064
0x29,0x4b,0x37,0xfe,0x28,0x6d,0x5f,0x69,0x46,0x30,0x73,0xc0,0xaa,0x42,0xe4,0x46};
1065
static UCHAR expected11[] =
1066
{0x0a,0x22,0xf7,0x96,0xe1,0xb9,0x3e,0x90,0x32,0xcf,0xf8,0x04,0x83,0x8a,0xdf,0xc3};
1067
static UCHAR expected12[] =
1068
{0xb5,0x9d,0xe7,0x8e,0x0f,0x80,0x16,0xc3,0xf6,0x80,0xad,0xf8,0xac,0xef,0xf9,0x9f};
1069
static UCHAR expected13[] =
1070
{0xc6,0x41,0x37,0xd8,0x6f,0x65,0x64,0x1d,0x2b,0xa0,0xad,0xee,0x67,0xba,0x9b,0x5f};
1071
static UCHAR expected14[] =
1072
{0x0a,0x22,0xf7,0x96,0xe1,0xb9,0x3e,0x90,0x32,0xcf,0xf8,0x04,0x83,0x8a,0xdf,0xc3,
1073
0xa5,0xfa,0x54,0xd7,0x62,0x9d,0x8b,0x11,0x3d,0xd8,0xe2,0x95,0xc2,0x23,0x3f,0x29};
1074
static UCHAR expected15[] =
1075
{0x0a,0x22,0xf7,0x96,0xe1,0xb9,0x3e,0x90,0x32,0xcf,0xf8,0x04,0x83,0x8a,0xdf,0xc3,
1076
0xa5,0xe5,0xcd,0x29,0x48,0x37,0x3f,0x92,0x6f,0x09,0x84,0x5a,0xb8,0x88,0xda,0xfd,
1077
0x65,0x00,0x20,0x9a,0xc6,0xdb,0xfa,0x82,0xdb,0xbc,0xf4,0x70,0x7d,0x88,0x86,0xb5};
1078
static UCHAR expected16[] =
1079
{0x64,0xff,0xc6,0x97,0x14,0x5e,0x21,0xfa,0xe8,0x6e,0xba,0xc1,0x0c,0xb1,0x72,0x64,
1080
0x5d,0xf0,0x22,0x72,0xef,0x39,0xe3,0x2f,0x80,0x3e,0x53,0x00,0xc1,0xcf,0x3f,0xbb,
1081
0xea,0x30,0x01,0x78,0x3b,0xba,0x4d,0xca,0xa0,0x2e,0x83,0x5e,0x0e,0xe2,0x65,0xcb};
1082
static UCHAR expected_tag[] =
1083
{0x89,0xb3,0x92,0x00,0x39,0x20,0x09,0xb4,0x6a,0xd6,0xaf,0xca,0x4b,0x5b,0xfd,0xd0};
1084
static UCHAR expected_tag2[] =
1085
{0x9a,0x92,0x32,0x2c,0x61,0x2a,0xae,0xef,0x66,0x2a,0xfb,0x55,0xe9,0x48,0xdf,0xbd};
1086
static UCHAR expected_tag3[] =
1087
{0x17,0x9d,0xc0,0x7a,0xf0,0xcf,0xaa,0xd5,0x1c,0x11,0xc4,0x4b,0xd6,0xa3,0x3e,0x77};
1088
static UCHAR expected_tag4[] =
1089
{0x4c,0x42,0x83,0x9e,0x8d,0x40,0xf1,0x19,0xd6,0x2b,0x1c,0x66,0x03,0x2b,0x39,0x63};
1090
1091
BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO auth_info;
1092
UCHAR *buf, ciphertext[48], ivbuf[16], tag[16];
1093
BCRYPT_AUTH_TAG_LENGTHS_STRUCT tag_length;
1094
ULONG size, len, i, test;
1095
BCRYPT_ALG_HANDLE aes;
1096
BCRYPT_KEY_HANDLE key;
1097
HANDLE hthread;
1098
NTSTATUS ret;
1099
1100
ret = BCryptOpenAlgorithmProvider(&aes, BCRYPT_AES_ALGORITHM, NULL, 0);
1101
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1102
1103
/******************
1104
* AES - CBC mode *
1105
******************/
1106
1107
len = 0xdeadbeef;
1108
size = sizeof(len);
1109
ret = BCryptGetProperty(aes, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
1110
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1111
1112
key = NULL;
1113
buf = calloc(1, len);
1114
ret = BCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0);
1115
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1116
ok(key != NULL, "key not set\n");
1117
1118
/* input size is a multiple of block size */
1119
size = 0;
1120
memcpy(ivbuf, iv, sizeof(iv));
1121
ret = BCryptEncrypt(key, data, 16, NULL, ivbuf, 16, NULL, 0, &size, 0);
1122
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1123
ok(size == 16, "got %lu\n", size);
1124
ok(!memcmp(ivbuf, iv, sizeof(iv)), "wrong iv data.\n");
1125
1126
size = 0;
1127
memcpy(ivbuf, iv, sizeof(iv));
1128
memset(ciphertext, 0, sizeof(ciphertext));
1129
ret = BCryptEncrypt(key, data, 16, NULL, ivbuf, 16, ciphertext, 16, &size, 0);
1130
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1131
ok(size == 16, "got %lu\n", size);
1132
ok(!memcmp(ciphertext, expected, sizeof(expected)), "wrong data\n");
1133
for (i = 0; i < 16; i++)
1134
ok(ciphertext[i] == expected[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected[i]);
1135
ok(!memcmp(ivbuf, ciphertext, sizeof(iv)), "wrong iv data.\n");
1136
1137
/* NULL initialization vector */
1138
size = 0;
1139
memset(ciphertext, 0, sizeof(ciphertext));
1140
ret = BCryptEncrypt(key, data, 16, NULL, NULL, 0, ciphertext, 16, &size, 0);
1141
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1142
ok(size == 16, "got %lu\n", size);
1143
ok(!memcmp(ciphertext, expected8, sizeof(expected8)), "wrong data\n");
1144
1145
/* all zero initialization vector */
1146
size = 0;
1147
memset(ciphertext, 0, sizeof(ciphertext));
1148
memset(ivbuf, 0, sizeof(ivbuf));
1149
ret = BCryptEncrypt(key, data, 16, NULL, ivbuf, 16, ciphertext, 16, &size, 0);
1150
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1151
ok(size == 16, "got %lu\n", size);
1152
ok(!memcmp(ciphertext, expected9, sizeof(expected9)), "wrong data\n");
1153
for (i = 0; i < 16; i++)
1154
ok(ciphertext[i] == expected9[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected9[i]);
1155
ok(!memcmp(ivbuf, ciphertext, sizeof(iv)), "wrong iv data.\n");
1156
1157
/* input size is not a multiple of block size */
1158
size = 0;
1159
memcpy(ivbuf, iv, sizeof(iv));
1160
ret = BCryptEncrypt(key, data, 17, NULL, ivbuf, 16, NULL, 0, &size, 0);
1161
ok(ret == STATUS_INVALID_BUFFER_SIZE, "got %#lx\n", ret);
1162
ok(size == 17, "got %lu\n", size);
1163
1164
/* input size is not a multiple of block size, block padding set */
1165
size = 0;
1166
memcpy(ivbuf, iv, sizeof(iv));
1167
ret = BCryptEncrypt(key, data, 17, NULL, ivbuf, 16, NULL, 0, &size, BCRYPT_BLOCK_PADDING);
1168
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1169
ok(size == 32, "got %lu\n", size);
1170
ok(!memcmp(ivbuf, iv, sizeof(iv)), "wrong iv data.\n");
1171
1172
size = 0;
1173
memcpy(ivbuf, iv, sizeof(iv));
1174
memset(ciphertext, 0, sizeof(ciphertext));
1175
ret = BCryptEncrypt(key, data, 17, NULL, ivbuf, 16, ciphertext, 32, &size, BCRYPT_BLOCK_PADDING);
1176
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1177
ok(size == 32, "got %lu\n", size);
1178
ok(!memcmp(ciphertext, expected2, sizeof(expected2)), "wrong data\n");
1179
for (i = 0; i < 32; i++)
1180
ok(ciphertext[i] == expected2[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected2[i]);
1181
ok(!memcmp(ivbuf, ciphertext + 32 - 16, sizeof(iv)), "wrong iv data.\n");
1182
1183
/* input size is a multiple of block size, block padding set */
1184
size = 0;
1185
memcpy(ivbuf, iv, sizeof(iv));
1186
ret = BCryptEncrypt(key, data2, 32, NULL, ivbuf, 16, NULL, 0, &size, BCRYPT_BLOCK_PADDING);
1187
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1188
ok(size == 48, "got %lu\n", size);
1189
ok(!memcmp(ivbuf, iv, sizeof(iv)), "wrong iv data.\n");
1190
1191
size = 0;
1192
memcpy(ivbuf, iv, sizeof(iv));
1193
memset(ciphertext, 0, sizeof(ciphertext));
1194
ret = BCryptEncrypt(key, data2, 32, NULL, ivbuf, 16, ciphertext, 48, &size, BCRYPT_BLOCK_PADDING);
1195
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1196
ok(size == 48, "got %lu\n", size);
1197
ok(!memcmp(ciphertext, expected3, sizeof(expected3)), "wrong data\n");
1198
for (i = 0; i < 48; i++)
1199
ok(ciphertext[i] == expected3[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected3[i]);
1200
ok(!memcmp(ivbuf, ciphertext + 48 - 16, sizeof(iv)), "wrong iv data.\n");
1201
1202
/* output size too small */
1203
size = 0;
1204
memcpy(ivbuf, iv, sizeof(iv));
1205
memset(ciphertext, 0, sizeof(ciphertext));
1206
ret = BCryptEncrypt(key, data, 17, NULL, ivbuf, 16, ciphertext, 31, &size, BCRYPT_BLOCK_PADDING);
1207
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
1208
ok(size == 32, "got %lu\n", size);
1209
1210
size = 0;
1211
memcpy(ivbuf, iv, sizeof(iv));
1212
memset(ciphertext, 0, sizeof(ciphertext));
1213
ret = BCryptEncrypt(key, data2, 32, NULL, ivbuf, 16, ciphertext, 32, &size, BCRYPT_BLOCK_PADDING);
1214
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
1215
ok(size == 48, "got %lu\n", size);
1216
1217
ret = BCryptDestroyKey(key);
1218
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1219
free(buf);
1220
1221
/* 256 bit key */
1222
buf = calloc(1, len);
1223
1224
ret = BCryptGenerateSymmetricKey(aes, &key, buf, len, secret256, sizeof(secret256), 0);
1225
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1226
ret = BCryptDestroyKey(key);
1227
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1228
1229
/* Key generations succeeds if the key size exceeds maximum and uses maximum key length
1230
* from secret. */
1231
ret = BCryptGenerateSymmetricKey(aes, &key, buf, len, secret256, sizeof(secret256) + 1, 0);
1232
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1233
1234
size = 0;
1235
memcpy(ivbuf, iv, sizeof(iv));
1236
ret = BCryptEncrypt(key, data2, 32, NULL, ivbuf, 16, NULL, 0, &size, BCRYPT_BLOCK_PADDING);
1237
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1238
ok(size == 48, "got %lu\n", size);
1239
ok(!memcmp(ivbuf, iv, sizeof(iv)), "wrong iv data.\n");
1240
1241
size = 0;
1242
memcpy(ivbuf, iv, sizeof(iv));
1243
memset(ciphertext, 0, sizeof(ciphertext));
1244
ret = BCryptEncrypt(key, data2, 32, NULL, ivbuf, 16, ciphertext, 48, &size, BCRYPT_BLOCK_PADDING);
1245
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1246
ok(size == 48, "got %lu\n", size);
1247
ok(!memcmp(ciphertext, expected10, sizeof(expected10)), "wrong data\n");
1248
for (i = 0; i < 48; i++)
1249
ok(ciphertext[i] == expected10[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected10[i]);
1250
ok(!memcmp(ivbuf, ciphertext + 48 - 16, sizeof(iv)), "wrong iv data.\n");
1251
1252
ret = BCryptDestroyKey(key);
1253
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1254
free(buf);
1255
1256
/******************
1257
* AES - GCM mode *
1258
******************/
1259
1260
size = 0;
1261
ret = BCryptGetProperty(aes, BCRYPT_AUTH_TAG_LENGTH, NULL, 0, &size, 0);
1262
ok(ret == STATUS_NOT_SUPPORTED, "got %#lx\n", ret);
1263
1264
ret = BCryptSetProperty(aes, BCRYPT_CHAINING_MODE, (UCHAR*)BCRYPT_CHAIN_MODE_GCM, sizeof(BCRYPT_CHAIN_MODE_GCM), 0);
1265
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1266
1267
size = 0;
1268
ret = BCryptGetProperty(aes, BCRYPT_AUTH_TAG_LENGTH, NULL, 0, &size, 0);
1269
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1270
ok(size == sizeof(tag_length), "got %lu\n", size);
1271
1272
size = 0;
1273
memset(&tag_length, 0, sizeof(tag_length));
1274
ret = BCryptGetProperty(aes, BCRYPT_AUTH_TAG_LENGTH, (UCHAR*)&tag_length, sizeof(tag_length), &size, 0);
1275
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1276
ok(size == sizeof(tag_length), "got %lu\n", size);
1277
ok(tag_length.dwMinLength == 12, "Expected 12, got %lu\n", tag_length.dwMinLength);
1278
ok(tag_length.dwMaxLength == 16, "Expected 16, got %lu\n", tag_length.dwMaxLength);
1279
ok(tag_length.dwIncrement == 1, "Expected 1, got %lu\n", tag_length.dwIncrement);
1280
1281
len = 0xdeadbeef;
1282
size = sizeof(len);
1283
ret = BCryptGetProperty(aes, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
1284
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1285
1286
key = NULL;
1287
buf = calloc(1, len);
1288
ret = BCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0);
1289
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1290
ok(key != NULL, "key not set\n");
1291
1292
ret = BCryptGetProperty(key, BCRYPT_AUTH_TAG_LENGTH, (UCHAR*)&tag_length, sizeof(tag_length), &size, 0);
1293
ok(ret == STATUS_NOT_SUPPORTED, "got %#lx\n", ret);
1294
1295
memset(&auth_info, 0, sizeof(auth_info));
1296
auth_info.cbSize = sizeof(auth_info);
1297
auth_info.dwInfoVersion = 1;
1298
auth_info.pbNonce = nonce;
1299
auth_info.cbNonce = sizeof(nonce);
1300
auth_info.pbTag = tag;
1301
auth_info.cbTag = sizeof(tag);
1302
1303
/* input size is a multiple of block size */
1304
size = 0;
1305
memcpy(ivbuf, iv, sizeof(iv));
1306
memset(ciphertext, 0xff, sizeof(ciphertext));
1307
memset(tag, 0xff, sizeof(tag));
1308
ret = BCryptEncrypt(key, data2, 32, &auth_info, ivbuf, 16, ciphertext, 32, &size, 0);
1309
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1310
ok(size == 32, "got %lu\n", size);
1311
ok(!memcmp(ciphertext, expected4, sizeof(expected4)), "wrong data\n");
1312
ok(!memcmp(tag, expected_tag, sizeof(expected_tag)), "wrong tag\n");
1313
for (i = 0; i < 32; i++)
1314
ok(ciphertext[i] == expected4[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected4[i]);
1315
for (i = 0; i < 16; i++)
1316
ok(tag[i] == expected_tag[i], "%lu: %02x != %02x\n", i, tag[i], expected_tag[i]);
1317
ok(!memcmp(ivbuf, iv, sizeof(iv)), "wrong iv data.\n");
1318
1319
/* NULL initialization vector */
1320
size = 0;
1321
memset(ciphertext, 0xff, sizeof(ciphertext));
1322
memset(tag, 0xff, sizeof(tag));
1323
ret = BCryptEncrypt(key, data2, 32, &auth_info, NULL, 0, ciphertext, 32, &size, 0);
1324
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1325
ok(size == 32, "got %lu\n", size);
1326
ok(!memcmp(ciphertext, expected4, sizeof(expected4)), "wrong data\n");
1327
ok(!memcmp(tag, expected_tag, sizeof(expected_tag)), "wrong tag\n");
1328
for (i = 0; i < 32; i++)
1329
ok(ciphertext[i] == expected4[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected4[i]);
1330
for (i = 0; i < 16; i++)
1331
ok(tag[i] == expected_tag[i], "%lu: %02x != %02x\n", i, tag[i], expected_tag[i]);
1332
1333
/* all zero initialization vector */
1334
size = 0;
1335
memset(ciphertext, 0xff, sizeof(ciphertext));
1336
memset(tag, 0xff, sizeof(tag));
1337
memset(ivbuf, 0, sizeof(ivbuf));
1338
ret = BCryptEncrypt(key, data2, 32, &auth_info, ivbuf, 16, ciphertext, 32, &size, 0);
1339
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1340
ok(size == 32, "got %lu\n", size);
1341
ok(!memcmp(ciphertext, expected4, sizeof(expected4)), "wrong data\n");
1342
ok(!memcmp(tag, expected_tag, sizeof(expected_tag)), "wrong tag\n");
1343
for (i = 0; i < 32; i++)
1344
ok(ciphertext[i] == expected4[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected4[i]);
1345
for (i = 0; i < 16; i++)
1346
ok(tag[i] == expected_tag[i], "%lu: %02x != %02x\n", i, tag[i], expected_tag[i]);
1347
memset(ciphertext, 0, sizeof(iv));
1348
ok(!memcmp(ivbuf, ciphertext, sizeof(iv)), "wrong iv data.\n");
1349
1350
/* input size is not multiple of block size */
1351
size = 0;
1352
memcpy(ivbuf, iv, sizeof(iv));
1353
memset(ciphertext, 0xff, sizeof(ciphertext));
1354
memset(tag, 0xff, sizeof(tag));
1355
ret = BCryptEncrypt(key, data2, 24, &auth_info, ivbuf, 16, ciphertext, 24, &size, 0);
1356
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1357
ok(size == 24, "got %lu\n", size);
1358
ok(!memcmp(ciphertext, expected4, 24), "wrong data\n");
1359
ok(!memcmp(tag, expected_tag2, sizeof(expected_tag2)), "wrong tag\n");
1360
for (i = 0; i < 24; i++)
1361
ok(ciphertext[i] == expected4[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected4[i]);
1362
for (i = 0; i < 16; i++)
1363
ok(tag[i] == expected_tag2[i], "%lu: %02x != %02x\n", i, tag[i], expected_tag2[i]);
1364
ok(!memcmp(ivbuf, iv, sizeof(iv)), "wrong iv data.\n");
1365
1366
/* test with auth data */
1367
auth_info.pbAuthData = auth_data;
1368
auth_info.cbAuthData = sizeof(auth_data);
1369
1370
size = 0;
1371
memcpy(ivbuf, iv, sizeof(iv));
1372
memset(ciphertext, 0xff, sizeof(ciphertext));
1373
memset(tag, 0xff, sizeof(tag));
1374
ret = BCryptEncrypt(key, data2, 32, &auth_info, ivbuf, 16, ciphertext, 32, &size, 0);
1375
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1376
ok(size == 32, "got %lu\n", size);
1377
ok(!memcmp(ciphertext, expected4, sizeof(expected4)), "wrong data\n");
1378
ok(!memcmp(tag, expected_tag3, sizeof(expected_tag3)), "wrong tag\n");
1379
for (i = 0; i < 32; i++)
1380
ok(ciphertext[i] == expected4[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected4[i]);
1381
for (i = 0; i < 16; i++)
1382
ok(tag[i] == expected_tag3[i], "%lu: %02x != %02x\n", i, tag[i], expected_tag3[i]);
1383
ok(!memcmp(ivbuf, iv, sizeof(iv)), "wrong iv data.\n");
1384
1385
memset(tag, 0xff, sizeof(tag));
1386
ret = BCryptEncrypt(key, data2, 0, &auth_info, ivbuf, 16, NULL, 0, &size, 0);
1387
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1388
ok(!size, "got %lu\n", size);
1389
for (i = 0; i < 16; i++)
1390
ok(tag[i] == 0xff, "%lu: %02x != %02x\n", i, tag[i], 0xff);
1391
1392
memset(tag, 0xff, sizeof(tag));
1393
ret = BCryptEncrypt(key, NULL, 0, &auth_info, ivbuf, 16, NULL, 0, &size, 0);
1394
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1395
ok(!size, "got %lu\n", size);
1396
ok(!memcmp(tag, expected_tag4, sizeof(expected_tag4)), "wrong tag\n");
1397
for (i = 0; i < 16; i++)
1398
ok(tag[i] == expected_tag4[i], "%lu: %02x != %02x\n", i, tag[i], expected_tag4[i]);
1399
1400
/* test with padding */
1401
memcpy(ivbuf, iv, sizeof(iv));
1402
memset(ciphertext, 0, sizeof(ciphertext));
1403
ret = BCryptEncrypt(key, data2, 32, &auth_info, ivbuf, 16, ciphertext, 32, &size, BCRYPT_BLOCK_PADDING);
1404
todo_wine ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
1405
1406
memcpy(ivbuf, iv, sizeof(iv));
1407
memset(ciphertext, 0, sizeof(ciphertext));
1408
ret = BCryptEncrypt(key, data2, 32, &auth_info, ivbuf, 16, ciphertext, 48, &size, BCRYPT_BLOCK_PADDING);
1409
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
1410
1411
/* race test */
1412
1413
encrypt_race_start_barrier = 0;
1414
hthread = CreateThread(NULL, 0, encrypt_race_thread, key, 0, NULL);
1415
1416
while (InterlockedCompareExchange(&encrypt_race_start_barrier, 2, 1) != 1)
1417
;
1418
1419
for (test = 0; test < RACE_TEST_COUNT; ++test)
1420
{
1421
size = 0;
1422
memset(ciphertext, 0xff, sizeof(ciphertext));
1423
memset(tag, 0xff, sizeof(tag));
1424
ret = BCryptEncrypt(key, data2, 32, &auth_info, NULL, 0, ciphertext, 32, &size, 0);
1425
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1426
ok(size == 32, "got %lu\n", size);
1427
ok(!memcmp(ciphertext, expected4, sizeof(expected4)), "wrong data\n");
1428
ok(!memcmp(tag, expected_tag3, sizeof(expected_tag2)), "wrong tag\n");
1429
for (i = 0; i < 32; i++)
1430
ok(ciphertext[i] == expected4[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected4[i]);
1431
for (i = 0; i < 16; i++)
1432
ok(tag[i] == expected_tag3[i], "%lu: %02x != %02x\n", i, tag[i], expected_tag3[i]);
1433
}
1434
1435
WaitForSingleObject(hthread, INFINITE);
1436
1437
ret = BCryptDestroyKey(key);
1438
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1439
free(buf);
1440
1441
/******************
1442
* AES - ECB mode *
1443
******************/
1444
1445
ret = BCryptSetProperty(aes, BCRYPT_CHAINING_MODE, (UCHAR*)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0);
1446
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1447
1448
len = 0xdeadbeef;
1449
size = sizeof(len);
1450
ret = BCryptGetProperty(aes, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
1451
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1452
1453
buf = calloc(1, len);
1454
ret = BCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0);
1455
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1456
1457
/* initialization vector is not allowed */
1458
size = 0;
1459
memcpy(ivbuf, iv, sizeof(iv));
1460
ret = BCryptEncrypt(key, data, 16, NULL, ivbuf, 16, ciphertext, 16, &size, 0);
1461
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
1462
ok(size == 16, "got %lu\n", size);
1463
1464
/* input size is a multiple of block size */
1465
size = 0;
1466
ret = BCryptEncrypt(key, data, 16, NULL, NULL, 16, NULL, 0, &size, 0);
1467
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1468
ok(size == 16, "got %lu\n", size);
1469
1470
size = 0;
1471
memset(ciphertext, 0, sizeof(ciphertext));
1472
ret = BCryptEncrypt(key, data, 16, NULL, NULL, 16, ciphertext, 16, &size, 0);
1473
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1474
ok(size == 16, "got %lu\n", size);
1475
ok(!memcmp(ciphertext, expected5, sizeof(expected5)), "wrong data\n");
1476
for (i = 0; i < 16; i++)
1477
ok(ciphertext[i] == expected5[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected5[i]);
1478
1479
/* input size is not a multiple of block size */
1480
size = 0;
1481
ret = BCryptEncrypt(key, data, 17, NULL, NULL, 16, NULL, 0, &size, 0);
1482
ok(ret == STATUS_INVALID_BUFFER_SIZE, "got %#lx\n", ret);
1483
ok(size == 17, "got %lu\n", size);
1484
1485
/* input size is not a multiple of block size, block padding set */
1486
size = 0;
1487
ret = BCryptEncrypt(key, data, 17, NULL, NULL, 16, NULL, 0, &size, BCRYPT_BLOCK_PADDING);
1488
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1489
ok(size == 32, "got %lu\n", size);
1490
1491
size = 0;
1492
memset(ciphertext, 0, sizeof(ciphertext));
1493
ret = BCryptEncrypt(key, data, 17, NULL, NULL, 16, ciphertext, 32, &size, BCRYPT_BLOCK_PADDING);
1494
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1495
ok(size == 32, "got %lu\n", size);
1496
ok(!memcmp(ciphertext, expected6, sizeof(expected6)), "wrong data\n");
1497
for (i = 0; i < 32; i++)
1498
ok(ciphertext[i] == expected6[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected6[i]);
1499
1500
/* input size is a multiple of block size, block padding set */
1501
size = 0;
1502
ret = BCryptEncrypt(key, data2, 32, NULL, NULL, 16, NULL, 0, &size, BCRYPT_BLOCK_PADDING);
1503
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1504
ok(size == 48, "got %lu\n", size);
1505
1506
size = 0;
1507
memset(ciphertext, 0, sizeof(ciphertext));
1508
ret = BCryptEncrypt(key, data2, 32, NULL, NULL, 16, ciphertext, 48, &size, BCRYPT_BLOCK_PADDING);
1509
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1510
ok(size == 48, "got %lu\n", size);
1511
ok(!memcmp(ciphertext, expected7, sizeof(expected7)), "wrong data\n");
1512
for (i = 0; i < 48; i++)
1513
ok(ciphertext[i] == expected7[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected7[i]);
1514
1515
/* output size too small */
1516
size = 0;
1517
memset(ciphertext, 0, sizeof(ciphertext));
1518
ret = BCryptEncrypt(key, data, 17, NULL, NULL, 16, ciphertext, 31, &size, BCRYPT_BLOCK_PADDING);
1519
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
1520
ok(size == 32, "got %lu\n", size);
1521
1522
size = 0;
1523
memset(ciphertext, 0, sizeof(ciphertext));
1524
ret = BCryptEncrypt(key, data2, 32, NULL, NULL, 16, ciphertext, 32, &size, BCRYPT_BLOCK_PADDING);
1525
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
1526
ok(size == 48, "got %lu\n", size);
1527
1528
ret = BCryptDestroyKey(key);
1529
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1530
free(buf);
1531
1532
/******************
1533
* AES - CFB mode *
1534
******************/
1535
1536
ret = BCryptSetProperty(aes, BCRYPT_CHAINING_MODE, (UCHAR *)BCRYPT_CHAIN_MODE_CFB, sizeof(BCRYPT_CHAIN_MODE_CFB), 0);
1537
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1538
1539
key = NULL;
1540
buf = calloc(1, len);
1541
ret = BCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0);
1542
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1543
ok(key != NULL, "key not set\n");
1544
1545
/* input size is a multiple of block size */
1546
size = 0;
1547
memcpy(ivbuf, iv, sizeof(iv));
1548
ret = BCryptEncrypt(key, data, 16, NULL, ivbuf, 16, NULL, 0, &size, 0);
1549
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1550
ok(size == 16, "got %lu\n", size);
1551
ok(!memcmp(ivbuf, iv, sizeof(iv)), "wrong iv data.\n");
1552
1553
size = 0;
1554
memcpy(ivbuf, iv, sizeof(iv));
1555
memset(ciphertext, 0, sizeof(ciphertext));
1556
ret = BCryptEncrypt(key, data, 16, NULL, ivbuf, 16, ciphertext, 16, &size, 0);
1557
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1558
ok(size == 16, "got %lu\n", size);
1559
ok(!memcmp(ciphertext, expected11, sizeof(expected11)), "wrong data\n");
1560
for (i = 0; i < 16; i++)
1561
ok(ciphertext[i] == expected11[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected11[i]);
1562
ok(!memcmp(ivbuf, ciphertext, sizeof(iv)), "wrong iv data.\n");
1563
1564
/* NULL initialization vector */
1565
size = 0;
1566
memset(ciphertext, 0, sizeof(ciphertext));
1567
ret = BCryptEncrypt(key, data, 16, NULL, NULL, 0, ciphertext, 16, &size, 0);
1568
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1569
ok(size == 16, "got %lu\n", size);
1570
ok(!memcmp(ciphertext, expected12, sizeof(expected12)), "wrong data\n");
1571
1572
/* all zero initialization vector */
1573
size = 0;
1574
memset(ciphertext, 0, sizeof(ciphertext));
1575
memset(ivbuf, 0, sizeof(ivbuf));
1576
ret = BCryptEncrypt(key, data, 16, NULL, ivbuf, 16, ciphertext, 16, &size, 0);
1577
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1578
ok(size == 16, "got %lu\n", size);
1579
ok(!memcmp(ciphertext, expected13, sizeof(expected13)), "wrong data\n");
1580
for (i = 0; i < 16; i++)
1581
ok(ciphertext[i] == expected13[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected13[i]);
1582
ok(!memcmp(ivbuf, ciphertext, sizeof(iv)), "wrong iv data.\n");
1583
1584
/* input size is not a multiple of block size */
1585
size = 0;
1586
memcpy(ivbuf, iv, sizeof(iv));
1587
ret = BCryptEncrypt(key, data, 17, NULL, ivbuf, 16, NULL, 0, &size, 0);
1588
todo_wine ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1589
ok(size == 17, "got %lu\n", size);
1590
1591
/* input size is not a multiple of block size, block padding set */
1592
size = 0;
1593
memcpy(ivbuf, iv, sizeof(iv));
1594
ret = BCryptEncrypt(key, data, 17, NULL, ivbuf, 16, NULL, 0, &size, BCRYPT_BLOCK_PADDING);
1595
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1596
ok(size == 32, "got %lu\n", size);
1597
ok(!memcmp(ivbuf, iv, sizeof(iv)), "wrong iv data.\n");
1598
1599
size = 0;
1600
memcpy(ivbuf, iv, sizeof(iv));
1601
memset(ciphertext, 0, sizeof(ciphertext));
1602
ret = BCryptEncrypt(key, data, 17, NULL, ivbuf, 16, ciphertext, 32, &size, BCRYPT_BLOCK_PADDING);
1603
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1604
ok(size == 32, "got %lu\n", size);
1605
ok(!memcmp(ciphertext, expected14, sizeof(expected14)), "wrong data\n");
1606
for (i = 0; i < 32; i++)
1607
ok(ciphertext[i] == expected14[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected14[i]);
1608
ok(!memcmp(ivbuf, ciphertext + 32 - 16, sizeof(iv)), "wrong iv data.\n");
1609
1610
/* input size is a multiple of block size, block padding set */
1611
size = 0;
1612
memcpy(ivbuf, iv, sizeof(iv));
1613
ret = BCryptEncrypt(key, data2, 32, NULL, ivbuf, 16, NULL, 0, &size, BCRYPT_BLOCK_PADDING);
1614
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1615
ok(size == 48, "got %lu\n", size);
1616
1617
size = 0;
1618
memcpy(ivbuf, iv, sizeof(iv));
1619
memset(ciphertext, 0, sizeof(ciphertext));
1620
ret = BCryptEncrypt(key, data2, 32, NULL, ivbuf, 16, ciphertext, 48, &size, BCRYPT_BLOCK_PADDING);
1621
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1622
ok(size == 48, "got %lu\n", size);
1623
ok(!memcmp(ciphertext, expected15, sizeof(expected15)), "wrong data\n");
1624
for (i = 0; i < 48; i++)
1625
ok(ciphertext[i] == expected15[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected15[i]);
1626
ok(!memcmp(ivbuf, ciphertext + 48 - 16, sizeof(iv)), "wrong iv data.\n");
1627
1628
/* output size too small */
1629
size = 0;
1630
memcpy(ivbuf, iv, sizeof(iv));
1631
memset(ciphertext, 0, sizeof(ciphertext));
1632
ret = BCryptEncrypt(key, data, 17, NULL, ivbuf, 16, ciphertext, 31, &size, BCRYPT_BLOCK_PADDING);
1633
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
1634
ok(size == 32, "got %lu\n", size);
1635
ok(!memcmp(ivbuf, iv, sizeof(iv)), "wrong iv data.\n");
1636
1637
size = 0;
1638
memcpy(ivbuf, iv, sizeof(iv));
1639
memset(ciphertext, 0, sizeof(ciphertext));
1640
ret = BCryptEncrypt(key, data2, 32, NULL, ivbuf, 16, ciphertext, 32, &size, BCRYPT_BLOCK_PADDING);
1641
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
1642
ok(size == 48, "got %lu\n", size);
1643
ok(!memcmp(ivbuf, iv, sizeof(iv)), "wrong iv data.\n");
1644
1645
ret = BCryptDestroyKey(key);
1646
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1647
free(buf);
1648
1649
/* 256 bit key */
1650
buf = calloc(1, len);
1651
1652
ret = BCryptGenerateSymmetricKey(aes, &key, buf, len, secret256, sizeof(secret256), 0);
1653
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1654
ret = BCryptDestroyKey(key);
1655
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1656
1657
/* Key generations succeeds if the key size exceeds maximum and uses maximum key length
1658
* from secret. */
1659
ret = BCryptGenerateSymmetricKey(aes, &key, buf, len, secret256, sizeof(secret256) + 1, 0);
1660
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1661
1662
size = 0;
1663
memcpy(ivbuf, iv, sizeof(iv));
1664
ret = BCryptEncrypt(key, data2, 32, NULL, ivbuf, 16, NULL, 0, &size, BCRYPT_BLOCK_PADDING);
1665
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1666
ok(size == 48, "got %lu\n", size);
1667
ok(!memcmp(ivbuf, iv, sizeof(iv)), "wrong iv data.\n");
1668
1669
size = 0;
1670
memcpy(ivbuf, iv, sizeof(iv));
1671
memset(ciphertext, 0, sizeof(ciphertext));
1672
ret = BCryptEncrypt(key, data2, 32, NULL, ivbuf, 16, ciphertext, 48, &size, BCRYPT_BLOCK_PADDING);
1673
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1674
ok(size == 48, "got %lu\n", size);
1675
ok(!memcmp(ciphertext, expected16, sizeof(expected16)), "wrong data\n");
1676
for (i = 0; i < 48; i++)
1677
ok(ciphertext[i] == expected16[i], "%lu: %02x != %02x\n", i, ciphertext[i], expected16[i]);
1678
ok(!memcmp(ivbuf, ciphertext + 48 - 16, sizeof(iv)), "wrong iv data.\n");
1679
1680
ret = BCryptCloseAlgorithmProvider(aes, 0);
1681
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1682
}
1683
1684
static void test_BCryptDecrypt(void)
1685
{
1686
static UCHAR nonce[] =
1687
{0x10,0x20,0x30,0x40,0x50,0x60,0x10,0x20,0x30,0x40,0x50,0x60};
1688
static UCHAR auth_data[] =
1689
{0x60,0x50,0x40,0x30,0x20,0x10,0x60,0x50,0x40,0x30,0x20,0x10};
1690
static UCHAR secret[] =
1691
{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
1692
static UCHAR iv[] =
1693
{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
1694
static UCHAR expected[] =
1695
{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
1696
static UCHAR expected2[] =
1697
{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10};
1698
static UCHAR expected3[] =
1699
{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
1700
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10};
1701
static UCHAR expected4[] =
1702
{0x28,0x73,0x3d,0xef,0x84,0x8f,0xb0,0xa6,0x5d,0x1a,0x51,0xb7,0xec,0x8f,0xea,0xe9,
1703
0x10,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f};
1704
static UCHAR expected5[] =
1705
{0x29,0x73,0x3d,0xef,0x84,0x8f,0xb0,0xa6,0x5d,0x1a,0x51,0xb7,0xec,0x8f,0xea,0xe9,
1706
0x10,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f};
1707
static UCHAR ciphertext[32] =
1708
{0xc6,0xa1,0x3b,0x37,0x87,0x8f,0x5b,0x82,0x6f,0x4f,0x81,0x62,0xa1,0xc8,0xd8,0x79,
1709
0x28,0x73,0x3d,0xef,0x84,0x8f,0xb0,0xa6,0x5d,0x1a,0x51,0xb7,0xec,0x8f,0xea,0xe9};
1710
static UCHAR ciphertext2[] =
1711
{0xc6,0xa1,0x3b,0x37,0x87,0x8f,0x5b,0x82,0x6f,0x4f,0x81,0x62,0xa1,0xc8,0xd8,0x79,
1712
0x28,0x73,0x3d,0xef,0x84,0x8f,0xb0,0xa6,0x5d,0x1a,0x51,0xb7,0xec,0x8f,0xea,0xe9};
1713
static UCHAR ciphertext3[] =
1714
{0xc6,0xa1,0x3b,0x37,0x87,0x8f,0x5b,0x82,0x6f,0x4f,0x81,0x62,0xa1,0xc8,0xd8,0x79,
1715
0xb1,0xa2,0x92,0x73,0xbe,0x2c,0x42,0x07,0xa5,0xac,0xe3,0x93,0x39,0x8c,0xb6,0xfb,
1716
0x87,0x5d,0xea,0xa3,0x7e,0x0f,0xde,0xfa,0xd9,0xec,0x6c,0x4e,0x3c,0x76,0x86,0xe4};
1717
static UCHAR ciphertext4[] =
1718
{0xe1,0x82,0xc3,0xc0,0x24,0xfb,0x86,0x85,0xf3,0xf1,0x2b,0x7d,0x09,0xb4,0x73,0x67,
1719
0x86,0x64,0xc3,0xfe,0xa3,0x07,0x61,0xf8,0x16,0xc9,0x78,0x7f,0xe7,0xb1,0xc4,0x94};
1720
static UCHAR ciphertext5[] =
1721
{0x0a,0x94,0x0b,0xb5,0x41,0x6e,0xf0,0x45,0xf1,0xc3,0x94,0x58,0xc6,0x53,0xea,0x5a,
1722
0x84,0x07,0x66,0xb7,0x49,0xc0,0x9b,0x49,0x74,0x28,0x8c,0x10,0xb9,0xc2,0x09,0x70};
1723
static UCHAR ciphertext6[] =
1724
{0x0a,0x94,0x0b,0xb5,0x41,0x6e,0xf0,0x45,0xf1,0xc3,0x94,0x58,0xc6,0x53,0xea,0x5a,
1725
0x95,0x4f,0x64,0xf2,0xe4,0xe8,0x6e,0x9e,0xee,0x82,0xd2,0x02,0x16,0x68,0x48,0x99,
1726
0x95,0x4f,0x64,0xf2,0xe4,0xe8,0x6e,0x9e,0xee,0x82,0xd2,0x02,0x16,0x68,0x48,0x99};
1727
static UCHAR tag[] =
1728
{0x89,0xb3,0x92,0x00,0x39,0x20,0x09,0xb4,0x6a,0xd6,0xaf,0xca,0x4b,0x5b,0xfd,0xd0};
1729
static UCHAR tag2[] =
1730
{0x17,0x9d,0xc0,0x7a,0xf0,0xcf,0xaa,0xd5,0x1c,0x11,0xc4,0x4b,0xd6,0xa3,0x3e,0x77};
1731
BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO auth_info;
1732
BCRYPT_KEY_LENGTHS_STRUCT key_lengths;
1733
BCRYPT_AUTH_TAG_LENGTHS_STRUCT tag_lengths;
1734
BCRYPT_ALG_HANDLE aes;
1735
BCRYPT_KEY_HANDLE key;
1736
UCHAR *buf, plaintext[48], ivbuf[16];
1737
ULONG size, len;
1738
NTSTATUS ret;
1739
1740
ret = BCryptOpenAlgorithmProvider(&aes, BCRYPT_AES_ALGORITHM, NULL, 0);
1741
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1742
1743
size = 0;
1744
memset(&key_lengths, 0, sizeof(key_lengths));
1745
ret = BCryptGetProperty(aes, BCRYPT_KEY_LENGTHS, (UCHAR*)&key_lengths, sizeof(key_lengths), &size, 0);
1746
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1747
ok(size == sizeof(key_lengths), "got %lu\n", size);
1748
ok(key_lengths.dwMinLength == 128, "Expected 128, got %lu\n", key_lengths.dwMinLength);
1749
ok(key_lengths.dwMaxLength == 256, "Expected 256, got %lu\n", key_lengths.dwMaxLength);
1750
ok(key_lengths.dwIncrement == 64, "Expected 64, got %lu\n", key_lengths.dwIncrement);
1751
1752
/******************
1753
* AES - CBC mode *
1754
******************/
1755
1756
len = 0xdeadbeef;
1757
size = sizeof(len);
1758
ret = BCryptGetProperty(aes, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
1759
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1760
1761
key = NULL;
1762
buf = calloc(1, len);
1763
ret = BCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0);
1764
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1765
ok(key != NULL, "key not set\n");
1766
1767
/* input size is a multiple of block size */
1768
size = 0;
1769
memcpy(ivbuf, iv, sizeof(iv));
1770
ret = BCryptDecrypt(key, ciphertext, 32, NULL, ivbuf, 16, NULL, 0, &size, 0);
1771
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1772
ok(size == 32, "got %lu\n", size);
1773
ok(!memcmp(ivbuf, iv, sizeof(iv)), "wrong iv data.\n");
1774
1775
size = 0;
1776
memcpy(ivbuf, iv, sizeof(iv));
1777
memset(plaintext, 0, sizeof(plaintext));
1778
ret = BCryptDecrypt(key, ciphertext, 32, NULL, ivbuf, 16, plaintext, 32, &size, 0);
1779
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1780
ok(size == 32, "got %lu\n", size);
1781
ok(!memcmp(plaintext, expected, sizeof(expected)), "wrong data\n");
1782
ok(!memcmp(ivbuf, ciphertext + size - sizeof(iv), sizeof(iv)), "wrong iv data.\n");
1783
1784
size = 0;
1785
++ivbuf[0];
1786
memset(plaintext, 0, sizeof(plaintext));
1787
ret = BCryptDecrypt(key, ciphertext, 32, NULL, ivbuf, 16, plaintext, 32, &size, 0);
1788
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1789
ok(size == 32, "got %lu\n", size);
1790
ok(!memcmp(plaintext, expected5, sizeof(expected)), "wrong data\n");
1791
ok(!memcmp(ivbuf, ciphertext + 32 - 16, sizeof(iv)), "wrong iv data.\n");
1792
1793
size = 0;
1794
memset(plaintext, 0, sizeof(plaintext));
1795
ret = BCryptDecrypt(key, ciphertext, 32, NULL, NULL, 0, plaintext, 32, &size, 0);
1796
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1797
ok(size == 32, "got %lu\n", size);
1798
ok(!memcmp(plaintext, expected4, sizeof(expected4)), "wrong data\n");
1799
1800
/* test with padding smaller than block size */
1801
size = 0;
1802
memcpy(ivbuf, iv, sizeof(iv));
1803
ret = BCryptDecrypt(key, ciphertext2, 32, NULL, ivbuf, 16, NULL, 0, &size, 0);
1804
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1805
ok(size == 32, "got %lu\n", size);
1806
ok(!memcmp(ivbuf, iv, sizeof(iv)), "wrong iv data.\n");
1807
1808
size = 0;
1809
memcpy(ivbuf, iv, sizeof(iv));
1810
memset(plaintext, 0, sizeof(plaintext));
1811
ret = BCryptDecrypt(key, ciphertext2, 32, NULL, ivbuf, 16, plaintext, 17, &size, BCRYPT_BLOCK_PADDING);
1812
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1813
ok(size == 17, "got %lu\n", size);
1814
ok(!memcmp(plaintext, expected2, sizeof(expected2)), "wrong data\n");
1815
ok(!memcmp(ivbuf, ciphertext2 + 32 - sizeof(iv), sizeof(iv)), "wrong iv data.\n");
1816
1817
size = 0;
1818
memset(plaintext, 0, sizeof(plaintext));
1819
ret = BCryptDecrypt(key, ciphertext2, 32, NULL, ivbuf, 16, plaintext, 17, &size, BCRYPT_BLOCK_PADDING);
1820
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1821
ok(size == 17, "got %lu\n", size);
1822
ok(!memcmp(plaintext, expected4, size), "wrong data\n");
1823
ok(!memcmp(ivbuf, ciphertext2 + 32 - 16, sizeof(iv)), "wrong iv data.\n");
1824
1825
/* test with padding of block size */
1826
size = 0;
1827
memcpy(ivbuf, iv, sizeof(iv));
1828
ret = BCryptDecrypt(key, ciphertext3, 48, NULL, ivbuf, 16, NULL, 0, &size, 0);
1829
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1830
ok(size == 48, "got %lu\n", size);
1831
ok(!memcmp(ivbuf, iv, sizeof(iv)), "wrong iv data.\n");
1832
1833
size = 0;
1834
memcpy(ivbuf, iv, sizeof(iv));
1835
memset(plaintext, 0, sizeof(plaintext));
1836
ret = BCryptDecrypt(key, ciphertext3, 48, NULL, ivbuf, 16, plaintext, 32, &size, BCRYPT_BLOCK_PADDING);
1837
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1838
ok(size == 32, "got %lu\n", size);
1839
ok(!memcmp(plaintext, expected3, sizeof(expected3)), "wrong data\n");
1840
ok(!memcmp(ivbuf, ciphertext3 + 48 - 16, sizeof(iv)), "wrong iv data.\n");
1841
1842
/* output size too small */
1843
size = 0;
1844
memcpy(ivbuf, iv, sizeof(iv));
1845
ret = BCryptDecrypt(key, ciphertext, 32, NULL, ivbuf, 16, plaintext, 31, &size, 0);
1846
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
1847
ok(size == 32, "got %lu\n", size);
1848
1849
size = 0;
1850
memcpy(ivbuf, iv, sizeof(iv));
1851
ret = BCryptDecrypt(key, ciphertext2, 32, NULL, ivbuf, 16, plaintext, 15, &size, BCRYPT_BLOCK_PADDING);
1852
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
1853
ok(size == 32, "got %lu\n", size);
1854
1855
size = 0;
1856
memcpy(ivbuf, iv, sizeof(iv));
1857
ret = BCryptDecrypt(key, ciphertext2, 32, NULL, ivbuf, 16, plaintext, 16, &size, BCRYPT_BLOCK_PADDING);
1858
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
1859
ok(size == 17, "got %lu\n", size);
1860
1861
size = 0;
1862
memcpy(ivbuf, iv, sizeof(iv));
1863
ret = BCryptDecrypt(key, ciphertext3, 48, NULL, ivbuf, 16, plaintext, 31, &size, BCRYPT_BLOCK_PADDING);
1864
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
1865
ok(size == 48, "got %lu\n", size);
1866
1867
/* input size is not a multiple of block size */
1868
size = 0;
1869
memcpy(ivbuf, iv, sizeof(iv));
1870
ret = BCryptDecrypt(key, ciphertext, 17, NULL, ivbuf, 16, NULL, 0, &size, 0);
1871
ok(ret == STATUS_INVALID_BUFFER_SIZE, "got %#lx\n", ret);
1872
ok(size == 17 || broken(size == 0 /* Win < 7 */), "got %lu\n", size);
1873
1874
/* input size is not a multiple of block size, block padding set */
1875
size = 0;
1876
memcpy(ivbuf, iv, sizeof(iv));
1877
ret = BCryptDecrypt(key, ciphertext, 17, NULL, ivbuf, 16, NULL, 0, &size, BCRYPT_BLOCK_PADDING);
1878
ok(ret == STATUS_INVALID_BUFFER_SIZE, "got %#lx\n", ret);
1879
ok(size == 17 || broken(size == 0 /* Win < 7 */), "got %lu\n", size);
1880
1881
ret = BCryptDestroyKey(key);
1882
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1883
free(buf);
1884
1885
/******************
1886
* AES - GCM mode *
1887
******************/
1888
1889
ret = BCryptSetProperty(aes, BCRYPT_CHAINING_MODE, (UCHAR*)BCRYPT_CHAIN_MODE_GCM, sizeof(BCRYPT_CHAIN_MODE_GCM), 0);
1890
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1891
1892
key = NULL;
1893
buf = calloc(1, len);
1894
ret = BCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0);
1895
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1896
ok(key != NULL, "key not set\n");
1897
1898
ret = BCryptGetProperty(key, BCRYPT_AUTH_TAG_LENGTH, (UCHAR*)&tag_lengths, sizeof(tag_lengths), &size, 0);
1899
ok(ret == STATUS_NOT_SUPPORTED, "got %#lx\n", ret);
1900
1901
memset(&auth_info, 0, sizeof(auth_info));
1902
auth_info.cbSize = sizeof(auth_info);
1903
auth_info.dwInfoVersion = 1;
1904
auth_info.pbNonce = nonce;
1905
auth_info.cbNonce = sizeof(nonce);
1906
auth_info.pbTag = tag;
1907
auth_info.cbTag = sizeof(tag);
1908
1909
/* input size is a multiple of block size */
1910
size = 0;
1911
memcpy(ivbuf, iv, sizeof(iv));
1912
memset(plaintext, 0, sizeof(plaintext));
1913
ret = BCryptDecrypt(key, ciphertext4, 32, &auth_info, ivbuf, 16, plaintext, 32, &size, 0);
1914
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1915
ok(size == 32, "got %lu\n", size);
1916
ok(!memcmp(plaintext, expected3, sizeof(expected3)), "wrong data\n");
1917
ok(!memcmp(ivbuf, iv, sizeof(iv)), "wrong iv.\n");
1918
1919
size = 0;
1920
memset(plaintext, 0, sizeof(plaintext));
1921
ret = BCryptDecrypt(key, ciphertext4, 32, &auth_info, NULL, 0, plaintext, 32, &size, 0);
1922
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1923
ok(size == 32, "got %lu\n", size);
1924
ok(!memcmp(plaintext, expected3, sizeof(expected3)), "wrong data\n");
1925
1926
size = 0;
1927
memcpy(ivbuf, iv, sizeof(iv));
1928
++ivbuf[0];
1929
memset(plaintext, 0, sizeof(plaintext));
1930
ret = BCryptDecrypt(key, ciphertext4, 32, &auth_info, ivbuf, 16, plaintext, 32, &size, 0);
1931
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1932
ok(size == 32, "got %lu\n", size);
1933
ok(!memcmp(plaintext, expected3, sizeof(expected3)), "wrong data\n");
1934
ok(!memcmp(ivbuf + 1, iv + 1, sizeof(iv) - 1), "wrong iv data.\n");
1935
ok(ivbuf[0] == iv[0] + 1, "wrong iv data.\n");
1936
1937
/* test with auth data */
1938
auth_info.pbAuthData = auth_data;
1939
auth_info.cbAuthData = sizeof(auth_data);
1940
auth_info.pbTag = tag2;
1941
auth_info.cbTag = sizeof(tag2);
1942
1943
size = 0;
1944
memcpy(ivbuf, iv, sizeof(iv));
1945
memset(plaintext, 0, sizeof(plaintext));
1946
ret = BCryptDecrypt(key, ciphertext4, 32, &auth_info, ivbuf, 16, plaintext, 32, &size, 0);
1947
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1948
ok(size == 32, "got %lu\n", size);
1949
ok(!memcmp(plaintext, expected3, sizeof(expected3)), "wrong data\n");
1950
ok(!memcmp(ivbuf, iv, sizeof(iv)), "wrong iv.\n");
1951
1952
/* test with wrong tag */
1953
memcpy(ivbuf, iv, sizeof(iv));
1954
auth_info.pbTag = iv; /* wrong tag */
1955
ret = BCryptDecrypt(key, ciphertext4, 32, &auth_info, ivbuf, 16, plaintext, 32, &size, 0);
1956
ok(ret == STATUS_AUTH_TAG_MISMATCH, "got %#lx\n", ret);
1957
ok(size == 32, "got %lu\n", size);
1958
ok(!memcmp(ivbuf, iv, sizeof(iv)), "wrong iv data.\n");
1959
1960
ret = BCryptDestroyKey(key);
1961
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1962
free(buf);
1963
1964
/******************
1965
* AES - ECB mode *
1966
******************/
1967
1968
ret = BCryptSetProperty(aes, BCRYPT_CHAINING_MODE, (UCHAR*)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0);
1969
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1970
1971
len = 0xdeadbeef;
1972
size = sizeof(len);
1973
ret = BCryptGetProperty(aes, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
1974
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1975
1976
buf = calloc(1, len);
1977
ret = BCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0);
1978
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1979
1980
/* initialization vector is not allowed */
1981
size = 0;
1982
memcpy(ivbuf, iv, sizeof(iv));
1983
ret = BCryptDecrypt(key, ciphertext5, 32, NULL, ivbuf, 16, plaintext, 32, &size, 0);
1984
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
1985
ok(size == 32, "got %lu\n", size);
1986
1987
/* input size is a multiple of block size */
1988
size = 0;
1989
ret = BCryptDecrypt(key, ciphertext5, 32, NULL, NULL, 16, NULL, 0, &size, 0);
1990
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1991
ok(size == 32, "got %lu\n", size);
1992
1993
size = 0;
1994
memset(plaintext, 0, sizeof(plaintext));
1995
ret = BCryptDecrypt(key, ciphertext5, 32, NULL, NULL, 16, plaintext, 32, &size, 0);
1996
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
1997
ok(size == 32, "got %lu\n", size);
1998
ok(!memcmp(plaintext, expected, sizeof(expected)), "wrong data\n");
1999
2000
/* test with padding smaller than block size */
2001
size = 0;
2002
ret = BCryptDecrypt(key, ciphertext5, 32, NULL, NULL, 16, NULL, 0, &size, 0);
2003
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2004
ok(size == 32, "got %lu\n", size);
2005
2006
size = 0;
2007
memset(plaintext, 0, sizeof(plaintext));
2008
ret = BCryptDecrypt(key, ciphertext5, 32, NULL, NULL, 16, plaintext, 17, &size, BCRYPT_BLOCK_PADDING);
2009
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2010
ok(size == 17, "got %lu\n", size);
2011
ok(!memcmp(plaintext, expected2, sizeof(expected2)), "wrong data\n");
2012
2013
/* test with padding of block size */
2014
size = 0;
2015
ret = BCryptDecrypt(key, ciphertext6, 48, NULL, NULL, 16, NULL, 0, &size, 0);
2016
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2017
ok(size == 48, "got %lu\n", size);
2018
2019
size = 0;
2020
memset(plaintext, 0, sizeof(plaintext));
2021
ret = BCryptDecrypt(key, ciphertext6, 48, NULL, NULL, 16, plaintext, 32, &size, BCRYPT_BLOCK_PADDING);
2022
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2023
ok(size == 32, "got %lu\n", size);
2024
ok(!memcmp(plaintext, expected3, sizeof(expected3)), "wrong data\n");
2025
2026
/* output size too small */
2027
size = 0;
2028
ret = BCryptDecrypt(key, ciphertext4, 32, NULL, NULL, 16, plaintext, 31, &size, 0);
2029
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
2030
ok(size == 32, "got %lu\n", size);
2031
2032
size = 0;
2033
ret = BCryptDecrypt(key, ciphertext5, 32, NULL, NULL, 16, plaintext, 15, &size, BCRYPT_BLOCK_PADDING);
2034
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
2035
ok(size == 32, "got %lu\n", size);
2036
2037
size = 0;
2038
ret = BCryptDecrypt(key, ciphertext5, 32, NULL, NULL, 16, plaintext, 16, &size, BCRYPT_BLOCK_PADDING);
2039
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
2040
ok(size == 17, "got %lu\n", size);
2041
2042
size = 0;
2043
ret = BCryptDecrypt(key, ciphertext6, 48, NULL, NULL, 16, plaintext, 31, &size, BCRYPT_BLOCK_PADDING);
2044
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
2045
ok(size == 48, "got %lu\n", size);
2046
2047
/* input size is not a multiple of block size */
2048
size = 0;
2049
ret = BCryptDecrypt(key, ciphertext4, 17, NULL, NULL, 16, NULL, 0, &size, 0);
2050
ok(ret == STATUS_INVALID_BUFFER_SIZE, "got %#lx\n", ret);
2051
ok(size == 17 || broken(size == 0 /* Win < 7 */), "got %lu\n", size);
2052
2053
/* input size is not a multiple of block size, block padding set */
2054
size = 0;
2055
ret = BCryptDecrypt(key, ciphertext4, 17, NULL, NULL, 16, NULL, 0, &size, BCRYPT_BLOCK_PADDING);
2056
ok(ret == STATUS_INVALID_BUFFER_SIZE, "got %#lx\n", ret);
2057
ok(size == 17 || broken(size == 0 /* Win < 7 */), "got %lu\n", size);
2058
2059
ret = BCryptDestroyKey(key);
2060
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2061
2062
ret = BCryptDestroyKey(key);
2063
ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret);
2064
free(buf);
2065
2066
ret = BCryptDestroyKey(NULL);
2067
ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret);
2068
2069
ret = BCryptCloseAlgorithmProvider(aes, 0);
2070
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2071
2072
ret = BCryptCloseAlgorithmProvider(aes, 0);
2073
ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret);
2074
2075
ret = BCryptCloseAlgorithmProvider(NULL, 0);
2076
ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret);
2077
}
2078
2079
static void test_key_import_export(void)
2080
{
2081
static const UCHAR encrypted_blob[40] = {0x33,0x6e,0x51,0x10,
2082
0x25,0xba,0xdb,0xce,0xcb,0x25,0x00,0x85,0x51,0xc0,0xfa,0x21,
2083
0x66,0xdd,0x6d,0x67,0x46,0x76,0x0f,0x8a,0x44,0xe5,0x65,0x31,
2084
0xcb,0x02,0x52,0x9c,0x69,0x59,0x1a,0xec,0x67,0x27,0x11,0xaa};
2085
UCHAR buffer1[sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + 16];
2086
UCHAR buffer2[sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + 32], *buf;
2087
UCHAR buffer3[32 + 8], buffer4[sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + 32];
2088
BCRYPT_KEY_DATA_BLOB_HEADER *key_data1 = (void*)buffer1;
2089
BCRYPT_KEY_DATA_BLOB_HEADER *key_data2 = (void*)buffer2;
2090
BCRYPT_ALG_HANDLE aes;
2091
BCRYPT_KEY_HANDLE key, key2, key3;
2092
NTSTATUS ret;
2093
ULONG size;
2094
2095
ret = BCryptOpenAlgorithmProvider(&aes, BCRYPT_AES_ALGORITHM, NULL, 0);
2096
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2097
2098
key_data1->dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC;
2099
key_data1->dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1;
2100
key_data1->cbKeyData = 16;
2101
memset(&key_data1[1], 0x11, 16);
2102
2103
key = NULL;
2104
ret = BCryptImportKey(aes, NULL, BCRYPT_KEY_DATA_BLOB, &key, NULL, 0, buffer1, sizeof(buffer1), 0);
2105
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2106
ok(key != NULL, "key not set\n");
2107
2108
key_data2->dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC;
2109
key_data2->dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1;
2110
key_data2->cbKeyData = 32;
2111
memset(&key_data2[1], 0x22, 32);
2112
key2 = NULL;
2113
ret = BCryptImportKey(aes, NULL, BCRYPT_KEY_DATA_BLOB, &key2, NULL, 0, buffer2, sizeof(buffer2), 0);
2114
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2115
ok(key2 != NULL, "key not set\n");
2116
2117
size = 0;
2118
ret = BCryptExportKey(key2, key, BCRYPT_AES_WRAP_KEY_BLOB, NULL, 0, &size, 0);
2119
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2120
ok(size == sizeof(buffer3), "got %lu\n", size);
2121
2122
ret = BCryptExportKey(key2, key, BCRYPT_AES_WRAP_KEY_BLOB, buffer3, size, &size, 0);
2123
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2124
ok(!memcmp(buffer3, encrypted_blob, sizeof(encrypted_blob)), "blobs didn't match\n");
2125
2126
key3 = NULL;
2127
ret = BCryptImportKey(aes, key, BCRYPT_AES_WRAP_KEY_BLOB, &key3, NULL, 0, buffer3, sizeof(buffer3), 0);
2128
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2129
ok(key3 != NULL, "key not set\n");
2130
2131
size = 0;
2132
memset(buffer4, 0xff, sizeof(buffer4));
2133
ret = BCryptExportKey(key3, NULL, BCRYPT_KEY_DATA_BLOB, buffer4, sizeof(buffer4), &size, 0);
2134
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2135
ok(size == sizeof(buffer2), "Got %lu\n", size);
2136
ok(!memcmp(buffer4, buffer2, sizeof(buffer2)), "Expected exported key to match imported key\n");
2137
2138
BCryptDestroyKey(key3);
2139
BCryptDestroyKey(key2);
2140
2141
size = 0;
2142
ret = BCryptExportKey(key, NULL, BCRYPT_KEY_DATA_BLOB, buffer1, 0, &size, 0);
2143
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
2144
ok(size == sizeof(buffer1), "got %lu\n", size);
2145
2146
size = 0;
2147
memset(buffer2, 0xff, sizeof(buffer2));
2148
ret = BCryptExportKey(key, NULL, BCRYPT_KEY_DATA_BLOB, buffer2, sizeof(buffer2), &size, 0);
2149
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2150
ok(size == sizeof(buffer1), "Got %lu\n", size);
2151
ok(!memcmp(buffer1, buffer2, sizeof(buffer1)), "Expected exported key to match imported key\n");
2152
2153
/* opaque blob */
2154
size = 0;
2155
ret = BCryptExportKey(key, NULL, BCRYPT_OPAQUE_KEY_BLOB, buffer2, 0, &size, 0);
2156
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
2157
ok(size > 0, "got zero\n");
2158
2159
buf = malloc(size);
2160
ret = BCryptExportKey(key, NULL, BCRYPT_OPAQUE_KEY_BLOB, buf, size, &size, 0);
2161
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2162
2163
ret = BCryptDestroyKey(key);
2164
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2165
2166
key = NULL;
2167
ret = BCryptImportKey(aes, NULL, BCRYPT_OPAQUE_KEY_BLOB, &key, NULL, 0, buf, size, 0);
2168
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2169
ok(key != NULL, "key not set\n");
2170
2171
ret = BCryptDestroyKey(key);
2172
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2173
2174
if (pBCryptHash)
2175
{
2176
ret = BCryptImportKey(BCRYPT_AES_CBC_ALG_HANDLE, NULL, BCRYPT_OPAQUE_KEY_BLOB, &key, NULL, 0, buf, size, 0);
2177
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2178
BCryptDestroyKey(key);
2179
}
2180
2181
free(buf);
2182
ret = BCryptCloseAlgorithmProvider(aes, 0);
2183
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2184
}
2185
2186
static BYTE eccPrivkey[] =
2187
{
2188
/* X */
2189
0x26, 0xff, 0x0e, 0xf9, 0x71, 0x93, 0xf8, 0xed, 0x59, 0xfa, 0x24, 0xec, 0x18, 0x13, 0xfe, 0xf5,
2190
0x0b, 0x4a, 0xb1, 0x27, 0xb7, 0xab, 0x3e, 0x4f, 0xc5, 0x5a, 0x91, 0xa3, 0x6e, 0x21, 0x61, 0x65,
2191
/* Y */
2192
0x62, 0x7b, 0x8b, 0x30, 0x7a, 0x63, 0x4c, 0x1a, 0xf4, 0x54, 0x54, 0xbb, 0x75, 0x59, 0x68, 0x36,
2193
0xfe, 0x49, 0x95, 0x75, 0x9e, 0x20, 0x3e, 0x69, 0x58, 0xb9, 0x7a, 0x84, 0x03, 0x45, 0x5c, 0x10,
2194
/* d */
2195
0xb9, 0xcd, 0xbe, 0xd4, 0x75, 0x5d, 0x05, 0xe5, 0x83, 0x0c, 0xd3, 0x37, 0x34, 0x15, 0xe3, 0x2c,
2196
0xe5, 0x85, 0x15, 0xa9, 0xee, 0xba, 0x94, 0x03, 0x03, 0x0b, 0x86, 0xea, 0x85, 0x40, 0xbd, 0x35,
2197
};
2198
static BYTE ecc521Privkey[] =
2199
{
2200
/* X */
2201
0x00, 0x5f, 0xea, 0x1e, 0x01, 0xae, 0x69, 0xc3, 0x88, 0x1c, 0xbf, 0x7f, 0x86, 0x1a, 0x48, 0x20,
2202
0xd3, 0xba, 0xac, 0x9f, 0x1c, 0xc9, 0x99, 0xfa, 0x7d, 0x39, 0xf6, 0xe0, 0xd6, 0x92, 0x97, 0xee,
2203
0xf6, 0xca, 0x65, 0x40, 0x24, 0xa6, 0xf7, 0x97, 0x17, 0x8c, 0xe1, 0x81, 0x6c, 0x10, 0x92, 0xcd,
2204
0x41, 0xbc, 0x1c, 0xde, 0x37, 0x4a, 0x21, 0xb9, 0xbc, 0x46, 0x40, 0xa9, 0x91, 0xd9, 0x61, 0x84,
2205
0x15, 0x33,
2206
/* Y */
2207
0x00, 0x31, 0xde, 0xe9, 0x64, 0x9d, 0xb8, 0x43, 0x3a, 0x93, 0x5d, 0xc8, 0x82, 0xec, 0xe4, 0x7f,
2208
0x83, 0x8d, 0x2c, 0xc7, 0xe8, 0x24, 0x38, 0x5a, 0x81, 0x3d, 0xe6, 0x8d, 0xd4, 0xb1, 0xa0, 0x37,
2209
0x89, 0xae, 0x1f, 0x81, 0x23, 0x22, 0x8f, 0xd1, 0xe0, 0xc4, 0x6a, 0x99, 0xcc, 0xc8, 0xe4, 0xa0,
2210
0x65, 0x42, 0x9e, 0xbd, 0xaf, 0x07, 0x79, 0xe8, 0x88, 0xc2, 0xfe, 0xc0, 0x2d, 0x88, 0xd5, 0x3a,
2211
0xbd, 0xb1,
2212
/* d */
2213
0x00, 0x8b, 0xc5, 0xd5, 0x06, 0x3a, 0x1d, 0xd2, 0xf8, 0x26, 0x8e, 0xa2, 0xd3, 0x69, 0x5a, 0xf9,
2214
0xb6, 0x42, 0x8b, 0x1a, 0x9c, 0x34, 0x04, 0xa6, 0x1d, 0xfc, 0x67, 0xe5, 0x23, 0x71, 0x8e, 0xad,
2215
0x61, 0x45, 0x4f, 0x00, 0x3e, 0x8f, 0x61, 0xa3, 0xfb, 0xb6, 0x7a, 0x98, 0xf8, 0x27, 0x2c, 0x1b,
2216
0xa8, 0xda, 0xb7, 0x78, 0xe9, 0xf5, 0x9d, 0xff, 0x6a, 0x07, 0xb0, 0xe2, 0xae, 0x64, 0x15, 0x03,
2217
0xb3, 0x8a,
2218
};
2219
static BYTE eccPubkey[] =
2220
{
2221
/* X */
2222
0x3b, 0x3c, 0x34, 0xc8, 0x3f, 0x15, 0xea, 0x02, 0x68, 0x46, 0x69, 0xdf, 0x0c, 0xa6, 0xee, 0x7a,
2223
0xd9, 0x82, 0x08, 0x9b, 0x37, 0x53, 0x42, 0xf3, 0x13, 0x63, 0xda, 0x65, 0x79, 0xe8, 0x04, 0x9e,
2224
/* Y */
2225
0x8c, 0x77, 0xc4, 0x33, 0x77, 0xd9, 0x5a, 0x7f, 0x60, 0x7b, 0x98, 0xce, 0xf3, 0x96, 0x56, 0xd6,
2226
0xb5, 0x8d, 0x87, 0x7a, 0x00, 0x2b, 0xf3, 0x70, 0xb3, 0x90, 0x73, 0xa0, 0x56, 0x06, 0x3b, 0x22,
2227
};
2228
static BYTE certHash[] =
2229
{
2230
0x28, 0x19, 0x0f, 0x15, 0x6d, 0x75, 0xcc, 0xcf, 0x62, 0xf1, 0x5e, 0xe6, 0x8a, 0xc3, 0xf0, 0x5d,
2231
0x89, 0x28, 0x2d, 0x48, 0xd8, 0x73, 0x7c, 0x05, 0x05, 0x8e, 0xbc, 0xce, 0x28, 0xb7, 0xba, 0xc9,
2232
};
2233
static BYTE certSignature[] =
2234
{
2235
/* r */
2236
0xd7, 0x29, 0xce, 0x5a, 0xef, 0x74, 0x85, 0xd1, 0x18, 0x5f, 0x6e, 0xf1, 0xba, 0x53, 0xd4, 0xcd,
2237
0xdd, 0xe0, 0x5d, 0xf1, 0x5e, 0x48, 0x51, 0xea, 0x63, 0xc0, 0xe8, 0xe2, 0xf6, 0xfa, 0x4c, 0xaf,
2238
/* s */
2239
0xe3, 0x94, 0x15, 0x3b, 0x6c, 0x71, 0x6e, 0x44, 0x22, 0xcb, 0xa0, 0x88, 0xcd, 0x0a, 0x5a, 0x50,
2240
0x29, 0x7c, 0x5c, 0xd6, 0x6c, 0xd2, 0xe0, 0x7f, 0xcd, 0x02, 0x92, 0x21, 0x4c, 0x2c, 0x92, 0xee,
2241
};
2242
static BYTE cert521Signature[] =
2243
{
2244
0x01, 0x6b, 0xd6, 0xca, 0xac, 0x28, 0xa8, 0xa9, 0x83, 0x9d, 0xca, 0x13, 0x08, 0xd6, 0xf2, 0x9c,
2245
0x94, 0x6b, 0x28, 0x6b, 0x93, 0x58, 0x3c, 0x65, 0x54, 0xb4, 0xa6, 0xb8, 0x0d, 0x55, 0xed, 0x4e,
2246
0xc9, 0x98, 0x26, 0x96, 0x1a, 0xbb, 0x9f, 0x9e, 0x5c, 0xb1, 0x1e, 0x8b, 0x04, 0x82, 0xe6, 0x32,
2247
0x15, 0x92, 0xcb, 0xfe, 0xe7, 0x53, 0xfc, 0x17, 0xe0, 0xc9, 0x44, 0xf5, 0x1d, 0x37, 0x33, 0x02,
2248
0xbb, 0x75, 0x01, 0x65, 0x84, 0xab, 0x89, 0xb3, 0x69, 0x56, 0xf4, 0x18, 0xb0, 0xdd, 0xfd, 0x69,
2249
0xe6, 0x52, 0x1e, 0x75, 0x4f, 0x98, 0xa8, 0x49, 0x88, 0x84, 0x15, 0x58, 0x23, 0x9f, 0x89, 0x06,
2250
0x73, 0x6b, 0x8c, 0xf9, 0x9a, 0x85, 0x1d, 0xd2, 0xf4, 0x06, 0x65, 0xa5, 0x88, 0x12, 0xa3, 0x4e,
2251
0xcd, 0x99, 0x06, 0x1b, 0xf8, 0x17, 0xe0, 0xeb, 0xb8, 0x7f, 0x6b, 0x89, 0x47, 0xd2, 0x5d, 0x30,
2252
0xf4, 0xf6, 0x5f, 0x83,
2253
};
2254
2255
static void test_ECDSA(void)
2256
{
2257
BYTE buffer[sizeof(BCRYPT_ECCKEY_BLOB) + sizeof(ecc521Privkey)];
2258
BCRYPT_ECCKEY_BLOB *ecckey = (void *)buffer;
2259
BCRYPT_ALG_HANDLE alg;
2260
BCRYPT_KEY_HANDLE key;
2261
NTSTATUS status;
2262
DWORD keylen;
2263
ULONG size;
2264
2265
status = BCryptOpenAlgorithmProvider(&alg, BCRYPT_ECDSA_P256_ALGORITHM, NULL, 0);
2266
ok(!status, "got %#lx\n", status);
2267
2268
ecckey->dwMagic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
2269
memcpy(ecckey + 1, eccPubkey, sizeof(eccPubkey));
2270
2271
ecckey->cbKey = 2;
2272
size = sizeof(BCRYPT_ECCKEY_BLOB) + sizeof(eccPubkey);
2273
status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPUBLIC_BLOB, &key, buffer, size, 0);
2274
ok(status == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %#lx\n", status);
2275
2276
ecckey->dwMagic = BCRYPT_ECDH_PUBLIC_P256_MAGIC;
2277
ecckey->cbKey = 32;
2278
status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPUBLIC_BLOB, &key, buffer, size, 0);
2279
ok(status == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %#lx\n", status);
2280
2281
ecckey->dwMagic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
2282
ecckey->cbKey = 32;
2283
status = BCryptImportKeyPair(alg, NULL, BCRYPT_PUBLIC_KEY_BLOB, &key, buffer, size, 0);
2284
ok(!status, "BCryptImportKeyPair failed: %#lx\n", status);
2285
BCryptDestroyKey(key);
2286
2287
if (pBCryptHash)
2288
{
2289
status = BCryptImportKeyPair(BCRYPT_ECDSA_P256_ALG_HANDLE, NULL, BCRYPT_PUBLIC_KEY_BLOB, &key, buffer,
2290
size, 0);
2291
ok(!status, "BCryptImportKeyPair failed: %#lx\n", status);
2292
BCryptDestroyKey(key);
2293
}
2294
2295
status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPUBLIC_BLOB, &key, buffer, size, 0);
2296
ok(!status, "BCryptImportKeyPair failed: %#lx\n", status);
2297
2298
keylen = 0;
2299
status = BCryptGetProperty(key, BCRYPT_KEY_STRENGTH, (UCHAR *)&keylen, sizeof(keylen), &size, 0);
2300
ok(!status, "got %#lx\n", status);
2301
ok(size == sizeof(keylen), "got %lu\n", size);
2302
ok(keylen == 256, "got %lu\n", keylen);
2303
2304
memset(buffer, 0xcc, sizeof(buffer));
2305
status = BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, buffer, sizeof(buffer), &size, 0);
2306
ok(!status, "Got unexpected status %#lx\n", status);
2307
ok(ecckey->dwMagic == BCRYPT_ECDSA_PUBLIC_P256_MAGIC, "Got unexpected magic %#lx.\n", ecckey->dwMagic);
2308
ok(ecckey->cbKey == 32, "got %lu\n", ecckey->cbKey);
2309
ok(!memcmp(ecckey + 1, eccPubkey, sizeof(eccPubkey)), "Got unexpected key data.\n");
2310
2311
status = BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, buffer, sizeof(buffer), &size, 0);
2312
ok(status == STATUS_INVALID_PARAMETER, "Got unexpected status %#lx\n", status);
2313
2314
status = BCryptVerifySignature(key, NULL, certHash, sizeof(certHash) - 1, certSignature, sizeof(certSignature), 0);
2315
ok(status == STATUS_INVALID_SIGNATURE, "Expected STATUS_INVALID_SIGNATURE, got %#lx\n", status);
2316
2317
status = BCryptVerifySignature(key, NULL, certHash, sizeof(certHash), certSignature, sizeof(certSignature), 0);
2318
ok(!status, "BCryptVerifySignature failed: %#lx\n", status);
2319
BCryptDestroyKey(key);
2320
2321
ecckey->dwMagic = BCRYPT_ECDSA_PRIVATE_P256_MAGIC;
2322
memcpy(ecckey + 1, eccPrivkey, sizeof(eccPrivkey));
2323
2324
ecckey->cbKey = 2;
2325
size = sizeof(BCRYPT_ECCKEY_BLOB) + sizeof(eccPrivkey);
2326
status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPRIVATE_BLOB, &key, buffer, size, 0);
2327
ok(status == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %#lx\n", status);
2328
2329
ecckey->dwMagic = BCRYPT_ECDH_PRIVATE_P256_MAGIC;
2330
ecckey->cbKey = 32;
2331
status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPRIVATE_BLOB, &key, buffer, size, 0);
2332
ok(status == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %#lx\n", status);
2333
2334
ecckey->dwMagic = BCRYPT_ECDSA_PRIVATE_P256_MAGIC;
2335
ecckey->cbKey = 32;
2336
status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPRIVATE_BLOB, &key, buffer, size, 0);
2337
ok(!status, "BCryptImportKeyPair failed: %#lx\n", status);
2338
2339
memset( buffer, 0xcc, sizeof(buffer) );
2340
status = BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, buffer, sizeof(buffer), &size, 0);
2341
ok(!status, "Got unexpected status %#lx\n", status);
2342
ok(ecckey->dwMagic == BCRYPT_ECDSA_PUBLIC_P256_MAGIC, "got %#lx\n", ecckey->dwMagic);
2343
ok(ecckey->cbKey == 32, "got %lu\n", ecckey->cbKey);
2344
ok(!memcmp(ecckey + 1, eccPrivkey, sizeof(eccPubkey)), "Got unexpected key data.\n");
2345
2346
size = sizeof(BCRYPT_ECCKEY_BLOB) + sizeof(eccPrivkey);
2347
memset( buffer, 0, sizeof(buffer) );
2348
status = BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, buffer, size, &size, 0);
2349
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
2350
ecckey = (BCRYPT_ECCKEY_BLOB *)buffer;
2351
ok(ecckey->dwMagic == BCRYPT_ECDSA_PRIVATE_P256_MAGIC, "got %#lx\n", ecckey->dwMagic);
2352
ok(ecckey->cbKey == 32, "got %lu\n", ecckey->cbKey);
2353
ok(size == sizeof(*ecckey) + ecckey->cbKey * 3, "got %lu\n", size);
2354
2355
BCryptDestroyKey(key);
2356
BCryptCloseAlgorithmProvider(alg, 0);
2357
2358
/* P521 */
2359
status = BCryptOpenAlgorithmProvider(&alg, BCRYPT_ECDSA_P521_ALGORITHM, NULL, 0);
2360
ok(!status, "got %#lx\n", status);
2361
2362
ecckey->dwMagic = BCRYPT_ECDSA_PUBLIC_P521_MAGIC;
2363
ecckey->cbKey = 66;
2364
size = sizeof(BCRYPT_ECCKEY_BLOB) + ecckey->cbKey * 2;
2365
memcpy(ecckey + 1, ecc521Privkey, ecckey->cbKey * 2);
2366
status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPUBLIC_BLOB, &key, buffer, size, 0);
2367
ok(!status, "BCryptImportKeyPair failed: %#lx\n", status);
2368
2369
keylen = 0;
2370
status = BCryptGetProperty(key, BCRYPT_KEY_STRENGTH, (UCHAR *)&keylen, sizeof(keylen), &size, 0);
2371
ok(!status, "got %#lx\n", status);
2372
ok(size == sizeof(keylen), "got %lu\n", size);
2373
ok(keylen == 521, "got %lu\n", keylen);
2374
2375
memset(buffer, 0xcc, sizeof(buffer));
2376
status = BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, buffer, sizeof(buffer), &size, 0);
2377
ok(!status, "Got unexpected status %#lx\n", status);
2378
ok(ecckey->dwMagic == BCRYPT_ECDSA_PUBLIC_P521_MAGIC, "Got unexpected magic %#lx.\n", ecckey->dwMagic);
2379
ok(ecckey->cbKey == 66, "got %lu\n", ecckey->cbKey);
2380
ok(!memcmp(ecckey + 1, ecc521Privkey, ecckey->cbKey * 2), "Got unexpected key data.\n");
2381
2382
memcpy(buffer, cert521Signature, sizeof(cert521Signature));
2383
status = BCryptVerifySignature(key, NULL, certHash, sizeof(certHash), buffer, sizeof(cert521Signature), 0);
2384
ok(!status, "BCryptVerifySignature failed: %#lx\n", status);
2385
2386
++buffer[5];
2387
status = BCryptVerifySignature(key, NULL, certHash, sizeof(certHash), buffer, sizeof(cert521Signature), 0);
2388
ok(status == STATUS_INVALID_SIGNATURE, "BCryptVerifySignature failed: %#lx\n", status);
2389
2390
BCryptDestroyKey(key);
2391
2392
ecckey->dwMagic = BCRYPT_ECDSA_PRIVATE_P521_MAGIC;
2393
ecckey->cbKey = 66;
2394
memcpy(ecckey + 1, ecc521Privkey, sizeof(ecc521Privkey));
2395
size = sizeof(*ecckey) + sizeof(ecc521Privkey);
2396
status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPRIVATE_BLOB, &key, buffer, size, 0);
2397
ok(!status, "BCryptImportKeyPair failed: %#lx\n", status);
2398
2399
memset( buffer, 0xcc, sizeof(buffer) );
2400
status = BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, buffer, sizeof(buffer), &size, 0);
2401
ok(!status, "Got unexpected status %#lx\n", status);
2402
ok(ecckey->dwMagic == BCRYPT_ECDSA_PUBLIC_P521_MAGIC, "got %#lx\n", ecckey->dwMagic);
2403
ok(ecckey->cbKey == 66, "got %lu\n", ecckey->cbKey);
2404
ok(!memcmp(ecckey + 1, ecc521Privkey, ecckey->cbKey * 2), "Got unexpected key data.\n");
2405
2406
size = sizeof(BCRYPT_ECCKEY_BLOB) + sizeof(ecc521Privkey);
2407
memset( buffer, 0xcc, sizeof(buffer) );
2408
status = BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, buffer, size, &size, 0);
2409
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
2410
ecckey = (BCRYPT_ECCKEY_BLOB *)buffer;
2411
ok(ecckey->dwMagic == BCRYPT_ECDSA_PRIVATE_P521_MAGIC, "got %#lx\n", ecckey->dwMagic);
2412
ok(ecckey->cbKey == 66, "got %lu\n", ecckey->cbKey);
2413
ok(size == sizeof(*ecckey) + ecckey->cbKey * 3, "got %lu\n", size);
2414
ok(!memcmp(ecckey + 1, ecc521Privkey, ecckey->cbKey * 3), "Got unexpected key data.\n");
2415
2416
BCryptDestroyKey(key);
2417
BCryptCloseAlgorithmProvider(alg, 0);
2418
}
2419
2420
static UCHAR rsaPublicBlob[] =
2421
{
2422
0x52, 0x53, 0x41, 0x31, 0x00, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
2423
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0xad, 0x41, 0x09, 0xa2, 0x56,
2424
0x3a, 0x7b, 0x75, 0x4b, 0x72, 0x9b, 0x28, 0x72, 0x3b, 0xae, 0x9f, 0xd8, 0xa8, 0x25, 0x4a, 0x4c,
2425
0x19, 0xf5, 0xa6, 0xd0, 0x05, 0x1c, 0x59, 0x8f, 0xe3, 0xf3, 0x2d, 0x29, 0x47, 0xf8, 0x80, 0x25,
2426
0x25, 0x21, 0x58, 0xc2, 0xac, 0xa1, 0x9e, 0x93, 0x8e, 0x82, 0x6d, 0xd7, 0xf3, 0xe7, 0x8f, 0x0b,
2427
0xc0, 0x41, 0x85, 0x29, 0x3c, 0xf1, 0x0b, 0x2c, 0x5d, 0x49, 0xed, 0xb4, 0x30, 0x6e, 0x02, 0x15,
2428
0x4b, 0x9a, 0x08, 0x0d, 0xe1, 0x6f, 0xa8, 0xd3, 0x12, 0xab, 0x66, 0x48, 0x4d, 0xd9, 0x28, 0x03,
2429
0x6c, 0x9d, 0x44, 0x7a, 0xed, 0xc9, 0x43, 0x4f, 0x9d, 0x4e, 0x3c, 0x7d, 0x0e, 0xff, 0x07, 0x87,
2430
0xeb, 0xca, 0xca, 0x65, 0x6d, 0xbe, 0xc5, 0x31, 0x8b, 0xcc, 0x7e, 0x0a, 0x71, 0x4a, 0x4d, 0x9d,
2431
0x3d, 0xfd, 0x7a, 0x56, 0x32, 0x8a, 0x6c, 0x6d, 0x9d, 0x2a, 0xd9, 0x8e, 0x68, 0x89, 0x63, 0xc6,
2432
0x4f, 0x24, 0xd1, 0x2a, 0x72, 0x69, 0x08, 0x77, 0xa0, 0x7f, 0xfe, 0xc6, 0x33, 0x8d, 0xb4, 0x7d,
2433
0x73, 0x91, 0x13, 0x9c, 0x47, 0x53, 0x6a, 0x13, 0xdf, 0x19, 0xc7, 0xed, 0x48, 0x81, 0xed, 0xd8,
2434
0x1f, 0x11, 0x11, 0xbb, 0x41, 0x15, 0x5b, 0xa4, 0xf5, 0xc9, 0x2b, 0x48, 0x5e, 0xd8, 0x4b, 0x52,
2435
0x1f, 0xf7, 0x87, 0xf2, 0x68, 0x25, 0x28, 0x79, 0xee, 0x39, 0x41, 0xc9, 0x0e, 0xc8, 0xf9, 0xf2,
2436
0xd8, 0x24, 0x09, 0xb4, 0xd4, 0xb7, 0x90, 0xba, 0x26, 0xe8, 0x1d, 0xb4, 0xd7, 0x09, 0x00, 0xc4,
2437
0xa0, 0xb6, 0x14, 0xe8, 0x4c, 0x29, 0x60, 0x54, 0x2e, 0x01, 0xde, 0x54, 0x66, 0x40, 0x22, 0x50,
2438
0x27, 0xf1, 0xe7, 0x62, 0xa9, 0x00, 0x5a, 0x61, 0x2e, 0xfa, 0xfe, 0x16, 0xd8, 0xe0, 0xe7, 0x66,
2439
0x17, 0xda, 0xb8, 0x0c, 0xa6, 0x04, 0x8d, 0xf8, 0x21, 0x68, 0x39
2440
};
2441
2442
static UCHAR rsaHash[] =
2443
{
2444
0x96, 0x1f, 0xa6, 0x49, 0x58, 0x81, 0x8f, 0x76, 0x77, 0x07, 0x07, 0x27, 0x55, 0xd7, 0x01, 0x8d,
2445
0xcd, 0x27, 0x8e, 0x94
2446
};
2447
2448
static UCHAR rsaSignature[] =
2449
{
2450
0xa8, 0x3a, 0x9d, 0xaf, 0x92, 0x94, 0xa4, 0x4d, 0x34, 0xba, 0x41, 0x0c, 0xc1, 0x23, 0x91, 0xc7,
2451
0x91, 0xa8, 0xf8, 0xfc, 0x94, 0x87, 0x4d, 0x05, 0x85, 0x63, 0xe8, 0x7d, 0xea, 0x7f, 0x6b, 0x8d,
2452
0xbb, 0x9a, 0xd4, 0x46, 0xa6, 0xc0, 0xd6, 0xdc, 0x91, 0xba, 0xd3, 0x1a, 0xbf, 0xf4, 0x52, 0xa0,
2453
0xc7, 0x15, 0x87, 0xe9, 0x1e, 0x60, 0x49, 0x9c, 0xee, 0x5a, 0x9c, 0x6c, 0xbd, 0x7a, 0x3e, 0xc3,
2454
0x48, 0xb3, 0xee, 0xca, 0x68, 0x40, 0x9b, 0xa1, 0x4c, 0x6e, 0x20, 0xd6, 0xca, 0x6c, 0x72, 0xaf,
2455
0x2b, 0x6b, 0x62, 0x7c, 0x78, 0x06, 0x94, 0x4c, 0x02, 0xf3, 0x8d, 0x49, 0xe0, 0x11, 0xc4, 0x9b,
2456
0x62, 0x5b, 0xc2, 0xfd, 0x68, 0xf4, 0x07, 0x15, 0x71, 0x11, 0x4c, 0x35, 0x97, 0x5d, 0xc0, 0xe6,
2457
0x22, 0xc9, 0x8a, 0x7b, 0x96, 0xc9, 0xc3, 0xe4, 0x2b, 0x1e, 0x88, 0x17, 0x4f, 0x98, 0x9b, 0xf3,
2458
0x42, 0x23, 0x0c, 0xa0, 0xfa, 0x19, 0x03, 0x2a, 0xf7, 0x13, 0x2d, 0x27, 0xac, 0x9f, 0xaf, 0x2d,
2459
0xa3, 0xce, 0xf7, 0x63, 0xbb, 0x39, 0x9f, 0x72, 0x80, 0xdd, 0x6c, 0x73, 0x00, 0x85, 0x70, 0xf2,
2460
0xed, 0x50, 0xed, 0xa0, 0x74, 0x42, 0xd7, 0x22, 0x46, 0x24, 0xee, 0x67, 0xdf, 0xb5, 0x45, 0xe8,
2461
0x49, 0xf4, 0x9c, 0xe4, 0x00, 0x83, 0xf2, 0x27, 0x8e, 0xa2, 0xb1, 0xc3, 0xc2, 0x01, 0xd7, 0x59,
2462
0x2e, 0x4d, 0xac, 0x49, 0xa2, 0xc1, 0x8d, 0x88, 0x4b, 0xfe, 0x28, 0xe5, 0xac, 0xa6, 0x85, 0xc4,
2463
0x1f, 0xf8, 0xc5, 0xc5, 0x14, 0x4e, 0xa3, 0xcb, 0x17, 0xb7, 0x64, 0xb3, 0xc2, 0x12, 0xf8, 0xf8,
2464
0x36, 0x99, 0x1c, 0x91, 0x9b, 0xbd, 0xed, 0x55, 0x0f, 0xfd, 0x49, 0x85, 0xbb, 0x32, 0xad, 0x78,
2465
0xc1, 0x74, 0xe6, 0x7c, 0x18, 0x0f, 0x2b, 0x3b, 0xaa, 0xd1, 0x9d, 0x40, 0x71, 0x1d, 0x19, 0x53
2466
};
2467
2468
static UCHAR rsaPrivateBlob[] =
2469
{
2470
0x52, 0x53, 0x41, 0x32, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
2471
0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0xa6, 0x8b, 0x46, 0x26, 0xb5,
2472
0xa9, 0x69, 0x83, 0x94, 0x66, 0xa7, 0xf3, 0x33, 0x95, 0x74, 0xe9, 0xeb, 0xc8, 0xcd, 0xd7, 0x81,
2473
0x9e, 0x45, 0x66, 0xb2, 0x48, 0x8b, 0x1f, 0xfe, 0xb3, 0x62, 0xc4, 0x0d, 0xa2, 0xf9, 0xf3, 0xe2,
2474
0xa6, 0x86, 0xd1, 0x1e, 0x8a, 0xbb, 0x1d, 0xa5, 0xc5, 0xe8, 0xa7, 0x50, 0x37, 0xfd, 0x69, 0x1f,
2475
0x6f, 0x99, 0x99, 0xca, 0x39, 0x13, 0xea, 0x5b, 0x6b, 0xe3, 0x91, 0xc0, 0xd2, 0x2c, 0x0b, 0x21,
2476
0xb1, 0xac, 0xa9, 0xe8, 0xa0, 0x6d, 0xa4, 0x1f, 0x1b, 0x34, 0xcb, 0x88, 0x7f, 0x2e, 0xeb, 0x7d,
2477
0x91, 0x38, 0x48, 0xce, 0x05, 0x73, 0x05, 0xdd, 0x22, 0x94, 0xc3, 0xdd, 0x1c, 0xfd, 0xc5, 0x41,
2478
0x2e, 0x94, 0xf9, 0xed, 0xe5, 0x92, 0x5f, 0x3f, 0x06, 0xf8, 0x49, 0x60, 0xb8, 0x92, 0x52, 0x6a,
2479
0x56, 0x6e, 0xd7, 0x04, 0x1a, 0xb5, 0xb5, 0x1c, 0x31, 0xd1, 0x1b,
2480
};
2481
2482
static UCHAR rsaFullPrivateBlob[] =
2483
{
2484
0x52, 0x53, 0x41, 0x33, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
2485
0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0xa6, 0x8b, 0x46, 0x26, 0xb5,
2486
0xa9, 0x69, 0x83, 0x94, 0x66, 0xa7, 0xf3, 0x33, 0x95, 0x74, 0xe9, 0xeb, 0xc8, 0xcd, 0xd7, 0x81,
2487
0x9e, 0x45, 0x66, 0xb2, 0x48, 0x8b, 0x1f, 0xfe, 0xb3, 0x62, 0xc4, 0x0d, 0xa2, 0xf9, 0xf3, 0xe2,
2488
0xa6, 0x86, 0xd1, 0x1e, 0x8a, 0xbb, 0x1d, 0xa5, 0xc5, 0xe8, 0xa7, 0x50, 0x37, 0xfd, 0x69, 0x1f,
2489
0x6f, 0x99, 0x99, 0xca, 0x39, 0x13, 0xea, 0x5b, 0x6b, 0xe3, 0x91, 0xc0, 0xd2, 0x2c, 0x0b, 0x21,
2490
0xb1, 0xac, 0xa9, 0xe8, 0xa0, 0x6d, 0xa4, 0x1f, 0x1b, 0x34, 0xcb, 0x88, 0x7f, 0x2e, 0xeb, 0x7d,
2491
0x91, 0x38, 0x48, 0xce, 0x05, 0x73, 0x05, 0xdd, 0x22, 0x94, 0xc3, 0xdd, 0x1c, 0xfd, 0xc5, 0x41,
2492
0x2e, 0x94, 0xf9, 0xed, 0xe5, 0x92, 0x5f, 0x3f, 0x06, 0xf8, 0x49, 0x60, 0xb8, 0x92, 0x52, 0x6a,
2493
0x56, 0x6e, 0xd7, 0x04, 0x1a, 0xb5, 0xb5, 0x1c, 0x31, 0xd1, 0x1b, 0xa3, 0xf3, 0xd1, 0x69, 0x61,
2494
0xab, 0xfe, 0xc1, 0xb6, 0x40, 0x7b, 0x19, 0xbb, 0x2d, 0x59, 0xf5, 0xda, 0x49, 0x32, 0x6f, 0x20,
2495
0x24, 0xd3, 0xb3, 0xec, 0x21, 0xec, 0x0c, 0xc7, 0x5b, 0xf9, 0x1b, 0xba, 0x6e, 0xe9, 0x61, 0xda,
2496
0x55, 0xc6, 0x72, 0xfd, 0x2d, 0x66, 0x3f, 0x3c, 0xcb, 0x49, 0xa9, 0xc5, 0x0d, 0x9b, 0x02, 0x36,
2497
0x7a, 0xee, 0x36, 0x09, 0x55, 0xe4, 0x03, 0xf2, 0xe3, 0xe6, 0x25, 0x14, 0x89, 0x7f, 0x2b, 0xfb,
2498
0x27, 0x0e, 0x8d, 0x37, 0x84, 0xfd, 0xad, 0x10, 0x79, 0x43, 0x4e, 0x38, 0x4a, 0xd4, 0x5e, 0xfa,
2499
0xda, 0x9f, 0x88, 0x21, 0x7c, 0xb4, 0x98, 0xb6, 0x6e, 0x1c, 0x24, 0x09, 0xe5, 0xe7, 0x22, 0x6f,
2500
0xd3, 0x84, 0xc0, 0xdc, 0x36, 0x09, 0xaf, 0x4b, 0x96, 0x8b, 0x5f, 0x47, 0xb3, 0x24, 0x80, 0xb5,
2501
0x64, 0x69, 0xad, 0x83, 0xd5, 0x09, 0xe7, 0xb9, 0xe4, 0x81, 0x6f, 0x1a, 0xe2, 0x6d, 0xf1, 0x5e,
2502
0x2b, 0xb3, 0x7a, 0xd0, 0x77, 0xef, 0x82, 0xcd, 0x55, 0x2e, 0xd5, 0xb1, 0xa7, 0x72, 0xec, 0x02,
2503
0x9d, 0xe2, 0xcc, 0x5a, 0xf1, 0x68, 0x30, 0xe5, 0xbc, 0x8d, 0xad,
2504
};
2505
2506
static struct
2507
{
2508
PUBLICKEYSTRUC header;
2509
RSAPUBKEY rsapubkey;
2510
BYTE modulus[512 / 8];
2511
BYTE prime1[512 / 16];
2512
BYTE prime2[512 / 16];
2513
BYTE exp1[512 / 16];
2514
BYTE exp2[512 / 16];
2515
BYTE coefficient[512 / 16];
2516
BYTE private_exp[512 / 8];
2517
2518
} rsaLegacyPrivateBlob =
2519
{
2520
{ PRIVATEKEYBLOB, CUR_BLOB_VERSION, 0, CALG_RSA_KEYX },
2521
{ BCRYPT_RSAPRIVATE_MAGIC, 512, 0x10001 },
2522
{
2523
0x91, 0xe3, 0x6b, 0x5b, 0xea, 0x13, 0x39, 0xca, 0x99, 0x99, 0x6f, 0x1f, 0x69, 0xfd, 0x37, 0x50,
2524
0xa7, 0xe8, 0xc5, 0xa5, 0x1d, 0xbb, 0x8a, 0x1e, 0xd1, 0x86, 0xa6, 0xe2, 0xf3, 0xf9, 0xa2, 0x0d,
2525
0xc4, 0x62, 0xb3, 0xfe, 0x1f, 0x8b, 0x48, 0xb2, 0x66, 0x45, 0x9e, 0x81, 0xd7, 0xcd, 0xc8, 0xeb,
2526
0xe9, 0x74, 0x95, 0x33, 0xf3, 0xa7, 0x66, 0x94, 0x83, 0x69, 0xa9, 0xb5, 0x26, 0x46, 0x8b, 0xa6
2527
},
2528
{
2529
0xc3, 0x94, 0x22, 0xdd, 0x05, 0x73, 0x05, 0xce, 0x48, 0x38, 0x91, 0x7d, 0xeb, 0x2e, 0x7f, 0x88,
2530
0xcb, 0x34, 0x1b, 0x1f, 0xa4, 0x6d, 0xa0, 0xe8, 0xa9, 0xac, 0xb1, 0x21, 0x0b, 0x2c, 0xd2, 0xc0
2531
},
2532
{
2533
0x1b, 0xd1, 0x31, 0x1c, 0xb5, 0xb5, 0x1a, 0x04, 0xd7, 0x6e, 0x56, 0x6a, 0x52, 0x92, 0xb8, 0x60,
2534
0x49, 0xf8, 0x06, 0x3f, 0x5f, 0x92, 0xe5, 0xed, 0xf9, 0x94, 0x2e, 0x41, 0xc5, 0xfd, 0x1c, 0xdd
2535
},
2536
{
2537
0x1b, 0xf9, 0x5b, 0xc7, 0x0c, 0xec, 0x21, 0xec, 0xb3, 0xd3, 0x24, 0x20, 0x6f, 0x32, 0x49, 0xda,
2538
0xf5, 0x59, 0x2d, 0xbb, 0x19, 0x7b, 0x40, 0xb6, 0xc1, 0xfe, 0xab, 0x61, 0x69, 0xd1, 0xf3, 0xa3
2539
},
2540
{
2541
0x25, 0xe6, 0xe3, 0xf2, 0x03, 0xe4, 0x55, 0x09, 0x36, 0xee, 0x7a, 0x36, 0x02, 0x9b, 0x0d, 0xc5,
2542
0xa9, 0x49, 0xcb, 0x3c, 0x3f, 0x66, 0x2d, 0xfd, 0x72, 0xc6, 0x55, 0xda, 0x61, 0xe9, 0x6e, 0xba
2543
},
2544
{
2545
0x24, 0x1c, 0x6e, 0xb6, 0x98, 0xb4, 0x7c, 0x21, 0x88, 0x9f, 0xda, 0xfa, 0x5e, 0xd4, 0x4a, 0x38,
2546
0x4e, 0x43, 0x79, 0x10, 0xad, 0xfd, 0x84, 0x37, 0x8d, 0x0e, 0x27, 0xfb, 0x2b, 0x7f, 0x89, 0x14
2547
},
2548
{
2549
0xad, 0x8d, 0xbc, 0xe5, 0x30, 0x68, 0xf1, 0x5a, 0xcc, 0xe2, 0x9d, 0x02, 0xec, 0x72, 0xa7, 0xb1,
2550
0xd5, 0x2e, 0x55, 0xcd, 0x82, 0xef, 0x77, 0xd0, 0x7a, 0xb3, 0x2b, 0x5e, 0xf1, 0x6d, 0xe2, 0x1a,
2551
0x6f, 0x81, 0xe4, 0xb9, 0xe7, 0x09, 0xd5, 0x83, 0xad, 0x69, 0x64, 0xb5, 0x80, 0x24, 0xb3, 0x47,
2552
0x5f, 0x8b, 0x96, 0x4b, 0xaf, 0x09, 0x36, 0xdc, 0xc0, 0x84, 0xd3, 0x6f, 0x22, 0xe7, 0xe5, 0x09
2553
}
2554
};
2555
2556
2557
static UCHAR rsaPublicBlobWithInvalidPublicExpSize[] =
2558
{
2559
0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
2560
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2561
0x01, 0x00, 0x01, 0xc7, 0x8f, 0xac, 0x2a, 0xce, 0xbf, 0xc9, 0x6c, 0x7b,
2562
0x85, 0x74, 0x71, 0xbb, 0xff, 0xbb, 0x9b, 0x20, 0x03, 0x79, 0x17, 0x34,
2563
0xe7, 0x26, 0x91, 0x5c, 0x1f, 0x1b, 0x03, 0x3d, 0x46, 0xdf, 0xb6, 0xf2,
2564
0x10, 0x55, 0xf0, 0x39, 0x55, 0x0a, 0xe3, 0x9c, 0x0c, 0x63, 0xc2, 0x14,
2565
0x03, 0x94, 0x51, 0x0d, 0xb4, 0x22, 0x09, 0xf2, 0x5c, 0xb2, 0xd1, 0xc3,
2566
0xac, 0x6f, 0xa8, 0xc4, 0xac, 0xb8, 0xbc, 0x59, 0xe7, 0xed, 0x77, 0x6e,
2567
0xb1, 0x80, 0x58, 0x7d, 0xb2, 0x94, 0x46, 0xe5, 0x00, 0xe2, 0xb7, 0x33,
2568
0x48, 0x7a, 0xd3, 0x78, 0xe9, 0x26, 0x01, 0xc7, 0x00, 0x7b, 0x41, 0x6d,
2569
0x94, 0x3a, 0xe1, 0x50, 0x2b, 0x9f, 0x6b, 0x1c, 0x08, 0xa3, 0xfc, 0x0a,
2570
0x44, 0x81, 0x09, 0x41, 0x80, 0x23, 0x7b, 0xf6, 0x3f, 0xaf, 0x91, 0xa1,
2571
0x87, 0x75, 0x33, 0x15, 0xb8, 0xde, 0x32, 0x30, 0xb4, 0x5e, 0xfd
2572
};
2573
2574
static const UCHAR rsa_encrypted_no_padding[] =
2575
{
2576
0x4a, 0xc1, 0xfa, 0x4f, 0xe0, 0x3f, 0x36, 0x9a, 0x64, 0xbf, 0x2e, 0x00, 0xb4, 0xb5, 0x40, 0xbe,
2577
0x2d, 0x9a, 0x14, 0xf6, 0x8f, 0xa5, 0xc2, 0xe2, 0x20, 0xaf, 0x21, 0x79, 0xc6, 0x32, 0x7e, 0xea,
2578
0x73, 0x00, 0x01, 0xbb, 0x9a, 0x19, 0x73, 0x41, 0x96, 0xae, 0x88, 0x6e, 0x36, 0x56, 0xe9, 0x9c,
2579
0xac, 0x04, 0x82, 0xa8, 0x00, 0xdb, 0x4e, 0x29, 0x61, 0x7e, 0xaf, 0x64, 0xdb, 0xa2, 0x70, 0x0f,
2580
};
2581
2582
static void test_rsa_encrypt(void)
2583
{
2584
UCHAR input[] = "Hello World!", input_no_padding[64] = { 0 }, encrypted[64], decrypted[64];
2585
BCRYPT_ALG_HANDLE rsa;
2586
BCRYPT_KEY_HANDLE key, key2;
2587
NTSTATUS ret;
2588
DWORD encrypted_size, decrypted_size;
2589
UCHAR *encrypted_a = NULL, *encrypted_b = NULL;
2590
BCRYPT_OAEP_PADDING_INFO oaep_pad;
2591
2592
oaep_pad.pszAlgId = BCRYPT_SHA256_ALGORITHM;
2593
oaep_pad.pbLabel = (UCHAR *)"test";
2594
oaep_pad.cbLabel = 5;
2595
2596
ret = BCryptOpenAlgorithmProvider(&rsa, BCRYPT_RSA_ALGORITHM, NULL, 0);
2597
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2598
ret = BCryptGenerateKeyPair(rsa, &key, 512, 0);
2599
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2600
2601
/* Not finalized key */
2602
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, NULL, 0, &encrypted_size, 0);
2603
ok(ret == STATUS_INVALID_HANDLE, "got %lx\n", ret);
2604
BCryptDestroyKey(key);
2605
2606
/* Import a different public key first to make sure a public key from private key improted next
2607
* overrides it. */
2608
ret = BCryptImportKeyPair(rsa, NULL, BCRYPT_RSAPUBLIC_BLOB, &key, rsaPublicBlob, sizeof(rsaPublicBlob), 0);
2609
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2610
2611
ret = BCryptImportKeyPair(rsa, NULL, BCRYPT_RSAPRIVATE_BLOB, &key, rsaPrivateBlob, sizeof(rsaPrivateBlob), 0);
2612
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2613
2614
/* No padding */
2615
todo_wine {
2616
memset(input_no_padding, 0, sizeof(input_no_padding));
2617
2618
encrypted_size = 0;
2619
ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, NULL, 0, &encrypted_size, BCRYPT_PAD_NONE);
2620
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2621
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
2622
2623
strcpy((char *)input_no_padding, "Hello World");
2624
encrypted_size = 0;
2625
ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, NULL, 0, &encrypted_size, BCRYPT_PAD_NONE);
2626
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2627
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
2628
2629
encrypted_a = malloc(encrypted_size);
2630
memset(encrypted_a, 0, encrypted_size);
2631
encrypted_b = malloc(encrypted_size);
2632
memset(encrypted_b, 0xff, encrypted_size);
2633
2634
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, encrypted_a, encrypted_size, &encrypted_size, BCRYPT_PAD_NONE);
2635
ok(ret == STATUS_INVALID_PARAMETER, "got %lx\n", ret);
2636
2637
ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, encrypted_a, 12, &encrypted_size, BCRYPT_PAD_NONE);
2638
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %lx\n", ret);
2639
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
2640
2641
ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, encrypted_a, encrypted_size, &encrypted_size, BCRYPT_PAD_NONE);
2642
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2643
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
2644
2645
ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, encrypted_b, encrypted_size, &encrypted_size, BCRYPT_PAD_NONE);
2646
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2647
}
2648
ok(!memcmp(encrypted_a, encrypted_b, encrypted_size), "Both outputs should be the same\n");
2649
ok(!memcmp(encrypted_b, rsa_encrypted_no_padding, encrypted_size), "Data mismatch.\n");
2650
2651
todo_wine {
2652
decrypted_size = 0;
2653
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, NULL, 0, &decrypted_size, BCRYPT_PAD_NONE);
2654
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2655
ok(decrypted_size == sizeof(input_no_padding), "got %lu\n", decrypted_size);
2656
2657
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, decrypted, decrypted_size, &decrypted_size, BCRYPT_PAD_NONE);
2658
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2659
ok(decrypted_size == sizeof(input_no_padding), "got %lu\n", decrypted_size);
2660
ok(!memcmp(decrypted, input_no_padding, sizeof(input_no_padding)), "unexpected output\n");
2661
}
2662
2663
/* PKCS1 Padding */
2664
encrypted_size = 0;
2665
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, NULL, 0, &encrypted_size, BCRYPT_PAD_PKCS1);
2666
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2667
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
2668
2669
encrypted_a = realloc(encrypted_a, encrypted_size);
2670
memset(encrypted_a, 0, encrypted_size);
2671
encrypted_b = realloc(encrypted_b, encrypted_size);
2672
memset(encrypted_b, 0, encrypted_size);
2673
2674
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, encrypted_a, encrypted_size, &encrypted_size, BCRYPT_PAD_PKCS1);
2675
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2676
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
2677
2678
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, encrypted_b, encrypted_size, &encrypted_size, BCRYPT_PAD_PKCS1);
2679
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2680
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
2681
ok(memcmp(encrypted_a, encrypted_b, encrypted_size), "Both outputs are the same\n");
2682
2683
decrypted_size = 0;
2684
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, NULL, 0, &decrypted_size, BCRYPT_PAD_PKCS1);
2685
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2686
ok(decrypted_size == sizeof(input), "got size of %ld\n", decrypted_size);
2687
2688
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, decrypted, decrypted_size, &decrypted_size, BCRYPT_PAD_PKCS1);
2689
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2690
ok(decrypted_size == sizeof(input), "got size of %ld\n", decrypted_size);
2691
ok(!memcmp(decrypted, input, sizeof(input)), "unexpected output\n");
2692
2693
ret = BCryptImportKeyPair(rsa, NULL, LEGACY_RSAPRIVATE_BLOB, &key2, (UCHAR *)&rsaLegacyPrivateBlob,
2694
sizeof(rsaLegacyPrivateBlob), 0);
2695
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2696
2697
ret = BCryptEncrypt(key2, input, sizeof(input), NULL, NULL, 0, encrypted, sizeof(encrypted),
2698
&encrypted_size, BCRYPT_PAD_PKCS1);
2699
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2700
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
2701
2702
memset(decrypted, 0, sizeof(decrypted));
2703
ret = BCryptDecrypt(key, encrypted, sizeof(encrypted), NULL, NULL, 0, decrypted, sizeof(decrypted),
2704
&decrypted_size, BCRYPT_PAD_PKCS1);
2705
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2706
ok(decrypted_size == sizeof(input), "got size of %ld\n", decrypted_size);
2707
ok(!memcmp(decrypted, input, sizeof(input)), "unexpected output\n");
2708
BCryptDestroyKey(key2);
2709
BCryptDestroyKey(key);
2710
2711
/* OAEP Padding */
2712
ret = BCryptGenerateKeyPair(rsa, &key, 640 /* minimum size for sha256 hash */, 0);
2713
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2714
2715
ret = BCryptFinalizeKeyPair(key, 0);
2716
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2717
2718
encrypted_size = 0;
2719
ret = BCryptEncrypt(key, input, sizeof(input), &oaep_pad, NULL, 0, NULL, 0, &encrypted_size, BCRYPT_PAD_OAEP);
2720
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2721
ok(encrypted_size == 80, "got size of %ld\n", encrypted_size);
2722
2723
encrypted_size = 0;
2724
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, NULL, 0, &encrypted_size, BCRYPT_PAD_OAEP);
2725
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2726
ok(encrypted_size == 80, "got size of %ld\n", encrypted_size);
2727
2728
encrypted_a = realloc(encrypted_a, encrypted_size);
2729
memset(encrypted_a, 0, encrypted_size);
2730
encrypted_b = realloc(encrypted_b, encrypted_size);
2731
memset(encrypted_b, 0, encrypted_size);
2732
2733
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, NULL, encrypted_size, &encrypted_size, BCRYPT_PAD_OAEP);
2734
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2735
ok(encrypted_size == 80, "got size of %ld\n", encrypted_size);
2736
2737
encrypted_size = 0;
2738
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, encrypted_a, 0, &encrypted_size, BCRYPT_PAD_OAEP);
2739
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %lx\n", ret);
2740
ok(encrypted_size == 80, "got size of %ld\n", encrypted_size);
2741
2742
ret = BCryptEncrypt(key, input, sizeof(input), &oaep_pad, NULL, 0, encrypted_a, encrypted_size, &encrypted_size, BCRYPT_PAD_OAEP);
2743
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2744
ok(encrypted_size == 80, "got size of %ld\n", encrypted_size);
2745
2746
ret = BCryptEncrypt(key, input, sizeof(input), &oaep_pad, NULL, 0, encrypted_b, encrypted_size, &encrypted_size, BCRYPT_PAD_OAEP);
2747
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2748
ok(encrypted_size == 80, "got size of %ld\n", encrypted_size);
2749
ok(memcmp(encrypted_a, encrypted_b, encrypted_size), "Both outputs are the same\n");
2750
2751
decrypted_size = 0;
2752
memset(decrypted, 0, sizeof(decrypted));
2753
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, NULL, 0, &decrypted_size, BCRYPT_PAD_OAEP);
2754
ok(ret == STATUS_INVALID_PARAMETER, "got %lx\n", ret);
2755
2756
decrypted_size = 0;
2757
memset(decrypted, 0, sizeof(decrypted));
2758
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, &oaep_pad, NULL, 0, NULL, 0, &decrypted_size, BCRYPT_PAD_OAEP);
2759
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2760
ok(decrypted_size == sizeof(input), "got %lu\n", decrypted_size);
2761
2762
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, &oaep_pad, NULL, 0, decrypted, decrypted_size, &decrypted_size, BCRYPT_PAD_OAEP);
2763
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2764
ok(decrypted_size == sizeof(input), "got %lu\n", decrypted_size);
2765
ok(!memcmp(decrypted, input, sizeof(input)), "unexpected output\n");
2766
2767
free(encrypted_a);
2768
free(encrypted_b);
2769
2770
BCryptDestroyKey(key);
2771
2772
if (pBCryptHash)
2773
{
2774
ret = BCryptGenerateKeyPair(BCRYPT_RSA_ALG_HANDLE, &key, 512, 0);
2775
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2776
BCryptDestroyKey(key);
2777
}
2778
}
2779
2780
static void test_RSA(void)
2781
{
2782
static UCHAR hash[] =
2783
{0x7e,0xe3,0x74,0xe7,0xc5,0x0b,0x6b,0x70,0xdb,0xab,0x32,0x6d,0x1d,0x51,0xd6,0x74,0x79,0x8e,0x5b,0x4b};
2784
static UCHAR hash48[] =
2785
{0x62,0xb2,0x1e,0x90,0xc9,0x02,0x2b,0x10,0x16,0x71,0xba,0x1f,0x80,0x8f,0x86,0x31,0xa8,0x14,0x9f,0x0f,
2786
0x12,0x90,0x40,0x55,0x83,0x9a,0x35,0xc1,0xca,0x78,0xae,0x53,0x1b,0xb3,0x36,0x06,0xba,0x90,0x89,0x12,
2787
0xa8,0x42,0x21,0x10,0x9d,0x29,0xcd,0x7e};
2788
BCRYPT_PKCS1_PADDING_INFO pad;
2789
BCRYPT_PSS_PADDING_INFO pad_pss;
2790
BCRYPT_ALG_HANDLE alg;
2791
BCRYPT_KEY_HANDLE key;
2792
BCRYPT_RSAKEY_BLOB *rsablob;
2793
UCHAR sig[256], sig_pss[256];
2794
ULONG len, size, size2, schemes;
2795
NTSTATUS ret;
2796
BYTE *buf;
2797
DWORD keylen;
2798
2799
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_RSA_ALGORITHM, NULL, 0);
2800
ok(!ret, "got %#lx\n", ret);
2801
2802
schemes = size = 0;
2803
ret = BCryptGetProperty(alg, L"PaddingSchemes", (UCHAR *)&schemes, sizeof(schemes), &size, 0);
2804
ok(!ret, "got %#lx\n", ret);
2805
ok(schemes, "schemes not set\n");
2806
ok(size == sizeof(schemes), "got %lu\n", size);
2807
2808
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_PUBLIC_KEY_BLOB, &key, rsaPublicBlob, sizeof(rsaPublicBlob), 0);
2809
ok(!ret, "BCryptImportKeyPair failed: %#lx\n", ret);
2810
BCryptDestroyKey(key);
2811
2812
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_RSAPUBLIC_BLOB, &key, rsaPublicBlob, sizeof(rsaPublicBlob), 0);
2813
ok(!ret, "BCryptImportKeyPair failed: %#lx\n", ret);
2814
2815
keylen = 0;
2816
ret = BCryptGetProperty(key, BCRYPT_KEY_STRENGTH, (UCHAR *)&keylen, sizeof(keylen), &size, 0);
2817
ok(!ret, "got %#lx\n", ret);
2818
ok(size == sizeof(keylen), "got %lu\n", size);
2819
ok(keylen == 2048, "got %lu\n", keylen);
2820
2821
pad.pszAlgId = BCRYPT_SHA1_ALGORITHM;
2822
ret = BCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
2823
ok(!ret, "BCryptVerifySignature failed: %#lx\n", ret);
2824
2825
ret = BCryptVerifySignature(key, NULL, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
2826
ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %#lx\n", ret);
2827
2828
pad.pszAlgId = BCRYPT_SHA1_ALGORITHM;
2829
ret = BCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), 0);
2830
ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %#lx\n", ret);
2831
2832
ret = BCryptVerifySignature(key, NULL, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), 0);
2833
ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %#lx\n", ret);
2834
2835
pad.pszAlgId = BCRYPT_AES_ALGORITHM;
2836
ret = BCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
2837
ok(ret == STATUS_NOT_SUPPORTED, "Expected STATUS_NOT_SUPPORTED, got %#lx\n", ret);
2838
2839
pad.pszAlgId = NULL;
2840
ret = BCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
2841
ok(ret == STATUS_INVALID_SIGNATURE, "Expected STATUS_INVALID_SIGNATURE, got %#lx\n", ret);
2842
2843
ret = BCryptDestroyKey(key);
2844
ok(!ret, "BCryptDestroyKey failed: %#lx\n", ret);
2845
2846
/* sign/verify with export/import round-trip */
2847
ret = BCryptGenerateKeyPair(alg, &key, 1024, 0);
2848
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2849
2850
keylen = 2048;
2851
ret = BCryptSetProperty(key, BCRYPT_KEY_LENGTH, (UCHAR *)&keylen, 2, 0);
2852
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
2853
ret = BCryptSetProperty(key, BCRYPT_KEY_LENGTH, (UCHAR *)&keylen, sizeof(keylen), 0);
2854
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2855
2856
ret = BCryptFinalizeKeyPair(key, 0);
2857
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2858
2859
keylen = 0;
2860
ret = BCryptGetProperty(key, BCRYPT_KEY_STRENGTH, (UCHAR *)&keylen, sizeof(keylen), &size, 0);
2861
ok(!ret, "got %#lx\n", ret);
2862
ok(size == sizeof(keylen), "got %lu\n", size);
2863
ok(keylen == 2048, "got %lu\n", keylen);
2864
2865
ret = BCryptSetProperty(key, BCRYPT_KEY_LENGTH, (UCHAR *)&keylen, sizeof(keylen), 0);
2866
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2867
2868
pad.pszAlgId = BCRYPT_MD5_ALGORITHM;
2869
memset(sig, 0, sizeof(sig));
2870
len = 0;
2871
ret = BCryptSignHash(key, &pad, hash, 16, sig, sizeof(sig), &len, BCRYPT_PAD_PKCS1);
2872
ok(!ret, "got %#lx\n", ret);
2873
ok(len == 256, "got %lu\n", len);
2874
pad.pszAlgId = BCRYPT_MD5_ALGORITHM;
2875
ret = BCryptVerifySignature(key, &pad, hash, 16, sig, len, BCRYPT_PAD_PKCS1);
2876
ok(!ret, "BCryptVerifySignature failed: %#lx\n", ret);
2877
2878
pad.pszAlgId = BCRYPT_SHA1_ALGORITHM;
2879
memset(sig, 0, sizeof(sig));
2880
len = 0;
2881
ret = BCryptSignHash(key, &pad, hash, sizeof(hash), sig, sizeof(sig), &len, BCRYPT_PAD_PKCS1);
2882
ok(!ret, "got %#lx\n", ret);
2883
ok(len == 256, "got %lu\n", len);
2884
pad.pszAlgId = BCRYPT_SHA1_ALGORITHM;
2885
ret = BCryptVerifySignature(key, &pad, hash, sizeof(hash), sig, len, BCRYPT_PAD_PKCS1);
2886
ok(!ret, "BCryptVerifySignature failed: %#lx\n", ret);
2887
2888
pad.pszAlgId = NULL;
2889
memset(sig, 0, sizeof(sig));
2890
len = 0;
2891
ret = BCryptSignHash(key, &pad, hash, sizeof(hash), sig, sizeof(sig), &len, BCRYPT_PAD_PKCS1);
2892
ok(!ret, "got %#lx\n", ret);
2893
ok(len == 256, "got %lu\n", len);
2894
2895
pad.pszAlgId = BCRYPT_SHA1_ALGORITHM;
2896
ret = BCryptVerifySignature(key, &pad, hash, sizeof(hash), sig, len, BCRYPT_PAD_PKCS1);
2897
ok(ret == STATUS_INVALID_SIGNATURE, "BCryptVerifySignature failed: %#lx, len %ld\n", ret, len);
2898
2899
pad.pszAlgId = NULL;
2900
ret = BCryptVerifySignature(key, &pad, hash, sizeof(hash), sig, len, BCRYPT_PAD_PKCS1);
2901
ok(!ret, "BCryptVerifySignature failed: %#lx, len %ld\n", ret, len);
2902
2903
pad_pss.pszAlgId = BCRYPT_SHA384_ALGORITHM;
2904
pad_pss.cbSalt = 48;
2905
memset(sig_pss, 0, sizeof(sig_pss));
2906
len = 0;
2907
ret = BCryptSignHash(key, &pad_pss, hash48, sizeof(hash48), sig_pss, sizeof(sig_pss), &len, BCRYPT_PAD_PSS);
2908
ok(!ret, "got %#lx\n", ret);
2909
ok(len == 256, "got %lu\n", len);
2910
2911
/* export private key */
2912
size = 0;
2913
ret = BCryptExportKey(key, NULL, BCRYPT_RSAPRIVATE_BLOB, NULL, 0, &size, 0);
2914
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2915
ok(size, "size not set\n");
2916
2917
buf = malloc(size);
2918
ret = BCryptExportKey(key, NULL, BCRYPT_RSAPRIVATE_BLOB, buf, size, &size, 0);
2919
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2920
rsablob = (BCRYPT_RSAKEY_BLOB *)buf;
2921
ok(rsablob->Magic == BCRYPT_RSAPRIVATE_MAGIC, "got %#lx\n", rsablob->Magic);
2922
ok(rsablob->BitLength == 2048, "got %lu\n", rsablob->BitLength);
2923
ok(rsablob->cbPublicExp == 3, "got %lu\n", rsablob->cbPublicExp);
2924
ok(rsablob->cbModulus == 256, "got %lu\n", rsablob->cbModulus);
2925
ok(rsablob->cbPrime1 == 128, "got %lu\n", rsablob->cbPrime1);
2926
ok(rsablob->cbPrime2 == 128, "got %lu\n", rsablob->cbPrime2);
2927
size2 = sizeof(*rsablob) + rsablob->cbPublicExp + rsablob->cbModulus + rsablob->cbPrime1 + rsablob->cbPrime2;
2928
ok(size == size2, "got %lu expected %lu\n", size2, size);
2929
free(buf);
2930
2931
size = 0;
2932
ret = BCryptExportKey(key, NULL, BCRYPT_RSAFULLPRIVATE_BLOB, NULL, 0, &size, 0);
2933
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2934
ok(size, "size not set\n");
2935
2936
buf = malloc(size);
2937
ret = BCryptExportKey(key, NULL, BCRYPT_RSAFULLPRIVATE_BLOB, buf, size, &size, 0);
2938
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2939
rsablob = (BCRYPT_RSAKEY_BLOB *)buf;
2940
ok(rsablob->Magic == BCRYPT_RSAFULLPRIVATE_MAGIC, "got %#lx\n", rsablob->Magic);
2941
ok(rsablob->BitLength == 2048, "got %lu\n", rsablob->BitLength);
2942
ok(rsablob->cbPublicExp == 3, "got %lu\n", rsablob->cbPublicExp);
2943
ok(rsablob->cbModulus == 256, "got %lu\n", rsablob->cbModulus);
2944
ok(rsablob->cbPrime1 == 128, "got %lu\n", rsablob->cbPrime1);
2945
ok(rsablob->cbPrime2 == 128, "got %lu\n", rsablob->cbPrime2);
2946
size2 = sizeof(*rsablob) + rsablob->cbPublicExp + rsablob->cbModulus * 2 + rsablob->cbPrime1 * 3 + rsablob->cbPrime2 * 2;
2947
ok(size == size2, "got %lu expected %lu\n", size2, size);
2948
free(buf);
2949
2950
/* import/export public key */
2951
size = 0;
2952
ret = BCryptExportKey(key, NULL, BCRYPT_RSAPUBLIC_BLOB, NULL, 0, &size, 0);
2953
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2954
ok(size, "size not set\n");
2955
2956
buf = malloc(size);
2957
ret = BCryptExportKey(key, NULL, BCRYPT_RSAPUBLIC_BLOB, buf, size, &size, 0);
2958
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2959
rsablob = (BCRYPT_RSAKEY_BLOB *)buf;
2960
ok(rsablob->Magic == BCRYPT_RSAPUBLIC_MAGIC, "got %#lx\n", rsablob->Magic);
2961
ok(rsablob->BitLength == 2048, "got %lu\n", rsablob->BitLength);
2962
ok(rsablob->cbPublicExp == 3, "got %lu\n", rsablob->cbPublicExp);
2963
ok(rsablob->cbModulus == 256, "got %lu\n", rsablob->cbModulus);
2964
ok(!rsablob->cbPrime1, "got %lu\n", rsablob->cbPrime1);
2965
ok(!rsablob->cbPrime2, "got %lu\n", rsablob->cbPrime2);
2966
ok(size == sizeof(*rsablob) + rsablob->cbPublicExp + rsablob->cbModulus, "got %lu\n", size);
2967
ret = BCryptDestroyKey(key);
2968
ok(!ret, "got %#lx\n", ret);
2969
2970
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_RSAPUBLIC_BLOB, &key, rsaPublicBlobWithInvalidPublicExpSize,
2971
sizeof(rsaPublicBlobWithInvalidPublicExpSize), 0);
2972
ok(ret == NTE_BAD_DATA, "got %#lx\n", ret);
2973
2974
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_RSAPUBLIC_BLOB, &key, buf, size, 0);
2975
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2976
free(buf);
2977
2978
ret = BCryptVerifySignature(key, &pad, hash, sizeof(hash), sig, sizeof(sig), BCRYPT_PAD_PKCS1);
2979
ok(!ret, "got %#lx\n", ret);
2980
ret = BCryptVerifySignature(key, &pad_pss, hash48, sizeof(hash48), sig_pss, sizeof(sig_pss), BCRYPT_PAD_PSS);
2981
ok(!ret, "got %#lx\n", ret);
2982
ret = BCryptDestroyKey(key);
2983
ok(!ret, "got %#lx\n", ret);
2984
2985
/* import/export private key */
2986
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_RSAPRIVATE_BLOB, &key, rsaPrivateBlob, sizeof(rsaPrivateBlob), 0);
2987
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2988
2989
ret = BCryptFinalizeKeyPair(key, 0);
2990
ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret);
2991
2992
size = 0;
2993
buf = malloc(sizeof(rsaPrivateBlob));
2994
ret = BCryptExportKey(key, NULL, BCRYPT_RSAPRIVATE_BLOB, buf, sizeof(rsaPrivateBlob), &size, 0);
2995
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2996
ok(size == sizeof(rsaPrivateBlob), "got %lu\n", size);
2997
ok(!memcmp(buf, rsaPrivateBlob, size), "wrong data\n");
2998
free(buf);
2999
BCryptDestroyKey(key);
3000
3001
/* import/export full private key */
3002
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_RSAFULLPRIVATE_BLOB, &key, rsaFullPrivateBlob, sizeof(rsaFullPrivateBlob), 0);
3003
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3004
3005
size = 0;
3006
buf = malloc(sizeof(rsaFullPrivateBlob));
3007
ret = BCryptExportKey(key, NULL, BCRYPT_RSAFULLPRIVATE_BLOB, buf, sizeof(rsaFullPrivateBlob), &size, 0);
3008
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3009
ok(size == sizeof(rsaFullPrivateBlob), "got %lu\n", size);
3010
ok(!memcmp(buf, rsaFullPrivateBlob, size), "wrong data\n");
3011
free(buf);
3012
BCryptDestroyKey(key);
3013
3014
ret = BCryptCloseAlgorithmProvider(alg, 0);
3015
ok(!ret, "got %#lx\n", ret);
3016
}
3017
3018
static void test_RSA_SIGN(void)
3019
{
3020
BCRYPT_PKCS1_PADDING_INFO pad;
3021
BCRYPT_ALG_HANDLE alg = NULL;
3022
BCRYPT_KEY_HANDLE key = NULL;
3023
BCRYPT_RSAKEY_BLOB *rsablob;
3024
NTSTATUS ret;
3025
ULONG size, size2;
3026
BYTE *buf, buf2[sizeof(BCRYPT_RSAKEY_BLOB) + sizeof(rsaPublicBlob)];
3027
3028
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_RSA_SIGN_ALGORITHM, NULL, 0);
3029
ok(!ret, "got %#lx\n", ret);
3030
3031
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_RSAPUBLIC_BLOB, &key, rsaPublicBlob, sizeof(rsaPublicBlob), 0);
3032
ok(!ret, "BCryptImportKeyPair failed: %#lx\n", ret);
3033
3034
memset(buf2, 0xcc, sizeof(buf2));
3035
ret = BCryptExportKey(key, NULL, BCRYPT_RSAPUBLIC_BLOB, buf2, sizeof(buf2), &size, 0);
3036
ok(!ret, "got %#lx\n", ret);
3037
rsablob = (BCRYPT_RSAKEY_BLOB *)buf2;
3038
ok(rsablob->Magic == BCRYPT_RSAPUBLIC_MAGIC, "got %#lx\n", rsablob->Magic);
3039
ok(rsablob->BitLength == 2048, "got %lu\n", rsablob->BitLength);
3040
ok(rsablob->cbPublicExp == 3, "got %lu\n", rsablob->cbPublicExp);
3041
ok(rsablob->cbModulus == 256, "got %lu\n", rsablob->cbModulus);
3042
ok(rsablob->cbPrime1 == 0, "got %lu\n", rsablob->cbPrime1);
3043
ok(rsablob->cbPrime2 == 0, "got %lu\n", rsablob->cbPrime2);
3044
size2 = sizeof(*rsablob) + rsablob->cbPublicExp + rsablob->cbModulus + rsablob->cbPrime1 + rsablob->cbPrime2;
3045
ok(size == size2, "got %lu expected %lu\n", size2, size);
3046
3047
ret = BCryptExportKey(key, NULL, BCRYPT_RSAPRIVATE_BLOB, buf2, sizeof(buf2), &size, 0);
3048
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
3049
3050
pad.pszAlgId = NULL;
3051
ret = BCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
3052
ok(ret == STATUS_INVALID_SIGNATURE, "BCryptVerifySignature failed: %#lx\n", ret);
3053
3054
pad.pszAlgId = BCRYPT_SHA1_ALGORITHM;
3055
ret = BCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
3056
ok(!ret, "BCryptVerifySignature failed: %#lx\n", ret);
3057
3058
ret = BCryptVerifySignature(key, NULL, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
3059
ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %#lx\n", ret);
3060
3061
pad.pszAlgId = BCRYPT_SHA1_ALGORITHM;
3062
ret = BCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), 0);
3063
ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %#lx\n", ret);
3064
3065
ret = BCryptVerifySignature(key, NULL, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), 0);
3066
ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %#lx\n", ret);
3067
3068
pad.pszAlgId = BCRYPT_AES_ALGORITHM;
3069
ret = BCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
3070
ok(ret == STATUS_NOT_SUPPORTED, "Expected STATUS_NOT_SUPPORTED, got %#lx\n", ret);
3071
3072
pad.pszAlgId = NULL;
3073
ret = BCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
3074
ok(ret == STATUS_INVALID_SIGNATURE, "Expected STATUS_INVALID_SIGNATURE, got %#lx\n", ret);
3075
3076
ret = BCryptDestroyKey(key);
3077
ok(!ret, "BCryptDestroyKey failed: %#lx\n", ret);
3078
3079
/* export private key */
3080
ret = BCryptGenerateKeyPair(alg, &key, 512, 0);
3081
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3082
3083
ret = BCryptFinalizeKeyPair(key, 0);
3084
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3085
3086
size = 0;
3087
ret = BCryptExportKey(key, NULL, BCRYPT_RSAPRIVATE_BLOB, NULL, 0, &size, 0);
3088
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3089
ok(size, "size not set\n");
3090
3091
buf = malloc(size);
3092
ret = BCryptExportKey(key, NULL, BCRYPT_RSAPRIVATE_BLOB, buf, size, &size, 0);
3093
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3094
rsablob = (BCRYPT_RSAKEY_BLOB *)buf;
3095
ok(rsablob->Magic == BCRYPT_RSAPRIVATE_MAGIC, "got %#lx\n", rsablob->Magic);
3096
ok(rsablob->BitLength == 512, "got %lu\n", rsablob->BitLength);
3097
ok(rsablob->cbPublicExp == 3, "got %lu\n", rsablob->cbPublicExp);
3098
ok(rsablob->cbModulus == 64, "got %lu\n", rsablob->cbModulus);
3099
ok(rsablob->cbPrime1 == 32, "got %lu\n", rsablob->cbPrime1);
3100
ok(rsablob->cbPrime2 == 32, "got %lu\n", rsablob->cbPrime2);
3101
size2 = sizeof(*rsablob) + rsablob->cbPublicExp + rsablob->cbModulus + rsablob->cbPrime1 + rsablob->cbPrime2;
3102
ok(size == size2, "got %lu expected %lu\n", size2, size);
3103
free(buf);
3104
3105
size = 0;
3106
ret = BCryptExportKey(key, NULL, BCRYPT_RSAFULLPRIVATE_BLOB, NULL, 0, &size, 0);
3107
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3108
ok(size, "size not set\n");
3109
3110
buf = malloc(size);
3111
ret = BCryptExportKey(key, NULL, BCRYPT_RSAFULLPRIVATE_BLOB, buf, size, &size, 0);
3112
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3113
rsablob = (BCRYPT_RSAKEY_BLOB *)buf;
3114
ok(rsablob->Magic == BCRYPT_RSAFULLPRIVATE_MAGIC, "got %#lx\n", rsablob->Magic);
3115
ok(rsablob->BitLength == 512, "got %lu\n", rsablob->BitLength);
3116
ok(rsablob->cbPublicExp == 3, "got %lu\n", rsablob->cbPublicExp);
3117
ok(rsablob->cbModulus == 64, "got %lu\n", rsablob->cbModulus);
3118
ok(rsablob->cbPrime1 == 32, "got %lu\n", rsablob->cbPrime1);
3119
ok(rsablob->cbPrime2 == 32, "got %lu\n", rsablob->cbPrime2);
3120
size2 = sizeof(*rsablob) + rsablob->cbPublicExp + rsablob->cbModulus * 2 + rsablob->cbPrime1 * 3 + rsablob->cbPrime2 * 2;
3121
ok(size == size2, "got %lu expected %lu\n", size2, size);
3122
free(buf);
3123
BCryptDestroyKey(key);
3124
3125
ret = BCryptCloseAlgorithmProvider(alg, 0);
3126
ok(!ret, "BCryptCloseAlgorithmProvider failed: %#lx\n", ret);
3127
}
3128
3129
struct ecdh_test
3130
{
3131
const WCHAR *alg;
3132
ULONG bitlen;
3133
BYTE *eccprivkey;
3134
ULONG eccprivkey_len;
3135
BYTE *ecdh_pubkey;
3136
ULONG ecdh_pubkey_len;
3137
BYTE *ecdh_secret;
3138
ULONG ecdh_secret_len;
3139
BYTE *hashed_secret;
3140
DWORD public_magic;
3141
DWORD private_magic;
3142
};
3143
3144
static void test_ECDH_alg(const struct ecdh_test *t)
3145
{
3146
BCryptBuffer hash_param_buffers[] =
3147
{
3148
{
3149
sizeof(BCRYPT_SHA1_ALGORITHM),
3150
KDF_HASH_ALGORITHM,
3151
(void *)BCRYPT_SHA1_ALGORITHM,
3152
}
3153
};
3154
3155
BCryptBufferDesc hash_params =
3156
{
3157
BCRYPTBUFFER_VERSION,
3158
ARRAY_SIZE(hash_param_buffers),
3159
hash_param_buffers,
3160
};
3161
BYTE *buf;
3162
BCRYPT_ECCKEY_BLOB *ecckey;
3163
BCRYPT_ALG_HANDLE alg;
3164
BCRYPT_KEY_HANDLE key, privkey, pubkey;
3165
BCRYPT_SECRET_HANDLE secret;
3166
NTSTATUS status;
3167
ULONG size;
3168
3169
status = BCryptOpenAlgorithmProvider(&alg, t->alg, NULL, 0);
3170
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3171
3172
key = NULL;
3173
status = BCryptGenerateKeyPair(alg, &key, t->bitlen, 0);
3174
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3175
ok(key != NULL, "key not set\n");
3176
3177
status = BCryptFinalizeKeyPair(key, 0);
3178
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3179
3180
size = 0;
3181
status = BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, NULL, 0, &size, 0);
3182
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3183
ok(size, "size not set\n");
3184
3185
buf = malloc(size);
3186
status = BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, buf, size, &size, 0);
3187
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3188
ecckey = (BCRYPT_ECCKEY_BLOB *)buf;
3189
ok(ecckey->dwMagic == t->public_magic, "got %#lx\n", ecckey->dwMagic);
3190
ok(ecckey->cbKey == (t->bitlen + 7) / 8, "got %lu\n", ecckey->cbKey);
3191
ok(size == sizeof(*ecckey) + ecckey->cbKey * 2, "got %lu\n", size);
3192
3193
status = BCryptImportKeyPair(alg, NULL, BCRYPT_PUBLIC_KEY_BLOB, &pubkey, buf, size, 0);
3194
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3195
BCryptDestroyKey(pubkey);
3196
3197
status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPUBLIC_BLOB, &pubkey, buf, size, 0);
3198
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3199
free(buf);
3200
3201
size = 0;
3202
status = BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, NULL, 0, &size, 0);
3203
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3204
ok(size, "size not set\n");
3205
3206
buf = malloc(size);
3207
status = BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, buf, size, &size, 0);
3208
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3209
ecckey = (BCRYPT_ECCKEY_BLOB *)buf;
3210
ok(ecckey->dwMagic == t->private_magic, "got %#lx\n", ecckey->dwMagic);
3211
ok(ecckey->cbKey == (t->bitlen + 7) / 8, "got %lu\n", ecckey->cbKey);
3212
ok(size == sizeof(*ecckey) + ecckey->cbKey * 3, "got %lu\n", size);
3213
3214
status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPRIVATE_BLOB, &privkey, buf, size, 0);
3215
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3216
free(buf);
3217
BCryptDestroyKey(pubkey);
3218
BCryptDestroyKey(privkey);
3219
BCryptDestroyKey(key);
3220
3221
status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPRIVATE_BLOB, &privkey, t->eccprivkey, t->eccprivkey_len, 0);
3222
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3223
3224
size = 0;
3225
status = BCryptExportKey(privkey, NULL, BCRYPT_ECCPRIVATE_BLOB, NULL, 0, &size, 0);
3226
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3227
ok(size, "size not set\n");
3228
3229
buf = malloc(size);
3230
status = BCryptExportKey(privkey, NULL, BCRYPT_ECCPRIVATE_BLOB, buf, size, &size, 0);
3231
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3232
ok(size == t->eccprivkey_len, "got %lu\n", size);
3233
ok(!memcmp(buf, t->eccprivkey, size), "wrong data\n");
3234
free(buf);
3235
3236
status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPUBLIC_BLOB, &pubkey, t->ecdh_pubkey, t->ecdh_pubkey_len, 0);
3237
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3238
3239
status = BCryptSecretAgreement(privkey, pubkey, &secret, 0);
3240
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3241
if (status != STATUS_SUCCESS) goto derive_end;
3242
3243
status = BCryptDeriveKey(secret, BCRYPT_KDF_RAW_SECRET, NULL, NULL, 0, &size, 0);
3244
if (status == STATUS_NOT_SUPPORTED) /* < win10 */
3245
{
3246
win_skip("BCRYPT_KDF_RAW_SECRET not supported\n");
3247
goto raw_secret_end;
3248
}
3249
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3250
if (status != STATUS_SUCCESS) goto raw_secret_end;
3251
3252
ok(size == (t->bitlen + 7) / 8, "size of secret key incorrect, got %lu, expected 32\n", size);
3253
buf = malloc(size);
3254
status = BCryptDeriveKey(secret, BCRYPT_KDF_RAW_SECRET, NULL, buf, size, &size, 0);
3255
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3256
ok(!(memcmp(t->ecdh_secret, buf, size)), "wrong data\n");
3257
free(buf);
3258
3259
raw_secret_end:
3260
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &hash_params, NULL, 0, &size, 0);
3261
ok (status == STATUS_SUCCESS, "got %#lx\n", status);
3262
if (status != STATUS_SUCCESS) goto derive_end;
3263
3264
ok (size == 20, "got %lu\n", size);
3265
buf = malloc(size);
3266
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &hash_params, buf, size, &size, 0);
3267
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3268
ok(!(memcmp(t->hashed_secret, buf, size)), "wrong data\n");
3269
free(buf);
3270
3271
/* ulVersion is not verified */
3272
hash_params.ulVersion = 0xdeadbeef;
3273
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &hash_params, NULL, 0, &size, 0);
3274
ok (status == STATUS_SUCCESS, "got %#lx\n", status);
3275
3276
hash_params.ulVersion = BCRYPTBUFFER_VERSION;
3277
hash_param_buffers[0].pvBuffer = (void*) L"INVALID";
3278
hash_param_buffers[0].cbBuffer = sizeof(L"INVALID");
3279
3280
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &hash_params, NULL, 0, &size, 0);
3281
ok (status == STATUS_NOT_SUPPORTED || broken (status == STATUS_NOT_FOUND) /* < win8 */, "got %#lx\n", status);
3282
3283
hash_param_buffers[0].pvBuffer = (void*) BCRYPT_RNG_ALGORITHM;
3284
hash_param_buffers[0].cbBuffer = sizeof(BCRYPT_RNG_ALGORITHM);
3285
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &hash_params, NULL, 0, &size, 0);
3286
ok (status == STATUS_NOT_SUPPORTED, "got %#lx\n", status);
3287
3288
derive_end:
3289
BCryptDestroySecret(secret);
3290
BCryptDestroyKey(pubkey);
3291
BCryptDestroyKey(privkey);
3292
BCryptCloseAlgorithmProvider(alg, 0);
3293
}
3294
3295
static void test_ECDH(void)
3296
{
3297
static BYTE ecc256privkey[] =
3298
{
3299
0x45, 0x43, 0x4b, 0x32, 0x20, 0x00, 0x00, 0x00,
3300
0xfb, 0xbd, 0x3d, 0x20, 0x1b, 0x6d, 0x66, 0xb3, 0x7c, 0x9f, 0x89, 0xf3, 0xe4, 0x41, 0x16, 0xa5,
3301
0x68, 0x52, 0x77, 0xac, 0xab, 0x55, 0xb2, 0x6c, 0xb0, 0x23, 0x55, 0xcb, 0x96, 0x14, 0xfd, 0x0b,
3302
0x1c, 0xef, 0xdf, 0x07, 0x6d, 0x31, 0xaf, 0x39, 0xce, 0x8c, 0x8f, 0x9d, 0x75, 0xd0, 0x7b, 0xea,
3303
0x81, 0xdc, 0x40, 0x21, 0x1f, 0x58, 0x22, 0x5f, 0x72, 0x55, 0xfc, 0x58, 0x8a, 0xeb, 0x88, 0x5d,
3304
0x02, 0x09, 0x90, 0xd2, 0xe3, 0x36, 0xac, 0xfe, 0x83, 0x13, 0x6c, 0x88, 0x1a, 0xab, 0x9b, 0xdd,
3305
0xaa, 0x8a, 0xee, 0x69, 0x9a, 0x6a, 0x62, 0x86, 0x6a, 0x13, 0x69, 0x88, 0xb7, 0xd5, 0xa3, 0xcd
3306
};
3307
static BYTE ecdh256_pubkey[] =
3308
{
3309
0x45, 0x43, 0x4b, 0x31, 0x20, 0x00, 0x00, 0x00,
3310
0x07, 0x61, 0x9d, 0x49, 0x63, 0x6b, 0x96, 0x94, 0xd1, 0x8f, 0xd1, 0x48, 0xcc, 0xcf, 0x72, 0x4d,
3311
0xff, 0x43, 0xf4, 0x97, 0x0f, 0xa3, 0x8a, 0x72, 0xe9, 0xe0, 0xba, 0x87, 0x6d, 0xc3, 0x62, 0x15,
3312
0xae, 0x65, 0xdd, 0x31, 0x51, 0xfc, 0x3b, 0xc9, 0x59, 0xa1, 0x0a, 0x92, 0x17, 0x2b, 0x64, 0x55,
3313
0x03, 0x3e, 0x62, 0x1d, 0xac, 0x3e, 0x37, 0x40, 0x6a, 0x4c, 0xb6, 0x21, 0x3f, 0x73, 0x5c, 0xf5
3314
};
3315
static BYTE ecdh256_secret[] =
3316
{
3317
0x48, 0xb0, 0x11, 0xdb, 0x69, 0x4e, 0xb4, 0xf4, 0xf5, 0x3e, 0xe1, 0x9b, 0xca, 0x00, 0x04, 0xc8,
3318
0x9b, 0x69, 0xaf, 0xd1, 0xaf, 0x1f, 0xc2, 0xd7, 0x83, 0x0a, 0xb7, 0xf8, 0x4f, 0x24, 0x32, 0x8e,
3319
};
3320
static BYTE hashed256_secret[] =
3321
{
3322
0x1b, 0xe7, 0xbf, 0x0f, 0x65, 0x1e, 0xd0, 0x07, 0xf9, 0xf4, 0x77, 0x48, 0x48, 0x39, 0xd0, 0xf8,
3323
0xf3, 0xce, 0xfc, 0x89
3324
};
3325
3326
static BYTE ecc384privkey[] =
3327
{
3328
0x45, 0x43, 0x4b, 0x34, 0x30, 0x00, 0x00, 0x00,
3329
0xc9, 0xcb, 0x38, 0x54, 0xa1, 0xe2, 0xb6, 0x60, 0x13, 0xd9, 0x45, 0x0d, 0x76, 0x90, 0xf9, 0x49,
3330
0x75, 0x81, 0x76, 0xac, 0x43, 0x96, 0xc1, 0x04, 0x04, 0xda, 0x76, 0x72, 0xb1, 0x19, 0x38, 0xbd,
3331
0xaf, 0x96, 0x0c, 0x4e, 0xc3, 0x29, 0x67, 0x91, 0x6c, 0xac, 0xcc, 0x33, 0x51, 0x1f, 0x82, 0xd5,
3332
0x17, 0xbf, 0xa2, 0x94, 0xd7, 0x15, 0x4f, 0x83, 0xe7, 0xa3, 0xb8, 0x6d, 0xd0, 0x7f, 0xbc, 0x8a,
3333
0x30, 0x09, 0x9e, 0x13, 0xaa, 0x2e, 0xf6, 0xde, 0x1c, 0x02, 0x4a, 0x65, 0xf6, 0x72, 0xb3, 0xf0,
3334
0x4f, 0x7f, 0x1a, 0xce, 0x4e, 0x94, 0xc5, 0x98, 0x89, 0x74, 0xad, 0x51, 0x8f, 0x2b, 0x25, 0x17,
3335
0xdc, 0x4a, 0x54, 0x8a, 0x42, 0xda, 0x30, 0x1a, 0xe3, 0x6d, 0x77, 0x4d, 0x3b, 0x33, 0x9a, 0xe3,
3336
0x37, 0xd4, 0x06, 0x5b, 0xb3, 0x3f, 0x73, 0xb9, 0x7e, 0x0b, 0x37, 0x02, 0x8b, 0xed, 0x08, 0x10,
3337
0x03, 0xf8, 0x69, 0xe3, 0x2a, 0x4f, 0xbb, 0x20, 0x6c, 0x5d, 0x24, 0x09, 0x0d, 0xd9, 0x86, 0x32,
3338
};
3339
static BYTE ecdh384_pubkey[] =
3340
{
3341
0x45, 0x43, 0x4b, 0x33, 0x30, 0x00, 0x00, 0x00,
3342
0xd6, 0xc3, 0xef, 0x4a, 0xbb, 0x4c, 0xa2, 0x27, 0xa1, 0x96, 0x03, 0x3b, 0x0a, 0x83, 0x01, 0xff,
3343
0xeb, 0x9a, 0xf1, 0x06, 0xee, 0x83, 0xce, 0x7c, 0xaa, 0x6b, 0x7c, 0x43, 0x1c, 0x8b, 0x30, 0x82,
3344
0x99, 0x8f, 0xc4, 0x86, 0x0d, 0x19, 0x16, 0xb6, 0xab, 0xd1, 0x9f, 0xeb, 0xf9, 0x31, 0xda, 0xcd,
3345
0xb9, 0xf8, 0xea, 0x87, 0xa1, 0x36, 0xaf, 0x10, 0x98, 0x8f, 0x9b, 0xcc, 0x6c, 0xe3, 0x24, 0xb4,
3346
0x82, 0x37, 0xde, 0x1e, 0x04, 0x53, 0x03, 0xc0, 0x2a, 0x41, 0xe9, 0x50, 0x07, 0x87, 0xb2, 0x60,
3347
0xe6, 0x32, 0x53, 0x4c, 0x8e, 0xa7, 0x80, 0x0f, 0xad, 0x25, 0x3b, 0x01, 0xa4, 0xd6, 0xe3, 0x54,
3348
};
3349
static BYTE ecdh384_secret[] =
3350
{
3351
0x08, 0x8c, 0xd1, 0xfa, 0x57, 0xb6, 0xf9, 0x79, 0x9e, 0x0c, 0x71, 0xc3, 0xcb, 0xa5, 0xb1, 0xfd,
3352
0xde, 0xbc, 0x6d, 0x7c, 0x8a, 0x5b, 0x26, 0xe8, 0x18, 0x80, 0x61, 0x45, 0x6a, 0x38, 0xf9, 0x13,
3353
0x2a, 0x8f, 0x4b, 0xfe, 0x75, 0x02, 0x62, 0xe9, 0xb3, 0x6e, 0xc5, 0x52, 0xc9, 0x82, 0x38, 0x53,
3354
};
3355
static BYTE hashed384_secret[] =
3356
{
3357
0x78, 0xf8, 0x07, 0xab, 0x00, 0x35, 0xaa, 0x8c, 0x22, 0xd0, 0xe7, 0x06, 0xfc, 0x0b, 0x74, 0x41,
3358
0xed, 0xdc, 0x16, 0x6c,
3359
};
3360
3361
static BYTE ecc521privkey[] =
3362
{
3363
0x45, 0x43, 0x4b, 0x36, 0x42, 0x00, 0x00, 0x00,
3364
0x01, 0x96, 0xb0, 0x4e, 0x35, 0x6f, 0xbe, 0x00, 0xb6, 0xc3, 0x83, 0x53, 0x92, 0x18, 0xda, 0x86,
3365
0x9e, 0x4b, 0x0f, 0xb2, 0x0b, 0xc3, 0x9f, 0xd8, 0x9c, 0x18, 0x8a, 0x93, 0x5c, 0x91, 0xb2, 0x4f,
3366
0x56, 0x7d, 0x0e, 0xf7, 0xf4, 0xdf, 0x91, 0xc6, 0x74, 0x00, 0xc7, 0xb8, 0x59, 0xeb, 0x55, 0xc0,
3367
0xb5, 0x26, 0x7f, 0x6d, 0x49, 0x53, 0x02, 0x3b, 0x3c, 0xa0, 0x57, 0x1e, 0x1c, 0x7c, 0x5b, 0x08,
3368
0x23, 0x68, 0x01, 0x47, 0x4d, 0x47, 0xcf, 0x05, 0xfe, 0x18, 0x26, 0x81, 0x9d, 0xb4, 0x34, 0xfa,
3369
0x50, 0x7e, 0x03, 0x29, 0xa3, 0x6e, 0x90, 0x9c, 0x27, 0x69, 0x66, 0x2c, 0x70, 0x7b, 0xf9, 0xe7,
3370
0xef, 0xac, 0x27, 0xbf, 0x15, 0x86, 0xf6, 0xff, 0x2d, 0x99, 0x41, 0x9e, 0x36, 0x1f, 0xe9, 0x3a,
3371
0x99, 0x74, 0x54, 0xf3, 0xc3, 0x08, 0xb1, 0x00, 0x28, 0x84, 0x82, 0x84, 0xe3, 0xf4, 0x32, 0xfd,
3372
0x48, 0x67, 0xae, 0x08, 0x01, 0xe2, 0x08, 0x1d, 0xeb, 0x27, 0xc2, 0x98, 0x45, 0x8b, 0x33, 0x20,
3373
0x3b, 0x21, 0x5c, 0x7f, 0x56, 0xbd, 0xa5, 0x99, 0x58, 0xea, 0x19, 0xf8, 0xbc, 0xf1, 0x9e, 0x39,
3374
0x00, 0xb9, 0x2c, 0x2a, 0xb6, 0x19, 0x3a, 0xaf, 0xea, 0x4b, 0xa6, 0x22, 0xb4, 0x35, 0x09, 0x86,
3375
0x2e, 0x67, 0xe0, 0xfe, 0x81, 0x0e, 0x6a, 0x68, 0x6a, 0xb3, 0x32, 0x3b, 0xf8, 0x89, 0x45, 0x72,
3376
0x69, 0xf1, 0xe1, 0x84, 0xd7, 0xed,
3377
};
3378
static BYTE ecdh521_pubkey[] =
3379
{
3380
0x45, 0x43, 0x4b, 0x35, 0x42, 0x00, 0x00, 0x00,
3381
0x00, 0xfd, 0x72, 0xca, 0x31, 0x08, 0x76, 0xd9, 0x08, 0xb7, 0x26, 0x4a, 0x04, 0xbc, 0x73, 0x1a,
3382
0x04, 0xbb, 0x77, 0xf4, 0xe2, 0xfc, 0x3a, 0x88, 0x0a, 0xa8, 0x72, 0x8f, 0xfc, 0xe9, 0xe3, 0x5f,
3383
0x73, 0x05, 0xf1, 0x7f, 0x31, 0xee, 0x15, 0x91, 0x36, 0xe9, 0xeb, 0xed, 0xbe, 0x0e, 0x78, 0xa1,
3384
0x28, 0x4e, 0xc5, 0xcb, 0xba, 0xd8, 0x0c, 0x96, 0x75, 0x44, 0x71, 0x71, 0x00, 0x41, 0x43, 0xdf,
3385
0x27, 0x91, 0x00, 0x81, 0xcc, 0x56, 0x8d, 0x8e, 0x32, 0xae, 0x78, 0xfb, 0x3e, 0x84, 0x7b, 0x3b,
3386
0xf8, 0x8e, 0x7b, 0x27, 0x73, 0xa4, 0x11, 0x61, 0x24, 0x40, 0x9b, 0xbe, 0xd3, 0xc3, 0x0e, 0xbb,
3387
0x26, 0xae, 0x55, 0x58, 0xd1, 0xec, 0x14, 0xd3, 0x13, 0xf2, 0x6b, 0x2b, 0xc3, 0xf9, 0xa4, 0x50,
3388
0x9e, 0xce, 0xfe, 0x18, 0xa0, 0x8b, 0x10, 0x80, 0x68, 0x72, 0x2e, 0x5c, 0xa0, 0xb3, 0x01, 0x6b,
3389
0x43, 0x26, 0xad, 0x58,
3390
};
3391
static BYTE ecdh521_secret[] =
3392
{
3393
0x2d, 0xab, 0x9f, 0x38, 0x14, 0x5d, 0x49, 0x65, 0x06, 0x22, 0x04, 0xf9, 0xb3, 0x25, 0xca, 0xf9,
3394
0xe6, 0xdc, 0xc6, 0xe8, 0xf9, 0x0b, 0xbf, 0x3c, 0x9d, 0xf0, 0x08, 0x95, 0x92, 0xdd, 0x92, 0x8a,
3395
0x95, 0x85, 0xe8, 0x1c, 0x6d, 0x41, 0xb9, 0xe4, 0x7b, 0x7a, 0xa5, 0x68, 0x30, 0x48, 0x8e, 0xc0,
3396
0xbc, 0x2b, 0xc6, 0xe9, 0x75, 0x9c, 0xed, 0xc3, 0xf5, 0x3a, 0xa3, 0xd7, 0x41, 0xec, 0x28, 0x82,
3397
0xef, 0x01,
3398
};
3399
static BYTE hashed521_secret[] =
3400
{
3401
0x72, 0x39, 0x73, 0x5f, 0xc9, 0x26, 0x1f, 0x8e, 0xe3, 0x30, 0x11, 0xe1, 0x4f, 0xc4, 0x65, 0xc0,
3402
0xde, 0xf9, 0xe6, 0x6a,
3403
};
3404
3405
static const struct ecdh_test tests[] =
3406
{
3407
{
3408
BCRYPT_ECDH_P256_ALGORITHM, 256, ecc256privkey, sizeof(ecc256privkey), ecdh256_pubkey, sizeof(ecdh256_pubkey),
3409
ecdh256_secret, sizeof(ecdh256_secret), hashed256_secret,
3410
BCRYPT_ECDH_PUBLIC_P256_MAGIC, BCRYPT_ECDH_PRIVATE_P256_MAGIC,
3411
},
3412
{
3413
BCRYPT_ECDH_P384_ALGORITHM, 384, ecc384privkey, sizeof(ecc384privkey), ecdh384_pubkey, sizeof(ecdh384_pubkey),
3414
ecdh384_secret, sizeof(ecdh384_secret), hashed384_secret,
3415
BCRYPT_ECDH_PUBLIC_P384_MAGIC, BCRYPT_ECDH_PRIVATE_P384_MAGIC,
3416
},
3417
{
3418
BCRYPT_ECDH_P521_ALGORITHM, 521, ecc521privkey, sizeof(ecc521privkey), ecdh521_pubkey, sizeof(ecdh521_pubkey),
3419
ecdh521_secret, sizeof(ecdh521_secret), hashed521_secret,
3420
BCRYPT_ECDH_PUBLIC_P521_MAGIC, BCRYPT_ECDH_PRIVATE_P521_MAGIC,
3421
},
3422
};
3423
unsigned int i;
3424
3425
for (i = 0; i < ARRAY_SIZE(tests); ++i)
3426
{
3427
winetest_push_context("%s", debugstr_w(tests[i].alg));
3428
test_ECDH_alg(&tests[i]);
3429
winetest_pop_context();
3430
}
3431
}
3432
3433
static BYTE dh_pubkey[] =
3434
{
3435
/* BCRYPT_DH_KEY_BLOB */
3436
0x44, 0x48, 0x50, 0x42, 0x40, 0x00, 0x00, 0x00,
3437
/* p */
3438
0xcf, 0x18, 0xe9, 0xa9, 0xb3, 0x97, 0x59, 0xae, 0x0d, 0xac, 0xf0, 0x99, 0x39, 0xdc, 0xd2, 0xfe,
3439
0x1e, 0xf3, 0xfc, 0x2c, 0x49, 0xdf, 0x76, 0x89, 0xff, 0x13, 0x57, 0xc7, 0xe6, 0xbd, 0xed, 0xa7,
3440
0x42, 0xc0, 0xc3, 0xd7, 0x8e, 0x84, 0xa8, 0xdf, 0xcd, 0x52, 0x50, 0x81, 0x73, 0x8a, 0x33, 0x60,
3441
0xde, 0x6d, 0x56, 0xeb, 0xd5, 0xec, 0x1f, 0x9f, 0x9f, 0xd6, 0x2c, 0xe4, 0x8f, 0xab, 0x58, 0x0b,
3442
/* g */
3443
0x5f, 0xc5, 0x50, 0x9a, 0xde, 0xf6, 0x84, 0x48, 0x39, 0xa9, 0xa7, 0xb1, 0x73, 0x0c, 0x56, 0xd4,
3444
0x28, 0xbb, 0x12, 0x93, 0x51, 0x44, 0x33, 0xdf, 0xa6, 0xe7, 0x7f, 0x0b, 0x3f, 0xe9, 0x41, 0xef,
3445
0x32, 0x80, 0xcd, 0x8e, 0x2b, 0x38, 0x85, 0x49, 0x4d, 0x0c, 0xcc, 0x74, 0x02, 0x07, 0x92, 0xd3,
3446
0xe4, 0x3e, 0x37, 0x84, 0x27, 0x1f, 0xa3, 0xad, 0x94, 0x8c, 0xc1, 0xc2, 0x22, 0x99, 0x36, 0xf0,
3447
/* y */
3448
0x22, 0xaf, 0x98, 0xeb, 0xd9, 0xc4, 0xb5, 0xbd, 0xe1, 0xab, 0x19, 0x1b, 0xe3, 0x36, 0x20, 0xca,
3449
0xff, 0xe8, 0x6c, 0x30, 0x96, 0x3c, 0x90, 0x77, 0x0e, 0xe0, 0x96, 0xae, 0xb1, 0x47, 0xd1, 0x52,
3450
0x2c, 0xc3, 0x65, 0x5e, 0x9b, 0x41, 0x9a, 0xa6, 0xfe, 0xab, 0x54, 0xa0, 0xf0, 0x71, 0xab, 0x6c,
3451
0xd0, 0x0e, 0x01, 0x08, 0x5b, 0x66, 0xe5, 0x62, 0xd2, 0xe5, 0x5d, 0xae, 0x9c, 0x60, 0xb2, 0xc6,
3452
};
3453
3454
static BYTE dh_privkey[] =
3455
{
3456
/* BCRYPT_DH_KEY_BLOB */
3457
0x44, 0x48, 0x50, 0x56, 0x40, 0x00, 0x00, 0x00,
3458
/* p */
3459
0xcf, 0x18, 0xe9, 0xa9, 0xb3, 0x97, 0x59, 0xae, 0x0d, 0xac, 0xf0, 0x99, 0x39, 0xdc, 0xd2, 0xfe,
3460
0x1e, 0xf3, 0xfc, 0x2c, 0x49, 0xdf, 0x76, 0x89, 0xff, 0x13, 0x57, 0xc7, 0xe6, 0xbd, 0xed, 0xa7,
3461
0x42, 0xc0, 0xc3, 0xd7, 0x8e, 0x84, 0xa8, 0xdf, 0xcd, 0x52, 0x50, 0x81, 0x73, 0x8a, 0x33, 0x60,
3462
0xde, 0x6d, 0x56, 0xeb, 0xd5, 0xec, 0x1f, 0x9f, 0x9f, 0xd6, 0x2c, 0xe4, 0x8f, 0xab, 0x58, 0x0b,
3463
/* g */
3464
0x5f, 0xc5, 0x50, 0x9a, 0xde, 0xf6, 0x84, 0x48, 0x39, 0xa9, 0xa7, 0xb1, 0x73, 0x0c, 0x56, 0xd4,
3465
0x28, 0xbb, 0x12, 0x93, 0x51, 0x44, 0x33, 0xdf, 0xa6, 0xe7, 0x7f, 0x0b, 0x3f, 0xe9, 0x41, 0xef,
3466
0x32, 0x80, 0xcd, 0x8e, 0x2b, 0x38, 0x85, 0x49, 0x4d, 0x0c, 0xcc, 0x74, 0x02, 0x07, 0x92, 0xd3,
3467
0xe4, 0x3e, 0x37, 0x84, 0x27, 0x1f, 0xa3, 0xad, 0x94, 0x8c, 0xc1, 0xc2, 0x22, 0x99, 0x36, 0xf0,
3468
/* y */
3469
0x22, 0xaf, 0x98, 0xeb, 0xd9, 0xc4, 0xb5, 0xbd, 0xe1, 0xab, 0x19, 0x1b, 0xe3, 0x36, 0x20, 0xca,
3470
0xff, 0xe8, 0x6c, 0x30, 0x96, 0x3c, 0x90, 0x77, 0x0e, 0xe0, 0x96, 0xae, 0xb1, 0x47, 0xd1, 0x52,
3471
0x2c, 0xc3, 0x65, 0x5e, 0x9b, 0x41, 0x9a, 0xa6, 0xfe, 0xab, 0x54, 0xa0, 0xf0, 0x71, 0xab, 0x6c,
3472
0xd0, 0x0e, 0x01, 0x08, 0x5b, 0x66, 0xe5, 0x62, 0xd2, 0xe5, 0x5d, 0xae, 0x9c, 0x60, 0xb2, 0xc6,
3473
/* x */
3474
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3475
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3476
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x71, 0x3e, 0x82,
3477
0x8b, 0xea, 0x11, 0x77, 0xc4, 0xb4, 0x62, 0xc7, 0x4d, 0xff, 0x0f, 0x63, 0xd9, 0xe2, 0xda, 0xab,
3478
};
3479
3480
static BYTE dh_secret[] =
3481
{
3482
0x73, 0x84, 0x62, 0xc1, 0x9a, 0x9c, 0xc2, 0x91, 0x9f, 0xc1, 0xc2, 0x94, 0x0c, 0xa8, 0x2f, 0x58,
3483
0xac, 0x50, 0xcd, 0xd5, 0x29, 0x43, 0x41, 0x8e, 0x5d, 0xca, 0x73, 0x55, 0x4d, 0x46, 0x50, 0xe5,
3484
0xb7, 0x34, 0xa9, 0xcb, 0x3a, 0x18, 0x68, 0x99, 0x30, 0xef, 0x58, 0x26, 0xd3, 0x03, 0x61, 0x02,
3485
0x17, 0xb7, 0xba, 0x01, 0xbc, 0xae, 0xdf, 0x3f, 0xb5, 0xb5, 0x4a, 0xb0, 0x08, 0xe5, 0xea, 0xc3,
3486
};
3487
3488
static BYTE dh_hashed_secret[] =
3489
{
3490
0xa7, 0xfc, 0xff, 0x21, 0xb3, 0xd1, 0x46, 0xb8, 0x21, 0x3d, 0xc6, 0xd4, 0xe3, 0x61, 0x97, 0x5e,
3491
0xb5, 0x0a, 0xfe, 0x8f,
3492
};
3493
3494
BCryptBuffer dh_hash_param_buffers[] =
3495
{
3496
{
3497
sizeof(BCRYPT_SHA1_ALGORITHM),
3498
KDF_HASH_ALGORITHM,
3499
(void *)BCRYPT_SHA1_ALGORITHM,
3500
}
3501
};
3502
3503
BCryptBufferDesc dh_hash_params =
3504
{
3505
BCRYPTBUFFER_VERSION,
3506
ARRAY_SIZE(dh_hash_param_buffers),
3507
dh_hash_param_buffers,
3508
};
3509
3510
static void test_DH(void)
3511
{
3512
UCHAR hash[20];
3513
BCRYPT_KEY_HANDLE key, pubkey, privkey;
3514
BCRYPT_SECRET_HANDLE secret;
3515
BCRYPT_DH_KEY_BLOB *dhkey;
3516
NTSTATUS status;
3517
UCHAR *buf;
3518
ULONG size;
3519
3520
if (!pBCryptHash) /* < Win10 */
3521
{
3522
win_skip("broken DH detected\n");
3523
return;
3524
}
3525
3526
key = NULL;
3527
status = BCryptGenerateKeyPair(BCRYPT_DH_ALG_HANDLE, &key, 512, 0);
3528
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3529
ok(key != NULL, "key not set\n");
3530
3531
status = BCryptFinalizeKeyPair(key, 0);
3532
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3533
if (status != STATUS_SUCCESS)
3534
{
3535
BCryptDestroyKey(key);
3536
return;
3537
}
3538
3539
size = 0;
3540
status = BCryptExportKey(key, NULL, BCRYPT_DH_PUBLIC_BLOB, NULL, 0, &size, 0);
3541
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3542
ok(size, "size not set\n");
3543
3544
buf = malloc(size);
3545
status = BCryptExportKey(key, NULL, BCRYPT_DH_PUBLIC_BLOB, buf, size, &size, 0);
3546
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3547
dhkey = (BCRYPT_DH_KEY_BLOB *)buf;
3548
ok(dhkey->dwMagic == BCRYPT_DH_PUBLIC_MAGIC, "got %#lx\n", dhkey->dwMagic);
3549
ok(dhkey->cbKey == 64, "got %lu\n", dhkey->cbKey);
3550
ok(size == sizeof(*dhkey) + dhkey->cbKey * 3, "got %lu\n", size);
3551
3552
status = BCryptImportKeyPair(BCRYPT_DH_ALG_HANDLE, NULL, BCRYPT_DH_PUBLIC_BLOB, &pubkey, buf, size, 0);
3553
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3554
free(buf);
3555
BCryptDestroyKey(pubkey);
3556
3557
size = 0;
3558
status = BCryptExportKey(key, NULL, BCRYPT_DH_PRIVATE_BLOB, NULL, 0, &size, 0);
3559
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3560
ok(size == sizeof(*dhkey) + 64 * 4, "size not set\n");
3561
3562
buf = calloc(1, size);
3563
status = BCryptExportKey(key, NULL, BCRYPT_DH_PRIVATE_BLOB, buf, size, &size, 0);
3564
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3565
dhkey = (BCRYPT_DH_KEY_BLOB *)buf;
3566
ok(dhkey->dwMagic == BCRYPT_DH_PRIVATE_MAGIC, "got %#lx\n", dhkey->dwMagic);
3567
ok(dhkey->cbKey == 64, "got %lu\n", dhkey->cbKey);
3568
ok(size == sizeof(*dhkey) + dhkey->cbKey * 4, "got %lu\n", size);
3569
BCryptDestroyKey(key);
3570
3571
status = BCryptImportKeyPair(BCRYPT_DH_ALG_HANDLE, NULL, BCRYPT_DH_PRIVATE_BLOB, &privkey, buf, size, 0);
3572
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3573
free(buf);
3574
BCryptDestroyKey(privkey);
3575
3576
status = BCryptImportKeyPair(BCRYPT_DH_ALG_HANDLE, NULL, BCRYPT_DH_PRIVATE_BLOB, &privkey, dh_privkey,
3577
sizeof(dh_privkey), 0);
3578
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3579
3580
size = 0;
3581
status = BCryptExportKey(privkey, NULL, BCRYPT_DH_PRIVATE_BLOB, NULL, 0, &size, 0);
3582
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3583
ok(size, "size not set\n");
3584
3585
buf = malloc(size);
3586
status = BCryptExportKey(privkey, NULL, BCRYPT_DH_PRIVATE_BLOB, buf, size, &size, 0);
3587
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3588
ok(size == sizeof(dh_privkey), "got %lu\n", size);
3589
ok(!memcmp(buf, dh_privkey, size), "wrong data\n");
3590
free(buf);
3591
3592
status = BCryptImportKeyPair(BCRYPT_DH_ALG_HANDLE, NULL, BCRYPT_DH_PUBLIC_BLOB, &pubkey, dh_pubkey,
3593
sizeof(dh_pubkey), 0);
3594
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3595
3596
size = 0;
3597
status = BCryptExportKey(privkey, NULL, BCRYPT_DH_PUBLIC_BLOB, NULL, 0, &size, 0);
3598
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3599
ok(size, "size not set\n");
3600
3601
buf = malloc(size);
3602
status = BCryptExportKey(privkey, NULL, BCRYPT_DH_PUBLIC_BLOB, buf, size, &size, 0);
3603
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3604
ok(size == sizeof(dh_pubkey), "got %lu\n", size);
3605
ok(!memcmp(buf, dh_pubkey, size), "wrong data\n");
3606
free(buf);
3607
3608
status = BCryptSignHash(privkey, NULL, hash, sizeof(hash), NULL, 0, &size, 0);
3609
ok(status == STATUS_NOT_SUPPORTED, "got %#lx\n", status);
3610
3611
status = BCryptEncrypt(privkey, NULL, 0, NULL, NULL, 0, NULL, 0, &size, 0);
3612
ok(status == STATUS_NOT_SUPPORTED, "got %lx\n", status);
3613
3614
status = BCryptSecretAgreement(privkey, pubkey, &secret, 0);
3615
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3616
BCryptDestroyKey(pubkey);
3617
BCryptDestroyKey(privkey);
3618
3619
size = 0;
3620
status = BCryptDeriveKey(secret, BCRYPT_KDF_RAW_SECRET, NULL, NULL, 0, &size, 0);
3621
if (status == STATUS_NOT_SUPPORTED)
3622
{
3623
win_skip("BCRYPT_KDF_RAW_SECRET not supported\n"); /* < win10 */
3624
BCryptDestroySecret(secret);
3625
return;
3626
}
3627
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3628
ok(size == 64, "got %lu\n", size);
3629
3630
buf = calloc(1, size);
3631
status = BCryptDeriveKey(secret, BCRYPT_KDF_RAW_SECRET, NULL, buf, size, &size, 0);
3632
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3633
ok(!memcmp(dh_secret, buf, size), "wrong data\n");
3634
free(buf);
3635
3636
size = 0;
3637
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, NULL, NULL, 0, &size, 0);
3638
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3639
ok(size == 20, "got %lu\n", size);
3640
3641
size = 0;
3642
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &dh_hash_params, NULL, 0, &size, 0);
3643
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3644
ok(size == 20, "got %lu\n", size);
3645
3646
buf = calloc(1, size);
3647
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &dh_hash_params, buf, size, NULL, 0);
3648
ok(status == STATUS_INVALID_PARAMETER, "got %#lx\n", status);
3649
3650
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &dh_hash_params, buf, size, &size, 0);
3651
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3652
ok(!memcmp(dh_hashed_secret, buf, size), "wrong data\n");
3653
ok(size == 20, "got %lu\n", size);
3654
3655
memset(buf, 0, 20);
3656
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &dh_hash_params, buf, 10, &size, 0);
3657
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3658
ok(!memcmp(dh_hashed_secret, buf, size), "wrong data\n");
3659
ok(size == 10, "got %lu\n", size);
3660
free(buf);
3661
3662
BCryptDestroySecret(secret);
3663
}
3664
3665
static void test_BCryptEnumContextFunctions(void)
3666
{
3667
CRYPT_CONTEXT_FUNCTIONS *buffer;
3668
NTSTATUS status;
3669
ULONG buflen;
3670
3671
buffer = NULL;
3672
status = BCryptEnumContextFunctions( CRYPT_LOCAL, L"SSL", NCRYPT_SCHANNEL_INTERFACE, &buflen, &buffer );
3673
todo_wine ok( status == STATUS_SUCCESS, "got %#lx\n", status);
3674
if (status == STATUS_SUCCESS) BCryptFreeBuffer( buffer );
3675
}
3676
3677
static BYTE rsapublic[] =
3678
{
3679
0x52, 0x53, 0x41, 0x31, 0x00, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3680
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0xd5, 0xfe, 0xf6, 0x7a, 0x9a, 0xa1, 0x2d, 0xcf, 0x98,
3681
0x60, 0xca, 0x38, 0x60, 0x0b, 0x74, 0x4c, 0x7e, 0xa1, 0x42, 0x64, 0xad, 0x05, 0xa5, 0x29, 0x25, 0xcb, 0xd5,
3682
0x9c, 0xaf, 0x6f, 0x63, 0x85, 0x6d, 0x5b, 0x59, 0xe5, 0x17, 0x8f, 0xf9, 0x18, 0x90, 0xa7, 0x63, 0xae, 0xe0,
3683
0x3a, 0x62, 0xf7, 0x98, 0x57, 0xe9, 0x91, 0xda, 0xfb, 0xd9, 0x36, 0x45, 0xe4, 0x9e, 0x75, 0xf6, 0x73, 0xc4,
3684
0x99, 0x23, 0x21, 0x1b, 0x3d, 0xe1, 0xe0, 0xa6, 0xa0, 0x4a, 0x50, 0x2a, 0xcb, 0x2a, 0x50, 0xf0, 0x8b, 0x70,
3685
0x9c, 0xe4, 0x1a, 0x14, 0x3b, 0xbe, 0x35, 0xa5, 0x5a, 0x91, 0xa3, 0xa1, 0x82, 0xea, 0x84, 0x4d, 0xe8, 0x62,
3686
0x3b, 0x11, 0xec, 0x61, 0x09, 0x6c, 0xfe, 0xb2, 0xcc, 0x4b, 0xa8, 0xff, 0xaf, 0x73, 0x72, 0x05, 0x4e, 0x7e,
3687
0xe5, 0x73, 0xdf, 0x24, 0xcf, 0x7f, 0x5d, 0xaf, 0x8a, 0xf0, 0xd8, 0xcb, 0x08, 0x1e, 0xf2, 0x36, 0x70, 0x8d,
3688
0x1b, 0x9e, 0xc8, 0x98, 0x60, 0x54, 0xeb, 0x45, 0x34, 0x21, 0x43, 0x4d, 0x42, 0x0a, 0x3a, 0x2d, 0x0f, 0x0e,
3689
0xd6, 0x0d, 0xe4, 0x2e, 0x8c, 0x31, 0x87, 0xa8, 0x09, 0x89, 0x61, 0x16, 0xca, 0x5b, 0xbe, 0x76, 0x69, 0xbb,
3690
0xfd, 0x91, 0x63, 0xd2, 0x66, 0x57, 0x08, 0xef, 0xe2, 0x40, 0x67, 0xd7, 0x7f, 0x50, 0x15, 0x42, 0x33, 0x97,
3691
0x54, 0x73, 0x47, 0xe7, 0x9c, 0x14, 0xa8, 0xb0, 0x3d, 0xc9, 0x23, 0xb0, 0x27, 0x3b, 0xe7, 0xdd, 0x5f, 0xd1,
3692
0x4f, 0x31, 0x10, 0x7d, 0xdd, 0x69, 0x8e, 0xde, 0xa3, 0xe8, 0x92, 0x00, 0xfa, 0xa5, 0xa4, 0x40, 0x51, 0x23,
3693
0x82, 0x84, 0xc7, 0xce, 0x19, 0x61, 0x26, 0xf1, 0xae, 0xf3, 0x90, 0x93, 0x98, 0x56, 0x23, 0x9a, 0xd1, 0xbd,
3694
0xf2, 0xdf, 0xfd, 0x13, 0x9c, 0x30, 0x07, 0xf9, 0x5a, 0x2e, 0x00, 0xc6, 0x1f
3695
};
3696
3697
static void test_BCryptSignHash(void)
3698
{
3699
static UCHAR hash[] =
3700
{0x7e,0xe3,0x74,0xe7,0xc5,0x0b,0x6b,0x70,0xdb,0xab,0x32,0x6d,0x1d,0x51,0xd6,0x74,0x79,0x8e,0x5b,0x4b};
3701
static UCHAR hash_sha256[] =
3702
{0x25,0x2f,0x10,0xc8,0x36,0x10,0xeb,0xca,0x1a,0x05,0x9c,0x0b,0xae,0x82,0x55,0xeb,0xa2,0xf9,0x5b,0xe4,
3703
0xd1,0xd7,0xbC,0xfA,0x89,0xd7,0x24,0x8a,0x82,0xd9,0xf1,0x11};
3704
BCRYPT_PKCS1_PADDING_INFO pad;
3705
BCRYPT_ALG_HANDLE alg;
3706
BCRYPT_KEY_HANDLE key;
3707
UCHAR sig[256];
3708
NTSTATUS ret;
3709
ULONG len;
3710
3711
/* RSA */
3712
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_RSA_ALGORITHM, NULL, 0);
3713
ok(!ret, "got %#lx\n", ret);
3714
3715
/* public key */
3716
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_RSAPUBLIC_BLOB, &key, rsapublic, sizeof(rsapublic), 0);
3717
ok(!ret, "got %#lx\n", ret);
3718
3719
len = 0;
3720
pad.pszAlgId = BCRYPT_SHA1_ALGORITHM;
3721
ret = BCryptSignHash(key, &pad, NULL, 0, NULL, 0, &len, BCRYPT_PAD_PKCS1);
3722
ok(!ret, "got %#lx\n", ret);
3723
ok(len == 256, "got %lu\n", len);
3724
3725
/* test len return when only output is NULL, as described in BCryptSignHash doc */
3726
ret = BCryptSignHash(key, &pad, hash, sizeof(hash), NULL, 0, &len, BCRYPT_PAD_PKCS1);
3727
ok(!ret, "got %#lx\n", ret);
3728
ok(len == 256, "got %lu\n", len);
3729
3730
len = 0;
3731
ret = BCryptSignHash(key, &pad, hash, sizeof(hash), sig, sizeof(sig), &len, BCRYPT_PAD_PKCS1);
3732
ok(ret == STATUS_INVALID_PARAMETER || broken(ret == STATUS_INTERNAL_ERROR) /* < win7 */, "got %#lx\n", ret);
3733
ret = BCryptDestroyKey(key);
3734
ok(!ret, "got %#lx\n", ret);
3735
3736
ret = BCryptGenerateKeyPair(alg, &key, 512, 0);
3737
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3738
3739
ret = BCryptFinalizeKeyPair(key, 0);
3740
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3741
3742
ret = BCryptFinalizeKeyPair(key, 0);
3743
ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret);
3744
3745
len = 0;
3746
memset(sig, 0, sizeof(sig));
3747
3748
/* inference of padding info on RSA not supported */
3749
ret = BCryptSignHash(key, NULL, hash, sizeof(hash), sig, sizeof(sig), &len, 0);
3750
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
3751
3752
ret = BCryptSignHash(key, &pad, hash, sizeof(hash), sig, 0, &len, BCRYPT_PAD_PKCS1);
3753
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
3754
3755
ret = BCryptSignHash(key, &pad, hash, sizeof(hash), sig, sizeof(sig), &len, BCRYPT_PAD_PKCS1);
3756
ok(!ret, "got %#lx\n", ret);
3757
ok(len == 64, "got %lu\n", len);
3758
3759
ret = BCryptVerifySignature(key, &pad, hash, sizeof(hash), sig, len, BCRYPT_PAD_PKCS1);
3760
ok(!ret, "got %#lx\n", ret);
3761
3762
ret = BCryptDestroyKey(key);
3763
ok(!ret, "got %#lx\n", ret);
3764
3765
ret = BCryptCloseAlgorithmProvider(alg, 0);
3766
ok(!ret, "got %#lx\n", ret);
3767
3768
/* ECDSA */
3769
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_ECDSA_P256_ALGORITHM, NULL, 0);
3770
ok(!ret, "got %#lx\n", ret);
3771
3772
ret = BCryptGenerateKeyPair(alg, &key, 256, 0);
3773
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3774
3775
ret = BCryptFinalizeKeyPair(key, 0);
3776
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3777
3778
memset(sig, 0, sizeof(sig));
3779
len = 0;
3780
3781
/* automatically detects padding info */
3782
ret = BCryptSignHash(key, NULL, hash, sizeof(hash), sig, sizeof(sig), &len, 0);
3783
ok (!ret, "got %#lx\n", ret);
3784
ok (len == 64, "got %lu\n", len);
3785
3786
ret = BCryptVerifySignature(key, NULL, hash, sizeof(hash), sig, len, 0);
3787
ok(!ret, "got %#lx\n", ret);
3788
3789
/* mismatch info (SHA-1 != SHA-256) */
3790
ret = BCryptSignHash(key, &pad, hash_sha256, sizeof(hash_sha256), sig, sizeof(sig), &len, BCRYPT_PAD_PKCS1);
3791
ok (ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
3792
3793
ret = BCryptDestroyKey(key);
3794
ok(!ret, "got %#lx\n", ret);
3795
3796
ret = BCryptCloseAlgorithmProvider(alg, 0);
3797
ok(!ret, "got %#lx\n", ret);
3798
3799
/* ECDSA P521 */
3800
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_ECDSA_P521_ALGORITHM, NULL, 0);
3801
ok(!ret, "got %#lx\n", ret);
3802
3803
ret = BCryptGenerateKeyPair(alg, &key, 256, 0);
3804
todo_wine ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
3805
ret = BCryptGenerateKeyPair(alg, &key, 522, 0);
3806
todo_wine ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
3807
3808
ret = BCryptGenerateKeyPair(alg, &key, 521, 0);
3809
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3810
ret = BCryptFinalizeKeyPair(key, 0);
3811
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3812
len = 0;
3813
ret = BCryptSignHash(key, NULL, hash, sizeof(hash), sig, sizeof(sig), &len, 0);
3814
ok (!ret, "got %#lx\n", ret);
3815
ok (len == 132, "got %lu\n", len);
3816
3817
ret = BCryptVerifySignature(key, NULL, hash, sizeof(hash), sig, len, 0);
3818
ok(!ret, "got %#lx\n", ret);
3819
3820
ret = BCryptDestroyKey(key);
3821
ok(!ret, "got %#lx\n", ret);
3822
ret = BCryptCloseAlgorithmProvider(alg, 0);
3823
ok(!ret, "got %#lx\n", ret);
3824
}
3825
3826
static void test_BCryptEnumAlgorithms(void)
3827
{
3828
BCRYPT_ALGORITHM_IDENTIFIER *list;
3829
NTSTATUS ret;
3830
ULONG count, op;
3831
3832
ret = BCryptEnumAlgorithms(0, NULL, NULL, 0);
3833
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
3834
3835
ret = BCryptEnumAlgorithms(0, &count, NULL, 0);
3836
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
3837
3838
ret = BCryptEnumAlgorithms(0, NULL, &list, 0);
3839
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
3840
3841
ret = BCryptEnumAlgorithms(~0u, &count, &list, 0);
3842
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
3843
3844
count = 0;
3845
list = NULL;
3846
ret = BCryptEnumAlgorithms(0, &count, &list, 0);
3847
ok(!ret, "got %#lx\n", ret);
3848
ok(list != NULL, "NULL list\n");
3849
ok(count, "got %lu\n", count);
3850
BCryptFreeBuffer( list );
3851
3852
op = BCRYPT_CIPHER_OPERATION | BCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION | BCRYPT_SIGNATURE_OPERATION |
3853
BCRYPT_SECRET_AGREEMENT_OPERATION;
3854
count = 0;
3855
list = NULL;
3856
ret = BCryptEnumAlgorithms(op, &count, &list, 0);
3857
ok(!ret, "got %#lx\n", ret);
3858
ok(list != NULL, "NULL list\n");
3859
ok(count, "got %lu\n", count);
3860
BCryptFreeBuffer( list );
3861
}
3862
3863
static void test_aes_vector(void)
3864
{
3865
static const UCHAR secret[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10};
3866
static const UCHAR expect[] = {0xb0,0xcb,0xf5,0x80,0xd4,0xe3,0x55,0x23,0x6e,0x19,0x5b,0xdb,0xfe,0xe0,0x6c,0xd3};
3867
static const UCHAR expect2[] = {0x06,0x0c,0x81,0xab,0xd4,0x28,0x80,0x42,0xce,0x30,0x56,0x17,0x15,0x00,0x9e,0xc1};
3868
static const UCHAR expect3[] = {0x3e,0x99,0xbf,0x02,0xf5,0xd3,0xb8,0x81,0x91,0x4d,0x93,0xea,0xd4,0x92,0x93,0x46};
3869
static UCHAR iv[16], input[] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'};
3870
UCHAR output[16];
3871
BCRYPT_ALG_HANDLE alg;
3872
BCRYPT_KEY_HANDLE key;
3873
UCHAR data[sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + sizeof(secret)];
3874
BCRYPT_KEY_DATA_BLOB_HEADER *blob = (BCRYPT_KEY_DATA_BLOB_HEADER *)data;
3875
ULONG size;
3876
NTSTATUS ret;
3877
3878
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_AES_ALGORITHM, NULL, 0);
3879
ok(!ret, "got %#lx\n", ret);
3880
3881
size = sizeof(BCRYPT_CHAIN_MODE_CBC);
3882
ret = BCryptSetProperty(alg, BCRYPT_CHAINING_MODE, (UCHAR *)BCRYPT_CHAIN_MODE_CBC, size, 0);
3883
ok(!ret, "got %#lx\n", ret);
3884
3885
blob->dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC;
3886
blob->dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1;
3887
blob->cbKeyData = sizeof(secret);
3888
memcpy(data + sizeof(*blob), secret, sizeof(secret));
3889
size = sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + sizeof(secret);
3890
ret = BCryptImportKey(alg, NULL, BCRYPT_KEY_DATA_BLOB, &key, NULL, 0, data, size, 0);
3891
ok(!ret, "got %#lx\n", ret);
3892
3893
/* zero initialization vector */
3894
size = 0;
3895
memset(output, 0, sizeof(output));
3896
ret = BCryptEncrypt(key, input, sizeof(input), NULL, iv, sizeof(iv), output, sizeof(output), &size, 0);
3897
ok(!ret, "got %#lx\n", ret);
3898
ok(size == 16, "got %lu\n", size);
3899
ok(!memcmp(output, expect, sizeof(expect)), "wrong cipher text\n");
3900
3901
/* same initialization vector */
3902
size = 0;
3903
memset(output, 0, sizeof(output));
3904
ret = BCryptEncrypt(key, input, sizeof(input), NULL, iv, sizeof(iv), output, sizeof(output), &size, 0);
3905
ok(!ret, "got %#lx\n", ret);
3906
ok(size == 16, "got %lu\n", size);
3907
ok(!memcmp(output, expect2, sizeof(expect2)), "wrong cipher text\n");
3908
3909
/* different initialization vector */
3910
iv[0] = 0x1;
3911
size = 0;
3912
memset(output, 0, sizeof(output));
3913
ret = BCryptEncrypt(key, input, sizeof(input), NULL, iv, sizeof(iv), output, sizeof(output), &size, 0);
3914
ok(!ret, "got %#lx\n", ret);
3915
ok(size == 16, "got %lu\n", size);
3916
ok(!memcmp(output, expect3, sizeof(expect3)), "wrong cipher text\n");
3917
3918
ret = BCryptDestroyKey(key);
3919
ok(!ret, "got %#lx\n", ret);
3920
3921
ret = BCryptCloseAlgorithmProvider(alg, 0);
3922
ok(!ret, "got %#lx\n", ret);
3923
}
3924
3925
static void test_BcryptDeriveKeyCapi(void)
3926
{
3927
static const UCHAR expect[] =
3928
{0xda,0x39,0xa3,0xee,0x5e,0x6b,0x4b,0x0d,0x32,0x55,0xbf,0xef,0x95,0x60,0x18,0x90,0xaf,0xd8,0x07,0x09};
3929
static const UCHAR expect2[] =
3930
{0x9b,0x03,0x17,0x41,0xf4,0x75,0x11,0xac,0xff,0x22,0xee,0x40,0xbb,0xe8,0xf9,0x74,0x17,0x26,0xb6,0xf2,
3931
0xf8,0xc7,0x88,0x02,0x9a,0xdc,0x0d,0xd7,0x83,0x58,0xea,0x65,0x2e,0x8b,0x85,0xc6,0xdb,0xb7,0xed,0x1c};
3932
BCRYPT_ALG_HANDLE alg;
3933
BCRYPT_HASH_HANDLE hash;
3934
UCHAR key[40];
3935
NTSTATUS ret;
3936
3937
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA1_ALGORITHM, NULL, 0);
3938
ok(!ret, "got %#lx\n", ret);
3939
3940
ret = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0);
3941
ok(!ret, "got %#lx\n", ret);
3942
3943
ret = BCryptDeriveKeyCapi(NULL, NULL, NULL, 0, 0);
3944
ok(ret == STATUS_INVALID_PARAMETER || ret == STATUS_INVALID_HANDLE /* win7 */, "got %#lx\n", ret);
3945
3946
ret = BCryptDeriveKeyCapi(hash, NULL, NULL, 0, 0);
3947
ok(ret == STATUS_INVALID_PARAMETER || !ret /* win7 */, "got %#lx\n", ret);
3948
3949
ret = BCryptDestroyHash(hash);
3950
ok(!ret, "got %#lx\n", ret);
3951
3952
ret = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0);
3953
ok(!ret, "got %#lx\n", ret);
3954
3955
ret = BCryptDeriveKeyCapi(hash, NULL, key, 0, 0);
3956
ok(ret == STATUS_INVALID_PARAMETER || !ret /* win7 */, "got %#lx\n", ret);
3957
3958
ret = BCryptDestroyHash(hash);
3959
ok(!ret, "got %#lx\n", ret);
3960
3961
ret = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0);
3962
ok(!ret, "got %#lx\n", ret);
3963
3964
memset(key, 0, sizeof(key));
3965
ret = BCryptDeriveKeyCapi(hash, NULL, key, 41, 0);
3966
ok(ret == STATUS_INVALID_PARAMETER || !ret /* win7 */, "got %#lx\n", ret);
3967
if (!ret)
3968
ok(!memcmp(key, expect, sizeof(expect) - 1), "wrong key data\n");
3969
3970
ret = BCryptDestroyHash(hash);
3971
ok(!ret, "got %#lx\n", ret);
3972
3973
ret = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0);
3974
ok(!ret, "got %#lx\n", ret);
3975
3976
memset(key, 0, sizeof(key));
3977
ret = BCryptDeriveKeyCapi(hash, NULL, key, 20, 0);
3978
ok(!ret, "got %#lx\n", ret);
3979
ok(!memcmp(key, expect, sizeof(expect) - 1), "wrong key data\n");
3980
3981
ret = BCryptDeriveKeyCapi(hash, NULL, key, 20, 0);
3982
todo_wine ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret);
3983
3984
ret = BCryptHashData(hash, NULL, 0, 0);
3985
todo_wine ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret);
3986
3987
ret = BCryptDestroyHash(hash);
3988
ok(!ret, "got %#lx\n", ret);
3989
3990
ret = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0);
3991
ok(!ret, "got %#lx\n", ret);
3992
3993
ret = BCryptHashData(hash, (UCHAR *)"test", 4, 0);
3994
ok(!ret, "got %#lx\n", ret);
3995
3996
/* padding */
3997
memset(key, 0, sizeof(key));
3998
ret = BCryptDeriveKeyCapi(hash, NULL, key, 40, 0);
3999
ok(!ret, "got %#lx\n", ret);
4000
ok(!memcmp(key, expect2, sizeof(expect2) - 1), "wrong key data\n");
4001
4002
ret = BCryptCloseAlgorithmProvider(alg, 0);
4003
ok(!ret, "got %#lx\n", ret);
4004
}
4005
4006
static UCHAR dsaHash[] =
4007
{
4008
0x7e,0xe3,0x74,0xe7,0xc5,0x0b,0x6b,0x70,0xdb,0xab,0x32,0x6d,0x1d,0x51,0xd6,0x74,0x79,0x8e,0x5b,0x4b
4009
};
4010
4011
static UCHAR dsaSignature[] =
4012
{
4013
0x5f,0x95,0x1f,0x08,0x19,0x44,0xa5,0xab,0x28,0x11,0x51,0x68,0x82,0x9b,0xe4,0xc3,0x04,0x1b,0xc9,0xdc,
4014
0x41,0x2a,0x89,0xd4,0x4a,0x8b,0x86,0xaf,0x98,0x2c,0x59,0x0b,0xd2,0x88,0xf6,0xe8,0x29,0x13,0x84,0x49
4015
};
4016
4017
static UCHAR dsaPublicBlob[] =
4018
{
4019
0x44,0x53,0x50,0x42,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x8f,0xd2,0x92,0xbb,0x92,0xb9,0x00,0xc5,0xed,
4020
0x52,0xcc,0x48,0x4a,0x44,0x1d,0xd3,0x74,0xfb,0x75,0xd1,0x7e,0xb6,0x24,0x9b,0x5d,0x57,0x0a,0x8a,0xc4,
4021
0x5d,0xab,0x9c,0x26,0x86,0xc6,0x25,0x16,0x20,0xf9,0xa9,0x71,0xbc,0x1d,0x30,0xc4,0xef,0x8c,0xc4,0xdf,
4022
0x1a,0xaf,0x96,0xdf,0x90,0xd8,0x85,0x9d,0xf9,0x2c,0x86,0x8c,0x91,0x39,0x6c,0x6d,0x11,0x4e,0x53,0x63,
4023
0x2a,0x2b,0x26,0xa7,0xf9,0x76,0x74,0x51,0xbf,0x08,0x87,0x6f,0xe0,0x71,0x91,0x24,0x8a,0xc2,0x84,0x2d,
4024
0x84,0x9c,0x5f,0x94,0xaa,0x38,0x53,0x77,0x84,0xba,0xbc,0xff,0x49,0x3a,0x08,0x0f,0x38,0xb5,0x91,0x5c,
4025
0x06,0x15,0xa4,0x27,0xf4,0xa5,0x59,0xaa,0x1c,0x41,0xa3,0xa0,0xbb,0xf7,0x32,0x86,0xfb,0x94,0x41,0xff,
4026
0xcd,0xed,0x69,0xeb,0xc6,0x5e,0xb6,0xa8,0x15,0x82,0x3b,0x60,0x1e,0x91,0x55,0xd5,0x2c,0xa5,0x74,0x5a,
4027
0x65,0x8f,0xc6,0x56,0xc4,0x3f,0x4e,0xe3,0x3a,0x71,0xb2,0x63,0x66,0xa4,0x0d,0x0d,0xf9,0xdd,0x1e,0x48,
4028
0x81,0xe9,0xbf,0x8f,0xbb,0x85,0x47,0x81,0x68,0x11,0xb5,0x91,0x6b,0xc4,0x05,0xef,0xa3,0xc7,0xbf,0x26,
4029
0x53,0x4f,0xc4,0x10,0xfd,0xfa,0xed,0x61,0x64,0xd6,0x2e,0xad,0x04,0x3e,0x82,0xed,0xb2,0x22,0x76,0xd0,
4030
0x44,0xad,0xc1,0x4c,0xde,0x33,0xa3,0x61,0x55,0xec,0x24,0xe5,0x79,0x45,0xcf,0x94,0x39,0x92,0x9f,0xd8,
4031
0x24,0xce,0x85,0xb9
4032
};
4033
4034
static UCHAR dssKey[] =
4035
{
4036
0x07,0x02,0x00,0x00,0x00,0x22,0x00,0x00,0x44,0x53,0x53,0x32,0x00,0x04,0x00,0x00,0x01,0xd1,0xfc,0x7a,
4037
0x70,0x53,0xb2,0x48,0x70,0x23,0x19,0x1f,0x3c,0xe1,0x26,0x14,0x7e,0x9f,0x0f,0x7f,0x33,0x5e,0x2b,0xf7,
4038
0xca,0x01,0x74,0x8c,0xb4,0xfd,0xf6,0x44,0x95,0x35,0x56,0xaa,0x4d,0x62,0x48,0xe2,0xd1,0xa2,0x7e,0x6e,
4039
0xeb,0xd6,0xcc,0x7c,0xe8,0xfd,0x21,0x9a,0xa2,0xfd,0x7a,0x9d,0x1a,0x38,0x69,0x87,0x39,0x5a,0x91,0xc0,
4040
0x52,0x2b,0x9f,0x2a,0x54,0x78,0x37,0x82,0x9a,0x70,0x57,0xab,0xec,0x93,0x8e,0xac,0x73,0x04,0xe8,0x53,
4041
0x72,0x72,0x32,0xc6,0xcb,0xef,0x47,0x98,0x3c,0x56,0x49,0x62,0xcb,0xbb,0xe7,0x34,0x84,0xa6,0x72,0x3a,
4042
0xbe,0x26,0x46,0x86,0xca,0xcb,0x35,0x62,0x4f,0x19,0x18,0x0b,0xb0,0x78,0xae,0xd5,0x42,0xdf,0x26,0xdb,
4043
0x85,0x63,0x77,0x85,0x01,0x3b,0x32,0xbe,0x5c,0xf8,0x05,0xc8,0xde,0x17,0x7f,0xb9,0x03,0x82,0xfa,0xf1,
4044
0x9e,0x32,0x73,0xfa,0x8d,0xea,0xa3,0x30,0x48,0xe2,0xdf,0x5a,0xcb,0x83,0x3d,0xff,0x56,0xe9,0xc0,0x94,
4045
0xf8,0x6d,0xb3,0xaf,0x4a,0x97,0xb9,0x43,0x0e,0xd4,0x28,0x98,0x57,0x2e,0x3a,0xca,0xde,0x6f,0x45,0x0d,
4046
0xfb,0x58,0xec,0x78,0x34,0x2e,0x46,0x4d,0xfe,0x98,0x02,0xbb,0xef,0x07,0x1a,0x13,0xb6,0xc2,0x2c,0x06,
4047
0xd9,0x0c,0xc4,0xb0,0x4c,0x3a,0xfc,0x01,0x63,0xb5,0x5a,0x5d,0x2d,0x9c,0x47,0x04,0x67,0x51,0xf2,0x52,
4048
0xf5,0x82,0x36,0xeb,0x6e,0x66,0x58,0x4c,0x10,0x2c,0x29,0x72,0x4a,0x6f,0x6b,0x6c,0xe0,0x93,0x31,0x42,
4049
0xf6,0xda,0xfa,0x5b,0x22,0x43,0x9b,0x1a,0x98,0x71,0xe7,0x41,0x74,0xe9,0x12,0xa4,0x1f,0x27,0x0a,0x63,
4050
0x94,0x49,0xd7,0xad,0xa5,0xc4,0x5c,0xc3,0xc9,0x70,0xb3,0x7b,0x16,0xb6,0x1d,0xd4,0x09,0xc4,0x9a,0x46,
4051
0x2d,0x0e,0x75,0x07,0x31,0x7b,0xed,0x45,0xcd,0x99,0x84,0x14,0xf1,0x01,0x00,0x00,0x93,0xd5,0xa3,0xe4,
4052
0x34,0x05,0xeb,0x98,0x3b,0x5f,0x2f,0x11,0xa4,0xa5,0xc4,0xff,0xfb,0x22,0x7c,0x54
4053
};
4054
4055
static void test_DSA(void)
4056
{
4057
BCRYPT_ALG_HANDLE alg;
4058
BCRYPT_KEY_HANDLE key;
4059
BCRYPT_DSA_KEY_BLOB *dsablob;
4060
UCHAR sig[40], schemes;
4061
ULONG len, size;
4062
NTSTATUS ret;
4063
BYTE *buf, buf2[sizeof(BCRYPT_DSA_KEY_BLOB) + sizeof(dsaPublicBlob)];
4064
4065
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_DSA_ALGORITHM, NULL, 0);
4066
ok(!ret, "got %#lx\n", ret);
4067
4068
ret = BCryptGetProperty(alg, L"PaddingSchemes", (UCHAR *)&schemes, sizeof(schemes), &size, 0);
4069
ok(ret == STATUS_NOT_SUPPORTED, "got %#lx\n", ret);
4070
4071
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_PUBLIC_KEY_BLOB, &key, dsaPublicBlob, sizeof(dsaPublicBlob), 0);
4072
ok(!ret, "got %#lx\n", ret);
4073
BCryptDestroyKey(key);
4074
4075
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_DSA_PUBLIC_BLOB, &key, dsaPublicBlob, sizeof(dsaPublicBlob), 0);
4076
ok(!ret, "got %#lx\n", ret);
4077
4078
memset(buf2, 0xcc, sizeof(buf2));
4079
ret = BCryptExportKey(key, NULL, BCRYPT_DSA_PUBLIC_BLOB, buf2, sizeof(buf2), &size, 0);
4080
ok(!ret, "got %#lx\n", ret);
4081
dsablob = (BCRYPT_DSA_KEY_BLOB *)buf2;
4082
ok(dsablob->dwMagic == BCRYPT_DSA_PUBLIC_MAGIC, "got %#lx\n", dsablob->dwMagic);
4083
ok(dsablob->cbKey == 64, "got %lu\n", dsablob->cbKey);
4084
ok(size == sizeof(*dsablob) + dsablob->cbKey * 3, "got %lu\n", size);
4085
4086
ret = BCryptExportKey(key, NULL, BCRYPT_DSA_PRIVATE_BLOB, buf2, sizeof(buf2), &size, 0);
4087
todo_wine ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
4088
4089
ret = BCryptVerifySignature(key, NULL, dsaHash, sizeof(dsaHash), dsaSignature, sizeof(dsaSignature), 0);
4090
ok(!ret, "got %#lx\n", ret);
4091
4092
ret = BCryptDestroyKey(key);
4093
ok(!ret, "got %#lx\n", ret);
4094
4095
/* sign/verify with export/import round-trip */
4096
ret = BCryptGenerateKeyPair(alg, &key, 512, 0);
4097
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
4098
4099
ret = BCryptFinalizeKeyPair(key, 0);
4100
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
4101
4102
len = 0;
4103
memset(sig, 0, sizeof(sig));
4104
ret = BCryptSignHash(key, NULL, dsaHash, sizeof(dsaHash), sig, sizeof(sig), &len, 0);
4105
ok(!ret, "got %#lx\n", ret);
4106
ok(len == 40, "got %lu\n", len);
4107
4108
size = 0;
4109
ret = BCryptExportKey(key, NULL, BCRYPT_DSA_PUBLIC_BLOB, NULL, 0, &size, 0);
4110
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
4111
ok(size, "size not set\n");
4112
4113
buf = calloc(1, size);
4114
ret = BCryptExportKey(key, NULL, BCRYPT_DSA_PUBLIC_BLOB, buf, size, &size, 0);
4115
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
4116
dsablob = (BCRYPT_DSA_KEY_BLOB *)buf;
4117
ok(dsablob->dwMagic == BCRYPT_DSA_PUBLIC_MAGIC, "got %#lx\n", dsablob->dwMagic);
4118
ok(dsablob->cbKey == 64, "got %lu\n", dsablob->cbKey);
4119
ok(size == sizeof(*dsablob) + dsablob->cbKey * 3, "got %lu\n", size);
4120
4121
ret = BCryptDestroyKey(key);
4122
ok(!ret, "got %#lx\n", ret);
4123
4124
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_DSA_PUBLIC_BLOB, &key, buf, size, 0);
4125
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
4126
free(buf);
4127
4128
ret = BCryptVerifySignature(key, NULL, dsaHash, sizeof(dsaHash), sig, len, 0);
4129
ok(!ret, "got %#lx\n", ret);
4130
ret = BCryptDestroyKey(key);
4131
ok(!ret, "got %#lx\n", ret);
4132
4133
ret = BCryptImportKeyPair(alg, NULL, LEGACY_DSA_V2_PRIVATE_BLOB, &key, dssKey, sizeof(dssKey), 0);
4134
ok(!ret, "got %#lx\n", ret);
4135
4136
size = 0;
4137
ret = BCryptExportKey(key, NULL, LEGACY_DSA_V2_PRIVATE_BLOB, NULL, 0, &size, 0);
4138
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
4139
ok(size, "size not set\n");
4140
4141
buf = calloc(1, size);
4142
ret = BCryptExportKey(key, NULL, LEGACY_DSA_V2_PRIVATE_BLOB, buf, size, &size, 0);
4143
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
4144
ok(size == sizeof(dssKey), "got %lu expected %Iu\n", size, sizeof(dssKey));
4145
ok(!memcmp(dssKey, buf, size), "wrong data\n");
4146
free(buf);
4147
4148
ret = BCryptDestroyKey(key);
4149
ok(!ret, "got %#lx\n", ret);
4150
4151
ret = BCryptCloseAlgorithmProvider(alg, 0);
4152
ok(!ret, "got %#lx\n", ret);
4153
}
4154
4155
static void test_SecretAgreement(void)
4156
{
4157
static BCryptBuffer hash_param_buffers[] =
4158
{
4159
{
4160
sizeof(BCRYPT_SHA256_ALGORITHM),
4161
KDF_HASH_ALGORITHM,
4162
(void *)BCRYPT_SHA256_ALGORITHM,
4163
}
4164
};
4165
static BCryptBufferDesc hash_params =
4166
{
4167
BCRYPTBUFFER_VERSION,
4168
ARRAY_SIZE(hash_param_buffers),
4169
hash_param_buffers,
4170
};
4171
4172
static const ULONG dh_private_key[] =
4173
{
4174
0xc4caf69c, 0x57b4db27, 0x36f7135f, 0x5ccba686, 0xc37b8819, 0x1d35c9b2, 0xbb07a1cf, 0x0c5d1c1b,
4175
0xc79acb10, 0x31dfdabb, 0x702e02b9, 0x1efab345, 0x262a8074, 0x5edf7698, 0x9b9dc630, 0x13c34b93,
4176
0xacbc928b, 0xb79eed8c, 0x7413dce9, 0xa5521280, 0x88d8e695, 0xa310269f, 0xca7c5719, 0xcd0c775b,
4177
0x9a6e2cf2, 0x9e235c51, 0xf49db62d, 0x28e72424, 0x4a44da5a, 0x3d98268d, 0x8e4d2be3, 0x254e44e6,
4178
4179
0x18a67e55, 0x572e13a1, 0x46f81ca8, 0xc331c9b9, 0xf8fe3dd4, 0x8a889e5a, 0x6c0505fd, 0xbd97a121,
4180
0xed2dbd67, 0xf39efa8e, 0x36f9c287, 0xf6bbfa6c, 0x461e42ad, 0x17dc170e, 0xc002dc2e, 0x4813d9a4,
4181
0x0b6fabb8, 0x6a9e1860, 0xa8a8cbd9, 0xb7ed6b5d, 0xabb34d23, 0xf2fbe1fd, 0x8670df1e, 0xba7fa4e6,
4182
0xf7039712, 0x94448f30, 0xe10c812e, 0x3e311976, 0xcfdd72c4, 0xbdbea98f, 0xc9a540d6, 0x89646d57,
4183
4184
0x7ab63b33, 0x03a1e9b6, 0x947f7a9b, 0x5ae59eeb, 0x1d12eb05, 0x3f425d92, 0xe028c6ba, 0xbf90ddc9,
4185
0xb554f55a, 0x7aeb88b6, 0x4a443a5f, 0xbab35111, 0x82c78a0c, 0x298dd482, 0x02937cb1, 0xc94cdc2e,
4186
0x59b010eb, 0x3bbc0a2b, 0xd845fee0, 0x04c1d0db, 0x0c8c9424, 0x1cafd4b2, 0x9aa7aed9, 0x6a478486,
4187
0xa8841fd7, 0xbfeff40a, 0x8fd7bcc5, 0x3bb28977, 0x2b9a7955, 0xa55cd2e4, 0x1b6ad657, 0x067cdf21,
4188
4189
0x06f36920, 0x63280e1b, 0xf17d930f, 0xa06e74a8, 0x463b3a6f, 0x2a464507, 0x93f8a982, 0x8f620a7d,
4190
0xeda32d11, 0x9706a6d4, 0x33dce588, 0x75a1c446, 0x048ab567, 0xd735aafa, 0x806f7c1c, 0xdcb9651a,
4191
0x26acf3b4, 0x45f91cc9, 0x2a0de6fc, 0xf3c03d0c, 0xf5aee0aa, 0x3eeaaf36, 0x18ccee61, 0x83faa783,
4192
0x4b2b5250, 0xf4ccea22, 0x5ac0714b, 0x3f0b2bc6, 0x481b13ce, 0x12040ea7, 0x66e0bbed, 0x158e1a67,
4193
};
4194
static const ULONG dh_private_key2[] =
4195
{
4196
0xffffffff, 0xffffffff, 0xa2da0fc9, 0x34c26821, 0x8b62c6c4, 0xd11cdc80, 0x084e0229, 0x74cc678a,
4197
0xa6be0b02, 0x229b133b, 0x79084a51, 0xdd04348e, 0xb31995ef, 0x1b433acd, 0x6d0a2b30, 0x37145ff2,
4198
0x6d35e14f, 0x45c2516d, 0x76b585e4, 0xc67e5e62, 0xe9424cf4, 0x6bed37a6, 0xb65cff0b, 0xedb706f4,
4199
0xfb6b38ee, 0xa59f895a, 0x11249fae, 0xe61f4b7c, 0x51662849, 0x8153e6ec, 0xffffffff, 0xffffffff,
4200
4201
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4202
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4203
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4204
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x02000000,
4205
4206
0xa0c3c734, 0xc130c92d, 0x5265abf8, 0xff409f17, 0xbcdce187, 0xff64dae3, 0x170560aa, 0xb2423ed8,
4207
0x9ee5a8b9, 0x92548030, 0x02bba1f9, 0x823e39a4, 0x69c438f5, 0xf91016ac, 0x89bfd166, 0x7f996446,
4208
0x86224203, 0x15bf689c, 0x619354a4, 0x0c1d3a1f, 0x11bcf3d2, 0x58aae029, 0x41c69824, 0x3fafc179,
4209
0xa742747c, 0x60658c7a, 0xd3b0bde4, 0x78d3f08b, 0x6cefa061, 0x33752536, 0xe84d4901, 0x48cd73f4,
4210
4211
0x8d449700, 0x1f95120e, 0xceb31745, 0x3663177b, 0xbd9bb2d5, 0x9c23c0d9, 0x814d34f8, 0xbc54edb0,
4212
0xb874659a, 0x3bac8a30, 0xa1f3dd46, 0x1705c900, 0xbc46fefe, 0x7d13875b, 0x3064351a, 0x4bd89a1c,
4213
0x9e938761, 0x931949db, 0x34490719, 0x84fb08ca, 0xa9dd355a, 0x5b3f5061, 0x2ac96663, 0xc594429e,
4214
0xbe58395d, 0x2f7d872a, 0x303d37b3, 0xa3a9b606, 0x735a6732, 0xa095bd95, 0x3d55a7c3, 0x00e54635,
4215
};
4216
static const ULONG dh_peer_key[] =
4217
{
4218
0xffffffff, 0xffffffff, 0xa2da0fc9, 0x34c26821, 0x8b62c6c4, 0xd11cdc80, 0x084e0229, 0x74cc678a,
4219
0xa6be0b02, 0x229b133b, 0x79084a51, 0xdd04348e, 0xb31995ef, 0x1b433acd, 0x6d0a2b30, 0x37145ff2,
4220
0x6d35e14f, 0x45c2516d, 0x76b585e4, 0xc67e5e62, 0xe9424cf4, 0x6bed37a6, 0xb65cff0b, 0xedb706f4,
4221
0xfb6b38ee, 0xa59f895a, 0x11249fae, 0xe61f4b7c, 0x51662849, 0x8153e6ec, 0xffffffff, 0xffffffff,
4222
4223
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4224
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4225
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4226
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x02000000,
4227
4228
0x3bf7404b, 0x6284fffe, 0x97c0d565, 0xd830c658, 0xcc21bf39, 0xcae45bb6, 0x019df7df, 0xbf4cd293,
4229
0x6bf1989d, 0x78a81f52, 0xa4ed861c, 0x6bacf493, 0xa3e700d1, 0xd06cc206, 0x411b9727, 0x01e9c9ab,
4230
0x9b7e6efa, 0xf46bb25d, 0xd1027242, 0x6130787c, 0xa7b87d8b, 0xfee41492, 0x50db6213, 0x321199b6,
4231
0x7dace53a, 0xe8b1ec51, 0x2181b113, 0x3b33e3c0, 0x5b3a2d67, 0xbd34f0c1, 0x7037c542, 0x4a8d5540,
4232
};
4233
static const ULONG dh_shared_secret_raw[] =
4234
{
4235
0x375d89b5, 0x35a9c270, 0xfbc5ba82, 0x09eb3069, 0xd50965b0, 0xace510f7, 0x981e8731, 0x80a76115,
4236
0xf386d348, 0xca17b8df, 0x0b0e84ec, 0xf81f756e, 0x5030fa20, 0x03113b71, 0x97b7e879, 0x899b5fae,
4237
0xe6913299, 0x09270076, 0x39bc813a, 0xde3ef070, 0x65ad5b3a, 0x2b7c4ba4, 0x86c98ef9, 0x3236feaf,
4238
0x3e0253f7, 0x0489d2dd, 0x97669a3d, 0x50242fca, 0x5d4aecb1, 0xcf2d805f, 0x2258afff, 0x750e92cd,
4239
};
4240
static const ULONG dh_shared_secret_raw2[] =
4241
{
4242
0x0815f37d, 0x19ee74ab, 0x9f63f123, 0xe1b3f10c, 0xbcc9be83, 0xaddf5b9d, 0x28174e72, 0xf8a33825,
4243
0xfc74e47d, 0x2c950888, 0xf5b776d9, 0xfc712fef, 0x5b213b32, 0x489a9829, 0xfc0a4d1d, 0x6e641d3b,
4244
0x3bb2ff57, 0x63500318, 0x081ee54f, 0xf33a2805, 0xb3759e98, 0xa9a64afe, 0x964b8897, 0x04691bbc,
4245
0x80f4aae1, 0x617405ee, 0xab71724d, 0x6c10c214, 0x6f60b96f, 0xdc777b0b, 0x22f40d4f, 0x8a1c4eb5,
4246
};
4247
static const ULONG dh_shared_secret_sha1[] =
4248
{
4249
0x0babba9c, 0x0bdeacbd, 0x04e36574, 0xdd504dcd, 0x0cd88db0,
4250
};
4251
static const ULONG dh_shared_secret_sha256[] =
4252
{
4253
0x3213db5b, 0x8cc8250b, 0xc829eaab, 0x00933709, 0x68160aa9, 0xfb9f1e20, 0xf92368e6, 0x2b8e18eb,
4254
};
4255
static const struct
4256
{
4257
const WCHAR *alg;
4258
ULONG bitlen;
4259
}
4260
ecdh_algorithms[] =
4261
{
4262
{ BCRYPT_ECDH_P256_ALGORITHM, 256 },
4263
{ BCRYPT_ECDH_P384_ALGORITHM, 384 },
4264
{ BCRYPT_ECDH_P521_ALGORITHM, 521 },
4265
};
4266
static const ULONG length = 1024;
4267
BCRYPT_DH_PARAMETER_HEADER *dh_header;
4268
BCRYPT_DH_KEY_BLOB *dh_key_blob;
4269
BCRYPT_SECRET_HANDLE secret, secret2;
4270
BCRYPT_ALG_HANDLE alg;
4271
BCRYPT_KEY_HANDLE key, key2;
4272
UCHAR buffer[2048];
4273
NTSTATUS status;
4274
ULONG size, i;
4275
4276
for (i = 0; i < ARRAY_SIZE(ecdh_algorithms); ++i)
4277
{
4278
winetest_push_context("%s", debugstr_w(ecdh_algorithms[i].alg));
4279
status = BCryptOpenAlgorithmProvider(&alg, ecdh_algorithms[i].alg, NULL, 0);
4280
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4281
4282
key = NULL;
4283
status = BCryptGenerateKeyPair(alg, &key, ecdh_algorithms[i].bitlen, 0);
4284
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4285
ok(key != NULL, "key not set\n");
4286
4287
status = BCryptFinalizeKeyPair(key, 0);
4288
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4289
4290
status = BCryptSecretAgreement(NULL, key, &secret, 0);
4291
ok(status == STATUS_INVALID_HANDLE, "got %#lx\n", status);
4292
4293
status = BCryptSecretAgreement(key, NULL, &secret, 0);
4294
ok(status == STATUS_INVALID_HANDLE, "got %#lx\n", status);
4295
4296
status = BCryptSecretAgreement(key, key, NULL, 0);
4297
ok(status == STATUS_INVALID_PARAMETER, "got %#lx\n", status);
4298
4299
status = BCryptSecretAgreement(key, key, &secret, 0);
4300
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4301
4302
status = BCryptDeriveKey(NULL, L"HASH", NULL, NULL, 0, &size, 0);
4303
ok(status == STATUS_INVALID_HANDLE, "got %#lx\n", status);
4304
4305
status = BCryptDeriveKey(key, L"HASH", NULL, NULL, 0, &size, 0);
4306
ok(status == STATUS_INVALID_HANDLE, "got %#lx\n", status);
4307
4308
status = BCryptDeriveKey(secret, NULL, NULL, NULL, 0, &size, 0);
4309
ok(status == STATUS_INVALID_PARAMETER, "got %#lx\n", status);
4310
4311
status = BCryptDeriveKey(secret, L"HASH", NULL, NULL, 0, &size, 0);
4312
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4313
4314
status = BCryptDestroyHash(secret);
4315
ok(status == STATUS_INVALID_PARAMETER, "got %#lx\n", status);
4316
4317
status = BCryptDestroyKey(secret);
4318
ok(status == STATUS_INVALID_HANDLE, "got %#lx\n", status);
4319
4320
status = BCryptDestroySecret(NULL);
4321
ok(status == STATUS_INVALID_HANDLE, "got %#lx\n", status);
4322
4323
status = BCryptDestroySecret(alg);
4324
ok(status == STATUS_INVALID_HANDLE, "got %#lx\n", status);
4325
4326
status = BCryptDestroySecret(secret);
4327
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4328
4329
status = BCryptDestroyKey(key);
4330
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4331
4332
status = BCryptCloseAlgorithmProvider(alg, 0);
4333
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4334
winetest_pop_context();
4335
}
4336
4337
/* DH */
4338
status = BCryptOpenAlgorithmProvider(&alg, BCRYPT_DH_ALGORITHM, NULL, 0);
4339
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4340
4341
key = NULL;
4342
status = BCryptGenerateKeyPair(alg, &key, 1024, 0);
4343
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4344
ok(key != NULL, "key not set\n");
4345
4346
status = BCryptFinalizeKeyPair(key, 0);
4347
if (status == STATUS_INVALID_PARAMETER)
4348
{
4349
win_skip("broken DH detected\n");
4350
BCryptCloseAlgorithmProvider(alg, 0);
4351
return;
4352
}
4353
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4354
4355
status = BCryptSecretAgreement(key, key, &secret, 0);
4356
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4357
4358
status = BCryptDestroyKey(key);
4359
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4360
4361
status = BCryptDeriveKey(secret, L"HASH", NULL, NULL, 0, &size, 0);
4362
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4363
4364
status = BCryptDestroySecret(secret);
4365
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4366
4367
key = NULL;
4368
status = BCryptGenerateKeyPair(alg, &key, 256, 0);
4369
ok(status == STATUS_INVALID_PARAMETER, "got %08lx\n", status);
4370
4371
status = BCryptGenerateKeyPair(alg, &key, length, 0);
4372
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4373
ok(key != NULL, "key not set\n");
4374
4375
memset(buffer, 0xcc, sizeof(buffer));
4376
status = BCryptGetProperty(key, BCRYPT_DH_PARAMETERS, buffer, sizeof(buffer), &size, 0);
4377
ok(status == STATUS_INVALID_HANDLE, "got %08lx\n", status);
4378
4379
status = BCryptExportKey(key, NULL, BCRYPT_DH_PUBLIC_BLOB, buffer, sizeof(buffer), &size, 0);
4380
ok(status == STATUS_INVALID_HANDLE, "got %08lx\n", status);
4381
4382
status = BCryptFinalizeKeyPair(key, 0);
4383
if (status != STATUS_SUCCESS)
4384
{
4385
BCryptDestroyKey(key);
4386
BCryptCloseAlgorithmProvider(alg, 0);
4387
return;
4388
}
4389
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4390
4391
status = BCryptFinalizeKeyPair(key, 0);
4392
ok(status == STATUS_INVALID_HANDLE, "got %08lx\n", status);
4393
4394
size = 0xdeadbeef;
4395
status = BCryptGetProperty(key, BCRYPT_DH_PARAMETERS, NULL, sizeof(buffer), &size, 0);
4396
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4397
ok(size == sizeof(BCRYPT_DH_PARAMETER_HEADER) + length / 8 * 2, "Got unexpected size %lu.\n", size);
4398
4399
size = 0xdeadbeef;
4400
status = BCryptGetProperty(key, BCRYPT_DH_PARAMETERS, buffer, 28, &size, 0);
4401
ok(status == STATUS_BUFFER_TOO_SMALL, "got %08lx\n", status);
4402
ok(size == sizeof(BCRYPT_DH_PARAMETER_HEADER) + length / 8 * 2, "Got unexpected size %lu.\n", size);
4403
4404
size = 0xdeadbeef;
4405
status = BCryptGetProperty(key, BCRYPT_DH_PARAMETERS, buffer, sizeof(buffer), &size, 0);
4406
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4407
ok(size == sizeof(BCRYPT_DH_PARAMETER_HEADER) + length / 8 * 2, "Got unexpected size %lu.\n", size);
4408
4409
dh_header = (BCRYPT_DH_PARAMETER_HEADER *)buffer;
4410
ok(dh_header->cbLength == sizeof(*dh_header) + length / 8 * 2, "Got unexpected length %lu.\n", dh_header->cbLength);
4411
ok(dh_header->cbKeyLength == length / 8, "Got unexpected length %lu.\n", dh_header->cbKeyLength);
4412
ok(dh_header->dwMagic == BCRYPT_DH_PARAMETERS_MAGIC, "Got unexpected magic %#lx.\n", dh_header->dwMagic);
4413
4414
status = BCryptDestroyKey(key);
4415
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4416
4417
dh_key_blob = (BCRYPT_DH_KEY_BLOB *)buffer;
4418
dh_key_blob->dwMagic = BCRYPT_DH_PRIVATE_MAGIC;
4419
dh_key_blob->cbKey = length / 8;
4420
memcpy(dh_key_blob + 1, dh_private_key, sizeof(dh_private_key));
4421
size = sizeof(buffer);
4422
status = BCryptImportKeyPair(alg, NULL, BCRYPT_DH_PRIVATE_BLOB, &key, buffer, size, 0);
4423
ok(status == STATUS_INVALID_PARAMETER, "got %08lx\n", status);
4424
size = sizeof(*dh_key_blob) + length / 8 * 4;
4425
status = BCryptImportKeyPair(alg, NULL, BCRYPT_DH_PRIVATE_BLOB, &key, buffer, size, 0);
4426
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4427
4428
memset(buffer, 0xcc, sizeof(buffer));
4429
size = 0xdeadbeef;
4430
status = BCryptExportKey(key, NULL, BCRYPT_DH_PUBLIC_BLOB, NULL, 0, &size, 0);
4431
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4432
ok(size == sizeof(BCRYPT_DH_KEY_BLOB) + length / 8 * 3, "Got unexpected size %lu.\n", size);
4433
4434
size = 0xdeadbeef;
4435
status = BCryptExportKey(key, NULL, BCRYPT_DH_PUBLIC_BLOB, buffer, sizeof(buffer), &size, 0);
4436
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4437
ok(size == sizeof(BCRYPT_DH_KEY_BLOB) + length / 8 * 3, "Got unexpected size %lu.\n", size);
4438
dh_key_blob = (BCRYPT_DH_KEY_BLOB *)buffer;
4439
ok(dh_key_blob->dwMagic == BCRYPT_DH_PUBLIC_MAGIC, "Got unexpected magic %#lx.\n", dh_key_blob->dwMagic);
4440
ok(dh_key_blob->cbKey == length / 8, "Got unexpected length %lu.\n", dh_key_blob->cbKey);
4441
ok(!memcmp(dh_key_blob + 1, dh_private_key, length / 8 * 3), "Key data does not match.\n");
4442
4443
status = BCryptGenerateKeyPair(alg, &key2, length, 0);
4444
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4445
dh_header = (BCRYPT_DH_PARAMETER_HEADER *)buffer;
4446
dh_header->dwMagic = BCRYPT_DH_PARAMETERS_MAGIC;
4447
dh_header->cbLength = sizeof(*dh_header) + length / 8 * 2;
4448
dh_header->cbKeyLength = length / 8;
4449
memcpy(dh_header + 1, dh_private_key, length / 8 * 2);
4450
status = BCryptSetProperty(key2, BCRYPT_DH_PARAMETERS, buffer, dh_header->cbLength, 0);
4451
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4452
status = BCryptFinalizeKeyPair(key2, 0);
4453
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4454
4455
status = BCryptExportKey(key2, NULL, BCRYPT_DH_PUBLIC_BLOB, buffer, sizeof(buffer), &size, 0);
4456
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4457
ok(size == sizeof(BCRYPT_DH_KEY_BLOB) + length / 8 * 3, "Got unexpected size %lu.\n", size);
4458
ok(dh_key_blob->dwMagic == BCRYPT_DH_PUBLIC_MAGIC, "Got unexpected dwMagic %#lx.\n", dh_key_blob->dwMagic);
4459
ok(dh_key_blob->cbKey == length / 8, "Got unexpected length %lu.\n", dh_key_blob->cbKey);
4460
ok(!memcmp(dh_key_blob + 1, dh_private_key, length / 8 * 2), "DH parameters do not match.\n");
4461
ok(memcmp((BYTE *)(dh_key_blob + 1) + length / 8 * 2, (BYTE *)dh_private_key + length / 8 * 2, length / 8),
4462
"Random public key data matches.\n");
4463
4464
memset(buffer, 0xcc, sizeof(buffer));
4465
status = BCryptExportKey(key, NULL, BCRYPT_DH_PRIVATE_BLOB, buffer, sizeof(buffer), &size, 0);
4466
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4467
dh_key_blob = (BCRYPT_DH_KEY_BLOB *)buffer;
4468
ok(size == sizeof(BCRYPT_DH_KEY_BLOB) + length / 8 * 4, "Got unexpected size %lu.\n", size);
4469
ok(dh_key_blob->dwMagic == BCRYPT_DH_PRIVATE_MAGIC, "Got unexpected dwMagic %#lx.\n", dh_key_blob->dwMagic);
4470
ok(dh_key_blob->cbKey == length / 8, "Got unexpected length %lu.\n", dh_key_blob->cbKey);
4471
ok(!memcmp(dh_key_blob + 1, dh_private_key, length / 8 * 4), "Private key data does not match.\n");
4472
4473
status = BCryptSecretAgreement(NULL, key, &secret, 0);
4474
ok(status == STATUS_INVALID_HANDLE, "got %08lx\n", status);
4475
4476
status = BCryptSecretAgreement(key, NULL, &secret, 0);
4477
ok(status == STATUS_INVALID_HANDLE, "got %08lx\n", status);
4478
4479
status = BCryptSecretAgreement(key, key, NULL, 0);
4480
ok(status == STATUS_INVALID_PARAMETER, "got %08lx\n", status);
4481
4482
status = BCryptSecretAgreement(key, key, &secret, 0);
4483
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4484
4485
status = BCryptDeriveKey(NULL, L"HASH", NULL, NULL, 0, &size, 0);
4486
ok(status == STATUS_INVALID_HANDLE, "got %08lx\n", status);
4487
4488
status = BCryptDeriveKey(key, L"HASH", NULL, NULL, 0, &size, 0);
4489
ok(status == STATUS_INVALID_HANDLE, "got %08lx\n", status);
4490
4491
status = BCryptDeriveKey(secret, NULL, NULL, NULL, 0, &size, 0);
4492
ok(status == STATUS_INVALID_PARAMETER, "got %08lx\n", status);
4493
4494
size = 0xdeadbeef;
4495
status = BCryptDeriveKey(secret, L"HASH", NULL, NULL, 0, &size, 0);
4496
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4497
ok(size == 20, "Got unexpected size %lu.\n", size);
4498
4499
size = 0xdeadbeef;
4500
status = BCryptDeriveKey(secret, BCRYPT_KDF_RAW_SECRET, NULL, NULL, 0, &size, 0);
4501
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4502
ok(size == length / 8, "Got unexpected size %lu.\n", size);
4503
4504
status = BCryptDeriveKey(secret, BCRYPT_KDF_RAW_SECRET, NULL, buffer, 128, &size, 0);
4505
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4506
ok(size == length / 8, "Got unexpected size %lu.\n", size);
4507
ok(!memcmp(buffer, dh_shared_secret_raw, size), "Raw shared secret data does not match.\n");
4508
4509
size = sizeof(buffer);
4510
memset(buffer, 0xcc, sizeof(buffer));
4511
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, NULL, buffer, 128, &size, 0);
4512
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4513
ok(size == 20, "Got unexpected size %lu.\n", size);
4514
ok(!memcmp(buffer, dh_shared_secret_sha1, sizeof(dh_shared_secret_sha1)),
4515
"sha1 shared secret data does not match.\n");
4516
4517
size = sizeof(buffer);
4518
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &hash_params, buffer, size, &size, 0);
4519
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4520
ok(size == 32, "Got unexpected size %lu.\n", size);
4521
ok(!memcmp(buffer, dh_shared_secret_sha256, sizeof(dh_shared_secret_sha256)),
4522
"sha256 shared secret data does not match.\n");
4523
4524
for (i = size; i < sizeof(buffer); ++i)
4525
if (buffer[i] != 0xcc) break;
4526
ok(i == sizeof(buffer), "Buffer modified at %lu, value %#x.\n", i, buffer[i]);
4527
4528
status = BCryptDestroySecret(secret);
4529
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4530
4531
status = BCryptSecretAgreement(key, key2, &secret, 0);
4532
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4533
status = BCryptSecretAgreement(key2, key, &secret2, 0);
4534
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4535
4536
status = BCryptDeriveKey(secret, BCRYPT_KDF_RAW_SECRET, NULL, buffer, 128, &size, 0);
4537
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4538
status = BCryptDeriveKey(secret, BCRYPT_KDF_RAW_SECRET, NULL, buffer + size, 128, &size, 0);
4539
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4540
ok(!memcmp(buffer, buffer + size, size), "Shared secrets do not match.\n");
4541
4542
status = BCryptDestroySecret(secret);
4543
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4544
status = BCryptDestroySecret(secret2);
4545
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4546
4547
status = BCryptDestroyKey(key);
4548
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4549
status = BCryptDestroyKey(key2);
4550
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4551
4552
dh_key_blob = (BCRYPT_DH_KEY_BLOB *)buffer;
4553
dh_key_blob->dwMagic = BCRYPT_DH_PRIVATE_MAGIC;
4554
dh_key_blob->cbKey = length / 8;
4555
memcpy(dh_key_blob + 1, dh_private_key2, sizeof(dh_private_key2));
4556
4557
size = sizeof(*dh_key_blob) + length / 8 * 4;
4558
status = BCryptImportKeyPair(alg, NULL, BCRYPT_DH_PRIVATE_BLOB, &key, buffer, size, 0);
4559
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4560
4561
dh_key_blob = (BCRYPT_DH_KEY_BLOB *)buffer;
4562
dh_key_blob->dwMagic = BCRYPT_DH_PUBLIC_MAGIC;
4563
dh_key_blob->cbKey = length / 8;
4564
memcpy(dh_key_blob + 1, dh_peer_key, sizeof(dh_peer_key));
4565
4566
size = sizeof(*dh_key_blob) + length / 8 * 3;
4567
status = BCryptImportKeyPair(alg, NULL, BCRYPT_DH_PUBLIC_BLOB, &key2, buffer, size, 0);
4568
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4569
4570
status = BCryptSecretAgreement(key, key2, &secret, 0);
4571
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4572
4573
status = BCryptDeriveKey(secret, BCRYPT_KDF_RAW_SECRET, NULL, buffer, 128, &size, 0);
4574
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4575
ok(size == length / 8, "Got unexpected size %lu.\n", size);
4576
ok(!memcmp(buffer, dh_shared_secret_raw2, size), "Raw shared secret data does not match.\n");
4577
4578
status = BCryptDestroySecret(secret);
4579
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4580
status = BCryptDestroyKey(key);
4581
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4582
status = BCryptDestroyKey(key2);
4583
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4584
4585
status = BCryptCloseAlgorithmProvider(alg, 0);
4586
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4587
}
4588
4589
static void test_RC4(void)
4590
{
4591
BCRYPT_ALG_HANDLE alg;
4592
NTSTATUS status;
4593
ULONG len, size;
4594
4595
status = BCryptOpenAlgorithmProvider(&alg, BCRYPT_RC4_ALGORITHM, NULL, 0);
4596
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4597
4598
len = size = 0;
4599
status = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
4600
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4601
ok(len, "expected non-zero len\n");
4602
ok(size == sizeof(len), "got %lu\n", size);
4603
4604
len = size = 0;
4605
status = BCryptGetProperty(alg, BCRYPT_BLOCK_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
4606
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4607
ok(len == 1, "got %lu\n", len);
4608
ok(size == sizeof(len), "got %lu\n", size);
4609
4610
size = sizeof(BCRYPT_CHAIN_MODE_NA);
4611
status = BCryptSetProperty(alg, BCRYPT_CHAINING_MODE, (UCHAR *)BCRYPT_CHAIN_MODE_NA, size, 0);
4612
ok(!status, "got %#lx\n", status);
4613
4614
status = BCryptCloseAlgorithmProvider(alg, 0);
4615
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4616
}
4617
4618
static void test_PBKDF2(void)
4619
{
4620
static char salt[] = "cCxuHMEHLibcglJOG88dIw==";
4621
static ULONGLONG iter_count = 25;
4622
static BCryptBuffer pbkdf2_param_buffers[] =
4623
{
4624
{
4625
sizeof(BCRYPT_SHA1_ALGORITHM),
4626
KDF_HASH_ALGORITHM,
4627
(void *)BCRYPT_SHA1_ALGORITHM,
4628
},
4629
{
4630
sizeof(salt) - 1,
4631
KDF_SALT,
4632
salt,
4633
},
4634
{
4635
sizeof(iter_count),
4636
KDF_ITERATION_COUNT,
4637
(void *)&iter_count,
4638
}
4639
};
4640
static BCryptBufferDesc pbkdf2_params =
4641
{
4642
BCRYPTBUFFER_VERSION,
4643
ARRAY_SIZE(pbkdf2_param_buffers),
4644
pbkdf2_param_buffers,
4645
};
4646
static UCHAR pbkdf2_hash[] =
4647
{
4648
0x18, 0xf2, 0x58, 0x0b, 0x92, 0x6e, 0x6d, 0xfe,
4649
0x55, 0xbb, 0x62, 0x87, 0x5b, 0x1f, 0x61, 0x83,
4650
0x4d, 0x16, 0xe4, 0x04, 0xcd, 0xab, 0x43, 0x77,
4651
0x25, 0x3e, 0x1d, 0xb4, 0x95, 0x5f, 0xf7, 0x01,
4652
};
4653
4654
BCRYPT_KEY_LENGTHS_STRUCT key_lengths;
4655
BCRYPT_ALG_HANDLE alg;
4656
BCRYPT_KEY_HANDLE key;
4657
NTSTATUS status;
4658
ULONG val, size;
4659
static BYTE buf[32];
4660
4661
status = BCryptOpenAlgorithmProvider(&alg, BCRYPT_PBKDF2_ALGORITHM, NULL, 0);
4662
if (status == STATUS_NOT_FOUND)
4663
{
4664
win_skip("PBKDF2 not available\n");
4665
return;
4666
}
4667
ok(!status, "got %#lx\n", status);
4668
ok(pBCryptKeyDerivation != NULL, "BCryptKeyDerivation not available\n");
4669
4670
val = size = 0;
4671
status = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&val, sizeof(val), &size, 0);
4672
ok(!status, "got %#lx\n", status);
4673
ok(val, "got %lu\n", val);
4674
ok(size == sizeof(val), "got %lu\n", size);
4675
4676
val = size = 0;
4677
status = BCryptGetProperty(alg, BCRYPT_BLOCK_LENGTH, (UCHAR *)&val, sizeof(val), &size, 0);
4678
ok(status == STATUS_NOT_SUPPORTED, "got %#lx\n", status);
4679
4680
memset(&key_lengths, 0xfe, sizeof(key_lengths));
4681
size = 0;
4682
status = BCryptGetProperty(alg, BCRYPT_KEY_LENGTHS, (UCHAR *)&key_lengths, sizeof(key_lengths), &size, 0);
4683
ok(!status, "got %#lx\n", status);
4684
ok(size == sizeof(key_lengths), "got %lu\n", size);
4685
ok(key_lengths.dwMinLength == 0, "got %lu\n", key_lengths.dwMinLength);
4686
ok(key_lengths.dwMaxLength == 16384, "got %lu\n", key_lengths.dwMaxLength);
4687
ok(key_lengths.dwIncrement == 8, "got %lu\n", key_lengths.dwIncrement);
4688
4689
key = 0;
4690
status = BCryptGenerateSymmetricKey(alg, &key, NULL, 0, (UCHAR *)"test", 4, 0);
4691
ok(!status, "got %#lx\n", status);
4692
val = size = 0;
4693
status = BCryptGetProperty(key, BCRYPT_KEY_STRENGTH, (UCHAR *)&val, sizeof(val), &size, 0);
4694
ok(!status, "got %#lx\n", status);
4695
ok(val == strlen("test") * 8, "got %lu\n", val);
4696
4697
status = pBCryptKeyDerivation(key, &pbkdf2_params, NULL, 0, &size, 0);
4698
ok(status == STATUS_INVALID_PARAMETER, "got %#lx\n", status);
4699
4700
buf[0] = buf[1] = 'x';
4701
status = pBCryptKeyDerivation(key, &pbkdf2_params, buf, 1, &size, 0);
4702
ok(!status, "got %#lx\n", status);
4703
ok(size == 1, "size = %lu\n", size);
4704
ok(buf[0] == pbkdf2_hash[0], "buf[0] = %x\n", buf[0]);
4705
ok(buf[1] == 'x', "buf[1] = %x\n", buf[1]);
4706
4707
memset(buf, 'x', sizeof(buf));
4708
status = pBCryptKeyDerivation(key, &pbkdf2_params, buf, sizeof(buf), &size, 0);
4709
ok(!status, "got %#lx\n", status);
4710
ok(size == sizeof(buf), "size = %lu\n", size);
4711
ok(!memcmp(buf, pbkdf2_hash, sizeof(pbkdf2_hash)),
4712
"wrong data (%s)\n", wine_dbgstr_an((char *)buf, size));
4713
4714
status = BCryptDestroyKey(key);
4715
ok(!status, "got %#lx\n", status);
4716
status = BCryptCloseAlgorithmProvider(alg, 0);
4717
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4718
}
4719
4720
START_TEST(bcrypt)
4721
{
4722
HMODULE module;
4723
4724
module = LoadLibraryA("bcrypt.dll");
4725
if (!module)
4726
{
4727
win_skip("bcrypt.dll not found\n");
4728
return;
4729
}
4730
pBCryptHash = (void *)GetProcAddress(module, "BCryptHash");
4731
pBCryptKeyDerivation = (void *)GetProcAddress(module, "BCryptKeyDerivation");
4732
4733
test_BCryptGenRandom();
4734
test_BCryptGetFipsAlgorithmMode();
4735
test_hashes();
4736
test_BcryptHash();
4737
test_BcryptDeriveKeyPBKDF2();
4738
test_rng();
4739
test_3des();
4740
test_aes();
4741
test_BCryptGenerateSymmetricKey();
4742
test_BCryptEncrypt();
4743
test_BCryptDecrypt();
4744
test_key_import_export();
4745
test_ECDSA();
4746
test_RSA();
4747
test_RSA_SIGN();
4748
test_ECDH();
4749
test_DH();
4750
test_BCryptEnumContextFunctions();
4751
test_BCryptSignHash();
4752
test_BCryptEnumAlgorithms();
4753
test_aes_vector();
4754
test_BcryptDeriveKeyCapi();
4755
test_DSA();
4756
test_SecretAgreement();
4757
test_rsa_encrypt();
4758
test_RC4();
4759
test_PBKDF2();
4760
4761
FreeLibrary(module);
4762
}
4763
4764