Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/bcrypt/tests/bcrypt.c
8599 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, strength;
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
/* generic ECDSA provider */
2420
status = BCryptOpenAlgorithmProvider(&alg, BCRYPT_ECDSA_ALGORITHM, NULL, 0);
2421
if (status == STATUS_NOT_FOUND)
2422
{
2423
win_skip("generic ECDSA provider not found\n");
2424
return;
2425
}
2426
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
2427
2428
status = BCryptGenerateKeyPair(alg, &key, 0, 0);
2429
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
2430
2431
status = BCryptFinalizeKeyPair(key, 0);
2432
ok(status == STATUS_INVALID_PARAMETER, "got %#lx\n", status);
2433
BCryptDestroyKey(key);
2434
BCryptCloseAlgorithmProvider(alg, 0);
2435
2436
status = BCryptOpenAlgorithmProvider(&alg, BCRYPT_ECDSA_ALGORITHM, NULL, 0);
2437
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
2438
2439
status = BCryptSetProperty(alg, BCRYPT_ECC_CURVE_NAME, (UCHAR *)BCRYPT_ECC_CURVE_SECP256R1, sizeof(BCRYPT_ECC_CURVE_SECP256R1), 0);
2440
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
2441
2442
status = BCryptGenerateKeyPair(alg, &key, 255, 0);
2443
todo_wine ok(status == STATUS_INVALID_PARAMETER, "got %#lx\n", status);
2444
2445
status = BCryptGenerateKeyPair(alg, &key, 0, 0);
2446
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
2447
2448
strength = 0;
2449
status = BCryptGetProperty(key, BCRYPT_KEY_STRENGTH, (UCHAR *)&strength, sizeof(strength), &size, 0);
2450
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
2451
ok(strength == 256, "got %lu\n", strength);
2452
2453
status = BCryptFinalizeKeyPair(key, 0);
2454
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
2455
BCryptDestroyKey(key);
2456
BCryptCloseAlgorithmProvider(alg, 0);
2457
}
2458
2459
static UCHAR rsaPublicBlob[] =
2460
{
2461
0x52, 0x53, 0x41, 0x31, 0x00, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
2462
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0xad, 0x41, 0x09, 0xa2, 0x56,
2463
0x3a, 0x7b, 0x75, 0x4b, 0x72, 0x9b, 0x28, 0x72, 0x3b, 0xae, 0x9f, 0xd8, 0xa8, 0x25, 0x4a, 0x4c,
2464
0x19, 0xf5, 0xa6, 0xd0, 0x05, 0x1c, 0x59, 0x8f, 0xe3, 0xf3, 0x2d, 0x29, 0x47, 0xf8, 0x80, 0x25,
2465
0x25, 0x21, 0x58, 0xc2, 0xac, 0xa1, 0x9e, 0x93, 0x8e, 0x82, 0x6d, 0xd7, 0xf3, 0xe7, 0x8f, 0x0b,
2466
0xc0, 0x41, 0x85, 0x29, 0x3c, 0xf1, 0x0b, 0x2c, 0x5d, 0x49, 0xed, 0xb4, 0x30, 0x6e, 0x02, 0x15,
2467
0x4b, 0x9a, 0x08, 0x0d, 0xe1, 0x6f, 0xa8, 0xd3, 0x12, 0xab, 0x66, 0x48, 0x4d, 0xd9, 0x28, 0x03,
2468
0x6c, 0x9d, 0x44, 0x7a, 0xed, 0xc9, 0x43, 0x4f, 0x9d, 0x4e, 0x3c, 0x7d, 0x0e, 0xff, 0x07, 0x87,
2469
0xeb, 0xca, 0xca, 0x65, 0x6d, 0xbe, 0xc5, 0x31, 0x8b, 0xcc, 0x7e, 0x0a, 0x71, 0x4a, 0x4d, 0x9d,
2470
0x3d, 0xfd, 0x7a, 0x56, 0x32, 0x8a, 0x6c, 0x6d, 0x9d, 0x2a, 0xd9, 0x8e, 0x68, 0x89, 0x63, 0xc6,
2471
0x4f, 0x24, 0xd1, 0x2a, 0x72, 0x69, 0x08, 0x77, 0xa0, 0x7f, 0xfe, 0xc6, 0x33, 0x8d, 0xb4, 0x7d,
2472
0x73, 0x91, 0x13, 0x9c, 0x47, 0x53, 0x6a, 0x13, 0xdf, 0x19, 0xc7, 0xed, 0x48, 0x81, 0xed, 0xd8,
2473
0x1f, 0x11, 0x11, 0xbb, 0x41, 0x15, 0x5b, 0xa4, 0xf5, 0xc9, 0x2b, 0x48, 0x5e, 0xd8, 0x4b, 0x52,
2474
0x1f, 0xf7, 0x87, 0xf2, 0x68, 0x25, 0x28, 0x79, 0xee, 0x39, 0x41, 0xc9, 0x0e, 0xc8, 0xf9, 0xf2,
2475
0xd8, 0x24, 0x09, 0xb4, 0xd4, 0xb7, 0x90, 0xba, 0x26, 0xe8, 0x1d, 0xb4, 0xd7, 0x09, 0x00, 0xc4,
2476
0xa0, 0xb6, 0x14, 0xe8, 0x4c, 0x29, 0x60, 0x54, 0x2e, 0x01, 0xde, 0x54, 0x66, 0x40, 0x22, 0x50,
2477
0x27, 0xf1, 0xe7, 0x62, 0xa9, 0x00, 0x5a, 0x61, 0x2e, 0xfa, 0xfe, 0x16, 0xd8, 0xe0, 0xe7, 0x66,
2478
0x17, 0xda, 0xb8, 0x0c, 0xa6, 0x04, 0x8d, 0xf8, 0x21, 0x68, 0x39
2479
};
2480
2481
static UCHAR rsaHash[] =
2482
{
2483
0x96, 0x1f, 0xa6, 0x49, 0x58, 0x81, 0x8f, 0x76, 0x77, 0x07, 0x07, 0x27, 0x55, 0xd7, 0x01, 0x8d,
2484
0xcd, 0x27, 0x8e, 0x94
2485
};
2486
2487
static UCHAR rsaSignature[] =
2488
{
2489
0xa8, 0x3a, 0x9d, 0xaf, 0x92, 0x94, 0xa4, 0x4d, 0x34, 0xba, 0x41, 0x0c, 0xc1, 0x23, 0x91, 0xc7,
2490
0x91, 0xa8, 0xf8, 0xfc, 0x94, 0x87, 0x4d, 0x05, 0x85, 0x63, 0xe8, 0x7d, 0xea, 0x7f, 0x6b, 0x8d,
2491
0xbb, 0x9a, 0xd4, 0x46, 0xa6, 0xc0, 0xd6, 0xdc, 0x91, 0xba, 0xd3, 0x1a, 0xbf, 0xf4, 0x52, 0xa0,
2492
0xc7, 0x15, 0x87, 0xe9, 0x1e, 0x60, 0x49, 0x9c, 0xee, 0x5a, 0x9c, 0x6c, 0xbd, 0x7a, 0x3e, 0xc3,
2493
0x48, 0xb3, 0xee, 0xca, 0x68, 0x40, 0x9b, 0xa1, 0x4c, 0x6e, 0x20, 0xd6, 0xca, 0x6c, 0x72, 0xaf,
2494
0x2b, 0x6b, 0x62, 0x7c, 0x78, 0x06, 0x94, 0x4c, 0x02, 0xf3, 0x8d, 0x49, 0xe0, 0x11, 0xc4, 0x9b,
2495
0x62, 0x5b, 0xc2, 0xfd, 0x68, 0xf4, 0x07, 0x15, 0x71, 0x11, 0x4c, 0x35, 0x97, 0x5d, 0xc0, 0xe6,
2496
0x22, 0xc9, 0x8a, 0x7b, 0x96, 0xc9, 0xc3, 0xe4, 0x2b, 0x1e, 0x88, 0x17, 0x4f, 0x98, 0x9b, 0xf3,
2497
0x42, 0x23, 0x0c, 0xa0, 0xfa, 0x19, 0x03, 0x2a, 0xf7, 0x13, 0x2d, 0x27, 0xac, 0x9f, 0xaf, 0x2d,
2498
0xa3, 0xce, 0xf7, 0x63, 0xbb, 0x39, 0x9f, 0x72, 0x80, 0xdd, 0x6c, 0x73, 0x00, 0x85, 0x70, 0xf2,
2499
0xed, 0x50, 0xed, 0xa0, 0x74, 0x42, 0xd7, 0x22, 0x46, 0x24, 0xee, 0x67, 0xdf, 0xb5, 0x45, 0xe8,
2500
0x49, 0xf4, 0x9c, 0xe4, 0x00, 0x83, 0xf2, 0x27, 0x8e, 0xa2, 0xb1, 0xc3, 0xc2, 0x01, 0xd7, 0x59,
2501
0x2e, 0x4d, 0xac, 0x49, 0xa2, 0xc1, 0x8d, 0x88, 0x4b, 0xfe, 0x28, 0xe5, 0xac, 0xa6, 0x85, 0xc4,
2502
0x1f, 0xf8, 0xc5, 0xc5, 0x14, 0x4e, 0xa3, 0xcb, 0x17, 0xb7, 0x64, 0xb3, 0xc2, 0x12, 0xf8, 0xf8,
2503
0x36, 0x99, 0x1c, 0x91, 0x9b, 0xbd, 0xed, 0x55, 0x0f, 0xfd, 0x49, 0x85, 0xbb, 0x32, 0xad, 0x78,
2504
0xc1, 0x74, 0xe6, 0x7c, 0x18, 0x0f, 0x2b, 0x3b, 0xaa, 0xd1, 0x9d, 0x40, 0x71, 0x1d, 0x19, 0x53
2505
};
2506
2507
static UCHAR rsaPrivateBlob[] =
2508
{
2509
0x52, 0x53, 0x41, 0x32, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
2510
0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0xa6, 0x8b, 0x46, 0x26, 0xb5,
2511
0xa9, 0x69, 0x83, 0x94, 0x66, 0xa7, 0xf3, 0x33, 0x95, 0x74, 0xe9, 0xeb, 0xc8, 0xcd, 0xd7, 0x81,
2512
0x9e, 0x45, 0x66, 0xb2, 0x48, 0x8b, 0x1f, 0xfe, 0xb3, 0x62, 0xc4, 0x0d, 0xa2, 0xf9, 0xf3, 0xe2,
2513
0xa6, 0x86, 0xd1, 0x1e, 0x8a, 0xbb, 0x1d, 0xa5, 0xc5, 0xe8, 0xa7, 0x50, 0x37, 0xfd, 0x69, 0x1f,
2514
0x6f, 0x99, 0x99, 0xca, 0x39, 0x13, 0xea, 0x5b, 0x6b, 0xe3, 0x91, 0xc0, 0xd2, 0x2c, 0x0b, 0x21,
2515
0xb1, 0xac, 0xa9, 0xe8, 0xa0, 0x6d, 0xa4, 0x1f, 0x1b, 0x34, 0xcb, 0x88, 0x7f, 0x2e, 0xeb, 0x7d,
2516
0x91, 0x38, 0x48, 0xce, 0x05, 0x73, 0x05, 0xdd, 0x22, 0x94, 0xc3, 0xdd, 0x1c, 0xfd, 0xc5, 0x41,
2517
0x2e, 0x94, 0xf9, 0xed, 0xe5, 0x92, 0x5f, 0x3f, 0x06, 0xf8, 0x49, 0x60, 0xb8, 0x92, 0x52, 0x6a,
2518
0x56, 0x6e, 0xd7, 0x04, 0x1a, 0xb5, 0xb5, 0x1c, 0x31, 0xd1, 0x1b,
2519
};
2520
2521
static UCHAR rsaFullPrivateBlob[] =
2522
{
2523
0x52, 0x53, 0x41, 0x33, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
2524
0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0xa6, 0x8b, 0x46, 0x26, 0xb5,
2525
0xa9, 0x69, 0x83, 0x94, 0x66, 0xa7, 0xf3, 0x33, 0x95, 0x74, 0xe9, 0xeb, 0xc8, 0xcd, 0xd7, 0x81,
2526
0x9e, 0x45, 0x66, 0xb2, 0x48, 0x8b, 0x1f, 0xfe, 0xb3, 0x62, 0xc4, 0x0d, 0xa2, 0xf9, 0xf3, 0xe2,
2527
0xa6, 0x86, 0xd1, 0x1e, 0x8a, 0xbb, 0x1d, 0xa5, 0xc5, 0xe8, 0xa7, 0x50, 0x37, 0xfd, 0x69, 0x1f,
2528
0x6f, 0x99, 0x99, 0xca, 0x39, 0x13, 0xea, 0x5b, 0x6b, 0xe3, 0x91, 0xc0, 0xd2, 0x2c, 0x0b, 0x21,
2529
0xb1, 0xac, 0xa9, 0xe8, 0xa0, 0x6d, 0xa4, 0x1f, 0x1b, 0x34, 0xcb, 0x88, 0x7f, 0x2e, 0xeb, 0x7d,
2530
0x91, 0x38, 0x48, 0xce, 0x05, 0x73, 0x05, 0xdd, 0x22, 0x94, 0xc3, 0xdd, 0x1c, 0xfd, 0xc5, 0x41,
2531
0x2e, 0x94, 0xf9, 0xed, 0xe5, 0x92, 0x5f, 0x3f, 0x06, 0xf8, 0x49, 0x60, 0xb8, 0x92, 0x52, 0x6a,
2532
0x56, 0x6e, 0xd7, 0x04, 0x1a, 0xb5, 0xb5, 0x1c, 0x31, 0xd1, 0x1b, 0xa3, 0xf3, 0xd1, 0x69, 0x61,
2533
0xab, 0xfe, 0xc1, 0xb6, 0x40, 0x7b, 0x19, 0xbb, 0x2d, 0x59, 0xf5, 0xda, 0x49, 0x32, 0x6f, 0x20,
2534
0x24, 0xd3, 0xb3, 0xec, 0x21, 0xec, 0x0c, 0xc7, 0x5b, 0xf9, 0x1b, 0xba, 0x6e, 0xe9, 0x61, 0xda,
2535
0x55, 0xc6, 0x72, 0xfd, 0x2d, 0x66, 0x3f, 0x3c, 0xcb, 0x49, 0xa9, 0xc5, 0x0d, 0x9b, 0x02, 0x36,
2536
0x7a, 0xee, 0x36, 0x09, 0x55, 0xe4, 0x03, 0xf2, 0xe3, 0xe6, 0x25, 0x14, 0x89, 0x7f, 0x2b, 0xfb,
2537
0x27, 0x0e, 0x8d, 0x37, 0x84, 0xfd, 0xad, 0x10, 0x79, 0x43, 0x4e, 0x38, 0x4a, 0xd4, 0x5e, 0xfa,
2538
0xda, 0x9f, 0x88, 0x21, 0x7c, 0xb4, 0x98, 0xb6, 0x6e, 0x1c, 0x24, 0x09, 0xe5, 0xe7, 0x22, 0x6f,
2539
0xd3, 0x84, 0xc0, 0xdc, 0x36, 0x09, 0xaf, 0x4b, 0x96, 0x8b, 0x5f, 0x47, 0xb3, 0x24, 0x80, 0xb5,
2540
0x64, 0x69, 0xad, 0x83, 0xd5, 0x09, 0xe7, 0xb9, 0xe4, 0x81, 0x6f, 0x1a, 0xe2, 0x6d, 0xf1, 0x5e,
2541
0x2b, 0xb3, 0x7a, 0xd0, 0x77, 0xef, 0x82, 0xcd, 0x55, 0x2e, 0xd5, 0xb1, 0xa7, 0x72, 0xec, 0x02,
2542
0x9d, 0xe2, 0xcc, 0x5a, 0xf1, 0x68, 0x30, 0xe5, 0xbc, 0x8d, 0xad,
2543
};
2544
2545
static struct
2546
{
2547
PUBLICKEYSTRUC header;
2548
RSAPUBKEY rsapubkey;
2549
BYTE modulus[512 / 8];
2550
BYTE prime1[512 / 16];
2551
BYTE prime2[512 / 16];
2552
BYTE exp1[512 / 16];
2553
BYTE exp2[512 / 16];
2554
BYTE coefficient[512 / 16];
2555
BYTE private_exp[512 / 8];
2556
2557
} rsaLegacyPrivateBlob =
2558
{
2559
{ PRIVATEKEYBLOB, CUR_BLOB_VERSION, 0, CALG_RSA_KEYX },
2560
{ BCRYPT_RSAPRIVATE_MAGIC, 512, 0x10001 },
2561
{
2562
0x91, 0xe3, 0x6b, 0x5b, 0xea, 0x13, 0x39, 0xca, 0x99, 0x99, 0x6f, 0x1f, 0x69, 0xfd, 0x37, 0x50,
2563
0xa7, 0xe8, 0xc5, 0xa5, 0x1d, 0xbb, 0x8a, 0x1e, 0xd1, 0x86, 0xa6, 0xe2, 0xf3, 0xf9, 0xa2, 0x0d,
2564
0xc4, 0x62, 0xb3, 0xfe, 0x1f, 0x8b, 0x48, 0xb2, 0x66, 0x45, 0x9e, 0x81, 0xd7, 0xcd, 0xc8, 0xeb,
2565
0xe9, 0x74, 0x95, 0x33, 0xf3, 0xa7, 0x66, 0x94, 0x83, 0x69, 0xa9, 0xb5, 0x26, 0x46, 0x8b, 0xa6
2566
},
2567
{
2568
0xc3, 0x94, 0x22, 0xdd, 0x05, 0x73, 0x05, 0xce, 0x48, 0x38, 0x91, 0x7d, 0xeb, 0x2e, 0x7f, 0x88,
2569
0xcb, 0x34, 0x1b, 0x1f, 0xa4, 0x6d, 0xa0, 0xe8, 0xa9, 0xac, 0xb1, 0x21, 0x0b, 0x2c, 0xd2, 0xc0
2570
},
2571
{
2572
0x1b, 0xd1, 0x31, 0x1c, 0xb5, 0xb5, 0x1a, 0x04, 0xd7, 0x6e, 0x56, 0x6a, 0x52, 0x92, 0xb8, 0x60,
2573
0x49, 0xf8, 0x06, 0x3f, 0x5f, 0x92, 0xe5, 0xed, 0xf9, 0x94, 0x2e, 0x41, 0xc5, 0xfd, 0x1c, 0xdd
2574
},
2575
{
2576
0x1b, 0xf9, 0x5b, 0xc7, 0x0c, 0xec, 0x21, 0xec, 0xb3, 0xd3, 0x24, 0x20, 0x6f, 0x32, 0x49, 0xda,
2577
0xf5, 0x59, 0x2d, 0xbb, 0x19, 0x7b, 0x40, 0xb6, 0xc1, 0xfe, 0xab, 0x61, 0x69, 0xd1, 0xf3, 0xa3
2578
},
2579
{
2580
0x25, 0xe6, 0xe3, 0xf2, 0x03, 0xe4, 0x55, 0x09, 0x36, 0xee, 0x7a, 0x36, 0x02, 0x9b, 0x0d, 0xc5,
2581
0xa9, 0x49, 0xcb, 0x3c, 0x3f, 0x66, 0x2d, 0xfd, 0x72, 0xc6, 0x55, 0xda, 0x61, 0xe9, 0x6e, 0xba
2582
},
2583
{
2584
0x24, 0x1c, 0x6e, 0xb6, 0x98, 0xb4, 0x7c, 0x21, 0x88, 0x9f, 0xda, 0xfa, 0x5e, 0xd4, 0x4a, 0x38,
2585
0x4e, 0x43, 0x79, 0x10, 0xad, 0xfd, 0x84, 0x37, 0x8d, 0x0e, 0x27, 0xfb, 0x2b, 0x7f, 0x89, 0x14
2586
},
2587
{
2588
0xad, 0x8d, 0xbc, 0xe5, 0x30, 0x68, 0xf1, 0x5a, 0xcc, 0xe2, 0x9d, 0x02, 0xec, 0x72, 0xa7, 0xb1,
2589
0xd5, 0x2e, 0x55, 0xcd, 0x82, 0xef, 0x77, 0xd0, 0x7a, 0xb3, 0x2b, 0x5e, 0xf1, 0x6d, 0xe2, 0x1a,
2590
0x6f, 0x81, 0xe4, 0xb9, 0xe7, 0x09, 0xd5, 0x83, 0xad, 0x69, 0x64, 0xb5, 0x80, 0x24, 0xb3, 0x47,
2591
0x5f, 0x8b, 0x96, 0x4b, 0xaf, 0x09, 0x36, 0xdc, 0xc0, 0x84, 0xd3, 0x6f, 0x22, 0xe7, 0xe5, 0x09
2592
}
2593
};
2594
2595
2596
static UCHAR rsaPublicBlobWithInvalidPublicExpSize[] =
2597
{
2598
0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
2599
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2600
0x01, 0x00, 0x01, 0xc7, 0x8f, 0xac, 0x2a, 0xce, 0xbf, 0xc9, 0x6c, 0x7b,
2601
0x85, 0x74, 0x71, 0xbb, 0xff, 0xbb, 0x9b, 0x20, 0x03, 0x79, 0x17, 0x34,
2602
0xe7, 0x26, 0x91, 0x5c, 0x1f, 0x1b, 0x03, 0x3d, 0x46, 0xdf, 0xb6, 0xf2,
2603
0x10, 0x55, 0xf0, 0x39, 0x55, 0x0a, 0xe3, 0x9c, 0x0c, 0x63, 0xc2, 0x14,
2604
0x03, 0x94, 0x51, 0x0d, 0xb4, 0x22, 0x09, 0xf2, 0x5c, 0xb2, 0xd1, 0xc3,
2605
0xac, 0x6f, 0xa8, 0xc4, 0xac, 0xb8, 0xbc, 0x59, 0xe7, 0xed, 0x77, 0x6e,
2606
0xb1, 0x80, 0x58, 0x7d, 0xb2, 0x94, 0x46, 0xe5, 0x00, 0xe2, 0xb7, 0x33,
2607
0x48, 0x7a, 0xd3, 0x78, 0xe9, 0x26, 0x01, 0xc7, 0x00, 0x7b, 0x41, 0x6d,
2608
0x94, 0x3a, 0xe1, 0x50, 0x2b, 0x9f, 0x6b, 0x1c, 0x08, 0xa3, 0xfc, 0x0a,
2609
0x44, 0x81, 0x09, 0x41, 0x80, 0x23, 0x7b, 0xf6, 0x3f, 0xaf, 0x91, 0xa1,
2610
0x87, 0x75, 0x33, 0x15, 0xb8, 0xde, 0x32, 0x30, 0xb4, 0x5e, 0xfd
2611
};
2612
2613
static const UCHAR rsa_encrypted_no_padding[] =
2614
{
2615
0x4a, 0xc1, 0xfa, 0x4f, 0xe0, 0x3f, 0x36, 0x9a, 0x64, 0xbf, 0x2e, 0x00, 0xb4, 0xb5, 0x40, 0xbe,
2616
0x2d, 0x9a, 0x14, 0xf6, 0x8f, 0xa5, 0xc2, 0xe2, 0x20, 0xaf, 0x21, 0x79, 0xc6, 0x32, 0x7e, 0xea,
2617
0x73, 0x00, 0x01, 0xbb, 0x9a, 0x19, 0x73, 0x41, 0x96, 0xae, 0x88, 0x6e, 0x36, 0x56, 0xe9, 0x9c,
2618
0xac, 0x04, 0x82, 0xa8, 0x00, 0xdb, 0x4e, 0x29, 0x61, 0x7e, 0xaf, 0x64, 0xdb, 0xa2, 0x70, 0x0f,
2619
};
2620
2621
static void test_rsa_encrypt(void)
2622
{
2623
UCHAR input[] = "Hello World!", input_no_padding[64] = { 0 }, encrypted[64], decrypted[64];
2624
BCRYPT_ALG_HANDLE rsa;
2625
BCRYPT_KEY_HANDLE key, key2;
2626
NTSTATUS ret;
2627
DWORD encrypted_size, decrypted_size;
2628
UCHAR *encrypted_a = NULL, *encrypted_b = NULL;
2629
BCRYPT_OAEP_PADDING_INFO oaep_pad;
2630
2631
oaep_pad.pszAlgId = BCRYPT_SHA256_ALGORITHM;
2632
oaep_pad.pbLabel = (UCHAR *)"test";
2633
oaep_pad.cbLabel = 5;
2634
2635
ret = BCryptOpenAlgorithmProvider(&rsa, BCRYPT_RSA_ALGORITHM, NULL, 0);
2636
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2637
ret = BCryptGenerateKeyPair(rsa, &key, 512, 0);
2638
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2639
2640
/* Not finalized key */
2641
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, NULL, 0, &encrypted_size, 0);
2642
ok(ret == STATUS_INVALID_HANDLE, "got %lx\n", ret);
2643
BCryptDestroyKey(key);
2644
2645
/* Import a different public key first to make sure a public key from private key improted next
2646
* overrides it. */
2647
ret = BCryptImportKeyPair(rsa, NULL, BCRYPT_RSAPUBLIC_BLOB, &key, rsaPublicBlob, sizeof(rsaPublicBlob), 0);
2648
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2649
2650
ret = BCryptImportKeyPair(rsa, NULL, BCRYPT_RSAPRIVATE_BLOB, &key, rsaPrivateBlob, sizeof(rsaPrivateBlob), 0);
2651
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2652
2653
/* No padding */
2654
todo_wine {
2655
memset(input_no_padding, 0, sizeof(input_no_padding));
2656
2657
encrypted_size = 0;
2658
ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, NULL, 0, &encrypted_size, BCRYPT_PAD_NONE);
2659
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2660
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
2661
2662
strcpy((char *)input_no_padding, "Hello World");
2663
encrypted_size = 0;
2664
ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, NULL, 0, &encrypted_size, BCRYPT_PAD_NONE);
2665
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2666
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
2667
2668
encrypted_a = malloc(encrypted_size);
2669
memset(encrypted_a, 0, encrypted_size);
2670
encrypted_b = malloc(encrypted_size);
2671
memset(encrypted_b, 0xff, encrypted_size);
2672
2673
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, encrypted_a, encrypted_size, &encrypted_size, BCRYPT_PAD_NONE);
2674
ok(ret == STATUS_INVALID_PARAMETER, "got %lx\n", ret);
2675
2676
ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, encrypted_a, 12, &encrypted_size, BCRYPT_PAD_NONE);
2677
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %lx\n", ret);
2678
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
2679
2680
ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, encrypted_a, encrypted_size, &encrypted_size, BCRYPT_PAD_NONE);
2681
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2682
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
2683
2684
ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, encrypted_b, encrypted_size, &encrypted_size, BCRYPT_PAD_NONE);
2685
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2686
}
2687
ok(!memcmp(encrypted_a, encrypted_b, encrypted_size), "Both outputs should be the same\n");
2688
ok(!memcmp(encrypted_b, rsa_encrypted_no_padding, encrypted_size), "Data mismatch.\n");
2689
2690
todo_wine {
2691
decrypted_size = 0;
2692
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, NULL, 0, &decrypted_size, BCRYPT_PAD_NONE);
2693
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2694
ok(decrypted_size == sizeof(input_no_padding), "got %lu\n", decrypted_size);
2695
2696
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, decrypted, decrypted_size, &decrypted_size, BCRYPT_PAD_NONE);
2697
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2698
ok(decrypted_size == sizeof(input_no_padding), "got %lu\n", decrypted_size);
2699
ok(!memcmp(decrypted, input_no_padding, sizeof(input_no_padding)), "unexpected output\n");
2700
}
2701
2702
/* PKCS1 Padding */
2703
encrypted_size = 0;
2704
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, NULL, 0, &encrypted_size, BCRYPT_PAD_PKCS1);
2705
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2706
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
2707
2708
encrypted_a = realloc(encrypted_a, encrypted_size);
2709
memset(encrypted_a, 0, encrypted_size);
2710
encrypted_b = realloc(encrypted_b, encrypted_size);
2711
memset(encrypted_b, 0, encrypted_size);
2712
2713
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, encrypted_a, encrypted_size, &encrypted_size, BCRYPT_PAD_PKCS1);
2714
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2715
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
2716
2717
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, encrypted_b, encrypted_size, &encrypted_size, BCRYPT_PAD_PKCS1);
2718
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2719
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
2720
ok(memcmp(encrypted_a, encrypted_b, encrypted_size), "Both outputs are the same\n");
2721
2722
decrypted_size = 0;
2723
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, NULL, 0, &decrypted_size, BCRYPT_PAD_PKCS1);
2724
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2725
ok(decrypted_size == sizeof(input), "got size of %ld\n", decrypted_size);
2726
2727
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, decrypted, decrypted_size, &decrypted_size, BCRYPT_PAD_PKCS1);
2728
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2729
ok(decrypted_size == sizeof(input), "got size of %ld\n", decrypted_size);
2730
ok(!memcmp(decrypted, input, sizeof(input)), "unexpected output\n");
2731
2732
ret = BCryptImportKeyPair(rsa, NULL, LEGACY_RSAPRIVATE_BLOB, &key2, (UCHAR *)&rsaLegacyPrivateBlob,
2733
sizeof(rsaLegacyPrivateBlob), 0);
2734
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2735
2736
ret = BCryptEncrypt(key2, input, sizeof(input), NULL, NULL, 0, encrypted, sizeof(encrypted),
2737
&encrypted_size, BCRYPT_PAD_PKCS1);
2738
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2739
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
2740
2741
memset(decrypted, 0, sizeof(decrypted));
2742
ret = BCryptDecrypt(key, encrypted, sizeof(encrypted), NULL, NULL, 0, decrypted, sizeof(decrypted),
2743
&decrypted_size, BCRYPT_PAD_PKCS1);
2744
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2745
ok(decrypted_size == sizeof(input), "got size of %ld\n", decrypted_size);
2746
ok(!memcmp(decrypted, input, sizeof(input)), "unexpected output\n");
2747
BCryptDestroyKey(key2);
2748
BCryptDestroyKey(key);
2749
2750
/* OAEP Padding */
2751
ret = BCryptGenerateKeyPair(rsa, &key, 640 /* minimum size for sha256 hash */, 0);
2752
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2753
2754
ret = BCryptFinalizeKeyPair(key, 0);
2755
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2756
2757
encrypted_size = 0;
2758
ret = BCryptEncrypt(key, input, sizeof(input), &oaep_pad, NULL, 0, NULL, 0, &encrypted_size, BCRYPT_PAD_OAEP);
2759
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2760
ok(encrypted_size == 80, "got size of %ld\n", encrypted_size);
2761
2762
encrypted_size = 0;
2763
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, NULL, 0, &encrypted_size, BCRYPT_PAD_OAEP);
2764
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2765
ok(encrypted_size == 80, "got size of %ld\n", encrypted_size);
2766
2767
encrypted_a = realloc(encrypted_a, encrypted_size);
2768
memset(encrypted_a, 0, encrypted_size);
2769
encrypted_b = realloc(encrypted_b, encrypted_size);
2770
memset(encrypted_b, 0, encrypted_size);
2771
2772
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, NULL, encrypted_size, &encrypted_size, BCRYPT_PAD_OAEP);
2773
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2774
ok(encrypted_size == 80, "got size of %ld\n", encrypted_size);
2775
2776
encrypted_size = 0;
2777
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, encrypted_a, 0, &encrypted_size, BCRYPT_PAD_OAEP);
2778
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %lx\n", ret);
2779
ok(encrypted_size == 80, "got size of %ld\n", encrypted_size);
2780
2781
ret = BCryptEncrypt(key, input, sizeof(input), &oaep_pad, NULL, 0, encrypted_a, encrypted_size, &encrypted_size, BCRYPT_PAD_OAEP);
2782
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2783
ok(encrypted_size == 80, "got size of %ld\n", encrypted_size);
2784
2785
ret = BCryptEncrypt(key, input, sizeof(input), &oaep_pad, NULL, 0, encrypted_b, encrypted_size, &encrypted_size, BCRYPT_PAD_OAEP);
2786
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2787
ok(encrypted_size == 80, "got size of %ld\n", encrypted_size);
2788
ok(memcmp(encrypted_a, encrypted_b, encrypted_size), "Both outputs are the same\n");
2789
2790
decrypted_size = 0;
2791
memset(decrypted, 0, sizeof(decrypted));
2792
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, NULL, 0, &decrypted_size, BCRYPT_PAD_OAEP);
2793
ok(ret == STATUS_INVALID_PARAMETER, "got %lx\n", ret);
2794
2795
decrypted_size = 0;
2796
memset(decrypted, 0, sizeof(decrypted));
2797
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, &oaep_pad, NULL, 0, NULL, 0, &decrypted_size, BCRYPT_PAD_OAEP);
2798
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2799
ok(decrypted_size == sizeof(input), "got %lu\n", decrypted_size);
2800
2801
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, &oaep_pad, NULL, 0, decrypted, decrypted_size, &decrypted_size, BCRYPT_PAD_OAEP);
2802
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2803
ok(decrypted_size == sizeof(input), "got %lu\n", decrypted_size);
2804
ok(!memcmp(decrypted, input, sizeof(input)), "unexpected output\n");
2805
2806
free(encrypted_a);
2807
free(encrypted_b);
2808
2809
BCryptDestroyKey(key);
2810
2811
if (pBCryptHash)
2812
{
2813
ret = BCryptGenerateKeyPair(BCRYPT_RSA_ALG_HANDLE, &key, 512, 0);
2814
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
2815
BCryptDestroyKey(key);
2816
}
2817
}
2818
2819
static void test_RSA(void)
2820
{
2821
static UCHAR hash[] =
2822
{0x7e,0xe3,0x74,0xe7,0xc5,0x0b,0x6b,0x70,0xdb,0xab,0x32,0x6d,0x1d,0x51,0xd6,0x74,0x79,0x8e,0x5b,0x4b};
2823
static UCHAR hash48[] =
2824
{0x62,0xb2,0x1e,0x90,0xc9,0x02,0x2b,0x10,0x16,0x71,0xba,0x1f,0x80,0x8f,0x86,0x31,0xa8,0x14,0x9f,0x0f,
2825
0x12,0x90,0x40,0x55,0x83,0x9a,0x35,0xc1,0xca,0x78,0xae,0x53,0x1b,0xb3,0x36,0x06,0xba,0x90,0x89,0x12,
2826
0xa8,0x42,0x21,0x10,0x9d,0x29,0xcd,0x7e};
2827
BCRYPT_PKCS1_PADDING_INFO pad;
2828
BCRYPT_PSS_PADDING_INFO pad_pss;
2829
BCRYPT_ALG_HANDLE alg;
2830
BCRYPT_KEY_HANDLE key;
2831
BCRYPT_RSAKEY_BLOB *rsablob;
2832
UCHAR sig[256], sig_pss[256];
2833
ULONG len, size, size2, schemes;
2834
NTSTATUS ret;
2835
BYTE *buf;
2836
DWORD keylen;
2837
2838
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_RSA_ALGORITHM, NULL, 0);
2839
ok(!ret, "got %#lx\n", ret);
2840
2841
schemes = size = 0;
2842
ret = BCryptGetProperty(alg, L"PaddingSchemes", (UCHAR *)&schemes, sizeof(schemes), &size, 0);
2843
ok(!ret, "got %#lx\n", ret);
2844
ok(schemes, "schemes not set\n");
2845
ok(size == sizeof(schemes), "got %lu\n", size);
2846
2847
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_PUBLIC_KEY_BLOB, &key, rsaPublicBlob, sizeof(rsaPublicBlob), 0);
2848
ok(!ret, "BCryptImportKeyPair failed: %#lx\n", ret);
2849
BCryptDestroyKey(key);
2850
2851
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_RSAPUBLIC_BLOB, &key, rsaPublicBlob, sizeof(rsaPublicBlob), 0);
2852
ok(!ret, "BCryptImportKeyPair failed: %#lx\n", ret);
2853
2854
keylen = 0;
2855
ret = BCryptGetProperty(key, BCRYPT_KEY_STRENGTH, (UCHAR *)&keylen, sizeof(keylen), &size, 0);
2856
ok(!ret, "got %#lx\n", ret);
2857
ok(size == sizeof(keylen), "got %lu\n", size);
2858
ok(keylen == 2048, "got %lu\n", keylen);
2859
2860
pad.pszAlgId = BCRYPT_SHA1_ALGORITHM;
2861
ret = BCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
2862
ok(!ret, "BCryptVerifySignature failed: %#lx\n", ret);
2863
2864
ret = BCryptVerifySignature(key, NULL, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
2865
ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %#lx\n", ret);
2866
2867
pad.pszAlgId = BCRYPT_SHA1_ALGORITHM;
2868
ret = BCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), 0);
2869
ok(ret == STATUS_INVALID_SIGNATURE || ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
2870
2871
ret = BCryptVerifySignature(key, NULL, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), 0);
2872
ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %#lx\n", ret);
2873
2874
pad.pszAlgId = BCRYPT_AES_ALGORITHM;
2875
ret = BCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
2876
ok(ret == STATUS_NOT_SUPPORTED, "Expected STATUS_NOT_SUPPORTED, got %#lx\n", ret);
2877
2878
pad.pszAlgId = NULL;
2879
ret = BCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
2880
ok(ret == STATUS_INVALID_SIGNATURE, "Expected STATUS_INVALID_SIGNATURE, got %#lx\n", ret);
2881
2882
ret = BCryptDestroyKey(key);
2883
ok(!ret, "BCryptDestroyKey failed: %#lx\n", ret);
2884
2885
/* sign/verify with export/import round-trip */
2886
ret = BCryptGenerateKeyPair(alg, &key, 1024, 0);
2887
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2888
2889
keylen = 2048;
2890
ret = BCryptSetProperty(key, BCRYPT_KEY_LENGTH, (UCHAR *)&keylen, 2, 0);
2891
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
2892
ret = BCryptSetProperty(key, BCRYPT_KEY_LENGTH, (UCHAR *)&keylen, sizeof(keylen), 0);
2893
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2894
2895
ret = BCryptFinalizeKeyPair(key, 0);
2896
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2897
2898
keylen = 0;
2899
ret = BCryptGetProperty(key, BCRYPT_KEY_STRENGTH, (UCHAR *)&keylen, sizeof(keylen), &size, 0);
2900
ok(!ret, "got %#lx\n", ret);
2901
ok(size == sizeof(keylen), "got %lu\n", size);
2902
ok(keylen == 2048, "got %lu\n", keylen);
2903
2904
ret = BCryptSetProperty(key, BCRYPT_KEY_LENGTH, (UCHAR *)&keylen, sizeof(keylen), 0);
2905
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2906
2907
pad.pszAlgId = BCRYPT_MD5_ALGORITHM;
2908
memset(sig, 0, sizeof(sig));
2909
len = 0;
2910
ret = BCryptSignHash(key, &pad, hash, 16, sig, sizeof(sig), &len, BCRYPT_PAD_PKCS1);
2911
ok(!ret, "got %#lx\n", ret);
2912
ok(len == 256, "got %lu\n", len);
2913
pad.pszAlgId = BCRYPT_MD5_ALGORITHM;
2914
ret = BCryptVerifySignature(key, &pad, hash, 16, sig, len, BCRYPT_PAD_PKCS1);
2915
ok(!ret, "BCryptVerifySignature failed: %#lx\n", ret);
2916
2917
pad.pszAlgId = BCRYPT_SHA1_ALGORITHM;
2918
memset(sig, 0, sizeof(sig));
2919
len = 0;
2920
ret = BCryptSignHash(key, &pad, hash, sizeof(hash), sig, sizeof(sig), &len, BCRYPT_PAD_PKCS1);
2921
ok(!ret, "got %#lx\n", ret);
2922
ok(len == 256, "got %lu\n", len);
2923
pad.pszAlgId = BCRYPT_SHA1_ALGORITHM;
2924
ret = BCryptVerifySignature(key, &pad, hash, sizeof(hash), sig, len, BCRYPT_PAD_PKCS1);
2925
ok(!ret, "BCryptVerifySignature failed: %#lx\n", ret);
2926
2927
pad.pszAlgId = NULL;
2928
memset(sig, 0, sizeof(sig));
2929
len = 0;
2930
ret = BCryptSignHash(key, &pad, hash, sizeof(hash), sig, sizeof(sig), &len, BCRYPT_PAD_PKCS1);
2931
ok(!ret, "got %#lx\n", ret);
2932
ok(len == 256, "got %lu\n", len);
2933
2934
pad.pszAlgId = BCRYPT_SHA1_ALGORITHM;
2935
ret = BCryptVerifySignature(key, &pad, hash, sizeof(hash), sig, len, BCRYPT_PAD_PKCS1);
2936
ok(ret == STATUS_INVALID_SIGNATURE, "BCryptVerifySignature failed: %#lx, len %ld\n", ret, len);
2937
2938
pad.pszAlgId = NULL;
2939
ret = BCryptVerifySignature(key, &pad, hash, sizeof(hash), sig, len, BCRYPT_PAD_PKCS1);
2940
ok(!ret, "BCryptVerifySignature failed: %#lx, len %ld\n", ret, len);
2941
2942
pad_pss.pszAlgId = BCRYPT_SHA384_ALGORITHM;
2943
pad_pss.cbSalt = 48;
2944
memset(sig_pss, 0, sizeof(sig_pss));
2945
len = 0;
2946
ret = BCryptSignHash(key, &pad_pss, hash48, sizeof(hash48), sig_pss, sizeof(sig_pss), &len, BCRYPT_PAD_PSS);
2947
ok(!ret, "got %#lx\n", ret);
2948
ok(len == 256, "got %lu\n", len);
2949
2950
/* export private key */
2951
size = 0;
2952
ret = BCryptExportKey(key, NULL, BCRYPT_RSAPRIVATE_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_RSAPRIVATE_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_RSAPRIVATE_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 == 128, "got %lu\n", rsablob->cbPrime1);
2965
ok(rsablob->cbPrime2 == 128, "got %lu\n", rsablob->cbPrime2);
2966
size2 = sizeof(*rsablob) + rsablob->cbPublicExp + rsablob->cbModulus + rsablob->cbPrime1 + rsablob->cbPrime2;
2967
ok(size == size2, "got %lu expected %lu\n", size2, size);
2968
free(buf);
2969
2970
size = 0;
2971
ret = BCryptExportKey(key, NULL, BCRYPT_RSAFULLPRIVATE_BLOB, NULL, 0, &size, 0);
2972
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2973
ok(size, "size not set\n");
2974
2975
buf = malloc(size);
2976
ret = BCryptExportKey(key, NULL, BCRYPT_RSAFULLPRIVATE_BLOB, buf, size, &size, 0);
2977
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2978
rsablob = (BCRYPT_RSAKEY_BLOB *)buf;
2979
ok(rsablob->Magic == BCRYPT_RSAFULLPRIVATE_MAGIC, "got %#lx\n", rsablob->Magic);
2980
ok(rsablob->BitLength == 2048, "got %lu\n", rsablob->BitLength);
2981
ok(rsablob->cbPublicExp == 3, "got %lu\n", rsablob->cbPublicExp);
2982
ok(rsablob->cbModulus == 256, "got %lu\n", rsablob->cbModulus);
2983
ok(rsablob->cbPrime1 == 128, "got %lu\n", rsablob->cbPrime1);
2984
ok(rsablob->cbPrime2 == 128, "got %lu\n", rsablob->cbPrime2);
2985
size2 = sizeof(*rsablob) + rsablob->cbPublicExp + rsablob->cbModulus * 2 + rsablob->cbPrime1 * 3 + rsablob->cbPrime2 * 2;
2986
ok(size == size2, "got %lu expected %lu\n", size2, size);
2987
free(buf);
2988
2989
/* import/export public key */
2990
size = 0;
2991
ret = BCryptExportKey(key, NULL, BCRYPT_RSAPUBLIC_BLOB, NULL, 0, &size, 0);
2992
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2993
ok(size, "size not set\n");
2994
2995
buf = malloc(size);
2996
ret = BCryptExportKey(key, NULL, BCRYPT_RSAPUBLIC_BLOB, buf, size, &size, 0);
2997
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
2998
rsablob = (BCRYPT_RSAKEY_BLOB *)buf;
2999
ok(rsablob->Magic == BCRYPT_RSAPUBLIC_MAGIC, "got %#lx\n", rsablob->Magic);
3000
ok(rsablob->BitLength == 2048, "got %lu\n", rsablob->BitLength);
3001
ok(rsablob->cbPublicExp == 3, "got %lu\n", rsablob->cbPublicExp);
3002
ok(rsablob->cbModulus == 256, "got %lu\n", rsablob->cbModulus);
3003
ok(!rsablob->cbPrime1, "got %lu\n", rsablob->cbPrime1);
3004
ok(!rsablob->cbPrime2, "got %lu\n", rsablob->cbPrime2);
3005
ok(size == sizeof(*rsablob) + rsablob->cbPublicExp + rsablob->cbModulus, "got %lu\n", size);
3006
ret = BCryptDestroyKey(key);
3007
ok(!ret, "got %#lx\n", ret);
3008
3009
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_RSAPUBLIC_BLOB, &key, rsaPublicBlobWithInvalidPublicExpSize,
3010
sizeof(rsaPublicBlobWithInvalidPublicExpSize), 0);
3011
ok(ret == NTE_BAD_DATA, "got %#lx\n", ret);
3012
3013
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_RSAPUBLIC_BLOB, &key, buf, size, 0);
3014
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3015
free(buf);
3016
3017
ret = BCryptVerifySignature(key, &pad, hash, sizeof(hash), sig, sizeof(sig), BCRYPT_PAD_PKCS1);
3018
ok(!ret, "got %#lx\n", ret);
3019
ret = BCryptVerifySignature(key, &pad_pss, hash48, sizeof(hash48), sig_pss, sizeof(sig_pss), BCRYPT_PAD_PSS);
3020
ok(!ret, "got %#lx\n", ret);
3021
ret = BCryptDestroyKey(key);
3022
ok(!ret, "got %#lx\n", ret);
3023
3024
/* import/export private key */
3025
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_RSAPRIVATE_BLOB, &key, rsaPrivateBlob, sizeof(rsaPrivateBlob), 0);
3026
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3027
3028
ret = BCryptFinalizeKeyPair(key, 0);
3029
ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret);
3030
3031
size = 0;
3032
buf = malloc(sizeof(rsaPrivateBlob));
3033
ret = BCryptExportKey(key, NULL, BCRYPT_RSAPRIVATE_BLOB, buf, sizeof(rsaPrivateBlob), &size, 0);
3034
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3035
ok(size == sizeof(rsaPrivateBlob), "got %lu\n", size);
3036
ok(!memcmp(buf, rsaPrivateBlob, size), "wrong data\n");
3037
free(buf);
3038
BCryptDestroyKey(key);
3039
3040
/* import/export full private key */
3041
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_RSAFULLPRIVATE_BLOB, &key, rsaFullPrivateBlob, sizeof(rsaFullPrivateBlob), 0);
3042
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3043
3044
size = 0;
3045
buf = malloc(sizeof(rsaFullPrivateBlob));
3046
ret = BCryptExportKey(key, NULL, BCRYPT_RSAFULLPRIVATE_BLOB, buf, sizeof(rsaFullPrivateBlob), &size, 0);
3047
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3048
ok(size == sizeof(rsaFullPrivateBlob), "got %lu\n", size);
3049
ok(!memcmp(buf, rsaFullPrivateBlob, size), "wrong data\n");
3050
free(buf);
3051
BCryptDestroyKey(key);
3052
3053
ret = BCryptCloseAlgorithmProvider(alg, 0);
3054
ok(!ret, "got %#lx\n", ret);
3055
}
3056
3057
static void test_RSA_SIGN(void)
3058
{
3059
BCRYPT_PKCS1_PADDING_INFO pad;
3060
BCRYPT_ALG_HANDLE alg = NULL;
3061
BCRYPT_KEY_HANDLE key = NULL;
3062
BCRYPT_RSAKEY_BLOB *rsablob;
3063
NTSTATUS ret;
3064
ULONG size, size2;
3065
BYTE *buf, buf2[sizeof(BCRYPT_RSAKEY_BLOB) + sizeof(rsaPublicBlob)];
3066
3067
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_RSA_SIGN_ALGORITHM, NULL, 0);
3068
ok(!ret, "got %#lx\n", ret);
3069
3070
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_RSAPUBLIC_BLOB, &key, rsaPublicBlob, sizeof(rsaPublicBlob), 0);
3071
ok(!ret, "BCryptImportKeyPair failed: %#lx\n", ret);
3072
3073
memset(buf2, 0xcc, sizeof(buf2));
3074
ret = BCryptExportKey(key, NULL, BCRYPT_RSAPUBLIC_BLOB, buf2, sizeof(buf2), &size, 0);
3075
ok(!ret, "got %#lx\n", ret);
3076
rsablob = (BCRYPT_RSAKEY_BLOB *)buf2;
3077
ok(rsablob->Magic == BCRYPT_RSAPUBLIC_MAGIC, "got %#lx\n", rsablob->Magic);
3078
ok(rsablob->BitLength == 2048, "got %lu\n", rsablob->BitLength);
3079
ok(rsablob->cbPublicExp == 3, "got %lu\n", rsablob->cbPublicExp);
3080
ok(rsablob->cbModulus == 256, "got %lu\n", rsablob->cbModulus);
3081
ok(rsablob->cbPrime1 == 0, "got %lu\n", rsablob->cbPrime1);
3082
ok(rsablob->cbPrime2 == 0, "got %lu\n", rsablob->cbPrime2);
3083
size2 = sizeof(*rsablob) + rsablob->cbPublicExp + rsablob->cbModulus + rsablob->cbPrime1 + rsablob->cbPrime2;
3084
ok(size == size2, "got %lu expected %lu\n", size2, size);
3085
3086
ret = BCryptExportKey(key, NULL, BCRYPT_RSAPRIVATE_BLOB, buf2, sizeof(buf2), &size, 0);
3087
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
3088
3089
pad.pszAlgId = NULL;
3090
ret = BCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
3091
ok(ret == STATUS_INVALID_SIGNATURE, "BCryptVerifySignature failed: %#lx\n", ret);
3092
3093
pad.pszAlgId = BCRYPT_SHA1_ALGORITHM;
3094
ret = BCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
3095
ok(!ret, "BCryptVerifySignature failed: %#lx\n", ret);
3096
3097
ret = BCryptVerifySignature(key, NULL, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
3098
ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %#lx\n", ret);
3099
3100
pad.pszAlgId = BCRYPT_SHA1_ALGORITHM;
3101
ret = BCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), 0);
3102
ok(ret == STATUS_INVALID_SIGNATURE || ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
3103
3104
ret = BCryptVerifySignature(key, NULL, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), 0);
3105
ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %#lx\n", ret);
3106
3107
pad.pszAlgId = BCRYPT_AES_ALGORITHM;
3108
ret = BCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
3109
ok(ret == STATUS_NOT_SUPPORTED, "Expected STATUS_NOT_SUPPORTED, got %#lx\n", ret);
3110
3111
pad.pszAlgId = NULL;
3112
ret = BCryptVerifySignature(key, &pad, rsaHash, sizeof(rsaHash), rsaSignature, sizeof(rsaSignature), BCRYPT_PAD_PKCS1);
3113
ok(ret == STATUS_INVALID_SIGNATURE, "Expected STATUS_INVALID_SIGNATURE, got %#lx\n", ret);
3114
3115
ret = BCryptDestroyKey(key);
3116
ok(!ret, "BCryptDestroyKey failed: %#lx\n", ret);
3117
3118
/* export private key */
3119
ret = BCryptGenerateKeyPair(alg, &key, 512, 0);
3120
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3121
3122
ret = BCryptFinalizeKeyPair(key, 0);
3123
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3124
3125
size = 0;
3126
ret = BCryptExportKey(key, NULL, BCRYPT_RSAPRIVATE_BLOB, NULL, 0, &size, 0);
3127
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3128
ok(size, "size not set\n");
3129
3130
buf = malloc(size);
3131
ret = BCryptExportKey(key, NULL, BCRYPT_RSAPRIVATE_BLOB, buf, size, &size, 0);
3132
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3133
rsablob = (BCRYPT_RSAKEY_BLOB *)buf;
3134
ok(rsablob->Magic == BCRYPT_RSAPRIVATE_MAGIC, "got %#lx\n", rsablob->Magic);
3135
ok(rsablob->BitLength == 512, "got %lu\n", rsablob->BitLength);
3136
ok(rsablob->cbPublicExp == 3, "got %lu\n", rsablob->cbPublicExp);
3137
ok(rsablob->cbModulus == 64, "got %lu\n", rsablob->cbModulus);
3138
ok(rsablob->cbPrime1 == 32, "got %lu\n", rsablob->cbPrime1);
3139
ok(rsablob->cbPrime2 == 32, "got %lu\n", rsablob->cbPrime2);
3140
size2 = sizeof(*rsablob) + rsablob->cbPublicExp + rsablob->cbModulus + rsablob->cbPrime1 + rsablob->cbPrime2;
3141
ok(size == size2, "got %lu expected %lu\n", size2, size);
3142
free(buf);
3143
3144
size = 0;
3145
ret = BCryptExportKey(key, NULL, BCRYPT_RSAFULLPRIVATE_BLOB, NULL, 0, &size, 0);
3146
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3147
ok(size, "size not set\n");
3148
3149
buf = malloc(size);
3150
ret = BCryptExportKey(key, NULL, BCRYPT_RSAFULLPRIVATE_BLOB, buf, size, &size, 0);
3151
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3152
rsablob = (BCRYPT_RSAKEY_BLOB *)buf;
3153
ok(rsablob->Magic == BCRYPT_RSAFULLPRIVATE_MAGIC, "got %#lx\n", rsablob->Magic);
3154
ok(rsablob->BitLength == 512, "got %lu\n", rsablob->BitLength);
3155
ok(rsablob->cbPublicExp == 3, "got %lu\n", rsablob->cbPublicExp);
3156
ok(rsablob->cbModulus == 64, "got %lu\n", rsablob->cbModulus);
3157
ok(rsablob->cbPrime1 == 32, "got %lu\n", rsablob->cbPrime1);
3158
ok(rsablob->cbPrime2 == 32, "got %lu\n", rsablob->cbPrime2);
3159
size2 = sizeof(*rsablob) + rsablob->cbPublicExp + rsablob->cbModulus * 2 + rsablob->cbPrime1 * 3 + rsablob->cbPrime2 * 2;
3160
ok(size == size2, "got %lu expected %lu\n", size2, size);
3161
free(buf);
3162
BCryptDestroyKey(key);
3163
3164
ret = BCryptCloseAlgorithmProvider(alg, 0);
3165
ok(!ret, "BCryptCloseAlgorithmProvider failed: %#lx\n", ret);
3166
}
3167
3168
struct ecdh_test
3169
{
3170
const WCHAR *alg;
3171
ULONG bitlen;
3172
BYTE *eccprivkey;
3173
ULONG eccprivkey_len;
3174
BYTE *ecdh_pubkey;
3175
ULONG ecdh_pubkey_len;
3176
BYTE *ecdh_secret;
3177
ULONG ecdh_secret_len;
3178
BYTE *hashed_secret;
3179
DWORD public_magic;
3180
DWORD private_magic;
3181
};
3182
3183
static void test_ECDH_alg(const struct ecdh_test *t)
3184
{
3185
BCryptBuffer hash_param_buffers[] =
3186
{
3187
{
3188
sizeof(BCRYPT_SHA1_ALGORITHM),
3189
KDF_HASH_ALGORITHM,
3190
(void *)BCRYPT_SHA1_ALGORITHM,
3191
}
3192
};
3193
3194
BCryptBufferDesc hash_params =
3195
{
3196
BCRYPTBUFFER_VERSION,
3197
ARRAY_SIZE(hash_param_buffers),
3198
hash_param_buffers,
3199
};
3200
BYTE *buf;
3201
BCRYPT_ECCKEY_BLOB *ecckey;
3202
BCRYPT_ALG_HANDLE alg;
3203
BCRYPT_KEY_HANDLE key, privkey, pubkey;
3204
BCRYPT_SECRET_HANDLE secret;
3205
NTSTATUS status;
3206
ULONG size;
3207
3208
status = BCryptOpenAlgorithmProvider(&alg, t->alg, NULL, 0);
3209
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3210
3211
key = NULL;
3212
status = BCryptGenerateKeyPair(alg, &key, t->bitlen, 0);
3213
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3214
ok(key != NULL, "key not set\n");
3215
3216
status = BCryptFinalizeKeyPair(key, 0);
3217
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3218
3219
size = 0;
3220
status = BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, NULL, 0, &size, 0);
3221
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3222
ok(size, "size not set\n");
3223
3224
buf = malloc(size);
3225
status = BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, buf, size, &size, 0);
3226
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3227
ecckey = (BCRYPT_ECCKEY_BLOB *)buf;
3228
ok(ecckey->dwMagic == t->public_magic, "got %#lx\n", ecckey->dwMagic);
3229
ok(ecckey->cbKey == (t->bitlen + 7) / 8, "got %lu\n", ecckey->cbKey);
3230
ok(size == sizeof(*ecckey) + ecckey->cbKey * 2, "got %lu\n", size);
3231
3232
status = BCryptImportKeyPair(alg, NULL, BCRYPT_PUBLIC_KEY_BLOB, &pubkey, buf, size, 0);
3233
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3234
BCryptDestroyKey(pubkey);
3235
3236
status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPUBLIC_BLOB, &pubkey, buf, size, 0);
3237
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3238
free(buf);
3239
3240
size = 0;
3241
status = BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, NULL, 0, &size, 0);
3242
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3243
ok(size, "size not set\n");
3244
3245
buf = malloc(size);
3246
status = BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, buf, size, &size, 0);
3247
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3248
ecckey = (BCRYPT_ECCKEY_BLOB *)buf;
3249
ok(ecckey->dwMagic == t->private_magic, "got %#lx\n", ecckey->dwMagic);
3250
ok(ecckey->cbKey == (t->bitlen + 7) / 8, "got %lu\n", ecckey->cbKey);
3251
ok(size == sizeof(*ecckey) + ecckey->cbKey * 3, "got %lu\n", size);
3252
3253
status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPRIVATE_BLOB, &privkey, buf, size, 0);
3254
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3255
free(buf);
3256
BCryptDestroyKey(pubkey);
3257
BCryptDestroyKey(privkey);
3258
BCryptDestroyKey(key);
3259
3260
status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPRIVATE_BLOB, &privkey, t->eccprivkey, t->eccprivkey_len, 0);
3261
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3262
3263
size = 0;
3264
status = BCryptExportKey(privkey, NULL, BCRYPT_ECCPRIVATE_BLOB, NULL, 0, &size, 0);
3265
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3266
ok(size, "size not set\n");
3267
3268
buf = malloc(size);
3269
status = BCryptExportKey(privkey, NULL, BCRYPT_ECCPRIVATE_BLOB, buf, size, &size, 0);
3270
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3271
ok(size == t->eccprivkey_len, "got %lu\n", size);
3272
ok(!memcmp(buf, t->eccprivkey, size), "wrong data\n");
3273
free(buf);
3274
3275
status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPUBLIC_BLOB, &pubkey, t->ecdh_pubkey, t->ecdh_pubkey_len, 0);
3276
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3277
3278
status = BCryptSecretAgreement(privkey, pubkey, &secret, 0);
3279
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3280
if (status != STATUS_SUCCESS) goto derive_end;
3281
3282
status = BCryptDeriveKey(secret, BCRYPT_KDF_RAW_SECRET, NULL, NULL, 0, &size, 0);
3283
if (status == STATUS_NOT_SUPPORTED) /* < win10 */
3284
{
3285
win_skip("BCRYPT_KDF_RAW_SECRET not supported\n");
3286
goto raw_secret_end;
3287
}
3288
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3289
if (status != STATUS_SUCCESS) goto raw_secret_end;
3290
3291
ok(size == (t->bitlen + 7) / 8, "size of secret key incorrect, got %lu, expected 32\n", size);
3292
buf = malloc(size);
3293
status = BCryptDeriveKey(secret, BCRYPT_KDF_RAW_SECRET, NULL, buf, size, &size, 0);
3294
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3295
ok(!(memcmp(t->ecdh_secret, buf, size)), "wrong data\n");
3296
free(buf);
3297
3298
raw_secret_end:
3299
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &hash_params, NULL, 0, &size, 0);
3300
ok (status == STATUS_SUCCESS, "got %#lx\n", status);
3301
if (status != STATUS_SUCCESS) goto derive_end;
3302
3303
ok (size == 20, "got %lu\n", size);
3304
buf = malloc(size);
3305
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &hash_params, buf, size, &size, 0);
3306
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3307
ok(!(memcmp(t->hashed_secret, buf, size)), "wrong data\n");
3308
free(buf);
3309
3310
/* ulVersion is not verified */
3311
hash_params.ulVersion = 0xdeadbeef;
3312
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &hash_params, NULL, 0, &size, 0);
3313
ok (status == STATUS_SUCCESS, "got %#lx\n", status);
3314
3315
hash_params.ulVersion = BCRYPTBUFFER_VERSION;
3316
hash_param_buffers[0].pvBuffer = (void*) L"INVALID";
3317
hash_param_buffers[0].cbBuffer = sizeof(L"INVALID");
3318
3319
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &hash_params, NULL, 0, &size, 0);
3320
ok (status == STATUS_NOT_SUPPORTED || broken (status == STATUS_NOT_FOUND) /* < win8 */, "got %#lx\n", status);
3321
3322
hash_param_buffers[0].pvBuffer = (void*) BCRYPT_RNG_ALGORITHM;
3323
hash_param_buffers[0].cbBuffer = sizeof(BCRYPT_RNG_ALGORITHM);
3324
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &hash_params, NULL, 0, &size, 0);
3325
ok (status == STATUS_NOT_SUPPORTED, "got %#lx\n", status);
3326
3327
derive_end:
3328
BCryptDestroySecret(secret);
3329
BCryptDestroyKey(pubkey);
3330
BCryptDestroyKey(privkey);
3331
BCryptCloseAlgorithmProvider(alg, 0);
3332
}
3333
3334
static void test_ECDH(void)
3335
{
3336
BCRYPT_ALG_HANDLE alg;
3337
BCRYPT_KEY_HANDLE key;
3338
NTSTATUS status;
3339
ULONG strength, size;
3340
3341
static BYTE ecc256privkey[] =
3342
{
3343
0x45, 0x43, 0x4b, 0x32, 0x20, 0x00, 0x00, 0x00,
3344
0xfb, 0xbd, 0x3d, 0x20, 0x1b, 0x6d, 0x66, 0xb3, 0x7c, 0x9f, 0x89, 0xf3, 0xe4, 0x41, 0x16, 0xa5,
3345
0x68, 0x52, 0x77, 0xac, 0xab, 0x55, 0xb2, 0x6c, 0xb0, 0x23, 0x55, 0xcb, 0x96, 0x14, 0xfd, 0x0b,
3346
0x1c, 0xef, 0xdf, 0x07, 0x6d, 0x31, 0xaf, 0x39, 0xce, 0x8c, 0x8f, 0x9d, 0x75, 0xd0, 0x7b, 0xea,
3347
0x81, 0xdc, 0x40, 0x21, 0x1f, 0x58, 0x22, 0x5f, 0x72, 0x55, 0xfc, 0x58, 0x8a, 0xeb, 0x88, 0x5d,
3348
0x02, 0x09, 0x90, 0xd2, 0xe3, 0x36, 0xac, 0xfe, 0x83, 0x13, 0x6c, 0x88, 0x1a, 0xab, 0x9b, 0xdd,
3349
0xaa, 0x8a, 0xee, 0x69, 0x9a, 0x6a, 0x62, 0x86, 0x6a, 0x13, 0x69, 0x88, 0xb7, 0xd5, 0xa3, 0xcd
3350
};
3351
static BYTE ecdh256_pubkey[] =
3352
{
3353
0x45, 0x43, 0x4b, 0x31, 0x20, 0x00, 0x00, 0x00,
3354
0x07, 0x61, 0x9d, 0x49, 0x63, 0x6b, 0x96, 0x94, 0xd1, 0x8f, 0xd1, 0x48, 0xcc, 0xcf, 0x72, 0x4d,
3355
0xff, 0x43, 0xf4, 0x97, 0x0f, 0xa3, 0x8a, 0x72, 0xe9, 0xe0, 0xba, 0x87, 0x6d, 0xc3, 0x62, 0x15,
3356
0xae, 0x65, 0xdd, 0x31, 0x51, 0xfc, 0x3b, 0xc9, 0x59, 0xa1, 0x0a, 0x92, 0x17, 0x2b, 0x64, 0x55,
3357
0x03, 0x3e, 0x62, 0x1d, 0xac, 0x3e, 0x37, 0x40, 0x6a, 0x4c, 0xb6, 0x21, 0x3f, 0x73, 0x5c, 0xf5
3358
};
3359
static BYTE ecdh256_secret[] =
3360
{
3361
0x48, 0xb0, 0x11, 0xdb, 0x69, 0x4e, 0xb4, 0xf4, 0xf5, 0x3e, 0xe1, 0x9b, 0xca, 0x00, 0x04, 0xc8,
3362
0x9b, 0x69, 0xaf, 0xd1, 0xaf, 0x1f, 0xc2, 0xd7, 0x83, 0x0a, 0xb7, 0xf8, 0x4f, 0x24, 0x32, 0x8e,
3363
};
3364
static BYTE hashed256_secret[] =
3365
{
3366
0x1b, 0xe7, 0xbf, 0x0f, 0x65, 0x1e, 0xd0, 0x07, 0xf9, 0xf4, 0x77, 0x48, 0x48, 0x39, 0xd0, 0xf8,
3367
0xf3, 0xce, 0xfc, 0x89
3368
};
3369
3370
static BYTE ecc384privkey[] =
3371
{
3372
0x45, 0x43, 0x4b, 0x34, 0x30, 0x00, 0x00, 0x00,
3373
0xc9, 0xcb, 0x38, 0x54, 0xa1, 0xe2, 0xb6, 0x60, 0x13, 0xd9, 0x45, 0x0d, 0x76, 0x90, 0xf9, 0x49,
3374
0x75, 0x81, 0x76, 0xac, 0x43, 0x96, 0xc1, 0x04, 0x04, 0xda, 0x76, 0x72, 0xb1, 0x19, 0x38, 0xbd,
3375
0xaf, 0x96, 0x0c, 0x4e, 0xc3, 0x29, 0x67, 0x91, 0x6c, 0xac, 0xcc, 0x33, 0x51, 0x1f, 0x82, 0xd5,
3376
0x17, 0xbf, 0xa2, 0x94, 0xd7, 0x15, 0x4f, 0x83, 0xe7, 0xa3, 0xb8, 0x6d, 0xd0, 0x7f, 0xbc, 0x8a,
3377
0x30, 0x09, 0x9e, 0x13, 0xaa, 0x2e, 0xf6, 0xde, 0x1c, 0x02, 0x4a, 0x65, 0xf6, 0x72, 0xb3, 0xf0,
3378
0x4f, 0x7f, 0x1a, 0xce, 0x4e, 0x94, 0xc5, 0x98, 0x89, 0x74, 0xad, 0x51, 0x8f, 0x2b, 0x25, 0x17,
3379
0xdc, 0x4a, 0x54, 0x8a, 0x42, 0xda, 0x30, 0x1a, 0xe3, 0x6d, 0x77, 0x4d, 0x3b, 0x33, 0x9a, 0xe3,
3380
0x37, 0xd4, 0x06, 0x5b, 0xb3, 0x3f, 0x73, 0xb9, 0x7e, 0x0b, 0x37, 0x02, 0x8b, 0xed, 0x08, 0x10,
3381
0x03, 0xf8, 0x69, 0xe3, 0x2a, 0x4f, 0xbb, 0x20, 0x6c, 0x5d, 0x24, 0x09, 0x0d, 0xd9, 0x86, 0x32,
3382
};
3383
static BYTE ecdh384_pubkey[] =
3384
{
3385
0x45, 0x43, 0x4b, 0x33, 0x30, 0x00, 0x00, 0x00,
3386
0xd6, 0xc3, 0xef, 0x4a, 0xbb, 0x4c, 0xa2, 0x27, 0xa1, 0x96, 0x03, 0x3b, 0x0a, 0x83, 0x01, 0xff,
3387
0xeb, 0x9a, 0xf1, 0x06, 0xee, 0x83, 0xce, 0x7c, 0xaa, 0x6b, 0x7c, 0x43, 0x1c, 0x8b, 0x30, 0x82,
3388
0x99, 0x8f, 0xc4, 0x86, 0x0d, 0x19, 0x16, 0xb6, 0xab, 0xd1, 0x9f, 0xeb, 0xf9, 0x31, 0xda, 0xcd,
3389
0xb9, 0xf8, 0xea, 0x87, 0xa1, 0x36, 0xaf, 0x10, 0x98, 0x8f, 0x9b, 0xcc, 0x6c, 0xe3, 0x24, 0xb4,
3390
0x82, 0x37, 0xde, 0x1e, 0x04, 0x53, 0x03, 0xc0, 0x2a, 0x41, 0xe9, 0x50, 0x07, 0x87, 0xb2, 0x60,
3391
0xe6, 0x32, 0x53, 0x4c, 0x8e, 0xa7, 0x80, 0x0f, 0xad, 0x25, 0x3b, 0x01, 0xa4, 0xd6, 0xe3, 0x54,
3392
};
3393
static BYTE ecdh384_secret[] =
3394
{
3395
0x08, 0x8c, 0xd1, 0xfa, 0x57, 0xb6, 0xf9, 0x79, 0x9e, 0x0c, 0x71, 0xc3, 0xcb, 0xa5, 0xb1, 0xfd,
3396
0xde, 0xbc, 0x6d, 0x7c, 0x8a, 0x5b, 0x26, 0xe8, 0x18, 0x80, 0x61, 0x45, 0x6a, 0x38, 0xf9, 0x13,
3397
0x2a, 0x8f, 0x4b, 0xfe, 0x75, 0x02, 0x62, 0xe9, 0xb3, 0x6e, 0xc5, 0x52, 0xc9, 0x82, 0x38, 0x53,
3398
};
3399
static BYTE hashed384_secret[] =
3400
{
3401
0x78, 0xf8, 0x07, 0xab, 0x00, 0x35, 0xaa, 0x8c, 0x22, 0xd0, 0xe7, 0x06, 0xfc, 0x0b, 0x74, 0x41,
3402
0xed, 0xdc, 0x16, 0x6c,
3403
};
3404
3405
static BYTE ecc521privkey[] =
3406
{
3407
0x45, 0x43, 0x4b, 0x36, 0x42, 0x00, 0x00, 0x00,
3408
0x01, 0x96, 0xb0, 0x4e, 0x35, 0x6f, 0xbe, 0x00, 0xb6, 0xc3, 0x83, 0x53, 0x92, 0x18, 0xda, 0x86,
3409
0x9e, 0x4b, 0x0f, 0xb2, 0x0b, 0xc3, 0x9f, 0xd8, 0x9c, 0x18, 0x8a, 0x93, 0x5c, 0x91, 0xb2, 0x4f,
3410
0x56, 0x7d, 0x0e, 0xf7, 0xf4, 0xdf, 0x91, 0xc6, 0x74, 0x00, 0xc7, 0xb8, 0x59, 0xeb, 0x55, 0xc0,
3411
0xb5, 0x26, 0x7f, 0x6d, 0x49, 0x53, 0x02, 0x3b, 0x3c, 0xa0, 0x57, 0x1e, 0x1c, 0x7c, 0x5b, 0x08,
3412
0x23, 0x68, 0x01, 0x47, 0x4d, 0x47, 0xcf, 0x05, 0xfe, 0x18, 0x26, 0x81, 0x9d, 0xb4, 0x34, 0xfa,
3413
0x50, 0x7e, 0x03, 0x29, 0xa3, 0x6e, 0x90, 0x9c, 0x27, 0x69, 0x66, 0x2c, 0x70, 0x7b, 0xf9, 0xe7,
3414
0xef, 0xac, 0x27, 0xbf, 0x15, 0x86, 0xf6, 0xff, 0x2d, 0x99, 0x41, 0x9e, 0x36, 0x1f, 0xe9, 0x3a,
3415
0x99, 0x74, 0x54, 0xf3, 0xc3, 0x08, 0xb1, 0x00, 0x28, 0x84, 0x82, 0x84, 0xe3, 0xf4, 0x32, 0xfd,
3416
0x48, 0x67, 0xae, 0x08, 0x01, 0xe2, 0x08, 0x1d, 0xeb, 0x27, 0xc2, 0x98, 0x45, 0x8b, 0x33, 0x20,
3417
0x3b, 0x21, 0x5c, 0x7f, 0x56, 0xbd, 0xa5, 0x99, 0x58, 0xea, 0x19, 0xf8, 0xbc, 0xf1, 0x9e, 0x39,
3418
0x00, 0xb9, 0x2c, 0x2a, 0xb6, 0x19, 0x3a, 0xaf, 0xea, 0x4b, 0xa6, 0x22, 0xb4, 0x35, 0x09, 0x86,
3419
0x2e, 0x67, 0xe0, 0xfe, 0x81, 0x0e, 0x6a, 0x68, 0x6a, 0xb3, 0x32, 0x3b, 0xf8, 0x89, 0x45, 0x72,
3420
0x69, 0xf1, 0xe1, 0x84, 0xd7, 0xed,
3421
};
3422
static BYTE ecdh521_pubkey[] =
3423
{
3424
0x45, 0x43, 0x4b, 0x35, 0x42, 0x00, 0x00, 0x00,
3425
0x00, 0xfd, 0x72, 0xca, 0x31, 0x08, 0x76, 0xd9, 0x08, 0xb7, 0x26, 0x4a, 0x04, 0xbc, 0x73, 0x1a,
3426
0x04, 0xbb, 0x77, 0xf4, 0xe2, 0xfc, 0x3a, 0x88, 0x0a, 0xa8, 0x72, 0x8f, 0xfc, 0xe9, 0xe3, 0x5f,
3427
0x73, 0x05, 0xf1, 0x7f, 0x31, 0xee, 0x15, 0x91, 0x36, 0xe9, 0xeb, 0xed, 0xbe, 0x0e, 0x78, 0xa1,
3428
0x28, 0x4e, 0xc5, 0xcb, 0xba, 0xd8, 0x0c, 0x96, 0x75, 0x44, 0x71, 0x71, 0x00, 0x41, 0x43, 0xdf,
3429
0x27, 0x91, 0x00, 0x81, 0xcc, 0x56, 0x8d, 0x8e, 0x32, 0xae, 0x78, 0xfb, 0x3e, 0x84, 0x7b, 0x3b,
3430
0xf8, 0x8e, 0x7b, 0x27, 0x73, 0xa4, 0x11, 0x61, 0x24, 0x40, 0x9b, 0xbe, 0xd3, 0xc3, 0x0e, 0xbb,
3431
0x26, 0xae, 0x55, 0x58, 0xd1, 0xec, 0x14, 0xd3, 0x13, 0xf2, 0x6b, 0x2b, 0xc3, 0xf9, 0xa4, 0x50,
3432
0x9e, 0xce, 0xfe, 0x18, 0xa0, 0x8b, 0x10, 0x80, 0x68, 0x72, 0x2e, 0x5c, 0xa0, 0xb3, 0x01, 0x6b,
3433
0x43, 0x26, 0xad, 0x58,
3434
};
3435
static BYTE ecdh521_secret[] =
3436
{
3437
0x2d, 0xab, 0x9f, 0x38, 0x14, 0x5d, 0x49, 0x65, 0x06, 0x22, 0x04, 0xf9, 0xb3, 0x25, 0xca, 0xf9,
3438
0xe6, 0xdc, 0xc6, 0xe8, 0xf9, 0x0b, 0xbf, 0x3c, 0x9d, 0xf0, 0x08, 0x95, 0x92, 0xdd, 0x92, 0x8a,
3439
0x95, 0x85, 0xe8, 0x1c, 0x6d, 0x41, 0xb9, 0xe4, 0x7b, 0x7a, 0xa5, 0x68, 0x30, 0x48, 0x8e, 0xc0,
3440
0xbc, 0x2b, 0xc6, 0xe9, 0x75, 0x9c, 0xed, 0xc3, 0xf5, 0x3a, 0xa3, 0xd7, 0x41, 0xec, 0x28, 0x82,
3441
0xef, 0x01,
3442
};
3443
static BYTE hashed521_secret[] =
3444
{
3445
0x72, 0x39, 0x73, 0x5f, 0xc9, 0x26, 0x1f, 0x8e, 0xe3, 0x30, 0x11, 0xe1, 0x4f, 0xc4, 0x65, 0xc0,
3446
0xde, 0xf9, 0xe6, 0x6a,
3447
};
3448
3449
static const struct ecdh_test tests[] =
3450
{
3451
{
3452
BCRYPT_ECDH_P256_ALGORITHM, 256, ecc256privkey, sizeof(ecc256privkey), ecdh256_pubkey, sizeof(ecdh256_pubkey),
3453
ecdh256_secret, sizeof(ecdh256_secret), hashed256_secret,
3454
BCRYPT_ECDH_PUBLIC_P256_MAGIC, BCRYPT_ECDH_PRIVATE_P256_MAGIC,
3455
},
3456
{
3457
BCRYPT_ECDH_P384_ALGORITHM, 384, ecc384privkey, sizeof(ecc384privkey), ecdh384_pubkey, sizeof(ecdh384_pubkey),
3458
ecdh384_secret, sizeof(ecdh384_secret), hashed384_secret,
3459
BCRYPT_ECDH_PUBLIC_P384_MAGIC, BCRYPT_ECDH_PRIVATE_P384_MAGIC,
3460
},
3461
{
3462
BCRYPT_ECDH_P521_ALGORITHM, 521, ecc521privkey, sizeof(ecc521privkey), ecdh521_pubkey, sizeof(ecdh521_pubkey),
3463
ecdh521_secret, sizeof(ecdh521_secret), hashed521_secret,
3464
BCRYPT_ECDH_PUBLIC_P521_MAGIC, BCRYPT_ECDH_PRIVATE_P521_MAGIC,
3465
},
3466
};
3467
unsigned int i;
3468
3469
for (i = 0; i < ARRAY_SIZE(tests); ++i)
3470
{
3471
winetest_push_context("%s", debugstr_w(tests[i].alg));
3472
test_ECDH_alg(&tests[i]);
3473
winetest_pop_context();
3474
}
3475
3476
/* generic ECDH provider */
3477
status = BCryptOpenAlgorithmProvider(&alg, BCRYPT_ECDH_ALGORITHM, NULL, 0);
3478
if (status == STATUS_NOT_FOUND)
3479
{
3480
win_skip("generic ECDH provider not found\n");
3481
return;
3482
}
3483
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3484
3485
status = BCryptGenerateKeyPair(alg, &key, 0, 0);
3486
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3487
3488
status = BCryptFinalizeKeyPair(key, 0);
3489
ok(status == STATUS_INVALID_PARAMETER, "got %#lx\n", status);
3490
BCryptDestroyKey(key);
3491
BCryptCloseAlgorithmProvider(alg, 0);
3492
3493
status = BCryptOpenAlgorithmProvider(&alg, BCRYPT_ECDH_ALGORITHM, NULL, 0);
3494
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3495
3496
status = BCryptSetProperty(alg, BCRYPT_ECC_CURVE_NAME, (UCHAR *)BCRYPT_ECC_CURVE_SECP256R1, sizeof(BCRYPT_ECC_CURVE_SECP256R1), 0);
3497
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3498
3499
status = BCryptGenerateKeyPair(alg, &key, 255, 0);
3500
todo_wine ok(status == STATUS_INVALID_PARAMETER, "got %#lx\n", status);
3501
3502
status = BCryptGenerateKeyPair(alg, &key, 0, 0);
3503
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3504
3505
strength = 0;
3506
status = BCryptGetProperty(key, BCRYPT_KEY_STRENGTH, (UCHAR *)&strength, sizeof(strength), &size, 0);
3507
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3508
ok(strength == 256, "got %lu\n", strength);
3509
3510
status = BCryptFinalizeKeyPair(key, 0);
3511
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3512
BCryptDestroyKey(key);
3513
BCryptCloseAlgorithmProvider(alg, 0);
3514
}
3515
3516
static BYTE dh_pubkey[] =
3517
{
3518
/* BCRYPT_DH_KEY_BLOB */
3519
0x44, 0x48, 0x50, 0x42, 0x40, 0x00, 0x00, 0x00,
3520
/* p */
3521
0xcf, 0x18, 0xe9, 0xa9, 0xb3, 0x97, 0x59, 0xae, 0x0d, 0xac, 0xf0, 0x99, 0x39, 0xdc, 0xd2, 0xfe,
3522
0x1e, 0xf3, 0xfc, 0x2c, 0x49, 0xdf, 0x76, 0x89, 0xff, 0x13, 0x57, 0xc7, 0xe6, 0xbd, 0xed, 0xa7,
3523
0x42, 0xc0, 0xc3, 0xd7, 0x8e, 0x84, 0xa8, 0xdf, 0xcd, 0x52, 0x50, 0x81, 0x73, 0x8a, 0x33, 0x60,
3524
0xde, 0x6d, 0x56, 0xeb, 0xd5, 0xec, 0x1f, 0x9f, 0x9f, 0xd6, 0x2c, 0xe4, 0x8f, 0xab, 0x58, 0x0b,
3525
/* g */
3526
0x5f, 0xc5, 0x50, 0x9a, 0xde, 0xf6, 0x84, 0x48, 0x39, 0xa9, 0xa7, 0xb1, 0x73, 0x0c, 0x56, 0xd4,
3527
0x28, 0xbb, 0x12, 0x93, 0x51, 0x44, 0x33, 0xdf, 0xa6, 0xe7, 0x7f, 0x0b, 0x3f, 0xe9, 0x41, 0xef,
3528
0x32, 0x80, 0xcd, 0x8e, 0x2b, 0x38, 0x85, 0x49, 0x4d, 0x0c, 0xcc, 0x74, 0x02, 0x07, 0x92, 0xd3,
3529
0xe4, 0x3e, 0x37, 0x84, 0x27, 0x1f, 0xa3, 0xad, 0x94, 0x8c, 0xc1, 0xc2, 0x22, 0x99, 0x36, 0xf0,
3530
/* y */
3531
0x22, 0xaf, 0x98, 0xeb, 0xd9, 0xc4, 0xb5, 0xbd, 0xe1, 0xab, 0x19, 0x1b, 0xe3, 0x36, 0x20, 0xca,
3532
0xff, 0xe8, 0x6c, 0x30, 0x96, 0x3c, 0x90, 0x77, 0x0e, 0xe0, 0x96, 0xae, 0xb1, 0x47, 0xd1, 0x52,
3533
0x2c, 0xc3, 0x65, 0x5e, 0x9b, 0x41, 0x9a, 0xa6, 0xfe, 0xab, 0x54, 0xa0, 0xf0, 0x71, 0xab, 0x6c,
3534
0xd0, 0x0e, 0x01, 0x08, 0x5b, 0x66, 0xe5, 0x62, 0xd2, 0xe5, 0x5d, 0xae, 0x9c, 0x60, 0xb2, 0xc6,
3535
};
3536
3537
static BYTE dh_privkey[] =
3538
{
3539
/* BCRYPT_DH_KEY_BLOB */
3540
0x44, 0x48, 0x50, 0x56, 0x40, 0x00, 0x00, 0x00,
3541
/* p */
3542
0xcf, 0x18, 0xe9, 0xa9, 0xb3, 0x97, 0x59, 0xae, 0x0d, 0xac, 0xf0, 0x99, 0x39, 0xdc, 0xd2, 0xfe,
3543
0x1e, 0xf3, 0xfc, 0x2c, 0x49, 0xdf, 0x76, 0x89, 0xff, 0x13, 0x57, 0xc7, 0xe6, 0xbd, 0xed, 0xa7,
3544
0x42, 0xc0, 0xc3, 0xd7, 0x8e, 0x84, 0xa8, 0xdf, 0xcd, 0x52, 0x50, 0x81, 0x73, 0x8a, 0x33, 0x60,
3545
0xde, 0x6d, 0x56, 0xeb, 0xd5, 0xec, 0x1f, 0x9f, 0x9f, 0xd6, 0x2c, 0xe4, 0x8f, 0xab, 0x58, 0x0b,
3546
/* g */
3547
0x5f, 0xc5, 0x50, 0x9a, 0xde, 0xf6, 0x84, 0x48, 0x39, 0xa9, 0xa7, 0xb1, 0x73, 0x0c, 0x56, 0xd4,
3548
0x28, 0xbb, 0x12, 0x93, 0x51, 0x44, 0x33, 0xdf, 0xa6, 0xe7, 0x7f, 0x0b, 0x3f, 0xe9, 0x41, 0xef,
3549
0x32, 0x80, 0xcd, 0x8e, 0x2b, 0x38, 0x85, 0x49, 0x4d, 0x0c, 0xcc, 0x74, 0x02, 0x07, 0x92, 0xd3,
3550
0xe4, 0x3e, 0x37, 0x84, 0x27, 0x1f, 0xa3, 0xad, 0x94, 0x8c, 0xc1, 0xc2, 0x22, 0x99, 0x36, 0xf0,
3551
/* y */
3552
0x22, 0xaf, 0x98, 0xeb, 0xd9, 0xc4, 0xb5, 0xbd, 0xe1, 0xab, 0x19, 0x1b, 0xe3, 0x36, 0x20, 0xca,
3553
0xff, 0xe8, 0x6c, 0x30, 0x96, 0x3c, 0x90, 0x77, 0x0e, 0xe0, 0x96, 0xae, 0xb1, 0x47, 0xd1, 0x52,
3554
0x2c, 0xc3, 0x65, 0x5e, 0x9b, 0x41, 0x9a, 0xa6, 0xfe, 0xab, 0x54, 0xa0, 0xf0, 0x71, 0xab, 0x6c,
3555
0xd0, 0x0e, 0x01, 0x08, 0x5b, 0x66, 0xe5, 0x62, 0xd2, 0xe5, 0x5d, 0xae, 0x9c, 0x60, 0xb2, 0xc6,
3556
/* x */
3557
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3558
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3559
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x71, 0x3e, 0x82,
3560
0x8b, 0xea, 0x11, 0x77, 0xc4, 0xb4, 0x62, 0xc7, 0x4d, 0xff, 0x0f, 0x63, 0xd9, 0xe2, 0xda, 0xab,
3561
};
3562
3563
static BYTE dh_secret[] =
3564
{
3565
0x73, 0x84, 0x62, 0xc1, 0x9a, 0x9c, 0xc2, 0x91, 0x9f, 0xc1, 0xc2, 0x94, 0x0c, 0xa8, 0x2f, 0x58,
3566
0xac, 0x50, 0xcd, 0xd5, 0x29, 0x43, 0x41, 0x8e, 0x5d, 0xca, 0x73, 0x55, 0x4d, 0x46, 0x50, 0xe5,
3567
0xb7, 0x34, 0xa9, 0xcb, 0x3a, 0x18, 0x68, 0x99, 0x30, 0xef, 0x58, 0x26, 0xd3, 0x03, 0x61, 0x02,
3568
0x17, 0xb7, 0xba, 0x01, 0xbc, 0xae, 0xdf, 0x3f, 0xb5, 0xb5, 0x4a, 0xb0, 0x08, 0xe5, 0xea, 0xc3,
3569
};
3570
3571
static BYTE dh_hashed_secret[] =
3572
{
3573
0xa7, 0xfc, 0xff, 0x21, 0xb3, 0xd1, 0x46, 0xb8, 0x21, 0x3d, 0xc6, 0xd4, 0xe3, 0x61, 0x97, 0x5e,
3574
0xb5, 0x0a, 0xfe, 0x8f,
3575
};
3576
3577
BCryptBuffer dh_hash_param_buffers[] =
3578
{
3579
{
3580
sizeof(BCRYPT_SHA1_ALGORITHM),
3581
KDF_HASH_ALGORITHM,
3582
(void *)BCRYPT_SHA1_ALGORITHM,
3583
}
3584
};
3585
3586
BCryptBufferDesc dh_hash_params =
3587
{
3588
BCRYPTBUFFER_VERSION,
3589
ARRAY_SIZE(dh_hash_param_buffers),
3590
dh_hash_param_buffers,
3591
};
3592
3593
static void test_DH(void)
3594
{
3595
UCHAR hash[20];
3596
BCRYPT_KEY_HANDLE key, pubkey, privkey;
3597
BCRYPT_SECRET_HANDLE secret;
3598
BCRYPT_DH_KEY_BLOB *dhkey;
3599
NTSTATUS status;
3600
UCHAR *buf;
3601
ULONG size;
3602
3603
if (!pBCryptHash) /* < Win10 */
3604
{
3605
win_skip("broken DH detected\n");
3606
return;
3607
}
3608
3609
key = NULL;
3610
status = BCryptGenerateKeyPair(BCRYPT_DH_ALG_HANDLE, &key, 512, 0);
3611
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3612
ok(key != NULL, "key not set\n");
3613
3614
status = BCryptFinalizeKeyPair(key, 0);
3615
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3616
if (status != STATUS_SUCCESS)
3617
{
3618
BCryptDestroyKey(key);
3619
return;
3620
}
3621
3622
size = 0;
3623
status = BCryptExportKey(key, NULL, BCRYPT_DH_PUBLIC_BLOB, NULL, 0, &size, 0);
3624
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3625
ok(size, "size not set\n");
3626
3627
buf = malloc(size);
3628
status = BCryptExportKey(key, NULL, BCRYPT_DH_PUBLIC_BLOB, buf, size, &size, 0);
3629
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3630
dhkey = (BCRYPT_DH_KEY_BLOB *)buf;
3631
ok(dhkey->dwMagic == BCRYPT_DH_PUBLIC_MAGIC, "got %#lx\n", dhkey->dwMagic);
3632
ok(dhkey->cbKey == 64, "got %lu\n", dhkey->cbKey);
3633
ok(size == sizeof(*dhkey) + dhkey->cbKey * 3, "got %lu\n", size);
3634
3635
status = BCryptImportKeyPair(BCRYPT_DH_ALG_HANDLE, NULL, BCRYPT_DH_PUBLIC_BLOB, &pubkey, buf, size, 0);
3636
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3637
free(buf);
3638
BCryptDestroyKey(pubkey);
3639
3640
size = 0;
3641
status = BCryptExportKey(key, NULL, BCRYPT_DH_PRIVATE_BLOB, NULL, 0, &size, 0);
3642
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3643
ok(size == sizeof(*dhkey) + 64 * 4, "size not set\n");
3644
3645
buf = calloc(1, size);
3646
status = BCryptExportKey(key, NULL, BCRYPT_DH_PRIVATE_BLOB, buf, size, &size, 0);
3647
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3648
dhkey = (BCRYPT_DH_KEY_BLOB *)buf;
3649
ok(dhkey->dwMagic == BCRYPT_DH_PRIVATE_MAGIC, "got %#lx\n", dhkey->dwMagic);
3650
ok(dhkey->cbKey == 64, "got %lu\n", dhkey->cbKey);
3651
ok(size == sizeof(*dhkey) + dhkey->cbKey * 4, "got %lu\n", size);
3652
BCryptDestroyKey(key);
3653
3654
status = BCryptImportKeyPair(BCRYPT_DH_ALG_HANDLE, NULL, BCRYPT_DH_PRIVATE_BLOB, &privkey, buf, size, 0);
3655
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3656
free(buf);
3657
BCryptDestroyKey(privkey);
3658
3659
status = BCryptImportKeyPair(BCRYPT_DH_ALG_HANDLE, NULL, BCRYPT_DH_PRIVATE_BLOB, &privkey, dh_privkey,
3660
sizeof(dh_privkey), 0);
3661
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3662
3663
size = 0;
3664
status = BCryptExportKey(privkey, NULL, BCRYPT_DH_PRIVATE_BLOB, NULL, 0, &size, 0);
3665
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3666
ok(size, "size not set\n");
3667
3668
buf = malloc(size);
3669
status = BCryptExportKey(privkey, NULL, BCRYPT_DH_PRIVATE_BLOB, buf, size, &size, 0);
3670
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3671
ok(size == sizeof(dh_privkey), "got %lu\n", size);
3672
ok(!memcmp(buf, dh_privkey, size), "wrong data\n");
3673
free(buf);
3674
3675
status = BCryptImportKeyPair(BCRYPT_DH_ALG_HANDLE, NULL, BCRYPT_DH_PUBLIC_BLOB, &pubkey, dh_pubkey,
3676
sizeof(dh_pubkey), 0);
3677
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3678
3679
size = 0;
3680
status = BCryptExportKey(privkey, NULL, BCRYPT_DH_PUBLIC_BLOB, NULL, 0, &size, 0);
3681
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3682
ok(size, "size not set\n");
3683
3684
buf = malloc(size);
3685
status = BCryptExportKey(privkey, NULL, BCRYPT_DH_PUBLIC_BLOB, buf, size, &size, 0);
3686
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3687
ok(size == sizeof(dh_pubkey), "got %lu\n", size);
3688
ok(!memcmp(buf, dh_pubkey, size), "wrong data\n");
3689
free(buf);
3690
3691
status = BCryptSignHash(privkey, NULL, hash, sizeof(hash), NULL, 0, &size, 0);
3692
ok(status == STATUS_NOT_SUPPORTED, "got %#lx\n", status);
3693
3694
status = BCryptEncrypt(privkey, NULL, 0, NULL, NULL, 0, NULL, 0, &size, 0);
3695
ok(status == STATUS_NOT_SUPPORTED, "got %lx\n", status);
3696
3697
status = BCryptSecretAgreement(privkey, pubkey, &secret, 0);
3698
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3699
BCryptDestroyKey(pubkey);
3700
BCryptDestroyKey(privkey);
3701
3702
size = 0;
3703
status = BCryptDeriveKey(secret, BCRYPT_KDF_RAW_SECRET, NULL, NULL, 0, &size, 0);
3704
if (status == STATUS_NOT_SUPPORTED)
3705
{
3706
win_skip("BCRYPT_KDF_RAW_SECRET not supported\n"); /* < win10 */
3707
BCryptDestroySecret(secret);
3708
return;
3709
}
3710
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3711
ok(size == 64, "got %lu\n", size);
3712
3713
buf = calloc(1, size);
3714
status = BCryptDeriveKey(secret, BCRYPT_KDF_RAW_SECRET, NULL, buf, size, &size, 0);
3715
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3716
ok(!memcmp(dh_secret, buf, size), "wrong data\n");
3717
free(buf);
3718
3719
size = 0;
3720
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, NULL, NULL, 0, &size, 0);
3721
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3722
ok(size == 20, "got %lu\n", size);
3723
3724
size = 0;
3725
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &dh_hash_params, NULL, 0, &size, 0);
3726
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3727
ok(size == 20, "got %lu\n", size);
3728
3729
buf = calloc(1, size);
3730
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &dh_hash_params, buf, size, NULL, 0);
3731
ok(status == STATUS_INVALID_PARAMETER, "got %#lx\n", status);
3732
3733
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &dh_hash_params, buf, size, &size, 0);
3734
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3735
ok(!memcmp(dh_hashed_secret, buf, size), "wrong data\n");
3736
ok(size == 20, "got %lu\n", size);
3737
3738
memset(buf, 0, 20);
3739
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &dh_hash_params, buf, 10, &size, 0);
3740
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
3741
ok(!memcmp(dh_hashed_secret, buf, size), "wrong data\n");
3742
ok(size == 10, "got %lu\n", size);
3743
free(buf);
3744
3745
BCryptDestroySecret(secret);
3746
}
3747
3748
static void test_BCryptEnumContextFunctions(void)
3749
{
3750
CRYPT_CONTEXT_FUNCTIONS *buffer;
3751
NTSTATUS status;
3752
ULONG buflen;
3753
3754
buffer = NULL;
3755
status = BCryptEnumContextFunctions( CRYPT_LOCAL, L"SSL", NCRYPT_SCHANNEL_INTERFACE, &buflen, &buffer );
3756
todo_wine ok( status == STATUS_SUCCESS, "got %#lx\n", status);
3757
if (status == STATUS_SUCCESS) BCryptFreeBuffer( buffer );
3758
}
3759
3760
static BYTE rsapublic[] =
3761
{
3762
0x52, 0x53, 0x41, 0x31, 0x00, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3763
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0xd5, 0xfe, 0xf6, 0x7a, 0x9a, 0xa1, 0x2d, 0xcf, 0x98,
3764
0x60, 0xca, 0x38, 0x60, 0x0b, 0x74, 0x4c, 0x7e, 0xa1, 0x42, 0x64, 0xad, 0x05, 0xa5, 0x29, 0x25, 0xcb, 0xd5,
3765
0x9c, 0xaf, 0x6f, 0x63, 0x85, 0x6d, 0x5b, 0x59, 0xe5, 0x17, 0x8f, 0xf9, 0x18, 0x90, 0xa7, 0x63, 0xae, 0xe0,
3766
0x3a, 0x62, 0xf7, 0x98, 0x57, 0xe9, 0x91, 0xda, 0xfb, 0xd9, 0x36, 0x45, 0xe4, 0x9e, 0x75, 0xf6, 0x73, 0xc4,
3767
0x99, 0x23, 0x21, 0x1b, 0x3d, 0xe1, 0xe0, 0xa6, 0xa0, 0x4a, 0x50, 0x2a, 0xcb, 0x2a, 0x50, 0xf0, 0x8b, 0x70,
3768
0x9c, 0xe4, 0x1a, 0x14, 0x3b, 0xbe, 0x35, 0xa5, 0x5a, 0x91, 0xa3, 0xa1, 0x82, 0xea, 0x84, 0x4d, 0xe8, 0x62,
3769
0x3b, 0x11, 0xec, 0x61, 0x09, 0x6c, 0xfe, 0xb2, 0xcc, 0x4b, 0xa8, 0xff, 0xaf, 0x73, 0x72, 0x05, 0x4e, 0x7e,
3770
0xe5, 0x73, 0xdf, 0x24, 0xcf, 0x7f, 0x5d, 0xaf, 0x8a, 0xf0, 0xd8, 0xcb, 0x08, 0x1e, 0xf2, 0x36, 0x70, 0x8d,
3771
0x1b, 0x9e, 0xc8, 0x98, 0x60, 0x54, 0xeb, 0x45, 0x34, 0x21, 0x43, 0x4d, 0x42, 0x0a, 0x3a, 0x2d, 0x0f, 0x0e,
3772
0xd6, 0x0d, 0xe4, 0x2e, 0x8c, 0x31, 0x87, 0xa8, 0x09, 0x89, 0x61, 0x16, 0xca, 0x5b, 0xbe, 0x76, 0x69, 0xbb,
3773
0xfd, 0x91, 0x63, 0xd2, 0x66, 0x57, 0x08, 0xef, 0xe2, 0x40, 0x67, 0xd7, 0x7f, 0x50, 0x15, 0x42, 0x33, 0x97,
3774
0x54, 0x73, 0x47, 0xe7, 0x9c, 0x14, 0xa8, 0xb0, 0x3d, 0xc9, 0x23, 0xb0, 0x27, 0x3b, 0xe7, 0xdd, 0x5f, 0xd1,
3775
0x4f, 0x31, 0x10, 0x7d, 0xdd, 0x69, 0x8e, 0xde, 0xa3, 0xe8, 0x92, 0x00, 0xfa, 0xa5, 0xa4, 0x40, 0x51, 0x23,
3776
0x82, 0x84, 0xc7, 0xce, 0x19, 0x61, 0x26, 0xf1, 0xae, 0xf3, 0x90, 0x93, 0x98, 0x56, 0x23, 0x9a, 0xd1, 0xbd,
3777
0xf2, 0xdf, 0xfd, 0x13, 0x9c, 0x30, 0x07, 0xf9, 0x5a, 0x2e, 0x00, 0xc6, 0x1f
3778
};
3779
3780
static void test_BCryptSignHash(void)
3781
{
3782
static UCHAR hash[] =
3783
{0x7e,0xe3,0x74,0xe7,0xc5,0x0b,0x6b,0x70,0xdb,0xab,0x32,0x6d,0x1d,0x51,0xd6,0x74,0x79,0x8e,0x5b,0x4b};
3784
static UCHAR hash_sha256[] =
3785
{0x25,0x2f,0x10,0xc8,0x36,0x10,0xeb,0xca,0x1a,0x05,0x9c,0x0b,0xae,0x82,0x55,0xeb,0xa2,0xf9,0x5b,0xe4,
3786
0xd1,0xd7,0xbC,0xfA,0x89,0xd7,0x24,0x8a,0x82,0xd9,0xf1,0x11};
3787
BCRYPT_PKCS1_PADDING_INFO pad;
3788
BCRYPT_ALG_HANDLE alg;
3789
BCRYPT_KEY_HANDLE key;
3790
UCHAR sig[256];
3791
NTSTATUS ret;
3792
ULONG len;
3793
3794
/* RSA */
3795
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_RSA_ALGORITHM, NULL, 0);
3796
ok(!ret, "got %#lx\n", ret);
3797
3798
/* public key */
3799
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_RSAPUBLIC_BLOB, &key, rsapublic, sizeof(rsapublic), 0);
3800
ok(!ret, "got %#lx\n", ret);
3801
3802
len = 0;
3803
pad.pszAlgId = BCRYPT_SHA1_ALGORITHM;
3804
ret = BCryptSignHash(key, &pad, NULL, 0, NULL, 0, &len, BCRYPT_PAD_PKCS1);
3805
ok(!ret, "got %#lx\n", ret);
3806
ok(len == 256, "got %lu\n", len);
3807
3808
/* test len return when only output is NULL, as described in BCryptSignHash doc */
3809
ret = BCryptSignHash(key, &pad, hash, sizeof(hash), NULL, 0, &len, BCRYPT_PAD_PKCS1);
3810
ok(!ret, "got %#lx\n", ret);
3811
ok(len == 256, "got %lu\n", len);
3812
3813
len = 0;
3814
ret = BCryptSignHash(key, &pad, hash, sizeof(hash), sig, sizeof(sig), &len, BCRYPT_PAD_PKCS1);
3815
ok(ret == STATUS_INVALID_PARAMETER || broken(ret == STATUS_INTERNAL_ERROR) /* < win7 */, "got %#lx\n", ret);
3816
ret = BCryptDestroyKey(key);
3817
ok(!ret, "got %#lx\n", ret);
3818
3819
ret = BCryptGenerateKeyPair(alg, &key, 512, 0);
3820
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3821
3822
ret = BCryptFinalizeKeyPair(key, 0);
3823
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3824
3825
ret = BCryptFinalizeKeyPair(key, 0);
3826
ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret);
3827
3828
len = 0;
3829
memset(sig, 0, sizeof(sig));
3830
3831
/* inference of padding info on RSA not supported */
3832
ret = BCryptSignHash(key, NULL, hash, sizeof(hash), sig, sizeof(sig), &len, 0);
3833
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
3834
3835
ret = BCryptSignHash(key, &pad, hash, sizeof(hash), sig, 0, &len, BCRYPT_PAD_PKCS1);
3836
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret);
3837
3838
ret = BCryptSignHash(key, &pad, hash, sizeof(hash), sig, sizeof(sig), &len, BCRYPT_PAD_PKCS1);
3839
ok(!ret, "got %#lx\n", ret);
3840
ok(len == 64, "got %lu\n", len);
3841
3842
ret = BCryptVerifySignature(key, &pad, hash, sizeof(hash), sig, len, BCRYPT_PAD_PKCS1);
3843
ok(!ret, "got %#lx\n", ret);
3844
3845
ret = BCryptDestroyKey(key);
3846
ok(!ret, "got %#lx\n", ret);
3847
3848
ret = BCryptCloseAlgorithmProvider(alg, 0);
3849
ok(!ret, "got %#lx\n", ret);
3850
3851
/* ECDSA */
3852
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_ECDSA_P256_ALGORITHM, NULL, 0);
3853
ok(!ret, "got %#lx\n", ret);
3854
3855
ret = BCryptGenerateKeyPair(alg, &key, 256, 0);
3856
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3857
3858
ret = BCryptFinalizeKeyPair(key, 0);
3859
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3860
3861
memset(sig, 0, sizeof(sig));
3862
len = 0;
3863
3864
/* automatically detects padding info */
3865
ret = BCryptSignHash(key, NULL, hash, sizeof(hash), sig, sizeof(sig), &len, 0);
3866
ok (!ret, "got %#lx\n", ret);
3867
ok (len == 64, "got %lu\n", len);
3868
3869
ret = BCryptVerifySignature(key, NULL, hash, sizeof(hash), sig, len, 0);
3870
ok(!ret, "got %#lx\n", ret);
3871
3872
/* mismatch info (SHA-1 != SHA-256) */
3873
ret = BCryptSignHash(key, &pad, hash_sha256, sizeof(hash_sha256), sig, sizeof(sig), &len, BCRYPT_PAD_PKCS1);
3874
ok (ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
3875
3876
ret = BCryptDestroyKey(key);
3877
ok(!ret, "got %#lx\n", ret);
3878
3879
ret = BCryptCloseAlgorithmProvider(alg, 0);
3880
ok(!ret, "got %#lx\n", ret);
3881
3882
/* ECDSA P521 */
3883
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_ECDSA_P521_ALGORITHM, NULL, 0);
3884
ok(!ret, "got %#lx\n", ret);
3885
3886
ret = BCryptGenerateKeyPair(alg, &key, 256, 0);
3887
todo_wine ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
3888
ret = BCryptGenerateKeyPair(alg, &key, 522, 0);
3889
todo_wine ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
3890
3891
ret = BCryptGenerateKeyPair(alg, &key, 521, 0);
3892
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3893
ret = BCryptFinalizeKeyPair(key, 0);
3894
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
3895
len = 0;
3896
ret = BCryptSignHash(key, NULL, hash, sizeof(hash), sig, sizeof(sig), &len, 0);
3897
ok (!ret, "got %#lx\n", ret);
3898
ok (len == 132, "got %lu\n", len);
3899
3900
ret = BCryptVerifySignature(key, NULL, hash, sizeof(hash), sig, len, 0);
3901
ok(!ret, "got %#lx\n", ret);
3902
3903
ret = BCryptDestroyKey(key);
3904
ok(!ret, "got %#lx\n", ret);
3905
ret = BCryptCloseAlgorithmProvider(alg, 0);
3906
ok(!ret, "got %#lx\n", ret);
3907
}
3908
3909
static void test_BCryptEnumAlgorithms(void)
3910
{
3911
BCRYPT_ALGORITHM_IDENTIFIER *list;
3912
NTSTATUS ret;
3913
ULONG count, op;
3914
3915
ret = BCryptEnumAlgorithms(0, NULL, NULL, 0);
3916
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
3917
3918
ret = BCryptEnumAlgorithms(0, &count, NULL, 0);
3919
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
3920
3921
ret = BCryptEnumAlgorithms(0, NULL, &list, 0);
3922
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
3923
3924
ret = BCryptEnumAlgorithms(~0u, &count, &list, 0);
3925
ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
3926
3927
count = 0;
3928
list = NULL;
3929
ret = BCryptEnumAlgorithms(0, &count, &list, 0);
3930
ok(!ret, "got %#lx\n", ret);
3931
ok(list != NULL, "NULL list\n");
3932
ok(count, "got %lu\n", count);
3933
BCryptFreeBuffer( list );
3934
3935
op = BCRYPT_CIPHER_OPERATION | BCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION | BCRYPT_SIGNATURE_OPERATION |
3936
BCRYPT_SECRET_AGREEMENT_OPERATION;
3937
count = 0;
3938
list = NULL;
3939
ret = BCryptEnumAlgorithms(op, &count, &list, 0);
3940
ok(!ret, "got %#lx\n", ret);
3941
ok(list != NULL, "NULL list\n");
3942
ok(count, "got %lu\n", count);
3943
BCryptFreeBuffer( list );
3944
}
3945
3946
static void test_aes_vector(void)
3947
{
3948
static const UCHAR secret[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10};
3949
static const UCHAR expect[] = {0xb0,0xcb,0xf5,0x80,0xd4,0xe3,0x55,0x23,0x6e,0x19,0x5b,0xdb,0xfe,0xe0,0x6c,0xd3};
3950
static const UCHAR expect2[] = {0x06,0x0c,0x81,0xab,0xd4,0x28,0x80,0x42,0xce,0x30,0x56,0x17,0x15,0x00,0x9e,0xc1};
3951
static const UCHAR expect3[] = {0x3e,0x99,0xbf,0x02,0xf5,0xd3,0xb8,0x81,0x91,0x4d,0x93,0xea,0xd4,0x92,0x93,0x46};
3952
static UCHAR iv[16], input[] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'};
3953
UCHAR output[16];
3954
BCRYPT_ALG_HANDLE alg;
3955
BCRYPT_KEY_HANDLE key;
3956
UCHAR data[sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + sizeof(secret)];
3957
BCRYPT_KEY_DATA_BLOB_HEADER *blob = (BCRYPT_KEY_DATA_BLOB_HEADER *)data;
3958
ULONG size;
3959
NTSTATUS ret;
3960
3961
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_AES_ALGORITHM, NULL, 0);
3962
ok(!ret, "got %#lx\n", ret);
3963
3964
size = sizeof(BCRYPT_CHAIN_MODE_CBC);
3965
ret = BCryptSetProperty(alg, BCRYPT_CHAINING_MODE, (UCHAR *)BCRYPT_CHAIN_MODE_CBC, size, 0);
3966
ok(!ret, "got %#lx\n", ret);
3967
3968
blob->dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC;
3969
blob->dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1;
3970
blob->cbKeyData = sizeof(secret);
3971
memcpy(data + sizeof(*blob), secret, sizeof(secret));
3972
size = sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + sizeof(secret);
3973
ret = BCryptImportKey(alg, NULL, BCRYPT_KEY_DATA_BLOB, &key, NULL, 0, data, size, 0);
3974
ok(!ret, "got %#lx\n", ret);
3975
3976
/* zero initialization vector */
3977
size = 0;
3978
memset(output, 0, sizeof(output));
3979
ret = BCryptEncrypt(key, input, sizeof(input), NULL, iv, sizeof(iv), output, sizeof(output), &size, 0);
3980
ok(!ret, "got %#lx\n", ret);
3981
ok(size == 16, "got %lu\n", size);
3982
ok(!memcmp(output, expect, sizeof(expect)), "wrong cipher text\n");
3983
3984
/* same initialization vector */
3985
size = 0;
3986
memset(output, 0, sizeof(output));
3987
ret = BCryptEncrypt(key, input, sizeof(input), NULL, iv, sizeof(iv), output, sizeof(output), &size, 0);
3988
ok(!ret, "got %#lx\n", ret);
3989
ok(size == 16, "got %lu\n", size);
3990
ok(!memcmp(output, expect2, sizeof(expect2)), "wrong cipher text\n");
3991
3992
/* different initialization vector */
3993
iv[0] = 0x1;
3994
size = 0;
3995
memset(output, 0, sizeof(output));
3996
ret = BCryptEncrypt(key, input, sizeof(input), NULL, iv, sizeof(iv), output, sizeof(output), &size, 0);
3997
ok(!ret, "got %#lx\n", ret);
3998
ok(size == 16, "got %lu\n", size);
3999
ok(!memcmp(output, expect3, sizeof(expect3)), "wrong cipher text\n");
4000
4001
ret = BCryptDestroyKey(key);
4002
ok(!ret, "got %#lx\n", ret);
4003
4004
ret = BCryptCloseAlgorithmProvider(alg, 0);
4005
ok(!ret, "got %#lx\n", ret);
4006
}
4007
4008
static void test_BcryptDeriveKeyCapi(void)
4009
{
4010
static const UCHAR expect[] =
4011
{0xda,0x39,0xa3,0xee,0x5e,0x6b,0x4b,0x0d,0x32,0x55,0xbf,0xef,0x95,0x60,0x18,0x90,0xaf,0xd8,0x07,0x09};
4012
static const UCHAR expect2[] =
4013
{0x9b,0x03,0x17,0x41,0xf4,0x75,0x11,0xac,0xff,0x22,0xee,0x40,0xbb,0xe8,0xf9,0x74,0x17,0x26,0xb6,0xf2,
4014
0xf8,0xc7,0x88,0x02,0x9a,0xdc,0x0d,0xd7,0x83,0x58,0xea,0x65,0x2e,0x8b,0x85,0xc6,0xdb,0xb7,0xed,0x1c};
4015
BCRYPT_ALG_HANDLE alg;
4016
BCRYPT_HASH_HANDLE hash;
4017
UCHAR key[40];
4018
NTSTATUS ret;
4019
4020
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA1_ALGORITHM, NULL, 0);
4021
ok(!ret, "got %#lx\n", ret);
4022
4023
ret = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0);
4024
ok(!ret, "got %#lx\n", ret);
4025
4026
ret = BCryptDeriveKeyCapi(NULL, NULL, NULL, 0, 0);
4027
ok(ret == STATUS_INVALID_PARAMETER || ret == STATUS_INVALID_HANDLE /* win7 */, "got %#lx\n", ret);
4028
4029
ret = BCryptDeriveKeyCapi(hash, NULL, NULL, 0, 0);
4030
ok(ret == STATUS_INVALID_PARAMETER || !ret /* win7 */, "got %#lx\n", ret);
4031
4032
ret = BCryptDestroyHash(hash);
4033
ok(!ret, "got %#lx\n", ret);
4034
4035
ret = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0);
4036
ok(!ret, "got %#lx\n", ret);
4037
4038
ret = BCryptDeriveKeyCapi(hash, NULL, key, 0, 0);
4039
ok(ret == STATUS_INVALID_PARAMETER || !ret /* win7 */, "got %#lx\n", ret);
4040
4041
ret = BCryptDestroyHash(hash);
4042
ok(!ret, "got %#lx\n", ret);
4043
4044
ret = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0);
4045
ok(!ret, "got %#lx\n", ret);
4046
4047
memset(key, 0, sizeof(key));
4048
ret = BCryptDeriveKeyCapi(hash, NULL, key, 41, 0);
4049
ok(ret == STATUS_INVALID_PARAMETER || !ret /* win7 */, "got %#lx\n", ret);
4050
if (!ret)
4051
ok(!memcmp(key, expect, sizeof(expect) - 1), "wrong key data\n");
4052
4053
ret = BCryptDestroyHash(hash);
4054
ok(!ret, "got %#lx\n", ret);
4055
4056
ret = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0);
4057
ok(!ret, "got %#lx\n", ret);
4058
4059
memset(key, 0, sizeof(key));
4060
ret = BCryptDeriveKeyCapi(hash, NULL, key, 20, 0);
4061
ok(!ret, "got %#lx\n", ret);
4062
ok(!memcmp(key, expect, sizeof(expect) - 1), "wrong key data\n");
4063
4064
ret = BCryptDeriveKeyCapi(hash, NULL, key, 20, 0);
4065
todo_wine ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret);
4066
4067
ret = BCryptHashData(hash, NULL, 0, 0);
4068
todo_wine ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret);
4069
4070
ret = BCryptDestroyHash(hash);
4071
ok(!ret, "got %#lx\n", ret);
4072
4073
ret = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0);
4074
ok(!ret, "got %#lx\n", ret);
4075
4076
ret = BCryptHashData(hash, (UCHAR *)"test", 4, 0);
4077
ok(!ret, "got %#lx\n", ret);
4078
4079
/* padding */
4080
memset(key, 0, sizeof(key));
4081
ret = BCryptDeriveKeyCapi(hash, NULL, key, 40, 0);
4082
ok(!ret, "got %#lx\n", ret);
4083
ok(!memcmp(key, expect2, sizeof(expect2) - 1), "wrong key data\n");
4084
4085
ret = BCryptCloseAlgorithmProvider(alg, 0);
4086
ok(!ret, "got %#lx\n", ret);
4087
}
4088
4089
static UCHAR dsaHash[] =
4090
{
4091
0x7e,0xe3,0x74,0xe7,0xc5,0x0b,0x6b,0x70,0xdb,0xab,0x32,0x6d,0x1d,0x51,0xd6,0x74,0x79,0x8e,0x5b,0x4b
4092
};
4093
4094
static UCHAR dsaSignature[] =
4095
{
4096
0x5f,0x95,0x1f,0x08,0x19,0x44,0xa5,0xab,0x28,0x11,0x51,0x68,0x82,0x9b,0xe4,0xc3,0x04,0x1b,0xc9,0xdc,
4097
0x41,0x2a,0x89,0xd4,0x4a,0x8b,0x86,0xaf,0x98,0x2c,0x59,0x0b,0xd2,0x88,0xf6,0xe8,0x29,0x13,0x84,0x49
4098
};
4099
4100
static UCHAR dsaPublicBlob[] =
4101
{
4102
0x44,0x53,0x50,0x42,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x8f,0xd2,0x92,0xbb,0x92,0xb9,0x00,0xc5,0xed,
4103
0x52,0xcc,0x48,0x4a,0x44,0x1d,0xd3,0x74,0xfb,0x75,0xd1,0x7e,0xb6,0x24,0x9b,0x5d,0x57,0x0a,0x8a,0xc4,
4104
0x5d,0xab,0x9c,0x26,0x86,0xc6,0x25,0x16,0x20,0xf9,0xa9,0x71,0xbc,0x1d,0x30,0xc4,0xef,0x8c,0xc4,0xdf,
4105
0x1a,0xaf,0x96,0xdf,0x90,0xd8,0x85,0x9d,0xf9,0x2c,0x86,0x8c,0x91,0x39,0x6c,0x6d,0x11,0x4e,0x53,0x63,
4106
0x2a,0x2b,0x26,0xa7,0xf9,0x76,0x74,0x51,0xbf,0x08,0x87,0x6f,0xe0,0x71,0x91,0x24,0x8a,0xc2,0x84,0x2d,
4107
0x84,0x9c,0x5f,0x94,0xaa,0x38,0x53,0x77,0x84,0xba,0xbc,0xff,0x49,0x3a,0x08,0x0f,0x38,0xb5,0x91,0x5c,
4108
0x06,0x15,0xa4,0x27,0xf4,0xa5,0x59,0xaa,0x1c,0x41,0xa3,0xa0,0xbb,0xf7,0x32,0x86,0xfb,0x94,0x41,0xff,
4109
0xcd,0xed,0x69,0xeb,0xc6,0x5e,0xb6,0xa8,0x15,0x82,0x3b,0x60,0x1e,0x91,0x55,0xd5,0x2c,0xa5,0x74,0x5a,
4110
0x65,0x8f,0xc6,0x56,0xc4,0x3f,0x4e,0xe3,0x3a,0x71,0xb2,0x63,0x66,0xa4,0x0d,0x0d,0xf9,0xdd,0x1e,0x48,
4111
0x81,0xe9,0xbf,0x8f,0xbb,0x85,0x47,0x81,0x68,0x11,0xb5,0x91,0x6b,0xc4,0x05,0xef,0xa3,0xc7,0xbf,0x26,
4112
0x53,0x4f,0xc4,0x10,0xfd,0xfa,0xed,0x61,0x64,0xd6,0x2e,0xad,0x04,0x3e,0x82,0xed,0xb2,0x22,0x76,0xd0,
4113
0x44,0xad,0xc1,0x4c,0xde,0x33,0xa3,0x61,0x55,0xec,0x24,0xe5,0x79,0x45,0xcf,0x94,0x39,0x92,0x9f,0xd8,
4114
0x24,0xce,0x85,0xb9
4115
};
4116
4117
static UCHAR dssKey[] =
4118
{
4119
0x07,0x02,0x00,0x00,0x00,0x22,0x00,0x00,0x44,0x53,0x53,0x32,0x00,0x04,0x00,0x00,0x01,0xd1,0xfc,0x7a,
4120
0x70,0x53,0xb2,0x48,0x70,0x23,0x19,0x1f,0x3c,0xe1,0x26,0x14,0x7e,0x9f,0x0f,0x7f,0x33,0x5e,0x2b,0xf7,
4121
0xca,0x01,0x74,0x8c,0xb4,0xfd,0xf6,0x44,0x95,0x35,0x56,0xaa,0x4d,0x62,0x48,0xe2,0xd1,0xa2,0x7e,0x6e,
4122
0xeb,0xd6,0xcc,0x7c,0xe8,0xfd,0x21,0x9a,0xa2,0xfd,0x7a,0x9d,0x1a,0x38,0x69,0x87,0x39,0x5a,0x91,0xc0,
4123
0x52,0x2b,0x9f,0x2a,0x54,0x78,0x37,0x82,0x9a,0x70,0x57,0xab,0xec,0x93,0x8e,0xac,0x73,0x04,0xe8,0x53,
4124
0x72,0x72,0x32,0xc6,0xcb,0xef,0x47,0x98,0x3c,0x56,0x49,0x62,0xcb,0xbb,0xe7,0x34,0x84,0xa6,0x72,0x3a,
4125
0xbe,0x26,0x46,0x86,0xca,0xcb,0x35,0x62,0x4f,0x19,0x18,0x0b,0xb0,0x78,0xae,0xd5,0x42,0xdf,0x26,0xdb,
4126
0x85,0x63,0x77,0x85,0x01,0x3b,0x32,0xbe,0x5c,0xf8,0x05,0xc8,0xde,0x17,0x7f,0xb9,0x03,0x82,0xfa,0xf1,
4127
0x9e,0x32,0x73,0xfa,0x8d,0xea,0xa3,0x30,0x48,0xe2,0xdf,0x5a,0xcb,0x83,0x3d,0xff,0x56,0xe9,0xc0,0x94,
4128
0xf8,0x6d,0xb3,0xaf,0x4a,0x97,0xb9,0x43,0x0e,0xd4,0x28,0x98,0x57,0x2e,0x3a,0xca,0xde,0x6f,0x45,0x0d,
4129
0xfb,0x58,0xec,0x78,0x34,0x2e,0x46,0x4d,0xfe,0x98,0x02,0xbb,0xef,0x07,0x1a,0x13,0xb6,0xc2,0x2c,0x06,
4130
0xd9,0x0c,0xc4,0xb0,0x4c,0x3a,0xfc,0x01,0x63,0xb5,0x5a,0x5d,0x2d,0x9c,0x47,0x04,0x67,0x51,0xf2,0x52,
4131
0xf5,0x82,0x36,0xeb,0x6e,0x66,0x58,0x4c,0x10,0x2c,0x29,0x72,0x4a,0x6f,0x6b,0x6c,0xe0,0x93,0x31,0x42,
4132
0xf6,0xda,0xfa,0x5b,0x22,0x43,0x9b,0x1a,0x98,0x71,0xe7,0x41,0x74,0xe9,0x12,0xa4,0x1f,0x27,0x0a,0x63,
4133
0x94,0x49,0xd7,0xad,0xa5,0xc4,0x5c,0xc3,0xc9,0x70,0xb3,0x7b,0x16,0xb6,0x1d,0xd4,0x09,0xc4,0x9a,0x46,
4134
0x2d,0x0e,0x75,0x07,0x31,0x7b,0xed,0x45,0xcd,0x99,0x84,0x14,0xf1,0x01,0x00,0x00,0x93,0xd5,0xa3,0xe4,
4135
0x34,0x05,0xeb,0x98,0x3b,0x5f,0x2f,0x11,0xa4,0xa5,0xc4,0xff,0xfb,0x22,0x7c,0x54
4136
};
4137
4138
static void test_DSA(void)
4139
{
4140
BCRYPT_ALG_HANDLE alg;
4141
BCRYPT_KEY_HANDLE key;
4142
BCRYPT_DSA_KEY_BLOB *dsablob;
4143
UCHAR sig[40], schemes;
4144
ULONG len, size;
4145
NTSTATUS ret;
4146
BYTE *buf, buf2[sizeof(BCRYPT_DSA_KEY_BLOB) + sizeof(dsaPublicBlob)];
4147
4148
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_DSA_ALGORITHM, NULL, 0);
4149
ok(!ret, "got %#lx\n", ret);
4150
4151
ret = BCryptGetProperty(alg, L"PaddingSchemes", (UCHAR *)&schemes, sizeof(schemes), &size, 0);
4152
ok(ret == STATUS_NOT_SUPPORTED, "got %#lx\n", ret);
4153
4154
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_PUBLIC_KEY_BLOB, &key, dsaPublicBlob, sizeof(dsaPublicBlob), 0);
4155
ok(!ret, "got %#lx\n", ret);
4156
BCryptDestroyKey(key);
4157
4158
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_DSA_PUBLIC_BLOB, &key, dsaPublicBlob, sizeof(dsaPublicBlob), 0);
4159
ok(!ret, "got %#lx\n", ret);
4160
4161
memset(buf2, 0xcc, sizeof(buf2));
4162
ret = BCryptExportKey(key, NULL, BCRYPT_DSA_PUBLIC_BLOB, buf2, sizeof(buf2), &size, 0);
4163
ok(!ret, "got %#lx\n", ret);
4164
dsablob = (BCRYPT_DSA_KEY_BLOB *)buf2;
4165
ok(dsablob->dwMagic == BCRYPT_DSA_PUBLIC_MAGIC, "got %#lx\n", dsablob->dwMagic);
4166
ok(dsablob->cbKey == 64, "got %lu\n", dsablob->cbKey);
4167
ok(size == sizeof(*dsablob) + dsablob->cbKey * 3, "got %lu\n", size);
4168
4169
ret = BCryptExportKey(key, NULL, BCRYPT_DSA_PRIVATE_BLOB, buf2, sizeof(buf2), &size, 0);
4170
todo_wine ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
4171
4172
ret = BCryptVerifySignature(key, NULL, dsaHash, sizeof(dsaHash), dsaSignature, sizeof(dsaSignature), 0);
4173
ok(!ret, "got %#lx\n", ret);
4174
4175
ret = BCryptDestroyKey(key);
4176
ok(!ret, "got %#lx\n", ret);
4177
4178
/* sign/verify with export/import round-trip */
4179
ret = BCryptGenerateKeyPair(alg, &key, 512, 0);
4180
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
4181
4182
ret = BCryptFinalizeKeyPair(key, 0);
4183
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
4184
4185
len = 0;
4186
memset(sig, 0, sizeof(sig));
4187
ret = BCryptSignHash(key, NULL, dsaHash, sizeof(dsaHash), sig, sizeof(sig), &len, 0);
4188
ok(!ret, "got %#lx\n", ret);
4189
ok(len == 40, "got %lu\n", len);
4190
4191
size = 0;
4192
ret = BCryptExportKey(key, NULL, BCRYPT_DSA_PUBLIC_BLOB, NULL, 0, &size, 0);
4193
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
4194
ok(size, "size not set\n");
4195
4196
buf = calloc(1, size);
4197
ret = BCryptExportKey(key, NULL, BCRYPT_DSA_PUBLIC_BLOB, buf, size, &size, 0);
4198
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
4199
dsablob = (BCRYPT_DSA_KEY_BLOB *)buf;
4200
ok(dsablob->dwMagic == BCRYPT_DSA_PUBLIC_MAGIC, "got %#lx\n", dsablob->dwMagic);
4201
ok(dsablob->cbKey == 64, "got %lu\n", dsablob->cbKey);
4202
ok(size == sizeof(*dsablob) + dsablob->cbKey * 3, "got %lu\n", size);
4203
4204
ret = BCryptDestroyKey(key);
4205
ok(!ret, "got %#lx\n", ret);
4206
4207
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_DSA_PUBLIC_BLOB, &key, buf, size, 0);
4208
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
4209
free(buf);
4210
4211
ret = BCryptVerifySignature(key, NULL, dsaHash, sizeof(dsaHash), sig, len, 0);
4212
ok(!ret, "got %#lx\n", ret);
4213
ret = BCryptDestroyKey(key);
4214
ok(!ret, "got %#lx\n", ret);
4215
4216
ret = BCryptImportKeyPair(alg, NULL, LEGACY_DSA_V2_PRIVATE_BLOB, &key, dssKey, sizeof(dssKey), 0);
4217
ok(!ret, "got %#lx\n", ret);
4218
4219
size = 0;
4220
ret = BCryptExportKey(key, NULL, LEGACY_DSA_V2_PRIVATE_BLOB, NULL, 0, &size, 0);
4221
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
4222
ok(size, "size not set\n");
4223
4224
buf = calloc(1, size);
4225
ret = BCryptExportKey(key, NULL, LEGACY_DSA_V2_PRIVATE_BLOB, buf, size, &size, 0);
4226
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
4227
ok(size == sizeof(dssKey), "got %lu expected %Iu\n", size, sizeof(dssKey));
4228
ok(!memcmp(dssKey, buf, size), "wrong data\n");
4229
free(buf);
4230
4231
ret = BCryptDestroyKey(key);
4232
ok(!ret, "got %#lx\n", ret);
4233
4234
ret = BCryptCloseAlgorithmProvider(alg, 0);
4235
ok(!ret, "got %#lx\n", ret);
4236
}
4237
4238
static void test_SecretAgreement(void)
4239
{
4240
static BCryptBuffer hash_param_buffers[] =
4241
{
4242
{
4243
sizeof(BCRYPT_SHA256_ALGORITHM),
4244
KDF_HASH_ALGORITHM,
4245
(void *)BCRYPT_SHA256_ALGORITHM,
4246
}
4247
};
4248
static BCryptBufferDesc hash_params =
4249
{
4250
BCRYPTBUFFER_VERSION,
4251
ARRAY_SIZE(hash_param_buffers),
4252
hash_param_buffers,
4253
};
4254
4255
static const ULONG dh_private_key[] =
4256
{
4257
0xc4caf69c, 0x57b4db27, 0x36f7135f, 0x5ccba686, 0xc37b8819, 0x1d35c9b2, 0xbb07a1cf, 0x0c5d1c1b,
4258
0xc79acb10, 0x31dfdabb, 0x702e02b9, 0x1efab345, 0x262a8074, 0x5edf7698, 0x9b9dc630, 0x13c34b93,
4259
0xacbc928b, 0xb79eed8c, 0x7413dce9, 0xa5521280, 0x88d8e695, 0xa310269f, 0xca7c5719, 0xcd0c775b,
4260
0x9a6e2cf2, 0x9e235c51, 0xf49db62d, 0x28e72424, 0x4a44da5a, 0x3d98268d, 0x8e4d2be3, 0x254e44e6,
4261
4262
0x18a67e55, 0x572e13a1, 0x46f81ca8, 0xc331c9b9, 0xf8fe3dd4, 0x8a889e5a, 0x6c0505fd, 0xbd97a121,
4263
0xed2dbd67, 0xf39efa8e, 0x36f9c287, 0xf6bbfa6c, 0x461e42ad, 0x17dc170e, 0xc002dc2e, 0x4813d9a4,
4264
0x0b6fabb8, 0x6a9e1860, 0xa8a8cbd9, 0xb7ed6b5d, 0xabb34d23, 0xf2fbe1fd, 0x8670df1e, 0xba7fa4e6,
4265
0xf7039712, 0x94448f30, 0xe10c812e, 0x3e311976, 0xcfdd72c4, 0xbdbea98f, 0xc9a540d6, 0x89646d57,
4266
4267
0x7ab63b33, 0x03a1e9b6, 0x947f7a9b, 0x5ae59eeb, 0x1d12eb05, 0x3f425d92, 0xe028c6ba, 0xbf90ddc9,
4268
0xb554f55a, 0x7aeb88b6, 0x4a443a5f, 0xbab35111, 0x82c78a0c, 0x298dd482, 0x02937cb1, 0xc94cdc2e,
4269
0x59b010eb, 0x3bbc0a2b, 0xd845fee0, 0x04c1d0db, 0x0c8c9424, 0x1cafd4b2, 0x9aa7aed9, 0x6a478486,
4270
0xa8841fd7, 0xbfeff40a, 0x8fd7bcc5, 0x3bb28977, 0x2b9a7955, 0xa55cd2e4, 0x1b6ad657, 0x067cdf21,
4271
4272
0x06f36920, 0x63280e1b, 0xf17d930f, 0xa06e74a8, 0x463b3a6f, 0x2a464507, 0x93f8a982, 0x8f620a7d,
4273
0xeda32d11, 0x9706a6d4, 0x33dce588, 0x75a1c446, 0x048ab567, 0xd735aafa, 0x806f7c1c, 0xdcb9651a,
4274
0x26acf3b4, 0x45f91cc9, 0x2a0de6fc, 0xf3c03d0c, 0xf5aee0aa, 0x3eeaaf36, 0x18ccee61, 0x83faa783,
4275
0x4b2b5250, 0xf4ccea22, 0x5ac0714b, 0x3f0b2bc6, 0x481b13ce, 0x12040ea7, 0x66e0bbed, 0x158e1a67,
4276
};
4277
static const ULONG dh_private_key2[] =
4278
{
4279
0xffffffff, 0xffffffff, 0xa2da0fc9, 0x34c26821, 0x8b62c6c4, 0xd11cdc80, 0x084e0229, 0x74cc678a,
4280
0xa6be0b02, 0x229b133b, 0x79084a51, 0xdd04348e, 0xb31995ef, 0x1b433acd, 0x6d0a2b30, 0x37145ff2,
4281
0x6d35e14f, 0x45c2516d, 0x76b585e4, 0xc67e5e62, 0xe9424cf4, 0x6bed37a6, 0xb65cff0b, 0xedb706f4,
4282
0xfb6b38ee, 0xa59f895a, 0x11249fae, 0xe61f4b7c, 0x51662849, 0x8153e6ec, 0xffffffff, 0xffffffff,
4283
4284
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4285
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4286
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4287
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x02000000,
4288
4289
0xa0c3c734, 0xc130c92d, 0x5265abf8, 0xff409f17, 0xbcdce187, 0xff64dae3, 0x170560aa, 0xb2423ed8,
4290
0x9ee5a8b9, 0x92548030, 0x02bba1f9, 0x823e39a4, 0x69c438f5, 0xf91016ac, 0x89bfd166, 0x7f996446,
4291
0x86224203, 0x15bf689c, 0x619354a4, 0x0c1d3a1f, 0x11bcf3d2, 0x58aae029, 0x41c69824, 0x3fafc179,
4292
0xa742747c, 0x60658c7a, 0xd3b0bde4, 0x78d3f08b, 0x6cefa061, 0x33752536, 0xe84d4901, 0x48cd73f4,
4293
4294
0x8d449700, 0x1f95120e, 0xceb31745, 0x3663177b, 0xbd9bb2d5, 0x9c23c0d9, 0x814d34f8, 0xbc54edb0,
4295
0xb874659a, 0x3bac8a30, 0xa1f3dd46, 0x1705c900, 0xbc46fefe, 0x7d13875b, 0x3064351a, 0x4bd89a1c,
4296
0x9e938761, 0x931949db, 0x34490719, 0x84fb08ca, 0xa9dd355a, 0x5b3f5061, 0x2ac96663, 0xc594429e,
4297
0xbe58395d, 0x2f7d872a, 0x303d37b3, 0xa3a9b606, 0x735a6732, 0xa095bd95, 0x3d55a7c3, 0x00e54635,
4298
};
4299
static const ULONG dh_peer_key[] =
4300
{
4301
0xffffffff, 0xffffffff, 0xa2da0fc9, 0x34c26821, 0x8b62c6c4, 0xd11cdc80, 0x084e0229, 0x74cc678a,
4302
0xa6be0b02, 0x229b133b, 0x79084a51, 0xdd04348e, 0xb31995ef, 0x1b433acd, 0x6d0a2b30, 0x37145ff2,
4303
0x6d35e14f, 0x45c2516d, 0x76b585e4, 0xc67e5e62, 0xe9424cf4, 0x6bed37a6, 0xb65cff0b, 0xedb706f4,
4304
0xfb6b38ee, 0xa59f895a, 0x11249fae, 0xe61f4b7c, 0x51662849, 0x8153e6ec, 0xffffffff, 0xffffffff,
4305
4306
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4307
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4308
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4309
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x02000000,
4310
4311
0x3bf7404b, 0x6284fffe, 0x97c0d565, 0xd830c658, 0xcc21bf39, 0xcae45bb6, 0x019df7df, 0xbf4cd293,
4312
0x6bf1989d, 0x78a81f52, 0xa4ed861c, 0x6bacf493, 0xa3e700d1, 0xd06cc206, 0x411b9727, 0x01e9c9ab,
4313
0x9b7e6efa, 0xf46bb25d, 0xd1027242, 0x6130787c, 0xa7b87d8b, 0xfee41492, 0x50db6213, 0x321199b6,
4314
0x7dace53a, 0xe8b1ec51, 0x2181b113, 0x3b33e3c0, 0x5b3a2d67, 0xbd34f0c1, 0x7037c542, 0x4a8d5540,
4315
};
4316
static const ULONG dh_shared_secret_raw[] =
4317
{
4318
0x375d89b5, 0x35a9c270, 0xfbc5ba82, 0x09eb3069, 0xd50965b0, 0xace510f7, 0x981e8731, 0x80a76115,
4319
0xf386d348, 0xca17b8df, 0x0b0e84ec, 0xf81f756e, 0x5030fa20, 0x03113b71, 0x97b7e879, 0x899b5fae,
4320
0xe6913299, 0x09270076, 0x39bc813a, 0xde3ef070, 0x65ad5b3a, 0x2b7c4ba4, 0x86c98ef9, 0x3236feaf,
4321
0x3e0253f7, 0x0489d2dd, 0x97669a3d, 0x50242fca, 0x5d4aecb1, 0xcf2d805f, 0x2258afff, 0x750e92cd,
4322
};
4323
static const ULONG dh_shared_secret_raw2[] =
4324
{
4325
0x0815f37d, 0x19ee74ab, 0x9f63f123, 0xe1b3f10c, 0xbcc9be83, 0xaddf5b9d, 0x28174e72, 0xf8a33825,
4326
0xfc74e47d, 0x2c950888, 0xf5b776d9, 0xfc712fef, 0x5b213b32, 0x489a9829, 0xfc0a4d1d, 0x6e641d3b,
4327
0x3bb2ff57, 0x63500318, 0x081ee54f, 0xf33a2805, 0xb3759e98, 0xa9a64afe, 0x964b8897, 0x04691bbc,
4328
0x80f4aae1, 0x617405ee, 0xab71724d, 0x6c10c214, 0x6f60b96f, 0xdc777b0b, 0x22f40d4f, 0x8a1c4eb5,
4329
};
4330
static const ULONG dh_shared_secret_sha1[] =
4331
{
4332
0x0babba9c, 0x0bdeacbd, 0x04e36574, 0xdd504dcd, 0x0cd88db0,
4333
};
4334
static const ULONG dh_shared_secret_sha256[] =
4335
{
4336
0x3213db5b, 0x8cc8250b, 0xc829eaab, 0x00933709, 0x68160aa9, 0xfb9f1e20, 0xf92368e6, 0x2b8e18eb,
4337
};
4338
static const struct
4339
{
4340
const WCHAR *alg;
4341
ULONG bitlen;
4342
}
4343
ecdh_algorithms[] =
4344
{
4345
{ BCRYPT_ECDH_P256_ALGORITHM, 256 },
4346
{ BCRYPT_ECDH_P384_ALGORITHM, 384 },
4347
{ BCRYPT_ECDH_P521_ALGORITHM, 521 },
4348
};
4349
static const ULONG length = 1024;
4350
BCRYPT_DH_PARAMETER_HEADER *dh_header;
4351
BCRYPT_DH_KEY_BLOB *dh_key_blob;
4352
BCRYPT_SECRET_HANDLE secret, secret2;
4353
BCRYPT_ALG_HANDLE alg;
4354
BCRYPT_KEY_HANDLE key, key2;
4355
UCHAR buffer[2048];
4356
NTSTATUS status;
4357
ULONG size, i;
4358
4359
for (i = 0; i < ARRAY_SIZE(ecdh_algorithms); ++i)
4360
{
4361
winetest_push_context("%s", debugstr_w(ecdh_algorithms[i].alg));
4362
status = BCryptOpenAlgorithmProvider(&alg, ecdh_algorithms[i].alg, NULL, 0);
4363
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4364
4365
key = NULL;
4366
status = BCryptGenerateKeyPair(alg, &key, ecdh_algorithms[i].bitlen, 0);
4367
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4368
ok(key != NULL, "key not set\n");
4369
4370
status = BCryptFinalizeKeyPair(key, 0);
4371
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4372
4373
status = BCryptSecretAgreement(NULL, key, &secret, 0);
4374
ok(status == STATUS_INVALID_HANDLE, "got %#lx\n", status);
4375
4376
status = BCryptSecretAgreement(key, NULL, &secret, 0);
4377
ok(status == STATUS_INVALID_HANDLE, "got %#lx\n", status);
4378
4379
status = BCryptSecretAgreement(key, key, NULL, 0);
4380
ok(status == STATUS_INVALID_PARAMETER, "got %#lx\n", status);
4381
4382
status = BCryptSecretAgreement(key, key, &secret, 0);
4383
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4384
4385
status = BCryptDeriveKey(NULL, L"HASH", NULL, NULL, 0, &size, 0);
4386
ok(status == STATUS_INVALID_HANDLE, "got %#lx\n", status);
4387
4388
status = BCryptDeriveKey(key, L"HASH", NULL, NULL, 0, &size, 0);
4389
ok(status == STATUS_INVALID_HANDLE, "got %#lx\n", status);
4390
4391
status = BCryptDeriveKey(secret, NULL, NULL, NULL, 0, &size, 0);
4392
ok(status == STATUS_INVALID_PARAMETER, "got %#lx\n", status);
4393
4394
status = BCryptDeriveKey(secret, L"HASH", NULL, NULL, 0, &size, 0);
4395
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4396
4397
status = BCryptDestroyHash(secret);
4398
ok(status == STATUS_INVALID_PARAMETER, "got %#lx\n", status);
4399
4400
status = BCryptDestroyKey(secret);
4401
ok(status == STATUS_INVALID_HANDLE, "got %#lx\n", status);
4402
4403
status = BCryptDestroySecret(NULL);
4404
ok(status == STATUS_INVALID_HANDLE, "got %#lx\n", status);
4405
4406
status = BCryptDestroySecret(alg);
4407
ok(status == STATUS_INVALID_HANDLE, "got %#lx\n", status);
4408
4409
status = BCryptDestroySecret(secret);
4410
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4411
4412
status = BCryptDestroyKey(key);
4413
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4414
4415
status = BCryptCloseAlgorithmProvider(alg, 0);
4416
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4417
winetest_pop_context();
4418
}
4419
4420
/* DH */
4421
status = BCryptOpenAlgorithmProvider(&alg, BCRYPT_DH_ALGORITHM, NULL, 0);
4422
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4423
4424
key = NULL;
4425
status = BCryptGenerateKeyPair(alg, &key, 1024, 0);
4426
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4427
ok(key != NULL, "key not set\n");
4428
4429
status = BCryptFinalizeKeyPair(key, 0);
4430
if (status == STATUS_INVALID_PARAMETER)
4431
{
4432
win_skip("broken DH detected\n");
4433
BCryptCloseAlgorithmProvider(alg, 0);
4434
return;
4435
}
4436
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4437
4438
status = BCryptSecretAgreement(key, key, &secret, 0);
4439
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4440
4441
status = BCryptDestroyKey(key);
4442
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4443
4444
status = BCryptDeriveKey(secret, L"HASH", NULL, NULL, 0, &size, 0);
4445
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4446
4447
status = BCryptDestroySecret(secret);
4448
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4449
4450
key = NULL;
4451
status = BCryptGenerateKeyPair(alg, &key, 256, 0);
4452
ok(status == STATUS_INVALID_PARAMETER, "got %08lx\n", status);
4453
4454
status = BCryptGenerateKeyPair(alg, &key, length, 0);
4455
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4456
ok(key != NULL, "key not set\n");
4457
4458
memset(buffer, 0xcc, sizeof(buffer));
4459
status = BCryptGetProperty(key, BCRYPT_DH_PARAMETERS, buffer, sizeof(buffer), &size, 0);
4460
ok(status == STATUS_INVALID_HANDLE, "got %08lx\n", status);
4461
4462
status = BCryptExportKey(key, NULL, BCRYPT_DH_PUBLIC_BLOB, buffer, sizeof(buffer), &size, 0);
4463
ok(status == STATUS_INVALID_HANDLE, "got %08lx\n", status);
4464
4465
status = BCryptFinalizeKeyPair(key, 0);
4466
if (status != STATUS_SUCCESS)
4467
{
4468
BCryptDestroyKey(key);
4469
BCryptCloseAlgorithmProvider(alg, 0);
4470
return;
4471
}
4472
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4473
4474
status = BCryptFinalizeKeyPair(key, 0);
4475
ok(status == STATUS_INVALID_HANDLE, "got %08lx\n", status);
4476
4477
size = 0xdeadbeef;
4478
status = BCryptGetProperty(key, BCRYPT_DH_PARAMETERS, NULL, sizeof(buffer), &size, 0);
4479
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4480
ok(size == sizeof(BCRYPT_DH_PARAMETER_HEADER) + length / 8 * 2, "Got unexpected size %lu.\n", size);
4481
4482
size = 0xdeadbeef;
4483
status = BCryptGetProperty(key, BCRYPT_DH_PARAMETERS, buffer, 28, &size, 0);
4484
ok(status == STATUS_BUFFER_TOO_SMALL, "got %08lx\n", status);
4485
ok(size == sizeof(BCRYPT_DH_PARAMETER_HEADER) + length / 8 * 2, "Got unexpected size %lu.\n", size);
4486
4487
size = 0xdeadbeef;
4488
status = BCryptGetProperty(key, BCRYPT_DH_PARAMETERS, buffer, sizeof(buffer), &size, 0);
4489
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4490
ok(size == sizeof(BCRYPT_DH_PARAMETER_HEADER) + length / 8 * 2, "Got unexpected size %lu.\n", size);
4491
4492
dh_header = (BCRYPT_DH_PARAMETER_HEADER *)buffer;
4493
ok(dh_header->cbLength == sizeof(*dh_header) + length / 8 * 2, "Got unexpected length %lu.\n", dh_header->cbLength);
4494
ok(dh_header->cbKeyLength == length / 8, "Got unexpected length %lu.\n", dh_header->cbKeyLength);
4495
ok(dh_header->dwMagic == BCRYPT_DH_PARAMETERS_MAGIC, "Got unexpected magic %#lx.\n", dh_header->dwMagic);
4496
4497
status = BCryptDestroyKey(key);
4498
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4499
4500
dh_key_blob = (BCRYPT_DH_KEY_BLOB *)buffer;
4501
dh_key_blob->dwMagic = BCRYPT_DH_PRIVATE_MAGIC;
4502
dh_key_blob->cbKey = length / 8;
4503
memcpy(dh_key_blob + 1, dh_private_key, sizeof(dh_private_key));
4504
size = sizeof(buffer);
4505
status = BCryptImportKeyPair(alg, NULL, BCRYPT_DH_PRIVATE_BLOB, &key, buffer, size, 0);
4506
ok(status == STATUS_INVALID_PARAMETER, "got %08lx\n", status);
4507
size = sizeof(*dh_key_blob) + length / 8 * 4;
4508
status = BCryptImportKeyPair(alg, NULL, BCRYPT_DH_PRIVATE_BLOB, &key, buffer, size, 0);
4509
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4510
4511
memset(buffer, 0xcc, sizeof(buffer));
4512
size = 0xdeadbeef;
4513
status = BCryptExportKey(key, NULL, BCRYPT_DH_PUBLIC_BLOB, NULL, 0, &size, 0);
4514
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4515
ok(size == sizeof(BCRYPT_DH_KEY_BLOB) + length / 8 * 3, "Got unexpected size %lu.\n", size);
4516
4517
size = 0xdeadbeef;
4518
status = BCryptExportKey(key, NULL, BCRYPT_DH_PUBLIC_BLOB, buffer, sizeof(buffer), &size, 0);
4519
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4520
ok(size == sizeof(BCRYPT_DH_KEY_BLOB) + length / 8 * 3, "Got unexpected size %lu.\n", size);
4521
dh_key_blob = (BCRYPT_DH_KEY_BLOB *)buffer;
4522
ok(dh_key_blob->dwMagic == BCRYPT_DH_PUBLIC_MAGIC, "Got unexpected magic %#lx.\n", dh_key_blob->dwMagic);
4523
ok(dh_key_blob->cbKey == length / 8, "Got unexpected length %lu.\n", dh_key_blob->cbKey);
4524
ok(!memcmp(dh_key_blob + 1, dh_private_key, length / 8 * 3), "Key data does not match.\n");
4525
4526
status = BCryptGenerateKeyPair(alg, &key2, length, 0);
4527
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4528
dh_header = (BCRYPT_DH_PARAMETER_HEADER *)buffer;
4529
dh_header->dwMagic = BCRYPT_DH_PARAMETERS_MAGIC;
4530
dh_header->cbLength = sizeof(*dh_header) + length / 8 * 2;
4531
dh_header->cbKeyLength = length / 8;
4532
memcpy(dh_header + 1, dh_private_key, length / 8 * 2);
4533
status = BCryptSetProperty(key2, BCRYPT_DH_PARAMETERS, buffer, dh_header->cbLength, 0);
4534
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4535
status = BCryptFinalizeKeyPair(key2, 0);
4536
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4537
4538
status = BCryptExportKey(key2, NULL, BCRYPT_DH_PUBLIC_BLOB, buffer, sizeof(buffer), &size, 0);
4539
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4540
ok(size == sizeof(BCRYPT_DH_KEY_BLOB) + length / 8 * 3, "Got unexpected size %lu.\n", size);
4541
ok(dh_key_blob->dwMagic == BCRYPT_DH_PUBLIC_MAGIC, "Got unexpected dwMagic %#lx.\n", dh_key_blob->dwMagic);
4542
ok(dh_key_blob->cbKey == length / 8, "Got unexpected length %lu.\n", dh_key_blob->cbKey);
4543
ok(!memcmp(dh_key_blob + 1, dh_private_key, length / 8 * 2), "DH parameters do not match.\n");
4544
ok(memcmp((BYTE *)(dh_key_blob + 1) + length / 8 * 2, (BYTE *)dh_private_key + length / 8 * 2, length / 8),
4545
"Random public key data matches.\n");
4546
4547
memset(buffer, 0xcc, sizeof(buffer));
4548
status = BCryptExportKey(key, NULL, BCRYPT_DH_PRIVATE_BLOB, buffer, sizeof(buffer), &size, 0);
4549
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4550
dh_key_blob = (BCRYPT_DH_KEY_BLOB *)buffer;
4551
ok(size == sizeof(BCRYPT_DH_KEY_BLOB) + length / 8 * 4, "Got unexpected size %lu.\n", size);
4552
ok(dh_key_blob->dwMagic == BCRYPT_DH_PRIVATE_MAGIC, "Got unexpected dwMagic %#lx.\n", dh_key_blob->dwMagic);
4553
ok(dh_key_blob->cbKey == length / 8, "Got unexpected length %lu.\n", dh_key_blob->cbKey);
4554
ok(!memcmp(dh_key_blob + 1, dh_private_key, length / 8 * 4), "Private key data does not match.\n");
4555
4556
status = BCryptSecretAgreement(NULL, key, &secret, 0);
4557
ok(status == STATUS_INVALID_HANDLE, "got %08lx\n", status);
4558
4559
status = BCryptSecretAgreement(key, NULL, &secret, 0);
4560
ok(status == STATUS_INVALID_HANDLE, "got %08lx\n", status);
4561
4562
status = BCryptSecretAgreement(key, key, NULL, 0);
4563
ok(status == STATUS_INVALID_PARAMETER, "got %08lx\n", status);
4564
4565
status = BCryptSecretAgreement(key, key, &secret, 0);
4566
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4567
4568
status = BCryptDeriveKey(NULL, L"HASH", NULL, NULL, 0, &size, 0);
4569
ok(status == STATUS_INVALID_HANDLE, "got %08lx\n", status);
4570
4571
status = BCryptDeriveKey(key, L"HASH", NULL, NULL, 0, &size, 0);
4572
ok(status == STATUS_INVALID_HANDLE, "got %08lx\n", status);
4573
4574
status = BCryptDeriveKey(secret, NULL, NULL, NULL, 0, &size, 0);
4575
ok(status == STATUS_INVALID_PARAMETER, "got %08lx\n", status);
4576
4577
size = 0xdeadbeef;
4578
status = BCryptDeriveKey(secret, L"HASH", NULL, NULL, 0, &size, 0);
4579
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4580
ok(size == 20, "Got unexpected size %lu.\n", size);
4581
4582
size = 0xdeadbeef;
4583
status = BCryptDeriveKey(secret, BCRYPT_KDF_RAW_SECRET, NULL, NULL, 0, &size, 0);
4584
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4585
ok(size == length / 8, "Got unexpected size %lu.\n", size);
4586
4587
status = BCryptDeriveKey(secret, BCRYPT_KDF_RAW_SECRET, NULL, buffer, 128, &size, 0);
4588
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4589
ok(size == length / 8, "Got unexpected size %lu.\n", size);
4590
ok(!memcmp(buffer, dh_shared_secret_raw, size), "Raw shared secret data does not match.\n");
4591
4592
size = sizeof(buffer);
4593
memset(buffer, 0xcc, sizeof(buffer));
4594
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, NULL, buffer, 128, &size, 0);
4595
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4596
ok(size == 20, "Got unexpected size %lu.\n", size);
4597
ok(!memcmp(buffer, dh_shared_secret_sha1, sizeof(dh_shared_secret_sha1)),
4598
"sha1 shared secret data does not match.\n");
4599
4600
size = sizeof(buffer);
4601
status = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, &hash_params, buffer, size, &size, 0);
4602
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4603
ok(size == 32, "Got unexpected size %lu.\n", size);
4604
ok(!memcmp(buffer, dh_shared_secret_sha256, sizeof(dh_shared_secret_sha256)),
4605
"sha256 shared secret data does not match.\n");
4606
4607
for (i = size; i < sizeof(buffer); ++i)
4608
if (buffer[i] != 0xcc) break;
4609
ok(i == sizeof(buffer), "Buffer modified at %lu, value %#x.\n", i, buffer[i]);
4610
4611
status = BCryptDestroySecret(secret);
4612
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4613
4614
status = BCryptSecretAgreement(key, key2, &secret, 0);
4615
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4616
status = BCryptSecretAgreement(key2, key, &secret2, 0);
4617
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4618
4619
status = BCryptDeriveKey(secret, BCRYPT_KDF_RAW_SECRET, NULL, buffer, 128, &size, 0);
4620
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4621
status = BCryptDeriveKey(secret, BCRYPT_KDF_RAW_SECRET, NULL, buffer + size, 128, &size, 0);
4622
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4623
ok(!memcmp(buffer, buffer + size, size), "Shared secrets do not match.\n");
4624
4625
status = BCryptDestroySecret(secret);
4626
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4627
status = BCryptDestroySecret(secret2);
4628
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4629
4630
status = BCryptDestroyKey(key);
4631
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4632
status = BCryptDestroyKey(key2);
4633
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4634
4635
dh_key_blob = (BCRYPT_DH_KEY_BLOB *)buffer;
4636
dh_key_blob->dwMagic = BCRYPT_DH_PRIVATE_MAGIC;
4637
dh_key_blob->cbKey = length / 8;
4638
memcpy(dh_key_blob + 1, dh_private_key2, sizeof(dh_private_key2));
4639
4640
size = sizeof(*dh_key_blob) + length / 8 * 4;
4641
status = BCryptImportKeyPair(alg, NULL, BCRYPT_DH_PRIVATE_BLOB, &key, buffer, size, 0);
4642
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4643
4644
dh_key_blob = (BCRYPT_DH_KEY_BLOB *)buffer;
4645
dh_key_blob->dwMagic = BCRYPT_DH_PUBLIC_MAGIC;
4646
dh_key_blob->cbKey = length / 8;
4647
memcpy(dh_key_blob + 1, dh_peer_key, sizeof(dh_peer_key));
4648
4649
size = sizeof(*dh_key_blob) + length / 8 * 3;
4650
status = BCryptImportKeyPair(alg, NULL, BCRYPT_DH_PUBLIC_BLOB, &key2, buffer, size, 0);
4651
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4652
4653
status = BCryptSecretAgreement(key, key2, &secret, 0);
4654
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4655
4656
status = BCryptDeriveKey(secret, BCRYPT_KDF_RAW_SECRET, NULL, buffer, 128, &size, 0);
4657
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4658
ok(size == length / 8, "Got unexpected size %lu.\n", size);
4659
ok(!memcmp(buffer, dh_shared_secret_raw2, size), "Raw shared secret data does not match.\n");
4660
4661
status = BCryptDestroySecret(secret);
4662
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4663
status = BCryptDestroyKey(key);
4664
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4665
status = BCryptDestroyKey(key2);
4666
ok(status == STATUS_SUCCESS, "got %08lx\n", status);
4667
4668
status = BCryptCloseAlgorithmProvider(alg, 0);
4669
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4670
}
4671
4672
static void test_RC4(void)
4673
{
4674
BCRYPT_ALG_HANDLE alg;
4675
NTSTATUS status;
4676
ULONG len, size;
4677
4678
status = BCryptOpenAlgorithmProvider(&alg, BCRYPT_RC4_ALGORITHM, NULL, 0);
4679
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4680
4681
len = size = 0;
4682
status = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
4683
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4684
ok(len, "expected non-zero len\n");
4685
ok(size == sizeof(len), "got %lu\n", size);
4686
4687
len = size = 0;
4688
status = BCryptGetProperty(alg, BCRYPT_BLOCK_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0);
4689
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4690
ok(len == 1, "got %lu\n", len);
4691
ok(size == sizeof(len), "got %lu\n", size);
4692
4693
size = sizeof(BCRYPT_CHAIN_MODE_NA);
4694
status = BCryptSetProperty(alg, BCRYPT_CHAINING_MODE, (UCHAR *)BCRYPT_CHAIN_MODE_NA, size, 0);
4695
ok(!status, "got %#lx\n", status);
4696
4697
status = BCryptCloseAlgorithmProvider(alg, 0);
4698
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4699
}
4700
4701
static void test_PBKDF2(void)
4702
{
4703
static char salt[] = "cCxuHMEHLibcglJOG88dIw==";
4704
static ULONGLONG iter_count = 25;
4705
static BCryptBuffer pbkdf2_param_buffers[] =
4706
{
4707
{
4708
sizeof(BCRYPT_SHA1_ALGORITHM),
4709
KDF_HASH_ALGORITHM,
4710
(void *)BCRYPT_SHA1_ALGORITHM,
4711
},
4712
{
4713
sizeof(salt) - 1,
4714
KDF_SALT,
4715
salt,
4716
},
4717
{
4718
sizeof(iter_count),
4719
KDF_ITERATION_COUNT,
4720
(void *)&iter_count,
4721
}
4722
};
4723
static BCryptBufferDesc pbkdf2_params =
4724
{
4725
BCRYPTBUFFER_VERSION,
4726
ARRAY_SIZE(pbkdf2_param_buffers),
4727
pbkdf2_param_buffers,
4728
};
4729
static UCHAR pbkdf2_hash[] =
4730
{
4731
0x18, 0xf2, 0x58, 0x0b, 0x92, 0x6e, 0x6d, 0xfe,
4732
0x55, 0xbb, 0x62, 0x87, 0x5b, 0x1f, 0x61, 0x83,
4733
0x4d, 0x16, 0xe4, 0x04, 0xcd, 0xab, 0x43, 0x77,
4734
0x25, 0x3e, 0x1d, 0xb4, 0x95, 0x5f, 0xf7, 0x01,
4735
};
4736
4737
BCRYPT_KEY_LENGTHS_STRUCT key_lengths;
4738
BCRYPT_ALG_HANDLE alg;
4739
BCRYPT_KEY_HANDLE key;
4740
NTSTATUS status;
4741
ULONG val, size;
4742
static BYTE buf[32];
4743
4744
status = BCryptOpenAlgorithmProvider(&alg, BCRYPT_PBKDF2_ALGORITHM, NULL, 0);
4745
if (status == STATUS_NOT_FOUND)
4746
{
4747
win_skip("PBKDF2 not available\n");
4748
return;
4749
}
4750
ok(!status, "got %#lx\n", status);
4751
ok(pBCryptKeyDerivation != NULL, "BCryptKeyDerivation not available\n");
4752
4753
val = size = 0;
4754
status = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&val, sizeof(val), &size, 0);
4755
ok(!status, "got %#lx\n", status);
4756
ok(val, "got %lu\n", val);
4757
ok(size == sizeof(val), "got %lu\n", size);
4758
4759
val = size = 0;
4760
status = BCryptGetProperty(alg, BCRYPT_BLOCK_LENGTH, (UCHAR *)&val, sizeof(val), &size, 0);
4761
ok(status == STATUS_NOT_SUPPORTED, "got %#lx\n", status);
4762
4763
memset(&key_lengths, 0xfe, sizeof(key_lengths));
4764
size = 0;
4765
status = BCryptGetProperty(alg, BCRYPT_KEY_LENGTHS, (UCHAR *)&key_lengths, sizeof(key_lengths), &size, 0);
4766
ok(!status, "got %#lx\n", status);
4767
ok(size == sizeof(key_lengths), "got %lu\n", size);
4768
ok(key_lengths.dwMinLength == 0, "got %lu\n", key_lengths.dwMinLength);
4769
ok(key_lengths.dwMaxLength == 16384, "got %lu\n", key_lengths.dwMaxLength);
4770
ok(key_lengths.dwIncrement == 8, "got %lu\n", key_lengths.dwIncrement);
4771
4772
key = 0;
4773
status = BCryptGenerateSymmetricKey(alg, &key, NULL, 0, (UCHAR *)"test", 4, 0);
4774
ok(!status, "got %#lx\n", status);
4775
val = size = 0;
4776
status = BCryptGetProperty(key, BCRYPT_KEY_STRENGTH, (UCHAR *)&val, sizeof(val), &size, 0);
4777
ok(!status, "got %#lx\n", status);
4778
ok(val == strlen("test") * 8, "got %lu\n", val);
4779
4780
status = pBCryptKeyDerivation(key, &pbkdf2_params, NULL, 0, &size, 0);
4781
ok(status == STATUS_INVALID_PARAMETER, "got %#lx\n", status);
4782
4783
buf[0] = buf[1] = 'x';
4784
status = pBCryptKeyDerivation(key, &pbkdf2_params, buf, 1, &size, 0);
4785
ok(!status, "got %#lx\n", status);
4786
ok(size == 1, "size = %lu\n", size);
4787
ok(buf[0] == pbkdf2_hash[0], "buf[0] = %x\n", buf[0]);
4788
ok(buf[1] == 'x', "buf[1] = %x\n", buf[1]);
4789
4790
memset(buf, 'x', sizeof(buf));
4791
status = pBCryptKeyDerivation(key, &pbkdf2_params, buf, sizeof(buf), &size, 0);
4792
ok(!status, "got %#lx\n", status);
4793
ok(size == sizeof(buf), "size = %lu\n", size);
4794
ok(!memcmp(buf, pbkdf2_hash, sizeof(pbkdf2_hash)),
4795
"wrong data (%s)\n", wine_dbgstr_an((char *)buf, size));
4796
4797
status = BCryptDestroyKey(key);
4798
ok(!status, "got %#lx\n", status);
4799
status = BCryptCloseAlgorithmProvider(alg, 0);
4800
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
4801
}
4802
4803
START_TEST(bcrypt)
4804
{
4805
HMODULE module;
4806
4807
module = LoadLibraryA("bcrypt.dll");
4808
if (!module)
4809
{
4810
win_skip("bcrypt.dll not found\n");
4811
return;
4812
}
4813
pBCryptHash = (void *)GetProcAddress(module, "BCryptHash");
4814
pBCryptKeyDerivation = (void *)GetProcAddress(module, "BCryptKeyDerivation");
4815
4816
test_BCryptGenRandom();
4817
test_BCryptGetFipsAlgorithmMode();
4818
test_hashes();
4819
test_BcryptHash();
4820
test_BcryptDeriveKeyPBKDF2();
4821
test_rng();
4822
test_3des();
4823
test_aes();
4824
test_BCryptGenerateSymmetricKey();
4825
test_BCryptEncrypt();
4826
test_BCryptDecrypt();
4827
test_key_import_export();
4828
test_ECDSA();
4829
test_RSA();
4830
test_RSA_SIGN();
4831
test_ECDH();
4832
test_DH();
4833
test_BCryptEnumContextFunctions();
4834
test_BCryptSignHash();
4835
test_BCryptEnumAlgorithms();
4836
test_aes_vector();
4837
test_BcryptDeriveKeyCapi();
4838
test_DSA();
4839
test_SecretAgreement();
4840
test_rsa_encrypt();
4841
test_RC4();
4842
test_PBKDF2();
4843
4844
FreeLibrary(module);
4845
}
4846
4847