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