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