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