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