Reverse the order for deleting the items in resetcontent to correctly
[wine] / dlls / rsaenh / tests / rsaenh.c
1 /*
2  * Unit tests for rsaenh functions
3  *
4  * Copyright (c) 2004 Michael Jung
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <string.h>
22 #include <stdio.h>
23 #include "wine/test.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "wincrypt.h"
28
29 static HCRYPTPROV hProv;
30 static const char szContainer[] = "winetest";
31 static const unsigned char pbData[] = "Wine rocks totally!";
32 static const char szProvider[] = MS_ENHANCED_PROV_A;
33
34 /*
35 static void trace_hex(BYTE *pbData, DWORD dwLen) {
36     char szTemp[256];
37     DWORD i, j;
38
39     for (i = 0; i < dwLen-7; i+=8) {
40         sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", 
41             pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5], 
42             pbData[i+6], pbData[i+7]);
43         trace(szTemp);
44     }
45     for (j=0; i<dwLen; j++,i++) {
46         sprintf(szTemp+6*j, "0x%02x, \n", pbData[i]);
47     }
48     trace(szTemp);
49 }
50 */
51
52 static int init_environment(void)
53 {
54     HCRYPTKEY hKey;
55     BOOL result;
56         
57     hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
58
59     result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
60     ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08lx\n", result, GetLastError());
61     
62     if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
63     {
64         ok(GetLastError()==NTE_BAD_KEYSET, "%08lx\n", GetLastError());
65         if (GetLastError()!=NTE_BAD_KEYSET) return 0;
66         result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 
67                                     CRYPT_NEWKEYSET);
68         ok(result, "%08lx\n", GetLastError());
69         if (!result) return 0;
70         result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
71         ok(result, "%08lx\n", GetLastError());
72         if (result) CryptDestroyKey(hKey);
73         result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
74         ok(result, "%08lx\n", GetLastError());
75         if (result) CryptDestroyKey(hKey);
76     }
77     return 1;
78 }
79
80 static void clean_up_environment(void)
81 {
82     BOOL result;
83
84     result = CryptReleaseContext(hProv, 1);
85     ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08lx\n", GetLastError());
86         
87     CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
88 }
89
90 static void test_prov() 
91 {
92     BOOL result;
93     DWORD dwLen, dwInc;
94     
95     dwLen = (DWORD)sizeof(DWORD);
96     result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
97     ok(result && dwInc==8, "%08lx, %ld\n", GetLastError(), dwInc);
98     
99     dwLen = (DWORD)sizeof(DWORD);
100     result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
101     ok(result && dwInc==8, "%08lx, %ld\n", GetLastError(), dwInc);
102 }
103
104 static void test_gen_random()
105 {
106     BOOL result;
107     BYTE rnd1[16], rnd2[16];
108
109     memset(rnd1, 0, sizeof(rnd1));
110     memset(rnd2, 0, sizeof(rnd2));
111
112     result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
113     if (!result && GetLastError() == NTE_FAIL) {
114         /* rsaenh compiled without OpenSSL */
115         return;
116     }
117     
118     ok(result, "%08lx\n", GetLastError());
119
120     result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
121     ok(result, "%08lx\n", GetLastError());
122
123     ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
124 }
125
126 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len) 
127 {
128     HCRYPTHASH hHash;
129     BOOL result;
130     unsigned char pbData[2000];
131     int i;
132
133     *phKey = (HCRYPTKEY)NULL;
134     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
135     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
136     if (!result) {
137         /* rsaenh compiled without OpenSSL */
138         ok(GetLastError()==NTE_BAD_ALGID, "%08lx\n", GetLastError());
139         return FALSE;
140     } 
141     ok(result, "%08lx\n", GetLastError());
142     if (!result) return FALSE;
143     result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
144     ok(result, "%08lx\n", GetLastError());
145     if (!result) return FALSE;
146     result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
147     ok(result, "%08lx\n", GetLastError());
148     if (!result) return FALSE;
149     len = 2000;
150     result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
151     ok(result, "%08lx\n", GetLastError());
152     CryptDestroyHash(hHash);
153     return TRUE;
154 }
155
156 static void test_hashes(void)
157 {
158     static const unsigned char md2hash[16] = {
159         0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9, 
160         0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
161     static const unsigned char md4hash[16] = {
162         0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23, 
163         0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
164     static const unsigned char md5hash[16] = { 
165         0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd, 
166         0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };    
167     static const unsigned char sha1hash[20] = { 
168         0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d, 
169         0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
170     unsigned char pbData[2048];
171     BOOL result;
172     HCRYPTHASH hHash, hHashClone;
173     BYTE pbHashValue[36];
174     DWORD hashlen, len;
175     int i;
176
177     for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
178
179     /* MD2 Hashing */
180     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
181     if (!result) {
182         /* rsaenh compiled without OpenSSL */
183         ok(GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
184     } else {
185         result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
186         ok(result, "%08lx\n", GetLastError());
187
188         len = sizeof(DWORD);
189         result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
190            ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
191
192         len = 16;
193         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
194         ok(result, "%08lx\n", GetLastError());
195
196         ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
197
198         result = CryptDestroyHash(hHash);
199         ok(result, "%08lx\n", GetLastError());
200     } 
201
202     /* MD4 Hashing */
203     result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
204     ok(result, "%08lx\n", GetLastError());
205
206     result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
207     ok(result, "%08lx\n", GetLastError());
208
209     len = sizeof(DWORD);
210     result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
211     ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
212
213     len = 16;
214     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
215     ok(result, "%08lx\n", GetLastError());
216
217     ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
218
219     result = CryptDestroyHash(hHash);
220     ok(result, "%08lx\n", GetLastError());
221
222     /* MD5 Hashing */
223     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
224     ok(result, "%08lx\n", GetLastError());
225
226     result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
227     ok(result, "%08lx\n", GetLastError());
228
229     len = sizeof(DWORD);
230     result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
231     ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
232
233     len = 16;
234     result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
235     ok(result, "%08lx\n", GetLastError());
236
237     ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
238
239     result = CryptDestroyHash(hHash);
240     ok(result, "%08lx\n", GetLastError());
241
242     /* SHA1 Hashing */
243     result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
244     ok(result, "%08lx\n", GetLastError());
245
246     result = CryptHashData(hHash, (BYTE*)pbData, 5, 0);
247     ok(result, "%08lx\n", GetLastError());
248
249     result = CryptDuplicateHash(hHash, 0, 0, &hHashClone);
250     ok(result, "%08lx\n", GetLastError());
251     
252     result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
253     ok(result, "%08lx\n", GetLastError());
254
255     len = sizeof(DWORD);
256     result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
257     ok(result && (hashlen == 20), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
258
259     len = 20;
260     result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
261     ok(result, "%08lx\n", GetLastError());
262
263     ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
264
265     result = CryptDestroyHash(hHashClone);
266     ok(result, "%08lx\n", GetLastError());
267
268     result = CryptDestroyHash(hHash);
269     ok(result, "%08lx\n", GetLastError());
270 }    
271
272 static void test_block_cipher_modes()
273 {
274     static const BYTE plain[23] = { 
275         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 
276         0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
277     static const BYTE ecb[24] = {   
278         0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f, 
279         0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
280     static const BYTE cbc[24] = {   
281         0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
282         0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
283     static const BYTE cfb[24] = {   
284         0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
285         0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
286     HCRYPTKEY hKey;
287     BOOL result;
288     BYTE abData[24];
289     DWORD dwMode, dwLen;
290
291     result = derive_key(CALG_RC2, &hKey, 40);
292     if (!result) return;
293
294     memcpy(abData, plain, sizeof(abData));
295
296     dwMode = CRYPT_MODE_ECB;
297     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
298     ok(result, "%08lx\n", GetLastError());
299
300     SetLastError(ERROR_SUCCESS);
301     dwLen = 23;
302     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
303     ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)), 
304        "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
305
306     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
307     ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)), 
308        "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
309
310     dwMode = CRYPT_MODE_CBC;
311     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
312     ok(result, "%08lx\n", GetLastError());
313     
314     dwLen = 23;
315     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
316     ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)), 
317        "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
318
319     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
320     ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)), 
321        "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
322
323     dwMode = CRYPT_MODE_CFB;
324     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
325     ok(result, "%08lx\n", GetLastError());
326     
327     dwLen = 16;
328     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen, 24);
329     ok(result && dwLen == 16, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
330
331     dwLen = 7;
332     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+16, &dwLen, 8);
333     ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)), 
334        "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
335     
336     dwLen = 8;
337     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen);
338     ok(result && dwLen == 8, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
339
340     dwLen = 16;
341     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+8, &dwLen);
342     ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)), 
343        "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
344
345     dwMode = CRYPT_MODE_OFB;
346     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
347     ok(result, "%08lx\n", GetLastError());
348     
349     dwLen = 23;
350     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
351     ok(!result && GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
352 }
353
354 static void test_3des112()
355 {
356     HCRYPTKEY hKey;
357     BOOL result;
358     DWORD dwLen;
359     unsigned char pbData[16];
360     int i;
361
362     result = derive_key(CALG_3DES_112, &hKey, 0);
363     if (!result) {
364         /* rsaenh compiled without OpenSSL */
365         ok(GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
366         return;
367     }
368
369     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
370     
371     dwLen = 13;
372     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
373     ok(result, "%08lx\n", GetLastError());
374     
375     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
376     ok(result, "%08lx\n", GetLastError());
377
378     result = CryptDestroyKey(hKey);
379     ok(result, "%08lx\n", GetLastError());
380 }
381
382 static void test_des() 
383 {
384     HCRYPTKEY hKey;
385     BOOL result;
386     DWORD dwLen, dwMode;
387     unsigned char pbData[16];
388     int i;
389
390     result = derive_key(CALG_DES, &hKey, 56);
391     if (!result) {
392         /* rsaenh compiled without OpenSSL */
393         ok(GetLastError()==NTE_BAD_ALGID, "%08lx\n", GetLastError());
394         return;
395     }
396
397     dwMode = CRYPT_MODE_ECB;
398     result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
399     ok(result, "%08lx\n", GetLastError());
400     
401     dwLen = sizeof(DWORD);
402     result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
403     ok(result, "%08lx\n", GetLastError());
404     
405     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
406     
407     dwLen = 13;
408     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
409     ok(result, "%08lx\n", GetLastError());
410     
411     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
412     ok(result, "%08lx\n", GetLastError());
413
414     result = CryptDestroyKey(hKey);
415     ok(result, "%08lx\n", GetLastError());
416 }
417
418 static void test_3des()
419 {
420     HCRYPTKEY hKey;
421     BOOL result;
422     DWORD dwLen;
423     unsigned char pbData[16];
424     static const BYTE des3[16] = { 
425         0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3, 
426         0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
427     int i;
428
429     result = derive_key(CALG_3DES, &hKey, 0);
430     if (!result) return;
431
432     for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
433     
434     dwLen = 13;
435     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
436     ok(result, "%08lx\n", GetLastError());
437     
438     ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
439     
440     result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
441     ok(result, "%08lx\n", GetLastError());
442
443     result = CryptDestroyKey(hKey);
444     ok(result, "%08lx\n", GetLastError());
445 }
446
447 static void test_rc2()
448 {
449     static const BYTE rc2encrypted[16] = { 
450         0x02, 0x34, 0x7d, 0xf6, 0x1d, 0xc5, 0x9b, 0x8b, 
451         0x2e, 0x0d, 0x63, 0x80, 0x72, 0xc1, 0xc2, 0xb1 };
452     HCRYPTHASH hHash;
453     HCRYPTKEY hKey;
454     BOOL result;
455     DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
456     BYTE *pbTemp;
457     unsigned char pbData[2000], pbHashValue[16];
458     int i;
459     
460     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
461
462     /* MD2 Hashing */
463     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
464     if (!result) {
465         ok(GetLastError()==NTE_BAD_ALGID, "%08lx\n", GetLastError());
466     } else {
467         result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
468         ok(result, "%08lx\n", GetLastError());
469
470         dwLen = 16;
471         result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
472         ok(result, "%08lx\n", GetLastError());
473
474         result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
475         ok(result, "%08lx\n", GetLastError());
476
477         dwLen = sizeof(DWORD);
478         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
479         ok(result, "%08lx\n", GetLastError());
480
481         dwMode = CRYPT_MODE_CBC;
482         result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
483         ok(result, "%08lx\n", GetLastError());
484
485         dwLen = sizeof(DWORD);
486         result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
487         ok(result, "%08lx\n", GetLastError());
488
489         dwLen = sizeof(DWORD);
490         result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
491         ok(result, "%08lx\n", GetLastError());
492
493         dwLen = sizeof(DWORD);
494         result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
495         ok(result, "%08lx\n", GetLastError());
496
497         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
498         ok(result, "%08lx\n", GetLastError());
499         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
500         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
501         HeapFree(GetProcessHeap(), 0, pbTemp);
502
503         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
504         ok(result, "%08lx\n", GetLastError());
505         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
506         CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
507         HeapFree(GetProcessHeap(), 0, pbTemp);
508
509         dwLen = sizeof(DWORD);
510         CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
511
512         result = CryptDestroyHash(hHash);
513         ok(result, "%08lx\n", GetLastError());
514
515         dwDataLen = 13;
516         result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
517         ok(result, "%08lx\n", GetLastError());
518
519         ok(!memcmp(pbData, rc2encrypted, 8), "RC2 encryption failed!\n");
520
521         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
522         ok(result, "%08lx\n", GetLastError());
523         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
524         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
525         HeapFree(GetProcessHeap(), 0, pbTemp);
526
527         result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
528         ok(result, "%08lx\n", GetLastError());
529
530         result = CryptDestroyKey(hKey);
531         ok(result, "%08lx\n", GetLastError());
532     }
533 }
534
535 static void test_rc4()
536 {
537     static const BYTE rc4[16] = { 
538         0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0, 
539         0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };    
540     BOOL result;
541     HCRYPTHASH hHash;
542     HCRYPTKEY hKey;
543     DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
544     unsigned char pbData[2000], *pbTemp;
545     unsigned char pszBuffer[256];
546     int i;
547
548     for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
549
550     /* MD2 Hashing */
551     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
552     if (!result) {
553         /* rsaenh compiled without OpenSSL */
554         ok(GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
555     } else {
556         result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
557            ok(result, "%08lx\n", GetLastError());
558
559         dwLen = 16;
560         result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
561         ok(result, "%08lx\n", GetLastError());
562
563         result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
564         ok(result, "%08lx\n", GetLastError());
565
566         dwLen = sizeof(DWORD);
567         result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
568         ok(result, "%08lx\n", GetLastError());
569
570         dwLen = sizeof(DWORD);
571         result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
572         ok(result, "%08lx\n", GetLastError());
573
574         result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
575         ok(result, "%08lx\n", GetLastError());
576         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
577         CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
578         HeapFree(GetProcessHeap(), 0, pbTemp);
579
580         result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
581         ok(result, "%08lx\n", GetLastError());
582         pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
583         CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
584         HeapFree(GetProcessHeap(), 0, pbTemp);
585
586         dwLen = sizeof(DWORD);
587         CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
588
589         result = CryptDestroyHash(hHash);
590         ok(result, "%08lx\n", GetLastError());
591
592         dwDataLen = 16;
593         result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
594         ok(result, "%08lx\n", GetLastError());
595
596         ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
597
598         result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
599         ok(result, "%08lx\n", GetLastError());
600
601         result = CryptDestroyKey(hKey);
602         ok(result, "%08lx\n", GetLastError());
603     }
604 }
605
606 static void test_hmac() {
607     HCRYPTKEY hKey;
608     HCRYPTHASH hHash;
609     BOOL result;
610     HMAC_INFO hmacInfo = { CALG_MD2, NULL, 0, NULL, 0 };
611     DWORD dwLen;
612     BYTE abData[256];
613     static const BYTE hmac[16] = { 
614         0xfd, 0x16, 0xb5, 0xb6, 0x13, 0x1c, 0x2b, 0xd6, 
615         0x0a, 0xc7, 0xae, 0x92, 0x76, 0xa3, 0x05, 0x71 };
616     int i;
617
618     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
619
620     if (!derive_key(CALG_RC2, &hKey, 56)) return;
621
622     result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
623     ok(result, "%08lx\n", GetLastError());
624     if (!result) return;
625
626     result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
627     ok(result, "%08lx\n", GetLastError());
628
629     result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
630     ok(result, "%08lx\n", GetLastError());
631
632     dwLen = sizeof(abData)/sizeof(BYTE);
633     result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
634     ok(result, "%08lx\n", GetLastError());
635
636     ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
637     
638     result = CryptDestroyHash(hHash);
639     ok(result, "%08lx\n", GetLastError());
640     
641     result = CryptDestroyKey(hKey);
642     ok(result, "%08lx\n", GetLastError());
643
644     /* Provoke errors */
645     result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
646     ok(!result && GetLastError() == NTE_BAD_KEY, "%08lx\n", GetLastError());
647 }
648
649 static void test_mac() {
650     HCRYPTKEY hKey;
651     HCRYPTHASH hHash;
652     BOOL result;
653     DWORD dwLen;
654     BYTE abData[256], abEnc[264];
655     static const BYTE mac[8] = { 0x0d, 0x3e, 0x15, 0x6b, 0x85, 0x63, 0x5c, 0x11 };
656     int i;
657
658     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
659     for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
660
661     if (!derive_key(CALG_RC2, &hKey, 56)) return;
662
663     dwLen = 256;
664     result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abEnc, &dwLen, 264);
665     ok (result && dwLen == 264, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
666     
667     result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
668     ok(result, "%08lx\n", GetLastError());
669     if (!result) return;
670
671     result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
672     ok(result, "%08lx\n", GetLastError());
673
674     dwLen = sizeof(abData)/sizeof(BYTE);
675     result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
676     ok(result && dwLen == 8, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
677
678     ok(!memcmp(abData, mac, sizeof(mac)), "MAC failed!\n");
679     
680     result = CryptDestroyHash(hHash);
681     ok(result, "%08lx\n", GetLastError());
682     
683     result = CryptDestroyKey(hKey);
684     ok(result, "%08lx\n", GetLastError());
685     
686     /* Provoke errors */
687     if (!derive_key(CALG_RC4, &hKey, 56)) return;
688
689     result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
690     ok(!result && GetLastError() == NTE_BAD_KEY, "%08lx\n", GetLastError());
691
692     result = CryptDestroyKey(hKey);
693     ok(result, "%08lx\n", GetLastError());
694 }
695
696 static void test_import_private() 
697 {
698     DWORD dwLen;
699     HCRYPTKEY hKeyExchangeKey, hSessionKey;
700     BOOL result;
701     BYTE abPlainPrivateKey[596] = {
702         0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
703         0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
704         0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
705         0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
706         0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
707         0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
708         0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
709         0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
710         0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
711         0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
712         0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
713         0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
714         0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
715         0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
716         0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
717         0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
718         0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
719         0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
720         0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
721         0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
722         0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
723         0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
724         0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
725         0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
726         0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
727         0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
728         0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
729         0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
730         0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
731         0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
732         0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
733         0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
734         0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
735         0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
736         0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
737         0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
738         0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
739         0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
740         0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
741         0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
742         0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
743         0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
744         0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
745         0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
746         0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
747         0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
748         0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
749         0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
750         0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
751         0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
752         0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
753         0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
754         0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
755         0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
756         0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
757         0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
758         0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
759         0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
760         0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
761         0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
762         0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
763         0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
764         0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
765         0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
766         0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
767         0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
768         0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
769         0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
770         0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
771         0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
772         0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
773         0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
774         0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
775         0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
776         0xf2, 0x5d, 0x58, 0x07
777     };
778     BYTE abSessionKey[148] = {
779         0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
780         0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
781         0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
782         0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
783         0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
784         0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
785         0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
786         0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
787         0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
788         0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
789         0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
790         0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
791         0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
792         0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
793         0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
794         0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
795         0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
796         0x04, 0x8c, 0x49, 0x92
797     };
798     BYTE abEncryptedMessage[12] = {
799         0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
800         0x1c, 0xfd, 0xde, 0x71
801     };
802             
803     dwLen = (DWORD)sizeof(abPlainPrivateKey);
804     result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
805     if (!result) {
806         /* rsaenh compiled without OpenSSL */
807         ok(GetLastError() == NTE_FAIL, "%08lx\n", GetLastError());
808         return;
809     }
810
811     dwLen = (DWORD)sizeof(abSessionKey);
812     result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
813     ok(result, "%08lx\n", GetLastError());
814     if (!result) return;
815
816     dwLen = (DWORD)sizeof(abEncryptedMessage);
817     result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
818     ok(result && dwLen == 12 && !strcmp(abEncryptedMessage, "Wine rocks!"), 
819        "%08lx, len: %ld\n", GetLastError(), dwLen);
820     
821     if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
822
823     dwLen = (DWORD)sizeof(abSessionKey);
824     result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
825     ok(result, "%08lx\n", GetLastError());
826     if (!result) return;
827
828     dwLen = (DWORD)sizeof(abSessionKey);
829     result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
830     ok(result, "%08lx\n", GetLastError());
831     if (!result) return;
832 }
833
834 static void test_verify_signature() {
835     HCRYPTHASH hHash;
836     HCRYPTKEY hPubSignKey;
837     BYTE abData[] = "Wine rocks!";
838     BOOL result;
839     BYTE abPubKey[148] = {
840         0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 
841         0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 
842         0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19, 
843         0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27, 
844         0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8, 
845         0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda, 
846         0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a, 
847         0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc, 
848         0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c, 
849         0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c, 
850         0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89, 
851         0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b, 
852         0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa, 
853         0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63, 
854         0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff, 
855         0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49, 
856         0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87, 
857         0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7, 
858         0xe1, 0x21, 0x50, 0xac
859     };
860     /* md2 with hash oid */
861     BYTE abSignatureMD2[128] = {
862         0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67, 
863         0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b, 
864         0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda, 
865         0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59, 
866         0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a, 
867         0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34, 
868         0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40, 
869         0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7, 
870         0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0, 
871         0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06, 
872         0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51, 
873         0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f, 
874         0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46, 
875         0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25, 
876         0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0, 
877         0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
878     };
879     /* md2 without hash oid */
880     BYTE abSignatureMD2NoOID[128] = {
881         0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d, 
882         0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19, 
883         0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd, 
884         0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4, 
885         0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65, 
886         0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99, 
887         0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf, 
888         0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc, 
889         0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0, 
890         0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01, 
891         0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7, 
892         0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f, 
893         0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a, 
894         0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9, 
895         0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06, 
896         0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
897     };
898     /* md4 with hash oid */
899     BYTE abSignatureMD4[128] = {
900         0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51, 
901         0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b, 
902         0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2, 
903         0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e, 
904         0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13, 
905         0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9, 
906         0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f, 
907         0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96, 
908         0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9, 
909         0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e, 
910         0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0, 
911         0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe, 
912         0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18, 
913         0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab, 
914         0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3, 
915         0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
916     };
917     /* md4 without hash oid */
918     BYTE abSignatureMD4NoOID[128] = {
919         0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda, 
920         0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24, 
921         0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0, 
922         0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36, 
923         0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85, 
924         0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3, 
925         0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f, 
926         0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9, 
927         0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06, 
928         0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f, 
929         0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb, 
930         0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96, 
931         0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f, 
932         0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9, 
933         0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb, 
934         0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
935     }; 
936     /* md5 with hash oid */
937     BYTE abSignatureMD5[128] = {
938         0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5, 
939         0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f, 
940         0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7, 
941         0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98, 
942         0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec, 
943         0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5, 
944         0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04, 
945         0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b, 
946         0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95, 
947         0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c, 
948         0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29, 
949         0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9, 
950         0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c, 
951         0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90, 
952         0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e, 
953         0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
954     };
955     /* md5 without hash oid */
956     BYTE abSignatureMD5NoOID[128] = {
957         0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f, 
958         0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75, 
959         0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f, 
960         0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d, 
961         0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f, 
962         0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49, 
963         0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8, 
964         0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c, 
965         0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23, 
966         0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19, 
967         0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb, 
968         0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3, 
969         0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b, 
970         0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b, 
971         0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5, 
972         0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
973     };
974     /* sha with hash oid */
975     BYTE abSignatureSHA[128] = {
976         0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91, 
977         0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd, 
978         0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24, 
979         0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94, 
980         0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f, 
981         0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a, 
982         0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52, 
983         0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20, 
984         0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5, 
985         0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a, 
986         0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff, 
987         0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53, 
988         0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00, 
989         0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e, 
990         0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98, 
991         0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
992     };
993     /* sha without hash oid */
994     BYTE abSignatureSHANoOID[128] = {
995         0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6, 
996         0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a, 
997         0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f, 
998         0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37, 
999         0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65, 
1000         0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe, 
1001         0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6, 
1002         0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe, 
1003         0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c, 
1004         0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4, 
1005         0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80, 
1006         0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a, 
1007         0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00, 
1008         0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd, 
1009         0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67, 
1010         0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1011     }; 
1012     
1013     result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1014     ok(result, "%08lx\n", GetLastError());
1015     if (!result) return;
1016
1017     result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1018     ok(result, "%08lx\n", GetLastError());
1019     if (!result) return;
1020
1021     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1022     ok(result, "%08lx\n", GetLastError());
1023     if (!result) return;
1024
1025     result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1026     ok(result, "%08lx\n", GetLastError());
1027     if (!result) return;
1028
1029     result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1030     ok(result, "%08lx\n", GetLastError());
1031     if (!result) return;
1032
1033     /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about 
1034      * the OID at all. */
1035     /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1036     ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1037     if (result) return;*/
1038
1039     result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1040     ok(result, "%08lx\n", GetLastError());
1041     if (!result) return;
1042
1043     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1044     ok(result, "%08lx\n", GetLastError());
1045     if (!result) return;
1046
1047     result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1048     ok(result, "%08lx\n", GetLastError());
1049     if (!result) return;
1050
1051     result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1052     ok(result, "%08lx\n", GetLastError());
1053     if (!result) return;
1054
1055     result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1056     ok(result, "%08lx\n", GetLastError());
1057     if (!result) return;
1058
1059     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1060     ok(result, "%08lx\n", GetLastError());
1061     if (!result) return;
1062
1063     result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1064     ok(result, "%08lx\n", GetLastError());
1065     if (!result) return;
1066
1067     result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1068     ok(result, "%08lx\n", GetLastError());
1069     if (!result) return;
1070
1071     result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1072     ok(result, "%08lx\n", GetLastError());
1073     if (!result) return;
1074
1075     result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1076     ok(result, "%08lx\n", GetLastError());
1077     if (!result) return;
1078
1079     result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1080     ok(result, "%08lx\n", GetLastError());
1081     if (!result) return;
1082
1083     result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1084     ok(result, "%08lx\n", GetLastError());
1085     if (!result) return;
1086 }
1087
1088 void test_rsa_encrypt()
1089 {
1090     HCRYPTKEY hRSAKey;
1091     BYTE abData[2048] = "Wine rocks!";
1092     BOOL result;
1093     DWORD dwLen;
1094
1095     /* It is allowed to use the key exchange key for encryption/decryption */
1096     result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1097     ok (result, "%08lx\n", GetLastError());
1098     if (!result) return;
1099
1100     dwLen = 12;
1101     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1102     ok (result, "%08lx\n", GetLastError());
1103     if (!result) return;
1104
1105     result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1106     ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08lx\n", GetLastError());
1107     
1108     CryptDestroyKey(hRSAKey);
1109
1110     /* It is not allowed to use the signature key for encryption/decryption */
1111     result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1112     ok (result, "%08lx\n", GetLastError());
1113     if (!result) return;
1114
1115     dwLen = 12;
1116     result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1117     ok (!result && GetLastError() == NTE_BAD_KEY, "%08lx\n", GetLastError());
1118
1119     CryptDestroyKey(hRSAKey);
1120 }
1121         
1122 void test_schannel_provider()
1123 {
1124     HCRYPTPROV hProv;
1125     HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1126     HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1127     BOOL result;
1128     DWORD dwLen;
1129     SCHANNEL_ALG saSChannelAlg;
1130     CRYPT_DATA_BLOB data_blob;
1131     HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1132     BYTE abPlainPrivateKey[596] = {
1133         0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1134         0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1135         0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1136         0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1137         0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1138         0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1139         0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1140         0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1141         0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1142         0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1143         0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1144         0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1145         0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1146         0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1147         0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1148         0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1149         0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1150         0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1151         0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1152         0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1153         0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1154         0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1155         0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1156         0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1157         0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1158         0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1159         0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1160         0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1161         0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1162         0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1163         0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1164         0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1165         0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1166         0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1167         0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1168         0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1169         0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1170         0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1171         0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1172         0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1173         0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1174         0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1175         0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1176         0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1177         0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1178         0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1179         0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1180         0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1181         0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1182         0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1183         0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1184         0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1185         0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1186         0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1187         0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1188         0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1189         0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1190         0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1191         0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1192         0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1193         0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1194         0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1195         0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1196         0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1197         0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1198         0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1199         0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1200         0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1201         0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1202         0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1203         0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1204         0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1205         0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1206         0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1207         0xf2, 0x5d, 0x58, 0x07
1208     };
1209     BYTE abTLS1Master[140] = {
1210         0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00, 
1211         0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68, 
1212         0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97, 
1213         0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53, 
1214         0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24, 
1215         0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3, 
1216         0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8, 
1217         0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d, 
1218         0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e, 
1219         0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e, 
1220         0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40, 
1221         0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b, 
1222         0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb, 
1223         0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6, 
1224         0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac, 
1225         0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41, 
1226         0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4, 
1227         0xd3, 0x1e, 0x82, 0xb3
1228     };
1229     BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1230     BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1231     BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1232     BYTE abClientFinished[16] = "client finished";
1233     BYTE abData[16] = "Wine rocks!";
1234     BYTE abMD5Hash[16];
1235     static const BYTE abEncryptedData[16] = {
1236         0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1237         0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d    
1238     };
1239     static const BYTE abPRF[16] = {
1240         0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1241         0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1242     };
1243     static const BYTE abMD5[16] = {
1244         0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1245         0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1246     };
1247     
1248     result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1249     ok (result, "%08lx\n", GetLastError());
1250     if (!result) return;
1251     
1252     /* To get deterministic results, we import the TLS1 master secret (which
1253      * is typically generated from a random generator). Therefore, we need
1254      * an RSA key. */
1255     dwLen = (DWORD)sizeof(abPlainPrivateKey);
1256     result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1257     ok (result, "%08lx\n", GetLastError());
1258     if (!result) return;
1259
1260     dwLen = (DWORD)sizeof(abTLS1Master);
1261     result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1262     ok (result, "%08lx\n", GetLastError());
1263     if (!result) return;    
1264    
1265     /* Setting the TLS1 client and server random parameters, as well as the 
1266      * MAC and encryption algorithm parameters. */
1267     data_blob.cbData = 33;
1268     data_blob.pbData = abClientSecret;
1269     result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1270     ok (result, "%08lx\n", GetLastError());
1271     if (!result) return;
1272
1273     data_blob.cbData = 33;
1274     data_blob.pbData = abServerSecret;
1275     result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1276     ok (result, "%08lx\n", GetLastError());
1277     if (!result) return;
1278     
1279     saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1280     saSChannelAlg.Algid = CALG_DES;
1281     saSChannelAlg.cBits = 64;
1282     saSChannelAlg.dwFlags = 0;
1283     saSChannelAlg.dwReserved = 0;
1284     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1285     ok (result, "%08lx\n", GetLastError());
1286     if (!result) return;
1287
1288     saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1289     saSChannelAlg.Algid = CALG_MD5;
1290     saSChannelAlg.cBits = 128;
1291     saSChannelAlg.dwFlags = 0;
1292     saSChannelAlg.dwReserved = 0;
1293     result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1294     ok (result, "%08lx\n", GetLastError());
1295     if (!result) return;
1296
1297     /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1298      * (Keys can only be derived from hashes, not from other keys.) */
1299     result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1300     ok (result, "%08lx\n", GetLastError());
1301     if (!result) return;
1302
1303     /* Deriving the server write encryption key from the master hash */
1304     result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1305     ok (result, "%08lx\n", GetLastError());
1306     if (!result) return;
1307
1308     /* Encrypting some data with the server write encryption key and checking the result. */
1309     dwLen = 12;
1310     result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1311     ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08lx\n", GetLastError());
1312
1313     /* Second test case: Test the TLS1 pseudo random number function. */
1314     result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1315     ok (result, "%08lx\n", GetLastError());
1316     if (!result) return;
1317
1318     /* Set the label and seed parameters for the random number function */
1319     data_blob.cbData = 36;
1320     data_blob.pbData = abHashedHandshakes;
1321     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1322     ok (result, "%08lx\n", GetLastError());
1323     if (!result) return;
1324
1325     data_blob.cbData = 15;
1326     data_blob.pbData = abClientFinished;
1327     result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1328     ok (result, "%08lx\n", GetLastError());
1329     if (!result) return;
1330
1331     /* Generate some pseudo random bytes and check if they are correct. */
1332     dwLen = (DWORD)sizeof(abData);
1333     result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1334     ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)), 
1335         "%08lx\n", GetLastError());
1336
1337     /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1338      * Hash some data with the HMAC. Compare results. */
1339     result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
1340     ok (result, "%08lx\n", GetLastError());
1341     if (!result) return;
1342     
1343     result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
1344     ok (result, "%08lx\n", GetLastError());
1345     if (!result) return;
1346
1347     result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
1348     ok (result, "%08lx\n", GetLastError());
1349     if (!result) return;
1350
1351     result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
1352     ok (result, "%08lx\n", GetLastError());
1353     if (!result) return;
1354
1355     dwLen = (DWORD)sizeof(abMD5Hash);
1356     result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
1357     ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08lx\n", GetLastError());
1358
1359     CryptDestroyHash(hHMAC);
1360     CryptDestroyHash(hTLS1PRF);
1361     CryptDestroyHash(hMasterHash);
1362     CryptDestroyKey(hServerWriteMACKey);
1363     CryptDestroyKey(hServerWriteKey);
1364     CryptDestroyKey(hRSAKey);
1365     CryptDestroyKey(hMasterSecret);
1366     CryptReleaseContext(hProv, 0);
1367 }
1368
1369 void test_enum_container()
1370 {
1371     BYTE abContainerName[256];
1372     DWORD dwBufferLen;
1373     BOOL result, fFound = FALSE;
1374
1375     /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1376      * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1377     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
1378     ok (result && dwBufferLen == MAX_PATH + 1, "%08lx\n", GetLastError());
1379
1380     /* If the result fits into abContainerName dwBufferLen is left untouched */
1381     dwBufferLen = (DWORD)sizeof(abContainerName);
1382     result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
1383     ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08lx\n", GetLastError());
1384     
1385     /* We only check, if the currently open 'winetest' container is among the enumerated. */
1386     do {
1387         if (!strcmp(abContainerName, "winetest")) fFound = TRUE;
1388         dwBufferLen = (DWORD)sizeof(abContainerName);
1389     } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
1390         
1391     ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08lx\n", fFound, GetLastError());
1392 }
1393
1394 START_TEST(rsaenh)
1395 {
1396     if (!init_environment()) 
1397         return;
1398     test_prov();
1399     test_gen_random();
1400     test_hashes();
1401     test_rc4();
1402     test_rc2();
1403     test_des();
1404     test_3des112();
1405     test_3des();
1406     test_hmac();
1407     test_mac();
1408     test_block_cipher_modes();
1409     test_import_private();
1410     test_verify_signature();
1411     test_rsa_encrypt();
1412     test_enum_container();
1413     clean_up_environment();
1414     test_schannel_provider();
1415 }