Release 1.5.29.
[wine] / dlls / dssenh / tests / dssenh.c
1 /*
2  * Unit tests for dss functions
3  *
4  * Copyright (c) 2012 Marek Kamil Chmiel
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <string.h>
22 #include <stdio.h>
23 #include "wine/test.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "wincrypt.h"
28
29 static void test_acquire_context(void)
30 {   /* failure tests common between all four CSP providers */
31
32     HCRYPTPROV hProv = 0;
33     BOOL result;
34
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());
40
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());
45
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());
51
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);
55     todo_wine
56     ok(!result && GetLastError() == NTE_PROV_TYPE_NO_MATCH,
57         "Expected NTE_PROV_TYPE_NO_MATCH, got %08x\n", GetLastError());
58
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());
64
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());
70
71     /* test base DSS provider (PROV_DSS) */
72
73     result = CryptAcquireContextA(
74         &hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
75     if(!result)
76     {
77         skip("DSS csp is currently not available, skipping tests.\n");
78         return;
79     }
80     ok(result, "Expected no errors.\n");
81
82     result = CryptReleaseContext(hProv, 0);
83     ok(result, "Expected release of the provider.\n");
84
85     result = CryptAcquireContextA(
86         &hProv, NULL, MS_DEF_DSS_DH_PROV_A, PROV_DSS_DH, CRYPT_NEWKEYSET);
87     ok(result, "Expected no errors.\n");
88
89     result = CryptReleaseContext(hProv, 0);
90     ok(result, "Expected release of the provider.\n");
91
92     result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DSS, 0);
93     ok(result, "Expected no errors.\n");
94
95     result = CryptReleaseContext(hProv, 0);
96     ok(result, "Expected release of the provider.\n");
97
98     result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, 0);
99     ok(result, "Expected no errors.\n");
100
101     /* test DSS Diffie Hellman provider (PROV_DSS_DH) */
102
103     result = CryptAcquireContextA(
104         &hProv, NULL, MS_DEF_DSS_DH_PROV, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
105     ok(result, "Expected no errors.\n");
106
107     result = CryptReleaseContext(hProv, 0);
108     ok(result, "Expected release of the provider.\n");
109
110     result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DSS_DH, 0);
111     ok(result, "Expected no errors.\n");
112
113     result = CryptReleaseContext(hProv, 0);
114     ok(result, "Expected release of the provider.\n");
115
116     result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_DH_PROV, PROV_DSS_DH, 0);
117     ok(result, "Expected no errors.\n");
118
119     /* test DSS Enhanced provider (MS_ENH_DSS_DH_PROV) */
120
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)
125     {
126         win_skip("DSSENH and Schannel provider is broken on WinNT4\n");
127         return;
128     }
129     ok(result, "Expected no errors.\n");
130
131     result = CryptReleaseContext(hProv, 0);
132     ok(result, "Expected release of the provider.\n");
133
134     result = CryptAcquireContextA(&hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, 0);
135     ok(result, "Expected no errors.\n");
136
137     result = CryptReleaseContext(hProv, 0);
138     ok(result, "Expected release of the provider.\n");
139
140     /* test DSS Schannel provider (PROV_DH_SCHANNEL) */
141
142     result = CryptAcquireContextA(
143         &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV, PROV_DH_SCHANNEL, CRYPT_VERIFYCONTEXT);
144     ok(result, "Expected no errors.\n");
145
146     result = CryptReleaseContext(hProv, 0);
147     ok(result, "Expected release of the provider.\n");
148
149     result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_DH_SCHANNEL, 0);
150     ok(result, "Expected no errors.\n");
151
152     result = CryptReleaseContext(hProv, 0);
153     ok(result, "Expected release of the provider.\n");
154
155     result = CryptAcquireContextA(
156         &hProv, NULL, MS_DEF_DH_SCHANNEL_PROV, PROV_DH_SCHANNEL, 0);
157     ok(result, "Expected no errors.\n");
158
159     result = CryptReleaseContext(hProv, 0);
160     ok(result, "Expected release of the provider.\n");
161
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());
168
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());
174
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());
180 }
181
182 struct keylength_test {
183     ALG_ID algid;
184     DWORD flags;
185     BOOL expectedResult;
186     DWORD expectedError;
187     BOOL brokenResult;
188     DWORD brokenError;
189 };
190
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}
221 };
222
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}
255 };
256
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}
294 };
295
296 static void test_keylength_array(HCRYPTPROV hProv,const struct keylength_test *tests, int testLen)
297 {
298     HCRYPTKEY key;
299     BOOL result;
300     int i;
301
302     for (i = 0; i < testLen; i++)
303     {
304         SetLastError(0xdeadbeef);
305         result = CryptGenKey(hProv, tests[i].algid, tests[i].flags, &key);
306
307         /* success */
308         if(tests[i].expectedResult)
309         {
310             ok(result, "Expected a key, got %08x\n", GetLastError());
311             result = CryptDestroyKey(key);
312             ok(result, "Expected no errors.\n");
313         }
314         else
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());
319             else
320             {
321                 /* error */
322                 if(!tests[i].brokenError)
323                     ok(!result && GetLastError() == tests[i].expectedError,
324                         "Expected a key, got %x.\n", GetLastError());
325
326                 /* error but different error on older system */
327                 else
328                     ok(!result && (GetLastError() == tests[i].expectedError ||
329                         broken(GetLastError() == tests[i].brokenError)),
330                         "Expected a key, got %x.\n", GetLastError());
331             }
332         }
333     }
334 }
335
336 #define TESTLEN(x) (sizeof(x) / sizeof((x)[0]))
337
338 static void test_keylength(void)
339 {
340     HCRYPTPROV hProv = 0;
341     BOOL result;
342
343     /* acquire base dss provider */
344     result = CryptAcquireContextA(
345         &hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
346     if(!result)
347     {
348         skip("DSSENH is currently not available, skipping key length tests.\n");
349         return;
350     }
351     ok(result, "Expected no errors.\n");
352
353     /* perform keylength tests */
354     test_keylength_array(hProv, baseDSS_keylength, TESTLEN(baseDSS_keylength));
355
356     result = CryptReleaseContext(hProv, 0);
357     ok(result, "Expected release of CSP provider.\n");
358
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");
363
364     /* perform keylength tests */
365     test_keylength_array(hProv, dssDH_keylength, TESTLEN(dssDH_keylength));
366
367     result = CryptReleaseContext(hProv, 0);
368     ok(result, "Expected release of CSP provider.\n");
369
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)
375     {
376         win_skip("DSSENH and Schannel provider is broken on WinNT4\n");
377         return;
378     }
379     ok(result, "Expected no errors.\n");
380
381     /* perform keylength tests */
382     test_keylength_array(hProv, dssENH_keylength, TESTLEN(dssENH_keylength));
383
384     result = CryptReleaseContext(hProv, 0);
385     ok(result, "Expected release of CSP provider.\n");
386
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");
391
392     /* perform keylength tests */
393     test_keylength_array(hProv, dssENH_keylength, TESTLEN(dssENH_keylength));
394
395     result = CryptReleaseContext(hProv, 0);
396     ok(result, "Expected release of CSP provider.\n");
397 }
398
399 struct hash_test {
400     ALG_ID algid;
401     BYTE* input;
402     DWORD dataLen;
403     BYTE hash[20];
404     DWORD hashLen;
405 };
406
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[] = "";
410
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}
430 };
431
432 static void test_hash(const struct hash_test *tests, int testLen)
433 {
434     HCRYPTPROV hProv = 0;
435     HCRYPTHASH hHash;
436     BYTE hashValue[36];
437     BOOL result;
438     int i;
439
440     result = CryptAcquireContextA(
441         &hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, CRYPT_VERIFYCONTEXT);
442     if(!result)
443     {
444         skip("DSSENH is currently not available, skipping hashing tests.\n");
445         return;
446     }
447     ok(result, "Expected no errors.\n");
448
449     for(i = 0; i < testLen; i++)
450     {
451         BYTE* data = tests[i].input;
452         DWORD dataLen = tests[i].dataLen;
453         DWORD hashLen;
454
455         /* test algid hash */
456         result = CryptCreateHash(hProv, tests[i].algid, 0, 0, &hHash);
457         ok(result, "Expected creation of a hash.\n");
458
459         result = CryptHashData(hHash, data, dataLen, 0);
460         ok(result, "Expected data to be added to hash.\n");
461
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());
466
467         result = CryptGetHashParam(hHash, HP_HASHVAL, hashValue, &hashLen, 0);
468         ok(result, "Expected hash value return.\n");
469
470         ok(!memcmp(hashValue, tests[i].hash, tests[i].hashLen), "Incorrect hash output.\n");
471
472         result = CryptHashData(hHash, data, dataLen, 0);
473         ok(!result, "Should not be able to add to hash.\n");
474
475         result = CryptDestroyHash(hHash);
476         ok(result, "Expected destruction of hash.\n");
477     }
478     result = CryptReleaseContext(hProv, 0);
479     ok(result, "Expected release of the DSS Enhanced provider.\n");
480 }
481
482 struct encrypt_test {
483     ALG_ID algid;
484     DWORD keyLength;
485     const char *plain;
486     DWORD plainLen;
487     const BYTE *decrypted;
488     const BYTE *encrypted;
489 };
490
491 static const char dataToEncrypt1[] = "Great performance with Wine.";
492 static const char dataToEncrypt2[] = "Wine implements Windows API";
493 static const char dataToEncrypt3[] = "";
494
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
498 };
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
502 };
503 static const BYTE encrypted3DES_3[] = {0xaf, 0x36, 0xc0, 0x3d, 0x78, 0x64, 0xc4, 0x4a};
504
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
508 };
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
512 };
513 static const BYTE encrypted3DES112_3[] = {0x04, 0xb3, 0x9c, 0x59, 0x48, 0xc7, 0x2f, 0xd1};
514
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
518 };
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
522 };
523 static const BYTE encryptedDES_3[] = {0x35, 0x02, 0xbb, 0x7c, 0x43, 0x5b, 0xf5, 0x59};
524
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
528 };
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
532 };
533 static const BYTE encryptedRC2_3[] = {0x26,0x40,0x73,0xfe,0x13,0xbb,0x32,0xa8};
534
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
538 };
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
542 };
543 static const BYTE encryptedRC4_3[] = {0x1d};
544
545 static const struct encrypt_test encrypt_data[] = {
546     {CALG_3DES, 168 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
547         encrypted3DES_1},
548     {CALG_3DES, 168 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
549         encrypted3DES_2},
550     {CALG_3DES, 168 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
551         encrypted3DES_3},
552     {CALG_3DES_112, 112 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
553         encrypted3DES112_1},
554     {CALG_3DES_112, 112 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
555         encrypted3DES112_2},
556     {CALG_3DES_112, 112 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
557         encrypted3DES112_3},
558     {CALG_DES, 56 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
559         encryptedDES_1},
560     {CALG_DES, 56 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
561         encryptedDES_2},
562     {CALG_DES, 56 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
563         encryptedDES_3},
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,
568         encryptedRC2_1},
569     {CALG_RC2, 40 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
570         encryptedRC2_2},
571     {CALG_RC2, 40 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
572         encryptedRC2_3},
573     {CALG_RC4, 40 << 16, dataToEncrypt1, sizeof(dataToEncrypt1), (BYTE *)dataToEncrypt1,
574         encryptedRC4_1},
575     {CALG_RC4, 40 << 16, dataToEncrypt2, sizeof(dataToEncrypt2), (BYTE *)dataToEncrypt2,
576         encryptedRC4_2},
577     {CALG_RC4, 40 << 16, dataToEncrypt3, sizeof(dataToEncrypt3), (BYTE *)dataToEncrypt3,
578         encryptedRC4_3}
579 };
580
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;
584     HCRYPTKEY pKey = 0;
585     HCRYPTHASH hHash;
586     const char dataToHash[] = "I love working with Wine";
587     unsigned char pbData[36];
588     DWORD dataLen;
589     BOOL result;
590     int i;
591
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)
597     {
598         skip("DSSENH is currently not available, skipping encryption tests.\n");
599         return;
600     }
601     ok(result, "Expected no errors.\n");
602
603     /* testing various encryption algorithms */
604     for(i = 0; i < testLen; i++)
605     {
606         memcpy(pbData, tests[i].plain, tests[i].plainLen);
607         dataLen = tests[i].plainLen;
608
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");
612
613         result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
614         ok(result, "Expected data to be added to hash for key derivation.\n");
615
616         /* Derive key */
617         result = CryptDeriveKey(hProv, tests[i].algid, hHash, tests[i].keyLength, &pKey);
618         ok(result, "Expected a derived key.\n");
619
620         result = CryptDestroyHash(hHash);
621         ok(result, "Expected destruction of hash after deriving key.\n");
622
623         /* testing CryptEncrypt with ALGID from array */
624         result = CryptEncrypt(pKey, 0, TRUE, 0, pbData, &dataLen, 36);
625         ok(result, "Expected data encryption.\n");
626
627         /* Verify we have received expected encrypted data */
628         ok(!memcmp(pbData, tests[i].encrypted, dataLen), "Incorrect encrypted data.\n");
629
630         result = CryptDecrypt(pKey, 0, TRUE, 0, pbData, &dataLen);
631         ok(result, "Expected data decryption.\n");
632
633         /* Verify we have received expected decrypted data */
634         ok(!memcmp(pbData, tests[i].decrypted, dataLen), "Incorrect decrypted data.\n");
635
636         result = CryptDestroyKey(pKey);
637         ok(result, "Expected no DestroyKey errors.\n");
638     }
639     result = CryptReleaseContext(hProv, 0);
640     ok(result, "Expected release of the provider\n");
641 }
642
643 struct ciphermode_test {
644     DWORD cipherMode;
645     BOOL expectedResult;
646     DWORD expectedError;
647     const BYTE *encrypted;
648 };
649
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
653 };
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
657 };
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
661 };
662
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 */
668 };
669
670 static void test_cipher_modes(const struct ciphermode_test *tests, int testLen)
671 {
672     HCRYPTPROV hProv = 0;
673     HCRYPTKEY pKey = 0;
674     HCRYPTHASH hHash;
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;
679     DWORD mode, dataLen;
680     BOOL result;
681
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)
687     {
688         skip("DSSENH is currently not available, skipping block cipher mode tests.\n");
689         return;
690     }
691     ok(result, "Expected no errors.\n");
692
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");
696
697     result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
698     ok(result, "Expected data to be added to hash for key derivation.\n");
699
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");
703
704     result = CryptDestroyHash(hHash);
705     ok(result, "Expected destruction of hash after deriving key.\n");
706
707     /* test block cipher modes */
708     for(i = 0; i < testLen; i++)
709     {
710         SetLastError(0xdeadbeef);
711         dataLen = plainLen;
712         mode = tests[i].cipherMode;
713         memcpy(pbData, plainText, plainLen);
714
715         result = CryptSetKeyParam(pKey, KP_MODE, (BYTE*)&mode, 0);
716         if(tests[i].expectedResult)
717         {
718             ok(result, "Expected setting of KP_MODE, got %x.\n", GetLastError());
719
720             result = CryptEncrypt(pKey, 0, TRUE, 0, pbData, &dataLen, 36);
721             ok(result, "Expected data encryption, got %x.\n", GetLastError());
722
723             /* Verify we have the correct encrypted data */
724             ok(!memcmp(pbData, tests[i].encrypted, dataLen), "Incorrect encrypted data.\n");
725
726             result = CryptDecrypt(pKey, 0, TRUE, 0, pbData, &dataLen);
727             ok(result, "Expected data decryption, got %x.\n", GetLastError());
728
729             /* Verify we have the correct decrypted data */
730             ok(!memcmp(pbData, (BYTE *)plainText, dataLen), "Incorrect decrypted data.\n");
731         }
732         else
733         {   /* Expected error */
734             ok(!result && GetLastError() == tests[i].expectedError, "Expected %d, got %x.\n",
735                 tests[i].expectedError, GetLastError());
736         }
737     }
738     result = CryptDestroyKey(pKey);
739     ok(result, "Expected no DestroyKey errors.\n");
740
741     result = CryptReleaseContext(hProv, 0);
742     ok(result, "Expected release of the provider.\n");
743 }
744
745 struct signature_test {
746     const BYTE *privateKey;
747     DWORD keyLen;
748     BYTE* signData;
749     DWORD dataLen;
750 };
751
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[] = "";
755
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
778 };
779
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
802 };
803
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)}
811 };
812
813 static void test_signhash_array(HCRYPTPROV hProv, const struct signature_test *tests, int testLen)
814 {
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;
822     BOOL result;
823     int i;
824
825     for (i = 0; i < testLen; i++)
826     {
827         DWORD signLen1 = tests[i].dataLen;
828         DWORD signLen2 = tests[i].dataLen;
829
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());
833
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());
837
838         result = CryptHashData(hHash1, tests[i].signData, signLen1, 0);
839         ok(result, "Failed to add data to hash, got %x\n", GetLastError());
840
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());
844
845         result = CryptHashData(hHash2, tests[i].signData, signLen2, 0);
846         ok(result, "Failed to add data to hash, got %x\n", GetLastError());
847
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());
852
853         result = CryptGetHashParam(hHash1, HP_HASHVAL, hashValue1, &hashLen1, 0);
854         ok(result, "Failed to return hash value.\n");
855
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());
859
860         result = CryptGetHashParam(hHash2, HP_HASHVAL, hashValue2, &hashLen2, 0);
861         ok(result, "Failed to return hash value.\n");
862
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");
866
867         /* Sign hash 1 */
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);
871
872         result = CryptSignHash(hHash1, AT_SIGNATURE, NULL, 0, signValue1, &signLen1);
873         ok(result, "Failed to sign hash, got %x\n", GetLastError());
874
875         /* Sign hash 2 */
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);
879
880         result = CryptSignHash(hHash2, AT_SIGNATURE, NULL, 0, signValue2, &signLen2);
881         ok(result, "Failed to sign hash2, got %x\n", GetLastError());
882
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");
887
888         result = CryptExportKey(privKey, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen);
889         ok(result, "Failed to acquire public key length, got %x\n", GetLastError());
890
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());
894
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());
899
900         /* Destroy the private key */
901         result = CryptDestroyKey(privKey);
902         ok(result, "Failed to destroy private key, got %x\n", GetLastError());
903
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());
907
908         result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash1);
909         ok(result, "Failed to create hash, got %x\n", GetLastError());
910
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());
914
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());
918
919         result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
920         ok(result, "Failed to create hash, got %x\n", GetLastError());
921
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());
925
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());
929
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());
934
935         /* Destroy the public key */
936         result = CryptDestroyKey(pubKey);
937         ok(result, "Failed to destroy public key, got %x\n", GetLastError());
938     }
939 }
940
941 static void test_verify_signature(void)
942 {
943     HCRYPTPROV hProv = 0;
944     BOOL result;
945
946     /* acquire base dss provider */
947     result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, 0);
948     if(!result)
949     {
950         skip("DSSENH is currently not available, skipping signature verification tests.\n");
951         return;
952     }
953     ok(result, "Failed to acquire CSP.\n");
954
955     test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
956
957     result = CryptReleaseContext(hProv, 0);
958     ok(result, "Failed to release CSP provider.\n");
959
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");
963
964     test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
965
966     result = CryptReleaseContext(hProv, 0);
967     ok(result, "Failed to release CSP provider.\n");
968
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)
973     {
974         win_skip("DSSENH and Schannel provider is broken on WinNT4, skipping signature "
975             "verification tests.\n");
976         return;
977     }
978     ok(result, "Failed to acquire CSP.\n");
979
980     test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
981
982     result = CryptReleaseContext(hProv, 0);
983     ok(result, "Failed to release CSP provider.\n");
984
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");
988
989     test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
990
991     result = CryptReleaseContext(hProv, 0);
992     ok(result, "Failed to release CSP provider.\n");
993 }
994
995 struct keyExchange_test {
996     ALG_ID algid;
997     const BYTE *primeNum;
998     int primeLen;
999     const BYTE *generatorNum;
1000     int generatorLen;
1001 };
1002
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
1009 };
1010
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
1016 };
1017
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
1023 };
1024
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
1030 };
1031
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
1037 };
1038
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
1044 };
1045
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)}
1054 };
1055
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)}
1063 };
1064
1065 static void test_keyExchange_baseDSS(HCRYPTPROV hProv, const struct keyExchange_test *tests, int testLen)
1066 {
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;
1076     ALG_ID algid;
1077     BOOL result;
1078
1079     for(i = 0; i < testLen; i++)
1080     {
1081         SetLastError(0xdeadbeef);
1082
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;
1088
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());
1093
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());
1097
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 */
1102
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 */
1106
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 */
1110
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 */
1114
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 */
1119
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 */
1123
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 */
1128
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 */
1132
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 */
1137
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 */
1141
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());
1149
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());
1156
1157         /* Set the shared key parameters to matching type */
1158         algid = CALG_RC4;
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 */
1162
1163         algid = CALG_RC4;
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 */
1167
1168         /* Encrypt some data and verify we are getting the same output */
1169         memcpy(pbData1, plainText, plainLen);
1170         dataLen = plainLen;
1171
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 */
1175
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 */
1179
1180         ok(!memcmp(pbData1, (BYTE *)plainText, sizeof(plainText)), "Incorrect decrypted data.\n");
1181
1182         memcpy(pbData2, plainText, plainLen);
1183         dataLen = plainLen;
1184
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 */
1188
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 */
1192
1193         ok(!memcmp(pbData1, pbData2, dataLen), "Decrypted data is not identical.\n");
1194
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 */
1199
1200         result = CryptDestroyKey(sessionKey2);
1201         ok((!result && GetLastError() ==  ERROR_INVALID_PARAMETER) || broken(result),
1202             "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1203
1204         result = CryptDestroyKey(privKey1);
1205         ok((!result && GetLastError() ==  ERROR_INVALID_PARAMETER) || broken(result),
1206             "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1207
1208         result = CryptDestroyKey(privKey2);
1209         ok((!result && GetLastError() ==  ERROR_INVALID_PARAMETER) || broken(result),
1210             "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); /* WinNT4 */
1211     }
1212 }
1213
1214 static void test_keyExchange_dssDH(HCRYPTPROV hProv, const struct keyExchange_test *tests, int testLen)
1215 {
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;
1225     ALG_ID algid;
1226     BOOL result;
1227
1228     for(i = 0; i < testLen; i++)
1229     {
1230         SetLastError(0xdeadbeef);
1231
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;
1237
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());
1241
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());
1244
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());
1248
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());
1251
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());
1254
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());
1257
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 */
1262
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 */
1266
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());
1270
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());
1273
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());
1277
1278         result = CryptExportKey(privKey2, 0, PUBLICKEYBLOB, 0, pubKeyBuffer2, &pubKeyLen2);
1279         ok(result, "Failed to export public key for user 2, got %x\n", GetLastError());
1280
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());
1284
1285         result = CryptImportKey(hProv, pubKeyBuffer1, pubKeyLen1, privKey2, 0, &sessionKey2);
1286         ok(result, "Failed to import key for user 2, got %x\n", GetLastError());
1287
1288         /* Set the shared key parameters to matching cipher type */
1289         algid = CALG_RC4;
1290         result = CryptSetKeyParam(sessionKey1, KP_ALGID, (BYTE *)&algid, 0);
1291         ok(result, "Failed to set session key for user 1, got %x\n", GetLastError());
1292
1293         algid = CALG_RC4;
1294         result = CryptSetKeyParam(sessionKey2, KP_ALGID, (BYTE *)&algid, 0);
1295         ok(result, "Failed to set session key for user 2, got %x\n", GetLastError());
1296
1297         /* Encrypt some data and verify we are getting the correct output */
1298         memcpy(pbData1, plainText, plainLen);
1299         dataLen = plainLen;
1300
1301         result = CryptEncrypt(sessionKey1, 0, TRUE, 0, pbData1, &dataLen, 36);
1302         ok(result, "Failed to encrypt data, got %x.\n", GetLastError());
1303
1304         result = CryptDecrypt(sessionKey2, 0, TRUE, 0, pbData1, &dataLen);
1305         ok(result, "Failed to decrypt data, got %x.\n", GetLastError());
1306
1307         ok(!memcmp(pbData1, (BYTE *)plainText, sizeof(plainText)), "Incorrect decrypted data.\n");
1308
1309         memcpy(pbData2, plainText, plainLen);
1310         dataLen = plainLen;
1311
1312         result = CryptEncrypt(sessionKey2, 0, TRUE, 0, pbData2, &dataLen, 36);
1313         ok(result, "Failed to encrypt data, got %x.\n", GetLastError());
1314
1315         result = CryptDecrypt(sessionKey1, 0, TRUE, 0, pbData2, &dataLen);
1316         ok(result, "Failed to decrypt data, got %x.\n", GetLastError());
1317
1318         ok(!memcmp(pbData1, pbData2, dataLen), "Decrypted data is not identical.\n");
1319
1320         /* Destroy all user keys */
1321         result = CryptDestroyKey(sessionKey1);
1322         ok(result, "Failed to destroy session key 1, got %x\n", GetLastError());
1323
1324         result = CryptDestroyKey(sessionKey2);
1325         ok(result, "Failed to destroy session key 2, got %x\n", GetLastError());
1326
1327         result = CryptDestroyKey(privKey1);
1328         ok(result, "Failed to destroy key private key 1, got %x\n", GetLastError());
1329
1330         result = CryptDestroyKey(privKey2);
1331         ok(result, "Failed to destroy key private key 2, got %x\n", GetLastError());
1332     }
1333 }
1334
1335 static void test_key_exchange(void)
1336 {
1337     HCRYPTPROV hProv = 0;
1338     BOOL result;
1339
1340     /* acquire base dss provider */
1341     result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
1342     if(!result)
1343     {
1344         skip("DSSENH is currently not available, skipping shared key tests.\n");
1345         return;
1346     }
1347     ok(result, "Failed to acquire CSP.\n");
1348
1349     test_keyExchange_baseDSS(hProv, baseDSSkey_data, TESTLEN(baseDSSkey_data));
1350
1351     result = CryptReleaseContext(hProv, 0);
1352     ok(result, "Failed to release CSP provider.\n");
1353
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");
1358
1359     test_keyExchange_dssDH(hProv,  dssDHkey_data, TESTLEN(dssDHkey_data));
1360
1361     result = CryptReleaseContext(hProv, 0);
1362     ok(result, "Failed to release CSP provider.\n");
1363
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)
1368     {
1369         win_skip("DSSENH and Schannel provider is broken on WinNT4, skipping shared key tests.\n");
1370         return;
1371     }
1372     ok(result, "Failed to acquire CSP.\n");
1373
1374     test_keyExchange_dssDH(hProv, dssDHkey_data, TESTLEN(dssDHkey_data));
1375
1376     result = CryptReleaseContext(hProv, 0);
1377     ok(result, "Failed to release CSP provider.\n");
1378
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");
1383
1384     test_keyExchange_dssDH(hProv, dssDHkey_data, TESTLEN(dssDHkey_data));
1385
1386     result = CryptReleaseContext(hProv, 0);
1387     ok(result, "Failed to release CSP provider.\n");
1388 }
1389
1390 START_TEST(dssenh)
1391 {
1392     test_acquire_context();
1393     test_keylength();
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();
1399 }