urlmon: Don't create stgmed_obj for binding to object.
[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
31 static HCRYPTPROV hProv;
32 static const char szContainer[] = "winetest";
33 static const char szProvider[] = MS_ENHANCED_PROV_A;
34
35 typedef struct _ctdatatype {
36        unsigned char origstr[32];
37        unsigned char decstr[32];
38        int strlen;
39        int enclen;
40        int buflen;
41 } cryptdata;
42
43 static const cryptdata cTestData[4] = {
44        {"abcdefghijkl",
45        {'a','b','c','d','e','f','g','h',0x2,0x2,'k','l',0},
46        12,8,16},
47        {"abcdefghij",
48        {'a','b','c','d','e','f','g','h',0x2,0x2,0},
49        10,8,16},
50        {"abcdefgh",
51        {'a','b','c','d','e','f','g','h',0},
52        8,8,16},
53        {"abcdefghijkl",
54        {'a','b','c','d','e','f','g','h','i','j','k','l',0},
55        12,12,16}
56 };
57
58 static void printBytes(const char *heading, const BYTE *pb, size_t cb)
59 {
60     size_t i;
61     printf("%s: ",heading);
62     for(i=0;i<cb;i++)
63         printf("0x%02x,",pb[i]);
64     putchar('\n');
65 }
66
67 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
68
69 /*
70 static void trace_hex(BYTE *pbData, DWORD dwLen) {
71     char szTemp[256];
72     DWORD i, j;
73
74     for (i = 0; i < dwLen-7; i+=8) {
75         sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", 
76             pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5], 
77             pbData[i+6], pbData[i+7]);
78         trace(szTemp);
79     }
80     for (j=0; i<dwLen; j++,i++) {
81         sprintf(szTemp+6*j, "0x%02x, \n", pbData[i]);
82     }
83     trace(szTemp);
84 }
85 */
86
87 static int init_base_environment(void)
88 {
89     HCRYPTKEY hKey;
90     BOOL result;
91         
92     pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
93         
94     hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
95
96     result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
97     ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
98     
99     if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
100     {
101         ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
102         if (GetLastError()!=NTE_BAD_KEYSET) return 0;
103         result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 
104                                      CRYPT_NEWKEYSET);
105         ok(result, "%08x\n", GetLastError());
106         if (!result) return 0;
107         result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
108         ok(result, "%08x\n", GetLastError());
109         if (result) CryptDestroyKey(hKey);
110         result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
111         ok(result, "%08x\n", GetLastError());
112         if (result) CryptDestroyKey(hKey);
113     }
114     return 1;
115 }
116
117 static void clean_up_base_environment(void)
118 {
119     BOOL result;
120
121     result = CryptReleaseContext(hProv, 1);
122     ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
123         
124     CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
125 }
126
127 static int init_aes_environment(void)
128 {
129     HCRYPTKEY hKey;
130     BOOL result;
131
132     pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
133
134     hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
135
136     /* we are using NULL as provider name for RSA_AES provider as the provider
137      * names are different in Windows XP and Vista. Its different as to what
138      * its defined in the SDK on Windows XP.
139      * This provider is available on Windows XP, Windows 2003 and Vista.      */
140
141     result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
142     ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
143
144     if (!CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, 0))
145     {
146         ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
147         if (GetLastError()!=NTE_BAD_KEYSET) return 0;
148         result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES,
149                                      CRYPT_NEWKEYSET);
150         ok(result, "%08x\n", GetLastError());
151         if (!result) return 0;
152         result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
153         ok(result, "%08x\n", GetLastError());
154         if (result) CryptDestroyKey(hKey);
155         result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
156         ok(result, "%08x\n", GetLastError());
157         if (result) CryptDestroyKey(hKey);
158     }
159     return 1;
160 }
161
162 static void clean_up_aes_environment(void)
163 {
164     BOOL result;
165
166     result = CryptReleaseContext(hProv, 1);
167     ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
168
169     CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_DELETEKEYSET);
170 }
171
172 static void test_prov(void) 
173 {
174     BOOL result;
175     DWORD dwLen, dwInc;
176     
177     dwLen = (DWORD)sizeof(DWORD);
178     result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
179     ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
180     
181     dwLen = (DWORD)sizeof(DWORD);
182     result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
183     ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
184 }
185
186 static void test_gen_random(void)
187 {
188     BOOL result;
189     BYTE rnd1[16], rnd2[16];
190
191     memset(rnd1, 0, sizeof(rnd1));
192     memset(rnd2, 0, sizeof(rnd2));
193
194     result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
195     if (!result && GetLastError() == NTE_FAIL) {
196         /* rsaenh compiled without OpenSSL */
197         return;
198     }
199     
200     ok(result, "%08x\n", GetLastError());
201
202     result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
203     ok(result, "%08x\n", GetLastError());
204
205     ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
206 }
207
208 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len) 
209 {
210     HCRYPTHASH hHash;
211     BOOL result;
212     unsigned char pbData[2000];
213     int i;
214
215     *phKey = (HCRYPTKEY)NULL;
216     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
217     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
218     if (!result) {
219         /* rsaenh compiled without OpenSSL */
220         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
221         return FALSE;
222     } 
223     ok(result, "%08x\n", GetLastError());
224     if (!result) return FALSE;
225     result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
226     ok(result, "%08x\n", GetLastError());
227     if (!result) return FALSE;
228     result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
229     ok(result, "%08x\n", GetLastError());
230     if (!result) return FALSE;
231     len = 2000;
232     result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
233     ok(result, "%08x\n", GetLastError());
234     CryptDestroyHash(hHash);
235     return TRUE;
236 }
237
238 static void test_hashes(void)
239 {
240     static const unsigned char md2hash[16] = {
241         0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9, 
242         0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
243     static const unsigned char md4hash[16] = {
244         0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23, 
245         0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
246     static const unsigned char empty_md5hash[16] = {
247         0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
248         0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
249     static const unsigned char md5hash[16] = { 
250         0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd, 
251         0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };    
252     static const unsigned char sha1hash[20] = { 
253         0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d, 
254         0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
255     unsigned char pbData[2048];
256     BOOL result;
257     HCRYPTHASH hHash, hHashClone;
258     BYTE pbHashValue[36];
259     DWORD hashlen, len;
260     int i;
261
262     for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
263
264     /* MD2 Hashing */
265     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
266     if (!result) {
267         /* rsaenh compiled without OpenSSL */
268         ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
269     } else {
270         result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
271         ok(result, "%08x\n", GetLastError());
272
273         len = sizeof(DWORD);
274         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
275            ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
276
277         len = 16;
278         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
279         ok(result, "%08x\n", GetLastError());
280
281         ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
282
283         result = CryptDestroyHash(hHash);
284         ok(result, "%08x\n", GetLastError());
285     } 
286
287     /* MD4 Hashing */
288     result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
289     ok(result, "%08x\n", GetLastError());
290
291     result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
292     ok(result, "%08x\n", GetLastError());
293
294     len = sizeof(DWORD);
295     result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
296     ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
297
298     len = 16;
299     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
300     ok(result, "%08x\n", GetLastError());
301
302     ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
303
304     result = CryptDestroyHash(hHash);
305     ok(result, "%08x\n", GetLastError());
306
307     /* MD5 Hashing */
308     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
309     ok(result, "%08x\n", GetLastError());
310
311     len = sizeof(DWORD);
312     result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
313     ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
314
315     result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
316     ok(result, "%08x\n", GetLastError());
317
318     len = 16;
319     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
320     ok(result, "%08x\n", GetLastError());
321
322     ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
323
324     result = CryptDestroyHash(hHash);
325     ok(result, "%08x\n", GetLastError());
326
327     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
328     ok(result, "%08x\n", GetLastError());
329
330     /* The hash is available even if CryptHashData hasn't been called */
331     len = 16;
332     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
333     ok(result, "%08x\n", GetLastError());
334
335     ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
336
337     /* It's also stable:  getting it twice results in the same value */
338     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
339     ok(result, "%08x\n", GetLastError());
340
341     ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
342
343     /* Can't add data after the hash been retrieved */
344     SetLastError(0xdeadbeef);
345     result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
346     ok(!result && GetLastError() == NTE_BAD_HASH_STATE, "%08x\n", GetLastError());
347
348     /* You can still retrieve the hash, its value just hasn't changed */
349     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
350     ok(result, "%08x\n", GetLastError());
351
352     ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
353
354     result = CryptDestroyHash(hHash);
355     ok(result, "%08x\n", GetLastError());
356
357     /* SHA1 Hashing */
358     result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
359     ok(result, "%08x\n", GetLastError());
360
361     result = CryptHashData(hHash, (BYTE*)pbData, 5, 0);
362     ok(result, "%08x\n", GetLastError());
363
364     if(pCryptDuplicateHash) {
365         result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
366         ok(result, "%08x\n", GetLastError());
367
368         result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
369         ok(result, "%08x\n", GetLastError());
370
371         len = sizeof(DWORD);
372         result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
373         ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
374
375         len = 20;
376         result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
377         ok(result, "%08x\n", GetLastError());
378
379         ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
380
381         result = CryptDestroyHash(hHashClone);
382         ok(result, "%08x\n", GetLastError());
383     }
384
385     result = CryptDestroyHash(hHash);
386     ok(result, "%08x\n", GetLastError());
387 }
388
389 static void test_block_cipher_modes(void)
390 {
391     static const BYTE plain[23] = { 
392         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 
393         0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
394     static const BYTE ecb[24] = {   
395         0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f, 
396         0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
397     static const BYTE cbc[24] = {   
398         0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
399         0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
400     static const BYTE cfb[24] = {   
401         0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
402         0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
403     HCRYPTKEY hKey;
404     BOOL result;
405     BYTE abData[24];
406     DWORD dwMode, dwLen;
407
408     result = derive_key(CALG_RC2, &hKey, 40);
409     if (!result) return;
410
411     memcpy(abData, plain, sizeof(abData));
412
413     dwMode = CRYPT_MODE_ECB;
414     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
415     ok(result, "%08x\n", GetLastError());
416
417     dwLen = 23;
418     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
419     ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
420     ok(dwLen == 24, "Unexpected length %d\n", dwLen);
421
422     SetLastError(ERROR_SUCCESS);
423     dwLen = 23;
424     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
425     ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)), 
426        "%08x, dwLen: %d\n", GetLastError(), dwLen);
427
428     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
429     ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)), 
430        "%08x, dwLen: %d\n", GetLastError(), dwLen);
431
432     dwMode = CRYPT_MODE_CBC;
433     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
434     ok(result, "%08x\n", GetLastError());
435     
436     dwLen = 23;
437     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
438     ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
439     ok(dwLen == 24, "Unexpected length %d\n", dwLen);
440
441     dwLen = 23;
442     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
443     ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)), 
444        "%08x, dwLen: %d\n", GetLastError(), dwLen);
445
446     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
447     ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)), 
448        "%08x, dwLen: %d\n", GetLastError(), dwLen);
449
450     dwMode = CRYPT_MODE_CFB;
451     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
452     ok(result, "%08x\n", GetLastError());
453     
454     dwLen = 16;
455     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen, 24);
456     ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
457
458     dwLen = 7;
459     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+16, &dwLen, 8);
460     ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)), 
461        "%08x, dwLen: %d\n", GetLastError(), dwLen);
462     
463     dwLen = 8;
464     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen);
465     ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
466
467     dwLen = 16;
468     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+8, &dwLen);
469     ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)), 
470        "%08x, dwLen: %d\n", GetLastError(), dwLen);
471
472     dwMode = CRYPT_MODE_OFB;
473     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
474     ok(result, "%08x\n", GetLastError());
475     
476     dwLen = 23;
477     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
478     ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
479
480     CryptDestroyKey(hKey);
481 }
482
483 static void test_3des112(void)
484 {
485     HCRYPTKEY hKey;
486     BOOL result;
487     DWORD dwLen;
488     unsigned char pbData[16];
489     int i;
490
491     result = derive_key(CALG_3DES_112, &hKey, 0);
492     if (!result) {
493         /* rsaenh compiled without OpenSSL */
494         ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
495         return;
496     }
497
498     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
499     
500     dwLen = 13;
501     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
502     ok(result, "%08x\n", GetLastError());
503     
504     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
505     ok(result, "%08x\n", GetLastError());
506
507     for (i=0; i<4; i++)
508     {
509       memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
510
511       dwLen = cTestData[i].enclen;
512       result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
513       ok(result, "%08x\n", GetLastError());
514       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
515
516       result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
517       ok(result, "%08x\n", GetLastError());
518       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
519       ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
520       if((dwLen != cTestData[i].enclen) ||
521          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
522       {
523           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
524           printBytes("got",pbData,dwLen);
525       }
526     }
527     result = CryptDestroyKey(hKey);
528     ok(result, "%08x\n", GetLastError());
529 }
530
531 static void test_des(void) 
532 {
533     HCRYPTKEY hKey;
534     BOOL result;
535     DWORD dwLen, dwMode;
536     unsigned char pbData[16];
537     int i;
538
539     result = derive_key(CALG_DES, &hKey, 56);
540     if (!result) {
541         /* rsaenh compiled without OpenSSL */
542         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
543         return;
544     }
545
546     dwMode = CRYPT_MODE_ECB;
547     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
548     ok(result, "%08x\n", GetLastError());
549     
550     dwLen = sizeof(DWORD);
551     result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
552     ok(result, "%08x\n", GetLastError());
553     
554     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
555     
556     dwLen = 13;
557     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
558     ok(result, "%08x\n", GetLastError());
559     
560     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
561     ok(result, "%08x\n", GetLastError());
562
563     for (i=0; i<4; i++)
564     {
565       memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
566
567       dwLen = cTestData[i].enclen;
568       result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
569       ok(result, "%08x\n", GetLastError());
570       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
571
572       result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
573       ok(result, "%08x\n", GetLastError());
574       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
575       ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
576       if((dwLen != cTestData[i].enclen) ||
577          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
578       {
579           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
580           printBytes("got",pbData,dwLen);
581       }
582     }
583
584     result = CryptDestroyKey(hKey);
585     ok(result, "%08x\n", GetLastError());
586 }
587
588 static void test_3des(void)
589 {
590     HCRYPTKEY hKey;
591     BOOL result;
592     DWORD dwLen;
593     unsigned char pbData[16];
594     static const BYTE des3[16] = { 
595         0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3, 
596         0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
597     int i;
598
599     result = derive_key(CALG_3DES, &hKey, 0);
600     if (!result) return;
601
602     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
603     
604     dwLen = 13;
605     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
606     ok(result, "%08x\n", GetLastError());
607     
608     ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
609     
610     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
611     ok(result, "%08x\n", GetLastError());
612
613     for (i=0; i<4; i++)
614     {
615       memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
616
617       dwLen = cTestData[i].enclen;
618       result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
619       ok(result, "%08x\n", GetLastError());
620       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
621
622       result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
623       ok(result, "%08x\n", GetLastError());
624       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
625       ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
626       if((dwLen != cTestData[i].enclen) ||
627          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
628       {
629           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
630           printBytes("got",pbData,dwLen);
631       }
632     }
633     result = CryptDestroyKey(hKey);
634     ok(result, "%08x\n", GetLastError());
635 }
636
637 static void test_aes(int keylen)
638 {
639     HCRYPTKEY hKey;
640     BOOL result;
641     DWORD dwLen;
642     unsigned char pbData[16];
643     int i;
644
645     switch (keylen)
646     {
647         case 256:
648             result = derive_key(CALG_AES_256, &hKey, 0);
649             break;
650         case 192:
651             result = derive_key(CALG_AES_192, &hKey, 0);
652             break;
653         default:
654         case 128:
655             result = derive_key(CALG_AES_128, &hKey, 0);
656             break;
657     }
658     if (!result) return;
659
660     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
661
662     dwLen = 13;
663     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
664     ok(result, "%08x\n", GetLastError());
665
666     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
667     ok(result, "%08x\n", GetLastError());
668
669     for (i=0; i<4; i++)
670     {
671       memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
672
673       dwLen = cTestData[i].enclen;
674       result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
675       ok(result, "%08x\n", GetLastError());
676       ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
677
678       result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
679       ok(result, "%08x\n", GetLastError());
680       ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
681       ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
682       if((dwLen != cTestData[i].enclen) ||
683          memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
684       {
685           printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
686           printBytes("got",pbData,dwLen);
687       }
688     }
689     result = CryptDestroyKey(hKey);
690     ok(result, "%08x\n", GetLastError());
691 }
692
693 static void test_rc2(void)
694 {
695     static const BYTE rc2encrypted[16] = { 
696         0x02, 0x34, 0x7d, 0xf6, 0x1d, 0xc5, 0x9b, 0x8b, 
697         0x2e, 0x0d, 0x63, 0x80, 0x72, 0xc1, 0xc2, 0xb1 };
698     static const BYTE rc2_128_encrypted[] = {
699         0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
700         0xb6,0x66 };
701     HCRYPTHASH hHash;
702     HCRYPTKEY hKey;
703     BOOL result;
704     DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
705     BYTE *pbTemp;
706     unsigned char pbData[2000], pbHashValue[16];
707     int i;
708     
709     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
710
711     /* MD2 Hashing */
712     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
713     if (!result) {
714         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
715     } else {
716         result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
717         ok(result, "%08x\n", GetLastError());
718
719         dwLen = 16;
720         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
721         ok(result, "%08x\n", GetLastError());
722
723         result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
724         ok(result, "%08x\n", GetLastError());
725
726         dwLen = sizeof(DWORD);
727         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
728         ok(result, "%08x\n", GetLastError());
729
730         dwMode = CRYPT_MODE_CBC;
731         result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
732         ok(result, "%08x\n", GetLastError());
733
734         dwLen = sizeof(DWORD);
735         result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
736         ok(result, "%08x\n", GetLastError());
737
738         dwLen = sizeof(DWORD);
739         result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
740         ok(result, "%08x\n", GetLastError());
741
742         dwLen = sizeof(DWORD);
743         result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
744         ok(result, "%08x\n", GetLastError());
745
746         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
747         ok(result, "%08x\n", GetLastError());
748         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
749         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
750         HeapFree(GetProcessHeap(), 0, pbTemp);
751
752         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
753         ok(result, "%08x\n", GetLastError());
754         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
755         CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
756         HeapFree(GetProcessHeap(), 0, pbTemp);
757
758         dwLen = sizeof(DWORD);
759         CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
760
761         result = CryptDestroyHash(hHash);
762         ok(result, "%08x\n", GetLastError());
763
764         dwDataLen = 13;
765         result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
766         ok(result, "%08x\n", GetLastError());
767
768         ok(!memcmp(pbData, rc2encrypted, 8), "RC2 encryption failed!\n");
769
770         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
771         ok(result, "%08x\n", GetLastError());
772         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
773         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
774         HeapFree(GetProcessHeap(), 0, pbTemp);
775
776         result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
777         ok(result, "%08x\n", GetLastError());
778
779         result = CryptDestroyKey(hKey);
780         ok(result, "%08x\n", GetLastError());
781     }
782
783     /* Again, but test setting the effective key len */
784     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
785
786     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
787     if (!result) {
788         ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
789     } else {
790         result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
791         ok(result, "%08x\n", GetLastError());
792
793         dwLen = 16;
794         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
795         ok(result, "%08x\n", GetLastError());
796
797         result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
798         ok(result, "%08x\n", GetLastError());
799
800         SetLastError(0xdeadbeef);
801         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
802         ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
803         dwKeyLen = 0;
804         SetLastError(0xdeadbeef);
805         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
806         ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
807         dwKeyLen = 1025;
808         SetLastError(0xdeadbeef);
809         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
810
811         dwLen = sizeof(dwKeyLen);
812         CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
813         ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
814         CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
815         ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
816
817         dwKeyLen = 128;
818         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
819         ok(result, "%d\n", GetLastError());
820
821         dwLen = sizeof(dwKeyLen);
822         CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
823         ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
824         CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
825         ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
826
827         result = CryptDestroyHash(hHash);
828         ok(result, "%08x\n", GetLastError());
829
830         dwDataLen = 13;
831         result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
832         ok(result, "%08x\n", GetLastError());
833
834         ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
835                 "RC2 encryption failed!\n");
836
837         /* Oddly enough this succeeds, though it should have no effect */
838         dwKeyLen = 40;
839         result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
840         ok(result, "%d\n", GetLastError());
841
842         result = CryptDestroyKey(hKey);
843         ok(result, "%08x\n", GetLastError());
844     }
845 }
846
847 static void test_rc4(void)
848 {
849     static const BYTE rc4[16] = { 
850         0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0, 
851         0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };    
852     BOOL result;
853     HCRYPTHASH hHash;
854     HCRYPTKEY hKey;
855     DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
856     unsigned char pbData[2000], *pbTemp;
857     unsigned char pszBuffer[256];
858     int i;
859
860     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
861
862     /* MD2 Hashing */
863     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
864     if (!result) {
865         /* rsaenh compiled without OpenSSL */
866         ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
867     } else {
868         result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
869            ok(result, "%08x\n", GetLastError());
870
871         dwLen = 16;
872         result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
873         ok(result, "%08x\n", GetLastError());
874
875         result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
876         ok(result, "%08x\n", GetLastError());
877
878         dwLen = sizeof(DWORD);
879         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
880         ok(result, "%08x\n", GetLastError());
881
882         dwLen = sizeof(DWORD);
883         result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
884         ok(result, "%08x\n", GetLastError());
885
886         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
887         ok(result, "%08x\n", GetLastError());
888         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
889         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
890         HeapFree(GetProcessHeap(), 0, pbTemp);
891
892         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
893         ok(result, "%08x\n", GetLastError());
894         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
895         CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
896         HeapFree(GetProcessHeap(), 0, pbTemp);
897
898         dwLen = sizeof(DWORD);
899         CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
900
901         result = CryptDestroyHash(hHash);
902         ok(result, "%08x\n", GetLastError());
903
904         dwDataLen = 16;
905         result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwDataLen, 24);
906         ok(result, "%08x\n", GetLastError());
907         dwDataLen = 16;
908         result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
909         ok(result, "%08x\n", GetLastError());
910
911         ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
912
913         result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
914         ok(result, "%08x\n", GetLastError());
915
916         result = CryptDestroyKey(hKey);
917         ok(result, "%08x\n", GetLastError());
918     }
919 }
920
921 static void test_hmac(void) {
922     HCRYPTKEY hKey;
923     HCRYPTHASH hHash;
924     BOOL result;
925     /* Using CALG_MD2 here fails on Windows 2003, why ? */
926     HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
927     DWORD dwLen;
928     BYTE abData[256];
929     static const BYTE hmac[16] = { 
930         0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c, 
931         0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
932     int i;
933
934     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
935
936     if (!derive_key(CALG_RC2, &hKey, 56)) return;
937
938     result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
939     ok(result, "%08x\n", GetLastError());
940     if (!result) return;
941
942     result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
943     ok(result, "%08x\n", GetLastError());
944
945     result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
946     ok(result, "%08x\n", GetLastError());
947
948     dwLen = sizeof(abData)/sizeof(BYTE);
949     result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
950     ok(result, "%08x\n", GetLastError());
951
952     ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
953     
954     result = CryptDestroyHash(hHash);
955     ok(result, "%08x\n", GetLastError());
956     
957     result = CryptDestroyKey(hKey);
958     ok(result, "%08x\n", GetLastError());
959
960     /* Provoke errors */
961     result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
962     ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
963 }
964
965 static void test_mac(void) {
966     HCRYPTKEY hKey;
967     HCRYPTHASH hHash;
968     BOOL result;
969     DWORD dwLen;
970     BYTE abData[256], abEnc[264];
971     static const BYTE mac[8] = { 0x0d, 0x3e, 0x15, 0x6b, 0x85, 0x63, 0x5c, 0x11 };
972     int i;
973
974     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
975     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
976
977     if (!derive_key(CALG_RC2, &hKey, 56)) return;
978
979     dwLen = 256;
980     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abEnc, &dwLen, 264);
981     ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
982     
983     result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
984     ok(result, "%08x\n", GetLastError());
985     if (!result) return;
986
987     result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
988     ok(result, "%08x\n", GetLastError());
989
990     dwLen = sizeof(abData)/sizeof(BYTE);
991     result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
992     ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
993
994     ok(!memcmp(abData, mac, sizeof(mac)), "MAC failed!\n");
995     
996     result = CryptDestroyHash(hHash);
997     ok(result, "%08x\n", GetLastError());
998     
999     result = CryptDestroyKey(hKey);
1000     ok(result, "%08x\n", GetLastError());
1001     
1002     /* Provoke errors */
1003     if (!derive_key(CALG_RC4, &hKey, 56)) return;
1004
1005     result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1006     ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1007
1008     result = CryptDestroyKey(hKey);
1009     ok(result, "%08x\n", GetLastError());
1010 }
1011
1012 static BYTE abPlainPrivateKey[596] = {
1013     0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1014     0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1015     0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1016     0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1017     0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1018     0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1019     0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1020     0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1021     0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1022     0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1023     0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1024     0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1025     0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1026     0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1027     0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1028     0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1029     0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1030     0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1031     0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1032     0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1033     0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1034     0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1035     0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1036     0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1037     0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1038     0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1039     0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1040     0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1041     0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1042     0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1043     0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1044     0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1045     0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1046     0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1047     0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1048     0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1049     0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1050     0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1051     0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1052     0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1053     0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1054     0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1055     0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1056     0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1057     0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1058     0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1059     0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1060     0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1061     0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1062     0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1063     0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1064     0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1065     0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1066     0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1067     0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1068     0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1069     0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1070     0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1071     0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1072     0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1073     0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1074     0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1075     0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1076     0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1077     0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1078     0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1079     0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1080     0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1081     0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1082     0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1083     0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1084     0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1085     0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1086     0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1087     0xf2, 0x5d, 0x58, 0x07
1088 };
1089
1090 static void test_import_private(void) 
1091 {
1092     DWORD dwLen;
1093     HCRYPTKEY hKeyExchangeKey, hSessionKey;
1094     BOOL result;
1095     static BYTE abSessionKey[148] = {
1096         0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1097         0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1098         0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1099         0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1100         0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1101         0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1102         0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1103         0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1104         0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1105         0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1106         0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1107         0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1108         0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1109         0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1110         0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1111         0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1112         0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1113         0x04, 0x8c, 0x49, 0x92
1114     };
1115     static BYTE abEncryptedMessage[12] = {
1116         0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1117         0x1c, 0xfd, 0xde, 0x71
1118     };
1119             
1120     dwLen = (DWORD)sizeof(abPlainPrivateKey);
1121     result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1122     if (!result) {
1123         /* rsaenh compiled without OpenSSL */
1124         ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1125         return;
1126     }
1127
1128     dwLen = (DWORD)sizeof(abSessionKey);
1129     result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1130     ok(result, "%08x\n", GetLastError());
1131     if (!result) return;
1132
1133     dwLen = (DWORD)sizeof(abEncryptedMessage);
1134     result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1135     ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12), 
1136        "%08x, len: %d\n", GetLastError(), dwLen);
1137     CryptDestroyKey(hSessionKey);
1138     
1139     if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1140
1141     dwLen = (DWORD)sizeof(abSessionKey);
1142     result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1143     ok(result, "%08x\n", GetLastError());
1144     CryptDestroyKey(hSessionKey);
1145     if (!result) return;
1146
1147     dwLen = (DWORD)sizeof(abSessionKey);
1148     result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1149     ok(result, "%08x\n", GetLastError());
1150     if (!result) return;
1151
1152     CryptDestroyKey(hSessionKey);
1153     CryptDestroyKey(hKeyExchangeKey);
1154 }
1155
1156 static void test_verify_signature(void) {
1157     HCRYPTHASH hHash;
1158     HCRYPTKEY hPubSignKey;
1159     BYTE abData[] = "Wine rocks!";
1160     BOOL result;
1161     BYTE abPubKey[148] = {
1162         0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 
1163         0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 
1164         0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19, 
1165         0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27, 
1166         0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8, 
1167         0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda, 
1168         0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a, 
1169         0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc, 
1170         0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c, 
1171         0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c, 
1172         0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89, 
1173         0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b, 
1174         0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa, 
1175         0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63, 
1176         0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff, 
1177         0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49, 
1178         0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87, 
1179         0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7, 
1180         0xe1, 0x21, 0x50, 0xac
1181     };
1182     /* md2 with hash oid */
1183     BYTE abSignatureMD2[128] = {
1184         0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67, 
1185         0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b, 
1186         0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda, 
1187         0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59, 
1188         0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a, 
1189         0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34, 
1190         0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40, 
1191         0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7, 
1192         0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0, 
1193         0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06, 
1194         0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51, 
1195         0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f, 
1196         0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46, 
1197         0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25, 
1198         0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0, 
1199         0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1200     };
1201     /* md2 without hash oid */
1202     BYTE abSignatureMD2NoOID[128] = {
1203         0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d, 
1204         0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19, 
1205         0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd, 
1206         0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4, 
1207         0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65, 
1208         0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99, 
1209         0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf, 
1210         0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc, 
1211         0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0, 
1212         0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01, 
1213         0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7, 
1214         0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f, 
1215         0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a, 
1216         0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9, 
1217         0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06, 
1218         0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1219     };
1220     /* md4 with hash oid */
1221     BYTE abSignatureMD4[128] = {
1222         0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51, 
1223         0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b, 
1224         0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2, 
1225         0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e, 
1226         0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13, 
1227         0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9, 
1228         0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f, 
1229         0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96, 
1230         0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9, 
1231         0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e, 
1232         0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0, 
1233         0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe, 
1234         0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18, 
1235         0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab, 
1236         0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3, 
1237         0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1238     };
1239     /* md4 without hash oid */
1240     BYTE abSignatureMD4NoOID[128] = {
1241         0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda, 
1242         0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24, 
1243         0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0, 
1244         0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36, 
1245         0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85, 
1246         0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3, 
1247         0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f, 
1248         0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9, 
1249         0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06, 
1250         0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f, 
1251         0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb, 
1252         0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96, 
1253         0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f, 
1254         0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9, 
1255         0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb, 
1256         0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1257     }; 
1258     /* md5 with hash oid */
1259     BYTE abSignatureMD5[128] = {
1260         0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5, 
1261         0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f, 
1262         0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7, 
1263         0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98, 
1264         0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec, 
1265         0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5, 
1266         0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04, 
1267         0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b, 
1268         0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95, 
1269         0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c, 
1270         0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29, 
1271         0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9, 
1272         0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c, 
1273         0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90, 
1274         0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e, 
1275         0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1276     };
1277     /* md5 without hash oid */
1278     BYTE abSignatureMD5NoOID[128] = {
1279         0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f, 
1280         0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75, 
1281         0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f, 
1282         0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d, 
1283         0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f, 
1284         0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49, 
1285         0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8, 
1286         0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c, 
1287         0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23, 
1288         0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19, 
1289         0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb, 
1290         0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3, 
1291         0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b, 
1292         0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b, 
1293         0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5, 
1294         0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1295     };
1296     /* sha with hash oid */
1297     BYTE abSignatureSHA[128] = {
1298         0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91, 
1299         0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd, 
1300         0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24, 
1301         0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94, 
1302         0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f, 
1303         0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a, 
1304         0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52, 
1305         0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20, 
1306         0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5, 
1307         0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a, 
1308         0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff, 
1309         0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53, 
1310         0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00, 
1311         0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e, 
1312         0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98, 
1313         0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1314     };
1315     /* sha without hash oid */
1316     BYTE abSignatureSHANoOID[128] = {
1317         0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6, 
1318         0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a, 
1319         0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f, 
1320         0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37, 
1321         0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65, 
1322         0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe, 
1323         0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6, 
1324         0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe, 
1325         0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c, 
1326         0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4, 
1327         0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80, 
1328         0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a, 
1329         0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00, 
1330         0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd, 
1331         0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67, 
1332         0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1333     }; 
1334     
1335     result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1336     ok(result, "%08x\n", GetLastError());
1337     if (!result) return;
1338
1339     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1340     ok(result, "%08x\n", GetLastError());
1341     if (!result) return;
1342
1343     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1344     ok(result, "%08x\n", GetLastError());
1345     if (!result) return;
1346
1347     /*check that a NULL pointer signature is correctly handled*/
1348     result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1349     ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1350      "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1351     if (result) return;
1352
1353     /* check that we get a bad signature error when the signature is too short*/
1354     result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1355     ok(!result && NTE_BAD_SIGNATURE == GetLastError(),
1356      "Expected NTE_BAD_SIGNATURE error, got %08x\n", GetLastError());
1357     if (result) return;
1358
1359     result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1360     ok(result, "%08x\n", GetLastError());
1361     if (!result) return;
1362
1363     result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1364     ok(result, "%08x\n", GetLastError());
1365     if (!result) return;
1366
1367     /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about 
1368      * the OID at all. */
1369     /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1370     ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1371     if (result) return;*/
1372
1373     CryptDestroyHash(hHash);
1374
1375     result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1376     ok(result, "%08x\n", GetLastError());
1377     if (!result) return;
1378
1379     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1380     ok(result, "%08x\n", GetLastError());
1381     if (!result) return;
1382
1383     result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1384     ok(result, "%08x\n", GetLastError());
1385     if (!result) return;
1386
1387     result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1388     ok(result, "%08x\n", GetLastError());
1389     if (!result) return;
1390
1391     CryptDestroyHash(hHash);
1392
1393     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1394     ok(result, "%08x\n", GetLastError());
1395     if (!result) return;
1396
1397     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1398     ok(result, "%08x\n", GetLastError());
1399     if (!result) return;
1400
1401     result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1402     ok(result, "%08x\n", GetLastError());
1403     if (!result) return;
1404
1405     result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1406     ok(result, "%08x\n", GetLastError());
1407     if (!result) return;
1408
1409     CryptDestroyHash(hHash);
1410
1411     result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1412     ok(result, "%08x\n", GetLastError());
1413     if (!result) return;
1414
1415     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1416     ok(result, "%08x\n", GetLastError());
1417     if (!result) return;
1418
1419     result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1420     ok(result, "%08x\n", GetLastError());
1421     if (!result) return;
1422
1423     result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1424     ok(result, "%08x\n", GetLastError());
1425     if (!result) return;
1426
1427     CryptDestroyHash(hHash);
1428     CryptDestroyKey(hPubSignKey);
1429 }
1430
1431 static void test_rsa_encrypt(void)
1432 {
1433     HCRYPTKEY hRSAKey;
1434     BYTE abData[2048] = "Wine rocks!";
1435     BOOL result;
1436     DWORD dwLen;
1437
1438     /* It is allowed to use the key exchange key for encryption/decryption */
1439     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1440     ok (result, "%08x\n", GetLastError());
1441     if (!result) return;
1442
1443     dwLen = 12;
1444     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1445     ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1446     ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1447     dwLen = 12;
1448     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1449     ok (result, "%08x\n", GetLastError());
1450     if (!result) return;
1451
1452     result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1453     ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1454     
1455     CryptDestroyKey(hRSAKey);
1456
1457     /* It is not allowed to use the signature key for encryption/decryption */
1458     result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1459     ok (result, "%08x\n", GetLastError());
1460     if (!result) return;
1461
1462     dwLen = 12;
1463     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1464     ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1465
1466     CryptDestroyKey(hRSAKey);
1467 }
1468
1469 static void test_import_export(void)
1470 {
1471     DWORD dwLen, dwDataLen;
1472     HCRYPTKEY hPublicKey;
1473     BOOL result;
1474     ALG_ID algID;
1475     BYTE emptyKey[2048];
1476     static BYTE abPlainPublicKey[84] = {
1477         0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1478         0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1479         0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1480         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1481         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1482         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1483         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1484         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1485         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1486         0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1487         0x11, 0x11, 0x11, 0x11
1488     };
1489
1490     dwLen=84;
1491     result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1492     ok(result, "failed to import the public key\n");
1493
1494     dwDataLen=sizeof(algID);
1495     result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1496     ok(result, "failed to get the KP_ALGID from the imported public key\n");
1497     ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1498         
1499     result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
1500     ok(result, "failed to export the fresh imported public key\n");
1501     ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
1502     ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
1503
1504     CryptDestroyKey(hPublicKey);
1505 }
1506         
1507 static void test_schannel_provider(void)
1508 {
1509     HCRYPTPROV hProv;
1510     HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1511     HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1512     BOOL result;
1513     DWORD dwLen;
1514     SCHANNEL_ALG saSChannelAlg;
1515     CRYPT_DATA_BLOB data_blob;
1516     HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1517     BYTE abTLS1Master[140] = {
1518         0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00, 
1519         0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68, 
1520         0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97, 
1521         0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53, 
1522         0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24, 
1523         0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3, 
1524         0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8, 
1525         0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d, 
1526         0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e, 
1527         0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e, 
1528         0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40, 
1529         0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b, 
1530         0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb, 
1531         0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6, 
1532         0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac, 
1533         0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41, 
1534         0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4, 
1535         0xd3, 0x1e, 0x82, 0xb3
1536     };
1537     BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1538     BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1539     BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1540     BYTE abClientFinished[16] = "client finished";
1541     BYTE abData[16] = "Wine rocks!";
1542     BYTE abMD5Hash[16];
1543     static const BYTE abEncryptedData[16] = {
1544         0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1545         0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d    
1546     };
1547     static const BYTE abPRF[16] = {
1548         0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1549         0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1550     };
1551     static const BYTE abMD5[16] = {
1552         0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1553         0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1554     };
1555     
1556     result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
1557     ok (result, "%08x\n", GetLastError());
1558     if (result)
1559         CryptReleaseContext(hProv, 0);
1560
1561     result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1562     ok (result, "%08x\n", GetLastError());
1563     if (!result) return;
1564     
1565     /* To get deterministic results, we import the TLS1 master secret (which
1566      * is typically generated from a random generator). Therefore, we need
1567      * an RSA key. */
1568     dwLen = (DWORD)sizeof(abPlainPrivateKey);
1569     result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1570     ok (result, "%08x\n", GetLastError());
1571     if (!result) return;
1572
1573     dwLen = (DWORD)sizeof(abTLS1Master);
1574     result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1575     ok (result, "%08x\n", GetLastError());
1576     if (!result) return;    
1577    
1578     /* Setting the TLS1 client and server random parameters, as well as the 
1579      * MAC and encryption algorithm parameters. */
1580     data_blob.cbData = 33;
1581     data_blob.pbData = abClientSecret;
1582     result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1583     ok (result, "%08x\n", GetLastError());
1584     if (!result) return;
1585
1586     data_blob.cbData = 33;
1587     data_blob.pbData = abServerSecret;
1588     result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1589     ok (result, "%08x\n", GetLastError());
1590     if (!result) return;
1591     
1592     saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1593     saSChannelAlg.Algid = CALG_DES;
1594     saSChannelAlg.cBits = 64;
1595     saSChannelAlg.dwFlags = 0;
1596     saSChannelAlg.dwReserved = 0;
1597     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1598     ok (result, "%08x\n", GetLastError());
1599     if (!result) return;
1600
1601     saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1602     saSChannelAlg.Algid = CALG_MD5;
1603     saSChannelAlg.cBits = 128;
1604     saSChannelAlg.dwFlags = 0;
1605     saSChannelAlg.dwReserved = 0;
1606     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1607     ok (result, "%08x\n", GetLastError());
1608     if (!result) return;
1609
1610     /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1611      * (Keys can only be derived from hashes, not from other keys.) */
1612     result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1613     ok (result, "%08x\n", GetLastError());
1614     if (!result) return;
1615
1616     /* Deriving the server write encryption key from the master hash */
1617     result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1618     ok (result, "%08x\n", GetLastError());
1619     if (!result) return;
1620
1621     /* Encrypting some data with the server write encryption key and checking the result. */
1622     dwLen = 12;
1623     result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1624     ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
1625
1626     /* Second test case: Test the TLS1 pseudo random number function. */
1627     result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1628     ok (result, "%08x\n", GetLastError());
1629     if (!result) return;
1630
1631     /* Set the label and seed parameters for the random number function */
1632     data_blob.cbData = 36;
1633     data_blob.pbData = abHashedHandshakes;
1634     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1635     ok (result, "%08x\n", GetLastError());
1636     if (!result) return;
1637
1638     data_blob.cbData = 15;
1639     data_blob.pbData = abClientFinished;
1640     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1641     ok (result, "%08x\n", GetLastError());
1642     if (!result) return;
1643
1644     /* Generate some pseudo random bytes and check if they are correct. */
1645     dwLen = (DWORD)sizeof(abData);
1646     result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1647     ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)), 
1648         "%08x\n", GetLastError());
1649
1650     /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1651      * Hash some data with the HMAC. Compare results. */
1652     result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
1653     ok (result, "%08x\n", GetLastError());
1654     if (!result) return;
1655     
1656     result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
1657     ok (result, "%08x\n", GetLastError());
1658     if (!result) return;
1659
1660     result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
1661     ok (result, "%08x\n", GetLastError());
1662     if (!result) return;
1663
1664     result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
1665     ok (result, "%08x\n", GetLastError());
1666     if (!result) return;
1667
1668     dwLen = (DWORD)sizeof(abMD5Hash);
1669     result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
1670     ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
1671
1672     CryptDestroyHash(hHMAC);
1673     CryptDestroyHash(hTLS1PRF);
1674     CryptDestroyHash(hMasterHash);
1675     CryptDestroyKey(hServerWriteMACKey);
1676     CryptDestroyKey(hServerWriteKey);
1677     CryptDestroyKey(hRSAKey);
1678     CryptDestroyKey(hMasterSecret);
1679     CryptReleaseContext(hProv, 0);
1680     CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
1681 }
1682
1683 static void test_enum_container(void)
1684 {
1685     BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
1686     DWORD dwBufferLen;
1687     BOOL result, fFound = FALSE;
1688
1689     /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1690      * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1691     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
1692     ok (result && dwBufferLen == MAX_PATH + 1, "%08x\n", GetLastError());
1693
1694     /* If the result fits into abContainerName dwBufferLen is left untouched */
1695     dwBufferLen = (DWORD)sizeof(abContainerName);
1696     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
1697     ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
1698     
1699     /* We only check, if the currently open 'winetest' container is among the enumerated. */
1700     do {
1701         if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
1702         dwBufferLen = (DWORD)sizeof(abContainerName);
1703     } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
1704         
1705     ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
1706 }
1707
1708 static BYTE signBlob[] = {
1709 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
1710 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
1711 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
1712 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
1713 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
1714 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
1715 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
1716 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
1717 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
1718 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
1719 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
1720 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
1721 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
1722 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
1723 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
1724 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
1725 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
1726 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
1727 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
1728 0xb6,0x85,0x86,0x07 };
1729
1730 static void test_null_provider(void)
1731 {
1732     HCRYPTPROV prov;
1733     HCRYPTKEY key;
1734     BOOL result;
1735     DWORD keySpec, dataLen,dwParam;
1736     char szName[MAX_PATH];
1737
1738     result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
1739     ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
1740      "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
1741     result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
1742     ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1743      "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1744     result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
1745      CRYPT_DELETEKEYSET);
1746     ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1747      "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1748     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1749      CRYPT_DELETEKEYSET);
1750     ok(!result && GetLastError() == NTE_BAD_KEYSET,
1751      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1752     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1753     ok(!result && GetLastError() == NTE_BAD_KEYSET,
1754      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1755
1756     /* Delete the default container. */
1757     CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1758     /* Once you've deleted the default container you can't open it as if it
1759      * already exists.
1760      */
1761     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
1762     ok(!result && GetLastError() == NTE_BAD_KEYSET,
1763      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1764     /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
1765     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1766      CRYPT_VERIFYCONTEXT);
1767     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1768     if (!result) return;
1769     dataLen = sizeof(keySpec);
1770     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1771     if (result)
1772         ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1773          "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1774     /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
1775      * supported, you can't get the keys from this container.
1776      */
1777     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1778     ok(!result && GetLastError() == NTE_NO_KEY,
1779      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1780     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1781     ok(!result && GetLastError() == NTE_NO_KEY,
1782      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1783     result = CryptReleaseContext(prov, 0);
1784     ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
1785     /* You can create a new default container. */
1786     result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1787      CRYPT_NEWKEYSET);
1788     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1789     /* But you still can't get the keys (until one's been generated.) */
1790     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1791     ok(!result && GetLastError() == NTE_NO_KEY,
1792      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1793     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1794     ok(!result && GetLastError() == NTE_NO_KEY,
1795      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1796     CryptReleaseContext(prov, 0);
1797     CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1798
1799     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1800      CRYPT_DELETEKEYSET);
1801     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1802     ok(!result && GetLastError() == NTE_BAD_KEYSET,
1803      "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1804     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1805      CRYPT_VERIFYCONTEXT);
1806     ok(!result && GetLastError() == NTE_BAD_FLAGS,
1807      "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
1808     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1809      CRYPT_NEWKEYSET);
1810     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1811     if (!result) return;
1812     /* Test provider parameters getter */
1813     dataLen = sizeof(dwParam);
1814     result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
1815     ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
1816         "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
1817     dataLen = sizeof(dwParam);
1818     result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
1819     ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
1820         "Expected 0, got 0x%08X\n",dwParam);
1821     dataLen = sizeof(dwParam);
1822     result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
1823     ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
1824         "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
1825     dataLen = sizeof(keySpec);
1826     result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1827     ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1828         "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1829     /* PP_CONTAINER parameter */
1830     dataLen = sizeof(szName);
1831     result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1832     ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1833         "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1834         (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1835     /* PP_UNIQUE_CONTAINER parameter */
1836     dataLen = sizeof(szName);
1837     result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1838     ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1839         "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1840         (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1841     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1842     ok(!result && GetLastError() == NTE_NO_KEY,
1843      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1844     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1845     ok(!result && GetLastError() == NTE_NO_KEY,
1846      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1847
1848     /* Importing a key exchange blob.. */
1849     result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
1850      0, 0, &key);
1851     ok(result, "CryptImportKey failed: %08x\n", GetLastError());
1852     CryptDestroyKey(key);
1853     /* allows access to the key exchange key.. */
1854     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1855     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1856     CryptDestroyKey(key);
1857     /* but not to the private key. */
1858     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1859     ok(!result && GetLastError() == NTE_NO_KEY,
1860      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1861     CryptReleaseContext(prov, 0);
1862     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1863      CRYPT_DELETEKEYSET);
1864
1865     /* Whereas importing a sign blob.. */
1866     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1867      CRYPT_NEWKEYSET);
1868     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1869     if (!result) return;
1870     result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
1871     ok(result, "CryptGenKey failed: %08x\n", GetLastError());
1872     CryptDestroyKey(key);
1873     /* doesn't allow access to the key exchange key.. */
1874     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1875     ok(!result && GetLastError() == NTE_NO_KEY,
1876      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1877     /* but does to the private key. */
1878     result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1879     ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1880     CryptDestroyKey(key);
1881     CryptReleaseContext(prov, 0);
1882
1883     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1884      CRYPT_DELETEKEYSET);
1885
1886
1887     /* test for the bug in accessing the user key in a container
1888      */
1889     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1890      CRYPT_NEWKEYSET);
1891     ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1892     result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
1893     ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
1894     CryptDestroyKey(key);
1895     CryptReleaseContext(prov,0);
1896     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
1897     ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
1898     result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1899     ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
1900     CryptDestroyKey(key);
1901     CryptReleaseContext(prov, 0);
1902
1903     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1904      CRYPT_DELETEKEYSET);
1905
1906     /* test the machine key set */
1907     CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1908      CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1909     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1910      CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
1911     ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1912     CryptReleaseContext(prov, 0);
1913     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1914      CRYPT_MACHINE_KEYSET);
1915     ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1916     CryptReleaseContext(prov,0);
1917     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1918        CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1919     ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
1920                 GetLastError());
1921     result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1922      CRYPT_MACHINE_KEYSET);
1923     ok(!result && GetLastError() == NTE_BAD_KEYSET ,
1924         "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1925
1926 }
1927
1928 START_TEST(rsaenh)
1929 {
1930     if (!init_base_environment())
1931         return;
1932     test_prov();
1933     test_gen_random();
1934     test_hashes();
1935     test_rc4();
1936     test_rc2();
1937     test_des();
1938     test_3des112();
1939     test_3des();
1940     test_hmac();
1941     test_mac();
1942     test_block_cipher_modes();
1943     test_import_private();
1944     test_verify_signature();
1945     test_rsa_encrypt();
1946     test_import_export();
1947     test_enum_container();
1948     clean_up_base_environment();
1949     test_schannel_provider();
1950     test_null_provider();
1951     if (!init_aes_environment())
1952         return;
1953     test_aes(128);
1954     test_aes(192);
1955     test_aes(256);
1956     clean_up_aes_environment();
1957 }