rsaenh/tests: Add tests for CRYPT_IPSEC_HMAC_KEY.
[wine] / dlls / rsaenh / tests / rsaenh.c
1 /*
2  * Unit tests for rsaenh functions
3  *
4  * Copyright (c) 2004 Michael Jung
5  * Copyright (c) 2006 Juan Lang
6  * Copyright (c) 2007 Vijay Kiran Kamuju
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22
23 #include <string.h>
24 #include <stdio.h>
25 #include "wine/test.h"
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winerror.h"
29 #include "wincrypt.h"
30 #include "winreg.h"
31
32 static HCRYPTPROV hProv;
33 static const char szContainer[] = "winetest";
34 static const char szProvider[] = MS_ENHANCED_PROV_A;
35
36 typedef struct _ctdatatype {
37        unsigned char origstr[32];
38        unsigned char decstr[32];
39        int strlen;
40        int enclen;
41        int buflen;
42 } cryptdata;
43
44 static const cryptdata cTestData[4] = {
45        {"abcdefghijkl",
46        {'a','b','c','d','e','f','g','h',0x2,0x2,'k','l',0},
47        12,8,16},
48        {"abcdefghij",
49        {'a','b','c','d','e','f','g','h',0x2,0x2,0},
50        10,8,16},
51        {"abcdefgh",
52        {'a','b','c','d','e','f','g','h',0},
53        8,8,16},
54        {"abcdefghijkl",
55        {'a','b','c','d','e','f','g','h','i','j','k','l',0},
56        12,12,16}
57 };
58
59 /*
60  * 1. Take the MD5 Hash of the container name (with an extra null byte)
61  * 2. Turn the hash into a 4 DWORD hex value
62  * 3. Append a '_'
63  * 4. Add the MachineGuid
64  *
65  */
66 static void uniquecontainer(char *unique)
67 {
68     /* MD5 hash of "winetest\0" in 4 DWORD hex */
69     static const char szContainer_md5[] = "9d20fd8d05ed2b8455d125d0bf6d6a70";
70     static const char szCryptography[] = "Software\\Microsoft\\Cryptography";
71     static const char szMachineGuid[] = "MachineGuid";
72     HKEY hkey;
73     char guid[MAX_PATH];
74     DWORD size = MAX_PATH;
75     HRESULT ret;
76
77     /* Get the MachineGUID */
78     ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, szCryptography, 0, KEY_READ | KEY_WOW64_64KEY, &hkey);
79     if (ret == ERROR_ACCESS_DENIED)
80     {
81         /* Windows 2000 can't handle KEY_WOW64_64KEY */
82         RegOpenKeyA(HKEY_LOCAL_MACHINE, szCryptography, &hkey);
83     }
84     RegQueryValueExA(hkey, szMachineGuid, NULL, NULL, (LPBYTE)guid, &size);
85     RegCloseKey(hkey);
86
87     lstrcpy(unique, szContainer_md5);
88     lstrcat(unique, "_");
89     lstrcat(unique, guid);
90 }
91
92 static void printBytes(const char *heading, const BYTE *pb, size_t cb)
93 {
94     size_t i;
95     printf("%s: ",heading);
96     for(i=0;i<cb;i++)
97         printf("0x%02x,",pb[i]);
98     putchar('\n');
99 }
100
101 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
102
103 /*
104 static void trace_hex(BYTE *pbData, DWORD dwLen) {
105     char szTemp[256];
106     DWORD i, j;
107
108     for (i = 0; i < dwLen-7; i+=8) {
109         sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", 
110             pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5], 
111             pbData[i+6], pbData[i+7]);
112         trace(szTemp);
113     }
114     for (j=0; i<dwLen; j++,i++) {
115         sprintf(szTemp+6*j, "0x%02x,\n", pbData[i]);
116     }
117     trace(szTemp);
118 }
119 */
120
121 static int init_base_environment(DWORD dwKeyFlags)
122 {
123     HCRYPTKEY hKey;
124     BOOL result;
125         
126     pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
127         
128     hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
129
130     result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
131     ok(!result && (GetLastError()==NTE_BAD_FLAGS ||
132        broken(GetLastError() == NTE_KEYSET_NOT_DEF /* Win9x/NT4 */)),
133        "%d, %08x\n", result, GetLastError());
134     
135     if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
136     {
137         ok(GetLastError()==NTE_BAD_KEYSET ||
138            broken(GetLastError() == NTE_TEMPORARY_PROFILE /* some Win7 setups */) ||
139            broken(GetLastError() == NTE_KEYSET_NOT_DEF /* Win9x/NT4 */),
140            "%08x\n", GetLastError());
141         if (GetLastError()!=NTE_BAD_KEYSET)
142         {
143             win_skip("RSA full provider not available\n");
144             return 0;
145         }
146         result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 
147                                      CRYPT_NEWKEYSET);
148         ok(result, "%08x\n", GetLastError());
149         if (!result)
150         {
151             win_skip("Couldn't create crypto provider\n");
152             return 0;
153         }
154         result = CryptGenKey(hProv, AT_KEYEXCHANGE, dwKeyFlags, &hKey);
155         ok(result, "%08x\n", GetLastError());
156         if (result) CryptDestroyKey(hKey);
157         result = CryptGenKey(hProv, AT_SIGNATURE, dwKeyFlags, &hKey);
158         ok(result, "%08x\n", GetLastError());
159         if (result) CryptDestroyKey(hKey);
160     }
161     return 1;
162 }
163
164 static void clean_up_base_environment(void)
165 {
166     BOOL result;
167
168     SetLastError(0xdeadbeef);
169     result = CryptReleaseContext(hProv, 1);
170     ok(!result || broken(result) /* Win98 */, "Expected failure\n");
171     ok(GetLastError()==NTE_BAD_FLAGS, "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
172         
173     /* Just to prove that Win98 also released the CSP */
174     SetLastError(0xdeadbeef);
175     result = CryptReleaseContext(hProv, 0);
176     ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
177
178     CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
179 }
180
181 static int init_aes_environment(void)
182 {
183     HCRYPTKEY hKey;
184     BOOL result;
185
186     pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
187
188     hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
189
190     /* we are using NULL as provider name for RSA_AES provider as the provider
191      * names are different in Windows XP and Vista. Its different as to what
192      * its defined in the SDK on Windows XP.
193      * This provider is available on Windows XP, Windows 2003 and Vista.      */
194
195     result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
196     if (!result && GetLastError() == NTE_PROV_TYPE_NOT_DEF)
197     {
198         win_skip("RSA_AES provider not supported\n");
199         return 0;
200     }
201     ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
202
203     if (!CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, 0))
204     {
205         ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
206         if (GetLastError()!=NTE_BAD_KEYSET) return 0;
207         result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES,
208                                      CRYPT_NEWKEYSET);
209         ok(result, "%08x\n", GetLastError());
210         if (!result) return 0;
211         result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
212         ok(result, "%08x\n", GetLastError());
213         if (result) CryptDestroyKey(hKey);
214         result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
215         ok(result, "%08x\n", GetLastError());
216         if (result) CryptDestroyKey(hKey);
217     }
218     return 1;
219 }
220
221 static void clean_up_aes_environment(void)
222 {
223     BOOL result;
224
225     result = CryptReleaseContext(hProv, 1);
226     ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
227
228     CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_DELETEKEYSET);
229 }
230
231 static void test_prov(void) 
232 {
233     BOOL result;
234     DWORD dwLen, dwInc;
235     
236     dwLen = (DWORD)sizeof(DWORD);
237     SetLastError(0xdeadbeef);
238     result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
239     if (!result && GetLastError() == NTE_BAD_TYPE)
240         skip("PP_SIG_KEYSIZE_INC is not supported (win9x or NT)\n");
241     else
242         ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
243     
244     dwLen = (DWORD)sizeof(DWORD);
245     SetLastError(0xdeadbeef);
246     result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
247     if (!result && GetLastError() == NTE_BAD_TYPE)
248         skip("PP_KEYX_KEYSIZE_INC is not supported (win9x or NT)\n");
249     else
250         ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
251 }
252
253 static void test_gen_random(void)
254 {
255     BOOL result;
256     BYTE rnd1[16], rnd2[16];
257
258     memset(rnd1, 0, sizeof(rnd1));
259     memset(rnd2, 0, sizeof(rnd2));
260
261     result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
262     if (!result && GetLastError() == NTE_FAIL) {
263         /* rsaenh compiled without OpenSSL */
264         return;
265     }
266     
267     ok(result, "%08x\n", GetLastError());
268
269     result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
270     ok(result, "%08x\n", GetLastError());
271
272     ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
273 }
274
275 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len) 
276 {
277     HCRYPTHASH hHash;
278     BOOL result;
279     unsigned char pbData[2000];
280     int i;
281
282     *phKey = 0;
283     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
284     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
285     if (!result) {
286         /* rsaenh compiled without OpenSSL */
287         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
288         return FALSE;
289     } 
290     ok(result, "%08x\n", GetLastError());
291     result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
292     ok(result, "%08x\n", GetLastError());
293     if (!result) return FALSE;
294     result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
295     ok(result, "%08x\n", GetLastError());
296     if (!result) return FALSE;
297     len = 2000;
298     result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
299     ok(result, "%08x\n", GetLastError());
300     CryptDestroyHash(hHash);
301     return TRUE;
302 }
303
304 static BYTE abPlainPrivateKey[596] = {
305     0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
306     0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
307     0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
308     0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
309     0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
310     0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
311     0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
312     0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
313     0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
314     0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
315     0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
316     0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
317     0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
318     0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
319     0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
320     0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
321     0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
322     0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
323     0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
324     0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
325     0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
326     0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
327     0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
328     0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
329     0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
330     0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
331     0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
332     0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
333     0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
334     0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
335     0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
336     0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
337     0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
338     0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
339     0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
340     0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
341     0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
342     0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
343     0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
344     0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
345     0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
346     0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
347     0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
348     0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
349     0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
350     0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
351     0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
352     0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
353     0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
354     0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
355     0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
356     0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
357     0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
358     0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
359     0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
360     0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
361     0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
362     0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
363     0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
364     0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
365     0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
366     0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
367     0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
368     0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
369     0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
370     0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
371     0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
372     0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
373     0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
374     0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
375     0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
376     0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
377     0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
378     0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
379     0xf2, 0x5d, 0x58, 0x07
380 };
381
382 static void test_hashes(void)
383 {
384     static const unsigned char md2hash[16] = {
385         0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9, 
386         0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
387     static const unsigned char md4hash[16] = {
388         0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23, 
389         0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
390     static const unsigned char empty_md5hash[16] = {
391         0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
392         0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
393     static const unsigned char md5hash[16] = { 
394         0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd, 
395         0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };    
396     static const unsigned char sha1hash[20] = { 
397         0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d, 
398         0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
399     static const unsigned char signed_ssl3_shamd5_hash[] = {
400         0x4f,0xcc,0x2f,0x33,0x44,0x60,0x76,0x16,0x13,0xc8,0xff,0xd4,0x59,0x19,
401         0xde,0x85,0x44,0x72,0x47,0x98,0x01,0xfb,0x67,0x5c,0x5b,0x35,0x15,0x0f,
402         0x91,0xda,0xc7,0x7c,0xfb,0xe2,0x18,0xef,0xac,0x31,0x40,0x7b,0xa9,0x83,
403         0xdb,0x30,0xcd,0x94,0x4b,0x8e,0x3b,0x6c,0x7a,0x86,0x59,0xf0,0xd1,0xd2,
404         0x5e,0xce,0xd4,0x1b,0x7f,0xed,0x24,0xee,0x53,0x5c,0x15,0x97,0x21,0x7c,
405         0x5c,0xea,0xab,0xf5,0xd6,0x4b,0xb3,0xbb,0x14,0xf5,0x59,0x9e,0x21,0x90,
406         0x21,0x99,0x19,0xad,0xa2,0xa6,0xea,0x61,0xc1,0x41,0xe2,0x70,0x77,0xf7,
407         0x15,0x68,0x96,0x1e,0x5c,0x84,0x97,0xe3,0x5c,0xd2,0xd9,0xfb,0x87,0x6f,
408         0x11,0x21,0x82,0x43,0x76,0x32,0xa4,0x38,0x7b,0x85,0x22,0x30,0x1e,0x55,
409         0x79,0x93 };
410     unsigned char pbData[2048];
411     BOOL result;
412     HCRYPTHASH hHash, hHashClone;
413     HCRYPTPROV prov;
414     BYTE pbHashValue[36];
415     BYTE pbSigValue[128];
416     HCRYPTKEY hKeyExchangeKey;
417     DWORD hashlen, len, error;
418     int i;
419
420     for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
421
422     /* MD2 Hashing */
423     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
424     if (!result) {
425         /* rsaenh compiled without OpenSSL */
426         ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
427     } else {
428         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
429         ok(result, "%08x\n", GetLastError());
430
431         len = sizeof(DWORD);
432         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
433            ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
434
435         len = 16;
436         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
437         ok(result, "%08x\n", GetLastError());
438
439         ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
440
441         result = CryptDestroyHash(hHash);
442         ok(result, "%08x\n", GetLastError());
443     } 
444
445     /* MD4 Hashing */
446     result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
447     ok(result, "%08x\n", GetLastError());
448
449     result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
450     ok(result, "%08x\n", GetLastError());
451
452     len = sizeof(DWORD);
453     result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
454     ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
455
456     len = 16;
457     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
458     ok(result, "%08x\n", GetLastError());
459
460     ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
461
462     result = CryptDestroyHash(hHash);
463     ok(result, "%08x\n", GetLastError());
464
465     /* MD5 Hashing */
466     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
467     ok(result, "%08x\n", GetLastError());
468
469     len = sizeof(DWORD);
470     result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
471     ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
472
473     result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
474     ok(result, "%08x\n", GetLastError());
475
476     len = 16;
477     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
478     ok(result, "%08x\n", GetLastError());
479
480     ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
481
482     result = CryptDestroyHash(hHash);
483     ok(result, "%08x\n", GetLastError());
484
485     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
486     ok(result, "%08x\n", GetLastError());
487
488     /* The hash is available even if CryptHashData hasn't been called */
489     len = 16;
490     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
491     ok(result, "%08x\n", GetLastError());
492
493     ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
494
495     /* It's also stable:  getting it twice results in the same value */
496     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
497     ok(result, "%08x\n", GetLastError());
498
499     ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
500
501     /* Can't add data after the hash been retrieved */
502     SetLastError(0xdeadbeef);
503     result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
504     ok(!result, "Expected failure\n");
505     ok(GetLastError() == NTE_BAD_HASH_STATE ||
506        GetLastError() == NTE_BAD_ALGID, /* Win9x, WinMe, NT4 */
507        "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID, got %08x\n", GetLastError());
508
509     /* You can still retrieve the hash, its value just hasn't changed */
510     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
511     ok(result, "%08x\n", GetLastError());
512
513     ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
514
515     result = CryptDestroyHash(hHash);
516     ok(result, "%08x\n", GetLastError());
517
518     /* SHA1 Hashing */
519     result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
520     ok(result, "%08x\n", GetLastError());
521
522     result = CryptHashData(hHash, pbData, 5, 0);
523     ok(result, "%08x\n", GetLastError());
524
525     if(pCryptDuplicateHash) {
526         result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
527         ok(result, "%08x\n", GetLastError());
528
529         result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
530         ok(result, "%08x\n", GetLastError());
531
532         len = sizeof(DWORD);
533         result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
534         ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
535
536         len = 20;
537         result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
538         ok(result, "%08x\n", GetLastError());
539
540         ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
541
542         result = CryptDestroyHash(hHashClone);
543         ok(result, "%08x\n", GetLastError());
544     }
545
546     result = CryptDestroyHash(hHash);
547     ok(result, "%08x\n", GetLastError());
548
549     /* The SHA-2 variants aren't supported in the RSA full provider */
550     result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
551     ok(!result && GetLastError() == NTE_BAD_ALGID,
552        "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
553     result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
554     ok(!result && GetLastError() == NTE_BAD_ALGID,
555        "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
556     result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
557     ok(!result && GetLastError() == NTE_BAD_ALGID,
558        "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
559
560     result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
561     ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError());
562
563     result = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hHash);
564     ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
565
566     /* release provider before using the hash */
567     result = CryptReleaseContext(prov, 0);
568     ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
569
570     SetLastError(0xdeadbeef);
571     result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
572     error = GetLastError();
573     ok(!result, "CryptHashData succeeded\n");
574     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
575
576     SetLastError(0xdeadbeef);
577     result = CryptDestroyHash(hHash);
578     error = GetLastError();
579     ok(!result, "CryptDestroyHash succeeded\n");
580     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
581
582     if (!pCryptDuplicateHash)
583     {
584         win_skip("CryptDuplicateHash is not available\n");
585         return;
586     }
587
588     result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
589     ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError());
590
591     result = CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
592     ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
593
594     result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
595     ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
596
597     result = pCryptDuplicateHash(hHash, NULL, 0, &hHashClone);
598     ok(result, "CryptDuplicateHash failed 0x%08x\n", GetLastError());
599
600     len = 20;
601     result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
602     ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
603
604     /* add data after duplicating the hash */
605     result = CryptHashData(hHash, (const BYTE *)"more data", sizeof("more data"), 0);
606     ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
607
608     result = CryptDestroyHash(hHash);
609     ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
610
611     result = CryptDestroyHash(hHashClone);
612     ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
613
614     result = CryptReleaseContext(prov, 0);
615     ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
616
617     /* Test CALG_SSL3_SHAMD5 */
618     result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
619     ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError());
620
621     /* Step 1: create an MD5 hash of the data */
622     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
623     ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
624     result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
625     ok(result, "%08x\n", GetLastError());
626     len = 16;
627     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
628     ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
629     result = CryptDestroyHash(hHash);
630     ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
631     /* Step 2: create a SHA1 hash of the data */
632     result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
633     ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
634     result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
635     ok(result, "%08x\n", GetLastError());
636     len = 20;
637     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue + 16, &len, 0);
638     ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
639     result = CryptDestroyHash(hHash);
640     ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
641     /* Step 3: create a CALG_SSL3_SHAMD5 hash handle */
642     result = CryptCreateHash(hProv, CALG_SSL3_SHAMD5, 0, 0, &hHash);
643     ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
644     /* Test that CryptHashData fails on this hash */
645     result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
646     ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
647     result = CryptSetHashParam(hHash, HP_HASHVAL, pbHashValue, 0);
648     ok(result, "%08x\n", GetLastError());
649     len = (DWORD)sizeof(abPlainPrivateKey);
650     result = CryptImportKey(hProv, abPlainPrivateKey, len, 0, 0, &hKeyExchangeKey);
651     ok(result, "%08x\n", GetLastError());
652     len = 0;
653     result = CryptSignHash(hHash, AT_KEYEXCHANGE, NULL, 0, NULL, &len);
654     ok(result, "%08x\n", GetLastError());
655     ok(len == 128, "expected len 128, got %d\n", len);
656     result = CryptSignHash(hHash, AT_KEYEXCHANGE, NULL, 0, pbSigValue, &len);
657     ok(result, "%08x\n", GetLastError());
658     ok(!memcmp(pbSigValue, signed_ssl3_shamd5_hash, len), "unexpected value\n");
659     if (len != 128 || memcmp(pbSigValue, signed_ssl3_shamd5_hash, len))
660     {
661         printBytes("expected", signed_ssl3_shamd5_hash,
662                    sizeof(signed_ssl3_shamd5_hash));
663         printBytes("got", pbSigValue, len);
664     }
665     result = CryptDestroyHash(hHash);
666     ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
667     result = CryptReleaseContext(prov, 0);
668     ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
669 }
670
671 static void test_block_cipher_modes(void)
672 {
673     static const BYTE plain[23] = { 
674         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 
675         0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
676     static const BYTE ecb[24] = {   
677         0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f, 
678         0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
679     static const BYTE cbc[24] = {   
680         0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
681         0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
682     static const BYTE cfb[24] = {   
683         0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
684         0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
685     HCRYPTKEY hKey;
686     BOOL result;
687     BYTE abData[24];
688     DWORD dwMode, dwLen;
689
690     result = derive_key(CALG_RC2, &hKey, 40);
691     if (!result) return;
692
693     memcpy(abData, plain, sizeof(plain));
694
695     dwMode = CRYPT_MODE_ECB;
696     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
697     ok(result, "%08x\n", GetLastError());
698
699     result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
700     ok(result, "%08x\n", GetLastError());
701     ok(dwLen == 11 || broken(dwLen == 0 /* Win9x/NT4 */), "unexpected salt length %d\n", dwLen);
702
703     dwLen = 23;
704     result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
705     ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
706     ok(dwLen == 24, "Unexpected length %d\n", dwLen);
707
708     SetLastError(ERROR_SUCCESS);
709     dwLen = 23;
710     result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
711     ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)), 
712        "%08x, dwLen: %d\n", GetLastError(), dwLen);
713
714     result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
715     ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)), 
716        "%08x, dwLen: %d\n", GetLastError(), dwLen);
717
718     dwMode = CRYPT_MODE_CBC;
719     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
720     ok(result, "%08x\n", GetLastError());
721     
722     dwLen = 23;
723     result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
724     ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
725     ok(dwLen == 24, "Unexpected length %d\n", dwLen);
726
727     dwLen = 23;
728     result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
729     ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)), 
730        "%08x, dwLen: %d\n", GetLastError(), dwLen);
731
732     result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
733     ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)), 
734        "%08x, dwLen: %d\n", GetLastError(), dwLen);
735
736     dwMode = CRYPT_MODE_CFB;
737     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
738     ok(result, "%08x\n", GetLastError());
739     
740     dwLen = 16;
741     result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
742     ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
743
744     dwLen = 7;
745     result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
746     ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)), 
747        "%08x, dwLen: %d\n", GetLastError(), dwLen);
748     
749     dwLen = 8;
750     result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
751     ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
752
753     dwLen = 16;
754     result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
755     ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)), 
756        "%08x, dwLen: %d\n", GetLastError(), dwLen);
757
758     dwMode = CRYPT_MODE_OFB;
759     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
760     ok(result, "%08x\n", GetLastError());
761     
762     dwLen = 23;
763     result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
764     ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
765
766     CryptDestroyKey(hKey);
767 }
768
769 static void test_3des112(void)
770 {
771     HCRYPTKEY hKey;
772     BOOL result;
773     DWORD dwLen;
774     unsigned char pbData[16];
775     int i;
776
777     result = derive_key(CALG_3DES_112, &hKey, 0);
778     if (!result) {
779         /* rsaenh compiled without OpenSSL */
780         ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
781         return;
782     }
783
784     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
785     
786     dwLen = 13;
787     result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
788     ok(result, "%08x\n", GetLastError());
789     
790     result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
791     ok(result, "%08x\n", GetLastError());
792
793     for (i=0; i<4; i++)
794     {
795       memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
796
797       dwLen = cTestData[i].enclen;
798       result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
799       ok(result, "%08x\n", GetLastError());
800       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
801
802       result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
803       ok(result, "%08x\n", GetLastError());
804       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
805       ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
806       if((dwLen != cTestData[i].enclen) ||
807          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
808       {
809           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
810           printBytes("got",pbData,dwLen);
811       }
812     }
813     result = CryptDestroyKey(hKey);
814     ok(result, "%08x\n", GetLastError());
815 }
816
817 static void test_des(void) 
818 {
819     HCRYPTKEY hKey;
820     BOOL result;
821     DWORD dwLen, dwMode;
822     unsigned char pbData[16];
823     int i;
824
825     result = derive_key(CALG_DES, &hKey, 56);
826     if (!result) {
827         /* rsaenh compiled without OpenSSL */
828         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
829         return;
830     }
831
832     dwMode = CRYPT_MODE_ECB;
833     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
834     ok(result, "%08x\n", GetLastError());
835     
836     dwLen = sizeof(DWORD);
837     result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
838     ok(result, "%08x\n", GetLastError());
839     
840     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
841     
842     dwLen = 13;
843     result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
844     ok(result, "%08x\n", GetLastError());
845     
846     result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
847     ok(result, "%08x\n", GetLastError());
848
849     for (i=0; i<4; i++)
850     {
851       memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
852
853       dwLen = cTestData[i].enclen;
854       result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
855       ok(result, "%08x\n", GetLastError());
856       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
857
858       result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
859       ok(result, "%08x\n", GetLastError());
860       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
861       ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
862       if((dwLen != cTestData[i].enclen) ||
863          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
864       {
865           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
866           printBytes("got",pbData,dwLen);
867       }
868     }
869
870     result = CryptDestroyKey(hKey);
871     ok(result, "%08x\n", GetLastError());
872 }
873
874 static void test_3des(void)
875 {
876     HCRYPTKEY hKey;
877     BOOL result;
878     DWORD dwLen;
879     unsigned char pbData[16];
880     static const BYTE des3[16] = { 
881         0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3, 
882         0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
883     int i;
884
885     result = derive_key(CALG_3DES, &hKey, 0);
886     if (!result) return;
887
888     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
889     
890     dwLen = 13;
891     result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
892     ok(result, "%08x\n", GetLastError());
893
894     ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
895
896     result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
897     ok(result, "%08x\n", GetLastError());
898
899     for (i=0; i<4; i++)
900     {
901       memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
902
903       dwLen = cTestData[i].enclen;
904       result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
905       ok(result, "%08x\n", GetLastError());
906       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
907
908       result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
909       ok(result, "%08x\n", GetLastError());
910       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
911       ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
912       if((dwLen != cTestData[i].enclen) ||
913          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
914       {
915           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
916           printBytes("got",pbData,dwLen);
917       }
918     }
919     result = CryptDestroyKey(hKey);
920     ok(result, "%08x\n", GetLastError());
921 }
922
923 static void test_aes(int keylen)
924 {
925     HCRYPTKEY hKey;
926     BOOL result;
927     DWORD dwLen;
928     unsigned char pbData[16];
929     int i;
930
931     switch (keylen)
932     {
933         case 256:
934             result = derive_key(CALG_AES_256, &hKey, 0);
935             break;
936         case 192:
937             result = derive_key(CALG_AES_192, &hKey, 0);
938             break;
939         default:
940         case 128:
941             result = derive_key(CALG_AES_128, &hKey, 0);
942             break;
943     }
944     if (!result) return;
945
946     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
947
948     /* AES provider doesn't support salt */
949     result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
950     ok((!result && GetLastError() == NTE_BAD_KEY) || result /* Win7 */,
951        "expected NTE_BAD_KEY, got %08x\n", GetLastError());
952
953     dwLen = 13;
954     result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
955     ok(result, "%08x\n", GetLastError());
956
957     result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
958     ok(result, "%08x\n", GetLastError());
959
960     for (i=0; i<4; i++)
961     {
962       memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
963
964       dwLen = cTestData[i].enclen;
965       result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
966       ok(result, "%08x\n", GetLastError());
967       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
968
969       result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
970       ok(result, "%08x\n", GetLastError());
971       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
972       ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
973       if((dwLen != cTestData[i].enclen) ||
974          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
975       {
976           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
977           printBytes("got",pbData,dwLen);
978       }
979     }
980     result = CryptDestroyKey(hKey);
981     ok(result, "%08x\n", GetLastError());
982 }
983
984 static void test_sha2(void)
985 {
986     static const unsigned char sha256hash[32] = {
987         0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
988         0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
989         0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
990         0x1a, 0x08
991     };
992     static const unsigned char sha384hash[48] = {
993         0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
994         0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
995         0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
996         0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
997         0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
998     };
999     static const unsigned char sha512hash[64] = {
1000         0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
1001         0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
1002         0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
1003         0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
1004         0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
1005         0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
1006         0xb7, 0xf4, 0x81, 0xd4
1007     };
1008     unsigned char pbData[2048];
1009     BOOL result;
1010     HCRYPTHASH hHash;
1011     BYTE pbHashValue[64];
1012     DWORD hashlen, len;
1013     int i;
1014
1015     for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
1016
1017     /* SHA-256 hash */
1018     SetLastError(0xdeadbeef);
1019     result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
1020     if (!result && GetLastError() == NTE_BAD_ALGID) {
1021         win_skip("SHA-256/384/512 hashes are not supported before Windows XP SP3\n");
1022         return;
1023     }
1024     ok(result, "%08x\n", GetLastError());
1025     if (result) {
1026         len = sizeof(DWORD);
1027         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1028         ok(result && (hashlen == 32), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1029
1030         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1031         ok(result, "%08x\n", GetLastError());
1032
1033         len = 32;
1034         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1035         ok(result, "%08x\n", GetLastError());
1036
1037         ok(!memcmp(pbHashValue, sha256hash, 32), "Wrong SHA-256 hash!\n");
1038
1039         result = CryptDestroyHash(hHash);
1040         ok(result, "%08x\n", GetLastError());
1041     }
1042
1043     /* SHA-384 hash */
1044     result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
1045     ok(result, "%08x\n", GetLastError());
1046     if (result) {
1047         len = sizeof(DWORD);
1048         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1049         ok(result && (hashlen == 48), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1050
1051         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1052         ok(result, "%08x\n", GetLastError());
1053
1054         len = 48;
1055         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1056         ok(result, "%08x\n", GetLastError());
1057
1058         ok(!memcmp(pbHashValue, sha384hash, 48), "Wrong SHA-384 hash!\n");
1059
1060         result = CryptDestroyHash(hHash);
1061         ok(result, "%08x\n", GetLastError());
1062     }
1063
1064     /* SHA-512 hash */
1065     result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
1066     ok(result, "%08x\n", GetLastError());
1067     if (result) {
1068         len = sizeof(DWORD);
1069         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1070         ok(result && (hashlen == 64), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1071
1072         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1073         ok(result, "%08x\n", GetLastError());
1074
1075         len = 64;
1076         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1077         ok(result, "%08x\n", GetLastError());
1078
1079         ok(!memcmp(pbHashValue, sha512hash, 64), "Wrong SHA-512 hash!\n");
1080
1081         result = CryptDestroyHash(hHash);
1082         ok(result, "%08x\n", GetLastError());
1083     }
1084 }
1085
1086 static void test_rc2(void)
1087 {
1088     static const BYTE rc2_40_encrypted[16] = {
1089         0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
1090         0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
1091     static const BYTE rc2_128_encrypted[] = {
1092         0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
1093         0xb6,0x66 };
1094     HCRYPTHASH hHash;
1095     HCRYPTKEY hKey;
1096     BOOL result;
1097     DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
1098     BYTE *pbTemp;
1099     unsigned char pbData[2000], pbHashValue[16];
1100     int i;
1101     
1102     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1103
1104     /* MD2 Hashing */
1105     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1106     if (!result) {
1107         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1108     } else {
1109         CRYPT_INTEGER_BLOB salt;
1110
1111         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1112         ok(result, "%08x\n", GetLastError());
1113
1114         dwLen = 16;
1115         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1116         ok(result, "%08x\n", GetLastError());
1117
1118         result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
1119         ok(result, "%08x\n", GetLastError());
1120
1121         dwLen = sizeof(DWORD);
1122         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1123         ok(result, "%08x\n", GetLastError());
1124
1125         dwMode = CRYPT_MODE_CBC;
1126         result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
1127         ok(result, "%08x\n", GetLastError());
1128
1129         dwLen = sizeof(DWORD);
1130         result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
1131         ok(result, "%08x\n", GetLastError());
1132
1133         dwModeBits = 0xdeadbeef;
1134         dwLen = sizeof(DWORD);
1135         result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1136         ok(result, "%08x\n", GetLastError());
1137         ok(dwModeBits ==
1138             (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1139             broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
1140             "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1141             " got %08x\n", dwModeBits);
1142
1143         dwLen = sizeof(DWORD);
1144         result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1145         ok(result, "%08x\n", GetLastError());
1146
1147         dwLen = sizeof(DWORD);
1148         result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
1149         ok(result, "%08x\n", GetLastError());
1150
1151         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1152         ok(result, "%08x\n", GetLastError());
1153         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1154         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1155         HeapFree(GetProcessHeap(), 0, pbTemp);
1156
1157         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1158         ok(result, "%08x\n", GetLastError());
1159         /* The default salt length is always 11... */
1160         ok(dwLen == 11, "unexpected salt length %d\n", dwLen);
1161         /* and the default salt is always empty. */
1162         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1163         CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1164         for (i=0; i<dwLen; i++)
1165             ok(!pbTemp[i], "unexpected salt value %02x @ %d\n", pbTemp[i], i);
1166         HeapFree(GetProcessHeap(), 0, pbTemp);
1167
1168         dwLen = sizeof(DWORD);
1169         CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1170
1171         result = CryptDestroyHash(hHash);
1172         ok(result, "%08x\n", GetLastError());
1173
1174         dwDataLen = 13;
1175         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1176         ok(result, "%08x\n", GetLastError());
1177
1178         ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
1179
1180         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1181         ok(result, "%08x\n", GetLastError());
1182         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1183         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1184         HeapFree(GetProcessHeap(), 0, pbTemp);
1185
1186         result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1187         ok(result, "%08x\n", GetLastError());
1188
1189         /* Setting the salt also succeeds... */
1190         result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1191         ok(result, "setting salt failed: %08x\n", GetLastError());
1192         /* but the resulting salt length is now zero? */
1193         dwLen = 0;
1194         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1195         ok(result, "%08x\n", GetLastError());
1196         ok(dwLen == 0 ||
1197            broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1198            "unexpected salt length %d\n", dwLen);
1199         /* What sizes salt can I set? */
1200         salt.pbData = pbData;
1201         for (i=0; i<24; i++)
1202         {
1203             salt.cbData = i;
1204             result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1205             ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1206             /* The returned salt length is the same as the set salt length */
1207             result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1208             ok(result, "%08x\n", GetLastError());
1209             ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1210         }
1211         salt.cbData = 25;
1212         SetLastError(0xdeadbeef);
1213         result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1214         ok(!result ||
1215            broken(result), /* Win9x, WinMe, NT4, W2K */
1216            "%08x\n", GetLastError());
1217
1218         result = CryptDestroyKey(hKey);
1219         ok(result, "%08x\n", GetLastError());
1220     }
1221
1222     /* Again, but test setting the effective key len */
1223     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1224
1225     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1226     if (!result) {
1227         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1228     } else {
1229         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1230         ok(result, "%08x\n", GetLastError());
1231
1232         dwLen = 16;
1233         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1234         ok(result, "%08x\n", GetLastError());
1235
1236         result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
1237         ok(result, "%08x\n", GetLastError());
1238
1239         SetLastError(0xdeadbeef);
1240         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
1241         ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
1242         dwKeyLen = 0;
1243         SetLastError(0xdeadbeef);
1244         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1245         ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
1246         dwKeyLen = 1025;
1247         SetLastError(0xdeadbeef);
1248         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1249
1250         dwLen = sizeof(dwKeyLen);
1251         CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1252         ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1253         CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1254         ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
1255
1256         dwKeyLen = 128;
1257         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1258         ok(result, "%d\n", GetLastError());
1259
1260         dwLen = sizeof(dwKeyLen);
1261         CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1262         ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1263         CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1264         ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
1265
1266         result = CryptDestroyHash(hHash);
1267         ok(result, "%08x\n", GetLastError());
1268
1269         dwDataLen = 13;
1270         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1271         ok(result, "%08x\n", GetLastError());
1272
1273         ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
1274                 "RC2 encryption failed!\n");
1275
1276         /* Oddly enough this succeeds, though it should have no effect */
1277         dwKeyLen = 40;
1278         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1279         ok(result, "%d\n", GetLastError());
1280
1281         result = CryptDestroyKey(hKey);
1282         ok(result, "%08x\n", GetLastError());
1283     }
1284 }
1285
1286 static void test_rc4(void)
1287 {
1288     static const BYTE rc4[16] = { 
1289         0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0, 
1290         0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };    
1291     BOOL result;
1292     HCRYPTHASH hHash;
1293     HCRYPTKEY hKey;
1294     DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1295     unsigned char pbData[2000], *pbTemp;
1296     unsigned char pszBuffer[256];
1297     int i;
1298
1299     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1300
1301     /* MD2 Hashing */
1302     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1303     if (!result) {
1304         /* rsaenh compiled without OpenSSL */
1305         ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
1306     } else {
1307         CRYPT_INTEGER_BLOB salt;
1308
1309         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1310            ok(result, "%08x\n", GetLastError());
1311
1312         dwLen = 16;
1313         result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1314         ok(result, "%08x\n", GetLastError());
1315
1316         result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1317         ok(result, "%08x\n", GetLastError());
1318
1319         dwLen = sizeof(DWORD);
1320         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1321         ok(result, "%08x\n", GetLastError());
1322
1323         dwLen = sizeof(DWORD);
1324         result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1325         ok(result, "%08x\n", GetLastError());
1326
1327         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1328         ok(result, "%08x\n", GetLastError());
1329         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1330         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
1331         HeapFree(GetProcessHeap(), 0, pbTemp);
1332
1333         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1334         ok(result, "%08x\n", GetLastError());
1335         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
1336         CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
1337         HeapFree(GetProcessHeap(), 0, pbTemp);
1338
1339         dwLen = sizeof(DWORD);
1340         CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1341
1342         result = CryptDestroyHash(hHash);
1343         ok(result, "%08x\n", GetLastError());
1344
1345         dwDataLen = 16;
1346         result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1347         ok(result, "%08x\n", GetLastError());
1348         dwDataLen = 16;
1349         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1350         ok(result, "%08x\n", GetLastError());
1351
1352         ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1353
1354         result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1355         ok(result, "%08x\n", GetLastError());
1356
1357         /* Setting the salt also succeeds... */
1358         result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1359         ok(result, "setting salt failed: %08x\n", GetLastError());
1360         /* but the resulting salt length is now zero? */
1361         dwLen = 0;
1362         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1363         ok(result, "%08x\n", GetLastError());
1364         ok(dwLen == 0 ||
1365            broken(dwLen == 11), /* Win9x/WinMe/NT4 */
1366            "unexpected salt length %d\n", dwLen);
1367         /* What sizes salt can I set? */
1368         salt.pbData = pbData;
1369         for (i=0; i<24; i++)
1370         {
1371             salt.cbData = i;
1372             result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1373             ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1374             /* The returned salt length is the same as the set salt length */
1375             result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1376             ok(result, "%08x\n", GetLastError());
1377             ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1378         }
1379         salt.cbData = 25;
1380         SetLastError(0xdeadbeef);
1381         result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1382         ok(!result ||
1383            broken(result), /* Win9x, WinMe, NT4, W2K */
1384            "%08x\n", GetLastError());
1385
1386         result = CryptDestroyKey(hKey);
1387         ok(result, "%08x\n", GetLastError());
1388     }
1389 }
1390
1391 static void test_hmac(void) {
1392     HCRYPTKEY hKey;
1393     HCRYPTHASH hHash;
1394     BOOL result;
1395     /* Using CALG_MD2 here fails on Windows 2003, why ? */
1396     HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1397     DWORD dwLen;
1398     BYTE abData[256];
1399     static const BYTE hmac[16] = { 
1400         0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c, 
1401         0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1402     int i;
1403
1404     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1405
1406     if (!derive_key(CALG_RC2, &hKey, 56)) return;
1407
1408     result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1409     ok(result, "%08x\n", GetLastError());
1410     if (!result) return;
1411
1412     result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1413     ok(result, "%08x\n", GetLastError());
1414
1415     result = CryptHashData(hHash, abData, sizeof(abData), 0);
1416     ok(result, "%08x\n", GetLastError());
1417
1418     dwLen = sizeof(abData)/sizeof(BYTE);
1419     result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1420     ok(result, "%08x\n", GetLastError());
1421
1422     ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1423     
1424     result = CryptDestroyHash(hHash);
1425     ok(result, "%08x\n", GetLastError());
1426     
1427     result = CryptDestroyKey(hKey);
1428     ok(result, "%08x\n", GetLastError());
1429
1430     /* Provoke errors */
1431     result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1432     ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1433 }
1434
1435 static void test_mac(void) {
1436     HCRYPTKEY hKey;
1437     HCRYPTHASH hHash;
1438     BOOL result;
1439     DWORD dwLen;
1440     BYTE abData[256], abEnc[264];
1441     static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1442     int i;
1443
1444     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1445     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1446
1447     if (!derive_key(CALG_RC2, &hKey, 40)) return;
1448
1449     dwLen = 256;
1450     result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1451     ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1452     
1453     result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1454     ok(result, "%08x\n", GetLastError());
1455     if (!result) return;
1456
1457     result = CryptHashData(hHash, abData, sizeof(abData), 0);
1458     ok(result, "%08x\n", GetLastError());
1459
1460     dwLen = sizeof(abData)/sizeof(BYTE);
1461     result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1462     ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1463
1464     ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1465     
1466     result = CryptDestroyHash(hHash);
1467     ok(result, "%08x\n", GetLastError());
1468     
1469     result = CryptDestroyKey(hKey);
1470     ok(result, "%08x\n", GetLastError());
1471     
1472     /* Provoke errors */
1473     if (!derive_key(CALG_RC4, &hKey, 56)) return;
1474
1475     SetLastError(0xdeadbeef);
1476     result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1477     ok((!result && GetLastError() == NTE_BAD_KEY) ||
1478             broken(result), /* Win9x, WinMe, NT4, W2K */
1479             "%08x\n", GetLastError());
1480
1481     result = CryptDestroyKey(hKey);
1482     ok(result, "%08x\n", GetLastError());
1483 }
1484
1485 static void test_import_private(void) 
1486 {
1487     DWORD dwLen, dwVal;
1488     HCRYPTKEY hKeyExchangeKey, hSessionKey;
1489     BOOL result;
1490     static BYTE abSessionKey[148] = {
1491         0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1492         0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1493         0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1494         0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1495         0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1496         0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1497         0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1498         0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1499         0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1500         0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1501         0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1502         0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1503         0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1504         0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1505         0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1506         0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1507         0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1508         0x04, 0x8c, 0x49, 0x92
1509     };
1510     static BYTE abEncryptedMessage[12] = {
1511         0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1512         0x1c, 0xfd, 0xde, 0x71
1513     };
1514             
1515     dwLen = (DWORD)sizeof(abPlainPrivateKey);
1516     result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1517     if (!result) {
1518         /* rsaenh compiled without OpenSSL */
1519         ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1520         return;
1521     }
1522
1523     dwLen = (DWORD)sizeof(abSessionKey);
1524     result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1525     ok(result, "%08x\n", GetLastError());
1526     if (!result) return;
1527
1528     dwVal = 0xdeadbeef;
1529     dwLen = sizeof(DWORD);
1530     result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1531     ok(result, "%08x\n", GetLastError());
1532     ok(dwVal ==
1533         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1534         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1535         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1536         " got %08x\n", dwVal);
1537
1538     dwLen = (DWORD)sizeof(abEncryptedMessage);
1539     result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1540     ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12), 
1541        "%08x, len: %d\n", GetLastError(), dwLen);
1542     CryptDestroyKey(hSessionKey);
1543     
1544     if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1545
1546     dwLen = (DWORD)sizeof(abSessionKey);
1547     result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1548     ok(result, "%08x\n", GetLastError());
1549     CryptDestroyKey(hSessionKey);
1550     if (!result) return;
1551
1552     dwLen = (DWORD)sizeof(abSessionKey);
1553     result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1554     ok(result, "%08x\n", GetLastError());
1555     if (!result) return;
1556
1557     CryptDestroyKey(hSessionKey);
1558     CryptDestroyKey(hKeyExchangeKey);
1559 }
1560
1561 static void test_verify_signature(void) {
1562     HCRYPTHASH hHash;
1563     HCRYPTKEY hPubSignKey;
1564     BYTE abData[] = "Wine rocks!";
1565     BOOL result;
1566     BYTE abPubKey[148] = {
1567         0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 
1568         0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 
1569         0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19, 
1570         0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27, 
1571         0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8, 
1572         0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda, 
1573         0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a, 
1574         0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc, 
1575         0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c, 
1576         0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c, 
1577         0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89, 
1578         0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b, 
1579         0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa, 
1580         0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63, 
1581         0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff, 
1582         0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49, 
1583         0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87, 
1584         0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7, 
1585         0xe1, 0x21, 0x50, 0xac
1586     };
1587     /* md2 with hash oid */
1588     BYTE abSignatureMD2[128] = {
1589         0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67, 
1590         0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b, 
1591         0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda, 
1592         0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59, 
1593         0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a, 
1594         0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34, 
1595         0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40, 
1596         0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7, 
1597         0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0, 
1598         0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06, 
1599         0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51, 
1600         0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f, 
1601         0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46, 
1602         0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25, 
1603         0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0, 
1604         0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1605     };
1606     /* md2 without hash oid */
1607     BYTE abSignatureMD2NoOID[128] = {
1608         0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d, 
1609         0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19, 
1610         0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd, 
1611         0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4, 
1612         0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65, 
1613         0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99, 
1614         0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf, 
1615         0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc, 
1616         0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0, 
1617         0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01, 
1618         0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7, 
1619         0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f, 
1620         0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a, 
1621         0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9, 
1622         0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06, 
1623         0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1624     };
1625     /* md4 with hash oid */
1626     BYTE abSignatureMD4[128] = {
1627         0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51, 
1628         0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b, 
1629         0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2, 
1630         0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e, 
1631         0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13, 
1632         0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9, 
1633         0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f, 
1634         0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96, 
1635         0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9, 
1636         0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e, 
1637         0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0, 
1638         0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe, 
1639         0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18, 
1640         0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab, 
1641         0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3, 
1642         0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1643     };
1644     /* md4 without hash oid */
1645     BYTE abSignatureMD4NoOID[128] = {
1646         0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda, 
1647         0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24, 
1648         0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0, 
1649         0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36, 
1650         0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85, 
1651         0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3, 
1652         0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f, 
1653         0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9, 
1654         0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06, 
1655         0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f, 
1656         0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb, 
1657         0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96, 
1658         0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f, 
1659         0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9, 
1660         0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb, 
1661         0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1662     }; 
1663     /* md5 with hash oid */
1664     BYTE abSignatureMD5[128] = {
1665         0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5, 
1666         0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f, 
1667         0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7, 
1668         0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98, 
1669         0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec, 
1670         0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5, 
1671         0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04, 
1672         0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b, 
1673         0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95, 
1674         0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c, 
1675         0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29, 
1676         0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9, 
1677         0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c, 
1678         0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90, 
1679         0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e, 
1680         0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1681     };
1682     /* md5 without hash oid */
1683     BYTE abSignatureMD5NoOID[128] = {
1684         0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f, 
1685         0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75, 
1686         0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f, 
1687         0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d, 
1688         0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f, 
1689         0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49, 
1690         0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8, 
1691         0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c, 
1692         0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23, 
1693         0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19, 
1694         0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb, 
1695         0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3, 
1696         0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b, 
1697         0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b, 
1698         0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5, 
1699         0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1700     };
1701     /* sha with hash oid */
1702     BYTE abSignatureSHA[128] = {
1703         0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91, 
1704         0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd, 
1705         0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24, 
1706         0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94, 
1707         0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f, 
1708         0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a, 
1709         0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52, 
1710         0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20, 
1711         0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5, 
1712         0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a, 
1713         0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff, 
1714         0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53, 
1715         0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00, 
1716         0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e, 
1717         0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98, 
1718         0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1719     };
1720     /* sha without hash oid */
1721     BYTE abSignatureSHANoOID[128] = {
1722         0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6, 
1723         0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a, 
1724         0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f, 
1725         0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37, 
1726         0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65, 
1727         0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe, 
1728         0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6, 
1729         0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe, 
1730         0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c, 
1731         0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4, 
1732         0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80, 
1733         0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a, 
1734         0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00, 
1735         0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd, 
1736         0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67, 
1737         0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1738     }; 
1739     
1740     result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1741     ok(result, "%08x\n", GetLastError());
1742     if (!result) return;
1743
1744     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1745     ok(result, "%08x\n", GetLastError());
1746     if (!result) return;
1747
1748     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1749     ok(result, "%08x\n", GetLastError());
1750     if (!result) return;
1751
1752     /*check that a NULL pointer signature is correctly handled*/
1753     result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1754     ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1755      "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1756     if (result) return;
1757
1758     /* check that we get a bad signature error when the signature is too short*/
1759     SetLastError(0xdeadbeef);
1760     result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1761     ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
1762      broken(result), /* Win9x, WinMe, NT4 */
1763      "Expected NTE_BAD_SIGNATURE, got %08x\n",  GetLastError());
1764
1765     result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1766     ok(result, "%08x\n", GetLastError());
1767     if (!result) return;
1768
1769     result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1770     ok(result, "%08x\n", GetLastError());
1771     if (!result) return;
1772
1773     /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about 
1774      * the OID at all. */
1775     /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1776     ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1777     if (result) return;*/
1778
1779     CryptDestroyHash(hHash);
1780
1781     result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1782     ok(result, "%08x\n", GetLastError());
1783     if (!result) return;
1784
1785     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1786     ok(result, "%08x\n", GetLastError());
1787     if (!result) return;
1788
1789     result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1790     ok(result, "%08x\n", GetLastError());
1791     if (!result) return;
1792
1793     result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1794     ok(result, "%08x\n", GetLastError());
1795     if (!result) return;
1796
1797     CryptDestroyHash(hHash);
1798
1799     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1800     ok(result, "%08x\n", GetLastError());
1801     if (!result) return;
1802
1803     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1804     ok(result, "%08x\n", GetLastError());
1805     if (!result) return;
1806
1807     result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1808     ok(result, "%08x\n", GetLastError());
1809     if (!result) return;
1810
1811     result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1812     ok(result, "%08x\n", GetLastError());
1813     if (!result) return;
1814
1815     CryptDestroyHash(hHash);
1816
1817     result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1818     ok(result, "%08x\n", GetLastError());
1819     if (!result) return;
1820
1821     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1822     ok(result, "%08x\n", GetLastError());
1823     if (!result) return;
1824
1825     result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1826     ok(result, "%08x\n", GetLastError());
1827     if (!result) return;
1828
1829     result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1830     ok(result, "%08x\n", GetLastError());
1831     if (!result) return;
1832
1833     CryptDestroyHash(hHash);
1834     CryptDestroyKey(hPubSignKey);
1835 }
1836
1837 static void test_rsa_encrypt(void)
1838 {
1839     HCRYPTKEY hRSAKey;
1840     BYTE abData[2048] = "Wine rocks!";
1841     BOOL result;
1842     DWORD dwVal, dwLen;
1843
1844     /* It is allowed to use the key exchange key for encryption/decryption */
1845     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1846     ok (result, "%08x\n", GetLastError());
1847     if (!result) return;
1848
1849     dwLen = 12;
1850     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1851     ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1852     ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1853     dwLen = 12;
1854     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1855     ok (result, "%08x\n", GetLastError());
1856     if (!result) return;
1857
1858     result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1859     ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1860     
1861     dwVal = 0xdeadbeef;
1862     dwLen = sizeof(DWORD);
1863     result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1864     ok(result, "%08x\n", GetLastError());
1865     ok(dwVal ==
1866         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1867         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1868         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1869         " got %08x\n", dwVal);
1870
1871     /* An RSA key doesn't support salt */
1872     result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
1873     ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == NTE_NOT_FOUND /* Win7 */),
1874        "expected NTE_BAD_KEY or NTE_NOT_FOUND, got %08x\n", GetLastError());
1875
1876     /* The key exchange key's public key may be exported.. */
1877     result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1878     ok(result, "%08x\n", GetLastError());
1879     /* but its private key may not be. */
1880     SetLastError(0xdeadbeef);
1881     result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1882     ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1883         broken(result), /* Win9x/NT4 */
1884         "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1885     /* Setting the permissions of the key exchange key isn't allowed, either. */
1886     dwVal |= CRYPT_EXPORT;
1887     SetLastError(0xdeadbeef);
1888     result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1889     ok(!result &&
1890         (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1891         "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1892
1893     CryptDestroyKey(hRSAKey);
1894
1895     /* It is not allowed to use the signature key for encryption/decryption */
1896     result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1897     ok (result, "%08x\n", GetLastError());
1898     if (!result) return;
1899
1900     dwVal = 0xdeadbeef;
1901     dwLen = sizeof(DWORD);
1902     result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1903     ok(result, "%08x\n", GetLastError());
1904     ok(dwVal ==
1905         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1906         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1907         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1908         " got %08x\n", dwVal);
1909
1910     /* The signature key's public key may also be exported.. */
1911     result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
1912     ok(result, "%08x\n", GetLastError());
1913     /* but its private key may not be. */
1914     SetLastError(0xdeadbeef);
1915     result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
1916     ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
1917         broken(result), /* Win9x/NT4 */
1918         "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
1919     /* Setting the permissions of the signature key isn't allowed, either. */
1920     dwVal |= CRYPT_EXPORT;
1921     SetLastError(0xdeadbeef);
1922     result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
1923     ok(!result &&
1924         (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
1925         "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
1926
1927     dwLen = 12;
1928     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1929     ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1930
1931     CryptDestroyKey(hRSAKey);
1932 }
1933
1934 static void test_import_export(void)
1935 {
1936     DWORD dwLen, dwDataLen, dwVal;
1937     HCRYPTKEY hPublicKey, hPrivKey;
1938     BOOL result;
1939     ALG_ID algID;
1940     BYTE emptyKey[2048], *exported_key;
1941     static BYTE abPlainPublicKey[84] = {
1942         0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1943         0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1944         0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1945         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1946         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1947         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1948         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1949         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1950         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1951         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1952         0x11, 0x11, 0x11, 0x11
1953     };
1954     static BYTE priv_key_with_high_bit[] = {
1955         0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1956         0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1957         0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
1958         0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
1959         0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
1960         0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
1961         0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
1962         0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
1963         0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
1964         0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
1965         0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
1966         0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
1967         0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
1968         0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
1969         0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
1970         0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
1971         0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
1972         0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
1973         0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
1974         0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
1975         0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
1976         0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
1977         0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
1978         0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
1979         0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
1980         0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
1981         0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
1982         0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
1983         0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
1984         0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
1985         0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
1986         0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
1987         0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
1988         0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
1989         0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
1990         0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
1991         0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
1992         0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
1993         0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
1994         0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
1995         0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
1996         0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
1997         0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
1998         0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
1999         0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2000         0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2001         0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2002         0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2003         0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2004         0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2005         0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2006         0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2007         0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2008         0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2009         0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2010         0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2011         0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2012         0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2013         0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2014         0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2015         0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2016         0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2017         0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2018         0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2019         0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2020         0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2021         0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2022         0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2023         0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2024         0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2025         0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2026         0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2027         0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2028         0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2029         0xb6, 0x5f, 0x01, 0x5e
2030     };
2031     static const BYTE expected_exported_priv_key[] = {
2032         0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2033         0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
2034         0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
2035         0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
2036         0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
2037         0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
2038         0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
2039         0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
2040         0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
2041         0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
2042         0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
2043         0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2044         0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2045         0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2046         0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2047         0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2048         0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2049         0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2050         0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2051         0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2052         0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2053         0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2054         0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2055         0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2056         0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2057         0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2058         0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2059         0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2060         0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2061         0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2062         0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2063         0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2064         0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2065         0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2066         0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2067         0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2068         0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2069         0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2070         0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2071         0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2072         0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2073         0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2074         0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2075         0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2076         0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2077         0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2078         0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2079         0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2080         0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2081         0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2082         0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2083         0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2084         0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2085         0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2086         0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2087         0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2088         0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2089         0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2090         0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2091         0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2092         0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2093         0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2094         0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2095         0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2096         0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2097         0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2098         0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2099         0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2100         0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2101         0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2102         0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2103         0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2104         0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2105         0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2106         0xb6, 0x5f, 0x01, 0x5e
2107     };
2108
2109     dwLen=84;
2110     result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
2111     ok(result, "failed to import the public key\n");
2112
2113     dwDataLen=sizeof(algID);
2114     result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
2115     ok(result, "failed to get the KP_ALGID from the imported public key\n");
2116     ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
2117         
2118     dwVal = 0xdeadbeef;
2119     dwDataLen = sizeof(DWORD);
2120     result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
2121     ok(result, "%08x\n", GetLastError());
2122     ok(dwVal ==
2123         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2124         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2125         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2126         " got %08x\n", dwVal);
2127     result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
2128     ok(result, "failed to export the fresh imported public key\n");
2129     ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
2130     ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
2131
2132     CryptDestroyKey(hPublicKey);
2133
2134     result = CryptImportKey(hProv, priv_key_with_high_bit,
2135         sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
2136     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2137
2138     result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
2139     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2140     exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2141     result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
2142         &dwDataLen);
2143     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2144
2145     ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
2146         dwDataLen);
2147     ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
2148         "unexpected value\n");
2149
2150     HeapFree(GetProcessHeap(), 0, exported_key);
2151
2152     CryptDestroyKey(hPrivKey);
2153 }
2154
2155 static void test_import_hmac(void)
2156 {
2157     /* Test cases from RFC 2202, section 3 */
2158     static const struct rfc2202_test_case {
2159         const char *key;
2160         DWORD key_len;
2161         const char *data;
2162         const DWORD data_len;
2163         const char *digest;
2164     } cases[] = {
2165         { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
2166           "\x0b\x0b\x0b\x0b", 20,
2167           "Hi There", 8,
2168           "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e"
2169           "\xf1\x46\xbe\x00" },
2170         { "Jefe", 4,
2171           "what do ya want for nothing?", 28,
2172           "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c"
2173           "\x25\x9a\x7c\x79" },
2174         { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2175           "\xaa\xaa\xaa\xaa", 20,
2176           "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2177           "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2178           "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2179           "\xdd\xdd", 50,
2180           "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f"
2181           "\x63\xf1\x75\xd3" },
2182         { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
2183           "\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25,
2184           "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2185           "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2186           "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2187           "\xcd\xcd", 50,
2188           "\x4c\x90\x07\xF4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c"
2189           "\x2d\x72\x35\xda" },
2190         { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
2191           "\x0c\x0c\x0c\x0c", 20,
2192           "Test With Truncation", 20,
2193           "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32"
2194           "\x4a\x9a\x5a\x04" },
2195         { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2196           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2197           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2198           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2199           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2200           80,
2201           "Test Using Larger Than Block-Size Key - Hash Key First", 54,
2202           "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55"
2203           "\xed\x40\x21\x12" },
2204         { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2205           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2206           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2207           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2208           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2209           80,
2210           "Test Using Larger Than Block-Size Key and Larger "
2211           "Than One Block-Size Data", 73,
2212           "\xe8\xe9\x9D\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08"
2213           "\xbb\xff\x1a\x91" }
2214     };
2215     DWORD i;
2216
2217     for (i = 0; i < sizeof(cases) / sizeof(cases[0]); i++)
2218     {
2219         const struct rfc2202_test_case *test_case = &cases[i];
2220         DWORD size = sizeof(BLOBHEADER) + sizeof(DWORD) + test_case->key_len;
2221         BYTE *blob = HeapAlloc(GetProcessHeap(), 0, size);
2222
2223         if (blob)
2224         {
2225             BLOBHEADER *header = (BLOBHEADER *)blob;
2226             DWORD *key_len = (DWORD *)(header + 1);
2227             BYTE *key_bytes = (BYTE *)(key_len + 1);
2228             BOOL result;
2229             HCRYPTKEY key;
2230
2231             header->bType = PLAINTEXTKEYBLOB;
2232             header->bVersion = CUR_BLOB_VERSION;
2233             header->reserved = 0;
2234             header->aiKeyAlg = CALG_RC2;
2235             *key_len = test_case->key_len;
2236             memcpy(key_bytes, test_case->key, *key_len);
2237             result = CryptImportKey(hProv, blob, size, 0, CRYPT_IPSEC_HMAC_KEY, &key);
2238             todo_wine
2239             ok(result || broken(GetLastError() == NTE_BAD_FLAGS /* Win2k */), "CryptImportKey failed on test case %d: %08x\n", i, GetLastError());
2240             if (result)
2241             {
2242                 HCRYPTHASH hash;
2243                 HMAC_INFO hmac_info = { CALG_SHA1, 0 };
2244                 BYTE digest[20];
2245                 DWORD digest_size;
2246
2247                 result = CryptCreateHash(hProv, CALG_HMAC, key, 0, &hash);
2248                 ok(result, "CryptCreateHash failed on test case %d: %08x\n", i, GetLastError());
2249                 result = CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&hmac_info, 0);
2250                 ok(result, "CryptSetHashParam failed on test case %d: %08x\n", i, GetLastError());
2251                 result = CryptHashData(hash, (const BYTE *)test_case->data, test_case->data_len, 0);
2252                 ok(result, "CryptHashData failed on test case %d: %08x\n", i, GetLastError());
2253                 digest_size = sizeof(digest);
2254                 result = CryptGetHashParam(hash, HP_HASHVAL, digest, &digest_size, 0);
2255                 ok(result, "CryptGetHashParam failed on test case %d: %08x\n", i, GetLastError());
2256                 ok(!memcmp(digest, test_case->digest, sizeof(digest)), "Unexpected valued on test case %d\n", i);
2257                 CryptDestroyHash(hash);
2258                 CryptDestroyKey(key);
2259             }
2260             HeapFree(GetProcessHeap(), 0, blob);
2261         }
2262     }
2263 }
2264         
2265 static void test_schannel_provider(void)
2266 {
2267     HCRYPTPROV hProv;
2268     HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
2269     HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
2270     BOOL result;
2271     DWORD dwLen;
2272     SCHANNEL_ALG saSChannelAlg;
2273     CRYPT_DATA_BLOB data_blob;
2274     HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
2275     BYTE abTLS1Master[140] = {
2276         0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00, 
2277         0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68, 
2278         0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97, 
2279         0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53, 
2280         0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24, 
2281         0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3, 
2282         0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8, 
2283         0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d, 
2284         0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e, 
2285         0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e, 
2286         0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40, 
2287         0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b, 
2288         0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb, 
2289         0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6, 
2290         0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac, 
2291         0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41, 
2292         0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4, 
2293         0xd3, 0x1e, 0x82, 0xb3
2294     };
2295     BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2296     BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2297     BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2298     BYTE abClientFinished[16] = "client finished";
2299     BYTE abData[16] = "Wine rocks!";
2300     BYTE abMD5Hash[16];
2301     static const BYTE abEncryptedData[16] = {
2302         0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2303         0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d    
2304     };
2305     static const BYTE abPRF[16] = {
2306         0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2307         0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2308     };
2309     static const BYTE abMD5[16] = {
2310         0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2311         0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2312     };
2313     
2314     result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
2315     if (!result)
2316     {
2317         win_skip("no PROV_RSA_SCHANNEL support\n");
2318         return;
2319     }
2320     ok (result, "%08x\n", GetLastError());
2321     if (result)
2322         CryptReleaseContext(hProv, 0);
2323
2324     result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
2325     ok (result, "%08x\n", GetLastError());
2326     if (!result) return;
2327     
2328     /* To get deterministic results, we import the TLS1 master secret (which
2329      * is typically generated from a random generator). Therefore, we need
2330      * an RSA key. */
2331     dwLen = (DWORD)sizeof(abPlainPrivateKey);
2332     result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
2333     ok (result, "%08x\n", GetLastError());
2334     if (!result) return;
2335
2336     dwLen = (DWORD)sizeof(abTLS1Master);
2337     result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
2338     ok (result, "%08x\n", GetLastError());
2339     if (!result) return;    
2340    
2341     /* Setting the TLS1 client and server random parameters, as well as the 
2342      * MAC and encryption algorithm parameters. */
2343     data_blob.cbData = 33;
2344     data_blob.pbData = abClientSecret;
2345     result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
2346     ok (result, "%08x\n", GetLastError());
2347     if (!result) return;
2348
2349     data_blob.cbData = 33;
2350     data_blob.pbData = abServerSecret;
2351     result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
2352     ok (result, "%08x\n", GetLastError());
2353     if (!result) return;
2354     
2355     saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
2356     saSChannelAlg.Algid = CALG_DES;
2357     saSChannelAlg.cBits = 64;
2358     saSChannelAlg.dwFlags = 0;
2359     saSChannelAlg.dwReserved = 0;
2360     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2361     ok (result, "%08x\n", GetLastError());
2362     if (!result) return;
2363
2364     saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
2365     saSChannelAlg.Algid = CALG_MD5;
2366     saSChannelAlg.cBits = 128;
2367     saSChannelAlg.dwFlags = 0;
2368     saSChannelAlg.dwReserved = 0;
2369     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2370     ok (result, "%08x\n", GetLastError());
2371     if (!result) return;
2372
2373     /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2374      * (Keys can only be derived from hashes, not from other keys.) */
2375     result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2376     ok (result, "%08x\n", GetLastError());
2377     if (!result) return;
2378
2379     /* Deriving the server write encryption key from the master hash */
2380     result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2381     ok (result, "%08x\n", GetLastError());
2382     if (!result) return;
2383
2384     /* Encrypting some data with the server write encryption key and checking the result. */
2385     dwLen = 12;
2386     result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
2387     ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
2388
2389     /* Second test case: Test the TLS1 pseudo random number function. */
2390     result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
2391     ok (result, "%08x\n", GetLastError());
2392     if (!result) return;
2393
2394     /* Set the label and seed parameters for the random number function */
2395     data_blob.cbData = 36;
2396     data_blob.pbData = abHashedHandshakes;
2397     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
2398     ok (result, "%08x\n", GetLastError());
2399     if (!result) return;
2400
2401     data_blob.cbData = 15;
2402     data_blob.pbData = abClientFinished;
2403     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
2404     ok (result, "%08x\n", GetLastError());
2405     if (!result) return;
2406
2407     /* Generate some pseudo random bytes and check if they are correct. */
2408     dwLen = (DWORD)sizeof(abData);
2409     result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2410     ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)), 
2411         "%08x\n", GetLastError());
2412
2413     /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
2414      * Hash some data with the HMAC. Compare results. */
2415     result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
2416     ok (result, "%08x\n", GetLastError());
2417     if (!result) return;
2418     
2419     result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
2420     ok (result, "%08x\n", GetLastError());
2421     if (!result) return;
2422
2423     result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
2424     ok (result, "%08x\n", GetLastError());
2425     if (!result) return;
2426
2427     result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
2428     ok (result, "%08x\n", GetLastError());
2429     if (!result) return;
2430
2431     dwLen = (DWORD)sizeof(abMD5Hash);
2432     result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
2433     ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
2434
2435     CryptDestroyHash(hHMAC);
2436     CryptDestroyHash(hTLS1PRF);
2437     CryptDestroyHash(hMasterHash);
2438     CryptDestroyKey(hServerWriteMACKey);
2439     CryptDestroyKey(hServerWriteKey);
2440     CryptDestroyKey(hRSAKey);
2441     CryptDestroyKey(hMasterSecret);
2442     CryptReleaseContext(hProv, 0);
2443     CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2444 }
2445
2446 /* Test that a key can be used to encrypt data and exported, and that, when
2447  * the exported key is imported again, can be used to decrypt the original
2448  * data again.
2449  */
2450 static void test_rsa_round_trip(void)
2451 {
2452     static const char test_string[] = "Well this is a fine how-do-you-do.";
2453     HCRYPTPROV prov;
2454     HCRYPTKEY signKey, keyExchangeKey;
2455     BOOL result;
2456     BYTE data[256], *exportedKey;
2457     DWORD dataLen, keyLen;
2458
2459     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2460      CRYPT_DELETEKEYSET);
2461
2462     /* Generate a new key... */
2463     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2464      CRYPT_NEWKEYSET);
2465     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2466     result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
2467     ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2468     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
2469     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2470     /* encrypt some data with it... */
2471     memcpy(data, test_string, strlen(test_string) + 1);
2472     dataLen = strlen(test_string) + 1;
2473     result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
2474                           sizeof(data));
2475     ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
2476        broken(GetLastError() == NTE_PERM /* NT4 */),
2477        "CryptEncrypt failed: %08x\n", GetLastError());
2478     /* export the key... */
2479     result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
2480                             &keyLen);
2481     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2482     exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
2483     result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
2484                             &keyLen);
2485     /* destroy the key... */
2486     CryptDestroyKey(keyExchangeKey);
2487     CryptDestroyKey(signKey);
2488     /* import the key again... */
2489     result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
2490     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2491     HeapFree(GetProcessHeap(), 0, exportedKey);
2492     /* and decrypt the data encrypted with the original key with the imported
2493      * key.
2494      */
2495     result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
2496     ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
2497        broken(GetLastError() == NTE_PERM /* NT4 */),
2498        "CryptDecrypt failed: %08x\n", GetLastError());
2499     if (result)
2500     {
2501         ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
2502         ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
2503     }
2504     CryptDestroyKey(keyExchangeKey);
2505     CryptReleaseContext(prov, 0);
2506
2507     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2508      CRYPT_DELETEKEYSET);
2509 }
2510
2511 static void test_enum_container(void)
2512 {
2513     BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
2514     DWORD dwBufferLen;
2515     BOOL result, fFound = FALSE;
2516
2517     /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
2518      * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
2519     SetLastError(0xdeadbeef);
2520     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
2521     ok (result, "%08x\n", GetLastError());
2522     ok (dwBufferLen == MAX_PATH + 1 ||
2523         broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
2524         "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
2525
2526     /* If the result fits into abContainerName dwBufferLen is left untouched */
2527     dwBufferLen = (DWORD)sizeof(abContainerName);
2528     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
2529     ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
2530     
2531     /* We only check, if the currently open 'winetest' container is among the enumerated. */
2532     do {
2533         if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
2534         dwBufferLen = (DWORD)sizeof(abContainerName);
2535     } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
2536         
2537     ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
2538 }
2539
2540 static BYTE signBlob[] = {
2541 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
2542 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
2543 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
2544 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
2545 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
2546 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
2547 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
2548 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
2549 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
2550 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
2551 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
2552 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
2553 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
2554 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
2555 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
2556 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
2557 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
2558 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
2559 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
2560 0xb6,0x85,0x86,0x07 };
2561
2562 static void test_null_provider(void)
2563 {
2564     HCRYPTPROV prov;
2565     HCRYPTKEY key;
2566     BOOL result;
2567     DWORD keySpec, dataLen,dwParam;
2568     char szName[MAX_PATH];
2569
2570     result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
2571     ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
2572      "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
2573     result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
2574     ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2575      "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2576     result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
2577      CRYPT_DELETEKEYSET);
2578     ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
2579      "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
2580     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2581      CRYPT_DELETEKEYSET);
2582     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2583      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2584     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2585     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2586      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2587
2588     /* Delete the default container. */
2589     CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2590     /* Once you've deleted the default container you can't open it as if it
2591      * already exists.
2592      */
2593     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
2594     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2595      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2596     /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
2597     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2598      CRYPT_VERIFYCONTEXT);
2599     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2600     if (!result) return;
2601     dataLen = sizeof(keySpec);
2602     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2603     if (result)
2604         ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2605          "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2606     /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
2607      * supported, you can't get the keys from this container.
2608      */
2609     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2610     ok(!result && GetLastError() == NTE_NO_KEY,
2611      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2612     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2613     ok(!result && GetLastError() == NTE_NO_KEY,
2614      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2615     result = CryptReleaseContext(prov, 0);
2616     ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
2617     /* You can create a new default container. */
2618     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
2619      CRYPT_NEWKEYSET);
2620     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2621     /* But you still can't get the keys (until one's been generated.) */
2622     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2623     ok(!result && GetLastError() == NTE_NO_KEY,
2624      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2625     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2626     ok(!result && GetLastError() == NTE_NO_KEY,
2627      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2628     CryptReleaseContext(prov, 0);
2629     CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2630
2631     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2632      CRYPT_DELETEKEYSET);
2633     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
2634     ok(!result && GetLastError() == NTE_BAD_KEYSET,
2635      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2636     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2637      CRYPT_VERIFYCONTEXT);
2638     ok(!result && GetLastError() == NTE_BAD_FLAGS,
2639      "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2640     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2641      CRYPT_NEWKEYSET);
2642     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2643     if (!result) return;
2644     /* Test provider parameters getter */
2645     dataLen = sizeof(dwParam);
2646     result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
2647     ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
2648         "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
2649     dataLen = sizeof(dwParam);
2650     result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
2651     ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
2652         "Expected 0, got 0x%08X\n",dwParam);
2653     dataLen = sizeof(dwParam);
2654     result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
2655     ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
2656         "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
2657     dataLen = sizeof(keySpec);
2658     SetLastError(0xdeadbeef);
2659     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
2660     if (!result && GetLastError() == NTE_BAD_TYPE)
2661         skip("PP_KEYSPEC is not supported (win9x or NT)\n");
2662     else
2663         ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
2664             "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
2665     /* PP_CONTAINER parameter */
2666     dataLen = sizeof(szName);
2667     result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2668     ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
2669         "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
2670         (result)? "TRUE":"FALSE",GetLastError(),dataLen);
2671     /* PP_UNIQUE_CONTAINER parameter */
2672     dataLen = sizeof(szName);
2673     SetLastError(0xdeadbeef);
2674     result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
2675     if (!result && GetLastError() == NTE_BAD_TYPE)
2676     {
2677         skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
2678     }
2679     else
2680     {
2681         char container[MAX_PATH];
2682
2683         ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
2684         uniquecontainer(container);
2685         todo_wine
2686         {
2687             ok(dataLen == strlen(container)+1 ||
2688                broken(dataLen == strlen(szContainer)+1) /* WinME */,
2689                "Expected a param length of 70, got %d\n", dataLen);
2690             ok(!strcmp(container, szName) ||
2691                broken(!strcmp(szName, szContainer)) /* WinME */,
2692                "Wrong container name : %s\n", szName);
2693         }
2694     }
2695     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2696     ok(!result && GetLastError() == NTE_NO_KEY,
2697      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2698     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2699     ok(!result && GetLastError() == NTE_NO_KEY,
2700      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2701
2702     /* Importing a key exchange blob.. */
2703     result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
2704      0, 0, &key);
2705     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2706     CryptDestroyKey(key);
2707     /* allows access to the key exchange key.. */
2708     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2709     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2710     CryptDestroyKey(key);
2711     /* but not to the private key. */
2712     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2713     ok(!result && GetLastError() == NTE_NO_KEY,
2714      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2715     CryptReleaseContext(prov, 0);
2716     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2717      CRYPT_DELETEKEYSET);
2718
2719     /* Whereas importing a sign blob.. */
2720     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2721      CRYPT_NEWKEYSET);
2722     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2723     if (!result) return;
2724     result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
2725     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2726     CryptDestroyKey(key);
2727     /* doesn't allow access to the key exchange key.. */
2728     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2729     ok(!result && GetLastError() == NTE_NO_KEY,
2730      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2731     /* but does to the private key. */
2732     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2733     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2734     CryptDestroyKey(key);
2735     CryptReleaseContext(prov, 0);
2736
2737     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2738      CRYPT_DELETEKEYSET);
2739
2740     /* Test for being able to get a key generated with CALG_RSA_SIGN. */
2741     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2742      CRYPT_NEWKEYSET);
2743     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2744     result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
2745     ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
2746     CryptDestroyKey(key);
2747     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2748     ok(!result, "expected CryptGetUserKey to fail\n");
2749     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2750     ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
2751     CryptDestroyKey(key);
2752     CryptReleaseContext(prov, 0);
2753
2754     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2755      CRYPT_DELETEKEYSET);
2756
2757     /* Test for being able to get a key generated with CALG_RSA_KEYX. */
2758     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2759      CRYPT_NEWKEYSET);
2760     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2761     result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
2762     ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
2763     CryptDestroyKey(key);
2764     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2765     ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
2766     CryptDestroyKey(key);
2767     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
2768     ok(!result, "expected CryptGetUserKey to fail\n");
2769     CryptReleaseContext(prov, 0);
2770
2771     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2772      CRYPT_DELETEKEYSET);
2773
2774     /* test for the bug in accessing the user key in a container
2775      */
2776     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2777      CRYPT_NEWKEYSET);
2778     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
2779     result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
2780     ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
2781     CryptDestroyKey(key);
2782     CryptReleaseContext(prov,0);
2783     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
2784     ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
2785     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
2786     ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
2787     CryptDestroyKey(key);
2788     CryptReleaseContext(prov, 0);
2789
2790     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2791      CRYPT_DELETEKEYSET);
2792
2793     /* test the machine key set */
2794     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2795      CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2796     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2797      CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
2798     ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2799     CryptReleaseContext(prov, 0);
2800     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2801      CRYPT_MACHINE_KEYSET);
2802     ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
2803     CryptReleaseContext(prov,0);
2804     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2805        CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
2806     ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
2807                 GetLastError());
2808     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
2809      CRYPT_MACHINE_KEYSET);
2810     ok(!result && GetLastError() == NTE_BAD_KEYSET ,
2811         "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
2812
2813 }
2814
2815 static void test_key_permissions(void)
2816 {
2817     HCRYPTKEY hKey1, hKey2;
2818     DWORD dwVal, dwLen;
2819     BOOL result;
2820
2821     /* Create keys that are exportable */
2822     if (!init_base_environment(CRYPT_EXPORTABLE))
2823         return;
2824
2825     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
2826     ok (result, "%08x\n", GetLastError());
2827     if (!result) return;
2828
2829     dwVal = 0xdeadbeef;
2830     dwLen = sizeof(DWORD);
2831     result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2832     ok(result, "%08x\n", GetLastError());
2833     ok(dwVal ==
2834         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2835         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2836         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2837         " got %08x\n", dwVal);
2838
2839     /* The key exchange key's public key may be exported.. */
2840     result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2841     ok(result, "%08x\n", GetLastError());
2842     /* and its private key may be too. */
2843     result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2844     ok(result, "%08x\n", GetLastError());
2845     /* Turning off the key's export permissions is "allowed".. */
2846     dwVal &= ~CRYPT_EXPORT;
2847     result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2848     ok(result ||
2849         broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
2850         broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
2851         "%08x\n", GetLastError());
2852     /* but it has no effect. */
2853     dwVal = 0xdeadbeef;
2854     dwLen = sizeof(DWORD);
2855     result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2856     ok(result, "%08x\n", GetLastError());
2857     ok(dwVal ==
2858         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2859         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2860         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2861         " got %08x\n", dwVal);
2862     /* Thus, changing the export flag of the key doesn't affect whether the key
2863      * may be exported.
2864      */
2865     result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2866     ok(result, "%08x\n", GetLastError());
2867
2868     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
2869     ok (result, "%08x\n", GetLastError());
2870
2871     /* A subsequent get of the same key, into a different handle, also doesn't
2872      * show that the permissions have been changed.
2873      */
2874     dwVal = 0xdeadbeef;
2875     dwLen = sizeof(DWORD);
2876     result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2877     ok(result, "%08x\n", GetLastError());
2878     ok(dwVal ==
2879         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2880         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2881         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2882         " got %08x\n", dwVal);
2883
2884     CryptDestroyKey(hKey2);
2885     CryptDestroyKey(hKey1);
2886
2887     clean_up_base_environment();
2888 }
2889
2890 static void test_key_initialization(void)
2891 {
2892     DWORD dwLen;
2893     HCRYPTPROV prov1, prov2;
2894     HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
2895     BOOL result;
2896     static BYTE abSessionKey[148] = {
2897         0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2898         0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2899         0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2900         0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2901         0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2902         0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2903         0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2904         0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2905         0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2906         0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2907         0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2908         0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2909         0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2910         0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2911         0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2912         0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2913         0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2914         0x04, 0x8c, 0x49, 0x92
2915     };
2916
2917     /* Like init_base_environment, but doesn't generate new keys, as they'll
2918      * be imported instead.
2919      */
2920     if (!CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
2921     {
2922         result = CryptAcquireContext(&prov1, szContainer, szProvider, PROV_RSA_FULL,
2923                                      CRYPT_NEWKEYSET);
2924         ok(result, "%08x\n", GetLastError());
2925     }
2926     dwLen = (DWORD)sizeof(abPlainPrivateKey);
2927     result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2928
2929     dwLen = (DWORD)sizeof(abSessionKey);
2930     result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2931     ok(result, "%08x\n", GetLastError());
2932
2933     /* Once the key has been imported, subsequently acquiring a context with
2934      * the same name will allow retrieving the key.
2935      */
2936     result = CryptAcquireContext(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
2937     ok(result, "%08x\n", GetLastError());
2938     result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
2939     ok(result, "%08x\n", GetLastError());
2940     if (result) CryptDestroyKey(hKey);
2941     CryptReleaseContext(prov2, 0);
2942
2943     CryptDestroyKey(hSessionKey);
2944     CryptDestroyKey(hKeyExchangeKey);
2945     CryptReleaseContext(prov1, 0);
2946     CryptAcquireContext(&prov1, szContainer, NULL, PROV_RSA_FULL,
2947      CRYPT_DELETEKEYSET);
2948 }
2949
2950 START_TEST(rsaenh)
2951 {
2952     if (!init_base_environment(0))
2953         return;
2954     test_prov();
2955     test_gen_random();
2956     test_hashes();
2957     test_rc4();
2958     test_rc2();
2959     test_des();
2960     test_3des112();
2961     test_3des();
2962     test_hmac();
2963     test_mac();
2964     test_block_cipher_modes();
2965     test_import_private();
2966     test_verify_signature();
2967     test_rsa_encrypt();
2968     test_import_export();
2969     test_import_hmac();
2970     test_enum_container();
2971     clean_up_base_environment();
2972     test_key_permissions();
2973     test_key_initialization();
2974     test_schannel_provider();
2975     test_null_provider();
2976     test_rsa_round_trip();
2977     if (!init_aes_environment())
2978         return;
2979     test_aes(128);
2980     test_aes(192);
2981     test_aes(256);
2982     test_sha2();
2983     clean_up_aes_environment();
2984 }