ReactOS  0.4.12-dev-918-g6c6e7b8
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 
740  dwMode = CRYPT_MODE_ECB;
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 
763  dwMode = CRYPT_MODE_CBC;
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 
781  dwMode = CRYPT_MODE_CFB;
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 
803  dwMode = CRYPT_MODE_OFB;
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 
934  dwMode = CRYPT_MODE_ECB;
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 
1017  dwMode = CRYPT_MODE_ECB;
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 
1417  dwMode = CRYPT_MODE_CBC;
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 < ARRAY_SIZE(abData); 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 = ARRAY_SIZE(abData);
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 < ARRAY_SIZE(abData); i++) abData[i] = (BYTE)i;
1859  for (i=0; i < ARRAY_SIZE(abData); 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 = ARRAY_SIZE(abData);
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  DWORD err;
2286 
2287  /* It is allowed to use the key exchange key for encryption/decryption */
2289  ok (result, "%08x\n", GetLastError());
2290  if (!result) return;
2291 
2292  dwLen = 12;
2293  result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
2294  if(!ENHANCED_PROV && !result && GetLastError() == NTE_BAD_KEY)
2295  {
2296  CryptDestroyKey(hRSAKey);
2297  return;
2298  }
2299  ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
2300  ok(dwLen == 128, "Unexpected length %d\n", dwLen);
2301  /* PKCS1 V1.5 */
2302  dwLen = 12;
2303  result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
2304  ok (result, "%08x\n", GetLastError());
2305  if (!result) return;
2306 
2307  result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
2308  ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
2309 
2310  /* OAEP, RFC 8017 PKCS #1 V2.2 */
2311  /* Test minimal buffer length requirement */
2312  dwLen = 1;
2313  SetLastError(0xdeadbeef);
2314  result = CryptEncrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen, 20 * 2 + 2);
2315  err = GetLastError();
2316  ok(!result && err == ERROR_MORE_DATA, "%08x\n", err);
2317 
2318  /* Test data length limit */
2319  dwLen = sizeof(abData) - (20 * 2 + 2) + 1;
2320  result = CryptEncrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen, (DWORD)sizeof(abData));
2321  err = GetLastError();
2322  ok(!result && err == NTE_BAD_LEN, "%08x\n", err);
2323 
2324  /* Test malformed data */
2325  dwLen = 12;
2326  SetLastError(0xdeadbeef);
2327  memcpy(abData, "Wine rocks!", dwLen);
2328  result = CryptDecrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen);
2329  err = GetLastError();
2330  /* NTE_DOUBLE_ENCRYPT on xp or 2003 */
2331  ok(!result && (err == NTE_BAD_DATA || broken(err == NTE_DOUBLE_ENCRYPT)), "%08x\n", err);
2332 
2333  /* Test decrypt with insufficient buffer */
2334  dwLen = 12;
2335  SetLastError(0xdeadbeef);
2336  memcpy(abData, "Wine rocks!", 12);
2337  result = CryptEncrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen, (DWORD)sizeof(abData));
2338  ok(result, "%08x\n", GetLastError());
2339  dwLen = 11;
2340  SetLastError(0xdeadbeef);
2341  result = CryptDecrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen);
2342  err = GetLastError();
2343  /* broken on xp or 2003 */
2344  ok((!result && dwLen == 11 && err == NTE_BAD_DATA) || broken(result == TRUE && dwLen == 12 && err == ERROR_NO_TOKEN),
2345  "%08x %d %08x\n", result, dwLen, err);
2346 
2347  /* Test normal encryption and decryption */
2348  dwLen = 12;
2349  memcpy(abData, "Wine rocks!", dwLen);
2350  result = CryptEncrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen, (DWORD)sizeof(abData));
2351  ok(result, "%08x\n", GetLastError());
2352  result = CryptDecrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen);
2353  ok(result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
2354 
2355  dwVal = 0xdeadbeef;
2356  dwLen = sizeof(DWORD);
2357  result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2358  ok(result, "%08x\n", GetLastError());
2359  ok(dwVal ==
2361  broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2362  "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2363  " got %08x\n", dwVal);
2364 
2365  /* An RSA key doesn't support salt */
2366  result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
2367  ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == NTE_NOT_FOUND /* Win7 */),
2368  "expected NTE_BAD_KEY or NTE_NOT_FOUND, got %08x\n", GetLastError());
2369 
2370  /* The key exchange key's public key may be exported.. */
2371  result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2372  ok(result, "%08x\n", GetLastError());
2373  /* but its private key may not be. */
2374  SetLastError(0xdeadbeef);
2375  result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2376  ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
2377  broken(result), /* Win9x/NT4 */
2378  "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
2379  /* Setting the permissions of the key exchange key isn't allowed, either. */
2380  dwVal |= CRYPT_EXPORT;
2381  SetLastError(0xdeadbeef);
2382  result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2383  ok(!result &&
2385  "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
2386 
2387  CryptDestroyKey(hRSAKey);
2388 
2389  /* It is not allowed to use the signature key for encryption/decryption */
2390  result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
2391  ok (result, "%08x\n", GetLastError());
2392  if (!result) return;
2393 
2394  dwVal = 0xdeadbeef;
2395  dwLen = sizeof(DWORD);
2396  result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2397  ok(result, "%08x\n", GetLastError());
2398  ok(dwVal ==
2400  broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2401  "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2402  " got %08x\n", dwVal);
2403 
2404  /* The signature key's public key may also be exported.. */
2405  result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2406  ok(result, "%08x\n", GetLastError());
2407  /* but its private key may not be. */
2408  SetLastError(0xdeadbeef);
2409  result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2410  ok((!result && GetLastError() == NTE_BAD_KEY_STATE) ||
2411  broken(result), /* Win9x/NT4 */
2412  "expected NTE_BAD_KEY_STATE, got %08x\n", GetLastError());
2413  /* Setting the permissions of the signature key isn't allowed, either. */
2414  dwVal |= CRYPT_EXPORT;
2415  SetLastError(0xdeadbeef);
2416  result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2417  ok(!result &&
2419  "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08x\n", GetLastError());
2420 
2421  dwLen = 12;
2422  result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
2423  ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
2424 
2425  CryptDestroyKey(hRSAKey);
2426 }
2427 
2428 static void test_import_export(void)
2429 {
2430  DWORD dwLen, dwDataLen, dwVal;
2431  HCRYPTKEY hPublicKey, hPrivKey;
2432  BOOL result;
2433  ALG_ID algID;
2434  BYTE emptyKey[2048], *exported_key, *exported_key2;
2435  static BYTE abPlainPublicKey[84] = {
2436  0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
2437  0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
2438  0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
2439  0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2440  0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2441  0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2442  0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2443  0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2444  0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2445  0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2446  0x11, 0x11, 0x11, 0x11
2447  };
2448  static BYTE priv_key_with_high_bit[] = {
2449  0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2450  0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
2451  0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
2452  0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
2453  0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
2454  0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
2455  0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
2456  0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
2457  0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
2458  0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
2459  0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
2460  0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2461  0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2462  0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2463  0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2464  0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2465  0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2466  0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2467  0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2468  0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2469  0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2470  0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2471  0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2472  0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2473  0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2474  0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2475  0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2476  0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2477  0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2478  0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2479  0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2480  0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2481  0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2482  0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2483  0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2484  0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2485  0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2486  0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2487  0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2488  0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2489  0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2490  0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2491  0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2492  0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2493  0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2494  0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2495  0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2496  0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2497  0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2498  0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2499  0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2500  0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2501  0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2502  0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2503  0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2504  0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2505  0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2506  0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2507  0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2508  0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2509  0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2510  0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2511  0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2512  0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2513  0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2514  0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2515  0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2516  0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2517  0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2518  0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2519  0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2520  0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2521  0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2522  0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2523  0xb6, 0x5f, 0x01, 0x5e
2524  };
2525  static const BYTE expected_exported_priv_key[] = {
2526  0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2527  0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
2528  0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
2529  0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
2530  0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
2531  0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
2532  0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
2533  0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
2534  0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
2535  0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
2536  0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
2537  0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2538  0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2539  0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2540  0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2541  0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2542  0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2543  0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2544  0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2545  0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2546  0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2547  0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2548  0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2549  0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2550  0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2551  0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2552  0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2553  0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2554  0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2555  0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2556  0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2557  0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2558  0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2559  0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2560  0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2561  0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2562  0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2563  0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2564  0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2565  0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2566  0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2567  0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2568  0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2569  0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2570  0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2571  0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2572  0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2573  0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2574  0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2575  0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2576  0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2577  0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2578  0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2579  0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2580  0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2581  0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2582  0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2583  0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2584  0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2585  0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2586  0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2587  0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2588  0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2589  0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2590  0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2591  0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2592  0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2593  0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2594  0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2595  0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2596  0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2597  0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2598  0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2599  0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2600  0xb6, 0x5f, 0x01, 0x5e
2601  };
2602 
2603  dwLen=84;
2604  result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
2605  ok(result, "failed to import the public key\n");
2606 
2607  dwDataLen=sizeof(algID);
2608  result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
2609  ok(result, "failed to get the KP_ALGID from the imported public key\n");
2610  ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
2611 
2612  dwVal = 0xdeadbeef;
2613  dwDataLen = sizeof(DWORD);
2614  result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
2615  ok(result, "%08x\n", GetLastError());
2616  ok(dwVal ==
2618  broken(dwVal == 0xffffffff), /* Win9x/NT4 */
2619  "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
2620  " got %08x\n", dwVal);
2621  result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
2622  ok(result, "failed to export the fresh imported public key\n");
2623  ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
2624  ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
2625 
2626  CryptDestroyKey(hPublicKey);
2627 
2628  /* imports into AT_SIGNATURE key container */
2629  result = CryptImportKey(hProv, priv_key_with_high_bit,
2630  sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
2631  ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2632 
2633  result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
2634  ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2635  exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2636  result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
2637  &dwDataLen);
2638  ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2639 
2640  ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n",
2641  dwDataLen);
2642  ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
2643  "unexpected value\n");
2644 
2645  HeapFree(GetProcessHeap(), 0, exported_key);
2646 
2647  CryptDestroyKey(hPrivKey);
2648 
2649  /* imports into AT_KEYEXCHANGE key container */
2651  sizeof(abPlainPrivateKey), 0, 0, &hPrivKey);
2652  ok(result, "CryptImportKey failed: %08x\n", GetLastError());
2653 
2654  result = CryptExportKey(hPrivKey, 0, PUBLICKEYBLOB, 0, NULL, &dwDataLen);
2655  ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2656  exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2657  result = CryptExportKey(hPrivKey, 0, PUBLICKEYBLOB, 0, exported_key,
2658  &dwDataLen);
2659  ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2660  CryptDestroyKey(hPrivKey);
2661 
2662  /* getting the public key from AT_KEYEXCHANGE, and compare it */
2663  result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hPrivKey);
2664  ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2665  result = CryptExportKey(hPrivKey, 0, PUBLICKEYBLOB, 0, NULL, &dwDataLen);
2666  ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2667  exported_key2 = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2668  result = CryptExportKey(hPrivKey, 0, PUBLICKEYBLOB, 0, exported_key2,
2669  &dwDataLen);
2670  ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2671  CryptDestroyKey(hPrivKey);
2672 
2673  result = !memcmp(exported_key, exported_key2, dwDataLen);
2674  ok(result, "unexpected value\n");
2675  if (!result && winetest_debug > 1) {
2676  trace("Expected public key (%u):\n", dwDataLen);
2677  trace_hex(exported_key, dwDataLen);
2678  trace("AT_KEYEXCHANGE public key (%u):\n", dwDataLen);
2679  trace_hex(exported_key2, dwDataLen);
2680  }
2681  HeapFree(GetProcessHeap(), 0, exported_key2);
2682 
2683  /* importing a public key doesn't update key container at all */
2684  result = CryptImportKey(hProv, abPlainPublicKey,
2685  sizeof(abPlainPublicKey), 0, 0, &hPublicKey);
2686  ok(result, "failed to import the public key\n");
2687  CryptDestroyKey(hPublicKey);
2688 
2689  /* getting the public key again, and compare it */
2690  result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hPrivKey);
2691  ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
2692  result = CryptExportKey(hPrivKey, 0, PUBLICKEYBLOB, 0, NULL, &dwDataLen);
2693  ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2694  exported_key2 = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2695  result = CryptExportKey(hPrivKey, 0, PUBLICKEYBLOB, 0, exported_key2,
2696  &dwDataLen);
2697  ok(result, "CryptExportKey failed: %08x\n", GetLastError());
2698  CryptDestroyKey(hPrivKey);
2699 
2700  result = !memcmp(exported_key, exported_key2, dwDataLen);
2701  ok(result, "unexpected value\n");
2702  if (!result && winetest_debug > 1) {
2703  trace("Expected public key (%u):\n", dwDataLen);
2704  trace_hex(exported_key, dwDataLen);
2705  trace("AT_KEYEXCHANGE public key (%u):\n", dwDataLen);
2706  trace_hex(exported_key2, dwDataLen);
2707  }
2708 
2709  HeapFree(GetProcessHeap(), 0, exported_key);
2710  HeapFree(GetProcessHeap(), 0, exported_key2);
2711 }
2712 
2713 static void test_import_hmac(void)
2714 {
2715  /* Test cases from RFC 2202, section 3 */
2716  static const struct rfc2202_test_case {
2717  const char *key;
2718  DWORD key_len;
2719  const char *data;
2720  const DWORD data_len;
2721  const char *digest;
2722  } cases[] = {
2723  { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
2724  "\x0b\x0b\x0b\x0b", 20,
2725  "Hi There", 8,
2726  "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e"
2727  "\xf1\x46\xbe\x00" },
2728  { "Jefe", 4,
2729  "what do ya want for nothing?", 28,
2730  "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c"
2731  "\x25\x9a\x7c\x79" },
2732  { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2733  "\xaa\xaa\xaa\xaa", 20,
2734  "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2735  "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2736  "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2737  "\xdd\xdd", 50,
2738  "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f"
2739  "\x63\xf1\x75\xd3" },
2740  { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
2741  "\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25,
2742  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2743  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2744  "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2745  "\xcd\xcd", 50,
2746  "\x4c\x90\x07\xF4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c"
2747  "\x2d\x72\x35\xda" },
2748  { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
2749  "\x0c\x0c\x0c\x0c", 20,
2750  "Test With Truncation", 20,
2751  "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32"
2752  "\x4a\x9a\x5a\x04" },
2753  { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2754  "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2755  "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2756  "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2757  "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2758  80,
2759  "Test Using Larger Than Block-Size Key - Hash Key First", 54,
2760  "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55"
2761  "\xed\x40\x21\x12" },
2762  { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2763  "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2764  "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2765  "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2766  "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2767  80,
2768  "Test Using Larger Than Block-Size Key and Larger "
2769  "Than One Block-Size Data", 73,
2770  "\xe8\xe9\x9D\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08"
2771  "\xbb\xff\x1a\x91" }
2772  };
2773  DWORD i;
2774 
2775  for (i = 0; i < ARRAY_SIZE(cases); i++)
2776  {
2777  const struct rfc2202_test_case *test_case = &cases[i];
2778  DWORD size = sizeof(BLOBHEADER) + sizeof(DWORD) + test_case->key_len;
2780 
2781  if (blob)
2782  {
2784  DWORD *key_len = (DWORD *)(header + 1);
2785  BYTE *key_bytes = (BYTE *)(key_len + 1);
2786  BOOL result;
2787  HCRYPTKEY key;
2788 
2789  header->bType = PLAINTEXTKEYBLOB;
2790  header->bVersion = CUR_BLOB_VERSION;
2791  header->reserved = 0;
2792  header->aiKeyAlg = CALG_RC2;
2793  *key_len = test_case->key_len;
2794  memcpy(key_bytes, test_case->key, *key_len);
2796  ok(result || broken(GetLastError() == NTE_BAD_FLAGS /* Win2k */), "CryptImportKey failed on test case %d: %08x\n", i, GetLastError());
2797  if (result)
2798  {
2799  HCRYPTHASH hash;
2800  HMAC_INFO hmac_info = { CALG_SHA1, 0 };
2801  BYTE digest[20];
2802  DWORD digest_size;
2803 
2805  ok(result, "CryptCreateHash failed on test case %d: %08x\n", i, GetLastError());
2806  result = CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&hmac_info, 0);
2807  ok(result, "CryptSetHashParam failed on test case %d: %08x\n", i, GetLastError());
2808  result = CryptHashData(hash, (const BYTE *)test_case->data, test_case->data_len, 0);
2809  ok(result, "CryptHashData failed on test case %d: %08x\n", i, GetLastError());
2810  digest_size = sizeof(digest);
2811  result = CryptGetHashParam(hash, HP_HASHVAL, digest, &digest_size, 0);
2812  ok(result, "CryptGetHashParam failed on test case %d: %08x\n", i, GetLastError());
2813  ok(!memcmp(digest, test_case->digest, sizeof(digest)), "Unexpected value on test case %d\n", i);
2816  }
2817  HeapFree(GetProcessHeap(), 0, blob);
2818  }
2819  }
2820 }
2821 
2822 static void test_schannel_provider(void)
2823 {
2824  HCRYPTPROV hProv;
2825  HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
2826  HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
2827  BOOL result;
2828  DWORD dwLen;
2829  SCHANNEL_ALG saSChannelAlg;
2830  CRYPT_DATA_BLOB data_blob;
2831  HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
2832  BYTE abTLS1Master[140] = {
2833  0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
2834  0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
2835  0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
2836  0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
2837  0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
2838  0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
2839  0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
2840  0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
2841  0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
2842  0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
2843  0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
2844  0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
2845  0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
2846  0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
2847  0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
2848  0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
2849  0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
2850  0xd3, 0x1e, 0x82, 0xb3
2851  };
2852  BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2853  BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2854  BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2855  BYTE abClientFinished[16] = "client finished";
2856  BYTE abData[16] = "Wine rocks!";
2857  BYTE abMD5Hash[16];
2858  static const BYTE abEncryptedData[16] = {
2859  0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2860  0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
2861  };
2862  static const BYTE abPRF[16] = {
2863  0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2864  0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2865  };
2866  static const BYTE abMD5[16] = {
2867  0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2868  0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2869  };
2870 
2872  if (!result)
2873  {
2874  win_skip("no PROV_RSA_SCHANNEL support\n");
2875  return;
2876  }
2877  ok (result, "%08x\n", GetLastError());
2878  if (result)
2880 
2882  ok (result, "%08x\n", GetLastError());
2883  if (!result) return;
2884 
2885  /* To get deterministic results, we import the TLS1 master secret (which
2886  * is typically generated from a random generator). Therefore, we need
2887  * an RSA key. */
2888  dwLen = (DWORD)sizeof(abPlainPrivateKey);
2889  result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
2890  ok (result, "%08x\n", GetLastError());
2891  if (!result) return;
2892 
2893  dwLen = (DWORD)sizeof(abTLS1Master);
2894  result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
2895  ok (result, "%08x\n", GetLastError());
2896  if (!result) return;
2897 
2898  /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
2899  * (Keys can only be derived from hashes, not from other keys.)
2900  * The hash can't be created yet because the key doesn't have the client
2901  * random or server random set.
2902  */
2903  result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2905  "expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2906 
2907  /* Setting the TLS1 client and server random parameters, as well as the
2908  * MAC and encryption algorithm parameters. */
2909  data_blob.cbData = 33;
2910  data_blob.pbData = abClientSecret;
2911  result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
2912  ok (result, "%08x\n", GetLastError());
2913  if (!result) return;
2914 
2915  data_blob.cbData = 33;
2916  data_blob.pbData = abServerSecret;
2917  result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
2918  ok (result, "%08x\n", GetLastError());
2919  if (!result) return;
2920 
2921  result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2922  ok (result ||
2923  broken(!result), /* Windows 8 and greater */
2924  "%08x\n", GetLastError());
2925  if (!result)
2926  {
2927  win_skip("Broken TLS1 hash creation\n");
2928  CryptDestroyKey(hRSAKey);
2929  CryptDestroyKey(hMasterSecret);
2932  return;
2933  }
2934 
2935  /* Deriving the server write encryption key from the master hash can't
2936  * succeed before the encryption key algorithm is set.
2937  */
2938  result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2939  ok (!result && GetLastError() == NTE_BAD_FLAGS,
2940  "expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
2941 
2942  CryptDestroyHash(hMasterHash);
2943 
2944  saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
2945  saSChannelAlg.Algid = CALG_DES;
2946  saSChannelAlg.cBits = 64;
2947  saSChannelAlg.dwFlags = 0;
2948  saSChannelAlg.dwReserved = 0;
2949  result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2950  ok (result, "%08x\n", GetLastError());
2951  if (!result) return;
2952 
2953  saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
2954  saSChannelAlg.Algid = CALG_MD5;
2955  saSChannelAlg.cBits = 128;
2956  saSChannelAlg.dwFlags = 0;
2957  saSChannelAlg.dwReserved = 0;
2958  result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
2959  ok (result, "%08x\n", GetLastError());
2960  if (!result) return;
2961 
2962  result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
2963  ok (result, "%08x\n", GetLastError());
2964  if (!result) return;
2965 
2966  /* Deriving the server write encryption key from the master hash */
2967  result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
2968  ok (result, "%08x\n", GetLastError());
2969  if (!result) return;
2970 
2971  /* Encrypting some data with the server write encryption key and checking the result. */
2972  dwLen = 12;
2973  result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
2974  ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
2975 
2976  /* Second test case: Test the TLS1 pseudo random number function. */
2977  result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
2978  ok (result, "%08x\n", GetLastError());
2979  if (!result) return;
2980 
2981  /* Set the label and seed parameters for the random number function */
2982  data_blob.cbData = 36;
2983  data_blob.pbData = abHashedHandshakes;
2984  result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
2985  ok (result, "%08x\n", GetLastError());
2986  if (!result) return;
2987 
2988  data_blob.cbData = 15;
2989  data_blob.pbData = abClientFinished;
2990  result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
2991  ok (result, "%08x\n", GetLastError());
2992  if (!result) return;
2993 
2994  /* Generate some pseudo random bytes and check if they are correct. */
2995  dwLen = (DWORD)sizeof(abData);
2996  result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
2997  ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
2998  "%08x\n", GetLastError());
2999 
3000  /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
3001  * Hash some data with the HMAC. Compare results. */
3002  result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
3003  ok (result, "%08x\n", GetLastError());
3004  if (!result) return;
3005 
3006  result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
3007  ok (result, "%08x\n", GetLastError());
3008  if (!result) return;
3009 
3010  result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
3011  ok (result, "%08x\n", GetLastError());
3012  if (!result) return;
3013 
3014  result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
3015  ok (result, "%08x\n", GetLastError());
3016  if (!result) return;
3017 
3018  dwLen = (DWORD)sizeof(abMD5Hash);
3019  result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
3020  ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
3021 
3022  CryptDestroyHash(hHMAC);
3023  CryptDestroyHash(hTLS1PRF);
3024  CryptDestroyHash(hMasterHash);
3025  CryptDestroyKey(hServerWriteMACKey);
3026  CryptDestroyKey(hServerWriteKey);
3027  CryptDestroyKey(hRSAKey);
3028  CryptDestroyKey(hMasterSecret);
3031 }
3032 
3033 /* Test that a key can be used to encrypt data and exported, and that, when
3034  * the exported key is imported again, can be used to decrypt the original
3035  * data again.
3036  */
3037 static void test_rsa_round_trip(void)
3038 {
3039  static const char test_string[] = "Well this is a fine how-do-you-do.";
3040  HCRYPTPROV prov;
3041  HCRYPTKEY signKey, keyExchangeKey;
3042  BOOL result;
3043  BYTE data[256], *exportedKey;
3044  DWORD dataLen, keyLen;
3045 
3048 
3049  /* Generate a new key... */
3051  CRYPT_NEWKEYSET);
3052  ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3053  result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey);
3054  ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
3055  result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
3056  ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
3057  /* encrypt some data with it... */
3059  dataLen = strlen(test_string) + 1;
3060  result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
3061  sizeof(data));
3062  ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
3063  broken(GetLastError() == NTE_PERM /* NT4 */),
3064  "CryptEncrypt failed: %08x\n", GetLastError());
3065  /* export the key... */
3066  result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
3067  &keyLen);
3068  ok(result, "CryptExportKey failed: %08x\n", GetLastError());
3069  exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
3070  result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
3071  &keyLen);
3072  ok(result, "CryptExportKey failed: %08x\n", GetLastError());
3073  /* destroy the key... */
3074  CryptDestroyKey(keyExchangeKey);
3075  CryptDestroyKey(signKey);
3076  /* import the key again... */
3077  result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
3078  ok(result, "CryptImportKey failed: %08x\n", GetLastError());
3079  HeapFree(GetProcessHeap(), 0, exportedKey);
3080  /* and decrypt the data encrypted with the original key with the imported
3081  * key.
3082  */
3083  result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
3084  ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */) ||
3085  broken(GetLastError() == NTE_PERM /* NT4 */),
3086  "CryptDecrypt failed: %08x\n", GetLastError());
3087  if (result)
3088  {
3089  ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen);
3090  ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
3091  }
3092  CryptDestroyKey(keyExchangeKey);
3093  CryptReleaseContext(prov, 0);
3094 
3097 }
3098 
3099 static void test_enum_container(void)
3100 {
3101  BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
3102  DWORD dwBufferLen;
3103  BOOL result, fFound = FALSE;
3104 
3105  /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
3106  * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
3107  SetLastError(0xdeadbeef);
3109  ok (result, "%08x\n", GetLastError());
3110  ok (dwBufferLen == MAX_PATH + 1 ||
3111  broken(dwBufferLen != MAX_PATH + 1), /* Win9x, WinMe, NT4 */
3112  "Expected dwBufferLen to be (MAX_PATH + 1), it was : %d\n", dwBufferLen);
3113 
3114  /* If the result fits into abContainerName dwBufferLen is left untouched */
3115  dwBufferLen = (DWORD)sizeof(abContainerName);
3116  result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
3117  ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
3118 
3119  /* We only check, if the currently open 'winetest' container is among the enumerated. */
3120  do {
3121  if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
3122  dwBufferLen = (DWORD)sizeof(abContainerName);
3123  } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
3124 
3125  ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
3126 }
3127 
3128 static BYTE signBlob[] = {
3129 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
3130 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
3131 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
3132 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
3133 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
3134 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
3135 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
3136 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
3137 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
3138 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
3139 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
3140 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
3141 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
3142 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
3143 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
3144 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
3145 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
3146 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
3147 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
3148 0xb6,0x85,0x86,0x07 };
3149 
3150 static void test_null_provider(void)
3151 {
3152  HCRYPTPROV prov;
3153  HCRYPTKEY key;
3154  BOOL result;
3155  DWORD keySpec, dataLen,dwParam;
3156  char szName[MAX_PATH];
3157 
3160  "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
3163  "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
3167  "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08x\n", GetLastError());
3171  "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
3174  "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
3175 
3176  /* Delete the default container. */
3178  /* Once you've deleted the default container you can't open it as if it
3179  * already exists.
3180  */
3183  "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
3184  /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
3187  ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3188  if (!result) return;
3189  dataLen = sizeof(keySpec);
3190  result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
3191  if (result)
3192  ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
3193  "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
3194  /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
3195  * supported, you can't get the keys from this container.
3196  */
3198  ok(!result && GetLastError() == NTE_NO_KEY,
3199  "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3201  ok(!result && GetLastError() == NTE_NO_KEY,
3202  "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3203  result = CryptReleaseContext(prov, 0);
3204  ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
3205  /* You can create a new default container. */
3207  CRYPT_NEWKEYSET);
3208  ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3209  /* But you still can't get the keys (until one's been generated.) */
3211  ok(!result && GetLastError() == NTE_NO_KEY,
3212  "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3214  ok(!result && GetLastError() == NTE_NO_KEY,
3215  "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3216  CryptReleaseContext(prov, 0);
3218 
3223  "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
3227  "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
3229  CRYPT_NEWKEYSET);
3230  ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3231  if (!result) return;
3232  /* Test provider parameters getter */
3233  dataLen = sizeof(dwParam);
3234  result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
3235  ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
3236  "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
3237  dataLen = sizeof(dwParam);
3238  result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
3239  ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
3240  "Expected 0, got 0x%08X\n",dwParam);
3241  dataLen = sizeof(dwParam);
3242  result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
3243  ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
3244  "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
3245  dataLen = sizeof(keySpec);
3246  SetLastError(0xdeadbeef);
3247  result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
3248  if (!result && GetLastError() == NTE_BAD_TYPE)
3249  skip("PP_KEYSPEC is not supported (win9x or NT)\n");
3250  else
3251  ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
3252  "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
3253  /* PP_CONTAINER parameter */
3254  dataLen = sizeof(szName);
3255  result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
3256  ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
3257  "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
3258  (result)? "TRUE":"FALSE",GetLastError(),dataLen);
3259  /* PP_UNIQUE_CONTAINER parameter */
3260  dataLen = sizeof(szName);
3261  SetLastError(0xdeadbeef);
3262  result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
3263  if (!result && GetLastError() == NTE_BAD_TYPE)
3264  {
3265  skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
3266  }
3267  else
3268  {
3269  char container[MAX_PATH];
3270 
3271  ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
3273  todo_wine
3274  {
3275  ok(dataLen == strlen(container)+1 ||
3276  broken(dataLen == strlen(szContainer)+1) /* WinME */,
3277  "Expected a param length of 70, got %d\n", dataLen);
3278  ok(!strcmp(container, szName) ||
3279  broken(!strcmp(szName, szContainer)) /* WinME */,
3280  "Wrong container name : %s\n", szName);
3281  }
3282  }
3284  ok(!result && GetLastError() == NTE_NO_KEY,
3285  "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3287  ok(!result && GetLastError() == NTE_NO_KEY,
3288  "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3289 
3290  /* Importing a key exchange blob.. */
3292  0, 0, &key);
3293  ok(result, "CryptImportKey failed: %08x\n", GetLastError());
3295  /* allows access to the key exchange key.. */
3297  ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
3299  /* but not to the private key. */
3301  ok(!result && GetLastError() == NTE_NO_KEY,
3302  "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3303  CryptReleaseContext(prov, 0);
3306 
3307  /* Whereas importing a sign blob.. */
3309  CRYPT_NEWKEYSET);
3310  ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3311  if (!result) return;
3312  result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
3313  ok(result, "CryptImportKey failed: %08x\n", GetLastError());
3315  /* doesn't allow access to the key exchange key.. */
3317  ok(!result && GetLastError() == NTE_NO_KEY,
3318  "Expected NTE_NO_KEY, got %08x\n", GetLastError());
3319  /* but does to the private key. */
3321  ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
3323  CryptReleaseContext(prov, 0);
3324 
3327 
3328  /* Test for being able to get a key generated with CALG_RSA_SIGN. */
3330  CRYPT_NEWKEYSET);
3331  ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3332  result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
3333  ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError());
3336  ok(!result, "expected CryptGetUserKey to fail\n");
3338  ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08x\n", GetLastError());
3340  CryptReleaseContext(prov, 0);
3341 
3344 
3345  /* Test for being able to get a key generated with CALG_RSA_KEYX. */
3347  CRYPT_NEWKEYSET);
3348  ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3349  result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
3350  ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError());
3353  ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError());
3356  ok(!result, "expected CryptGetUserKey to fail\n");
3357  CryptReleaseContext(prov, 0);
3358 
3361 
3362  /* test for the bug in accessing the user key in a container
3363  */
3365  CRYPT_NEWKEYSET);
3366  ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3367  result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
3368  ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
3370  CryptReleaseContext(prov,0);
3372  ok(result, "CryptAcquireContextA failed: 0x%08x\n", GetLastError());
3374  ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
3376  CryptReleaseContext(prov, 0);
3377 
3380 
3381  /* test the machine key set */
3386  ok(result, "CryptAcquireContextA with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
3387  CryptReleaseContext(prov, 0);
3390  ok(result, "CryptAcquireContextA with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
3391  CryptReleaseContext(prov,0);
3394  ok(result, "CryptAcquireContextA with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
3395  GetLastError());
3399  "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
3400 
3401 }
3402 
3403 static void test_key_permissions(void)
3404 {
3405  HCRYPTKEY hKey1, hKey2;
3406  DWORD dwVal, dwLen;
3407  BOOL result;
3408 
3409  /* Create keys that are exportable */
3411  return;
3412 
3414  ok (result, "%08x\n", GetLastError());
3415  if (!result) return;
3416 
3417  dwVal = 0xdeadbeef;
3418  dwLen = sizeof(DWORD);
3419  result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
3420  ok(result, "%08x\n", GetLastError());
3421  ok(dwVal ==
3423  broken(dwVal == 0xffffffff), /* Win9x/NT4 */
3424  "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
3425  " got %08x\n", dwVal);
3426 
3427  /* The key exchange key's public key may be exported.. */
3428  result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
3429  ok(result, "%08x\n", GetLastError());
3430  /* and its private key may be too. */
3431  result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
3432  ok(result, "%08x\n", GetLastError());
3433  /* Turning off the key's export permissions is "allowed".. */
3434  dwVal &= ~CRYPT_EXPORT;
3435  result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
3436  ok(result ||
3437  broken(!result && GetLastError() == NTE_BAD_DATA) || /* W2K */
3438  broken(!result && GetLastError() == NTE_BAD_FLAGS), /* Win9x/WinME/NT4 */
3439  "%08x\n", GetLastError());
3440  /* but it has no effect. */
3441  dwVal = 0xdeadbeef;
3442  dwLen = sizeof(DWORD);
3443  result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
3444  ok(result, "%08x\n", GetLastError());
3445  ok(dwVal ==
3447  broken(dwVal == 0xffffffff), /* Win9x/NT4 */
3448  "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
3449  " got %08x\n", dwVal);
3450  /* Thus, changing the export flag of the key doesn't affect whether the key
3451  * may be exported.
3452  */
3453  result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
3454  ok(result, "%08x\n", GetLastError());
3455 
3457  ok (result, "%08x\n", GetLastError());
3458 
3459  /* A subsequent get of the same key, into a different handle, also doesn't
3460  * show that the permissions have been changed.
3461  */
3462  dwVal = 0xdeadbeef;
3463  dwLen = sizeof(DWORD);
3464  result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
3465  ok(result, "%08x\n", GetLastError());
3466  ok(dwVal ==
3468  broken(dwVal == 0xffffffff), /* Win9x/NT4 */
3469  "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
3470  " got %08x\n", dwVal);
3471 
3472  CryptDestroyKey(hKey2);
3473  CryptDestroyKey(hKey1);
3474 
3476 }
3477 
3478 static void test_key_initialization(void)
3479 {
3480  DWORD dwLen;
3481  HCRYPTPROV prov1, prov2;
3482  HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
3483  BOOL result;
3484  static BYTE abSessionKey[148] = {
3485  0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
3486  0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
3487  0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
3488  0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
3489  0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
3490  0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
3491  0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
3492  0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
3493  0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
3494  0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
3495  0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
3496  0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
3497  0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
3498  0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
3499  0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
3500  0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
3501  0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
3502  0x04, 0x8c, 0x49, 0x92
3503  };
3504 
3505  /* Like init_base_environment, but doesn't generate new keys, as they'll
3506  * be imported instead.
3507  */
3509  {
3511  CRYPT_NEWKEYSET);
3512  ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3513  }
3514  dwLen = (DWORD)sizeof(abPlainPrivateKey);
3515  result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
3516  ok(result, "CryptImportKey failed: %08x\n", GetLastError());
3517 
3518  dwLen = (DWORD)sizeof(abSessionKey);
3519  result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
3520  ok(result, "CryptImportKey failed: %08x\n", GetLastError());
3521 
3522  /* Once the key has been imported, subsequently acquiring a context with
3523  * the same name will allow retrieving the key.
3524  */
3526  ok(result, "CryptAcquireContextA failed: %08x\n", GetLastError());
3527  result = CryptGetUserKey(prov2, AT_KEYEXCHANGE, &hKey);
3528  ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
3529  if (result) CryptDestroyKey(hKey);
3530  CryptReleaseContext(prov2, 0);
3531 
3532  CryptDestroyKey(hSessionKey);
3533  CryptDestroyKey(hKeyExchangeKey);
3534  CryptReleaseContext(prov1, 0);
3537 }
3538</