wined3d: Use correct initial color for FFP texture blending in GLSL backend.
[wine.git] / dlls / dssenh / tests / dssenh.c
blobfeb9a30867fa856b2ebef4bb3037aee307142668
1 /*
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
21 #include <string.h>
22 #include <stdio.h>
23 #include "ntstatus.h"
24 #define WIN32_NO_STATUS
25 #include "wine/test.h"
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winerror.h"
29 #include "wincrypt.h"
31 static void test_acquire_context(void)
32 { /* failure tests common between all four CSP providers */
34 HCRYPTPROV hProv = 0;
35 BOOL result;
37 /* cannot acquire provider with 0 as Prov Type and NULL as CSP name */
38 SetLastError(0xdeadbeef);
39 result = CryptAcquireContextA(&hProv, NULL, NULL, 0, 0);
40 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
41 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
43 SetLastError(0xdeadbeef);
44 result = CryptAcquireContextA(&hProv, NULL, NULL, 0, CRYPT_VERIFYCONTEXT);
45 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
46 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
48 /* flag allows us to delete a keyset, but not of an unknown provider */
49 SetLastError(0xdeadbeef);
50 result = CryptAcquireContextA(&hProv, NULL, NULL, 0, CRYPT_DELETEKEYSET);
51 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
52 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
54 /* cannot acquire along with PROV_RSA_SIG, not compatible */
55 SetLastError(0xdeadbeef);
56 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_RSA_SIG, 0);
57 todo_wine
58 ok(!result && GetLastError() == NTE_PROV_TYPE_NO_MATCH,
59 "Expected NTE_PROV_TYPE_NO_MATCH, got %08x\n", GetLastError());
61 /* cannot acquire along with MS_DEF_RSA_SIG_PROV_A, not compatible */
62 SetLastError(0xdeadbeef);
63 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_RSA_SIG_PROV_A, PROV_DSS, 0);
64 ok(!result && GetLastError() == NTE_KEYSET_NOT_DEF,
65 "Expected NTE_KEYSET_NOT_DEF, got %08x\n", GetLastError());
67 /* cannot acquire provider with 0 as Prov Type */
68 SetLastError(0xdeadbeef);
69 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, 0, 0);
70 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
71 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
73 /* test base DSS provider (PROV_DSS) */
75 result = CryptAcquireContextA(
76 &hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
77 if(!result)
79 skip("DSS csp is currently not available, skipping tests.\n");
80 return;
82 ok(result, "Expected no errors.\n");
84 result = CryptReleaseContext(hProv, 0);
85 ok(result, "Expected release of the provider.\n");
87 result = CryptAcquireContextA(
88 &hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_NEWKEYSET);
89 ok(result, "Expected no errors.\n");
91 result = CryptReleaseContext(hProv, 0);
92 ok(result, "Expected release of the provider.\n");
94 result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DSS, 0);
95 ok(result, "Expected no errors.\n");
97 result = CryptReleaseContext(hProv, 0);
98 ok(result, "Expected release of the provider.\n");
100 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, 0);
101 ok(result, "Expected no errors.\n");
103 /* test DSS Diffie Hellman provider (PROV_DSS_DH) */
105 result = CryptAcquireContextA(
106 &hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
107 ok(result, "Expected no errors.\n");
109 result = CryptReleaseContext(hProv, 0);
110 ok(result, "Expected release of the provider.\n");
112 result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DSS_DH, 0);
113 ok(result, "Expected no errors.\n");
115 result = CryptReleaseContext(hProv, 0);
116 ok(result, "Expected release of the provider.\n");
118 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, 0);
119 ok(result, "Expected no errors.\n");
121 /* test DSS Enhanced provider (MS_ENH_DSS_DH_PROV_A) */
123 SetLastError(0xdeadbeef);
124 result = CryptAcquireContextA(
125 &hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
126 if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
128 win_skip("DSSENH and Schannel provider is broken on WinNT4\n");
129 return;
131 ok(result, "Expected no errors.\n");
133 result = CryptReleaseContext(hProv, 0);
134 ok(result, "Expected release of the provider.\n");
136 result = CryptAcquireContextA(&hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, 0);
137 ok(result, "Expected no errors.\n");
139 result = CryptReleaseContext(hProv, 0);
140 ok(result, "Expected release of the provider.\n");
142 /* test DSS Schannel provider (PROV_DH_SCHANNEL) */
144 result = CryptAcquireContextA(
145 &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV_A, PROV_DH_SCHANNEL, CRYPT_VERIFYCONTEXT);
146 ok(result, "Expected no errors.\n");
148 result = CryptReleaseContext(hProv, 0);
149 ok(result, "Expected release of the provider.\n");
151 result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DH_SCHANNEL, 0);
152 ok(result, "Expected no errors.\n");
154 result = CryptReleaseContext(hProv, 0);
155 ok(result, "Expected release of the provider.\n");
157 result = CryptAcquireContextA(
158 &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV_A, PROV_DH_SCHANNEL, 0);
159 ok(result, "Expected no errors.\n");
161 result = CryptReleaseContext(hProv, 0);
162 ok(result, "Expected release of the provider.\n");
164 /* failure tests, cannot acquire context because the key container already exists */
165 SetLastError(0xdeadbeef);
166 result = CryptAcquireContextA(
167 &hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_NEWKEYSET);
168 ok(!result && GetLastError() == NTE_EXISTS,
169 "Expected NTE_EXISTS, got %08x\n", GetLastError());
171 SetLastError(0xdeadbeef);
172 result = CryptAcquireContextA(
173 &hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_NEWKEYSET);
174 ok(!result && GetLastError() == NTE_EXISTS,
175 "Expected NTE_EXISTS, got %08x\n", GetLastError());
177 SetLastError(0xdeadbeef);
178 result = CryptAcquireContextA(
179 &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV_A, PROV_DH_SCHANNEL, CRYPT_NEWKEYSET);
180 ok(!result && GetLastError() == NTE_EXISTS,
181 "Expected NTE_EXISTS, got %08x\n", GetLastError());
184 struct keylength_test {
185 ALG_ID algid;
186 DWORD flags;
187 BOOL expectedResult;
188 DWORD expectedError;
189 BOOL brokenResult;
190 DWORD brokenError;
191 DWORD altError;
194 static const struct keylength_test baseDSS_keylength[] = {
195 /* AT_KEYEXCHANGE is not supported by the base DSS provider */
196 {AT_KEYEXCHANGE, 448 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
197 {AT_KEYEXCHANGE, 512 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
198 {AT_KEYEXCHANGE, 1024 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
199 {AT_KEYEXCHANGE, 1088 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS},/* WinNT4 and Win2k */
200 /* min 512 max 1024 increment by 64 */
201 {AT_SIGNATURE, 448 << 16, FALSE, NTE_BAD_FLAGS},
202 {AT_SIGNATURE, 512 << 16, TRUE},
203 {AT_SIGNATURE, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS, STATUS_INVALID_PARAMETER}, /* WinNT4 and Win2k */
204 {AT_SIGNATURE, 768 << 16, TRUE},
205 {AT_SIGNATURE, 1024 << 16, TRUE},
206 {AT_SIGNATURE, 1088 << 16, FALSE, NTE_BAD_FLAGS},
207 /* CALG_DH_EPHEM is not supported by the base DSS provider */
208 {CALG_DH_EPHEM, 448 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
209 {CALG_DH_EPHEM, 512 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
210 {CALG_DH_EPHEM, 1024 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
211 {CALG_DH_EPHEM, 1088 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
212 /* CALG_DH_SF is not supported by the base DSS provider */
213 {CALG_DH_SF, 448 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
214 {CALG_DH_SF, 512 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
215 {CALG_DH_SF, 1024 << 16, FALSE, NTE_BAD_ALGID, TRUE}, /* success on WinNT4 */
216 {CALG_DH_SF, 1088 << 16, FALSE, NTE_BAD_ALGID, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
217 /* min 512 max 1024, increment by 64 */
218 {CALG_DSS_SIGN, 448 << 16, FALSE, NTE_BAD_FLAGS},
219 {CALG_DSS_SIGN, 512 << 16, TRUE},
220 {CALG_DSS_SIGN, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS, STATUS_INVALID_PARAMETER}, /* WinNT4 and Win2k */
221 {CALG_DSS_SIGN, 768 << 16, TRUE},
222 {CALG_DSS_SIGN, 1024 << 16, TRUE},
223 {CALG_DSS_SIGN, 1088 << 16, FALSE, NTE_BAD_FLAGS}
226 static const struct keylength_test dssDH_keylength[] = {
227 /* min 512 max 1024, increment by 64 */
228 {AT_KEYEXCHANGE, 448 << 16, FALSE, NTE_BAD_FLAGS},
229 {AT_KEYEXCHANGE, 512 << 16, TRUE},
230 {AT_KEYEXCHANGE, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
231 {AT_KEYEXCHANGE, 768 << 16, TRUE},
232 {AT_KEYEXCHANGE, 1024 << 16, TRUE},
233 {AT_KEYEXCHANGE, 1088 << 16, FALSE, NTE_BAD_FLAGS},
234 {AT_SIGNATURE, 448 << 16, FALSE, NTE_BAD_FLAGS},
235 {AT_SIGNATURE, 512 << 16, TRUE},
236 {AT_SIGNATURE, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS, STATUS_INVALID_PARAMETER}, /* WinNT4 and Win2k */
237 {AT_SIGNATURE, 768 << 16, TRUE},
238 {AT_SIGNATURE, 1024 << 16, TRUE},
239 {AT_SIGNATURE, 1088 << 16, FALSE, NTE_BAD_FLAGS},
240 {CALG_DH_EPHEM, 448 << 16, FALSE, NTE_BAD_FLAGS},
241 {CALG_DH_EPHEM, 512 << 16, TRUE},
242 {CALG_DH_EPHEM, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
243 {CALG_DH_EPHEM, 768 << 16, TRUE},
244 {CALG_DH_EPHEM, 1024 << 16, TRUE},
245 {CALG_DH_EPHEM, 1088 << 16, FALSE, NTE_BAD_FLAGS},
246 {CALG_DH_SF, 448 << 16, FALSE, NTE_BAD_FLAGS},
247 {CALG_DH_SF, 512 << 16, TRUE},
248 {CALG_DH_SF, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
249 {CALG_DH_SF, 768 << 16, TRUE},
250 {CALG_DH_SF, 1024 << 16, TRUE},
251 {CALG_DH_SF, 1088 << 16, FALSE, NTE_BAD_FLAGS},
252 {CALG_DSS_SIGN, 448 << 16, FALSE, NTE_BAD_FLAGS},
253 {CALG_DSS_SIGN, 512 << 16, TRUE},
254 {CALG_DSS_SIGN, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS, STATUS_INVALID_PARAMETER}, /* WinNT4 and Win2k */
255 {CALG_DSS_SIGN, 768 << 16, TRUE},
256 {CALG_DSS_SIGN, 1024 << 16, TRUE},
257 {CALG_DSS_SIGN, 1088 << 16, FALSE, NTE_BAD_FLAGS}
260 static const struct keylength_test dssENH_keylength[] = {
261 /* min 512 max 1024 (AT_KEYEXCHANGE max 4096), increment by 64*/
262 {AT_KEYEXCHANGE, 448 << 16, FALSE, NTE_BAD_FLAGS},
263 {AT_KEYEXCHANGE, 512 << 16, TRUE},
264 {AT_KEYEXCHANGE, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
265 {AT_KEYEXCHANGE, 768 << 16, TRUE},
266 {AT_KEYEXCHANGE, 1024 << 16, TRUE},
267 {AT_KEYEXCHANGE, 1088 << 16, TRUE},
268 {AT_KEYEXCHANGE, 2048 << 16, TRUE},
269 /* Keylength too large - test bot timeout.
270 {AT_KEYEXCHANGE, 3072 << 16, TRUE},
271 {AT_KEYEXCHANGE, 4096 << 16, TRUE}, */
272 {AT_KEYEXCHANGE, 4160 << 16, FALSE, NTE_BAD_FLAGS},
273 {AT_SIGNATURE, 448 << 16, FALSE, NTE_BAD_FLAGS},
274 {AT_SIGNATURE, 512 << 16, TRUE},
275 {AT_SIGNATURE, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS, STATUS_INVALID_PARAMETER}, /* WinNT4 and Win2k */
276 {AT_SIGNATURE, 768 << 16, TRUE},
277 {AT_SIGNATURE, 1024 << 16, TRUE},
278 {AT_SIGNATURE, 1032 << 16, FALSE, NTE_BAD_FLAGS},
279 {CALG_DH_EPHEM, 448 << 16, FALSE, NTE_BAD_FLAGS},
280 {CALG_DH_EPHEM, 512 << 16, TRUE},
281 {CALG_DH_EPHEM, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
282 {CALG_DH_EPHEM, 768 << 16, TRUE},
283 {CALG_DH_EPHEM, 1024 << 16, TRUE},
284 {CALG_DH_EPHEM, 1040 << 16, FALSE, NTE_BAD_FLAGS},
285 {CALG_DH_SF, 448 << 16, FALSE, NTE_BAD_FLAGS},
286 {CALG_DH_SF, 512 << 16, TRUE},
287 {CALG_DH_SF, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS}, /* WinNT4 and Win2k */
288 {CALG_DH_SF, 768 << 16, TRUE},
289 {CALG_DH_SF, 1024 << 16, TRUE},
290 {CALG_DH_SF, 1032 << 16, FALSE, NTE_BAD_FLAGS},
291 {CALG_DSS_SIGN, 448 << 16, FALSE, NTE_BAD_FLAGS},
292 {CALG_DSS_SIGN, 512 << 16, TRUE},
293 {CALG_DSS_SIGN, 513 << 16, FALSE, NTE_FAIL, FALSE, NTE_BAD_FLAGS, STATUS_INVALID_PARAMETER}, /* WinNT4 and Win2k */
294 {CALG_DSS_SIGN, 768 << 16, TRUE},
295 {CALG_DSS_SIGN, 1024 << 16, TRUE},
296 {CALG_DSS_SIGN, 1088 << 16, FALSE, NTE_BAD_FLAGS}
299 static void test_keylength_array(HCRYPTPROV hProv,const struct keylength_test *tests, int testLen)
301 HCRYPTKEY key;
302 BOOL result;
303 int i;
305 for (i = 0; i < testLen; i++)
307 SetLastError(0xdeadbeef);
308 result = CryptGenKey(hProv, tests[i].algid, tests[i].flags, &key);
310 /* success */
311 if(tests[i].expectedResult)
313 ok(result, "%d: Expected a key, got %08x\n", i, GetLastError());
314 result = CryptDestroyKey(key);
315 ok(result, "Expected no errors.\n");
317 else
318 { /* error but success on older system */
319 if(tests[i].brokenResult)
320 ok((!result && GetLastError() == tests[i].expectedError) ||
321 broken(result), "%d: Didn't really expect a key, got %x, %d\n",
322 i, GetLastError(), result);
323 else
325 /* error */
326 if(!tests[i].brokenError)
327 ok(!result && GetLastError() == tests[i].expectedError,
328 "%d: Expected an error, got %x, %d.\n", i, GetLastError(), result);
330 /* error but different error on older system */
331 else
332 ok(!result && (GetLastError() == tests[i].expectedError ||
333 GetLastError() == tests[i].altError ||
334 broken(GetLastError() == tests[i].brokenError) ),
335 "%d: Expected an error, got %x, %d.\n", i, GetLastError(), result);
341 #define TESTLEN(x) (sizeof(x) / sizeof((x)[0]))
343 static void test_keylength(void)
345 HCRYPTPROV hProv = 0;
346 BOOL result;
348 /* acquire base dss provider */
349 result = CryptAcquireContextA(
350 &hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
351 if(!result)
353 skip("DSSENH is currently not available, skipping key length tests.\n");
354 return;
356 ok(result, "Expected no errors.\n");
358 /* perform keylength tests */
359 test_keylength_array(hProv, baseDSS_keylength, TESTLEN(baseDSS_keylength));
361 result = CryptReleaseContext(hProv, 0);
362 ok(result, "Expected release of CSP provider.\n");
364 /* acquire diffie hellman dss provider */
365 result = CryptAcquireContextA(
366 &hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
367 ok(result, "Expected no errors.\n");
369 /* perform keylength tests */
370 test_keylength_array(hProv, dssDH_keylength, TESTLEN(dssDH_keylength));
372 result = CryptReleaseContext(hProv, 0);
373 ok(result, "Expected release of CSP provider.\n");
375 /* acquire enhanced dss provider */
376 SetLastError(0xdeadbeef);
377 result = CryptAcquireContextA(
378 &hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
379 if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
381 win_skip("DSSENH and Schannel provider is broken on WinNT4\n");
382 return;
384 ok(result, "Expected no errors.\n");
386 /* perform keylength tests */
387 test_keylength_array(hProv, dssENH_keylength, TESTLEN(dssENH_keylength));
389 result = CryptReleaseContext(hProv, 0);
390 ok(result, "Expected release of CSP provider.\n");
392 /* acquire schannel dss provider */
393 result = CryptAcquireContextA(
394 &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV_A, PROV_DH_SCHANNEL, CRYPT_VERIFYCONTEXT);
395 ok(result, "Expected no errors.\n");
397 /* perform keylength tests */
398 test_keylength_array(hProv, dssENH_keylength, TESTLEN(dssENH_keylength));
400 result = CryptReleaseContext(hProv, 0);
401 ok(result, "Expected release of CSP provider.\n");
404 struct hash_test {
405 ALG_ID algid;
406 BYTE* input;
407 DWORD dataLen;
408 BYTE hash[20];
409 DWORD hashLen;
412 static const char testHashVal1[] = "I love working with Wine";
413 static const char testHashVal2[] = "Wine is not an emulater.";
414 static const char testHashVal3[] = "";
416 static const struct hash_test hash_data[] = {
417 {CALG_MD5, (BYTE *)testHashVal1, sizeof(testHashVal1),
418 {0x4f, 0xf4, 0xd0, 0xdf, 0xe8, 0xf6, 0x6b, 0x1b,
419 0x87, 0xea, 0xca, 0x3d, 0xe8, 0x3c, 0xdd, 0xae}, 16},
420 {CALG_MD5, (BYTE *)testHashVal2, sizeof(testHashVal2),
421 {0x80, 0x5c, 0x1c, 0x0e, 0x79, 0x70, 0xd9, 0x38,
422 0x04, 0x46, 0x19, 0xbe, 0x38, 0x1f, 0xef, 0xe1}, 16},
423 {CALG_MD5, (BYTE *)testHashVal3, sizeof(testHashVal3),
424 {0x93, 0xb8, 0x85, 0xad, 0xfe, 0x0d, 0xa0, 0x89,
425 0xcd, 0xf6, 0x34, 0x90, 0x4f, 0xd5, 0x9f, 0x71}, 16},
426 {CALG_SHA, (BYTE *)testHashVal1, sizeof(testHashVal1),
427 {0x2a, 0xd0, 0xc9, 0x42, 0xfb, 0x73, 0x02, 0x48, 0xbb, 0x5f,
428 0xc2, 0xa4, 0x78, 0xdd, 0xe4, 0x3b, 0xfc, 0x76, 0xe9, 0xe2}, 20},
429 {CALG_SHA, (BYTE *)testHashVal2, sizeof(testHashVal2),
430 {0xfd, 0xfc, 0xab, 0x3a, 0xde, 0x33, 0x01, 0x38, 0xfe, 0xbb,
431 0xc3, 0x13, 0x84, 0x20, 0x9e, 0x55, 0x94, 0x8d, 0xc6, 0x05}, 20},
432 {CALG_SHA, (BYTE *)testHashVal3, sizeof(testHashVal3),
433 {0x5b, 0xa9, 0x3c, 0x9d, 0xb0, 0xcf, 0xf9, 0x3f, 0x52, 0xb5,
434 0x21, 0xd7, 0x42, 0x0e, 0x43, 0xf6, 0xed, 0xa2, 0x78, 0x4f}, 20}
437 static void test_hash(const struct hash_test *tests, int testLen)
439 HCRYPTPROV hProv = 0;
440 HCRYPTHASH hHash;
441 BYTE hashValue[36];
442 BOOL result;
443 int i;
445 result = CryptAcquireContextA(
446 &hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
447 if(!result)
449 skip("DSSENH is currently not available, skipping hashing tests.\n");
450 return;
452 ok(result, "Expected no errors.\n");
454 for(i = 0; i < testLen; i++)
456 BYTE* data = tests[i].input;
457 DWORD dataLen = tests[i].dataLen;
458 DWORD hashLen;
460 /* test algid hash */
461 result = CryptCreateHash(hProv, tests[i].algid, 0, 0, &hHash);
462 ok(result, "Expected creation of a hash.\n");
464 result = CryptHashData(hHash, data, dataLen, 0);
465 ok(result, "Expected data to be added to hash.\n");
467 dataLen = sizeof(DWORD);
468 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&hashLen, &dataLen, 0);
469 ok(result && (hashLen == tests[i].hashLen), "Expected %d hash len, got %d.Error: %x\n",
470 tests[i].hashLen, hashLen, GetLastError());
472 result = CryptGetHashParam(hHash, HP_HASHVAL, hashValue, &hashLen, 0);
473 ok(result, "Expected hash value return.\n");
475 ok(!memcmp(hashValue, tests[i].hash, tests[i].hashLen), "Incorrect hash output.\n");
477 result = CryptHashData(hHash, data, dataLen, 0);
478 ok(!result, "Should not be able to add to hash.\n");
480 result = CryptDestroyHash(hHash);
481 ok(result, "Expected destruction of hash.\n");
483 result = CryptReleaseContext(hProv, 0);
484 ok(result, "Expected release of the DSS Enhanced provider.\n");
487 struct encrypt_test {
488 ALG_ID algid;
489 DWORD keyLength;
490 const char *plain;
491 DWORD plainLen;
492 const BYTE *decrypted;
493 const BYTE *encrypted;
496 static const char dataToEncrypt1[] = "Great performance with Wine.";
497 static const char dataToEncrypt2[] = "Wine implements Windows API";
498 static const char dataToEncrypt3[] = "";
500 static const BYTE encrypted3DES_1[] = {
501 0x6c,0x60,0x19,0x41,0x27,0xc1,0x16,0x69, 0x6f,0x96,0x0c,0x2e,0xa4,0x5f,0xf5,0x6a,
502 0xed,0x4b,0xec,0xd4,0x92,0x0c,0xe2,0x34, 0xe1,0x4a,0xb5,0xe2,0x05,0x43,0xfe,0x17
504 static const BYTE encrypted3DES_2[] = {
505 0x17,0xeb,0x80,0xde,0xac,0x4d,0x9e,0xd0, 0xa9,0xae,0x74,0xb5,0x86,0x1a,0xea,0xb4,
506 0x96,0x27,0x5d,0x75,0x4f,0xdd,0x87,0x60, 0xfc,0xaf,0xa1,0x82,0x83,0x09,0xf1,0xca
508 static const BYTE encrypted3DES_3[] = {0xaf, 0x36, 0xc0, 0x3d, 0x78, 0x64, 0xc4, 0x4a};
510 static const BYTE encrypted3DES112_1[] = {
511 0xb3,0xf8,0x4b,0x08,0xd6,0x23,0xcb,0xca, 0x43,0x26,0xd9,0x9f,0x6b,0x99,0x09,0xe9,
512 0x8c,0x4c,0x7d,0xef,0x49,0xda,0x0b,0x44, 0xcc,0x8d,0x06,0x6b,0xed,0xb7,0xf1,0x67
514 static const BYTE encrypted3DES112_2[] = {
515 0xdc,0xcf,0x93,0x11,0x7a,0xe4,0xcd,0x3f, 0x11,0xd8,0xe0,0x1e,0xe0,0x8d,0x9c,0xba,
516 0x97,0x5d,0x74,0x4d,0x83,0x03,0x5c,0xf2, 0x01,0xaf,0xed,0x7a,0x87,0x8f,0x88,0x8b
518 static const BYTE encrypted3DES112_3[] = {0x04, 0xb3, 0x9c, 0x59, 0x48, 0xc7, 0x2f, 0xd1};
520 static const BYTE encryptedDES_1[] = {
521 0x3d,0xdc,0x54,0xaf,0x66,0x72,0x4e,0xef, 0x9d,0x35,0x02,0xc2,0x1a,0xf4,0x1f,0x01,
522 0xb1,0xaf,0x13,0xd9,0xbe,0x7b,0xd4,0xf3, 0xf5,0x9d,0x2a,0xd8,0x32,0x90,0xe9,0x0b
524 static const BYTE encryptedDES_2[] = {
525 0xa8,0x05,0xd7,0xe9,0x61,0xf4,0x6c,0xce, 0x95,0x2b,0x52,0x08,0x25,0x03,0x30,0xac,
526 0xd7,0xe7,0xd3,0x07,0xb2,0x68,0x63,0x7b, 0xe3,0xab,0x26,0x1e,0x5c,0xec,0x42,0x4f
528 static const BYTE encryptedDES_3[] = {0x35, 0x02, 0xbb, 0x7c, 0x43, 0x5b, 0xf5, 0x59};
530 static const BYTE encryptedRC2_1[] = {
531 0x9e,0xcb,0xa2,0x27,0xc2,0xec,0x10,0xe0, 0x94,0xb3,0xc3,0x9d,0x7d,0xe2,0x12,0xe4,
532 0xb0,0xde,0xd9,0x46,0xca,0x1f,0xa6,0xfa, 0xa4,0x79,0x08,0x59,0xa6,0x00,0x62,0x16
534 static const BYTE encryptedRC2_2[] = {
535 0x29,0x06,0xfd,0xa1,0xe0,0x88,0x89,0xb0, 0x4d,0x7f,0x96,0x9d,0x2c,0x44,0xa1,0xd2,
536 0xbe,0xc6,0xaf,0x10,0xb8,0x86,0x68,0x1b, 0x1d,0x9f,0x3c,0xc4,0x12,0x02,0xbc,0x73
538 static const BYTE encryptedRC2_3[] = {0x26,0x40,0x73,0xfe,0x13,0xbb,0x32,0xa8};
540 static const BYTE encryptedRC4_1[] = {
541 0x5a,0x48,0xeb,0x16,0x96,0x23,0x16,0xb7, 0xbb,0x36,0xe8,0x43,0x88,0x74,0xb1,0x9d,
542 0x96,0xf0,0x84,0x0f,0x5a,0x56,0xf9,0x62, 0xae,0xb5,0x4a,0xce,0x52
544 static const BYTE encryptedRC4_2[] = {
545 0x4a,0x53,0xe0,0x12,0xc2,0x6a,0x0b,0xa2, 0xa5,0x35,0xea,0x54,0x8b,0x61,0xac,0xde,
546 0xa4,0xb9,0x9d,0x02,0x41,0x49,0xaa,0x15, 0x86,0x8b,0x66,0xe0
548 static const BYTE encryptedRC4_3[] = {0x1d};
550 static const struct encrypt_test encrypt_data[] = {
551 {CALG_3DES, 168 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
552 encrypted3DES_1},
553 {CALG_3DES, 168 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
554 encrypted3DES_2},
555 {CALG_3DES, 168 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
556 encrypted3DES_3},
557 {CALG_3DES_112, 112 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
558 encrypted3DES112_1},
559 {CALG_3DES_112, 112 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
560 encrypted3DES112_2},
561 {CALG_3DES_112, 112 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
562 encrypted3DES112_3},
563 {CALG_DES, 56 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
564 encryptedDES_1},
565 {CALG_DES, 56 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
566 encryptedDES_2},
567 {CALG_DES, 56 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
568 encryptedDES_3},
569 /* CALG_RC2 key unexpected results under Win2K when default key length is used, here we use
570 minimum length because Win2K's DSSENH provider has a different default key length compared
571 to the younger operating systems, though there is no default key len issue with CALG_RC4 */
572 {CALG_RC2, 40 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
573 encryptedRC2_1},
574 {CALG_RC2, 40 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
575 encryptedRC2_2},
576 {CALG_RC2, 40 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
577 encryptedRC2_3},
578 {CALG_RC4, 40 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
579 encryptedRC4_1},
580 {CALG_RC4, 40 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
581 encryptedRC4_2},
582 {CALG_RC4, 40 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
583 encryptedRC4_3}
586 static void test_data_encryption(const struct encrypt_test *tests, int testLen)
587 { /* Here we test the same encryption ciphers as the RSAENH cryptographic service provider */
588 HCRYPTPROV hProv = 0;
589 HCRYPTKEY pKey = 0;
590 HCRYPTHASH hHash;
591 const char dataToHash[] = "I love working with Wine";
592 unsigned char pbData[36];
593 DWORD dataLen;
594 BOOL result;
595 int i;
597 /* acquire dss enhanced provider */
598 SetLastError(0xdeadbeef);
599 result = CryptAcquireContextA(
600 &hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
601 if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
603 skip("DSSENH is currently not available, skipping encryption tests.\n");
604 return;
606 ok(result, "Expected no errors.\n");
608 /* testing various encryption algorithms */
609 for(i = 0; i < testLen; i++)
611 memcpy(pbData, tests[i].plain, tests[i].plainLen);
612 dataLen = tests[i].plainLen;
614 SetLastError(0xdeadbeef);
615 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
616 ok(result, "Expected creation of a MD5 hash for key derivation.\n");
618 result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
619 ok(result, "Expected data to be added to hash for key derivation.\n");
621 /* Derive key */
622 result = CryptDeriveKey(hProv, tests[i].algid, hHash, tests[i].keyLength, &pKey);
623 ok(result, "Expected a derived key.\n");
625 result = CryptDestroyHash(hHash);
626 ok(result, "Expected destruction of hash after deriving key.\n");
628 /* testing CryptEncrypt with ALGID from array */
629 result = CryptEncrypt(pKey, 0, TRUE, 0, pbData, &dataLen, 36);
630 ok(result, "Expected data encryption.\n");
632 /* Verify we have received expected encrypted data */
633 ok(!memcmp(pbData, tests[i].encrypted, dataLen), "Incorrect encrypted data.\n");
635 result = CryptDecrypt(pKey, 0, TRUE, 0, pbData, &dataLen);
636 ok(result, "Expected data decryption.\n");
638 /* Verify we have received expected decrypted data */
639 ok(!memcmp(pbData, tests[i].decrypted, dataLen), "Incorrect decrypted data.\n");
641 result = CryptDestroyKey(pKey);
642 ok(result, "Expected no DestroyKey errors.\n");
644 result = CryptReleaseContext(hProv, 0);
645 ok(result, "Expected release of the provider\n");
648 struct ciphermode_test {
649 DWORD cipherMode;
650 BOOL expectedResult;
651 DWORD expectedError;
652 const BYTE *encrypted;
655 static const BYTE encryptedCFB[] = {
656 0x51,0x15,0x77,0xab,0x62,0x1f,0x7d,0xcb, 0x35,0x1e,0xd8,0xd3,0x2a,0x00,0xf0,0x94,
657 0x7c,0xa5,0x28,0xda,0xb8,0x81,0x15,0x99, 0xd1,0xd5,0x06,0x1d,0xd3,0x46,0x7e,0xca
659 static const BYTE encryptedCBC[] = {
660 0x8f,0x7b,0x56,0xeb,0xad,0x4d,0x76,0xc2, 0xd5,0x1d,0xf0,0x60,0x9d,0xde,0x96,0xe8,
661 0xb7,0x7b,0xeb,0x4b,0xee,0x3f,0xae,0x05, 0x20,0xf5,0xe0,0x75,0xa0,0x1d,0xf9,0x39
663 static const BYTE encryptedECB[] = {
664 0x8f,0x7b,0x56,0xeb,0xad,0x4d,0x76,0xc2, 0x8b,0xe0,0x4e,0xe4,0x98,0x4f,0xb8,0x3b,
665 0xf3,0xeb,0x6f,0x0a,0x57,0x91,0xdd,0xc7, 0x34,0x5d,0x4c,0xa3,0x7e,0x97,0xbf,0xee
668 static const struct ciphermode_test ciphermode_data[] = {
669 {CRYPT_MODE_CFB, TRUE, 0xdeadbeef, encryptedCFB}, /* Testing cipher block chaining */
670 {CRYPT_MODE_CBC, TRUE, 0xdeadbeef, encryptedCBC}, /* Testing cipher feedback */
671 {CRYPT_MODE_ECB, TRUE, 0xdeadbeef, encryptedECB}, /* Testing electronic codebook */
672 {CRYPT_MODE_OFB, FALSE, NTE_BAD_DATA}/* DSSENH does not support Output Feedback cipher mode */
675 static void test_cipher_modes(const struct ciphermode_test *tests, int testLen)
677 HCRYPTPROV hProv = 0;
678 HCRYPTKEY pKey = 0;
679 HCRYPTHASH hHash;
680 const char plainText[] = "Testing block cipher modes.";
681 const char dataToHash[] = "GSOC is awesome!";
682 unsigned char pbData[36];
683 int plainLen = sizeof(plainText), i;
684 DWORD mode, dataLen;
685 BOOL result;
687 /* acquire dss enhanced provider */
688 SetLastError(0xdeadbeef);
689 result = CryptAcquireContextA(
690 &hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
691 if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
693 skip("DSSENH is currently not available, skipping block cipher mode tests.\n");
694 return;
696 ok(result, "Expected no errors.\n");
698 SetLastError(0xdeadbeef);
699 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
700 ok(result, "Expected creation of a MD5 hash for key derivation.\n");
702 result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
703 ok(result, "Expected data to be added to hash for key derivation.\n");
705 /* Derive a CALG_RC2 key, but could be any other encryption cipher */
706 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &pKey);
707 ok(result, "Expected a derived key.\n");
709 result = CryptDestroyHash(hHash);
710 ok(result, "Expected destruction of hash after deriving key.\n");
712 /* the default algorithm is CBC, test that without setting a mode */
713 mode = 0xdeadbeef;
714 dataLen = sizeof(mode);
715 result = CryptGetKeyParam(pKey, KP_MODE, (BYTE*)&mode, &dataLen, 0);
716 ok(result, "Expected getting of KP_MODE, got %x.\n", GetLastError());
717 ok(mode == CRYPT_MODE_CBC, "Default mode should be CBC\n");
719 memcpy(pbData, plainText, plainLen);
720 dataLen = plainLen;
721 result = CryptEncrypt(pKey, 0, TRUE, 0, pbData, &dataLen, 36);
722 ok(result, "Expected data encryption, got %x.\n", GetLastError());
724 /* Verify we have the correct encrypted data */
725 ok(!memcmp(pbData, tests[1].encrypted, dataLen), "Incorrect encrypted data.\n");
727 result = CryptDecrypt(pKey, 0, TRUE, 0, pbData, &dataLen);
728 ok(result, "Expected data decryption, got %x.\n", GetLastError());
730 /* Verify we have the correct decrypted data */
731 ok(!memcmp(pbData, (BYTE *)plainText, dataLen), "Incorrect decrypted data.\n");
733 /* test block cipher modes */
734 for(i = 0; i < testLen; i++)
736 SetLastError(0xdeadbeef);
737 dataLen = plainLen;
738 mode = tests[i].cipherMode;
739 memcpy(pbData, plainText, plainLen);
741 result = CryptSetKeyParam(pKey, KP_MODE, (BYTE*)&mode, 0);
742 if(tests[i].expectedResult)
744 ok(result, "Expected setting of KP_MODE, got %x.\n", GetLastError());
746 result = CryptEncrypt(pKey, 0, TRUE, 0, pbData, &dataLen, 36);
747 ok(result, "Expected data encryption, got %x.\n", GetLastError());
749 /* Verify we have the correct encrypted data */
750 ok(!memcmp(pbData, tests[i].encrypted, dataLen), "Incorrect encrypted data.\n");
752 result = CryptDecrypt(pKey, 0, TRUE, 0, pbData, &dataLen);
753 ok(result, "Expected data decryption, got %x.\n", GetLastError());
755 /* Verify we have the correct decrypted data */
756 ok(!memcmp(pbData, (BYTE *)plainText, dataLen), "Incorrect decrypted data.\n");
758 else
759 { /* Expected error */
760 ok(!result && GetLastError() == tests[i].expectedError, "Expected %d, got %x.\n",
761 tests[i].expectedError, GetLastError());
764 result = CryptDestroyKey(pKey);
765 ok(result, "Expected no DestroyKey errors.\n");
767 result = CryptReleaseContext(hProv, 0);
768 ok(result, "Expected release of the provider.\n");
771 struct signature_test {
772 const BYTE *privateKey;
773 DWORD keyLen;
774 BYTE* signData;
775 DWORD dataLen;
778 static const char dataToSign1[] = "Put your hands up for Cryptography :)";
779 static const char dataToSign2[] = "With DSSENH implemented, applications requiring it will now work.";
780 static const char dataToSign3[] = "";
782 static const BYTE AT_SIGNATURE_PrivateKey[] = {
783 0x07,0x02,0x00,0x00,0x00,0x22,0x00,0x00, 0x44,0x53,0x53,0x32,0x00,0x04,0x00,0x00,
784 0x01,0xd1,0xfc,0x7a,0x70,0x53,0xb2,0x48, 0x70,0x23,0x19,0x1f,0x3c,0xe1,0x26,0x14,
785 0x7e,0x9f,0x0f,0x7f,0x33,0x5e,0x2b,0xf7, 0xca,0x01,0x74,0x8c,0xb4,0xfd,0xf6,0x44,
786 0x95,0x35,0x56,0xaa,0x4d,0x62,0x48,0xe2, 0xd1,0xa2,0x7e,0x6e,0xeb,0xd6,0xcc,0x7c,
787 0xe8,0xfd,0x21,0x9a,0xa2,0xfd,0x7a,0x9d, 0x1a,0x38,0x69,0x87,0x39,0x5a,0x91,0xc0,
788 0x52,0x2b,0x9f,0x2a,0x54,0x78,0x37,0x82, 0x9a,0x70,0x57,0xab,0xec,0x93,0x8e,0xac,
789 0x73,0x04,0xe8,0x53,0x72,0x72,0x32,0xc6, 0xcb,0xef,0x47,0x98,0x3c,0x56,0x49,0x62,
790 0xcb,0xbb,0xe7,0x34,0x84,0xa6,0x72,0x3a, 0xbe,0x26,0x46,0x86,0xca,0xcb,0x35,0x62,
791 0x4f,0x19,0x18,0x0b,0xb0,0x78,0xae,0xd5, 0x42,0xdf,0x26,0xdb,0x85,0x63,0x77,0x85,
792 0x01,0x3b,0x32,0xbe,0x5c,0xf8,0x05,0xc8, 0xde,0x17,0x7f,0xb9,0x03,0x82,0xfa,0xf1,
793 0x9e,0x32,0x73,0xfa,0x8d,0xea,0xa3,0x30, 0x48,0xe2,0xdf,0x5a,0xcb,0x83,0x3d,0xff,
794 0x56,0xe9,0xc0,0x94,0xf8,0x6d,0xb3,0xaf, 0x4a,0x97,0xb9,0x43,0x0e,0xd4,0x28,0x98,
795 0x57,0x2e,0x3a,0xca,0xde,0x6f,0x45,0x0d, 0xfb,0x58,0xec,0x78,0x34,0x2e,0x46,0x4d,
796 0xfe,0x98,0x02,0xbb,0xef,0x07,0x1a,0x13, 0xb6,0xc2,0x2c,0x06,0xd9,0x0c,0xc4,0xb0,
797 0x4c,0x3a,0xfc,0x01,0x63,0xb5,0x5a,0x5d, 0x2d,0x9c,0x47,0x04,0x67,0x51,0xf2,0x52,
798 0xf5,0x82,0x36,0xeb,0x6e,0x66,0x58,0x4c, 0x10,0x2c,0x29,0x72,0x4a,0x6f,0x6b,0x6c,
799 0xe0,0x93,0x31,0x42,0xf6,0xda,0xfa,0x5b, 0x22,0x43,0x9b,0x1a,0x98,0x71,0xe7,0x41,
800 0x74,0xe9,0x12,0xa4,0x1f,0x27,0x0a,0x63, 0x94,0x49,0xd7,0xad,0xa5,0xc4,0x5c,0xc3,
801 0xc9,0x70,0xb3,0x7b,0x16,0xb6,0x1d,0xd4, 0x09,0xc4,0x9a,0x46,0x2d,0x0e,0x75,0x07,
802 0x31,0x7b,0xed,0x45,0xcd,0x99,0x84,0x14, 0xf1,0x01,0x00,0x00,0x93,0xd5,0xa3,0xe4,
803 0x34,0x05,0xeb,0x98,0x3b,0x5f,0x2f,0x11, 0xa4,0xa5,0xc4,0xff,0xfb,0x22,0x7c,0x54
806 static const BYTE DSS_SIGN_PrivateKey[] = {
807 0x07,0x02,0x00,0x00,0x00,0x22,0x00,0x00, 0x44,0x53,0x53,0x32,0x00,0x04,0x00,0x00,
808 0xf7,0x9e,0x89,0xa2,0xcd,0x0b,0x61,0xe0, 0xa3,0xe5,0x86,0x6b,0x04,0x98,0x80,0x9c,
809 0x36,0xc2,0x76,0x4e,0x22,0xd5,0x21,0xaa, 0x03,0x59,0xf4,0x95,0xb2,0x11,0x1f,0xa0,
810 0xc5,0xfc,0xbe,0x5d,0x1f,0x2e,0xf4,0x36, 0x40,0x48,0x81,0x51,0xb4,0x25,0x86,0xe0,
811 0x98,0xc8,0x4d,0xa0,0x08,0x99,0xa1,0x00, 0x45,0x1b,0x75,0x6b,0x0d,0x3e,0x7d,0x13,
812 0xd7,0x23,0x32,0x08,0xf4,0xeb,0x27,0x9e, 0xe9,0x05,0x5d,0xac,0xc8,0xd7,0x62,0x13,
813 0x43,0x2a,0x69,0x65,0xdc,0xe6,0x52,0xf9, 0x6a,0xe8,0x07,0xcf,0x3e,0xf8,0xc9,0x1d,
814 0x8e,0xdf,0x4e,0x9a,0xd1,0x48,0xf2,0xda, 0x9e,0xfa,0x92,0x5f,0x6d,0x57,0xf2,0xa4,
815 0x5f,0x60,0xce,0x92,0x7a,0x80,0x39,0x21, 0x9d,0x4d,0x3a,0x60,0x76,0x4c,0x2f,0xc0,
816 0xd3,0xf4,0x14,0x03,0x03,0x05,0xa9,0x0c, 0x57,0x72,0x4f,0x60,0x3c,0xe9,0x09,0x54,
817 0x0c,0x2a,0x56,0xda,0x30,0xb6,0x2e,0x6a, 0x96,0x7f,0x4a,0x8f,0x83,0x0a,0xb9,0x5c,
818 0xff,0x84,0xfa,0x0e,0x85,0x81,0x46,0xe9, 0x1c,0xbb,0x78,0x1d,0x78,0x25,0x00,0x8c,
819 0x78,0x56,0x68,0xe4,0x06,0x37,0xcc,0xc7, 0x22,0x27,0xee,0x0e,0xf8,0xca,0xfc,0x72,
820 0x0e,0xd6,0xe6,0x90,0x30,0x66,0x22,0xe2, 0xa2,0xbf,0x2e,0x35,0xbc,0xe7,0xd6,0x24,
821 0x6a,0x3d,0x06,0xe8,0xe2,0xbe,0x96,0xcc, 0x9a,0x08,0x06,0xb5,0x44,0x83,0xb0,0x7b,
822 0x70,0x7b,0x2d,0xc3,0x46,0x9a,0xc5,0x6b, 0xd9,0xde,0x9a,0x24,0xc9,0xea,0xf5,0x28,
823 0x69,0x8a,0x17,0xca,0xdf,0xc4,0x0e,0xa3, 0x08,0x22,0x99,0xd2,0x27,0xdc,0x9b,0x08,
824 0x54,0x4a,0xf9,0xb1,0x74,0x3a,0x9d,0xd9, 0xc2,0x82,0x21,0xf5,0x97,0x04,0x90,0x37,
825 0xda,0xd9,0xdc,0x19,0xad,0x83,0xcd,0x35, 0xb0,0x4e,0x06,0x68,0xd1,0x69,0x7e,0x73,
826 0x93,0xbe,0xa5,0x05,0xb3,0xcc,0xd2,0x51, 0x3c,0x00,0x00,0x00,0x16,0xe1,0xac,0x17,
827 0xdc,0x68,0xae,0x03,0xad,0xf7,0xb9,0xca, 0x0d,0xca,0x27,0xef,0x76,0xda,0xe5,0xcb
830 static const struct signature_test dssSign_data[] = {
831 {AT_SIGNATURE_PrivateKey, sizeof(AT_SIGNATURE_PrivateKey), (BYTE *)dataToSign1, sizeof(dataToSign1)},
832 {AT_SIGNATURE_PrivateKey, sizeof(AT_SIGNATURE_PrivateKey), (BYTE *)dataToSign2, sizeof(dataToSign2)},
833 {AT_SIGNATURE_PrivateKey, sizeof(AT_SIGNATURE_PrivateKey), (BYTE *)dataToSign3, sizeof(dataToSign3)},
834 {DSS_SIGN_PrivateKey, sizeof(DSS_SIGN_PrivateKey), (BYTE *)dataToSign1, sizeof(dataToSign1)},
835 {DSS_SIGN_PrivateKey, sizeof(DSS_SIGN_PrivateKey), (BYTE *)dataToSign2, sizeof(dataToSign2)},
836 {DSS_SIGN_PrivateKey, sizeof(DSS_SIGN_PrivateKey), (BYTE *)dataToSign3, sizeof(dataToSign3)}
839 static void test_signhash_array(HCRYPTPROV hProv, const struct signature_test *tests, int testLen)
841 HCRYPTHASH hHash1, hHash2;
842 HCRYPTKEY privKey = 0, pubKey = 0;
843 BYTE pubKeyBuffer[512];
844 BYTE signValue1[40], signValue2[40];
845 BYTE hashValue1[40], hashValue2[40];
846 DWORD hashLen1, hashLen2, pubKeyLen;
847 DWORD dataLen1, dataLen2;
848 BOOL result;
849 int i;
851 for (i = 0; i < testLen; i++)
853 DWORD signLen1 = tests[i].dataLen;
854 DWORD signLen2 = tests[i].dataLen;
856 /* Get a private key of array specified ALG_ID */
857 result = CryptImportKey(hProv, tests[i].privateKey, tests[i].keyLen, 0, 0, &privKey);
858 ok(result, "Failed to imported key, got %x\n", GetLastError());
860 /* Create hash object and add data for signature 1 */
861 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash1);
862 ok(result, "Failed to create a hash, got %x\n", GetLastError());
864 result = CryptHashData(hHash1, tests[i].signData, signLen1, 0);
865 ok(result, "Failed to add data to hash, got %x\n", GetLastError());
867 /* Create hash object and add data for signature 2 */
868 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
869 ok(result, "Failed to create a hash, got %x\n", GetLastError());
871 result = CryptHashData(hHash2, tests[i].signData, signLen2, 0);
872 ok(result, "Failed to add data to hash, got %x\n", GetLastError());
874 /* Acquire hash length and hash value */
875 dataLen1 = sizeof(DWORD);
876 result = CryptGetHashParam(hHash1, HP_HASHSIZE, (BYTE *)&hashLen1, &dataLen1, 0);
877 ok(result, "Failed to get hash length, got %x\n", GetLastError());
879 result = CryptGetHashParam(hHash1, HP_HASHVAL, hashValue1, &hashLen1, 0);
880 ok(result, "Failed to return hash value.\n");
882 dataLen2 = sizeof(DWORD);
883 result = CryptGetHashParam(hHash2, HP_HASHSIZE, (BYTE *)&hashLen2, &dataLen2, 0);
884 ok(result, "Failed to get hash length, got %x\n", GetLastError());
886 result = CryptGetHashParam(hHash2, HP_HASHVAL, hashValue2, &hashLen2, 0);
887 ok(result, "Failed to return hash value.\n");
889 /* Compare hashes to ensure they are the same */
890 ok(hashLen1 == hashLen2, "Hash lengths were not the same.\n");
891 ok(!memcmp(hashValue1, hashValue2, hashLen2), "Hashes were not identical.\n");
893 /* Sign hash 1 */
894 result = CryptSignHashA(hHash1, AT_SIGNATURE, NULL, 0, NULL, &signLen1);
895 ok(result, "Failed to get signature length, got %x\n", GetLastError());
896 ok(signLen1 == 40, "Expected a 40-byte signature, got %d\n", signLen1);
898 result = CryptSignHashA(hHash1, AT_SIGNATURE, NULL, 0, signValue1, &signLen1);
899 ok(result, "Failed to sign hash, got %x\n", GetLastError());
901 /* Sign hash 2 */
902 result = CryptSignHashA(hHash2, AT_SIGNATURE, NULL, 0, NULL, &signLen2);
903 ok(result, "Failed to get signature length, got %x\n", GetLastError());
904 ok(signLen2 == 40, "Expected a 40-byte signature, got %d\n", signLen2);
906 result = CryptSignHashA(hHash2, AT_SIGNATURE, NULL, 0, signValue2, &signLen2);
907 ok(result, "Failed to sign hash2, got %x\n", GetLastError());
909 /* Compare signatures to ensure they are both different, because every DSS signature
910 should be different even if the input hash data is identical */
911 ok(memcmp(signValue1, signValue2, signLen2), "Expected two different signatures from "
912 "the same hash input.\n");
914 result = CryptExportKey(privKey, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen);
915 ok(result, "Failed to acquire public key length, got %x\n", GetLastError());
917 /* Export the public key */
918 result = CryptExportKey(privKey, 0, PUBLICKEYBLOB, 0, pubKeyBuffer, &pubKeyLen);
919 ok(result, "Failed to export public key, got %x\n", GetLastError());
921 result = CryptDestroyHash(hHash1);
922 ok(result, "Failed to destroy hash1, got %x\n", GetLastError());
923 result = CryptDestroyHash(hHash2);
924 ok(result, "Failed to destroy hash2, got %x\n", GetLastError());
926 /* Destroy the private key */
927 result = CryptDestroyKey(privKey);
928 ok(result, "Failed to destroy private key, got %x\n", GetLastError());
930 /* Import the public key we obtained earlier */
931 result = CryptImportKey(hProv, pubKeyBuffer, pubKeyLen, 0, 0, &pubKey);
932 ok(result, "Failed to import public key, got %x\n", GetLastError());
934 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash1);
935 ok(result, "Failed to create hash, got %x\n", GetLastError());
937 /* Hash the data to compare with the signed hash */
938 result = CryptHashData(hHash1, tests[i].signData, tests[i].dataLen, 0);
939 ok(result, "Failed to add data to hash1, got %x\n", GetLastError());
941 /* Verify signed hash 1 */
942 result = CryptVerifySignatureA(hHash1, signValue1, sizeof(signValue1), pubKey, NULL, 0);
943 ok(result, "Failed to verify signature, got %x\n", GetLastError());
945 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
946 ok(result, "Failed to create hash, got %x\n", GetLastError());
948 /* Hash the data to compare with the signed hash */
949 result = CryptHashData(hHash2, tests[i].signData, tests[i].dataLen, 0);
950 ok(result, "Failed to add data to hash2, got %x\n", GetLastError());
952 /* Verify signed hash 2 */
953 result = CryptVerifySignatureA(hHash2, signValue2, sizeof(signValue2), pubKey, NULL, 0);
954 ok(result, "Failed to verify signature, got %x\n", GetLastError());
956 result = CryptDestroyHash(hHash1);
957 ok(result, "Failed to destroy hash1, got %x\n", GetLastError());
958 result = CryptDestroyHash(hHash2);
959 ok(result, "Failed to destroy hash2, got %x\n", GetLastError());
961 /* Destroy the public key */
962 result = CryptDestroyKey(pubKey);
963 ok(result, "Failed to destroy public key, got %x\n", GetLastError());
967 static void test_verify_signature(void)
969 HCRYPTPROV hProv = 0;
970 BOOL result;
972 /* acquire base dss provider */
973 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, 0);
974 if(!result)
976 skip("DSSENH is currently not available, skipping signature verification tests.\n");
977 return;
979 ok(result, "Failed to acquire CSP.\n");
981 test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
983 result = CryptReleaseContext(hProv, 0);
984 ok(result, "Failed to release CSP provider.\n");
986 /* acquire diffie hellman dss provider */
987 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, 0);
988 ok(result, "Failed to acquire CSP.\n");
990 test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
992 result = CryptReleaseContext(hProv, 0);
993 ok(result, "Failed to release CSP provider.\n");
995 /* acquire enhanced dss provider */
996 SetLastError(0xdeadbeef);
997 result = CryptAcquireContextA(&hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH, 0);
998 if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
1000 win_skip("DSSENH and Schannel provider is broken on WinNT4, skipping signature "
1001 "verification tests.\n");
1002 return;
1004 ok(result, "Failed to acquire CSP.\n");
1006 test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
1008 result = CryptReleaseContext(hProv, 0);
1009 ok(result, "Failed to release CSP provider.\n");
1011 /* acquire schannel dss provider */
1012 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DH_SCHANNEL_PROV_A, PROV_DH_SCHANNEL, 0);
1013 ok(result, "Failed to acquire CSP.\n");
1015 test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
1017 result = CryptReleaseContext(hProv, 0);
1018 ok(result, "Failed to release CSP provider.\n");
1021 struct keyExchange_test {
1022 ALG_ID algid;
1023 const BYTE *primeNum;
1024 int primeLen;
1025 const BYTE *generatorNum;
1026 int generatorLen;
1029 /* AT_KEYEXCHANGE interprets to CALG_DH_SF by the DSSENH cryptographic service provider */
1030 static const BYTE primeAT_KEYEXCHANGE[] = {
1031 0x65,0x28,0x24,0xd8,0xbe,0x3f,0x95,0x93, 0x3c,0x4d,0x1b,0x51,0xe1,0x89,0x9a,0x90,
1032 0x5e,0xa0,0x6c,0x25,0xf0,0xb5,0x93,0x98, 0xba,0x76,0x9d,0x54,0x78,0xf6,0xdc,0x04,
1033 0xe1,0xd0,0x87,0x8f,0xa0,0xe4,0x2f,0xb4, 0x09,0x78,0x24,0xbf,0xc8,0x7f,0x59,0xf4,
1034 0x07,0xee,0x07,0x20,0x1b,0x2d,0x54,0x2a, 0xb5,0xb4,0x8f,0x8c,0x33,0x73,0xec,0xaf
1037 static const BYTE generatorAT_KEYEXCHANGE[] = {
1038 0xdc,0x62,0x20,0xe7,0x36,0xa2,0xa6,0xef, 0x77,0x91,0xa8,0xa3,0x6d,0x60,0x70,0x0d,
1039 0x1d,0x79,0xb1,0xbe,0xa8,0x87,0x69,0x39, 0x29,0xaa,0x54,0x27,0x05,0xe6,0x6f,0xa5,
1040 0xde,0x82,0x00,0x5d,0x87,0x1f,0x84,0xf7, 0x40,0xec,0x6f,0x15,0x64,0x02,0x0d,0xb8,
1041 0x50,0x48,0x94,0x66,0xb2,0x7d,0xbd,0xf2, 0x66,0xf8,0x40,0x62,0x94,0xbf,0x24,0x3b
1044 static const BYTE primeCALG_DH_EPHEM[] = {
1045 0x17,0x99,0xa9,0x79,0x31,0xb9,0x05,0xdd, 0x7f,0xf0,0x02,0x11,0x4d,0x0d,0xc3,0x81,
1046 0x8b,0x41,0x50,0x41,0x5f,0x07,0xe6,0x8d, 0x02,0xf9,0xaa,0x86,0x2a,0x07,0x07,0xea,
1047 0x0a,0x75,0xed,0x96,0xa7,0x85,0xee,0xac, 0xb1,0x71,0xbd,0x57,0x48,0xbd,0x41,0x0b,
1048 0xde,0x34,0xe2,0xba,0x5b,0x55,0x64,0x77, 0x84,0xfa,0x96,0xd1,0xaf,0x79,0x49,0x9d
1051 static const BYTE generatorCALG_DH_EPHEM[] = {
1052 0xc7,0x64,0x56,0xde,0xf7,0xb4,0xd3,0xd8, 0xa2,0xd4,0x12,0x2d,0x54,0x5c,0x54,0xc8,
1053 0x04,0x11,0x88,0x14,0x6c,0x9f,0x88,0x41, 0x82,0x93,0x32,0xb1,0x82,0x84,0x5b,0x07,
1054 0x55,0x13,0x82,0x7a,0x64,0x7b,0x12,0x09, 0xe2,0xa0,0x28,0x51,0xf4,0x7a,0xd9,0x26,
1055 0x86,0x95,0x5f,0xc0,0x9a,0x25,0xc2,0x7e, 0x91,0x14,0xdd,0x3c,0x4e,0x86,0x4f,0x6f
1058 static const BYTE primeCALG_DH_SF[] = {
1059 0x85,0xb8,0xa5,0x4a,0xcf,0x2b,0x7c,0x61, 0xb2,0x06,0x93,0x8a,0x87,0x37,0x58,0xb0,
1060 0x8d,0xc7,0x2a,0xa7,0x7f,0x0d,0x74,0xf9, 0x3a,0x7e,0xbc,0xab,0x3a,0x54,0xe4,0x11,
1061 0x69,0x6f,0xcd,0xea,0xad,0x32,0x44,0x4f, 0xee,0x54,0x69,0x8c,0x9c,0x3b,0x87,0x27,
1062 0x36,0x70,0x06,0xf3,0x4e,0xde,0x7f,0x9d, 0xa6,0xf2,0xad,0x43,0x90,0xdd,0xb5,0x9b
1065 static const BYTE generatorCALG_DH_SF[] = {
1066 0xea,0xdc,0xe0,0xbb,0x60,0x26,0xc6,0xb3, 0x93,0x6f,0x61,0xe6,0x7e,0xe2,0xee,0xd6,
1067 0xdb,0x3d,0xca,0xa8,0x31,0x46,0x8f,0x5d, 0xb4,0xaa,0x83,0xd3,0x52,0x10,0xcd,0xfb,
1068 0xfd,0xfc,0x14,0x89,0x0c,0xde,0xcf,0x54, 0x1d,0x05,0x8c,0xbe,0x4a,0xe4,0x37,0xb4,
1069 0xc0,0x15,0x75,0xc5,0xa2,0xfc,0x99,0xfc, 0xad,0x63,0xcb,0x7c,0xb8,0x20,0xdc,0x2b
1072 static const struct keyExchange_test baseDSSkey_data[] = {
1073 /* Cannot exchange keys using the base DSS provider, except on WinNT4 */
1074 {AT_KEYEXCHANGE, primeAT_KEYEXCHANGE, sizeof(primeAT_KEYEXCHANGE), generatorAT_KEYEXCHANGE,
1075 sizeof(generatorAT_KEYEXCHANGE)},
1076 {CALG_DH_EPHEM, primeCALG_DH_EPHEM, sizeof(primeCALG_DH_EPHEM), generatorCALG_DH_EPHEM,
1077 sizeof(generatorCALG_DH_EPHEM)},
1078 {CALG_DH_SF, primeCALG_DH_SF, sizeof(generatorCALG_DH_SF), generatorCALG_DH_SF,
1079 sizeof(generatorCALG_DH_SF)}
1082 static const struct keyExchange_test dssDHkey_data[] = {
1083 {AT_KEYEXCHANGE, primeAT_KEYEXCHANGE, sizeof(primeAT_KEYEXCHANGE), generatorAT_KEYEXCHANGE,
1084 sizeof(generatorAT_KEYEXCHANGE)},
1085 {CALG_DH_EPHEM, primeCALG_DH_EPHEM, sizeof(primeCALG_DH_EPHEM), generatorCALG_DH_EPHEM,
1086 sizeof(generatorCALG_DH_EPHEM)},
1087 {CALG_DH_SF, primeCALG_DH_SF, sizeof(generatorCALG_DH_SF), generatorCALG_DH_SF,
1088 sizeof(generatorCALG_DH_SF)}
1091 static void test_keyExchange_baseDSS(HCRYPTPROV hProv, const struct keyExchange_test *tests, int testLen)
1093 HCRYPTKEY privKey1 = 0, privKey2 = 0;
1094 HCRYPTKEY sessionKey1 = 0, sessionKey2 = 0;
1095 const char plainText[] = "Testing shared key.";
1096 unsigned char pbData1[36];
1097 unsigned char pbData2[36];
1098 BYTE pubKeyBuffer1[512], pubKeyBuffer2[512];
1099 DWORD pubKeyLen1, pubKeyLen2, dataLen;
1100 DATA_BLOB Prime, Generator;
1101 int plainLen = sizeof(plainText), i;
1102 ALG_ID algid;
1103 BOOL result;
1105 for(i = 0; i < testLen; i++)
1107 SetLastError(0xdeadbeef);
1109 /* Create the data blobs and the prime and generator */
1110 Prime.cbData = tests[i].primeLen;
1111 Prime.pbData = (BYTE *)tests[i].primeNum;
1112 Generator.cbData = tests[i].generatorLen;
1113 Generator.pbData = (BYTE *)tests[i].generatorNum;
1115 /* Generate key exchange keys for user1 and user2 */
1116 result = CryptGenKey(hProv, tests[i].algid, 512 << 16 | CRYPT_PREGEN, &privKey1);
1117 ok((!result && GetLastError() == NTE_BAD_ALGID) || broken(result), /* WinNT4 */
1118 "Expected NTE_BAD_ALGID, got %x\n", GetLastError());
1120 result = CryptGenKey(hProv, tests[i].algid, 512 << 16 | CRYPT_PREGEN, &privKey2);
1121 ok((!result && GetLastError() == NTE_BAD_ALGID) || broken(result), /* WinNT4 */
1122 "Expected NTE_BAD_ALGID, got %x\n", GetLastError());
1124 /* Set the prime and generator values, which are agreed upon */
1125 result = CryptSetKeyParam(privKey1, KP_P, (BYTE *)&Prime, 0);
1126 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1127 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1129 result = CryptSetKeyParam(privKey2, KP_P, (BYTE *)&Prime, 0);
1130 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1131 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1133 result = CryptSetKeyParam(privKey1, KP_G, (BYTE *)&Generator, 0);
1134 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1135 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1137 result = CryptSetKeyParam(privKey2, KP_G, (BYTE *)&Generator, 0);
1138 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1139 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1141 /* Generate the secret value for user1 and user2 */
1142 result = CryptSetKeyParam(privKey1, KP_X, NULL, 0);
1143 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1144 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1146 result = CryptSetKeyParam(privKey2, KP_X, NULL, 0);
1147 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1148 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1150 /* Acquire required size for the public keys */
1151 result = CryptExportKey(privKey1, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen1);
1152 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1153 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1155 result = CryptExportKey(privKey2, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen2);
1156 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1157 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1159 /* Export public key which will be calculated into the shared key */
1160 result = CryptExportKey(privKey1, 0, PUBLICKEYBLOB, 0, pubKeyBuffer1, &pubKeyLen1);
1161 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1162 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1164 result = CryptExportKey(privKey2, 0, PUBLICKEYBLOB, 0, pubKeyBuffer2, &pubKeyLen2);
1165 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1166 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1168 /* Import the public key and convert it into a shared key */
1169 result = CryptImportKey(hProv, pubKeyBuffer2, pubKeyLen2, privKey1, 0, &sessionKey1);
1170 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) ||
1171 broken(!result && GetLastError() == NTE_BAD_DATA) || /* Vista.64 */
1172 broken(!result && GetLastError() == NTE_BAD_TYPE) || /* Win2K-W2K8, Win7.64 */
1173 broken(!result && GetLastError() == NTE_BAD_ALGID) || /* W7SP164 (32 bit dssenh) */
1174 broken(result), /* WinNT4 */
1175 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1177 result = CryptImportKey(hProv, pubKeyBuffer1, pubKeyLen1, privKey2, 0, &sessionKey2);
1178 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) ||
1179 broken(!result && GetLastError() == NTE_BAD_TYPE) || /* Win2K-W2K8, Win7.64 */
1180 broken(!result && GetLastError() == NTE_BAD_ALGID) || /* W7SP164 (32 bit dssenh) */
1181 broken(result), /* WinNT4 */
1182 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1184 /* Set the shared key parameters to matching type */
1185 algid = CALG_RC4;
1186 result = CryptSetKeyParam(sessionKey1, KP_ALGID, (BYTE *)&algid, 0);
1187 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1188 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1190 algid = CALG_RC4;
1191 result = CryptSetKeyParam(sessionKey2, KP_ALGID, (BYTE *)&algid, 0);
1192 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1193 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1195 /* Encrypt some data and verify we are getting the same output */
1196 memcpy(pbData1, plainText, plainLen);
1197 dataLen = plainLen;
1199 result = CryptEncrypt(sessionKey1, 0, TRUE, 0, pbData1, &dataLen, 36);
1200 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1201 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1203 result = CryptDecrypt(sessionKey2, 0, TRUE, 0, pbData1, &dataLen);
1204 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1205 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1207 ok(!memcmp(pbData1, (BYTE *)plainText, sizeof(plainText)), "Incorrect decrypted data.\n");
1209 memcpy(pbData2, plainText, plainLen);
1210 dataLen = plainLen;
1212 result = CryptEncrypt(sessionKey2, 0, TRUE, 0, pbData2, &dataLen, 36);
1213 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1214 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1216 result = CryptDecrypt(sessionKey1, 0, TRUE, 0, pbData2, &dataLen);
1217 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1218 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1220 ok(!memcmp(pbData1, pbData2, dataLen), "Decrypted data is not identical.\n");
1222 /* Destroy all user keys */
1223 result = CryptDestroyKey(sessionKey1);
1224 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1225 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1227 result = CryptDestroyKey(sessionKey2);
1228 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1229 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1231 result = CryptDestroyKey(privKey1);
1232 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1233 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1235 result = CryptDestroyKey(privKey2);
1236 ok((!result && GetLastError() == ERROR_INVALID_PARAMETER) || broken(result),
1237 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1241 static void test_keyExchange_dssDH(HCRYPTPROV hProv, const struct keyExchange_test *tests, int testLen)
1243 HCRYPTKEY privKey1 = 0, privKey2 = 0;
1244 HCRYPTKEY sessionKey1 = 0, sessionKey2 = 0;
1245 const char plainText[] = "Testing shared key.";
1246 unsigned char pbData1[36];
1247 unsigned char pbData2[36];
1248 BYTE pubKeyBuffer1[512], pubKeyBuffer2[512];
1249 DWORD pubKeyLen1, pubKeyLen2, dataLen;
1250 DATA_BLOB Prime, Generator;
1251 int plainLen = sizeof(plainText), i;
1252 ALG_ID algid;
1253 BOOL result;
1255 for(i = 0; i < testLen; i++)
1257 SetLastError(0xdeadbeef);
1259 /* Create the data blobs and the prime and generator */
1260 Prime.cbData = tests[i].primeLen;
1261 Prime.pbData = (BYTE *)tests[i].primeNum;
1262 Generator.cbData = tests[i].generatorLen;
1263 Generator.pbData = (BYTE *)tests[i].generatorNum;
1265 /* Generate key exchange keys for user1 and user2 */
1266 result = CryptGenKey(hProv, tests[i].algid, 512 << 16 | CRYPT_PREGEN, &privKey1);
1267 ok(result, "Failed to generate a key for user1, got %x\n", GetLastError());
1269 result = CryptGenKey(hProv, tests[i].algid, 512 << 16 | CRYPT_PREGEN, &privKey2);
1270 ok(result, "Failed to generate a key for user2, got %x\n", GetLastError());
1272 /* Set the prime and generator values, which are agreed upon */
1273 result = CryptSetKeyParam(privKey1, KP_P, (BYTE *)&Prime, 0);
1274 ok(result, "Failed to set prime for user 1's key, got %x\n", GetLastError());
1276 result = CryptSetKeyParam(privKey2, KP_P, (BYTE *)&Prime, 0);
1277 ok(result, "Failed to set prime for user 2's key, got %x\n", GetLastError());
1279 result = CryptSetKeyParam(privKey1, KP_G, (BYTE *)&Generator, 0);
1280 ok(result, "Failed to set generator for user 1's key, got %x\n", GetLastError());
1282 result = CryptSetKeyParam(privKey2, KP_G, (BYTE *)&Generator, 0);
1283 ok(result, "Failed to set generator for user 2's key, got %x\n", GetLastError());
1285 /* Generate the secret value for user1 and user2 */
1286 result = CryptSetKeyParam(privKey1, KP_X, NULL, 0);
1287 ok(result || broken(!result && GetLastError() == ERROR_INVALID_PARAMETER),
1288 "Failed to set secret value for user 1, got %x\n", GetLastError());/* Win2k & WinXP */
1290 result = CryptSetKeyParam(privKey2, KP_X, NULL, 0);
1291 ok(result || broken(!result && GetLastError() == ERROR_INVALID_PARAMETER),
1292 "Failed to set secret value for user 2, got %x\n", GetLastError());/* Win2k & WinXP */
1294 /* Acquire required size for the public keys */
1295 result = CryptExportKey(privKey1, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen1);
1296 ok(result, "Failed to acquire public key length for user 1, got %x\n", GetLastError());
1298 result = CryptExportKey(privKey2, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen2);
1299 ok(result, "Failed to acquire public key length for user 2, got %x\n", GetLastError());
1301 /* Export public key which will be calculated into the shared key */
1302 result = CryptExportKey(privKey1, 0, PUBLICKEYBLOB, 0, pubKeyBuffer1, &pubKeyLen1);
1303 ok(result, "Failed to export public key for user 1, got %x\n", GetLastError());
1305 result = CryptExportKey(privKey2, 0, PUBLICKEYBLOB, 0, pubKeyBuffer2, &pubKeyLen2);
1306 ok(result, "Failed to export public key for user 2, got %x\n", GetLastError());
1308 /* Import the public key and convert it into a shared key */
1309 result = CryptImportKey(hProv, pubKeyBuffer2, pubKeyLen2, privKey1, 0, &sessionKey1);
1310 ok(result, "Failed to import key for user 1, got %x\n", GetLastError());
1312 result = CryptImportKey(hProv, pubKeyBuffer1, pubKeyLen1, privKey2, 0, &sessionKey2);
1313 ok(result, "Failed to import key for user 2, got %x\n", GetLastError());
1315 /* Set the shared key parameters to matching cipher type */
1316 algid = CALG_RC4;
1317 result = CryptSetKeyParam(sessionKey1, KP_ALGID, (BYTE *)&algid, 0);
1318 ok(result, "Failed to set session key for user 1, got %x\n", GetLastError());
1320 algid = CALG_RC4;
1321 result = CryptSetKeyParam(sessionKey2, KP_ALGID, (BYTE *)&algid, 0);
1322 ok(result, "Failed to set session key for user 2, got %x\n", GetLastError());
1324 /* Encrypt some data and verify we are getting the correct output */
1325 memcpy(pbData1, plainText, plainLen);
1326 dataLen = plainLen;
1328 result = CryptEncrypt(sessionKey1, 0, TRUE, 0, pbData1, &dataLen, 36);
1329 ok(result, "Failed to encrypt data, got %x.\n", GetLastError());
1331 result = CryptDecrypt(sessionKey2, 0, TRUE, 0, pbData1, &dataLen);
1332 ok(result, "Failed to decrypt data, got %x.\n", GetLastError());
1334 ok(!memcmp(pbData1, (BYTE *)plainText, sizeof(plainText)), "Incorrect decrypted data.\n");
1336 memcpy(pbData2, plainText, plainLen);
1337 dataLen = plainLen;
1339 result = CryptEncrypt(sessionKey2, 0, TRUE, 0, pbData2, &dataLen, 36);
1340 ok(result, "Failed to encrypt data, got %x.\n", GetLastError());
1342 result = CryptDecrypt(sessionKey1, 0, TRUE, 0, pbData2, &dataLen);
1343 ok(result, "Failed to decrypt data, got %x.\n", GetLastError());
1345 ok(!memcmp(pbData1, pbData2, dataLen), "Decrypted data is not identical.\n");
1347 /* Destroy all user keys */
1348 result = CryptDestroyKey(sessionKey1);
1349 ok(result, "Failed to destroy session key 1, got %x\n", GetLastError());
1351 result = CryptDestroyKey(sessionKey2);
1352 ok(result, "Failed to destroy session key 2, got %x\n", GetLastError());
1354 result = CryptDestroyKey(privKey1);
1355 ok(result, "Failed to destroy key private key 1, got %x\n", GetLastError());
1357 result = CryptDestroyKey(privKey2);
1358 ok(result, "Failed to destroy key private key 2, got %x\n", GetLastError());
1362 static void test_key_exchange(void)
1364 HCRYPTPROV hProv = 0;
1365 BOOL result;
1367 /* acquire base dss provider */
1368 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
1369 if(!result)
1371 skip("DSSENH is currently not available, skipping shared key tests.\n");
1372 return;
1374 ok(result, "Failed to acquire CSP.\n");
1376 test_keyExchange_baseDSS(hProv, baseDSSkey_data, TESTLEN(baseDSSkey_data));
1378 result = CryptReleaseContext(hProv, 0);
1379 ok(result, "Failed to release CSP provider.\n");
1381 /* acquire diffie hellman dss provider */
1382 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH,
1383 CRYPT_VERIFYCONTEXT);
1384 ok(result, "Failed to acquire CSP.\n");
1386 test_keyExchange_dssDH(hProv, dssDHkey_data, TESTLEN(dssDHkey_data));
1388 result = CryptReleaseContext(hProv, 0);
1389 ok(result, "Failed to release CSP provider.\n");
1391 /* acquire enhanced dss provider */
1392 result = CryptAcquireContextA(&hProv, NULL, MS_ENH_DSS_DH_PROV_A, PROV_DSS_DH,
1393 CRYPT_VERIFYCONTEXT);
1394 if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
1396 win_skip("DSSENH and Schannel provider is broken on WinNT4, skipping shared key tests.\n");
1397 return;
1399 ok(result, "Failed to acquire CSP.\n");
1401 test_keyExchange_dssDH(hProv, dssDHkey_data, TESTLEN(dssDHkey_data));
1403 result = CryptReleaseContext(hProv, 0);
1404 ok(result, "Failed to release CSP provider.\n");
1406 /* acquire schannel dss provider */
1407 result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DH_SCHANNEL_PROV_A, PROV_DH_SCHANNEL,
1408 CRYPT_VERIFYCONTEXT);
1409 ok(result, "Failed to acquire CSP.\n");
1411 test_keyExchange_dssDH(hProv, dssDHkey_data, TESTLEN(dssDHkey_data));
1413 result = CryptReleaseContext(hProv, 0);
1414 ok(result, "Failed to release CSP provider.\n");
1417 START_TEST(dssenh)
1419 test_acquire_context();
1420 test_keylength();
1421 test_hash(hash_data, TESTLEN(hash_data));
1422 test_data_encryption(encrypt_data, TESTLEN(encrypt_data));
1423 test_cipher_modes(ciphermode_data, TESTLEN(ciphermode_data));
1424 test_verify_signature();
1425 test_key_exchange();