2 * Unit tests for dss functions
4 * Copyright (c) 2012 Marek Kamil Chmiel
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/test.h"
29 static void test_acquire_context(void)
30 { /* failure tests common between all four CSP providers */
35 /* cannot acquire provider with 0 as Prov Type and NULL as CSP name */
36 SetLastError(0xdeadbeef);
37 result = CryptAcquireContextA(&hProv, NULL, NULL, 0, 0);
38 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
39 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
41 SetLastError(0xdeadbeef);
42 result = CryptAcquireContextA(&hProv, NULL, NULL, 0, CRYPT_VERIFYCONTEXT);
43 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
44 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
46 /* flag allows us to delete a keyset, but not of an unknown provider */
47 SetLastError(0xdeadbeef);
48 result = CryptAcquireContextA(&hProv, NULL, NULL, 0, CRYPT_DELETEKEYSET);
49 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
50 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
52 /* cannot acquire along with PROV_RSA_SIG, not compatible */
53 SetLastError(0xdeadbeef);
54 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_RSA_SIG, 0);
56 ok(!result && GetLastError() == NTE_PROV_TYPE_NO_MATCH,
57 "Expected NTE_PROV_TYPE_NO_MATCH, got %08x\n", GetLastError());
59 /* cannot acquire along with MS_DEF_RSA_SIG_PROV, not compatible */
60 SetLastError(0xdeadbeef);
61 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_RSA_SIG_PROV, PROV_DSS, 0);
62 ok(!result && GetLastError() == NTE_KEYSET_NOT_DEF,
63 "Expected NTE_KEYSET_NOT_DEF, got %08x\n", GetLastError());
65 /* cannot acquire provider with 0 as Prov Type */
66 SetLastError(0xdeadbeef);
67 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, 0, 0);
68 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
69 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
71 /* test base DSS provider (PROV_DSS) */
73 result = CryptAcquireContextA(
74 &hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
77 skip("DSS csp is currently not available, skipping tests.\n");
80 ok(result, "Expected no errors.\n");
82 result = CryptReleaseContext(hProv, 0);
83 ok(result, "Expected release of the provider.\n");
85 result = CryptAcquireContextA(
86 &hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_NEWKEYSET);
87 ok(result, "Expected no errors.\n");
89 result = CryptReleaseContext(hProv, 0);
90 ok(result, "Expected release of the provider.\n");
92 result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DSS, 0);
93 ok(result, "Expected no errors.\n");
95 result = CryptReleaseContext(hProv, 0);
96 ok(result, "Expected release of the provider.\n");
98 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, 0);
99 ok(result, "Expected no errors.\n");
101 /* test DSS Diffie Hellman provider (PROV_DSS_DH) */
103 result = CryptAcquireContextA(
104 &hProv, NULL, MS_DEF_DSS_DH_PROV, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
105 ok(result, "Expected no errors.\n");
107 result = CryptReleaseContext(hProv, 0);
108 ok(result, "Expected release of the provider.\n");
110 result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DSS_DH, 0);
111 ok(result, "Expected no errors.\n");
113 result = CryptReleaseContext(hProv, 0);
114 ok(result, "Expected release of the provider.\n");
116 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_DH_PROV, PROV_DSS_DH, 0);
117 ok(result, "Expected no errors.\n");
119 /* test DSS Enhanced provider (MS_ENH_DSS_DH_PROV) */
121 SetLastError(0xdeadbeef);
122 result = CryptAcquireContextA(
123 &hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
124 if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
126 win_skip("DSSENH and Schannel provider is broken on WinNT4\n");
129 ok(result, "Expected no errors.\n");
131 result = CryptReleaseContext(hProv, 0);
132 ok(result, "Expected release of the provider.\n");
134 result = CryptAcquireContextA(&hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, 0);
135 ok(result, "Expected no errors.\n");
137 result = CryptReleaseContext(hProv, 0);
138 ok(result, "Expected release of the provider.\n");
140 /* test DSS Schannel provider (PROV_DH_SCHANNEL) */
142 result = CryptAcquireContextA(
143 &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV, PROV_DH_SCHANNEL, CRYPT_VERIFYCONTEXT);
144 ok(result, "Expected no errors.\n");
146 result = CryptReleaseContext(hProv, 0);
147 ok(result, "Expected release of the provider.\n");
149 result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DH_SCHANNEL, 0);
150 ok(result, "Expected no errors.\n");
152 result = CryptReleaseContext(hProv, 0);
153 ok(result, "Expected release of the provider.\n");
155 result = CryptAcquireContextA(
156 &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV, PROV_DH_SCHANNEL, 0);
157 ok(result, "Expected no errors.\n");
159 result = CryptReleaseContext(hProv, 0);
160 ok(result, "Expected release of the provider.\n");
162 /* failure tests, cannot acquire context because the key container already exists */
163 SetLastError(0xdeadbeef);
164 result = CryptAcquireContextA(
165 &hProv, NULL, MS_DEF_DSS_DH_PROV, PROV_DSS_DH, CRYPT_NEWKEYSET);
166 ok(!result && GetLastError() == NTE_EXISTS,
167 "Expected NTE_EXISTS, got %08x\n", GetLastError());
169 SetLastError(0xdeadbeef);
170 result = CryptAcquireContextA(
171 &hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, CRYPT_NEWKEYSET);
172 ok(!result && GetLastError() == NTE_EXISTS,
173 "Expected NTE_EXISTS, got %08x\n", GetLastError());
175 SetLastError(0xdeadbeef);
176 result = CryptAcquireContextA(
177 &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV, PROV_DH_SCHANNEL, CRYPT_NEWKEYSET);
178 ok(!result && GetLastError() == NTE_EXISTS,
179 "Expected NTE_EXISTS, got %08x\n", GetLastError());
182 struct keylength_test {
191 static const struct keylength_test baseDSS_keylength[] = {
192 /* AT_KEYEXCHANGE is not supported by the base DSS provider */
193 {AT_KEYEXCHANGE, 448 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
194 {AT_KEYEXCHANGE, 512 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
195 {AT_KEYEXCHANGE, 1024 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
196 {AT_KEYEXCHANGE, 1088 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS},/* WinNT4 and Win2k */
197 /* min 512 max 1024 increment by 64 */
198 {AT_SIGNATURE, 448 << 16, FALSE, NTE_BAD_FLAGS},
199 {AT_SIGNATURE, 512 << 16, TRUE},
200 {AT_SIGNATURE, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
201 {AT_SIGNATURE, 768 << 16, TRUE},
202 {AT_SIGNATURE, 1024 << 16, TRUE},
203 {AT_SIGNATURE, 1088 << 16, FALSE, NTE_BAD_FLAGS},
204 /* CALG_DH_EPHEM is not supported by the base DSS provider */
205 {CALG_DH_EPHEM, 448 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
206 {CALG_DH_EPHEM, 512 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
207 {CALG_DH_EPHEM, 1024 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
208 {CALG_DH_EPHEM, 1088 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
209 /* CALG_DH_SF is not supported by the base DSS provider */
210 {CALG_DH_SF, 448 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
211 {CALG_DH_SF, 512 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
212 {CALG_DH_SF, 1024 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
213 {CALG_DH_SF, 1088 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
214 /* min 512 max 1024, increment by 64 */
215 {CALG_DSS_SIGN, 448 << 16, FALSE, NTE_BAD_FLAGS},
216 {CALG_DSS_SIGN, 512 << 16, TRUE},
217 {CALG_DSS_SIGN, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
218 {CALG_DSS_SIGN, 768 << 16, TRUE},
219 {CALG_DSS_SIGN, 1024 << 16, TRUE},
220 {CALG_DSS_SIGN, 1088 << 16, FALSE, NTE_BAD_FLAGS}
223 static const struct keylength_test dssDH_keylength[] = {
224 /* min 512 max 1024, increment by 64 */
225 {AT_KEYEXCHANGE, 448 << 16, FALSE, NTE_BAD_FLAGS},
226 {AT_KEYEXCHANGE, 512 << 16, TRUE},
227 {AT_KEYEXCHANGE, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
228 {AT_KEYEXCHANGE, 768 << 16, TRUE},
229 {AT_KEYEXCHANGE, 1024 << 16, TRUE},
230 {AT_KEYEXCHANGE, 1088 << 16, FALSE, NTE_BAD_FLAGS},
231 {AT_SIGNATURE, 448 << 16, FALSE, NTE_BAD_FLAGS},
232 {AT_SIGNATURE, 512 << 16, TRUE},
233 {AT_SIGNATURE, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
234 {AT_SIGNATURE, 768 << 16, TRUE},
235 {AT_SIGNATURE, 1024 << 16, TRUE},
236 {AT_SIGNATURE, 1088 << 16, FALSE, NTE_BAD_FLAGS},
237 {CALG_DH_EPHEM, 448 << 16, FALSE, NTE_BAD_FLAGS},
238 {CALG_DH_EPHEM, 512 << 16, TRUE},
239 {CALG_DH_EPHEM, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
240 {CALG_DH_EPHEM, 768 << 16, TRUE},
241 {CALG_DH_EPHEM, 1024 << 16, TRUE},
242 {CALG_DH_EPHEM, 1088 << 16, FALSE, NTE_BAD_FLAGS},
243 {CALG_DH_SF, 448 << 16, FALSE, NTE_BAD_FLAGS},
244 {CALG_DH_SF, 512 << 16, TRUE},
245 {CALG_DH_SF, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
246 {CALG_DH_SF, 768 << 16, TRUE},
247 {CALG_DH_SF, 1024 << 16, TRUE},
248 {CALG_DH_SF, 1088 << 16, FALSE, NTE_BAD_FLAGS},
249 {CALG_DSS_SIGN, 448 << 16, FALSE, NTE_BAD_FLAGS},
250 {CALG_DSS_SIGN, 512 << 16, TRUE},
251 {CALG_DSS_SIGN, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
252 {CALG_DSS_SIGN, 768 << 16, TRUE},
253 {CALG_DSS_SIGN, 1024 << 16, TRUE},
254 {CALG_DSS_SIGN, 1088 << 16, FALSE, NTE_BAD_FLAGS}
257 static const struct keylength_test dssENH_keylength[] = {
258 /* min 512 max 1024 (AT_KEYEXCHANGE max 4096), increment by 64*/
259 {AT_KEYEXCHANGE, 448 << 16, FALSE, NTE_BAD_FLAGS},
260 {AT_KEYEXCHANGE, 512 << 16, TRUE},
261 {AT_KEYEXCHANGE, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
262 {AT_KEYEXCHANGE, 768 << 16, TRUE},
263 {AT_KEYEXCHANGE, 1024 << 16, TRUE},
264 {AT_KEYEXCHANGE, 1088 << 16, TRUE},
265 {AT_KEYEXCHANGE, 2048 << 16, TRUE},
266 /* Keylength too large - test bot timeout.
267 {AT_KEYEXCHANGE, 3072 << 16, TRUE},
268 {AT_KEYEXCHANGE, 4096 << 16, TRUE}, */
269 {AT_KEYEXCHANGE, 4160 << 16, FALSE, NTE_BAD_FLAGS},
270 {AT_SIGNATURE, 448 << 16, FALSE, NTE_BAD_FLAGS},
271 {AT_SIGNATURE, 512 << 16, TRUE},
272 {AT_SIGNATURE, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
273 {AT_SIGNATURE, 768 << 16, TRUE},
274 {AT_SIGNATURE, 1024 << 16, TRUE},
275 {AT_SIGNATURE, 1032 << 16, FALSE, NTE_BAD_FLAGS},
276 {CALG_DH_EPHEM, 448 << 16, FALSE, NTE_BAD_FLAGS},
277 {CALG_DH_EPHEM, 512 << 16, TRUE},
278 {CALG_DH_EPHEM, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
279 {CALG_DH_EPHEM, 768 << 16, TRUE},
280 {CALG_DH_EPHEM, 1024 << 16, TRUE},
281 {CALG_DH_EPHEM, 1040 << 16, FALSE, NTE_BAD_FLAGS},
282 {CALG_DH_SF, 448 << 16, FALSE, NTE_BAD_FLAGS},
283 {CALG_DH_SF, 512 << 16, TRUE},
284 {CALG_DH_SF, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
285 {CALG_DH_SF, 768 << 16, TRUE},
286 {CALG_DH_SF, 1024 << 16, TRUE},
287 {CALG_DH_SF, 1032 << 16, FALSE, NTE_BAD_FLAGS},
288 {CALG_DSS_SIGN, 448 << 16, FALSE, NTE_BAD_FLAGS},
289 {CALG_DSS_SIGN, 512 << 16, TRUE},
290 {CALG_DSS_SIGN, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
291 {CALG_DSS_SIGN, 768 << 16, TRUE},
292 {CALG_DSS_SIGN, 1024 << 16, TRUE},
293 {CALG_DSS_SIGN, 1088 << 16, FALSE, NTE_BAD_FLAGS}
296 static void test_keylength_array(HCRYPTPROV hProv,const struct keylength_test *tests, int testLen)
302 for (i = 0; i < testLen; i++)
304 SetLastError(0xdeadbeef);
305 result = CryptGenKey(hProv, tests[i].algid, tests[i].flags, &key);
308 if(tests[i].expectedResult)
310 ok(result, "Expected a key, got %08x\n", GetLastError());
311 result = CryptDestroyKey(key);
312 ok(result, "Expected no errors.\n");
315 { /* error but success on older system */
316 if(tests[i].brokenResult)
317 ok((!result && GetLastError() == tests[i].expectedError) ||
318 broken(result), "Expected a key, got %x.\n", GetLastError());
322 if(!tests[i].brokenError)
323 ok(!result && GetLastError() == tests[i].expectedError,
324 "Expected a key, got %x.\n", GetLastError());
326 /* error but different error on older system */
328 ok(!result && (GetLastError() == tests[i].expectedError ||
329 broken(GetLastError() == tests[i].brokenError)),
330 "Expected a key, got %x.\n", GetLastError());
336 #define TESTLEN(x) (sizeof(x) / sizeof((x)[0]))
338 static void test_keylength(void)
340 HCRYPTPROV hProv = 0;
343 /* acquire base dss provider */
344 result = CryptAcquireContextA(
345 &hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
348 skip("DSSENH is currently not available, skipping key length tests.\n");
351 ok(result, "Expected no errors.\n");
353 /* perform keylength tests */
354 test_keylength_array(hProv, baseDSS_keylength, TESTLEN(baseDSS_keylength));
356 result = CryptReleaseContext(hProv, 0);
357 ok(result, "Expected release of CSP provider.\n");
359 /* acquire diffie hellman dss provider */
360 result = CryptAcquireContextA(
361 &hProv, NULL, MS_DEF_DSS_DH_PROV, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
362 ok(result, "Expected no errors.\n");
364 /* perform keylength tests */
365 test_keylength_array(hProv, dssDH_keylength, TESTLEN(dssDH_keylength));
367 result = CryptReleaseContext(hProv, 0);
368 ok(result, "Expected release of CSP provider.\n");
370 /* acquire enhanced dss provider */
371 SetLastError(0xdeadbeef);
372 result = CryptAcquireContextA(
373 &hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
374 if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
376 win_skip("DSSENH and Schannel provider is broken on WinNT4\n");
379 ok(result, "Expected no errors.\n");
381 /* perform keylength tests */
382 test_keylength_array(hProv, dssENH_keylength, TESTLEN(dssENH_keylength));
384 result = CryptReleaseContext(hProv, 0);
385 ok(result, "Expected release of CSP provider.\n");
387 /* acquire schannel dss provider */
388 result = CryptAcquireContextA(
389 &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV, PROV_DH_SCHANNEL, CRYPT_VERIFYCONTEXT);
390 ok(result, "Expected no errors.\n");
392 /* perform keylength tests */
393 test_keylength_array(hProv, dssENH_keylength, TESTLEN(dssENH_keylength));
395 result = CryptReleaseContext(hProv, 0);
396 ok(result, "Expected release of CSP provider.\n");
407 static const char testHashVal1[] = "I love working with Wine";
408 static const char testHashVal2[] = "Wine is not an emulater.";
409 static const char testHashVal3[] = "";
411 static const struct hash_test hash_data[] = {
412 {CALG_MD5, (BYTE *)testHashVal1, sizeof(testHashVal1),
413 {0x4f, 0xf4, 0xd0, 0xdf, 0xe8, 0xf6, 0x6b, 0x1b,
414 0x87, 0xea, 0xca, 0x3d, 0xe8, 0x3c, 0xdd, 0xae}, 16},
415 {CALG_MD5, (BYTE *)testHashVal2, sizeof(testHashVal2),
416 {0x80, 0x5c, 0x1c, 0x0e, 0x79, 0x70, 0xd9, 0x38,
417 0x04, 0x46, 0x19, 0xbe, 0x38, 0x1f, 0xef, 0xe1}, 16},
418 {CALG_MD5, (BYTE *)testHashVal3, sizeof(testHashVal3),
419 {0x93, 0xb8, 0x85, 0xad, 0xfe, 0x0d, 0xa0, 0x89,
420 0xcd, 0xf6, 0x34, 0x90, 0x4f, 0xd5, 0x9f, 0x71}, 16},
421 {CALG_SHA, (BYTE *)testHashVal1, sizeof(testHashVal1),
422 {0x2a, 0xd0, 0xc9, 0x42, 0xfb, 0x73, 0x02, 0x48, 0xbb, 0x5f,
423 0xc2, 0xa4, 0x78, 0xdd, 0xe4, 0x3b, 0xfc, 0x76, 0xe9, 0xe2}, 20},
424 {CALG_SHA, (BYTE *)testHashVal2, sizeof(testHashVal2),
425 {0xfd, 0xfc, 0xab, 0x3a, 0xde, 0x33, 0x01, 0x38, 0xfe, 0xbb,
426 0xc3, 0x13, 0x84, 0x20, 0x9e, 0x55, 0x94, 0x8d, 0xc6, 0x05}, 20},
427 {CALG_SHA, (BYTE *)testHashVal3, sizeof(testHashVal3),
428 {0x5b, 0xa9, 0x3c, 0x9d, 0xb0, 0xcf, 0xf9, 0x3f, 0x52, 0xb5,
429 0x21, 0xd7, 0x42, 0x0e, 0x43, 0xf6, 0xed, 0xa2, 0x78, 0x4f}, 20}
432 static void test_hash(const struct hash_test *tests, int testLen)
434 HCRYPTPROV hProv = 0;
440 result = CryptAcquireContextA(
441 &hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
444 skip("DSSENH is currently not available, skipping hashing tests.\n");
447 ok(result, "Expected no errors.\n");
449 for(i = 0; i < testLen; i++)
451 BYTE* data = tests[i].input;
452 DWORD dataLen = tests[i].dataLen;
455 /* test algid hash */
456 result = CryptCreateHash(hProv, tests[i].algid, 0, 0, &hHash);
457 ok(result, "Expected creation of a hash.\n");
459 result = CryptHashData(hHash, data, dataLen, 0);
460 ok(result, "Expected data to be added to hash.\n");
462 dataLen = sizeof(DWORD);
463 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&hashLen, &dataLen, 0);
464 ok(result && (hashLen == tests[i].hashLen), "Expected %d hash len, got %d.Error: %x\n",
465 tests[i].hashLen, hashLen, GetLastError());
467 result = CryptGetHashParam(hHash, HP_HASHVAL, hashValue, &hashLen, 0);
468 ok(result, "Expected hash value return.\n");
470 ok(!memcmp(hashValue, tests[i].hash, tests[i].hashLen), "Incorrect hash output.\n");
472 result = CryptHashData(hHash, data, dataLen, 0);
473 ok(!result, "Should not be able to add to hash.\n");
475 result = CryptDestroyHash(hHash);
476 ok(result, "Expected destruction of hash.\n");
478 result = CryptReleaseContext(hProv, 0);
479 ok(result, "Expected release of the DSS Enhanced provider.\n");
482 struct encrypt_test {
487 const BYTE *decrypted;
488 const BYTE *encrypted;
491 static const char dataToEncrypt1[] = "Great performance with Wine.";
492 static const char dataToEncrypt2[] = "Wine implements Windows API";
493 static const char dataToEncrypt3[] = "";
495 static const BYTE encrypted3DES_1[] = {
496 0x6c,0x60,0x19,0x41,0x27,0xc1,0x16,0x69, 0x6f,0x96,0x0c,0x2e,0xa4,0x5f,0xf5,0x6a,
497 0xed,0x4b,0xec,0xd4,0x92,0x0c,0xe2,0x34, 0xe1,0x4a,0xb5,0xe2,0x05,0x43,0xfe,0x17
499 static const BYTE encrypted3DES_2[] = {
500 0x17,0xeb,0x80,0xde,0xac,0x4d,0x9e,0xd0, 0xa9,0xae,0x74,0xb5,0x86,0x1a,0xea,0xb4,
501 0x96,0x27,0x5d,0x75,0x4f,0xdd,0x87,0x60, 0xfc,0xaf,0xa1,0x82,0x83,0x09,0xf1,0xca
503 static const BYTE encrypted3DES_3[] = {0xaf, 0x36, 0xc0, 0x3d, 0x78, 0x64, 0xc4, 0x4a};
505 static const BYTE encrypted3DES112_1[] = {
506 0xb3,0xf8,0x4b,0x08,0xd6,0x23,0xcb,0xca, 0x43,0x26,0xd9,0x9f,0x6b,0x99,0x09,0xe9,
507 0x8c,0x4c,0x7d,0xef,0x49,0xda,0x0b,0x44, 0xcc,0x8d,0x06,0x6b,0xed,0xb7,0xf1,0x67
509 static const BYTE encrypted3DES112_2[] = {
510 0xdc,0xcf,0x93,0x11,0x7a,0xe4,0xcd,0x3f, 0x11,0xd8,0xe0,0x1e,0xe0,0x8d,0x9c,0xba,
511 0x97,0x5d,0x74,0x4d,0x83,0x03,0x5c,0xf2, 0x01,0xaf,0xed,0x7a,0x87,0x8f,0x88,0x8b
513 static const BYTE encrypted3DES112_3[] = {0x04, 0xb3, 0x9c, 0x59, 0x48, 0xc7, 0x2f, 0xd1};
515 static const BYTE encryptedDES_1[] = {
516 0x3d,0xdc,0x54,0xaf,0x66,0x72,0x4e,0xef, 0x9d,0x35,0x02,0xc2,0x1a,0xf4,0x1f,0x01,
517 0xb1,0xaf,0x13,0xd9,0xbe,0x7b,0xd4,0xf3, 0xf5,0x9d,0x2a,0xd8,0x32,0x90,0xe9,0x0b
519 static const BYTE encryptedDES_2[] = {
520 0xa8,0x05,0xd7,0xe9,0x61,0xf4,0x6c,0xce, 0x95,0x2b,0x52,0x08,0x25,0x03,0x30,0xac,
521 0xd7,0xe7,0xd3,0x07,0xb2,0x68,0x63,0x7b, 0xe3,0xab,0x26,0x1e,0x5c,0xec,0x42,0x4f
523 static const BYTE encryptedDES_3[] = {0x35, 0x02, 0xbb, 0x7c, 0x43, 0x5b, 0xf5, 0x59};
525 static const BYTE encryptedRC2_1[] = {
526 0x9e,0xcb,0xa2,0x27,0xc2,0xec,0x10,0xe0, 0x94,0xb3,0xc3,0x9d,0x7d,0xe2,0x12,0xe4,
527 0xb0,0xde,0xd9,0x46,0xca,0x1f,0xa6,0xfa, 0xa4,0x79,0x08,0x59,0xa6,0x00,0x62,0x16
529 static const BYTE encryptedRC2_2[] = {
530 0x29,0x06,0xfd,0xa1,0xe0,0x88,0x89,0xb0, 0x4d,0x7f,0x96,0x9d,0x2c,0x44,0xa1,0xd2,
531 0xbe,0xc6,0xaf,0x10,0xb8,0x86,0x68,0x1b, 0x1d,0x9f,0x3c,0xc4,0x12,0x02,0xbc,0x73
533 static const BYTE encryptedRC2_3[] = {0x26,0x40,0x73,0xfe,0x13,0xbb,0x32,0xa8};
535 static const BYTE encryptedRC4_1[] = {
536 0x5a,0x48,0xeb,0x16,0x96,0x23,0x16,0xb7, 0xbb,0x36,0xe8,0x43,0x88,0x74,0xb1,0x9d,
537 0x96,0xf0,0x84,0x0f,0x5a,0x56,0xf9,0x62, 0xae,0xb5,0x4a,0xce,0x52
539 static const BYTE encryptedRC4_2[] = {
540 0x4a,0x53,0xe0,0x12,0xc2,0x6a,0x0b,0xa2, 0xa5,0x35,0xea,0x54,0x8b,0x61,0xac,0xde,
541 0xa4,0xb9,0x9d,0x02,0x41,0x49,0xaa,0x15, 0x86,0x8b,0x66,0xe0
543 static const BYTE encryptedRC4_3[] = {0x1d};
545 static const struct encrypt_test encrypt_data[] = {
546 {CALG_3DES, 168 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
548 {CALG_3DES, 168 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
550 {CALG_3DES, 168 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
552 {CALG_3DES_112, 112 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
554 {CALG_3DES_112, 112 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
556 {CALG_3DES_112, 112 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
558 {CALG_DES, 56 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
560 {CALG_DES, 56 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
562 {CALG_DES, 56 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
564 /* CALG_RC2 key unexpected results under Win2K when default key length is used, here we use
565 minimum length because Win2K's DSSENH provider has a different default key length compared
566 to the younger operating systems, though there is no default key len issue with CALG_RC4 */
567 {CALG_RC2, 40 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
569 {CALG_RC2, 40 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
571 {CALG_RC2, 40 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
573 {CALG_RC4, 40 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
575 {CALG_RC4, 40 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
577 {CALG_RC4, 40 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
581 static void test_data_encryption(const struct encrypt_test *tests, int testLen)
582 { /* Here we test the same encryption ciphers as the RSAENH cryptographic service provider */
583 HCRYPTPROV hProv = 0;
586 const char dataToHash[] = "I love working with Wine";
587 unsigned char pbData[36];
592 /* acquire dss enhanced provider */
593 SetLastError(0xdeadbeef);
594 result = CryptAcquireContextA(
595 &hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
596 if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
598 skip("DSSENH is currently not available, skipping encryption tests.\n");
601 ok(result, "Expected no errors.\n");
603 /* testing various encryption algorithms */
604 for(i = 0; i < testLen; i++)
606 memcpy(pbData, tests[i].plain, tests[i].plainLen);
607 dataLen = tests[i].plainLen;
609 SetLastError(0xdeadbeef);
610 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
611 ok(result, "Expected creation of a MD5 hash for key derivation.\n");
613 result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
614 ok(result, "Expected data to be added to hash for key derivation.\n");
617 result = CryptDeriveKey(hProv, tests[i].algid, hHash, tests[i].keyLength, &pKey);
618 ok(result, "Expected a derived key.\n");
620 result = CryptDestroyHash(hHash);
621 ok(result, "Expected destruction of hash after deriving key.\n");
623 /* testing CryptEncrypt with ALGID from array */
624 result = CryptEncrypt(pKey, 0, TRUE, 0, pbData, &dataLen, 36);
625 ok(result, "Expected data encryption.\n");
627 /* Verify we have received expected encrypted data */
628 ok(!memcmp(pbData, tests[i].encrypted, dataLen), "Incorrect encrypted data.\n");
630 result = CryptDecrypt(pKey, 0, TRUE, 0, pbData, &dataLen);
631 ok(result, "Expected data decryption.\n");
633 /* Verify we have received expected decrypted data */
634 ok(!memcmp(pbData, tests[i].decrypted, dataLen), "Incorrect decrypted data.\n");
636 result = CryptDestroyKey(pKey);
637 ok(result, "Expected no DestroyKey errors.\n");
639 result = CryptReleaseContext(hProv, 0);
640 ok(result, "Expected release of the provider\n");
643 struct ciphermode_test {
647 const BYTE *encrypted;
650 static const BYTE encryptedCFB[] = {
651 0x51,0x15,0x77,0xab,0x62,0x1f,0x7d,0xcb, 0x35,0x1e,0xd8,0xd3,0x2a,0x00,0xf0,0x94,
652 0x7c,0xa5,0x28,0xda,0xb8,0x81,0x15,0x99, 0xd1,0xd5,0x06,0x1d,0xd3,0x46,0x7e,0xca
654 static const BYTE encryptedCBC[] = {
655 0x8f,0x7b,0x56,0xeb,0xad,0x4d,0x76,0xc2, 0xd5,0x1d,0xf0,0x60,0x9d,0xde,0x96,0xe8,
656 0xb7,0x7b,0xeb,0x4b,0xee,0x3f,0xae,0x05, 0x20,0xf5,0xe0,0x75,0xa0,0x1d,0xf9,0x39
658 static const BYTE encryptedECB[] = {
659 0x8f,0x7b,0x56,0xeb,0xad,0x4d,0x76,0xc2, 0x8b,0xe0,0x4e,0xe4,0x98,0x4f,0xb8,0x3b,
660 0xf3,0xeb,0x6f,0x0a,0x57,0x91,0xdd,0xc7, 0x34,0x5d,0x4c,0xa3,0x7e,0x97,0xbf,0xee
663 static const struct ciphermode_test ciphermode_data[] = {
664 {CRYPT_MODE_CFB, TRUE, 0xdeadbeef, encryptedCFB}, /* Testing cipher block chaining */
665 {CRYPT_MODE_CBC, TRUE, 0xdeadbeef, encryptedCBC}, /* Testing cipher feedback */
666 {CRYPT_MODE_ECB, TRUE, 0xdeadbeef, encryptedECB}, /* Testing electronic codebook */
667 {CRYPT_MODE_OFB, FALSE, NTE_BAD_DATA}/* DSSENH does not support Output Feedback cipher mode */
670 static void test_cipher_modes(const struct ciphermode_test *tests, int testLen)
672 HCRYPTPROV hProv = 0;
675 const char plainText[] = "Testing block cipher modes.";
676 const char dataToHash[] = "GSOC is awesome!";
677 unsigned char pbData[36];
678 int plainLen = sizeof(plainText), i;
682 /* acquire dss enhanced provider */
683 SetLastError(0xdeadbeef);
684 result = CryptAcquireContextA(
685 &hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
686 if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
688 skip("DSSENH is currently not available, skipping block cipher mode tests.\n");
691 ok(result, "Expected no errors.\n");
693 SetLastError(0xdeadbeef);
694 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
695 ok(result, "Expected creation of a MD5 hash for key derivation.\n");
697 result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
698 ok(result, "Expected data to be added to hash for key derivation.\n");
700 /* Derive a CALG_RC2 key, but could be any other encryption cipher */
701 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &pKey);
702 ok(result, "Expected a derived key.\n");
704 result = CryptDestroyHash(hHash);
705 ok(result, "Expected destruction of hash after deriving key.\n");
707 /* test block cipher modes */
708 for(i = 0; i < testLen; i++)
710 SetLastError(0xdeadbeef);
712 mode = tests[i].cipherMode;
713 memcpy(pbData, plainText, plainLen);
715 result = CryptSetKeyParam(pKey, KP_MODE, (BYTE*)&mode, 0);
716 if(tests[i].expectedResult)
718 ok(result, "Expected setting of KP_MODE, got %x.\n", GetLastError());
720 result = CryptEncrypt(pKey, 0, TRUE, 0, pbData, &dataLen, 36);
721 ok(result, "Expected data encryption, got %x.\n", GetLastError());
723 /* Verify we have the correct encrypted data */
724 ok(!memcmp(pbData, tests[i].encrypted, dataLen), "Incorrect encrypted data.\n");
726 result = CryptDecrypt(pKey, 0, TRUE, 0, pbData, &dataLen);
727 ok(result, "Expected data decryption, got %x.\n", GetLastError());
729 /* Verify we have the correct decrypted data */
730 ok(!memcmp(pbData, (BYTE *)plainText, dataLen), "Incorrect decrypted data.\n");
733 { /* Expected error */
734 ok(!result && GetLastError() == tests[i].expectedError, "Expected %d, got %x.\n",
735 tests[i].expectedError, GetLastError());
738 result = CryptDestroyKey(pKey);
739 ok(result, "Expected no DestroyKey errors.\n");
741 result = CryptReleaseContext(hProv, 0);
742 ok(result, "Expected release of the provider.\n");
745 struct signature_test {
746 const BYTE *privateKey;
752 static const char dataToSign1[] = "Put your hands up for Cryptography :)";
753 static const char dataToSign2[] = "With DSSENH implemented, applications requiring it will now work.";
754 static const char dataToSign3[] = "";
756 static const BYTE AT_SIGNATURE_PrivateKey[] = {
757 0x07,0x02,0x00,0x00,0x00,0x22,0x00,0x00, 0x44,0x53,0x53,0x32,0x00,0x04,0x00,0x00,
758 0x01,0xd1,0xfc,0x7a,0x70,0x53,0xb2,0x48, 0x70,0x23,0x19,0x1f,0x3c,0xe1,0x26,0x14,
759 0x7e,0x9f,0x0f,0x7f,0x33,0x5e,0x2b,0xf7, 0xca,0x01,0x74,0x8c,0xb4,0xfd,0xf6,0x44,
760 0x95,0x35,0x56,0xaa,0x4d,0x62,0x48,0xe2, 0xd1,0xa2,0x7e,0x6e,0xeb,0xd6,0xcc,0x7c,
761 0xe8,0xfd,0x21,0x9a,0xa2,0xfd,0x7a,0x9d, 0x1a,0x38,0x69,0x87,0x39,0x5a,0x91,0xc0,
762 0x52,0x2b,0x9f,0x2a,0x54,0x78,0x37,0x82, 0x9a,0x70,0x57,0xab,0xec,0x93,0x8e,0xac,
763 0x73,0x04,0xe8,0x53,0x72,0x72,0x32,0xc6, 0xcb,0xef,0x47,0x98,0x3c,0x56,0x49,0x62,
764 0xcb,0xbb,0xe7,0x34,0x84,0xa6,0x72,0x3a, 0xbe,0x26,0x46,0x86,0xca,0xcb,0x35,0x62,
765 0x4f,0x19,0x18,0x0b,0xb0,0x78,0xae,0xd5, 0x42,0xdf,0x26,0xdb,0x85,0x63,0x77,0x85,
766 0x01,0x3b,0x32,0xbe,0x5c,0xf8,0x05,0xc8, 0xde,0x17,0x7f,0xb9,0x03,0x82,0xfa,0xf1,
767 0x9e,0x32,0x73,0xfa,0x8d,0xea,0xa3,0x30, 0x48,0xe2,0xdf,0x5a,0xcb,0x83,0x3d,0xff,
768 0x56,0xe9,0xc0,0x94,0xf8,0x6d,0xb3,0xaf, 0x4a,0x97,0xb9,0x43,0x0e,0xd4,0x28,0x98,
769 0x57,0x2e,0x3a,0xca,0xde,0x6f,0x45,0x0d, 0xfb,0x58,0xec,0x78,0x34,0x2e,0x46,0x4d,
770 0xfe,0x98,0x02,0xbb,0xef,0x07,0x1a,0x13, 0xb6,0xc2,0x2c,0x06,0xd9,0x0c,0xc4,0xb0,
771 0x4c,0x3a,0xfc,0x01,0x63,0xb5,0x5a,0x5d, 0x2d,0x9c,0x47,0x04,0x67,0x51,0xf2,0x52,
772 0xf5,0x82,0x36,0xeb,0x6e,0x66,0x58,0x4c, 0x10,0x2c,0x29,0x72,0x4a,0x6f,0x6b,0x6c,
773 0xe0,0x93,0x31,0x42,0xf6,0xda,0xfa,0x5b, 0x22,0x43,0x9b,0x1a,0x98,0x71,0xe7,0x41,
774 0x74,0xe9,0x12,0xa4,0x1f,0x27,0x0a,0x63, 0x94,0x49,0xd7,0xad,0xa5,0xc4,0x5c,0xc3,
775 0xc9,0x70,0xb3,0x7b,0x16,0xb6,0x1d,0xd4, 0x09,0xc4,0x9a,0x46,0x2d,0x0e,0x75,0x07,
776 0x31,0x7b,0xed,0x45,0xcd,0x99,0x84,0x14, 0xf1,0x01,0x00,0x00,0x93,0xd5,0xa3,0xe4,
777 0x34,0x05,0xeb,0x98,0x3b,0x5f,0x2f,0x11, 0xa4,0xa5,0xc4,0xff,0xfb,0x22,0x7c,0x54
780 static const BYTE DSS_SIGN_PrivateKey[] = {
781 0x07,0x02,0x00,0x00,0x00,0x22,0x00,0x00, 0x44,0x53,0x53,0x32,0x00,0x04,0x00,0x00,
782 0xf7,0x9e,0x89,0xa2,0xcd,0x0b,0x61,0xe0, 0xa3,0xe5,0x86,0x6b,0x04,0x98,0x80,0x9c,
783 0x36,0xc2,0x76,0x4e,0x22,0xd5,0x21,0xaa, 0x03,0x59,0xf4,0x95,0xb2,0x11,0x1f,0xa0,
784 0xc5,0xfc,0xbe,0x5d,0x1f,0x2e,0xf4,0x36, 0x40,0x48,0x81,0x51,0xb4,0x25,0x86,0xe0,
785 0x98,0xc8,0x4d,0xa0,0x08,0x99,0xa1,0x00, 0x45,0x1b,0x75,0x6b,0x0d,0x3e,0x7d,0x13,
786 0xd7,0x23,0x32,0x08,0xf4,0xeb,0x27,0x9e, 0xe9,0x05,0x5d,0xac,0xc8,0xd7,0x62,0x13,
787 0x43,0x2a,0x69,0x65,0xdc,0xe6,0x52,0xf9, 0x6a,0xe8,0x07,0xcf,0x3e,0xf8,0xc9,0x1d,
788 0x8e,0xdf,0x4e,0x9a,0xd1,0x48,0xf2,0xda, 0x9e,0xfa,0x92,0x5f,0x6d,0x57,0xf2,0xa4,
789 0x5f,0x60,0xce,0x92,0x7a,0x80,0x39,0x21, 0x9d,0x4d,0x3a,0x60,0x76,0x4c,0x2f,0xc0,
790 0xd3,0xf4,0x14,0x03,0x03,0x05,0xa9,0x0c, 0x57,0x72,0x4f,0x60,0x3c,0xe9,0x09,0x54,
791 0x0c,0x2a,0x56,0xda,0x30,0xb6,0x2e,0x6a, 0x96,0x7f,0x4a,0x8f,0x83,0x0a,0xb9,0x5c,
792 0xff,0x84,0xfa,0x0e,0x85,0x81,0x46,0xe9, 0x1c,0xbb,0x78,0x1d,0x78,0x25,0x00,0x8c,
793 0x78,0x56,0x68,0xe4,0x06,0x37,0xcc,0xc7, 0x22,0x27,0xee,0x0e,0xf8,0xca,0xfc,0x72,
794 0x0e,0xd6,0xe6,0x90,0x30,0x66,0x22,0xe2, 0xa2,0xbf,0x2e,0x35,0xbc,0xe7,0xd6,0x24,
795 0x6a,0x3d,0x06,0xe8,0xe2,0xbe,0x96,0xcc, 0x9a,0x08,0x06,0xb5,0x44,0x83,0xb0,0x7b,
796 0x70,0x7b,0x2d,0xc3,0x46,0x9a,0xc5,0x6b, 0xd9,0xde,0x9a,0x24,0xc9,0xea,0xf5,0x28,
797 0x69,0x8a,0x17,0xca,0xdf,0xc4,0x0e,0xa3, 0x08,0x22,0x99,0xd2,0x27,0xdc,0x9b,0x08,
798 0x54,0x4a,0xf9,0xb1,0x74,0x3a,0x9d,0xd9, 0xc2,0x82,0x21,0xf5,0x97,0x04,0x90,0x37,
799 0xda,0xd9,0xdc,0x19,0xad,0x83,0xcd,0x35, 0xb0,0x4e,0x06,0x68,0xd1,0x69,0x7e,0x73,
800 0x93,0xbe,0xa5,0x05,0xb3,0xcc,0xd2,0x51, 0x3c,0x00,0x00,0x00,0x16,0xe1,0xac,0x17,
801 0xdc,0x68,0xae,0x03,0xad,0xf7,0xb9,0xca, 0x0d,0xca,0x27,0xef,0x76,0xda,0xe5,0xcb
804 static const struct signature_test dssSign_data[] = {
805 {AT_SIGNATURE_PrivateKey, sizeof(AT_SIGNATURE_PrivateKey), (BYTE *)dataToSign1, sizeof(dataToSign1)},
806 {AT_SIGNATURE_PrivateKey, sizeof(AT_SIGNATURE_PrivateKey), (BYTE *)dataToSign2, sizeof(dataToSign2)},
807 {AT_SIGNATURE_PrivateKey, sizeof(AT_SIGNATURE_PrivateKey), (BYTE *)dataToSign3, sizeof(dataToSign3)},
808 {DSS_SIGN_PrivateKey, sizeof(DSS_SIGN_PrivateKey), (BYTE *)dataToSign1, sizeof(dataToSign1)},
809 {DSS_SIGN_PrivateKey, sizeof(DSS_SIGN_PrivateKey), (BYTE *)dataToSign2, sizeof(dataToSign2)},
810 {DSS_SIGN_PrivateKey, sizeof(DSS_SIGN_PrivateKey), (BYTE *)dataToSign3, sizeof(dataToSign3)}
813 static void test_signhash_array(HCRYPTPROV hProv, const struct signature_test *tests, int testLen)
815 HCRYPTHASH hHash1, hHash2;
816 HCRYPTKEY privKey = 0, pubKey = 0;
817 BYTE pubKeyBuffer[512];
818 BYTE signValue1[40], signValue2[40];
819 BYTE hashValue1[40], hashValue2[40];
820 DWORD hashLen1, hashLen2, pubKeyLen;
821 DWORD dataLen1, dataLen2;
825 for (i = 0; i < testLen; i++)
827 DWORD signLen1 = tests[i].dataLen;
828 DWORD signLen2 = tests[i].dataLen;
830 /* Get a private key of array specified ALG_ID */
831 result = CryptImportKey(hProv, tests[i].privateKey, tests[i].keyLen, 0, 0, &privKey);
832 ok(result, "Failed to imported key, got %x\n", GetLastError());
834 /* Create hash object and add data for signature 1 */
835 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash1);
836 ok(result, "Failed to create a hash, got %x\n", GetLastError());
838 result = CryptHashData(hHash1, tests[i].signData, signLen1, 0);
839 ok(result, "Failed to add data to hash, got %x\n", GetLastError());
841 /* Create hash object and add data for signature 2 */
842 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
843 ok(result, "Failed to create a hash, got %x\n", GetLastError());
845 result = CryptHashData(hHash2, tests[i].signData, signLen2, 0);
846 ok(result, "Failed to add data to hash, got %x\n", GetLastError());
848 /* Acquire hash length and hash value */
849 dataLen1 = sizeof(DWORD);
850 result = CryptGetHashParam(hHash1, HP_HASHSIZE, (BYTE *)&hashLen1, &dataLen1, 0);
851 ok(result, "Failed to get hash length, got %x\n", GetLastError());
853 result = CryptGetHashParam(hHash1, HP_HASHVAL, hashValue1, &hashLen1, 0);
854 ok(result, "Failed to return hash value.\n");
856 dataLen2 = sizeof(DWORD);
857 result = CryptGetHashParam(hHash2, HP_HASHSIZE, (BYTE *)&hashLen2, &dataLen2, 0);
858 ok(result, "Failed to get hash length, got %x\n", GetLastError());
860 result = CryptGetHashParam(hHash2, HP_HASHVAL, hashValue2, &hashLen2, 0);
861 ok(result, "Failed to return hash value.\n");
863 /* Compare hashes to ensure they are the same */
864 ok(hashLen1 == hashLen2, "Hash lengths were not the same.\n");
865 ok(!memcmp(hashValue1, hashValue2, hashLen2), "Hashes were not identical.\n");
868 result = CryptSignHash(hHash1, AT_SIGNATURE, NULL, 0, NULL, &signLen1);
869 ok(result, "Failed to get signature length, got %x\n", GetLastError());
870 ok(signLen1 == 40, "Expected a 40-byte signature, got %d\n", signLen1);
872 result = CryptSignHash(hHash1, AT_SIGNATURE, NULL, 0, signValue1, &signLen1);
873 ok(result, "Failed to sign hash, got %x\n", GetLastError());
876 result = CryptSignHash(hHash2, AT_SIGNATURE, NULL, 0, NULL, &signLen2);
877 ok(result, "Failed to get signature length, got %x\n", GetLastError());
878 ok(signLen2 == 40, "Expected a 40-byte signature, got %d\n", signLen2);
880 result = CryptSignHash(hHash2, AT_SIGNATURE, NULL, 0, signValue2, &signLen2);
881 ok(result, "Failed to sign hash2, got %x\n", GetLastError());
883 /* Compare signatures to ensure they are both different, because every DSS signature
884 should be different even if the input hash data is identical */
885 ok(memcmp(signValue1, signValue2, signLen2), "Expected two different signatures from "
886 "the same hash input.\n");
888 result = CryptExportKey(privKey, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen);
889 ok(result, "Failed to acquire public key length, got %x\n", GetLastError());
891 /* Export the public key */
892 result = CryptExportKey(privKey, 0, PUBLICKEYBLOB, 0, pubKeyBuffer, &pubKeyLen);
893 ok(result, "Failed to export public key, got %x\n", GetLastError());
895 result = CryptDestroyHash(hHash1);
896 ok(result, "Failed to destroy hash1, got %x\n", GetLastError());
897 result = CryptDestroyHash(hHash2);
898 ok(result, "Failed to destroy hash2, got %x\n", GetLastError());
900 /* Destroy the private key */
901 result = CryptDestroyKey(privKey);
902 ok(result, "Failed to destroy private key, got %x\n", GetLastError());
904 /* Import the public key we obtained earlier */
905 result = CryptImportKey(hProv, pubKeyBuffer, pubKeyLen, 0, 0, &pubKey);
906 ok(result, "Failed to import public key, got %x\n", GetLastError());
908 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash1);
909 ok(result, "Failed to create hash, got %x\n", GetLastError());
911 /* Hash the data to compare with the signed hash */
912 result = CryptHashData(hHash1, tests[i].signData, tests[i].dataLen, 0);
913 ok(result, "Failed to add data to hash1, got %x\n", GetLastError());
915 /* Verify signed hash 1 */
916 result = CryptVerifySignature(hHash1, signValue1, sizeof(signValue1), pubKey, NULL, 0);
917 ok(result, "Failed to verify signature, got %x\n", GetLastError());
919 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
920 ok(result, "Failed to create hash, got %x\n", GetLastError());
922 /* Hash the data to compare with the signed hash */
923 result = CryptHashData(hHash2, tests[i].signData, tests[i].dataLen, 0);
924 ok(result, "Failed to add data to hash2, got %x\n", GetLastError());
926 /* Verify signed hash 2 */
927 result = CryptVerifySignature(hHash2, signValue2, sizeof(signValue2), pubKey, NULL, 0);
928 ok(result, "Failed to verify signature, got %x\n", GetLastError());
930 result = CryptDestroyHash(hHash1);
931 ok(result, "Failed to destroy hash1, got %x\n", GetLastError());
932 result = CryptDestroyHash(hHash2);
933 ok(result, "Failed to destroy hash2, got %x\n", GetLastError());
935 /* Destroy the public key */
936 result = CryptDestroyKey(pubKey);
937 ok(result, "Failed to destroy public key, got %x\n", GetLastError());
941 static void test_verify_signature(void)
943 HCRYPTPROV hProv = 0;
946 /* acquire base dss provider */
947 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, 0);
950 skip("DSSENH is currently not available, skipping signature verification tests.\n");
953 ok(result, "Failed to acquire CSP.\n");
955 test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
957 result = CryptReleaseContext(hProv, 0);
958 ok(result, "Failed to release CSP provider.\n");
960 /* acquire diffie hellman dss provider */
961 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_DH_PROV, PROV_DSS_DH, 0);
962 ok(result, "Failed to acquire CSP.\n");
964 test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
966 result = CryptReleaseContext(hProv, 0);
967 ok(result, "Failed to release CSP provider.\n");
969 /* acquire enhanced dss provider */
970 SetLastError(0xdeadbeef);
971 result = CryptAcquireContextA(&hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, 0);
972 if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
974 win_skip("DSSENH and Schannel provider is broken on WinNT4, skipping signature "
975 "verification tests.\n");
978 ok(result, "Failed to acquire CSP.\n");
980 test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
982 result = CryptReleaseContext(hProv, 0);
983 ok(result, "Failed to release CSP provider.\n");
985 /* acquire schannel dss provider */
986 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DH_SCHANNEL_PROV, PROV_DH_SCHANNEL, 0);
987 ok(result, "Failed to acquire CSP.\n");
989 test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
991 result = CryptReleaseContext(hProv, 0);
992 ok(result, "Failed to release CSP provider.\n");
995 struct keyExchange_test {
997 const BYTE *primeNum;
999 const BYTE *generatorNum;
1003 /* AT_KEYEXCHANGE interprets to CALG_DH_SF by the DSSENH cryptographic service provider */
1004 static const BYTE primeAT_KEYEXCHANGE[] = {
1005 0x65,0x28,0x24,0xd8,0xbe,0x3f,0x95,0x93, 0x3c,0x4d,0x1b,0x51,0xe1,0x89,0x9a,0x90,
1006 0x5e,0xa0,0x6c,0x25,0xf0,0xb5,0x93,0x98, 0xba,0x76,0x9d,0x54,0x78,0xf6,0xdc,0x04,
1007 0xe1,0xd0,0x87,0x8f,0xa0,0xe4,0x2f,0xb4, 0x09,0x78,0x24,0xbf,0xc8,0x7f,0x59,0xf4,
1008 0x07,0xee,0x07,0x20,0x1b,0x2d,0x54,0x2a, 0xb5,0xb4,0x8f,0x8c,0x33,0x73,0xec,0xaf
1011 static const BYTE generatorAT_KEYEXCHANGE[] = {
1012 0xdc,0x62,0x20,0xe7,0x36,0xa2,0xa6,0xef, 0x77,0x91,0xa8,0xa3,0x6d,0x60,0x70,0x0d,
1013 0x1d,0x79,0xb1,0xbe,0xa8,0x87,0x69,0x39, 0x29,0xaa,0x54,0x27,0x05,0xe6,0x6f,0xa5,
1014 0xde,0x82,0x00,0x5d,0x87,0x1f,0x84,0xf7, 0x40,0xec,0x6f,0x15,0x64,0x02,0x0d,0xb8,
1015 0x50,0x48,0x94,0x66,0xb2,0x7d,0xbd,0xf2, 0x66,0xf8,0x40,0x62,0x94,0xbf,0x24,0x3b
1018 static const BYTE primeCALG_DH_EPHEM[] = {
1019 0x17,0x99,0xa9,0x79,0x31,0xb9,0x05,0xdd, 0x7f,0xf0,0x02,0x11,0x4d,0x0d,0xc3,0x81,
1020 0x8b,0x41,0x50,0x41,0x5f,0x07,0xe6,0x8d, 0x02,0xf9,0xaa,0x86,0x2a,0x07,0x07,0xea,
1021 0x0a,0x75,0xed,0x96,0xa7,0x85,0xee,0xac, 0xb1,0x71,0xbd,0x57,0x48,0xbd,0x41,0x0b,
1022 0xde,0x34,0xe2,0xba,0x5b,0x55,0x64,0x77, 0x84,0xfa,0x96,0xd1,0xaf,0x79,0x49,0x9d
1025 static const BYTE generatorCALG_DH_EPHEM[] = {
1026 0xc7,0x64,0x56,0xde,0xf7,0xb4,0xd3,0xd8, 0xa2,0xd4,0x12,0x2d,0x54,0x5c,0x54,0xc8,
1027 0x04,0x11,0x88,0x14,0x6c,0x9f,0x88,0x41, 0x82,0x93,0x32,0xb1,0x82,0x84,0x5b,0x07,
1028 0x55,0x13,0x82,0x7a,0x64,0x7b,0x12,0x09, 0xe2,0xa0,0x28,0x51,0xf4,0x7a,0xd9,0x26,
1029 0x86,0x95,0x5f,0xc0,0x9a,0x25,0xc2,0x7e, 0x91,0x14,0xdd,0x3c,0x4e,0x86,0x4f,0x6f
1032 static const BYTE primeCALG_DH_SF[] = {
1033 0x85,0xb8,0xa5,0x4a,0xcf,0x2b,0x7c,0x61, 0xb2,0x06,0x93,0x8a,0x87,0x37,0x58,0xb0,
1034 0x8d,0xc7,0x2a,0xa7,0x7f,0x0d,0x74,0xf9, 0x3a,0x7e,0xbc,0xab,0x3a,0x54,0xe4,0x11,
1035 0x69,0x6f,0xcd,0xea,0xad,0x32,0x44,0x4f, 0xee,0x54,0x69,0x8c,0x9c,0x3b,0x87,0x27,
1036 0x36,0x70,0x06,0xf3,0x4e,0xde,0x7f,0x9d, 0xa6,0xf2,0xad,0x43,0x90,0xdd,0xb5,0x9b
1039 static const BYTE generatorCALG_DH_SF[] = {
1040 0xea,0xdc,0xe0,0xbb,0x60,0x26,0xc6,0xb3, 0x93,0x6f,0x61,0xe6,0x7e,0xe2,0xee,0xd6,
1041 0xdb,0x3d,0xca,0xa8,0x31,0x46,0x8f,0x5d, 0xb4,0xaa,0x83,0xd3,0x52,0x10,0xcd,0xfb,
1042 0xfd,0xfc,0x14,0x89,0x0c,0xde,0xcf,0x54, 0x1d,0x05,0x8c,0xbe,0x4a,0xe4,0x37,0xb4,
1043 0xc0,0x15,0x75,0xc5,0xa2,0xfc,0x99,0xfc, 0xad,0x63,0xcb,0x7c,0xb8,0x20,0xdc,0x2b
1046 static const struct keyExchange_test baseDSSkey_data[] = {
1047 /* Cannot exchange keys using the base DSS provider, except on WinNT4 */
1048 {AT_KEYEXCHANGE, primeAT_KEYEXCHANGE, sizeof(primeAT_KEYEXCHANGE), generatorAT_KEYEXCHANGE,
1049 sizeof(generatorAT_KEYEXCHANGE)},
1050 {CALG_DH_EPHEM, primeCALG_DH_EPHEM, sizeof(primeCALG_DH_EPHEM), generatorCALG_DH_EPHEM,
1051 sizeof(generatorCALG_DH_EPHEM)},
1052 {CALG_DH_SF, primeCALG_DH_SF, sizeof(generatorCALG_DH_SF), generatorCALG_DH_SF,
1053 sizeof(generatorCALG_DH_SF)}
1056 static const struct keyExchange_test dssDHkey_data[] = {
1057 {AT_KEYEXCHANGE, primeAT_KEYEXCHANGE, sizeof(primeAT_KEYEXCHANGE), generatorAT_KEYEXCHANGE,
1058 sizeof(generatorAT_KEYEXCHANGE)},
1059 {CALG_DH_EPHEM, primeCALG_DH_EPHEM, sizeof(primeCALG_DH_EPHEM), generatorCALG_DH_EPHEM,
1060 sizeof(generatorCALG_DH_EPHEM)},
1061 {CALG_DH_SF, primeCALG_DH_SF, sizeof(generatorCALG_DH_SF), generatorCALG_DH_SF,
1062 sizeof(generatorCALG_DH_SF)}
1065 static void test_keyExchange_baseDSS(HCRYPTPROV hProv, const struct keyExchange_test *tests, int testLen)
1067 HCRYPTKEY privKey1 = 0, privKey2 = 0;
1068 HCRYPTKEY sessionKey1 = 0, sessionKey2 = 0;
1069 const char plainText[] = "Testing shared key.";
1070 unsigned char pbData1[36];
1071 unsigned char pbData2[36];
1072 BYTE pubKeyBuffer1[512], pubKeyBuffer2[512];
1073 DWORD pubKeyLen1, pubKeyLen2, dataLen;
1074 DATA_BLOB Prime, Generator;
1075 int plainLen = sizeof(plainText), i;
1079 for(i = 0; i < testLen; i++)
1081 SetLastError(0xdeadbeef);
1083 /* Create the data blobs and the prime and generator */
1084 Prime.cbData = tests[i].primeLen;
1085 Prime.pbData = (BYTE *)tests[i].primeNum;
1086 Generator.cbData = tests[i].generatorLen;
1087 Generator.pbData = (BYTE *)tests[i].generatorNum;
1089 /* Generate key exchange keys for user1 and user2 */
1090 result = CryptGenKey(hProv, tests[i].algid, 512 << 16 | CRYPT_PREGEN, &privKey1);
1091 ok((!result && GetLastError() == NTE_BAD_ALGID) || broken(result), /* WinNT4 */
1092 "Expected NTE_BAD_ALGID, got %x\n", GetLastError());
1094 result = CryptGenKey(hProv, tests[i].algid, 512 << 16 | CRYPT_PREGEN, &privKey2);
1095 ok((!result && GetLastError() == NTE_BAD_ALGID) || broken(result), /* WinNT4 */
1096 "Expected NTE_BAD_ALGID, got %x\n", GetLastError());
1098 /* Set the prime and generator values, which are agreed upon */
1099 result = CryptSetKeyParam(privKey1, KP_P, (BYTE *)&Prime, 0);
1100 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1101 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1103 result = CryptSetKeyParam(privKey2, KP_P, (BYTE *)&Prime, 0);
1104 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1105 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1107 result = CryptSetKeyParam(privKey1, KP_G, (BYTE *)&Generator, 0);
1108 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1109 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1111 result = CryptSetKeyParam(privKey2, KP_G, (BYTE *)&Generator, 0);
1112 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1113 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1115 /* Generate the secret value for user1 and user2 */
1116 result = CryptSetKeyParam(privKey1, KP_X, NULL, 0);
1117 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1118 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1120 result = CryptSetKeyParam(privKey2, KP_X, NULL, 0);
1121 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1122 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1124 /* Acquire required size for the public keys */
1125 result = CryptExportKey(privKey1, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen1);
1126 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1127 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1129 result = CryptExportKey(privKey2, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen2);
1130 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1131 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1133 /* Export public key which will be calculated into the shared key */
1134 result = CryptExportKey(privKey1, 0, PUBLICKEYBLOB, 0, pubKeyBuffer1, &pubKeyLen1);
1135 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1136 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1138 result = CryptExportKey(privKey2, 0, PUBLICKEYBLOB, 0, pubKeyBuffer2, &pubKeyLen2);
1139 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1140 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1142 /* Import the public key and convert it into a shared key */
1143 result = CryptImportKey(hProv, pubKeyBuffer2, pubKeyLen2, privKey1, 0, &sessionKey1);
1144 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) ||
1145 broken(!result && GetLastError() == NTE_BAD_TYPE) || /* Win2K-W2K8, Win7.64 */
1146 broken(!result && GetLastError() == NTE_BAD_ALGID) || /* W7SP164 (32 bit dssenh) */
1147 broken(result), /* WinNT4 */
1148 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1150 result = CryptImportKey(hProv, pubKeyBuffer1, pubKeyLen1, privKey2, 0, &sessionKey2);
1151 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) ||
1152 broken(!result && GetLastError() == NTE_BAD_TYPE) || /* Win2K-W2K8, Win7.64 */
1153 broken(!result && GetLastError() == NTE_BAD_ALGID) || /* W7SP164 (32 bit dssenh) */
1154 broken(result), /* WinNT4 */
1155 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1157 /* Set the shared key parameters to matching type */
1159 result = CryptSetKeyParam(sessionKey1, KP_ALGID, (BYTE *)&algid, 0);
1160 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1161 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1164 result = CryptSetKeyParam(sessionKey2, KP_ALGID, (BYTE *)&algid, 0);
1165 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1166 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1168 /* Encrypt some data and verify we are getting the same output */
1169 memcpy(pbData1, plainText, plainLen);
1172 result = CryptEncrypt(sessionKey1, 0, TRUE, 0, pbData1, &dataLen, 36);
1173 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1174 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1176 result = CryptDecrypt(sessionKey2, 0, TRUE, 0, pbData1, &dataLen);
1177 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1178 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1180 ok(!memcmp(pbData1, (BYTE *)plainText, sizeof(plainText)), "Incorrect decrypted data.\n");
1182 memcpy(pbData2, plainText, plainLen);
1185 result = CryptEncrypt(sessionKey2, 0, TRUE, 0, pbData2, &dataLen, 36);
1186 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1187 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1189 result = CryptDecrypt(sessionKey1, 0, TRUE, 0, pbData2, &dataLen);
1190 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1191 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1193 ok(!memcmp(pbData1, pbData2, dataLen), "Decrypted data is not identical.\n");
1195 /* Destroy all user keys */
1196 result = CryptDestroyKey(sessionKey1);
1197 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1198 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1200 result = CryptDestroyKey(sessionKey2);
1201 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1202 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1204 result = CryptDestroyKey(privKey1);
1205 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1206 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1208 result = CryptDestroyKey(privKey2);
1209 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1210 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1214 static void test_keyExchange_dssDH(HCRYPTPROV hProv, const struct keyExchange_test *tests, int testLen)
1216 HCRYPTKEY privKey1 = 0, privKey2 = 0;
1217 HCRYPTKEY sessionKey1 = 0, sessionKey2 = 0;
1218 const char plainText[] = "Testing shared key.";
1219 unsigned char pbData1[36];
1220 unsigned char pbData2[36];
1221 BYTE pubKeyBuffer1[512], pubKeyBuffer2[512];
1222 DWORD pubKeyLen1, pubKeyLen2, dataLen;
1223 DATA_BLOB Prime, Generator;
1224 int plainLen = sizeof(plainText), i;
1228 for(i = 0; i < testLen; i++)
1230 SetLastError(0xdeadbeef);
1232 /* Create the data blobs and the prime and generator */
1233 Prime.cbData = tests[i].primeLen;
1234 Prime.pbData = (BYTE *)tests[i].primeNum;
1235 Generator.cbData = tests[i].generatorLen;
1236 Generator.pbData = (BYTE *)tests[i].generatorNum;
1238 /* Generate key exchange keys for user1 and user2 */
1239 result = CryptGenKey(hProv, tests[i].algid, 512 << 16 | CRYPT_PREGEN, &privKey1);
1240 ok(result, "Failed to generate a key for user1, got %x\n", GetLastError());
1242 result = CryptGenKey(hProv, tests[i].algid, 512 << 16 | CRYPT_PREGEN, &privKey2);
1243 ok(result, "Failed to generate a key for user2, got %x\n", GetLastError());
1245 /* Set the prime and generator values, which are agreed upon */
1246 result = CryptSetKeyParam(privKey1, KP_P, (BYTE *)&Prime, 0);
1247 ok(result, "Failed to set prime for user 1's key, got %x\n", GetLastError());
1249 result = CryptSetKeyParam(privKey2, KP_P, (BYTE *)&Prime, 0);
1250 ok(result, "Failed to set prime for user 2's key, got %x\n", GetLastError());
1252 result = CryptSetKeyParam(privKey1, KP_G, (BYTE *)&Generator, 0);
1253 ok(result, "Failed to set generator for user 1's key, got %x\n", GetLastError());
1255 result = CryptSetKeyParam(privKey2, KP_G, (BYTE *)&Generator, 0);
1256 ok(result, "Failed to set generator for user 2's key, got %x\n", GetLastError());
1258 /* Generate the secret value for user1 and user2 */
1259 result = CryptSetKeyParam(privKey1, KP_X, NULL, 0);
1260 ok(result || broken(!result && GetLastError() == ERROR_INVALID_PARAMETER),
1261 "Failed to set secret value for user 1, got %x\n", GetLastError());/* Win2k & WinXP */
1263 result = CryptSetKeyParam(privKey2, KP_X, NULL, 0);
1264 ok(result || broken(!result && GetLastError() == ERROR_INVALID_PARAMETER),
1265 "Failed to set secret value for user 2, got %x\n", GetLastError());/* Win2k & WinXP */
1267 /* Acquire required size for the public keys */
1268 result = CryptExportKey(privKey1, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen1);
1269 ok(result, "Failed to acquire public key length for user 1, got %x\n", GetLastError());
1271 result = CryptExportKey(privKey2, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen2);
1272 ok(result, "Failed to acquire public key length for user 2, got %x\n", GetLastError());
1274 /* Export public key which will be calculated into the shared key */
1275 result = CryptExportKey(privKey1, 0, PUBLICKEYBLOB, 0, pubKeyBuffer1, &pubKeyLen1);
1276 ok(result, "Failed to export public key for user 1, got %x\n", GetLastError());
1278 result = CryptExportKey(privKey2, 0, PUBLICKEYBLOB, 0, pubKeyBuffer2, &pubKeyLen2);
1279 ok(result, "Failed to export public key for user 2, got %x\n", GetLastError());
1281 /* Import the public key and convert it into a shared key */
1282 result = CryptImportKey(hProv, pubKeyBuffer2, pubKeyLen2, privKey1, 0, &sessionKey1);
1283 ok(result, "Failed to import key for user 1, got %x\n", GetLastError());
1285 result = CryptImportKey(hProv, pubKeyBuffer1, pubKeyLen1, privKey2, 0, &sessionKey2);
1286 ok(result, "Failed to import key for user 2, got %x\n", GetLastError());
1288 /* Set the shared key parameters to matching cipher type */
1290 result = CryptSetKeyParam(sessionKey1, KP_ALGID, (BYTE *)&algid, 0);
1291 ok(result, "Failed to set session key for user 1, got %x\n", GetLastError());
1294 result = CryptSetKeyParam(sessionKey2, KP_ALGID, (BYTE *)&algid, 0);
1295 ok(result, "Failed to set session key for user 2, got %x\n", GetLastError());
1297 /* Encrypt some data and verify we are getting the correct output */
1298 memcpy(pbData1, plainText, plainLen);
1301 result = CryptEncrypt(sessionKey1, 0, TRUE, 0, pbData1, &dataLen, 36);
1302 ok(result, "Failed to encrypt data, got %x.\n", GetLastError());
1304 result = CryptDecrypt(sessionKey2, 0, TRUE, 0, pbData1, &dataLen);
1305 ok(result, "Failed to decrypt data, got %x.\n", GetLastError());
1307 ok(!memcmp(pbData1, (BYTE *)plainText, sizeof(plainText)), "Incorrect decrypted data.\n");
1309 memcpy(pbData2, plainText, plainLen);
1312 result = CryptEncrypt(sessionKey2, 0, TRUE, 0, pbData2, &dataLen, 36);
1313 ok(result, "Failed to encrypt data, got %x.\n", GetLastError());
1315 result = CryptDecrypt(sessionKey1, 0, TRUE, 0, pbData2, &dataLen);
1316 ok(result, "Failed to decrypt data, got %x.\n", GetLastError());
1318 ok(!memcmp(pbData1, pbData2, dataLen), "Decrypted data is not identical.\n");
1320 /* Destroy all user keys */
1321 result = CryptDestroyKey(sessionKey1);
1322 ok(result, "Failed to destroy session key 1, got %x\n", GetLastError());
1324 result = CryptDestroyKey(sessionKey2);
1325 ok(result, "Failed to destroy session key 2, got %x\n", GetLastError());
1327 result = CryptDestroyKey(privKey1);
1328 ok(result, "Failed to destroy key private key 1, got %x\n", GetLastError());
1330 result = CryptDestroyKey(privKey2);
1331 ok(result, "Failed to destroy key private key 2, got %x\n", GetLastError());
1335 static void test_key_exchange(void)
1337 HCRYPTPROV hProv = 0;
1340 /* acquire base dss provider */
1341 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
1344 skip("DSSENH is currently not available, skipping shared key tests.\n");
1347 ok(result, "Failed to acquire CSP.\n");
1349 test_keyExchange_baseDSS(hProv, baseDSSkey_data, TESTLEN(baseDSSkey_data));
1351 result = CryptReleaseContext(hProv, 0);
1352 ok(result, "Failed to release CSP provider.\n");
1354 /* acquire diffie hellman dss provider */
1355 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_DH_PROV, PROV_DSS_DH,
1356 CRYPT_VERIFYCONTEXT);
1357 ok(result, "Failed to acquire CSP.\n");
1359 test_keyExchange_dssDH(hProv, dssDHkey_data, TESTLEN(dssDHkey_data));
1361 result = CryptReleaseContext(hProv, 0);
1362 ok(result, "Failed to release CSP provider.\n");
1364 /* acquire enhanced dss provider */
1365 result = CryptAcquireContextA(&hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH,
1366 CRYPT_VERIFYCONTEXT);
1367 if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
1369 win_skip("DSSENH and Schannel provider is broken on WinNT4, skipping shared key tests.\n");
1372 ok(result, "Failed to acquire CSP.\n");
1374 test_keyExchange_dssDH(hProv, dssDHkey_data, TESTLEN(dssDHkey_data));
1376 result = CryptReleaseContext(hProv, 0);
1377 ok(result, "Failed to release CSP provider.\n");
1379 /* acquire schannel dss provider */
1380 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DH_SCHANNEL_PROV, PROV_DH_SCHANNEL,
1381 CRYPT_VERIFYCONTEXT);
1382 ok(result, "Failed to acquire CSP.\n");
1384 test_keyExchange_dssDH(hProv, dssDHkey_data, TESTLEN(dssDHkey_data));
1386 result = CryptReleaseContext(hProv, 0);
1387 ok(result, "Failed to release CSP provider.\n");
1392 test_acquire_context();
1394 test_hash(hash_data, TESTLEN(hash_data));
1395 test_data_encryption(encrypt_data, TESTLEN(encrypt_data));
1396 test_cipher_modes(ciphermode_data, TESTLEN(ciphermode_data));
1397 test_verify_signature();
1398 test_key_exchange();