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