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 *szProviders[] = {MS_ENHANCED_PROV_A, MS_DEF_PROV_A, MS_STRONG_PROV_A};
34 static int iProv;
35 static const char szContainer[] = "winetest";
36 static const char *szProvider;
37 
38 #define ENHANCED_PROV (iProv == 0)
39 #define BASE_PROV (iProv == 1)
40 #define STRONG_PROV (iProv == 2)
41 
42 typedef struct _ctdatatype {
43        unsigned char origstr[32];
44        unsigned char decstr[32];
45        int strlen;
46        int enclen;
47        int buflen;
48 } cryptdata;
49 
50 static const cryptdata cTestData[4] = {
51        {"abcdefghijkl",
52        {'a','b','c','d','e','f','g','h',0x2,0x2,'k','l',0},
53        12,8,16},
54        {"abcdefghij",
55        {'a','b','c','d','e','f','g','h',0x2,0x2,0},
56        10,8,16},
57        {"abcdefgh",
58        {'a','b','c','d','e','f','g','h',0},
59        8,8,16},
60        {"abcdefghijkl",
61        {'a','b','c','d','e','f','g','h','i','j','k','l',0},
62        12,12,16}
63 };
64 
65 static int win2k, nt4;
66 
67 /*
68  * 1. Take the MD5 Hash of the container name (with an extra null byte)
69  * 2. Turn the hash into a 4 DWORD hex value
70  * 3. Append a '_'
71  * 4. Add the MachineGuid
72  *
73  */
74 static void uniquecontainer(char *unique)
75 {
76     /* MD5 hash of "winetest\0" in 4 DWORD hex */
77     static const char szContainer_md5[] = "9d20fd8d05ed2b8455d125d0bf6d6a70";
78     static const char szCryptography[] = "Software\\Microsoft\\Cryptography";
79     static const char szMachineGuid[] = "MachineGuid";
80     HKEY hkey;
81     char guid[MAX_PATH];
82     DWORD size = MAX_PATH;
83     HRESULT ret;
84 
85     /* Get the MachineGUID */
86     ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, szCryptography, 0, KEY_READ | KEY_WOW64_64KEY, &hkey);
87     if (ret == ERROR_ACCESS_DENIED)
88     {
89         /* Windows 2000 can't handle KEY_WOW64_64KEY */
90         RegOpenKeyA(HKEY_LOCAL_MACHINE, szCryptography, &hkey);
91         win2k++;
92     }
93     RegQueryValueExA(hkey, szMachineGuid, NULL, NULL, (LPBYTE)guid, &size);
94     RegCloseKey(hkey);
95 
96     if (!unique) return;
97     lstrcpyA(unique, szContainer_md5);
98     lstrcatA(unique, "_");
99     lstrcatA(unique, guid);
100 }
101 
102 static void printBytes(const char *heading, const BYTE *pb, size_t cb)
103 {
104     size_t i;
105     printf("%s: ",heading);
106     for(i=0;i<cb;i++)
107         printf("0x%02x,",pb[i]);
108     putchar('\n');
109 }
110 
111 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
112 
113 static void trace_hex(BYTE *pbData, DWORD dwLen) {
114     char szTemp[256];
115     DWORD i, j;
116 
117     for (i = 0; i < dwLen-7; i+=8) {
118         trace("0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
119               pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5],
120               pbData[i+6], pbData[i+7]);
121     }
122     for (j=0; i<dwLen; j++,i++) {
123         sprintf(szTemp+6*j, "0x%02x, ", pbData[i]);
124     }
125     if (j)
126         trace("%s\n", szTemp);
127 }
128 
129 static BOOL init_base_environment(const char *provider, DWORD dwKeyFlags)
130 {
131     HCRYPTKEY hKey;
132     BOOL result;
133 
134     if (provider) szProvider = provider;
135 
136     pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
137 
138     hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
139 
140     result = CryptAcquireContextA(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
141     ok(!result && (GetLastError()==NTE_BAD_FLAGS ||
142        broken(GetLastError() == NTE_KEYSET_NOT_DEF /* Win9x/NT4 */)),
143        "%d, %08x\n", result, GetLastError());
144 
145     if (!CryptAcquireContextA(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
146     {
147         ok(GetLastError()==NTE_BAD_KEYSET ||
148            broken(GetLastError() == NTE_TEMPORARY_PROFILE /* some Win7 setups */) ||
149            broken(GetLastError() == NTE_KEYSET_NOT_DEF /* Win9x/NT4 */),
150            "%08x\n", GetLastError());
151         if (GetLastError()!=NTE_BAD_KEYSET)
152         {
153             win_skip("RSA full provider not available\n");
154             return FALSE;
155         }
156         result = CryptAcquireContextA(&hProv, szContainer, szProvider, PROV_RSA_FULL,
157                                      CRYPT_NEWKEYSET);
158         ok(result, "%08x\n", GetLastError());
159         if (!result)
160         {
161             win_skip("Couldn't create crypto provider\n");
162             return FALSE;
163         }
164         result = CryptGenKey(hProv, AT_KEYEXCHANGE, dwKeyFlags, &hKey);
165         ok(result, "%08x\n", GetLastError());
166         if (result) CryptDestroyKey(hKey);
167         result = CryptGenKey(hProv, AT_SIGNATURE, dwKeyFlags, &hKey);
168         ok(result, "%08x\n", GetLastError());
169         if (result) CryptDestroyKey(hKey);
170     }
171     return TRUE;
172 }
173 
174 static void clean_up_base_environment(void)
175 {
176     BOOL result;
177 
178     SetLastError(0xdeadbeef);
179     result = CryptReleaseContext(hProv, 1);
180     ok(!result || broken(result) /* Win98 */, "Expected failure\n");
181     ok(GetLastError()==NTE_BAD_FLAGS, "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
182 
183     /* Just to prove that Win98 also released the CSP */
184     SetLastError(0xdeadbeef);
185     result = CryptReleaseContext(hProv, 0);
186     ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
187 
188     CryptAcquireContextA(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
189 }
190 
191 static BOOL init_aes_environment(void)
192 {
193     HCRYPTKEY hKey;
194     BOOL result;
195 
196     pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
197 
198     hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
199 
200     /* we are using NULL as provider name for RSA_AES provider as the provider
201      * names are different in Windows XP and Vista. This differs from what
202      * is defined in the SDK on Windows XP.
203      * This provider is available on Windows XP, Windows 2003 and Vista.      */
204 
205     result = CryptAcquireContextA(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
206     if (!result && GetLastError() == NTE_PROV_TYPE_NOT_DEF)
207     {
208         win_skip("RSA_AES provider not supported\n");
209         return FALSE;
210     }
211     ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
212 
213     if (!CryptAcquireContextA(&hProv, szContainer, NULL, PROV_RSA_AES, 0))
214     {
215         ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
216         if (GetLastError()!=NTE_BAD_KEYSET) return FALSE;
217         result = CryptAcquireContextA(&hProv, szContainer, NULL, PROV_RSA_AES,
218                                      CRYPT_NEWKEYSET);
219         ok(result, "%08x\n", GetLastError());
220         if (!result) return FALSE;
221         result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
222         ok(result, "%08x\n", GetLastError());
223         if (result) CryptDestroyKey(hKey);
224         result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
225         ok(result, "%08x\n", GetLastError());
226         if (result) CryptDestroyKey(hKey);
227 
228         /* CALG_AES is not supported, but CALG_AES_128 is */
229         result = CryptGenKey(hProv, CALG_AES, 0, &hKey);
230         ok(!result && GetLastError() == NTE_BAD_ALGID, "%d %08x\n", result, GetLastError());
231         result = CryptGenKey(hProv, CALG_AES, 128 << 16, &hKey);
232         ok(!result && GetLastError() == NTE_BAD_ALGID, "%d %08x\n", result, GetLastError());
233         result = CryptGenKey(hProv, CALG_AES_128, 0, &hKey);
234         ok(result, "%08x\n", GetLastError());
235         if (result) CryptDestroyKey(hKey);
236     }
237     return TRUE;
238 }
239 
240 static void clean_up_aes_environment(void)
241 {
242     BOOL result;
243 
244     result = CryptReleaseContext(hProv, 1);
245     ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
246 
247     CryptAcquireContextA(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_DELETEKEYSET);
248 }
249 
250 static void test_prov(void)
251 {
252     BOOL result;
253     DWORD dwLen, dwInc;
254 
255     dwLen = (DWORD)sizeof(DWORD);
256     SetLastError(0xdeadbeef);
257     result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
258     if (!result && GetLastError() == NTE_BAD_TYPE)
259     {
260         skip("PP_SIG_KEYSIZE_INC is not supported (win9x or NT)\n");
261         nt4++;
262     }
263     else
264         ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
265 
266     dwLen = (DWORD)sizeof(DWORD);
267     SetLastError(0xdeadbeef);
268     result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
269     if (!result && GetLastError() == NTE_BAD_TYPE)
270         skip("PP_KEYX_KEYSIZE_INC is not supported (win9x or NT)\n");
271     else
272         ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
273 }
274 
275 static void test_gen_random(void)
276 {
277     BOOL result;
278     BYTE rnd1[16], rnd2[16];
279 
280     memset(rnd1, 0, sizeof(rnd1));
281     memset(rnd2, 0, sizeof(rnd2));
282 
283     result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
284     if (!result && GetLastError() == NTE_FAIL) {
285         /* rsaenh compiled without OpenSSL */
286         return;
287     }
288 
289     ok(result, "%08x\n", GetLastError());
290 
291     result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
292     ok(result, "%08x\n", GetLastError());
293 
294     ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
295 }
296 
297 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
298 {
299     HCRYPTHASH hHash;
300     BOOL result;
301     unsigned char pbData[2000];
302     int i;
303 
304     *phKey = 0;
305     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
306     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
307     if (!result) {
308         /* rsaenh compiled without OpenSSL */
309         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
310         return FALSE;
311     }
312     ok(result, "%08x\n", GetLastError());
313     result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
314     ok(result, "%08x\n", GetLastError());
315     if (!result) return FALSE;
316     result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
317     ok(result, "%08x\n", GetLastError());
318     if (!result) return FALSE;
319     len = 2000;
320     result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
321     ok(result, "%08x\n", GetLastError());
322     CryptDestroyHash(hHash);
323     return TRUE;
324 }
325 
326 static BYTE abPlainPrivateKey[596] = {
327     0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
328     0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
329     0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
330     0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
331     0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
332     0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
333     0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
334     0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
335     0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
336     0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
337     0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
338     0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
339     0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
340     0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
341     0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
342     0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
343     0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
344     0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
345     0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
346     0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
347     0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
348     0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
349     0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
350     0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
351     0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
352     0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
353     0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
354     0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
355     0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
356     0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
357     0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
358     0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
359     0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
360     0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
361     0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
362     0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
363     0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
364     0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
365     0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
366     0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
367     0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
368     0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
369     0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
370     0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
371     0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
372     0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
373     0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
374     0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
375     0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
376     0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
377     0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
378     0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
379     0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
380     0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
381     0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
382     0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
383     0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
384     0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
385     0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
386     0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
387     0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
388     0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
389     0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
390     0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
391     0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
392     0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
393     0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
394     0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
395     0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
396     0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
397     0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
398     0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
399     0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
400     0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
401     0xf2, 0x5d, 0x58, 0x07
402 };
403 
404 static void test_hashes(void)
405 {
406     static const unsigned char md2hash[16] = {
407         0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
408         0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
409     static const unsigned char md4hash[16] = {
410         0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
411         0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
412     static const unsigned char empty_md5hash[16] = {
413         0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
414         0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
415     static const unsigned char md5hash[16] = {
416         0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
417         0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
418     static const unsigned char sha1hash[20] = {
419         0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
420         0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
421     static const unsigned char signed_ssl3_shamd5_hash[] = {
422         0x4f,0xcc,0x2f,0x33,0x44,0x60,0x76,0x16,0x13,0xc8,0xff,0xd4,0x59,0x19,
423         0xde,0x85,0x44,0x72,0x47,0x98,0x01,0xfb,0x67,0x5c,0x5b,0x35,0x15,0x0f,
424         0x91,0xda,0xc7,0x7c,0xfb,0xe2,0x18,0xef,0xac,0x31,0x40,0x7b,0xa9,0x83,
425         0xdb,0x30,0xcd,0x94,0x4b,0x8e,0x3b,0x6c,0x7a,0x86,0x59,0xf0,0xd1,0xd2,
426         0x5e,0xce,0xd4,0x1b,0x7f,0xed,0x24,0xee,0x53,0x5c,0x15,0x97,0x21,0x7c,
427         0x5c,0xea,0xab,0xf5,0xd6,0x4b,0xb3,0xbb,0x14,0xf5,0x59,0x9e,0x21,0x90,
428         0x21,0x99,0x19,0xad,0xa2,0xa6,0xea,0x61,0xc1,0x41,0xe2,0x70,0x77,0xf7,
429         0x15,0x68,0x96,0x1e,0x5c,0x84,0x97,0xe3,0x5c,0xd2,0xd9,0xfb,0x87,0x6f,
430         0x11,0x21,0x82,0x43,0x76,0x32,0xa4,0x38,0x7b,0x85,0x22,0x30,0x1e,0x55,
431         0x79,0x93 };
432     unsigned char pbData[2048];
433     BOOL result;
434     HCRYPTHASH hHash, hHashClone;
435     HCRYPTPROV prov;
436     BYTE pbHashValue[36];
437     BYTE pbSigValue[128];
438     HCRYPTKEY hKeyExchangeKey;
439     DWORD hashlen, len, error, cryptflags;
440     int i;
441 
442     for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
443 
444     /* MD2 Hashing */
445     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
446     if (!result) {
447         /* rsaenh compiled without OpenSSL */
448         ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
449     } else {
450         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
451         ok(result, "%08x\n", GetLastError());
452 
453         len = sizeof(DWORD);
454         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
455            ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
456 
457         len = 16;
458         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
459         ok(result, "%08x\n", GetLastError());
460 
461         ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
462 
463         result = CryptDestroyHash(hHash);
464         ok(result, "%08x\n", GetLastError());
465     }
466 
467     /* MD4 Hashing */
468     result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
469     ok(result, "%08x\n", GetLastError());
470 
471     result = CryptHashData(hHash, pbData, sizeof(pbData), ~0);
472     ok(!result && GetLastError() == NTE_BAD_FLAGS, "%08x\n", GetLastError());
473 
474     cryptflags = CRYPT_USERDATA;
475     result = CryptHashData(hHash, pbData, sizeof(pbData), cryptflags);
476     if (!result && GetLastError() == NTE_BAD_FLAGS) /* <= NT4 */
477     {
478         cryptflags &= ~CRYPT_USERDATA;
479         ok(broken(1), "Failed to support CRYPT_USERDATA flag\n");
480         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
481     }
482     ok(result, "%08x\n", GetLastError());
483 
484     len = sizeof(DWORD);
485     result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
486     ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
487 
488     len = 16;
489     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
490     ok(result, "%08x\n", GetLastError());
491 
492     ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
493 
494     result = CryptDestroyHash(hHash);
495     ok(result, "%08x\n", GetLastError());
496 
497     /* MD5 Hashing */
498     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
499     ok(result, "%08x\n", GetLastError());
500 
501     len = sizeof(DWORD);
502     result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
503     ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
504 
505     result = CryptHashData(hHash, pbData, sizeof(pbData), ~0);
506     ok(!result && GetLastError() == NTE_BAD_FLAGS, "%08x\n", GetLastError());
507 
508     result = CryptHashData(hHash, pbData, sizeof(pbData), cryptflags);
509     ok(result, "%08x\n", GetLastError());
510 
511     len = 16;
512     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
513     ok(result, "%08x\n", GetLastError());
514 
515     ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
516 
517     result = CryptDestroyHash(hHash);
518     ok(result, "%08x\n", GetLastError());
519 
520     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
521     ok(result, "%08x\n", GetLastError());
522 
523     /* The hash is available even if CryptHashData hasn't been called */
524     len = 16;
525     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
526     ok(result, "%08x\n", GetLastError());
527 
528     ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
529 
530     /* It's also stable:  getting it twice results in the same value */
531     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
532     ok(result, "%08x\n", GetLastError());
533 
534     ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
535 
536     /* Can't add data after the hash been retrieved */
537     SetLastError(0xdeadbeef);
538     result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
539     ok(!result, "Expected failure\n");
540     ok(GetLastError() == NTE_BAD_HASH_STATE ||
541        GetLastError() == NTE_BAD_ALGID, /* Win9x, WinMe, NT4 */
542        "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID, got %08x\n", GetLastError());
543 
544     /* You can still retrieve the hash, its value just hasn't changed */
545     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
546     ok(result, "%08x\n", GetLastError());
547 
548     ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
549 
550     result = CryptDestroyHash(hHash);
551     ok(result, "%08x\n", GetLastError());
552 
553     /* SHA1 Hashing */
554     result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
555     ok(result, "%08x\n", GetLastError());
556 
557     result = CryptHashData(hHash, pbData, 5, cryptflags);
558     ok(result, "%08x\n", GetLastError());
559 
560     if(pCryptDuplicateHash) {
561         result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
562         ok(result, "%08x\n", GetLastError());
563 
564         result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
565         ok(result, "%08x\n", GetLastError());
566 
567         len = sizeof(DWORD);
568         result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
569         ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
570 
571         len = 20;
572         result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
573         ok(result, "%08x\n", GetLastError());
574 
575         ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
576 
577         result = CryptDestroyHash(hHashClone);
578         ok(result, "%08x\n", GetLastError());
579     }
580 
581     result = CryptDestroyHash(hHash);
582     ok(result, "%08x\n", GetLastError());
583 
584     /* The SHA-2 variants aren't supported in the RSA full provider */
585     result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
586     ok(!result && GetLastError() == NTE_BAD_ALGID,
587        "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
588     result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
589     ok(!result && GetLastError() == NTE_BAD_ALGID,
590        "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
591     result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
592     ok(!result && GetLastError() == NTE_BAD_ALGID,
593        "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
594 
595     result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
596     ok(result, "CryptAcquireContextA failed 0x%08x\n", GetLastError());
597 
598     result = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hHash);
599     ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
600 
601     /* release provider before using the hash */
602     result = CryptReleaseContext(prov, 0);
603     ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
604 
605     SetLastError(0xdeadbeef);
606     result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
607     error = GetLastError();
608     ok(!result, "CryptHashData succeeded\n");
609     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
610 
611     SetLastError(0xdeadbeef);
612     result = CryptDestroyHash(hHash);
613     error = GetLastError();
614     ok(!result, "CryptDestroyHash succeeded\n");
615     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
616 
617     if (!pCryptDuplicateHash)
618     {
619         win_skip("CryptDuplicateHash is not available\n");
620         return;
621     }
622 
623     result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
624     ok(result, "CryptAcquireContextA failed 0x%08x\n", GetLastError());
625 
626     result = CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
627     ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
628 
629     result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
630     ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
631 
632     result = pCryptDuplicateHash(hHash, NULL, 0, &hHashClone);
633     ok(result, "CryptDuplicateHash failed 0x%08x\n", GetLastError());
634 
635     len = 20;
636     result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
637     ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
638 
639     /* add data after duplicating the hash */
640     result = CryptHashData(hHash, (const BYTE *)"more data", sizeof("more data"), 0);
641     ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
642 
643     result = CryptDestroyHash(hHash);
644     ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
645 
646     result = CryptDestroyHash(hHashClone);
647     ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
648 
649     result = CryptReleaseContext(prov, 0);
650     ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
651 
652     /* Test CALG_SSL3_SHAMD5 */
653     result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
654     ok(result, "CryptAcquireContextA failed 0x%08x\n", GetLastError());
655 
656     /* Step 1: create an MD5 hash of the data */
657     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
658     ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
659     result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
660     ok(result, "%08x\n", GetLastError());
661     len = 16;
662     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
663     ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
664     result = CryptDestroyHash(hHash);
665     ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
666     /* Step 2: create a SHA1 hash of the data */
667     result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
668     ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
669     result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
670     ok(result, "%08x\n", GetLastError());
671     len = 20;
672     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue + 16, &len, 0);
673     ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
674     result = CryptDestroyHash(hHash);
675     ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
676     /* Step 3: create a CALG_SSL3_SHAMD5 hash handle */
677     result = CryptCreateHash(hProv, CALG_SSL3_SHAMD5, 0, 0, &hHash);
678     ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
679     /* Test that CryptHashData fails on this hash */
680     result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
681     ok(!result && (GetLastError() == NTE_BAD_ALGID || broken(GetLastError() == ERROR_INVALID_HANDLE)) /* Win 8 */,
682        "%08x\n", GetLastError());
683     result = CryptSetHashParam(hHash, HP_HASHVAL, pbHashValue, 0);
684     ok(result, "%08x\n", GetLastError());
685     len = (DWORD)sizeof(abPlainPrivateKey);
686     result = CryptImportKey(hProv, abPlainPrivateKey, len, 0, 0, &hKeyExchangeKey);
687     ok(result, "%08x\n", GetLastError());
688     len = 0;
689     result = CryptSignHashA(hHash, AT_KEYEXCHANGE, NULL, 0, NULL, &len);
690     ok(result, "%08x\n", GetLastError());
691     ok(len == 128, "expected len 128, got %d\n", len);
692     result = CryptSignHashA(hHash, AT_KEYEXCHANGE, NULL, 0, pbSigValue, &len);
693     ok(result, "%08x\n", GetLastError());
694     ok(!memcmp(pbSigValue, signed_ssl3_shamd5_hash, len), "unexpected value\n");
695     if (len != 128 || memcmp(pbSigValue, signed_ssl3_shamd5_hash, len))
696     {
697         printBytes("expected", signed_ssl3_shamd5_hash,
698                    sizeof(signed_ssl3_shamd5_hash));
699         printBytes("got", pbSigValue, len);
700     }
701     result = CryptDestroyKey(hKeyExchangeKey);
702     ok(result, "CryptDestroyKey failed 0x%08x\n", GetLastError());
703     result = CryptDestroyHash(hHash);
704     ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
705     result = CryptReleaseContext(prov, 0);
706     ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
707 }
708 
709 static void test_block_cipher_modes(void)
710 {
711     static const BYTE plain[23] = {
712         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
713         0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
714     static const BYTE ecb[24] = {
715         0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
716         0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
717     static const BYTE cbc[24] = {
718         0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
719         0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
720     static const BYTE cfb[24] = {
721         0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
722         0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
723     HCRYPTKEY hKey;
724     BOOL result;
725     BYTE abData[24];
726     DWORD dwMode, dwLen;
727 
728     result = derive_key(CALG_RC2, &hKey, 40);
729     if (!result) return;
730 
731     memcpy(abData, plain, sizeof(plain));
732 
733     /* test default chaining mode */
734     dwMode = 0xdeadbeef;
735     dwLen = sizeof(dwMode);
736     result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
737     ok(result, "%08x\n", GetLastError());
738     ok(dwMode == CRYPT_MODE_CBC, "Wrong default chaining mode\n");
739 
740     dwMode = CRYPT_MODE_ECB;
741     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
742     ok(result, "%08x\n", GetLastError());
743 
744     result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
745     ok(result, "%08x\n", GetLastError());
746     ok(dwLen == 11 || broken(dwLen == 0 /* Win9x/NT4 */), "unexpected salt length %d\n", dwLen);
747 
748     dwLen = 23;
749     result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
750     ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
751     ok(dwLen == 24, "Unexpected length %d\n", dwLen);
752 
753     SetLastError(ERROR_SUCCESS);
754     dwLen = 23;
755     result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
756     ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
757        "%08x, dwLen: %d\n", GetLastError(), dwLen);
758 
759     result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
760     ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
761        "%08x, dwLen: %d\n", GetLastError(), dwLen);
762 
763     dwMode = CRYPT_MODE_CBC;
764     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
765     ok(result, "%08x\n", GetLastError());
766 
767     dwLen = 23;
768     result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
769     ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
770     ok(dwLen == 24, "Unexpected length %d\n", dwLen);
771 
772     dwLen = 23;
773     result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
774     ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
775        "%08x, dwLen: %d\n", GetLastError(), dwLen);
776 
777     result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
778     ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
779        "%08x, dwLen: %d\n", GetLastError(), dwLen);
780 
781     dwMode = CRYPT_MODE_CFB;
782     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
783     ok(result, "%08x\n", GetLastError());
784 
785     dwLen = 16;
786     result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
787     ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
788 
789     dwLen = 7;
790     result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
791     ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
792        "%08x, dwLen: %d\n", GetLastError(), dwLen);
793 
794     dwLen = 8;
795     result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
796     ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
797 
798     dwLen = 16;
799     result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
800     ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
801        "%08x, dwLen: %d\n", GetLastError(), dwLen);
802 
803     dwMode = CRYPT_MODE_OFB;
804     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
805     if(!result && GetLastError() == ERROR_INTERNAL_ERROR)
806     {
807         ok(broken(1), "OFB mode not supported\n"); /* Windows 8 */
808     }
809     else
810     {
811         ok(result, "%08x\n", GetLastError());
812 
813         dwLen = 23;
814         result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
815         ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
816     }
817 
818     CryptDestroyKey(hKey);
819 }
820 
821 static void test_3des112(void)
822 {
823     HCRYPTKEY hKey;
824     BOOL result;
825     DWORD dwLen;
826     unsigned char pbData[16], enc_data[16], bad_data[16];
827     static const BYTE des112[16] = {
828         0x8e, 0x0c, 0x3c, 0xa3, 0x05, 0x88, 0x5f, 0x7a,
829         0x32, 0xa1, 0x06, 0x52, 0x64, 0xd2, 0x44, 0x1c };
830     int i;
831 
832     result = derive_key(CALG_3DES_112, &hKey, 0);
833     if (!result) {
834         /* rsaenh compiled without OpenSSL */
835         ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
836         return;
837     }
838 
839     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
840 
841     dwLen = 13;
842     result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
843     ok(result, "%08x\n", GetLastError());
844 
845     ok(!memcmp(pbData, des112, sizeof(des112)), "3DES_112 encryption failed!\n");
846 
847     result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
848     ok(result, "%08x\n", GetLastError());
849 
850     for (i=0; i<4; i++)
851     {
852       memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
853 
854       dwLen = cTestData[i].enclen;
855       result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
856       ok(result, "%08x\n", GetLastError());
857       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
858       memcpy(enc_data, pbData, cTestData[i].buflen);
859 
860       result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
861       ok(result, "%08x\n", GetLastError());
862       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
863       ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
864       if((dwLen != cTestData[i].enclen) ||
865          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
866       {
867           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
868           printBytes("got",pbData,dwLen);
869       }
870 
871       /* Test bad data:
872          Decrypting a block of bad data with Final = TRUE should restore the
873          initial state of the key as well as decrypting a block of good data.
874        */
875 
876       /* Changing key state by setting Final = FALSE */
877       dwLen = cTestData[i].buflen;
878       memcpy(pbData, enc_data, cTestData[i].buflen);
879       result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
880       ok(result, "%08x\n", GetLastError());
881 
882       /* Restoring key state by decrypting bad_data with Final = TRUE */
883       memcpy(bad_data, enc_data, cTestData[i].buflen);
884       bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
885       SetLastError(0xdeadbeef);
886       result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
887       ok(!result, "CryptDecrypt should failed!\n");
888       ok(GetLastError() == NTE_BAD_DATA, "%08x\n", GetLastError());
889       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
890       ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
891 
892       /* Checking key state */
893       dwLen = cTestData[i].buflen;
894       memcpy(pbData, enc_data, cTestData[i].buflen);
895       result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
896       ok(result, "%08x\n", GetLastError());
897       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
898       ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
899       if((dwLen != cTestData[i].enclen) ||
900          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
901       {
902           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
903           printBytes("got",pbData,dwLen);
904       }
905     }
906     result = CryptDestroyKey(hKey);
907     ok(result, "%08x\n", GetLastError());
908 }
909 
910 static void test_des(void)
911 {
912     HCRYPTKEY hKey;
913     BOOL result;
914     DWORD dwLen, dwMode;
915     unsigned char pbData[16], enc_data[16], bad_data[16];
916     static const BYTE des[16] = {
917         0x58, 0x86, 0x42, 0x46, 0x65, 0x4b, 0x92, 0x62,
918         0xcf, 0x0f, 0x65, 0x37, 0x43, 0x7a, 0x82, 0xb9 };
919     static const BYTE des_old_behavior[16] = {
920         0xb0, 0xfd, 0x11, 0x69, 0x76, 0xb1, 0xa1, 0x03,
921         0xf7, 0xbc, 0x23, 0xaa, 0xd4, 0xc1, 0xc9, 0x55 };
922     static const BYTE des_old_strong[16] = {
923         0x9b, 0xc1, 0x2a, 0xec, 0x4a, 0xf9, 0x0f, 0x14,
924         0x0a, 0xed, 0xf6, 0xd3, 0xdc, 0xad, 0xf7, 0x0c };
925     int i;
926 
927     result = derive_key(CALG_DES, &hKey, 0);
928     if (!result) {
929         /* rsaenh compiled without OpenSSL */
930         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
931         return;
932     }
933 
934     dwMode = CRYPT_MODE_ECB;
935     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
936     ok(result, "%08x\n", GetLastError());
937 
938     dwLen = sizeof(DWORD);
939     result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
940     ok(result, "%08x\n", GetLastError());
941     ok(dwMode == CRYPT_MODE_ECB, "Expected CRYPT_MODE_ECB, got %d\n", dwMode);
942 
943     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
944 
945     dwLen = 13;
946     result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
947     ok(result, "%08x\n", GetLastError());
948 
949     ok(!memcmp(pbData, des, sizeof(des)), "DES encryption failed!\n");
950 
951     result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
952     ok(result, "%08x\n", GetLastError());
953 
954     for (i=0; i<4; i++)
955     {
956       memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
957 
958       dwLen = cTestData[i].enclen;
959       result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
960       ok(result, "%08x\n", GetLastError());
961       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
962       memcpy(enc_data, pbData, cTestData[i].buflen);
963 
964       result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
965       ok(result, "%08x\n", GetLastError());
966       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
967       ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
968       if((dwLen != cTestData[i].enclen) ||
969          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
970       {
971           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
972           printBytes("got",pbData,dwLen);
973       }
974 
975       /* Test bad data:
976          Decrypting a block of bad data with Final = TRUE should restore the
977          initial state of the key as well as decrypting a block of good data.
978        */
979 
980       /* Changing key state by setting Final = FALSE */
981       dwLen = cTestData[i].buflen;
982       memcpy(pbData, enc_data, cTestData[i].buflen);
983       result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
984       ok(result, "%08x\n", GetLastError());
985 
986       /* Restoring key state by decrypting bad_data with Final = TRUE */
987       memcpy(bad_data, enc_data, cTestData[i].buflen);
988       bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
989       SetLastError(0xdeadbeef);
990       result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
991       ok(!result, "CryptDecrypt should failed!\n");
992       ok(GetLastError() == NTE_BAD_DATA, "%08x\n", GetLastError());
993       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
994       ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
995 
996       /* Checking key state */
997       dwLen = cTestData[i].buflen;
998       memcpy(pbData, enc_data, cTestData[i].buflen);
999       result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1000       ok(result, "%08x\n", GetLastError());
1001       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
1002       ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1003       if((dwLen != cTestData[i].enclen) ||
1004          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1005       {
1006           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1007           printBytes("got",pbData,dwLen);
1008       }
1009     }
1010 
1011     result = CryptDestroyKey(hKey);
1012     ok(result, "%08x\n", GetLastError());
1013 
1014     /* Windows >= XP changed the way DES keys are derived, this test ensures we don't break that */
1015     derive_key(CALG_DES, &hKey, 56);
1016 
1017     dwMode = CRYPT_MODE_ECB;
1018     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
1019     ok(result, "%08x\n", GetLastError());
1020 
1021     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
1022 
1023     dwLen = 13;
1024     result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
1025     ok(result, "%08x\n", GetLastError());
1026     ok(!memcmp(pbData, des, sizeof(des)) || broken(
1027     !memcmp(pbData, des_old_behavior, sizeof(des)) ||
1028     (STRONG_PROV && !memcmp(pbData, des_old_strong, sizeof(des)))) /* <= 2000 */,
1029        "DES encryption failed!\n");
1030 
1031     result = CryptDestroyKey(hKey);
1032     ok(result, "%08x\n", GetLastError());
1033 }
1034 
1035 static void test_3des(void)
1036 {
1037     HCRYPTKEY hKey;
1038     BOOL result;
1039     DWORD dwLen;
1040     unsigned char pbData[16], enc_data[16], bad_data[16];
1041     static const BYTE des3[16] = {
1042         0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
1043         0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
1044     int i;
1045 
1046     result = derive_key(CALG_3DES, &hKey, 0);
1047     if (!result) return;
1048 
1049     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
1050 
1051     dwLen = 13;
1052     result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
1053     ok(result, "%08x\n", GetLastError());
1054 
1055     ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
1056 
1057     result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1058     ok(result, "%08x\n", GetLastError());
1059 
1060     for (i=0; i<4; i++)
1061     {
1062       memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
1063 
1064       dwLen = cTestData[i].enclen;
1065       result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
1066       ok(result, "%08x\n", GetLastError());
1067       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
1068       memcpy(enc_data, pbData, cTestData[i].buflen);
1069 
1070       result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1071       ok(result, "%08x\n", GetLastError());
1072       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
1073       ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
1074       if((dwLen != cTestData[i].enclen) ||
1075          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1076       {
1077           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1078           printBytes("got",pbData,dwLen);
1079       }
1080 
1081       /* Test bad data:
1082          Decrypting a block of bad data with Final = TRUE should restore the
1083          initial state of the key as well as decrypting a block of good data.
1084        */
1085 
1086       /* Changing key state by setting Final = FALSE */
1087       dwLen = cTestData[i].buflen;
1088       memcpy(pbData, enc_data, cTestData[i].buflen);
1089       result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
1090       ok(result, "%08x\n", GetLastError());
1091 
1092       /* Restoring key state by decrypting bad_data with Final = TRUE */
1093       memcpy(bad_data, enc_data, cTestData[i].buflen);
1094       bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
1095       SetLastError(0xdeadbeef);
1096       result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
1097       ok(!result, "CryptDecrypt should failed!\n");
1098       ok(GetLastError() == NTE_BAD_DATA, "%08x\n", GetLastError());
1099       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
1100       ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1101 
1102       /* Checking key state */
1103       dwLen = cTestData[i].buflen;
1104       memcpy(pbData, enc_data, cTestData[i].buflen);
1105       result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1106       ok(result, "%08x\n", GetLastError());
1107       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
1108       ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1109       if((dwLen != cTestData[i].enclen) ||
1110          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1111       {
1112           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1113           printBytes("got",pbData,dwLen);
1114       }
1115     }
1116     result = CryptDestroyKey(hKey);
1117     ok(result, "%08x\n", GetLastError());
1118 }
1119 
1120 static void test_aes(int keylen)
1121 {
1122     HCRYPTKEY hKey;
1123     BOOL result;
1124     DWORD dwLen, dwMode;
1125     unsigned char pbData[48], enc_data[16], bad_data[16];
1126     int i;
1127     static const BYTE aes_plain[32] = {
1128         "AES Test With 2 Blocks Of Data." };
1129     static const BYTE aes_cbc_enc[3][48] = {
1130     /* 128 bit key encrypted text */
1131     { 0xfe, 0x85, 0x3b, 0xe1, 0xf5, 0xe1, 0x58, 0x75, 0xd5, 0xa9, 0x74, 0xe3, 0x09, 0xea, 0xa5, 0x04,
1132       0x23, 0x35, 0xa2, 0x3b, 0x5c, 0xf1, 0x6c, 0x6f, 0xb9, 0xcd, 0x64, 0x06, 0x3e, 0x41, 0x83, 0xef,
1133       0x2a, 0xfe, 0xea, 0xb5, 0x6c, 0x17, 0x20, 0x79, 0x8c, 0x51, 0x3e, 0x56, 0xed, 0xe1, 0x47, 0x68 },
1134     /* 192 bit key encrypted text */
1135     { 0x6b, 0xf0, 0xfd, 0x32, 0xee, 0xc6, 0x06, 0x13, 0xa8, 0xe6, 0x3c, 0x81, 0x85, 0xb8, 0x2e, 0xa1,
1136       0xd4, 0x3b, 0xe8, 0x22, 0xa5, 0x74, 0x4a, 0xbe, 0x9d, 0xcf, 0xcc, 0x37, 0x26, 0x19, 0x5a, 0xd1,
1137       0x7f, 0x76, 0xbf, 0x94, 0x28, 0xce, 0x27, 0x21, 0x61, 0x87, 0xeb, 0xb9, 0x8b, 0xa8, 0xb4, 0x57 },
1138     /* 256 bit key encrypted text */
1139     { 0x20, 0x57, 0x17, 0x0b, 0x17, 0x76, 0xd8, 0x3b, 0x26, 0x90, 0x8b, 0x4c, 0xf2, 0x00, 0x79, 0x33,
1140       0x29, 0x2b, 0x13, 0x9c, 0xe2, 0x95, 0x09, 0xc1, 0xcd, 0x20, 0x87, 0x22, 0x32, 0x70, 0x9d, 0x75,
1141       0x9a, 0x94, 0xf5, 0x76, 0x5c, 0xb1, 0x62, 0x2c, 0xe1, 0x76, 0x7c, 0x86, 0x73, 0xe6, 0x7a, 0x23 }
1142     };
1143     switch (keylen)
1144     {
1145         case 256:
1146             result = derive_key(CALG_AES_256, &hKey, 0);
1147             i = 2;
1148             break;
1149         case 192:
1150             result = derive_key(CALG_AES_192, &hKey, 0);
1151             i = 1;
1152             break;
1153         default:
1154         case 128:
1155             result = derive_key(CALG_AES_128, &hKey, 0);
1156             i = 0;
1157             break;
1158     }
1159     if (!result) return;
1160 
1161     dwLen = sizeof(aes_plain);
1162     memcpy(pbData, aes_plain, dwLen);
1163     result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, sizeof(pbData));
1164     ok(result, "Expected OK, got last error %d\n", GetLastError());
1165     ok(dwLen == 48, "Expected dwLen 48, got %d\n", dwLen);
1166     ok(!memcmp(aes_cbc_enc[i], pbData, dwLen), "Expected equal data sequences\n");
1167 
1168     result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1169     ok(result && dwLen == 32 && !memcmp(aes_plain, pbData, dwLen),
1170        "%08x, dwLen: %d\n", GetLastError(), dwLen);
1171 
1172     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
1173 
1174     /* Does AES provider support salt? */
1175     result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1176     todo_wine ok(result || broken(GetLastError() == NTE_BAD_KEY), /* Vista or older */
1177        "Expected OK, got last error %d\n", GetLastError());
1178     if (result)
1179         ok(!dwLen, "unexpected salt length %d\n", dwLen);
1180 
1181     /* test default chaining mode */
1182     dwMode = 0xdeadbeef;
1183     dwLen = sizeof(dwMode);
1184     result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1185     ok(result, "%08x\n", GetLastError());
1186     ok(dwMode == CRYPT_MODE_CBC, "Wrong default chaining\n");
1187 
1188     dwLen = 13;
1189     result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
1190     ok(result, "%08x\n", GetLastError());
1191 
1192     result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1193     ok(result, "%08x\n", GetLastError());
1194 
1195     for (i=0; i<4; i++)
1196     {
1197       memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
1198 
1199       dwLen = cTestData[i].enclen;
1200       result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
1201       ok(result, "%08x\n", GetLastError());
1202       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
1203       memcpy(enc_data, pbData, cTestData[i].buflen);
1204 
1205       result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1206       ok(result, "%08x\n", GetLastError());
1207       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
1208       ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1209       if((dwLen != cTestData[i].enclen) ||
1210          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1211       {
1212           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1213           printBytes("got",pbData,dwLen);
1214       }
1215 
1216       /* Test bad data:
1217          Decrypting a block of bad data with Final = TRUE should restore the
1218          initial state of the key as well as decrypting a block of good data.
1219        */
1220 
1221       /* Changing key state by setting Final = FALSE */
1222       dwLen = cTestData[i].buflen;
1223       memcpy(pbData, enc_data, cTestData[i].buflen);
1224       result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
1225       ok(result, "%08x\n", GetLastError());
1226 
1227       /* Restoring key state by decrypting bad_data with Final = TRUE */
1228       memcpy(bad_data, enc_data, cTestData[i].buflen);
1229       bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
1230       SetLastError(0xdeadbeef);
1231       result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
1232       ok(!result, "CryptDecrypt should failed!\n");
1233       ok(GetLastError() == NTE_BAD_DATA, "%08x\n", GetLastError());
1234       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
1235       ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1236 
1237       /* Checking key state */
1238       dwLen = cTestData[i].buflen;
1239       memcpy(pbData, enc_data, cTestData[i].buflen);
1240       result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1241       ok(result, "%08x\n", GetLastError());
1242       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
1243       ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1244       if((dwLen != cTestData[i].enclen) ||
1245          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1246       {
1247           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1248           printBytes("got",pbData,dwLen);
1249       }
1250     }
1251     result = CryptDestroyKey(hKey);
1252     ok(result, "%08x\n", GetLastError());
1253 }
1254 
1255 static void test_sha2(void)
1256 {
1257     static const unsigned char sha256hash[32] = {
1258         0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
1259         0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
1260         0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
1261         0x1a, 0x08
1262     };
1263     static const unsigned char sha384hash[48] = {
1264         0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
1265         0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
1266         0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
1267         0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
1268         0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
1269     };
1270     static const unsigned char sha512hash[64] = {
1271         0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
1272         0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
1273         0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
1274         0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
1275         0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
1276         0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
1277         0xb7, 0xf4, 0x81, 0xd4
1278     };
1279     unsigned char pbData[2048];
1280     BOOL result;
1281     HCRYPTHASH hHash;
1282     BYTE pbHashValue[64];
1283     DWORD hashlen, len;
1284     int i;
1285 
1286     for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
1287 
1288     /* SHA-256 hash */
1289     SetLastError(0xdeadbeef);
1290     result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
1291     if (!result && GetLastError() == NTE_BAD_ALGID) {
1292         win_skip("SHA-256/384/512 hashes are not supported before Windows XP SP3\n");
1293         return;
1294     }
1295     ok(result, "%08x\n", GetLastError());
1296     if (result) {
1297         len = sizeof(DWORD);
1298         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1299         ok(result && (hashlen == 32), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1300 
1301         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1302         ok(result, "%08x\n", GetLastError());
1303 
1304         len = 32;
1305         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1306         ok(result, "%08x\n", GetLastError());
1307 
1308         ok(!memcmp(pbHashValue, sha256hash, 32), "Wrong SHA-256 hash!\n");
1309 
1310         result = CryptDestroyHash(hHash);
1311         ok(result, "%08x\n", GetLastError());
1312     }
1313 
1314     /* SHA-384 hash */
1315     result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
1316     ok(result, "%08x\n", GetLastError());
1317     if (result) {
1318         len = sizeof(DWORD);
1319         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1320         ok(result && (hashlen == 48), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1321 
1322         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1323         ok(result, "%08x\n", GetLastError());
1324 
1325         len = 48;
1326         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1327         ok(result, "%08x\n", GetLastError());
1328 
1329         ok(!memcmp(pbHashValue, sha384hash, 48), "Wrong SHA-384 hash!\n");
1330 
1331         result = CryptDestroyHash(hHash);
1332         ok(result, "%08x\n", GetLastError());
1333     }
1334 
1335     /* SHA-512 hash */
1336     result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
1337     ok(result, "%08x\n", GetLastError());
1338     if (result) {
1339         len = sizeof(DWORD);
1340         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1341         ok(result && (hashlen == 64), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1342 
1343         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1344         ok(result, "%08x\n", GetLastError());
1345 
1346         len = 64;
1347         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1348         ok(result, "%08x\n", GetLastError());
1349 
1350         ok(!memcmp(pbHashValue, sha512hash, 64), "Wrong SHA-512 hash!\n");
1351 
1352         result = CryptDestroyHash(hHash);
1353         ok(result, "%08x\n", GetLastError());
1354     }
1355 }
1356 
1357 static void test_rc2(void)
1358 {
1359     static const BYTE rc2_40_encrypted[16] = {
1360         0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
1361         0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
1362     static const BYTE rc2_128_encrypted[] = {
1363         0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,
1364         0x2a,0x2a,0xc0,0xce,0x4c,0x89,0xb6,0x66 };
1365     static const BYTE rc2_40def_encrypted[] = {
1366         0x23,0xc8,0x70,0x13,0x42,0x2e,0xa8,0x98,
1367         0x5c,0xdf,0x7a,0x9b,0xea,0xdb,0x96,0x1b };
1368     static const BYTE rc2_40_salt_enh[24] = {
1369         0xA3, 0xD7, 0x41, 0x87, 0x7A, 0xD0, 0x18, 0xDB,
1370         0xD4, 0x6A, 0x4F, 0xEE, 0xF3, 0xCA, 0xCD, 0x34,
1371         0xB3, 0x15, 0x9A, 0x2A, 0x88, 0x5F, 0x43, 0xA5 };
1372     static const BYTE rc2_40_salt_base[24] = {
1373         0x8C, 0x4E, 0xA6, 0x00, 0x9B, 0x15, 0xEF, 0x9E,
1374         0x88, 0x81, 0xD0, 0x65, 0xD6, 0x53, 0x57, 0x08,
1375         0x0A, 0x77, 0x80, 0xFA, 0x7E, 0x89, 0x14, 0x55 };
1376     static const BYTE rc2_40_salt_strong[24] = {
1377         0xB9, 0x33, 0xB6, 0x7A, 0x35, 0xC3, 0x06, 0x88,
1378         0xBF, 0xD5, 0xCC, 0xAF, 0x14, 0xAE, 0xE2, 0x31,
1379         0xC6, 0x9A, 0xAA, 0x3F, 0x05, 0x2F, 0x22, 0xDA };
1380     HCRYPTHASH hHash;
1381     HCRYPTKEY hKey;
1382     BOOL result;
1383     DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits, error;
1384     unsigned char pbData[2000], pbHashValue[16], pszBuffer[256];
1385     int i;
1386 
1387     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1388 
1389     /* MD2 Hashing */
1390     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1391     if (!result) {
1392         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1393     } else {
1394         CRYPT_INTEGER_BLOB salt;
1395 
1396         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1397         ok(result, "%08x\n", GetLastError());
1398 
1399         dwLen = 16;
1400         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1401         ok(result, "%08x\n", GetLastError());
1402 
1403         result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
1404         ok(result, "%08x\n", GetLastError());
1405 
1406         dwLen = sizeof(DWORD);
1407         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1408         ok(result, "%08x\n", GetLastError());
1409 
1410         /* test default chaining mode */
1411         dwMode = 0xdeadbeef;
1412         dwLen = sizeof(dwMode);
1413         result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1414         ok(result, "%08x\n", GetLastError());
1415         ok(dwMode == CRYPT_MODE_CBC, "Wrong default chaining mode\n");
1416 
1417         dwMode = CRYPT_MODE_CBC;
1418         result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
1419         ok(result, "%08x\n", GetLastError());
1420 
1421         dwLen = sizeof(DWORD);
1422         result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
1423         ok(result, "%08x\n", GetLastError());
1424 
1425         dwModeBits = 0xdeadbeef;
1426         dwLen = sizeof(DWORD);
1427         result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1428         ok(result, "%08x\n", GetLastError());
1429         ok(dwModeBits ==
1430             (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1431             broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
1432             "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1433             " got %08x\n", dwModeBits);
1434 
1435         dwLen = sizeof(DWORD);
1436         result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1437         ok(result, "%08x\n", GetLastError());
1438 
1439         dwLen = sizeof(DWORD);
1440         result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
1441         ok(result, "%08x\n", GetLastError());
1442         ok(dwLen == 4, "Expected 4, got %d\n", dwLen);
1443 
1444         dwLen = 0;
1445         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1446         ok(result, "%08x\n", GetLastError());
1447         result = CryptGetKeyParam(hKey, KP_IV, pszBuffer, &dwLen, 0);
1448         ok(result, "%08x\n", GetLastError());
1449         ok(dwLen == 8, "Expected 8, got %d\n", dwLen);
1450 
1451         dwLen = 0;
1452         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1453         ok(result, "%08x\n", GetLastError());
1454         /* The default salt length is always 11... */
1455         ok(dwLen == 11, "unexpected salt length %d\n", dwLen);
1456         /* and the default salt is always empty. */
1457         result = CryptGetKeyParam(hKey, KP_SALT, pszBuffer, &dwLen, 0);
1458         ok(result, "%08x\n", GetLastError());
1459         for (i=0; i<dwLen; i++)
1460             ok(!pszBuffer[i], "unexpected salt value %02x @ %d\n", pszBuffer[i], i);
1461 
1462         dwLen = sizeof(DWORD);
1463         result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1464         ok(result, "%08x\n", GetLastError());
1465         ok(dwMode == CRYPT_MODE_CBC, "Expected CRYPT_MODE_CBC, got %d\n", dwMode);
1466 
1467         result = CryptDestroyHash(hHash);
1468         ok(result, "%08x\n", GetLastError());
1469 
1470         dwDataLen = 13;
1471         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1472         ok(result, "%08x\n", GetLastError());
1473 
1474         ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
1475 
1476         dwLen = 0;
1477         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1478         ok(result, "%08x\n", GetLastError());
1479         result = CryptGetKeyParam(hKey, KP_IV, pszBuffer, &dwLen, 0);
1480         ok(result, "%08x\n", GetLastError());
1481 
1482         result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1483         ok(result, "%08x\n", GetLastError());
1484 
1485         /* Setting the salt value will not reset the salt length in base or strong providers */
1486         result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1487         ok(result, "setting salt failed: %08x\n", GetLastError());
1488         dwLen = 0;
1489         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1490         ok(result, "%08x\n", GetLastError());
1491         if (BASE_PROV || STRONG_PROV)
1492             ok(dwLen == 11, "expected salt length 11, got %d\n", dwLen);
1493         else
1494             ok(dwLen == 0 || broken(nt4 && dwLen == 11), "expected salt length 0, got %d\n", dwLen);
1495         /* What sizes salt can I set? */
1496         salt.pbData = pbData;
1497         for (i=0; i<24; i++)
1498         {
1499             salt.cbData = i;
1500             result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1501             ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1502             /* The returned salt length is the same as the set salt length */
1503             result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1504             ok(result, "%08x\n", GetLastError());
1505             ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1506         }
1507         salt.cbData = 25;
1508         SetLastError(0xdeadbeef);
1509         result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1510         ok(!result ||
1511            broken(result), /* Win9x, WinMe, NT4, W2K */
1512            "%08x\n", GetLastError());
1513 
1514         result = CryptDestroyKey(hKey);
1515         ok(result, "%08x\n", GetLastError());
1516     }
1517 
1518     /* Again, but test setting the effective key len */
1519     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1520 
1521     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1522     if (!result) {
1523         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1524     } else {
1525         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1526         ok(result, "%08x\n", GetLastError());
1527 
1528         dwLen = 16;
1529         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1530         ok(result, "%08x\n", GetLastError());
1531 
1532         result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
1533         ok(result, "%08x\n", GetLastError());
1534 
1535         SetLastError(0xdeadbeef);
1536         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
1537         ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
1538         dwKeyLen = 0;
1539         SetLastError(0xdeadbeef);
1540         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1541         ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
1542         dwKeyLen = 1025;
1543         SetLastError(0xdeadbeef);
1544         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1545         ok(!result, "CryptSetKeyParam failed: %08x\n", GetLastError());
1546 
1547         dwLen = sizeof(dwKeyLen);
1548         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1549         ok(result, "%08x\n", GetLastError());
1550         ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1551         result = CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1552         ok(result, "%08x\n", GetLastError());
1553         ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
1554 
1555         dwKeyLen = 128;
1556         SetLastError(0xdeadbeef);
1557         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1558         if (!BASE_PROV)
1559         {
1560             dwKeyLen = 12345;
1561             ok(result, "expected success, got error 0x%08X\n", GetLastError());
1562             result = CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1563             ok(result, "%08x\n", GetLastError());
1564             ok(dwKeyLen == 128, "Expected 128, got %d\n", dwKeyLen);
1565         }
1566         else
1567         {
1568             ok(!result, "expected error\n");
1569             ok(GetLastError() == NTE_BAD_DATA, "Expected 0x80009005, got 0x%08X\n", GetLastError());
1570             result = CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1571             ok(result, "%08x\n", GetLastError());
1572             ok(dwKeyLen == 40, "Expected 40, got %d\n", dwKeyLen);
1573         }
1574 
1575         dwLen = sizeof(dwKeyLen);
1576         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1577         ok(result, "%08x\n", GetLastError());
1578         ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1579         result = CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1580         ok(result, "%08x\n", GetLastError());
1581         ok((!BASE_PROV && dwKeyLen == 128) || (BASE_PROV && dwKeyLen == 40),
1582            "%d (%08x)\n", dwKeyLen, GetLastError());
1583 
1584         result = CryptDestroyHash(hHash);
1585         ok(result, "%08x\n", GetLastError());
1586 
1587         dwDataLen = 13;
1588         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1589         ok(result, "%08x\n", GetLastError());
1590         ok(!memcmp(pbData, !BASE_PROV ? rc2_128_encrypted : rc2_40def_encrypted,
1591            sizeof(rc2_128_encrypted)), "RC2 encryption failed!\n");
1592 
1593         /* Oddly enough this succeeds, though it should have no effect */
1594         dwKeyLen = 40;
1595         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1596         ok(result, "%d\n", GetLastError());
1597 
1598         result = CryptDestroyKey(hKey);
1599         ok(result, "%08x\n", GetLastError());
1600 
1601         /* Test a 40 bit key with salt */
1602         result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1603         ok(result, "%08x\n", GetLastError());
1604 
1605         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1606         ok(result, "%08x\n", GetLastError());
1607 
1608         result = CryptDeriveKey(hProv, CALG_RC2, hHash, (40<<16)|CRYPT_CREATE_SALT, &hKey);
1609         ok(result, "%08x\n", GetLastError());
1610 
1611         dwDataLen = 16;
1612         memset(pbData, 0xAF, dwDataLen);
1613         SetLastError(0xdeadbeef);
1614         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1615         if(result)
1616         {
1617             ok((ENHANCED_PROV && !memcmp(pbData, rc2_40_salt_enh, dwDataLen)) ||
1618                (STRONG_PROV && !memcmp(pbData, rc2_40_salt_strong, dwDataLen)) ||
1619                (BASE_PROV && !memcmp(pbData, rc2_40_salt_base, dwDataLen)),
1620                "RC2 encryption failed!\n");
1621         }
1622         else /* <= XP */
1623         {
1624             error = GetLastError();
1625             ok(error == NTE_BAD_DATA || broken(error == NTE_DOUBLE_ENCRYPT),
1626                "Expected 0x80009005, got 0x%08X\n", error);
1627         }
1628         dwLen = sizeof(DWORD);
1629         dwKeyLen = 12345;
1630         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1631         ok(result, "%08x\n", GetLastError());
1632         ok(dwKeyLen == 40, "Expected 40, got %d\n", dwKeyLen);
1633 
1634         dwLen = sizeof(pszBuffer);
1635         memset(pszBuffer, 0xAF, dwLen);
1636         result = CryptGetKeyParam(hKey, KP_SALT, pszBuffer, &dwLen, 0);
1637         ok(result, "%08x\n", GetLastError());
1638         if (!ENHANCED_PROV)
1639             ok(dwLen == 11, "Expected 11, got %d\n", dwLen);
1640         else
1641             ok(dwLen == 0, "Expected 0, got %d\n", dwLen);
1642 
1643         result = CryptDestroyKey(hKey);
1644         ok(result, "%08x\n", GetLastError());
1645 
1646         result = CryptDestroyHash(hHash);
1647         ok(result, "%08x\n", GetLastError());
1648     }
1649 }
1650 
1651 static void test_rc4(void)
1652 {
1653     static const BYTE rc4[16] = {
1654         0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
1655         0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
1656     static const BYTE rc4_40_salt[16] = {
1657         0x41, 0xE6, 0x33, 0xC9, 0x50, 0xA1, 0xBF, 0x88,
1658         0x12, 0x4D, 0xD3, 0xE3, 0x47, 0x88, 0x6D, 0xA5 };
1659     static const BYTE rc4_40_salt_base[16] = {
1660         0x2F, 0xAC, 0xEA, 0xEA, 0xFF, 0x68, 0x7E, 0x77,
1661         0xF4, 0xB9, 0x48, 0x7C, 0x4E, 0x79, 0xA6, 0xB5 };
1662     BOOL result;
1663     HCRYPTHASH hHash;
1664     HCRYPTKEY hKey;
1665     DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1666     unsigned char pbData[2000];
1667     unsigned char pszBuffer[256];
1668     int i;
1669 
1670     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1671 
1672     /* MD2 Hashing */
1673     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1674     if (!result) {
1675         /* rsaenh compiled without OpenSSL */
1676         ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
1677     } else {
1678         CRYPT_INTEGER_BLOB salt;
1679 
1680         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1681            ok(result, "%08x\n", GetLastError());
1682 
1683         dwLen = 16;
1684         result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1685         ok(result, "%08x\n", GetLastError());
1686 
1687         result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1688         ok(result, "%08x\n", GetLastError());
1689 
1690         dwLen = sizeof(DWORD);
1691         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1692         ok(result, "%08x\n", GetLastError());
1693         ok(dwKeyLen == 56, "Expected 56, got %d\n", dwKeyLen);
1694 
1695         dwLen = sizeof(DWORD);
1696         result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1697         ok(result, "%08x\n", GetLastError());
1698         ok(dwKeyLen == 0, "Expected 0, got %d\n", dwKeyLen);
1699 
1700         dwLen = 0;
1701         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1702         ok(result, "%08x\n", GetLastError());
1703         result = CryptGetKeyParam(hKey, KP_IV, pszBuffer, &dwLen, 0);
1704 
1705         dwLen = 0;
1706         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1707         ok(result, "%08x\n", GetLastError());
1708         result = CryptGetKeyParam(hKey, KP_SALT, pszBuffer, &dwLen, 0);
1709         ok(result, "%08x\n", GetLastError());
1710 
1711         dwLen = sizeof(DWORD);
1712         result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1713         ok(result, "%08x\n", GetLastError());
1714         ok(dwMode == 0 || broken(dwMode == CRYPT_MODE_CBC) /* <= 2000 */,
1715            "Expected 0, got %d\n", dwMode);
1716 
1717         result = CryptDestroyHash(hHash);
1718         ok(result, "%08x\n", GetLastError());
1719 
1720         dwDataLen = 16;
1721         result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1722         ok(result, "%08x\n", GetLastError());
1723         dwDataLen = 16;
1724         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1725         ok(result, "%08x\n", GetLastError());
1726 
1727         ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1728 
1729         result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1730         ok(result, "%08x\n", GetLastError());
1731 
1732         /* Setting the salt value will not reset the salt length in base or strong providers */
1733         result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1734         ok(result, "setting salt failed: %08x\n", GetLastError());
1735         dwLen = 0;
1736         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1737         ok(result, "%08x\n", GetLastError());
1738         if (BASE_PROV || STRONG_PROV)
1739             ok(dwLen == 11, "expected salt length 11, got %d\n", dwLen);
1740         else
1741             ok(dwLen == 0 || broken(nt4 && dwLen == 11), "expected salt length 0, got %d\n", dwLen);
1742         /* What sizes salt can I set? */
1743         salt.pbData = pbData;
1744         for (i=0; i<24; i++)
1745         {
1746             salt.cbData = i;
1747             result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1748             ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1749             /* The returned salt length is the same as the set salt length */
1750             result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1751             ok(result, "%08x\n", GetLastError());
1752             ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1753         }
1754         salt.cbData = 25;
1755         SetLastError(0xdeadbeef);
1756         result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1757         ok(!result ||
1758            broken(result), /* Win9x, WinMe, NT4, W2K */
1759            "%08x\n", GetLastError());
1760 
1761         result = CryptDestroyKey(hKey);
1762         ok(result, "%08x\n", GetLastError());
1763 
1764         /* Test a 40 bit key with salt */
1765         result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1766         ok(result, "%08x\n", GetLastError());
1767 
1768         result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1769         ok(result, "%08x\n", GetLastError());
1770 
1771         result = CryptDeriveKey(hProv, CALG_RC4, hHash, (40<<16)|CRYPT_CREATE_SALT, &hKey);
1772         ok(result, "%08x\n", GetLastError());
1773         dwDataLen = 16;
1774         memset(pbData, 0xAF, dwDataLen);
1775         SetLastError(0xdeadbeef);
1776         result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1777         ok(result, "%08x\n", GetLastError());
1778         ok((ENHANCED_PROV && !memcmp(pbData, rc4_40_salt, dwDataLen)) ||
1779            (!ENHANCED_PROV && !memcmp(pbData, rc4_40_salt_base, dwDataLen)),
1780            "RC4 encryption failed!\n");
1781 
1782         dwLen = sizeof(DWORD);
1783         dwKeyLen = 12345;
1784         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1785         ok(result, "%08x\n", GetLastError());
1786         ok(dwKeyLen == 40, "Expected 40, got %d\n", dwKeyLen);
1787 
1788         dwLen = sizeof(pszBuffer);
1789         memset(pszBuffer, 0xAF, dwLen);
1790         result = CryptGetKeyParam(hKey, KP_SALT, pszBuffer, &dwLen, 0);
1791         ok(result, "%08x\n", GetLastError());
1792         if (!ENHANCED_PROV)
1793             ok(dwLen == 11, "Expected 11, got %d\n", dwLen);
1794         else
1795             ok(dwLen == 0, "Expected 0, got %d\n", dwLen);
1796 
1797         result = CryptDestroyKey(hKey);
1798         ok(result, "%08x\n", GetLastError());
1799 
1800         result = CryptDestroyHash(hHash);
1801         ok(result, "%08x\n", GetLastError());
1802     }
1803 }
1804 
1805 static void test_hmac(void) {
1806     HCRYPTKEY hKey;
1807     HCRYPTHASH hHash;
1808     BOOL result;
1809     /* Using CALG_MD2 here fails on Windows 2003, why ? */
1810     HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1811     DWORD dwLen;
1812     BYTE abData[256];
1813     static const BYTE hmac[16] = {
1814         0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1815         0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1816     int i;
1817 
1818     for (i=0; i < ARRAY_SIZE(abData); i++) abData[i] = (BYTE)i;
1819 
1820     if (!derive_key(CALG_RC2, &hKey, 56)) return;
1821 
1822     result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1823     ok(result, "%08x\n", GetLastError());
1824     if (!result) return;
1825 
1826     result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1827     ok(result, "%08x\n", GetLastError());
1828 
1829     result = CryptHashData(hHash, abData, sizeof(abData), 0);
1830     ok(result, "%08x\n", GetLastError());
1831 
1832     dwLen = ARRAY_SIZE(abData);
1833     result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1834     ok(result, "%08x\n", GetLastError());
1835 
1836     ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1837 
1838     result = CryptDestroyHash(hHash);
1839     ok(result, "%08x\n", GetLastError());
1840 
1841     result = CryptDestroyKey(hKey);
1842     ok(result, "%08x\n", GetLastError());
1843 
1844     /* Provoke errors */
1845     result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1846     ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1847 }
1848 
1849 static void test_mac(void) {
1850     HCRYPTKEY hKey;
1851     HCRYPTHASH hHash;
1852     BOOL result;
1853     DWORD dwLen;
1854     BYTE abData[256], abEnc[264];
1855     static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1856     int i;
1857 
1858     for (i=0; i < ARRAY_SIZE(abData); i++) abData[i] = (BYTE)i;
1859     for (i=0; i < ARRAY_SIZE(abData); i++) abEnc[i] = (BYTE)i;
1860 
1861     if (!derive_key(CALG_RC2, &hKey, 40)) return;
1862 
1863     dwLen = 256;
1864     result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1865     ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1866 
1867     result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1868     ok(result, "%08x\n", GetLastError());
1869     if (!result) return;
1870 
1871     result = CryptHashData(hHash, abData, sizeof(abData), 0);
1872     ok(result, "%08x\n", GetLastError());
1873 
1874     dwLen = ARRAY_SIZE(abData);
1875     result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1876     ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1877 
1878     ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1879 
1880     result = CryptDestroyHash(hHash);
1881     ok(result, "%08x\n", GetLastError());
1882 
1883     result = CryptDestroyKey(hKey);
1884     ok(result, "%08x\n", GetLastError());
1885 
1886     /* Provoke errors */
1887     if (!derive_key(CALG_RC4, &hKey, 56)) return;
1888 
1889     SetLastError(0xdeadbeef);
1890     result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1891     ok((!result && GetLastError() == NTE_BAD_KEY) ||
1892             broken(result), /* Win9x, WinMe, NT4, W2K */
1893             "%08x\n", GetLastError());
1894 
1895     result = CryptDestroyKey(hKey);
1896     ok(result, "%08x\n", GetLastError());
1897 }
1898 
1899 static void test_import_private(void)
1900 {
1901     DWORD dwLen, dwVal;
1902     HCRYPTKEY hKeyExchangeKey, hSessionKey;
1903     BOOL result;
1904     static BYTE abSessionKey[148] = {
1905         0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1906         0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1907         0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1908         0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1909         0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1910         0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1911         0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1912         0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1913         0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1914         0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1915         0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1916         0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1917         0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1918         0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1919         0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1920         0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1921         0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1922         0x04, 0x8c, 0x49, 0x92
1923     };
1924     static BYTE abEncryptedMessage[12] = {
1925         0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1926         0x1c, 0xfd, 0xde, 0x71
1927     };
1928     BLOBHEADER *blobHeader = (BLOBHEADER *)abPlainPrivateKey;
1929     RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(blobHeader+1);
1930 
1931     dwLen = (DWORD)sizeof(abPlainPrivateKey);
1932     result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1933     if (!result) {
1934         /* rsaenh compiled without OpenSSL */
1935         ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1936         return;
1937     }
1938 
1939     dwLen = (DWORD)sizeof(abSessionKey);
1940     result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1941     ok(result, "%08x\n", GetLastError());
1942     if (!result) return;
1943 
1944     dwVal = 0xdeadbeef;
1945     dwLen = sizeof(DWORD);
1946     result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1947     ok(result, "%08x\n", GetLastError());
1948     ok(dwVal ==
1949         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1950         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1951         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1952         " got %08x\n", dwVal);
1953 
1954     dwLen = (DWORD)sizeof(abEncryptedMessage);
1955     result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1956     ok(result, "%08x\n", GetLastError());
1957     ok(dwLen == 12, "expected 12, got %d\n", dwLen);
1958     ok(!memcmp(abEncryptedMessage, "Wine rocks!", 12), "decrypt failed\n");
1959     CryptDestroyKey(hSessionKey);
1960 
1961     if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1962 
1963     dwLen = (DWORD)sizeof(abSessionKey);
1964     result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1965     ok(result, "%08x\n", GetLastError());
1966     CryptDestroyKey(hSessionKey);
1967     if (!result) return;
1968 
1969     dwLen = (DWORD)sizeof(abSessionKey);
1970     result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1971     ok(result, "%08x\n", GetLastError());
1972     if (!result) return;
1973 
1974     CryptDestroyKey(hSessionKey);
1975     CryptDestroyKey(hKeyExchangeKey);
1976 
1977     /* Test importing a private key with a buffer that's smaller than the
1978      * actual buffer.  The private exponent can be omitted, its length is
1979      * inferred from the passed-in length parameter.
1980      */
1981     dwLen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + rsaPubKey->bitlen / 2;
1982     for (; dwLen < sizeof(abPlainPrivateKey); dwLen++)
1983     {
1984         result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1985         ok(result, "CryptImportKey failed at size %d: %d (%08x)\n", dwLen,
1986            GetLastError(), GetLastError());
1987         if (result)
1988             CryptDestroyKey(hKeyExchangeKey);
1989     }
1990 }
1991 
1992 static void test_verify_signature(void) {
1993     HCRYPTHASH hHash;
1994     HCRYPTKEY hPubSignKey;
1995     BYTE abData[] = "Wine rocks!";
1996     BOOL result;
1997     BYTE abPubKey[148] = {
1998         0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1999         0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
2000         0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
2001         0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
2002         0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
2003         0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
2004         0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
2005         0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
2006         0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
2007         0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
2008         0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
2009         0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
2010         0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
2011         0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
2012         0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
2013         0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
2014         0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
2015         0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
2016         0xe1, 0x21, 0x50, 0xac
2017     };
2018     /* md2 with hash oid */
2019     BYTE abSignatureMD2[128] = {
2020         0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
2021         0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
2022         0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
2023         0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
2024         0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
2025         0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
2026         0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
2027         0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
2028         0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
2029         0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
2030         0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
2031         0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
2032         0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
2033         0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
2034         0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
2035         0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
2036     };
2037     /* md2 without hash oid */
2038     BYTE abSignatureMD2NoOID[128] = {
2039         0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
2040         0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
2041         0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
2042         0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
2043         0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
2044         0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
2045         0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
2046         0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
2047         0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
2048         0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
2049         0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
2050         0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
2051         0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
2052         0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
2053         0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
2054         0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
2055     };
2056     /* md4 with hash oid */
2057     BYTE abSignatureMD4[128] = {
2058         0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
2059         0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
2060         0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
2061         0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
2062         0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
2063         0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
2064         0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
2065         0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
2066         0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
2067         0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
2068         0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
2069         0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
2070         0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
2071         0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
2072         0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
2073         0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
2074     };
2075     /* md4 without hash oid */
2076     BYTE abSignatureMD4NoOID[128] = {
2077         0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
2078         0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
2079         0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
2080         0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
2081         0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
2082         0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
2083         0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
2084         0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
2085         0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
2086         0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
2087         0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
2088         0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
2089         0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
2090         0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
2091         0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
2092         0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
2093     };
2094     /* md5 with hash oid */
2095     BYTE abSignatureMD5[128] = {
2096         0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
2097         0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
2098         0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
2099         0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
2100         0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
2101         0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
2102         0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
2103         0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
2104         0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
2105         0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
2106         0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
2107         0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
2108         0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
2109         0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
2110         0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
2111         0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
2112     };
2113     /* md5 without hash oid */
2114     BYTE abSignatureMD5NoOID[128] = {
2115         0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
2116         0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
2117         0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
2118         0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
2119         0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
2120         0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
2121         0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
2122         0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
2123         0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
2124         0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
2125         0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
2126         0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
2127         0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
2128         0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
2129         0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
2130         0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
2131     };
2132     /* sha with hash oid */
2133     BYTE abSignatureSHA[128] = {
2134         0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
2135         0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
2136         0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
2137         0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
2138         0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
2139         0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
2140         0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
2141         0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
2142         0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
2143         0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
2144         0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
2145         0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
2146         0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
2147         0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
2148         0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
2149         0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
2150     };
2151     /* sha without hash oid */
2152     BYTE abSignatureSHANoOID[128] = {
2153         0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
2154         0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
2155         0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
2156         0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
2157         0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
2158         0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
2159         0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
2160         0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
2161         0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
2162         0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
2163         0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
2164         0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
2165         0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
2166         0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
2167         0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
2168         0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
2169     };
2170 
2171     result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
2172     ok(result, "%08x\n", GetLastError());
2173     if (!result) return;
2174 
2175     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
2176     ok(result, "%08x\n", GetLastError());
2177     if (!result) return;
2178 
2179     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
2180     ok(result, "%08x\n", GetLastError());
2181     if (!result) return;
2182 
2183     /*check that a NULL pointer signature is correctly handled*/
2184     result = CryptVerifySignatureA(hHash, NULL, 128, hPubSignKey, NULL, 0);
2185     ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
2186      "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
2187     if (result) return;
2188 
2189     /* check that we get a bad signature error when the signature is too short*/
2190     SetLastError(0xdeadbeef);
2191     result = CryptVerifySignatureA(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
2192     ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
2193      broken(result), /* Win9x, WinMe, NT4 */
2194      "Expected NTE_BAD_SIGNATURE, got %08x\n",  GetLastError());
2195 
2196     result = CryptVerifySignatureA(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
2197     ok(result, "%08x\n", GetLastError());
2198     if (!result) return;
2199 
2200     /* It seems that CPVerifySignature doesn't care about the OID at all. */
2201     result = CryptVerifySignatureA(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
2202     ok(result, "%08x\n", GetLastError());
2203     if (!result) return;
2204 
2205     result = CryptVerifySignatureA(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
2206     ok(result, "%08x\n", GetLastError());
2207     if (!result) return;
2208 
2209     CryptDestroyHash(hHash);
2210 
2211     result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
2212     ok(result, "%08x\n", GetLastError());
2213     if (!result) return;
2214 
2215     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
2216     ok(result, "%08x\n", GetLastError());
2217     if (!result) return;
2218 
2219     result = CryptVerifySignatureA(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
2220     ok(result, "%08x\n", GetLastError());
2221     if (!result) return;
2222 
2223     result = CryptVerifySignatureA(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, 0);
2224     ok(result, "%08x\n", GetLastError());
2225     if (!result) return;
2226 
2227     result = CryptVerifySignatureA(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
2228     ok(result, "%08x\n", GetLastError());
2229     if (!result) return;
2230 
2231     CryptDestroyHash(hHash);
2232 
2233     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
2234     ok(result, "%08x\n", GetLastError());
2235     if (!result) return;
2236 
2237     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
2238     ok(result, "%08x\n", GetLastError());
2239     if (!result) return;
2240 
2241     result = CryptVerifySignatureA(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
2242     ok(result, "%08x\n", GetLastError());
2243     if (!result) return;
2244 
2245     result = CryptVerifySignatureA(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, 0);
2246     ok(result, "%08x\n", GetLastError());
2247     if (!result) return;
2248 
2249     result = CryptVerifySignatureA(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
2250     ok(result, "%08x\n", GetLastError());
2251     if (!result) return;
2252 
2253     CryptDestroyHash(hHash);
2254 
2255     result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
2256     ok(result, "%08x\n", GetLastError());
2257     if (!result) return;
2258 
2259     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
2260     ok(result, "%08x\n", GetLastError());
2261     if (!result) return;
2262 
2263     result = CryptVerifySignatureA(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
2264     ok(result, "%08x\n", GetLastError());
2265     if (!result) return;
2266 
2267     result = CryptVerifySignatureA(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, 0);
2268     ok(result, "%08x\n", GetLastError());
2269     if (!result) return;
2270 
2271     result = CryptVerifySignatureA(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
2272     ok(result, "%08x\n", GetLastError());
2273     if (!result) return;
2274 
2275     CryptDestroyHash(hHash);
2276     CryptDestroyKey(hPubSignKey);
2277 }
2278 
2279 static void test_rsa_encrypt(void)
2280 {
2281     HCRYPTKEY hRSAKey;
2282     BYTE abData[2048] = "Wine rocks!";
2283     BOOL result;
2284     DWORD dwVal, dwLen;
2285     DWORD err;
2286 
2287     /* It is allowed to use the key exchange key for encryption/decryption */
2288     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
2289     ok (result, "%08x\n", GetLastError());
2290     if (!result) return;
2291 
2292     dwLen = 12;
2293     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
2294     if(!ENHANCED_PROV && !result && GetLastError() == NTE_BAD_KEY)
2295     {
2296         CryptDestroyKey(hRSAKey);
2297         return;
2298     }
2299     ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
2300     ok(dwLen == 128, "Unexpected length %d\n", dwLen);
2301     /* PKCS1 V1.5 */
2302     dwLen = 12;
2303     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
2304     ok (result, "%08x\n", GetLastError());
2305     if (!result) return;
2306 
2307     result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
2308     ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
2309 
2310     /* OAEP, RFC 8017 PKCS #1 V2.2 */
2311     /* Test minimal buffer length requirement */
2312     dwLen = 1;
2313     SetLastError(0xdeadbeef);
2314     result = CryptEncrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen, 20 * 2 + 2);
2315     err = GetLastError();
2316     ok(!result && err == ERROR_MORE_DATA, "%08x\n", err);
2317 
2318     /* Test data length limit */
2319     dwLen = sizeof(abData) - (20 * 2 + 2) + 1;
2320     result = CryptEncrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen, (DWORD)sizeof(abData));
2321     err = GetLastError();
2322     ok(!result && err == NTE_BAD_LEN, "%08x\n", err);
2323 
2324     /* Test malformed data */
2325     dwLen = 12;
2326     SetLastError(0xdeadbeef);
2327     memcpy(abData, "Wine rocks!", dwLen);
2328     result = CryptDecrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen);
2329     err = GetLastError();
2330     /* NTE_DOUBLE_ENCRYPT on xp or 2003 */
2331     ok(!result && (err == NTE_BAD_DATA || broken(err == NTE_DOUBLE_ENCRYPT)), "%08x\n", err);
2332 
2333     /* Test decrypt with insufficient buffer */
2334     dwLen = 12;
2335     SetLastError(0xdeadbeef);
2336     memcpy(abData, "Wine rocks!", 12);
2337     result = CryptEncrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen, (DWORD)sizeof(abData));
2338     ok(result, "%08x\n", GetLastError());
2339     dwLen = 11;
2340     SetLastError(0xdeadbeef);
2341     result = CryptDecrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen);
2342     err = GetLastError();
2343     /* broken on xp or 2003 */
2344     ok((!result && dwLen == 11 && err == NTE_BAD_DATA) || broken(result == TRUE && dwLen == 12 && err == ERROR_NO_TOKEN),
2345        "%08x %d %08x\n", result, dwLen, err);
2346 
2347     /* Test normal encryption and decryption */
2348     dwLen = 12;
2349     memcpy(abData, "Wine rocks!", dwLen);
2350     result = CryptEncrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen, (DWORD)sizeof(abData));
2351     ok(result, "%08x\n", GetLastError());
2352     result = CryptDecrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen);
2353     ok(result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
2354 
2355     dwVal = 0xdeadbeef;
2356     dwLen = sizeof(DWORD);
2357     result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2358     ok(result, "%08x\n", GetLastError());
2359     ok(dwVal ==
2360         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2361         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2362         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2363         " got %08x\n", dwVal);
2364 
2365     /* An RSA key doesn't support salt */
2366     result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
2367     ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == NTE_NOT_FOUND /* Win7 */),
2368        "expected NTE_BAD_KEY or NTE_NOT_FOUND, got %08x\n", GetLastError());
2369 
2370     /* The key exchange key's public key may be exported.. */
2371     result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2372     ok(result, "%08x\n", GetLastError());
2373     /* but its private key may not be. */
2374     SetLastError(0xdeadbeef);
2375     result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2376     ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
2377         broken(result), /* Win9x/NT4 */
2378         "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
2379     /* Setting the permissions of the key exchange key isn't allowed, either. */
2380     dwVal |= CRYPT_EXPORT;
2381     SetLastError(0xdeadbeef);
2382     result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2383     ok(!result &&
2384         (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
2385         "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
2386 
2387     CryptDestroyKey(hRSAKey);
2388 
2389     /* It is not allowed to use the signature key for encryption/decryption */
2390     result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
2391     ok (result, "%08x\n", GetLastError());
2392     if (!result) return;
2393 
2394     dwVal = 0xdeadbeef;
2395     dwLen = sizeof(DWORD);
2396     result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2397     ok(result, "%08x\n", GetLastError());
2398     ok(dwVal ==
2399         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2400         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2401         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2402         " got %08x\n", dwVal);
2403 
2404     /* The signature key's public key may also be exported.. */
2405     result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2406     ok(result, "%08x\n", GetLastError());
2407     /* but its private key may not be. */
2408     SetLastError(0xdeadbeef);
2409     result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2410     ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
2411         broken(result), /* Win9x/NT4 */
2412         "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
2413     /* Setting the permissions of the signature key isn't allowed, either. */
2414     dwVal |= CRYPT_EXPORT;
2415     SetLastError(0xdeadbeef);
2416     result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2417     ok(!result &&
2418         (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_FLAGS),
2419         "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
2420 
2421     dwLen = 12;
2422     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
2423     ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
2424 
2425     CryptDestroyKey(hRSAKey);
2426 }
2427 
2428 static void test_import_export(void)
2429 {
2430     DWORD dwLen, dwDataLen, dwVal;
2431     HCRYPTKEY hPublicKey, hPrivKey;
2432     BOOL result;
2433     ALG_ID algID;
2434     BYTE emptyKey[2048], *exported_key, *exported_key2;
2435     static BYTE abPlainPublicKey[84] = {
2436         0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
2437         0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
2438         0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
2439         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2440         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2441         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2442         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2443         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2444         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2445         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2446         0x11, 0x11, 0x11, 0x11
2447     };
2448     static BYTE priv_key_with_high_bit[] = {
2449         0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2450         0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
2451         0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
2452         0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
2453         0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
2454         0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
2455         0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
2456         0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
2457         0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
2458         0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
2459         0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
2460         0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2461         0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2462         0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2463         0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2464         0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2465         0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2466         0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2467         0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2468         0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2469         0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2470         0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2471         0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2472         0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2473         0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2474         0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2475         0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2476         0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2477         0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2478         0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2479         0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2480         0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2481         0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2482         0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2483         0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2484         0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2485         0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2486         0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2487         0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2488         0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2489         0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2490         0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2491         0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2492         0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2493         0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2494         0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2495         0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2496         0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2497         0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2498         0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2499         0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2500         0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2501         0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2502         0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2503         0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2504         0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2505         0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2506         0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2507         0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2508         0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2509         0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2510         0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2511         0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2512         0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2513         0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2514         0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2515         0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2516         0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2517         0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2518         0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2519         0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2520         0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2521         0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2522         0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2523         0xb6, 0x5f, 0x01, 0x5e
2524     };
2525     static const BYTE expected_exported_priv_key[] = {
2526         0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2527         0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
2528         0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
2529         0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
2530         0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
2531         0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
2532         0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
2533         0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
2534         0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
2535         0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
2536         0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
2537         0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2538         0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2539         0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2540         0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2541         0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2542         0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2543         0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2544         0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2545         0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2546         0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2547         0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2548         0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2549         0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2550         0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2551         0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2552         0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2553         0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2554         0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2555         0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2556         0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2557         0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2558         0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2559         0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2560         0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2561         0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2562         0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2563         0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2564         0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2565         0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2566         0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2567         0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2568         0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2569         0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2570         0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2571         0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2572         0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2573         0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2574         0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2575         0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2576         0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2577         0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2578         0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2579         0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2580         0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2581         0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2582         0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2583         0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2584         0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2585         0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2586         0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2587         0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2588         0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2589         0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2590         0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2591         0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2592         0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2593         0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2594         0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2595         0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2596         0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2597         0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2598         0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2599         0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2600         0xb6, 0x5f, 0x01, 0x5e
2601     };
2602 
2603     dwLen=84;
2604     result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
2605     ok(result, "failed to import the public key\n");
2606 
2607     dwDataLen=sizeof(algID);
2608     result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
2609     ok(result, "failed to get the KP_ALGID from the imported public key\n");
2610     ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
2611 
2612     dwVal = 0xdeadbeef;
2613     dwDataLen = sizeof(DWORD);
2614     result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
2615     ok(result, "%08x\n", GetLastError());
2616     ok(dwVal ==
2617         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
2618         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2619         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2620         " got %08x\n", dwVal);
2621     result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
2622     ok(result, "failed to export the fresh imported public key\n");
2623     ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
2624     ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
2625 
2626     CryptDestroyKey(hPublicKey);
2627 
2628     /* imports into AT_SIGNATURE key container */
2629     result = CryptImportKey(hProv, priv_key_with_high_bit,
2630         sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
2631     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2632 
2633     result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
2634     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2635     exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2636     result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
2637         &dwDataLen);
2638     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2639 
2640     ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
2641         dwDataLen);
2642     ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
2643         "unexpected value\n");
2644 
2645     HeapFree(GetProcessHeap(), 0, exported_key);
2646 
2647     CryptDestroyKey(hPrivKey);
2648 
2649     /* imports into AT_KEYEXCHANGE key container */
2650     result = CryptImportKey(hProv, abPlainPrivateKey,
2651                             sizeof(abPlainPrivateKey), 0, 0, &hPrivKey);
2652     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2653 
2654     result = CryptExportKey(hPrivKey, 0, PUBLICKEYBLOB, 0, NULL, &dwDataLen);
2655     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2656     exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2657     result = CryptExportKey(hPrivKey, 0, PUBLICKEYBLOB, 0, exported_key,
2658         &dwDataLen);
2659     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2660     CryptDestroyKey(hPrivKey);
2661 
2662     /* getting the public key from AT_KEYEXCHANGE, and compare it */
2663     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hPrivKey);
2664     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2665     result = CryptExportKey(hPrivKey, 0, PUBLICKEYBLOB, 0, NULL, &dwDataLen);
2666     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2667     exported_key2 = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2668     result = CryptExportKey(hPrivKey, 0, PUBLICKEYBLOB, 0, exported_key2,
2669         &dwDataLen);
2670     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2671     CryptDestroyKey(hPrivKey);
2672 
2673     result = !memcmp(exported_key, exported_key2, dwDataLen);
2674     ok(result, "unexpected value\n");
2675     if (!result && winetest_debug > 1) {
2676         trace("Expected public key (%u):\n", dwDataLen);
2677         trace_hex(exported_key, dwDataLen);
2678         trace("AT_KEYEXCHANGE public key (%u):\n", dwDataLen);
2679         trace_hex(exported_key2, dwDataLen);
2680     }
2681     HeapFree(GetProcessHeap(), 0, exported_key2);
2682 
2683     /* importing a public key doesn't update key container at all */
2684     result = CryptImportKey(hProv, abPlainPublicKey,
2685                             sizeof(abPlainPublicKey), 0, 0, &hPublicKey);
2686     ok(result, "failed to import the public key\n");
2687     CryptDestroyKey(hPublicKey);
2688 
2689     /* getting the public key again, and compare it */
2690     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hPrivKey);
2691     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2692     result = CryptExportKey(hPrivKey, 0, PUBLICKEYBLOB, 0, NULL, &dwDataLen);
2693     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2694     exported_key2 = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2695     result = CryptExportKey(hPrivKey, 0, PUBLICKEYBLOB, 0, exported_key2,
2696         &dwDataLen);
2697     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2698     CryptDestroyKey(hPrivKey);
2699 
2700     result = !memcmp(exported_key, exported_key2, dwDataLen);
2701     ok(result, "unexpected value\n");
2702     if (!result && winetest_debug > 1) {
2703         trace("Expected public key (%u):\n", dwDataLen);
2704         trace_hex(exported_key, dwDataLen);
2705         trace("AT_KEYEXCHANGE public key (%u):\n", dwDataLen);
2706         trace_hex(exported_key2, dwDataLen);
2707     }
2708 
2709     HeapFree(GetProcessHeap(), 0, exported_key);
2710     HeapFree(GetProcessHeap(), 0, exported_key2);
2711 }
2712 
2713 static void test_import_hmac(void)
2714 {
2715     /* Test cases from RFC 2202, section 3 */
2716     static const struct rfc2202_test_case {
2717         const char *key;
2718         DWORD key_len;
2719         const char *data;
2720         const DWORD data_len;
2721         const char *digest;
2722     } cases[] = {
2723         { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
2724           "\x0b\x0b\x0b\x0b", 20,
2725           "Hi There", 8,
2726           "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e"
2727           "\xf1\x46\xbe\x00" },
2728         { "Jefe", 4,
2729           "what do ya want for nothing?", 28,
2730           "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c"
2731           "\x25\x9a\x7c\x79" },
2732         { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2733           "\xaa\xaa\xaa\xaa", 20,
2734           "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2735           "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2736           "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2737           "\xdd\xdd", 50,
2738           "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f"
2739           "\x63\xf1\x75\xd3" },
2740         { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
2741           "\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25,
2742           "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2743           "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2744           "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2745           "\xcd\xcd", 50,
2746           "\x4c\x90\x07\xF4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c"
2747           "\x2d\x72\x35\xda" },
2748         { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
2749           "\x0c\x0c\x0c\x0c", 20,
2750           "Test With Truncation", 20,
2751           "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32"
2752           "\x4a\x9a\x5a\x04" },
2753         { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2754           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2755           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2756           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2757           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2758           80,
2759           "Test Using Larger Than Block-Size Key - Hash Key First", 54,
2760           "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55"
2761           "\xed\x40\x21\x12" },
2762         { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2763           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2764           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2765           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2766           "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2767           80,
2768           "Test Using Larger Than Block-Size Key and Larger "
2769           "Than One Block-Size Data", 73,
2770           "\xe8\xe9\x9D\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08"
2771           "\xbb\xff\x1a\x91" }
2772     };
2773     DWORD i;
2774 
2775     for (i = 0; i < ARRAY_SIZE(cases); i++)
2776     {
2777         const struct rfc2202_test_case *test_case = &cases[i];
2778         DWORD size = sizeof(BLOBHEADER) + sizeof(DWORD) + test_case->key_len;
2779         BYTE *blob = HeapAlloc(GetProcessHeap(), 0, size);
2780 
2781         if (blob)
2782         {
2783             BLOBHEADER *header = (BLOBHEADER *)blob;
2784             DWORD *key_len = (DWORD *)(header + 1);
2785             BYTE *key_bytes = (BYTE *)(key_len + 1);
2786             BOOL result;
2787             HCRYPTKEY key;
2788 
2789             header->bType = PLAINTEXTKEYBLOB;
2790             header->bVersion = CUR_BLOB_VERSION;
2791             header->reserved = 0;
2792             header->aiKeyAlg = CALG_RC2;
2793             *key_len = test_case->key_len;
2794             memcpy(key_bytes, test_case->key, *key_len);
2795             result = CryptImportKey(hProv, blob, size, 0, CRYPT_IPSEC_HMAC_KEY, &key);
2796             ok(result || broken(GetLastError() == NTE_BAD_FLAGS /* Win2k */), "CryptImportKey failed on test case %d: %08x\n", i, GetLastError());
2797             if (result)
2798             {
2799                 HCRYPTHASH hash;
2800                 HMAC_INFO hmac_info = { CALG_SHA1, 0 };
2801                 BYTE digest[20];
2802                 DWORD digest_size;
2803 
2804                 result = CryptCreateHash(hProv, CALG_HMAC, key, 0, &hash);
2805                 ok(result, "CryptCreateHash failed on test case %d: %08x\n", i, GetLastError());
2806                 result = CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&hmac_info, 0);
2807                 ok(result, "CryptSetHashParam failed on test case %d: %08x\n", i, GetLastError());
2808                 result = CryptHashData(hash, (const BYTE *)test_case->data, test_case->data_len, 0);
2809                 ok(result, "CryptHashData failed on test case %d: %08x\n", i, GetLastError());
2810                 digest_size = sizeof(digest);
2811                 result = CryptGetHashParam(hash, HP_HASHVAL, digest, &digest_size, 0);
2812                 ok(result, "CryptGetHashParam failed on test case %d: %08x\n", i, GetLastError());
2813                 ok(!memcmp(digest, test_case->digest, sizeof(digest)), "Unexpected value on test case %d\n", i);
2814                 CryptDestroyHash(hash);
2815                 CryptDestroyKey(key);
2816             }
2817             HeapFree(GetProcessHeap(), 0, blob);
2818         }
2819     }
2820 }
2821 
2822 static void test_schannel_provider(void)
2823 {
2824     HCRYPTPROV hProv;
2825     HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
2826     HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
2827     BOOL result;
2828     DWORD dwLen;
2829     SCHANNEL_ALG saSChannelAlg;
2830     CRYPT_DATA_BLOB data_blob;
2831     HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
2832     BYTE abTLS1Master[140] = {
2833         0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
2834         0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
2835         0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
2836         0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
2837         0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
2838         0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
2839         0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
2840         0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
2841         0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
2842         0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
2843         0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
2844         0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
2845         0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
2846         0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
2847         0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
2848         0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
2849         0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
2850         0xd3, 0x1e, 0x82, 0xb3
2851     };
2852     BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2853     BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2854     BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2855     BYTE abClientFinished[16] = "client finished";
2856     BYTE abData[16] = "Wine rocks!";
2857     BYTE abMD5Hash[16];
2858     static const BYTE abEncryptedData[16] = {
2859         0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2860         0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
2861     };
2862     static const BYTE abPRF[16] = {
2863         0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2864         0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2865     };
2866     static const BYTE abMD5[16] = {
2867         0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2868         0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2869     };
2870 
2871     result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
2872     if (!result)
2873     {
2874         win_skip("no PROV_RSA_SCHANNEL support\n");
2875         return;
2876     }
2877     ok (result, "%08x\n", GetLastError());
2878     if (result)
2879         CryptReleaseContext(hProv, 0);
2880 
2881     result = CryptAcquireContextA(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
2882     ok (result, "%08x\n", GetLastError());
2883     if (!result) return;
2884 
2885     /* To get deterministic results, we import the TLS1 master secret (which
2886      * is typically generated from a random generator). Therefore, we need
2887      * an RSA key. */
2888     dwLen = (DWORD)sizeof(abPlainPrivateKey);
2889     result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
2890     ok (result, "%08x\n", GetLastError());
2891     if (!result) return;
2892 
2893     dwLen = (DWORD)sizeof(abTLS1Master);
2894     result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
2895     ok (result, "%08x\n", GetLastError());
2896     if (!result) return;
2897 
2898     /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2899      * (Keys can only be derived from hashes, not from other keys.)
2900      * The hash can't be created yet because the key doesn't have the client
2901      * random or server random set.
2902      */
2903     result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2904     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER,
2905         "expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2906 
2907     /* Setting the TLS1 client and server random parameters, as well as the
2908      * MAC and encryption algorithm parameters. */
2909     data_blob.cbData = 33;
2910     data_blob.pbData = abClientSecret;
2911     result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
2912     ok (result, "%08x\n", GetLastError());
2913     if (!result) return;
2914 
2915     data_blob.cbData = 33;
2916     data_blob.pbData = abServerSecret;
2917     result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
2918     ok (result, "%08x\n", GetLastError());
2919     if (!result) return;
2920 
2921     result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2922     ok (result ||
2923         broken(!result), /* Windows 8 and greater */
2924         "%08x\n", GetLastError());
2925     if (!result)
2926     {
2927         win_skip("Broken TLS1 hash creation\n");
2928         CryptDestroyKey(hRSAKey);
2929         CryptDestroyKey(hMasterSecret);
2930         CryptReleaseContext(hProv, 0);
2931         CryptAcquireContextA(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
2932         return;
2933     }
2934 
2935     /* Deriving the server write encryption key from the master hash can't
2936      * succeed before the encryption key algorithm is set.
2937      */
2938     result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2939     ok (!result && GetLastError() == NTE_BAD_FLAGS,
2940         "expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2941 
2942     CryptDestroyHash(hMasterHash);
2943 
2944     saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
2945     saSChannelAlg.Algid = CALG_DES;
2946     saSChannelAlg.cBits = 64;
2947     saSChannelAlg.dwFlags = 0;
2948     saSChannelAlg.dwReserved = 0;
2949     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2950     ok (result, "%08x\n", GetLastError());
2951     if (!result) return;
2952 
2953     saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
2954     saSChannelAlg.Algid = CALG_MD5;
2955     saSChannelAlg.cBits = 128;
2956     saSChannelAlg.dwFlags = 0;
2957     saSChannelAlg.dwReserved = 0;
2958     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2959     ok (result, "%08x\n", GetLastError());
2960     if (!result) return;
2961 
2962     result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2963     ok (result, "%08x\n", GetLastError());
2964     if (!result) return;
2965 
2966     /* Deriving the server write encryption key from the master hash */
2967     result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2968     ok (result, "%08x\n", GetLastError());
2969     if (!result) return;
2970 
2971     /* Encrypting some data with the server write encryption key and checking the result. */
2972     dwLen = 12;
2973     result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
2974     ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
2975 
2976     /* Second test case: Test the TLS1 pseudo random number function. */
2977     result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
2978     ok (result, "%08x\n", GetLastError());
2979     if (!result) return;
2980 
2981     /* Set the label and seed parameters for the random number function */
2982     data_blob.cbData = 36;
2983     data_blob.pbData = abHashedHandshakes;
2984     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
2985     ok (result, "%08x\n", GetLastError());
2986     if (!result) return;
2987 
2988     data_blob.cbData = 15;
2989     data_blob.pbData = abClientFinished;
2990     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
2991     ok (result, "%08x\n", GetLastError());
2992     if (!result) return;
2993 
2994     /* Generate some pseudo random bytes and check if they are correct. */
2995     dwLen = (DWORD)sizeof(abData);
2996     result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2997     ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
2998         "%08x\n", GetLastError());
2999 
3000     /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
3001      * Hash some data with the HMAC. Compare results. */
3002     result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
3003     ok (result, "%08x\n", GetLastError());
3004     if (!result) return;
3005 
3006     result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
3007     ok (result, "%08x\n", GetLastError());
3008     if (!result) return;
3009 
3010     result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
3011     ok (result, "%08x\n", GetLastError());
3012     if (!result) return;
3013 
3014     result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
3015     ok (result, "%08x\n", GetLastError());
3016     if (!result) return;
3017 
3018     dwLen = (DWORD)sizeof(abMD5Hash);
3019     result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
3020     ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
3021 
3022     CryptDestroyHash(hHMAC);
3023     CryptDestroyHash(hTLS1PRF);
3024     CryptDestroyHash(hMasterHash);
3025     CryptDestroyKey(hServerWriteMACKey);
3026     CryptDestroyKey(hServerWriteKey);
3027     CryptDestroyKey(hRSAKey);
3028     CryptDestroyKey(hMasterSecret);
3029     CryptReleaseContext(hProv, 0);
3030     CryptAcquireContextA(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
3031 }
3032 
3033 /* Test that a key can be used to encrypt data and exported, and that, when
3034  * the exported key is imported again, can be used to decrypt the original
3035  * data again.
3036  */
3037 static void test_rsa_round_trip(void)
3038 {
3039     static const char test_string[] = "Well this is a fine how-do-you-do.";
3040     HCRYPTPROV prov;
3041     HCRYPTKEY signKey, keyExchangeKey;
3042     BOOL result;
3043     BYTE data[256], *exportedKey;
3044     DWORD dataLen, keyLen;
3045 
3046     CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3047      CRYPT_DELETEKEYSET);
3048 
3049     /* Generate a new key... */
3050     result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3051      CRYPT_NEWKEYSET);
3052     ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3053     result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
3054     ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
3055     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
3056     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
3057     /* encrypt some data with it... */
3058     memcpy(data, test_string, strlen(test_string) + 1);
3059     dataLen = strlen(test_string) + 1;
3060     result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
3061                           sizeof(data));
3062     ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
3063        broken(GetLastError() == NTE_PERM /* NT4 */),
3064        "CryptEncrypt failed: %08x\n", GetLastError());
3065     /* export the key... */
3066     result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
3067                             &keyLen);
3068     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
3069     exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
3070     result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
3071                             &keyLen);
3072     ok(result, "CryptExportKey failed: %08x\n", GetLastError());
3073     /* destroy the key... */
3074     CryptDestroyKey(keyExchangeKey);
3075     CryptDestroyKey(signKey);
3076     /* import the key again... */
3077     result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
3078     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
3079     HeapFree(GetProcessHeap(), 0, exportedKey);
3080     /* and decrypt the data encrypted with the original key with the imported
3081      * key.
3082      */
3083     result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
3084     ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
3085        broken(GetLastError() == NTE_PERM /* NT4 */),
3086        "CryptDecrypt failed: %08x\n", GetLastError());
3087     if (result)
3088     {
3089         ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
3090         ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
3091     }
3092     CryptDestroyKey(keyExchangeKey);
3093     CryptReleaseContext(prov, 0);
3094 
3095     CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3096      CRYPT_DELETEKEYSET);
3097 }
3098 
3099 static void test_enum_container(void)
3100 {
3101     BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
3102     DWORD dwBufferLen;
3103     BOOL result, fFound = FALSE;
3104 
3105     /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
3106      * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
3107     SetLastError(0xdeadbeef);
3108     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
3109     ok (result, "%08x\n", GetLastError());
3110     ok (dwBufferLen == MAX_PATH + 1 ||
3111         broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
3112         "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
3113 
3114     /* If the result fits into abContainerName dwBufferLen is left untouched */
3115     dwBufferLen = (DWORD)sizeof(abContainerName);
3116     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
3117     ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
3118 
3119     /* We only check, if the currently open 'winetest' container is among the enumerated. */
3120     do {
3121         if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
3122         dwBufferLen = (DWORD)sizeof(abContainerName);
3123     } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
3124 
3125     ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
3126 }
3127 
3128 static BYTE signBlob[] = {
3129 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
3130 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
3131 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
3132 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
3133 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
3134 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
3135 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
3136 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
3137 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
3138 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
3139 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
3140 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
3141 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
3142 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
3143 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
3144 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
3145 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
3146 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
3147 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
3148 0xb6,0x85,0x86,0x07 };
3149 
3150 static void test_null_provider(void)
3151 {
3152     HCRYPTPROV prov;
3153     HCRYPTKEY key;
3154     BOOL result;
3155     DWORD keySpec, dataLen,dwParam;
3156     char szName[MAX_PATH];
3157 
3158     result = CryptAcquireContextA(NULL, szContainer, NULL, 0, 0);
3159     ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
3160      "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
3161     result = CryptAcquireContextA(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
3162     ok(!result && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
3163      "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
3164     result = CryptAcquireContextA(NULL, szContainer, NULL, PROV_RSA_FULL,
3165      CRYPT_DELETEKEYSET);
3166     ok(!result && ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_KEYSET),
3167      "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
3168     result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3169      CRYPT_DELETEKEYSET);
3170     ok(!result && GetLastError() == NTE_BAD_KEYSET,
3171      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
3172     result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
3173     ok(!result && GetLastError() == NTE_BAD_KEYSET,
3174      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
3175 
3176     /* Delete the default container. */
3177     CryptAcquireContextA(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
3178     /* Once you've deleted the default container you can't open it as if it
3179      * already exists.
3180      */
3181     result = CryptAcquireContextA(&prov, NULL, NULL, PROV_RSA_FULL, 0);
3182     ok(!result && GetLastError() == NTE_BAD_KEYSET,
3183      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
3184     /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
3185     result = CryptAcquireContextA(&prov, NULL, NULL, PROV_RSA_FULL,
3186      CRYPT_VERIFYCONTEXT);
3187     ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3188     if (!result) return;
3189     dataLen = sizeof(keySpec);
3190     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
3191     if (result)
3192         ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
3193          "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
3194     /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
3195      * supported, you can't get the keys from this container.
3196      */
3197     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
3198     ok(!result && GetLastError() == NTE_NO_KEY,
3199      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3200     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
3201     ok(!result && GetLastError() == NTE_NO_KEY,
3202      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3203     result = CryptReleaseContext(prov, 0);
3204     ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
3205     /* You can create a new default container. */
3206     result = CryptAcquireContextA(&prov, NULL, NULL, PROV_RSA_FULL,
3207      CRYPT_NEWKEYSET);
3208     ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3209     /* But you still can't get the keys (until one's been generated.) */
3210     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
3211     ok(!result && GetLastError() == NTE_NO_KEY,
3212      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3213     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
3214     ok(!result && GetLastError() == NTE_NO_KEY,
3215      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3216     CryptReleaseContext(prov, 0);
3217     CryptAcquireContextA(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
3218 
3219     CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3220      CRYPT_DELETEKEYSET);
3221     result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
3222     ok(!result && GetLastError() == NTE_BAD_KEYSET,
3223      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
3224     result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3225      CRYPT_VERIFYCONTEXT);
3226     ok(!result && GetLastError() == NTE_BAD_FLAGS,
3227      "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
3228     result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3229      CRYPT_NEWKEYSET);
3230     ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3231     if (!result) return;
3232     /* Test provider parameters getter */
3233     dataLen = sizeof(dwParam);
3234     result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
3235     ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
3236         "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
3237     dataLen = sizeof(dwParam);
3238     result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
3239     ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
3240         "Expected 0, got 0x%08X\n",dwParam);
3241     dataLen = sizeof(dwParam);
3242     result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
3243     ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
3244         "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
3245     dataLen = sizeof(keySpec);
3246     SetLastError(0xdeadbeef);
3247     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
3248     if (!result && GetLastError() == NTE_BAD_TYPE)
3249         skip("PP_KEYSPEC is not supported (win9x or NT)\n");
3250     else
3251         ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
3252             "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
3253     /* PP_CONTAINER parameter */
3254     dataLen = sizeof(szName);
3255     result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
3256     ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
3257         "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
3258         (result)? "TRUE":"FALSE",GetLastError(),dataLen);
3259     /* PP_UNIQUE_CONTAINER parameter */
3260     dataLen = sizeof(szName);
3261     SetLastError(0xdeadbeef);
3262     result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
3263     if (!result && GetLastError() == NTE_BAD_TYPE)
3264     {
3265         skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
3266     }
3267     else
3268     {
3269         char container[MAX_PATH];
3270 
3271         ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
3272         uniquecontainer(container);
3273         todo_wine
3274         {
3275             ok(dataLen == strlen(container)+1 ||
3276                broken(dataLen == strlen(szContainer)+1) /* WinME */,
3277                "Expected a param length of 70, got %d\n", dataLen);
3278             ok(!strcmp(container, szName) ||
3279                broken(!strcmp(szName, szContainer)) /* WinME */,
3280                "Wrong container name : %s\n", szName);
3281         }
3282     }
3283     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
3284     ok(!result && GetLastError() == NTE_NO_KEY,
3285      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3286     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
3287     ok(!result && GetLastError() == NTE_NO_KEY,
3288      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3289 
3290     /* Importing a key exchange blob.. */
3291     result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
3292      0, 0, &key);
3293     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
3294     CryptDestroyKey(key);
3295     /* allows access to the key exchange key.. */
3296     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
3297     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
3298     CryptDestroyKey(key);
3299     /* but not to the private key. */
3300     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
3301     ok(!result && GetLastError() == NTE_NO_KEY,
3302      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3303     CryptReleaseContext(prov, 0);
3304     CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3305      CRYPT_DELETEKEYSET);
3306 
3307     /* Whereas importing a sign blob.. */
3308     result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3309      CRYPT_NEWKEYSET);
3310     ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3311     if (!result) return;
3312     result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
3313     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
3314     CryptDestroyKey(key);
3315     /* doesn't allow access to the key exchange key.. */
3316     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
3317     ok(!result && GetLastError() == NTE_NO_KEY,
3318      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3319     /* but does to the private key. */
3320     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
3321     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
3322     CryptDestroyKey(key);
3323     CryptReleaseContext(prov, 0);
3324 
3325     CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3326      CRYPT_DELETEKEYSET);
3327 
3328     /* Test for being able to get a key generated with CALG_RSA_SIGN. */
3329     result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3330      CRYPT_NEWKEYSET);
3331     ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3332     result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
3333     ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
3334     CryptDestroyKey(key);
3335     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
3336     ok(!result, "expected CryptGetUserKey to fail\n");
3337     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
3338     ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
3339     CryptDestroyKey(key);
3340     CryptReleaseContext(prov, 0);
3341 
3342     CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3343      CRYPT_DELETEKEYSET);
3344 
3345     /* Test for being able to get a key generated with CALG_RSA_KEYX. */
3346     result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3347      CRYPT_NEWKEYSET);
3348     ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3349     result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
3350     ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
3351     CryptDestroyKey(key);
3352     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
3353     ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
3354     CryptDestroyKey(key);
3355     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
3356     ok(!result, "expected CryptGetUserKey to fail\n");
3357     CryptReleaseContext(prov, 0);
3358 
3359     CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3360      CRYPT_DELETEKEYSET);
3361 
3362     /* test for the bug in accessing the user key in a container
3363      */
3364     result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3365      CRYPT_NEWKEYSET);
3366     ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3367     result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
3368     ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
3369     CryptDestroyKey(key);
3370     CryptReleaseContext(prov,0);
3371     result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,0);
3372     ok(result, "CryptAcquireContextA failed: 0x%08x\n", GetLastError());
3373     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
3374     ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
3375     CryptDestroyKey(key);
3376     CryptReleaseContext(prov, 0);
3377 
3378     CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3379      CRYPT_DELETEKEYSET);
3380 
3381     /* test the machine key set */
3382     CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3383      CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
3384     result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3385      CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
3386     ok(result, "CryptAcquireContextA with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
3387     CryptReleaseContext(prov, 0);
3388     result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3389      CRYPT_MACHINE_KEYSET);
3390     ok(result, "CryptAcquireContextA with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
3391     CryptReleaseContext(prov,0);
3392     result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3393        CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
3394     ok(result, "CryptAcquireContextA with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
3395 		GetLastError());
3396     result = CryptAcquireContextA(&prov, szContainer, NULL, PROV_RSA_FULL,
3397      CRYPT_MACHINE_KEYSET);
3398     ok(!result && GetLastError() == NTE_BAD_KEYSET ,
3399 	"Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
3400 
3401 }
3402 
3403 static void test_key_permissions(void)
3404 {
3405     HCRYPTKEY hKey1, hKey2;
3406     DWORD dwVal, dwLen;
3407     BOOL result;
3408 
3409     /* Create keys that are exportable */
3410     if (!init_base_environment(NULL, CRYPT_EXPORTABLE))
3411         return;
3412 
3413     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey1);
3414     ok (result, "%08x\n", GetLastError());
3415     if (!result) return;
3416 
3417     dwVal = 0xdeadbeef;
3418     dwLen = sizeof(DWORD);
3419     result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
3420     ok(result, "%08x\n", GetLastError());
3421     ok(dwVal ==
3422         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
3423         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
3424         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
3425         " got %08x\n", dwVal);
3426 
3427     /* The key exchange key's public key may be exported.. */
3428     result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
3429     ok(result, "%08x\n", GetLastError());
3430     /* and its private key may be too. */
3431     result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
3432     ok(result, "%08x\n", GetLastError());
3433     /* Turning off the key's export permissions is "allowed".. */
3434     dwVal &= ~CRYPT_EXPORT;
3435     result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
3436     ok(result ||
3437         broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
3438         broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
3439         "%08x\n", GetLastError());
3440     /* but it has no effect. */
3441     dwVal = 0xdeadbeef;
3442     dwLen = sizeof(DWORD);
3443     result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
3444     ok(result, "%08x\n", GetLastError());
3445     ok(dwVal ==
3446         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
3447         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
3448         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
3449         " got %08x\n", dwVal);
3450     /* Thus, changing the export flag of the key doesn't affect whether the key
3451      * may be exported.
3452      */
3453     result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
3454     ok(result, "%08x\n", GetLastError());
3455 
3456     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey2);
3457     ok (result, "%08x\n", GetLastError());
3458 
3459     /* A subsequent get of the same key, into a different handle, also doesn't
3460      * show that the permissions have been changed.
3461      */
3462     dwVal = 0xdeadbeef;
3463     dwLen = sizeof(DWORD);
3464     result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
3465     ok(result, "%08x\n", GetLastError());
3466     ok(dwVal ==
3467         (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
3468         broken(dwVal == 0xffffffff), /* Win9x/NT4 */
3469         "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
3470         " got %08x\n", dwVal);
3471 
3472     CryptDestroyKey(hKey2);
3473     CryptDestroyKey(hKey1);
3474 
3475     clean_up_base_environment();
3476 }
3477 
3478 static void test_key_initialization(void)
3479 {
3480     DWORD dwLen;
3481     HCRYPTPROV prov1, prov2;
3482     HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
3483     BOOL result;
3484     static BYTE abSessionKey[148] = {
3485         0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
3486         0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
3487         0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
3488         0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
3489         0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
3490         0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
3491         0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
3492         0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
3493         0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
3494         0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
3495         0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
3496         0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
3497         0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
3498         0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
3499         0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
3500         0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
3501         0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
3502         0x04, 0x8c, 0x49, 0x92
3503     };
3504 
3505     /* Like init_base_environment, but doesn't generate new keys, as they'll
3506      * be imported instead.
3507      */
3508     if (!CryptAcquireContextA(&prov1, szContainer, szProvider, PROV_RSA_FULL, 0))
3509     {
3510         result = CryptAcquireContextA(&prov1, szContainer, szProvider, PROV_RSA_FULL,
3511                                      CRYPT_NEWKEYSET);
3512         ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3513     }
3514     dwLen = (DWORD)sizeof(abPlainPrivateKey);
3515     result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
3516     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
3517 
3518     dwLen = (DWORD)sizeof(abSessionKey);
3519     result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
3520     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
3521 
3522     /* Once the key has been imported, subsequently acquiring a context with
3523      * the same name will allow retrieving the key.
3524      */
3525     result = CryptAcquireContextA(&prov2, szContainer, szProvider, PROV_RSA_FULL, 0);
3526     ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3527     result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
3528     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
3529     if (result) CryptDestroyKey(hKey);
3530     CryptReleaseContext(prov2, 0);
3531 
3532     CryptDestroyKey(hSessionKey);
3533     CryptDestroyKey(hKeyExchangeKey);
3534     CryptReleaseContext(prov1, 0);
3535     CryptAcquireContextA(&prov1, szContainer, NULL, PROV_RSA_FULL,
3536      CRYPT_DELETEKEYSET);
3537 }
3538 
3539 static void test_key_derivation(const char *prov)
3540 {
3541     HCRYPTKEY hKey;
3542     HCRYPTHASH hHash;
3543     BOOL result;
3544     unsigned char pbData[128], dvData[512];
3545     DWORD i, j, len, mode;
3546     struct _test
3547     {
3548         ALG_ID crypt_algo, hash_algo;
3549         int blocklen, hashlen, chain_mode;
3550         DWORD errorkey;
3551         const char *expected_hash, *expected_enc;
3552     } tests[] = {
3553         /* ================================================================== */
3554         { CALG_DES, CALG_MD2, 8, 16, CRYPT_MODE_CBC, 0,
3555           "\xBA\xBF\x93\xAE\xBC\x77\x45\xAA\x7E\x45\x69\xE5\x90\xE6\x04\x7F",
3556           "\x5D\xDA\x25\xA6\xB5\xC4\x43\xFB",
3557           /* 0 */
3558         },
3559         { CALG_3DES_112, CALG_MD2, 8, 16, CRYPT_MODE_CBC, 0,
3560           "\xDA\x4A\x9F\x5D\x2E\x7A\x3A\x4B\xBF\xDE\x47\x5B\x06\x84\x48\xA7",
3561           "\x6B\x18\x3B\xA1\x89\x27\xBF\xD4",
3562           /* 1 */
3563         },
3564         { CALG_3DES, CALG_MD2, 8, 16, CRYPT_MODE_CBC, 0,
3565           "\x38\xE5\x2E\x95\xA4\xA3\x73\x88\xF8\x1F\x87\xB7\x74\xB1\xA1\x56",
3566           "\x91\xAB\x17\xE5\xDA\x27\x11\x7D",
3567           /* 2 */
3568         },
3569         { CALG_RC2, CALG_MD2, 8, 16, CRYPT_MODE_CBC, 0,
3570           "\x7D\xA4\xB1\x10\x43\x26\x76\xB1\x0D\xB6\xE6\x9C\xA5\x8B\xCB\xE6",
3571           "\x7D\x45\x3D\x56\x00\xD7\xD1\x54",
3572           /* 3 */
3573         },
3574         { CALG_RC4, CALG_MD2, 4, 16, 0, 0,
3575           "\xFF\x32\xF1\x69\x62\xDE\xEB\x53\x8C\xFF\xA6\x92\x58\xA8\x22\xEA",
3576           "\xA9\x83\x73\xA9",
3577           /* 4 */
3578         },
3579         { CALG_RC5, CALG_MD2, 0, 16, 0, NTE_BAD_ALGID,
3580           "\x8A\xF2\xA3\xDA\xA5\x9A\x8B\x42\x4C\xE0\x2E\x00\xE5\x1E\x98\xE4",
3581           NULL,
3582           /* 5 */
3583         },
3584         { CALG_RSA_SIGN, CALG_MD2, 0, 16, 0, NTE_BAD_ALGID,
3585           "\xAE\xFE\xD6\xA5\x3E\x4B\xAC\xFA\x0E\x92\xC4\xC0\x06\xC9\x2B\xFD",
3586           NULL,
3587           /* 6 */
3588         },
3589         { CALG_RSA_KEYX, CALG_MD2, 0, 16, CRYPT_MODE_CBC, NTE_BAD_ALGID,
3590           "\x30\xF4\xBC\x33\x93\xF3\x58\x19\xD1\x2B\x73\x4A\x92\xC7\xFC\xD7",
3591           NULL,
3592           /* 7 */
3593         },
3594         { CALG_AES, CALG_MD2, 0, 16, 0, NTE_BAD_ALGID,
3595           "\x07\x3B\x12\xE9\x96\x93\x85\xD7\xEC\xF4\xB1\xAC\x89\x2D\xC6\x9A",
3596           NULL,
3597           /* 8 */
3598         },
3599         { CALG_AES_128, CALG_MD2, 16, 16, CRYPT_MODE_CBC, NTE_BAD_ALGID,
3600           "\xD2\x37\xE2\x49\xEB\x99\x23\xDA\x3E\x88\x55\x7E\x04\x5E\x15\x5D",
3601           "\xA1\x64\x3F\xFE\x99\x7F\x24\x13\x0C\xA9\x03\xEF\x9B\xC8\x1F\x2A",
3602           /* 9 */
3603         },
3604         { CALG_AES_192, CALG_MD2, 16, 16, CRYPT_MODE_CBC, NTE_BAD_ALGID,
3605           "\x3E\x74\xED\xBF\x23\xAB\x03\x09\xBB\xD3\xE3\xAB\xCA\x12\x72\x7F",
3606           "\x5D\xEC\xF8\x72\xB2\xA6\x4D\x5C\xEA\x38\x9E\xF0\x86\xB6\x79\x34",
3607           /* 10 */
3608         },
3609         { CALG_AES_256, CALG_MD2, 16, 16, CRYPT_MODE_CBC, NTE_BAD_ALGID,
3610           "\xBE\x9A\xE8\xF6\xCE\x79\x86\x5C\x1B\x01\x96\x4E\x5A\x8D\x09\x33",
3611           "\xD9\x4B\xC2\xE3\xCA\x89\x8B\x94\x0D\x87\xBB\xA2\xE8\x3D\x5C\x62",
3612           /* 11 */
3613         },
3614         /* ================================================================== */
3615         { CALG_DES, CALG_MD4, 8, 16, CRYPT_MODE_CBC, 0,
3616           "\xE8\x2F\x96\xC4\x6C\xC1\x91\xB4\x78\x40\x56\xD8\xA0\x25\xF5\x71",
3617           "\x21\x5A\xBD\x26\xB4\x3E\x86\x04",
3618           /* 12 */
3619         },
3620         { CALG_3DES_112, CALG_MD4, 8, 16, CRYPT_MODE_CBC, 0,
3621           "\x23\xBB\x6F\xE4\xB0\xF6\x35\xB6\x89\x2F\xEC\xDC\x06\xA9\xDF\x35",
3622           "\x9B\xE5\xD1\xEB\x8F\x13\x0B\xB3",
3623           /* 13 */
3624         },
3625         { CALG_3DES, CALG_MD4, 8, 16, CRYPT_MODE_CBC, 0,
3626           "\xE4\x72\x48\xC6\x6E\x38\x2F\x00\xC9\x2D\x01\x12\xB7\x8B\x64\x09",
3627           "\x7D\x5E\xAA\xEA\x10\xA4\xA4\x44",
3628           /* 14 */
3629         },
3630         { CALG_RC2, CALG_MD4, 8, 16, CRYPT_MODE_CBC, 0,
3631           "\xBF\x54\xDA\x3A\x56\x72\x0D\x9F\x30\x7D\x2F\x54\x13\xB2\xD7\xC6",
3632           "\x77\x42\x0E\xD2\x60\x29\x6F\x68",
3633           /* 15 */
3634         },
3635         { CALG_RC4, CALG_MD4, 4, 16, 0, 0,
3636           "\x9B\x74\x6D\x22\x11\x16\x05\x50\xA3\x75\x6B\xB2\x38\x8C\x2B\xC6",
3637           "\x5C\x7E\x99\x84",
3638           /* 16 */
3639         },
3640         { CALG_RC5, CALG_MD4, 0, 16, 0, NTE_BAD_ALGID,
3641           "\x51\xA8\x29\x8D\xE0\x36\xC1\xD3\x5E\x6A\x51\x4F\xE1\x65\xEE\xF1",
3642           NULL,
3643           /* 17 */
3644         },
3645         { CALG_RSA_SIGN, CALG_MD4, 0, 16, 0, NTE_BAD_ALGID,
3646           "\xA6\x83\x13\x4C\xB1\xAA\x06\x16\xE6\x4E\x7F\x0B\x8D\x19\xF5\x45",
3647           NULL,
3648           /* 18 */
3649         },
3650         { CALG_RSA_KEYX, CALG_MD4, 0, 16, CRYPT_MODE_CBC, NTE_BAD_ALGID,
3651           "\x04\x24\xC8\x64\x98\x84\xE3\x3A\x7B\x9C\x50\x3E\xE7\xC4\x89\x82",
3652           NULL,
3653           /* 19 */
3654         },
3655         { CALG_AES, CALG_MD4, 0, 16, 0, NTE_BAD_ALGID,
3656           "\xF6\xEF\x81\xF8\xF2\xA3\xF6\x11\xFE\xA4\x7D\xC1\xD2\xF7\x7C\xDC",
3657           NULL,
3658           /* 20 */
3659         },
3660         { CALG_AES_128, CALG_MD4, 16, 16, CRYPT_MODE_CBC, NTE_BAD_ALGID,
3661           "\xFF\xE9\x69\xFF\xC1\xDB\x08\xD4\x5B\xC8\x51\x71\x38\xEF\x8A\x5B",
3662           "\x8A\x24\xD0\x7A\x03\xE7\xA7\x02\xF2\x17\x4C\x01\xD5\x0E\x7F\x12",
3663           /* 21 */
3664         },
3665         { CALG_AES_192, CALG_MD4, 16, 16, CRYPT_MODE_CBC, NTE_BAD_ALGID,
3666           "\x12\x01\xDD\x25\xBA\x8F\x1B\xCB\x7B\xAD\x3F\xDF\xB2\x68\x4F\x6A",
3667           "\xA9\x56\xBC\xA7\x97\x4E\x28\xAA\x4B\xE1\xA0\x6C\xE2\x43\x2C\x61",
3668           /* 22 */
3669         },
3670         { CALG_AES_256, CALG_MD4, 16, 16, CRYPT_MODE_CBC, NTE_BAD_ALGID,
3671           "\x69\x08\x9F\x76\xD7\x9A\x93\x6F\xC7\x51\xA4\x00\xCF\x5A\xBB\x3D",
3672           "\x04\x07\xEA\xD9\x89\x0A\xD2\x65\x12\x13\x68\x9A\xD0\x86\x15\xED",
3673           /* 23 */
3674         },
3675         /* ================================================================== */
3676         { CALG_DES, CALG_MD5, 8, 16, CRYPT_MODE_CBC, 0,
3677           "\xEA\x01\x47\xA0\x7F\x96\x44\x6B\x0D\x95\x2C\x97\x4B\x28\x1C\x86",
3678           "\xF3\x75\xCC\x7C\x6C\x0B\xCF\x93",
3679           /* 24 */
3680         },
3681         { CALG_3DES_112, CALG_MD5, 8, 16, CRYPT_MODE_CBC, 0,
3682           "\xD2\xA2\xD7\x87\x32\x29\xF9\xE0\x45\x0D\xEC\x8D\xB5\xBC\x8A\xD9",
3683           "\x51\x70\xE0\xB7\x00\x0D\x3E\x21",
3684           /* 25 */
3685         },
3686         { CALG_3DES, CALG_MD5, 8, 16, CRYPT_MODE_CBC, 0,
3687           "\x2B\x36\xA2\x85\x85\xC0\xEC\xBE\x04\x56\x1D\x97\x8E\x82\xDB\xD8",
3688           "\x58\x23\x75\x25\x3F\x88\x25\xEB",
3689           /* 26 */
3690         },
3691         { CALG_RC2, CALG_MD5, 8, 16, CRYPT_MODE_CBC, 0,
3692           "\x3B\x89\x72\x3B\x8A\xD1\x2E\x13\x44\xD6\xD0\x97\xE6\xB8\x46\xCD",
3693           "\x90\x1C\x77\x45\x87\xDD\x1C\x2E",
3694           /* 27 */
3695         },
3696         { CALG_RC4, CALG_MD5, 4, 16, 0, 0,
3697           "\x00\x6D\xEF\xB1\xC8\xC6\x25\x5E\x45\x4F\x4E\x3D\xAF\x9C\x53\xD2",
3698           "\xC4\x4C\xD2\xF1",
3699           /* 28 */
3700         },
3701         { CALG_RC5, CALG_MD5, 0, 16, 0, NTE_BAD_ALGID,
3702           "\x56\x49\xDC\xBA\x32\xC6\x0D\x84\xE9\x2D\x42\x8C\xD6\x7C\x4A\x7A",
3703           NULL,
3704           /* 29 */
3705         },
3706         { CALG_RSA_SIGN, CALG_MD5, 0, 16, 0, NTE_BAD_ALGID,
3707           "\xDF\xD6\x3A\xE6\x3E\x8D\xB4\x17\x9F\x29\xF0\xFD\x6D\x98\x98\xAD",
3708           NULL,
3709           /* 30 */
3710         },
3711         { CALG_RSA_KEYX, CALG_MD5, 0, 16, CRYPT_MODE_CBC, NTE_BAD_ALGID,
3712           "\xD4\x4D\x60\x9A\x39\x27\x88\xB7\xD7\xB4\x34\x2F\x92\x61\x3C\xA8",
3713           NULL,
3714           /* 31 */
3715         },
3716         { CALG_AES, CALG_MD5, 0, 16, 0, NTE_BAD_ALGID,
3717           "\xF4\x83\x2E\x02\xDE\xAE\x46\x1F\xE1\x31\x65\x03\x08\x58\xE0\x7D",
3718           NULL,
3719           /* 32 */
3720         },
3721         { CALG_AES_128, CALG_MD5, 16, 16, CRYPT_MODE_CBC, NTE_BAD_ALGID,
3722           "\x0E\xA0\x40\x72\x55\xE5\x4C\xEB\x79\xCB\x48\xC3\xD1\xB1\xD0\xF4",
3723           "\x97\x66\x92\x02\x6D\xEC\x33\xF8\x4E\x82\x11\x20\xC7\xE2\xE6\xE8",
3724           /* 33 */
3725         },
3726         { CALG_AES_192, CALG_MD5, 16, 16, CRYPT_MODE_CBC, NTE_BAD_ALGID,
3727           "\x3F\x91\x5E\x09\x19\x11\x14\x27\xCA\x6A\x20\x24\x3E\xF0\x02\x3E",
3728           "\x9B\xDA\x73\xF4\xF3\x06\x93\x07\xC9\x32\xF1\xD8\xD4\x96\xD1\x7D",
3729           /* 34 */
3730         },
3731         { CALG_AES_256, CALG_MD5, 16, 16, CRYPT_MODE_CBC, NTE_BAD_ALGID,
3732           "\x27\x51\xD8\xB3\xC7\x14\x66\xE1\x99\xC3\x5C\x9C\x90\xF5\xE5\x94",
3733           "\x2A\x0F\xE9\xA9\x6F\x53\x7C\x9E\x07\xE6\xC3\xC9\x15\x99\x7C\xA8",
3734           /* 35 */
3735         },
3736         /* ================================================================== */
3737         { CALG_DES, CALG_SHA1, 8, 20, CRYPT_MODE_CBC, 0,
3738           "\xC1\x91\xF6\x5A\x81\x87\xAC\x6D\x48\x7C\x78\xF7\xEC\x37\xE2\x0C\xEC\xF7\xC0\xB8",
3739           "\xD4\xD8\xAA\x44\xAC\x5E\x0B\x8D",
3740           /* 36 */
3741         },
3742         { CALG_3DES_112, CALG_SHA1, 8, 20, CRYPT_MODE_CBC, 0,
3743           "\x5D\x9B\xC3\x99\xC4\x73\x90\x78\xCB\x51\x6B\x61\x8A\xBE\x1A\xF3\x7A\x90\xF3\x34",
3744           "\xD8\x1C\xBC\x6C\x92\xD3\x09\xBF",
3745           /* 37 */
3746         },
3747         { CALG_3DES, CALG_SHA1, 8, 20, CRYPT_MODE_CBC, 0,
3748           "\x90\xB8\x01\x89\xEC\x9A\x6C\xAD\x1E\xAC\xB3\x17\x0A\x44\xA2\x4D\x80\xA5\x25\x97",
3749           "\xBD\x58\x5A\x88\x98\xF8\x69\x9A",
3750           /* 38 */
3751         },
3752         { CALG_RC2, CALG_SHA1, 8, 20, CRYPT_MODE_CBC, 0,
3753           "\x42\xBD\xB8\xF2\xB5\xC2\x28\x64\x85\x98\x8E\x49\xE6\xDC\x92\x80\xCD\xC1\x63\x00",
3754           "\xCC\xFB\x1A\x4D\x29\xAD\x3E\x65",
3755           /* 39 */
3756         },
3757         { CALG_RC4, CALG_SHA1, 4, 20, 0, 0,
3758           "\x67\x36\xE9\x57\x5E\xCD\x56\x5E\x8B\x25\x35\x23\x74\xBA\x20\x46\xD0\x21\xDE\x0A",
3759           "\x7A\x34\x3D\x3C",
3760           /* 40 */
3761         },
3762         { CALG_RC5, CALG_SHA1, 0, 20, 0, NTE_BAD_ALGID,
3763           "\x5F\x29\xA5\xA4\x10\x08\x56\x15\x92\xF9\x55\x3B\x4B\xF5\xAB\xBD\xE7\x4D\x47\x28",
3764           NULL,
3765           /* 41 */
3766         },
3767         { CALG_RSA_SIGN, CALG_SHA1, 0, 20, 0, NTE_BAD_ALGID,
3768           "\xD3\xB7\xF8\xB9\xBE\x67\xD1\xFE\x10\x51\x23\x3B\x7D\xB7\x61\xF5\xA7\x1A\x02\x5E",
3769           NULL,
3770           /* 42 */
3771         },
3772         { CALG_RSA_KEYX, CALG_SHA1, 0, 20, CRYPT_MODE_CBC, NTE_BAD_ALGID,
3773           "\x09\x68\x97\x23\x11\x2B\x6A\x71\xBA\x33\x60\x43\xEE\xC9\x9B\xB7\x8F\x8A\x2E\x33",
3774           NULL,
3775           /* 43 */
3776         },
3777         { CALG_AES, CALG_SHA1, 0, 20, 0, NTE_BAD_ALGID,
3778           "\xCF\x28\x23\x83\x62\x87\x43\xF6\x50\x57\xED\x54\xEC\x93\x5E\xEC\x0E\xD3\x23\x9A",
3779           NULL,
3780           /* 44 */
3781         },
3782         { CALG_AES_128, CALG_SHA1, 16, 20, CRYPT_MODE_CBC, NTE_BAD_ALGID,
3783           "\x81\xC1\x7E\x42\xC3\x07\x1F\x5E\xF8\x75\xA3\x5A\xFC\x0B\x61\xBA\x0B\xD8\x53\x0D",
3784           "\x39\xCB\xAF\xD7\x8B\x75\x4A\x3B\xD2\x0E\x0D\xB1\x64\x57\x88\x58",
3785           /* 45 */
3786         },
3787         { CALG_AES_192, CALG_SHA1, 16, 20, CRYPT_MODE_CBC, NTE_BAD_ALGID,
3788           "\x93\xA7\xE8\x9E\x96\xB5\x97\x23\xD0\x58\x44\x8C\x4D\xBB\xAB\xB6\x3E\x1F\x2C\x1D",
3789           "\xA9\x13\x83\xCA\x21\xA2\xF0\xBE\x13\xBC\x55\x04\x38\x08\xA9\xC4",
3790           /* 46 */
3791         },
3792         { CALG_AES_256, CALG_SHA1, 16, 20, CRYPT_MODE_CBC, NTE_BAD_ALGID,
3793           "\x15\x6A\xB2\xDF\x32\x57\x14\x69\x09\x07\xAD\x24\x83\xA1\x74\x47\x41\x72\x69\xBC",
3794           "\xE1\x6C\xA8\x54\x0E\x24\x67\x6D\xCA\xA2\xFE\x84\xF0\x9B\x78\x66",
3795           /* 47 */
3796         },
3797         /* ================================================================== */
3798         { CALG_DES, CALG_SHA_256, 8, 32, CRYPT_MODE_CBC, 0,
3799           "\x20\x34\xf7\xbb\x7a\x3a\x79\xf0\xb9\x65\x18\x11\xaa\xfd\x26\x6b"
3800           "\x60\x5c\x6d\x4c\x81\x7c\x3f\xc4\xce\x94\xe3\x67\xdf\xf2\x16\xd8",
3801           "\x86\x0d\x8c\xf4\xc0\x22\x4a\xdd",
3802           /* 48 */
3803         },
3804         { CALG_3DES_112, CALG_SHA_256, 8, 32, CRYPT_MODE_CBC, 0,
3805           "\x09\x6e\x7f\xd5\xf2\x72\x4e\x18\x70\x09\xc1\x35\xf4\xd1\x3a\xe8"
3806           "\xe6\x1f\x91\xae\x2f\xfd\xa8\x8c\xce\x47\x0f\x7a\xf5\xef\xfd\xbe",
3807           "\x2d\xe7\x63\xf6\x58\x4d\x9a\xa6",
3808           /* 49 */
3809         },
3810         { CALG_3DES, CALG_SHA_256, 8, 32, CRYPT_MODE_CBC, 0,
3811           "\x54\x7f\x84\x7f\xfe\x83\xc6\x50\xbc\xd9\x92\x78\x32\x67\x50\x7d"
3812           "\xdf\x44\x55\x7d\x87\x74\xd2\x56\xff\xd9\x74\x44\xd5\x07\x9e\xdc",
3813           "\x20\xaa\x66\xd0\xac\x83\x9d\x99",
3814           /* 50 */
3815         },
3816         { CALG_RC2, CALG_SHA_256, 8, 32, CRYPT_MODE_CBC, 0,
3817           "\xc6\x22\x46\x15\xa1\x27\x38\x23\x91\xf2\x29\xda\x15\xc9\x5d\x92"
3818           "\x7c\x34\x4a\x1f\xb0\x8a\x81\xd6\x17\x09\xda\x52\x1f\xb9\x64\x60",
3819           "\x8c\x01\x19\x47\x7e\xd2\x10\x2c",
3820           /* 51 */
3821         },
3822         { CALG_RC4, CALG_SHA_256, 4, 32, 0, 0,
3823           "\xcd\x53\x95\xa6\xb6\x6e\x25\x92\x78\xac\xe6\x7e\xfc\xd3\x8d\xaa"
3824           "\xc3\x15\x83\xb5\xe6\xaf\xf9\x32\x4c\x17\xb8\x82\xdf\xc0\x45\x9e",
3825           "\xfa\x54\x13\x9c",
3826           /* 52 */
3827         },
3828         { CALG_RC5, CALG_SHA_256, 0, 32, 0, NTE_BAD_ALGID,
3829           "\x2a\x3b\x08\xe1\xec\xa7\x04\xf9\xc9\x42\x74\x9a\x82\xad\x99\xd2"
3830           "\x10\x51\xe3\x51\x6c\x67\xa4\xf2\xca\x99\x21\x43\xdf\xa0\xfc\xa1",
3831           NULL,
3832           /* 53 */
3833         },
3834         { CALG_RSA_SIGN, CALG_SHA_256, 0, 32, 0, NTE_BAD_ALGID,
3835           "\x10\x1d\x36\xc7\x38\x73\xc3\x80\xf0\x7a\x4e\x25\x52\x8a\x5c\x3f"
3836           "\xfc\x41\xa7\xe5\x20\xed\xd5\x1d\x00\x6e\x77\xf4\xa7\x71\x81\x6b",
3837           NULL,
3838           /* 54 */
3839         },
3840         { CALG_RSA_KEYX, CALG_SHA_256, 0, 32, CRYPT_MODE_CBC, NTE_BAD_ALGID,
3841           "\x0a\x74\xde\x4f\x07\xce\x73\xd6\xd9\xa3\xba\xbb\x7c\x98\xe1\x94"
3842           "\x13\x93\xb1\xfd\x26\x31\x4b\xfc\x61\x27\xef\x4d\xd0\x48\x76\x67",
3843           NULL,
3844           /* 55 */
3845         },
3846         { CALG_AES, CALG_SHA_256, 0, 32, 0, NTE_BAD_ALGID,
3847           "\xf0\x13\xbc\x25\x2a\x2f\xba\xf1\x39\xe5\x7d\xb8\x5f\xaa\xd0\x19"
3848           "\xbd\x1c\xd8\x7b\x39\x5a\xb3\x85\x84\x80\xbd\xe0\x4a\x65\x03\xdd",
3849           NULL,
3850           /* 56 */
3851         },
3852         { CALG_AES_128, CALG_SHA_256, 16, 32, CRYPT_MODE_CBC, NTE_BAD_ALGID,
3853           "\xc8\xc2\x6f\xe2\xbe\xa7\x38\x87\x04\xc7\x39\xcb\x9f\x57\xfc\xde"
3854           "\x14\x81\x46\xa4\xbb\xa7\x0f\x01\x1d\xc2\x6d\x7a\x43\x5f\x38\xc3",
3855           "\xf8\x75\xc6\x71\x8b\xb6\x54\xd3\xdc\xff\x0e\x84\x8a\x3f\x19\x46",
3856           /* 57 */
3857         },
3858         { CALG_AES_192, CALG_SHA_256, 16, 32, CRYPT_MODE_CBC, NTE_BAD_ALGID,
3859           "\xb7\x3a\x43\x0f\xea\x90\x4f\x0f\xb9\x82\xf6\x1e\x07\xc4\x25\x4e"
3860           "\xdb\xe7\xf7\x1d\x7c\xd0\xe5\x51\xd8\x1b\x97\xc8\xc2\x46\xb9\xfe",
3861           "\x35\xf2\x20\xc7\x6c\xb2\x8e\x51\x3e\xc7\x6b\x3e\x64\xa5\x05\xdf",
3862           /* 58 */
3863         },
3864         { CALG_AES_256, CALG_SHA_256, 16, 32, CRYPT_MODE_CBC, NTE_BAD_ALGID,
3865           "\xbd\xcc\x0c\x59\x99\x29\xa7\x24\xf3\xdc\x20\x40\x4e\xe8\xe5\x48"
3866           "\xdd\x27\x0e\xdf\x7e\x50\x65\x17\x34\x50\x47\x78\x9a\x23\x1b\x40",
3867           "\x8c\xeb\x1f\xd3\x78\x77\xf5\xbf\x7a\xde\x8d\x2c\xa5\x16\xcc\xe9",
3868           /* 59 */
3869         },
3870     };
3871     /* Due to differences between encryption from <= 2000 and >= XP some tests need to be skipped */
3872     int old_broken[ARRAY_SIZE(tests)];
3873     memset(old_broken, 0, sizeof(old_broken));
3874     old_broken[3] = old_broken[4] = old_broken[15] = old_broken[16] = 1;
3875     old_broken[27] = old_broken[28] = old_broken[39] = old_broken[40] = 1;
3876     uniquecontainer(NULL);
3877 
3878     for (i=0; i < ARRAY_SIZE(tests); i++)
3879     {
3880         if (win2k && old_broken[i]) continue;
3881 
3882         for (j=0; j<sizeof(dvData); j++) dvData[j] = (unsigned char)j+i;
3883         SetLastError(0xdeadbeef);
3884         result = CryptCreateHash(hProv, tests[i].hash_algo, 0, 0, &hHash);
3885         if (!result)
3886         {
3887             /* rsaenh compiled without OpenSSL or not supported by provider */
3888             ok(GetLastError() == NTE_BAD_ALGID, "Test [%s %d]: Expected NTE_BAD_ALGID, got 0x%08x\n",
3889                prov, i, GetLastError());
3890             continue;
3891         }
3892         ok(result, "Test [%s %d]: CryptCreateHash failed with error 0x%08x\n", prov, i, GetLastError());
3893         result = CryptHashData(hHash, dvData, sizeof(dvData), 0);
3894         ok(result, "Test [%s %d]: CryptHashData failed with error 0x%08x\n", prov, i, GetLastError());
3895 
3896         len = sizeof(pbData);
3897         result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
3898         ok(result, "Test [%s %d]: CryptGetHashParam failed with error 0x%08x\n", prov, i, GetLastError());
3899         ok(len == tests[i].hashlen, "Test [%s %d]: Expected hash len %d, got %d\n",
3900            prov, i, tests[i].hashlen, len);
3901         ok(!tests[i].hashlen || !memcmp(pbData, tests[i].expected_hash, tests[i].hashlen),
3902            "Test [%s %d]: Hash comparison failed\n", prov, i);
3903 
3904         SetLastError(0xdeadbeef);
3905         result = CryptDeriveKey(hProv, tests[i].crypt_algo, hHash, 0, &hKey);
3906         /* the provider may not support the algorithm */
3907         if(!result && (GetLastError() == tests[i].errorkey
3908            || GetLastError() == ERROR_INVALID_PARAMETER /* <= NT4*/))
3909             goto err;
3910         ok(result, "Test [%s %d]: CryptDeriveKey failed with error 0x%08x\n", prov, i, GetLastError());
3911 
3912         len = sizeof(mode);
3913         mode = 0xdeadbeef;
3914         result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&mode, &len, 0);
3915         ok(result, "Test [%s %d]: CryptGetKeyParam failed with error %08x\n", prov, i, GetLastError());
3916         ok(mode == tests[i].chain_mode, "Test [%s %d]: Expected chaining mode %d, got %d\n",
3917            prov, i, tests[i].chain_mode, mode);
3918 
3919         SetLastError(0xdeadbeef);
3920         len = 4;
3921         result = CryptEncrypt(hKey, 0, TRUE, 0, dvData, &len, sizeof(dvData));
3922         ok(result, "Test [%s %d]: CryptEncrypt failed with error 0x%08x\n", prov, i, GetLastError());
3923         ok(len == tests[i].blocklen, "Test [%s %d]: Expected block len %d, got %d\n",
3924            prov, i, tests[i].blocklen, len);
3925         ok(!memcmp(dvData, tests[i].expected_enc, tests[i].blocklen),
3926            "Test [%s %d]: Encrypted data comparison failed\n", prov, i);
3927 
3928         CryptDestroyKey(hKey);
3929 err:
3930         CryptDestroyHash(hHash);
3931     }
3932 }
3933 
3934 START_TEST(rsaenh)
3935 {
3936     for (iProv = 0; iProv < ARRAY_SIZE(szProviders); iProv++)
3937     {
3938         if (!init_base_environment(szProviders[iProv], 0))
3939             continue;
3940         trace("Testing '%s'\n", szProviders[iProv]);
3941         test_prov();
3942         test_gen_random();
3943         test_hashes();
3944         test_rc4();
3945         test_rc2();
3946         test_des();
3947         if(!BASE_PROV)
3948         {
3949             test_3des112();
3950             test_3des();
3951         }
3952         if(ENHANCED_PROV)
3953         {
3954             test_import_private();
3955         }
3956         test_hmac();
3957         test_mac();
3958         test_block_cipher_modes();
3959         test_verify_signature();
3960         test_rsa_encrypt();
3961         test_import_export();
3962         test_import_hmac();
3963         test_enum_container();
3964         if(!BASE_PROV) test_key_derivation(STRONG_PROV ? "STRONG" : "ENH");
3965         clean_up_base_environment();
3966     }
3967 
3968     test_key_permissions();
3969     test_key_initialization();
3970     test_schannel_provider();
3971     test_null_provider();
3972     test_rsa_round_trip();
3973     if (!init_aes_environment())
3974         return;
3975     test_aes(128);
3976     test_aes(192);
3977     test_aes(256);
3978     test_sha2();
3979     test_key_derivation("AES");
3980     clean_up_aes_environment();
3981 }
3982