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