[RSAENH_WINETEST] Sync with Wine Staging 1.7.37. CORE-9246
[reactos.git] / rostests / winetests / rsaenh / rsaenh.c
1 /*
2 * Unit tests for rsaenh functions
3 *
4 * Copyright (c) 2004 Michael Jung
5 * Copyright (c) 2006 Juan Lang
6 * Copyright (c) 2007 Vijay Kiran Kamuju
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23 #include <string.h>
24 #include <stdio.h>
25 #include "wine/test.h"
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winerror.h"
29 #include "wincrypt.h"
30 #include "winreg.h"
31
32 static HCRYPTPROV hProv;
33 static const char *szProviders[] = {MS_ENHANCED_PROV_A, MS_DEF_PROV_A, MS_STRONG_PROV_A};
34 static int iProv;
35 static const char szContainer[] = "winetest";
36 static const char *szProvider;
37
38 #define ENHANCED_PROV (iProv == 0)
39 #define BASE_PROV (iProv == 1)
40 #define STRONG_PROV (iProv == 2)
41
42 typedef struct _ctdatatype {
43 unsigned char origstr[32];
44 unsigned char decstr[32];
45 int strlen;
46 int enclen;
47 int buflen;
48 } cryptdata;
49
50 static const cryptdata cTestData[4] = {
51 {"abcdefghijkl",
52 {'a','b','c','d','e','f','g','h',0x2,0x2,'k','l',0},
53 12,8,16},
54 {"abcdefghij",
55 {'a','b','c','d','e','f','g','h',0x2,0x2,0},
56 10,8,16},
57 {"abcdefgh",
58 {'a','b','c','d','e','f','g','h',0},
59 8,8,16},
60 {"abcdefghijkl",
61 {'a','b','c','d','e','f','g','h','i','j','k','l',0},
62 12,12,16}
63 };
64
65 static int win2k, nt4;
66
67 /*
68 * 1. Take the MD5 Hash of the container name (with an extra null byte)
69 * 2. Turn the hash into a 4 DWORD hex value
70 * 3. Append a '_'
71 * 4. Add the MachineGuid
72 *
73 */
74 static void uniquecontainer(char *unique)
75 {
76 /* MD5 hash of "winetest\0" in 4 DWORD hex */
77 static const char szContainer_md5[] = "9d20fd8d05ed2b8455d125d0bf6d6a70";
78 static const char szCryptography[] = "Software\\Microsoft\\Cryptography";
79 static const char szMachineGuid[] = "MachineGuid";
80 HKEY hkey;
81 char guid[MAX_PATH];
82 DWORD size = MAX_PATH;
83 HRESULT ret;
84
85 /* Get the MachineGUID */
86 ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, szCryptography, 0, KEY_READ | KEY_WOW64_64KEY, &hkey);
87 if (ret == ERROR_ACCESS_DENIED)
88 {
89 /* Windows 2000 can't handle KEY_WOW64_64KEY */
90 RegOpenKeyA(HKEY_LOCAL_MACHINE, szCryptography, &hkey);
91 win2k++;
92 }
93 RegQueryValueExA(hkey, szMachineGuid, NULL, NULL, (LPBYTE)guid, &size);
94 RegCloseKey(hkey);
95
96 if (!unique) return;
97 lstrcpyA(unique, szContainer_md5);
98 lstrcatA(unique, "_");
99 lstrcatA(unique, guid);
100 }
101
102 static void printBytes(const char *heading, const BYTE *pb, size_t cb)
103 {
104 size_t i;
105 printf("%s: ",heading);
106 for(i=0;i<cb;i++)
107 printf("0x%02x,",pb[i]);
108 putchar('\n');
109 }
110
111 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
112
113 /*
114 static void trace_hex(BYTE *pbData, DWORD dwLen) {
115 char szTemp[256];
116 DWORD i, j;
117
118 for (i = 0; i < dwLen-7; i+=8) {
119 sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
120 pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5],
121 pbData[i+6], pbData[i+7]);
122 trace(szTemp);
123 }
124 for (j=0; i<dwLen; j++,i++) {
125 sprintf(szTemp+6*j, "0x%02x,\n", pbData[i]);
126 }
127 trace(szTemp);
128 }
129 */
130
131 static BOOL init_base_environment(const char *provider, DWORD dwKeyFlags)
132 {
133 HCRYPTKEY hKey;
134 BOOL result;
135
136 if (provider) szProvider = provider;
137
138 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
139
140 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
141
142 result = CryptAcquireContextA(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
143 ok(!result && (GetLastError()==NTE_BAD_FLAGS ||
144 broken(GetLastError() == NTE_KEYSET_NOT_DEF /* Win9x/NT4 */)),
145 "%d, %08x\n", result, GetLastError());
146
147 if (!CryptAcquireContextA(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
148 {
149 ok(GetLastError()==NTE_BAD_KEYSET ||
150 broken(GetLastError() == NTE_TEMPORARY_PROFILE /* some Win7 setups */) ||
151 broken(GetLastError() == NTE_KEYSET_NOT_DEF /* Win9x/NT4 */),
152 "%08x\n", GetLastError());
153 if (GetLastError()!=NTE_BAD_KEYSET)
154 {
155 win_skip("RSA full provider not available\n");
156 return FALSE;
157 }
158 result = CryptAcquireContextA(&hProv, szContainer, szProvider, PROV_RSA_FULL,
159 CRYPT_NEWKEYSET);
160 ok(result, "%08x\n", GetLastError());
161 if (!result)
162 {
163 win_skip("Couldn't create crypto provider\n");
164 return FALSE;
165 }
166 result = CryptGenKey(hProv, AT_KEYEXCHANGE, dwKeyFlags, &hKey);
167 ok(result, "%08x\n", GetLastError());
168 if (result) CryptDestroyKey(hKey);
169 result = CryptGenKey(hProv, AT_SIGNATURE, dwKeyFlags, &hKey);
170 ok(result, "%08x\n", GetLastError());
171 if (result) CryptDestroyKey(hKey);
172 }
173 return TRUE;
174 }
175
176 static void clean_up_base_environment(void)
177 {
178 BOOL result;
179
180 SetLastError(0xdeadbeef);
181 result = CryptReleaseContext(hProv, 1);
182 ok(!result || broken(result) /* Win98 */, "Expected failure\n");
183 ok(GetLastError()==NTE_BAD_FLAGS, "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
184
185 /* Just to prove that Win98 also released the CSP */
186 SetLastError(0xdeadbeef);
187 result = CryptReleaseContext(hProv, 0);
188 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
189
190 CryptAcquireContextA(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
191 }
192
193 static BOOL init_aes_environment(void)
194 {
195 HCRYPTKEY hKey;
196 BOOL result;
197
198 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
199
200 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
201
202 /* we are using NULL as provider name for RSA_AES provider as the provider
203 * names are different in Windows XP and Vista. This differs from what
204 * is defined in the SDK on Windows XP.
205 * This provider is available on Windows XP, Windows 2003 and Vista. */
206
207 result = CryptAcquireContextA(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
208 if (!result && GetLastError() == NTE_PROV_TYPE_NOT_DEF)
209 {
210 win_skip("RSA_AES provider not supported\n");
211 return FALSE;
212 }
213 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
214
215 if (!CryptAcquireContextA(&hProv, szContainer, NULL, PROV_RSA_AES, 0))
216 {
217 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
218 if (GetLastError()!=NTE_BAD_KEYSET) return FALSE;
219 result = CryptAcquireContextA(&hProv, szContainer, NULL, PROV_RSA_AES,
220 CRYPT_NEWKEYSET);
221 ok(result, "%08x\n", GetLastError());
222 if (!result) return FALSE;
223 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
224 ok(result, "%08x\n", GetLastError());
225 if (result) CryptDestroyKey(hKey);
226 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
227 ok(result, "%08x\n", GetLastError());
228 if (result) CryptDestroyKey(hKey);
229 }
230 return TRUE;
231 }
232
233 static void clean_up_aes_environment(void)
234 {
235 BOOL result;
236
237 result = CryptReleaseContext(hProv, 1);
238 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
239
240 CryptAcquireContextA(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_DELETEKEYSET);
241 }
242
243 static void test_prov(void)
244 {
245 BOOL result;
246 DWORD dwLen, dwInc;
247
248 dwLen = (DWORD)sizeof(DWORD);
249 SetLastError(0xdeadbeef);
250 result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
251 if (!result && GetLastError() == NTE_BAD_TYPE)
252 {
253 skip("PP_SIG_KEYSIZE_INC is not supported (win9x or NT)\n");
254 nt4++;
255 }
256 else
257 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
258
259 dwLen = (DWORD)sizeof(DWORD);
260 SetLastError(0xdeadbeef);
261 result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
262 if (!result && GetLastError() == NTE_BAD_TYPE)
263 skip("PP_KEYX_KEYSIZE_INC is not supported (win9x or NT)\n");
264 else
265 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
266 }
267
268 static void test_gen_random(void)
269 {
270 BOOL result;
271 BYTE rnd1[16], rnd2[16];
272
273 memset(rnd1, 0, sizeof(rnd1));
274 memset(rnd2, 0, sizeof(rnd2));
275
276 result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
277 if (!result && GetLastError() == NTE_FAIL) {
278 /* rsaenh compiled without OpenSSL */
279 return;
280 }
281
282 ok(result, "%08x\n", GetLastError());
283
284 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
285 ok(result, "%08x\n", GetLastError());
286
287 ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
288 }
289
290 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
291 {
292 HCRYPTHASH hHash;
293 BOOL result;
294 unsigned char pbData[2000];
295 int i;
296
297 *phKey = 0;
298 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
299 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
300 if (!result) {
301 /* rsaenh compiled without OpenSSL */
302 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
303 return FALSE;
304 }
305 ok(result, "%08x\n", GetLastError());
306 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
307 ok(result, "%08x\n", GetLastError());
308 if (!result) return FALSE;
309 result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
310 ok(result, "%08x\n", GetLastError());
311 if (!result) return FALSE;
312 len = 2000;
313 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
314 ok(result, "%08x\n", GetLastError());
315 CryptDestroyHash(hHash);
316 return TRUE;
317 }
318
319 static BYTE abPlainPrivateKey[596] = {
320 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
321 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
322 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
323 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
324 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
325 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
326 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
327 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
328 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
329 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
330 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
331 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
332 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
333 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
334 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
335 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
336 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
337 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
338 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
339 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
340 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
341 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
342 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
343 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
344 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
345 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
346 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
347 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
348 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
349 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
350 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
351 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
352 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
353 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
354 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
355 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
356 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
357 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
358 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
359 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
360 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
361 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
362 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
363 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
364 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
365 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
366 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
367 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
368 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
369 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
370 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
371 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
372 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
373 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
374 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
375 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
376 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
377 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
378 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
379 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
380 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
381 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
382 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
383 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
384 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
385 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
386 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
387 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
388 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
389 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
390 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
391 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
392 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
393 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
394 0xf2, 0x5d, 0x58, 0x07
395 };
396
397 static void test_hashes(void)
398 {
399 static const unsigned char md2hash[16] = {
400 0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
401 0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
402 static const unsigned char md4hash[16] = {
403 0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
404 0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
405 static const unsigned char empty_md5hash[16] = {
406 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
407 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
408 static const unsigned char md5hash[16] = {
409 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
410 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
411 static const unsigned char sha1hash[20] = {
412 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
413 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
414 static const unsigned char signed_ssl3_shamd5_hash[] = {
415 0x4f,0xcc,0x2f,0x33,0x44,0x60,0x76,0x16,0x13,0xc8,0xff,0xd4,0x59,0x19,
416 0xde,0x85,0x44,0x72,0x47,0x98,0x01,0xfb,0x67,0x5c,0x5b,0x35,0x15,0x0f,
417 0x91,0xda,0xc7,0x7c,0xfb,0xe2,0x18,0xef,0xac,0x31,0x40,0x7b,0xa9,0x83,
418 0xdb,0x30,0xcd,0x94,0x4b,0x8e,0x3b,0x6c,0x7a,0x86,0x59,0xf0,0xd1,0xd2,
419 0x5e,0xce,0xd4,0x1b,0x7f,0xed,0x24,0xee,0x53,0x5c,0x15,0x97,0x21,0x7c,
420 0x5c,0xea,0xab,0xf5,0xd6,0x4b,0xb3,0xbb,0x14,0xf5,0x59,0x9e,0x21,0x90,
421 0x21,0x99,0x19,0xad,0xa2,0xa6,0xea,0x61,0xc1,0x41,0xe2,0x70,0x77,0xf7,
422 0x15,0x68,0x96,0x1e,0x5c,0x84,0x97,0xe3,0x5c,0xd2,0xd9,0xfb,0x87,0x6f,
423 0x11,0x21,0x82,0x43,0x76,0x32,0xa4,0x38,0x7b,0x85,0x22,0x30,0x1e,0x55,
424 0x79,0x93 };
425 unsigned char pbData[2048];
426 BOOL result;
427 HCRYPTHASH hHash, hHashClone;
428 HCRYPTPROV prov;
429 BYTE pbHashValue[36];
430 BYTE pbSigValue[128];
431 HCRYPTKEY hKeyExchangeKey;
432 DWORD hashlen, len, error, cryptflags;
433 int i;
434
435 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
436
437 /* MD2 Hashing */
438 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
439 if (!result) {
440 /* rsaenh compiled without OpenSSL */
441 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
442 } else {
443 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
444 ok(result, "%08x\n", GetLastError());
445
446 len = sizeof(DWORD);
447 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
448 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
449
450 len = 16;
451 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
452 ok(result, "%08x\n", GetLastError());
453
454 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
455
456 result = CryptDestroyHash(hHash);
457 ok(result, "%08x\n", GetLastError());
458 }
459
460 /* MD4 Hashing */
461 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
462 ok(result, "%08x\n", GetLastError());
463
464 result = CryptHashData(hHash, pbData, sizeof(pbData), ~0);
465 ok(!result && GetLastError() == NTE_BAD_FLAGS, "%08x\n", GetLastError());
466
467 cryptflags = CRYPT_USERDATA;
468 result = CryptHashData(hHash, pbData, sizeof(pbData), cryptflags);
469 if (!result && GetLastError() == NTE_BAD_FLAGS) /* <= NT4 */
470 {
471 cryptflags &= ~CRYPT_USERDATA;
472 ok(broken(1), "Failed to support CRYPT_USERDATA flag\n");
473 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
474 }
475 ok(result, "%08x\n", GetLastError());
476
477 len = sizeof(DWORD);
478 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
479 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
480
481 len = 16;
482 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
483 ok(result, "%08x\n", GetLastError());
484
485 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
486
487 result = CryptDestroyHash(hHash);
488 ok(result, "%08x\n", GetLastError());
489
490 /* MD5 Hashing */
491 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
492 ok(result, "%08x\n", GetLastError());
493
494 len = sizeof(DWORD);
495 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
496 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
497
498 result = CryptHashData(hHash, pbData, sizeof(pbData), ~0);
499 ok(!result && GetLastError() == NTE_BAD_FLAGS, "%08x\n", GetLastError());
500
501 result = CryptHashData(hHash, pbData, sizeof(pbData), cryptflags);
502 ok(result, "%08x\n", GetLastError());
503
504 len = 16;
505 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
506 ok(result, "%08x\n", GetLastError());
507
508 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
509
510 result = CryptDestroyHash(hHash);
511 ok(result, "%08x\n", GetLastError());
512
513 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
514 ok(result, "%08x\n", GetLastError());
515
516 /* The hash is available even if CryptHashData hasn't been called */
517 len = 16;
518 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
519 ok(result, "%08x\n", GetLastError());
520
521 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
522
523 /* It's also stable: getting it twice results in the same value */
524 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
525 ok(result, "%08x\n", GetLastError());
526
527 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
528
529 /* Can't add data after the hash been retrieved */
530 SetLastError(0xdeadbeef);
531 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
532 ok(!result, "Expected failure\n");
533 ok(GetLastError() == NTE_BAD_HASH_STATE ||
534 GetLastError() == NTE_BAD_ALGID, /* Win9x, WinMe, NT4 */
535 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID, got %08x\n", GetLastError());
536
537 /* You can still retrieve the hash, its value just hasn't changed */
538 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
539 ok(result, "%08x\n", GetLastError());
540
541 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
542
543 result = CryptDestroyHash(hHash);
544 ok(result, "%08x\n", GetLastError());
545
546 /* SHA1 Hashing */
547 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
548 ok(result, "%08x\n", GetLastError());
549
550 result = CryptHashData(hHash, pbData, 5, cryptflags);
551 ok(result, "%08x\n", GetLastError());
552
553 if(pCryptDuplicateHash) {
554 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
555 ok(result, "%08x\n", GetLastError());
556
557 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
558 ok(result, "%08x\n", GetLastError());
559
560 len = sizeof(DWORD);
561 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
562 ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
563
564 len = 20;
565 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
566 ok(result, "%08x\n", GetLastError());
567
568 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
569
570 result = CryptDestroyHash(hHashClone);
571 ok(result, "%08x\n", GetLastError());
572 }
573
574 result = CryptDestroyHash(hHash);
575 ok(result, "%08x\n", GetLastError());
576
577 /* The SHA-2 variants aren't supported in the RSA full provider */
578 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
579 ok(!result && GetLastError() == NTE_BAD_ALGID,
580 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
581 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
582 ok(!result && GetLastError() == NTE_BAD_ALGID,
583 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
584 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
585 ok(!result && GetLastError() == NTE_BAD_ALGID,
586 "expected NTE_BAD_ALGID, got %08x\n", GetLastError());
587
588 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
589 ok(result, "CryptAcquireContextA failed 0x%08x\n", GetLastError());
590
591 result = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hHash);
592 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
593
594 /* release provider before using the hash */
595 result = CryptReleaseContext(prov, 0);
596 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
597
598 SetLastError(0xdeadbeef);
599 result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
600 error = GetLastError();
601 ok(!result, "CryptHashData succeeded\n");
602 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
603
604 SetLastError(0xdeadbeef);
605 result = CryptDestroyHash(hHash);
606 error = GetLastError();
607 ok(!result, "CryptDestroyHash succeeded\n");
608 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
609
610 if (!pCryptDuplicateHash)
611 {
612 win_skip("CryptDuplicateHash is not available\n");
613 return;
614 }
615
616 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
617 ok(result, "CryptAcquireContextA failed 0x%08x\n", GetLastError());
618
619 result = CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
620 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
621
622 result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
623 ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
624
625 result = pCryptDuplicateHash(hHash, NULL, 0, &hHashClone);
626 ok(result, "CryptDuplicateHash failed 0x%08x\n", GetLastError());
627
628 len = 20;
629 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
630 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
631
632 /* add data after duplicating the hash */
633 result = CryptHashData(hHash, (const BYTE *)"more data", sizeof("more data"), 0);
634 ok(result, "CryptHashData failed 0x%08x\n", GetLastError());
635
636 result = CryptDestroyHash(hHash);
637 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
638
639 result = CryptDestroyHash(hHashClone);
640 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
641
642 result = CryptReleaseContext(prov, 0);
643 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
644
645 /* Test CALG_SSL3_SHAMD5 */
646 result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
647 ok(result, "CryptAcquireContextA failed 0x%08x\n", GetLastError());
648
649 /* Step 1: create an MD5 hash of the data */
650 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
651 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
652 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
653 ok(result, "%08x\n", GetLastError());
654 len = 16;
655 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
656 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
657 result = CryptDestroyHash(hHash);
658 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
659 /* Step 2: create a SHA1 hash of the data */
660 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
661 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
662 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
663 ok(result, "%08x\n", GetLastError());
664 len = 20;
665 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue + 16, &len, 0);
666 ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
667 result = CryptDestroyHash(hHash);
668 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
669 /* Step 3: create a CALG_SSL3_SHAMD5 hash handle */
670 result = CryptCreateHash(hProv, CALG_SSL3_SHAMD5, 0, 0, &hHash);
671 ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
672 /* Test that CryptHashData fails on this hash */
673 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
674 ok(!result && (GetLastError() == NTE_BAD_ALGID || broken(GetLastError() == ERROR_INVALID_HANDLE)) /* Win 8 */,
675 "%08x\n", GetLastError());
676 result = CryptSetHashParam(hHash, HP_HASHVAL, pbHashValue, 0);
677 ok(result, "%08x\n", GetLastError());
678 len = (DWORD)sizeof(abPlainPrivateKey);
679 result = CryptImportKey(hProv, abPlainPrivateKey, len, 0, 0, &hKeyExchangeKey);
680 ok(result, "%08x\n", GetLastError());
681 len = 0;
682 result = CryptSignHashA(hHash, AT_KEYEXCHANGE, NULL, 0, NULL, &len);
683 ok(result, "%08x\n", GetLastError());
684 ok(len == 128, "expected len 128, got %d\n", len);
685 result = CryptSignHashA(hHash, AT_KEYEXCHANGE, NULL, 0, pbSigValue, &len);
686 ok(result, "%08x\n", GetLastError());
687 ok(!memcmp(pbSigValue, signed_ssl3_shamd5_hash, len), "unexpected value\n");
688 if (len != 128 || memcmp(pbSigValue, signed_ssl3_shamd5_hash, len))
689 {
690 printBytes("expected", signed_ssl3_shamd5_hash,
691 sizeof(signed_ssl3_shamd5_hash));
692 printBytes("got", pbSigValue, len);
693 }
694 result = CryptDestroyKey(hKeyExchangeKey);
695 ok(result, "CryptDestroyKey failed 0x%08x\n", GetLastError());
696 result = CryptDestroyHash(hHash);
697 ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
698 result = CryptReleaseContext(prov, 0);
699 ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
700 }
701
702 static void test_block_cipher_modes(void)
703 {
704 static const BYTE plain[23] = {
705 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
706 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
707 static const BYTE ecb[24] = {
708 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
709 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
710 static const BYTE cbc[24] = {
711 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
712 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
713 static const BYTE cfb[24] = {
714 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
715 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
716 HCRYPTKEY hKey;
717 BOOL result;
718 BYTE abData[24];
719 DWORD dwMode, dwLen;
720
721 result = derive_key(CALG_RC2, &hKey, 40);
722 if (!result) return;
723
724 memcpy(abData, plain, sizeof(plain));
725
726 /* test default chaining mode */
727 dwMode = 0xdeadbeef;
728 dwLen = sizeof(dwMode);
729 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
730 ok(result, "%08x\n", GetLastError());
731 ok(dwMode == CRYPT_MODE_CBC, "Wrong default chaining mode\n");
732
733 dwMode = CRYPT_MODE_ECB;
734 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
735 ok(result, "%08x\n", GetLastError());
736
737 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
738 ok(result, "%08x\n", GetLastError());
739 ok(dwLen == 11 || broken(dwLen == 0 /* Win9x/NT4 */), "unexpected salt length %d\n", dwLen);
740
741 dwLen = 23;
742 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
743 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
744 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
745
746 SetLastError(ERROR_SUCCESS);
747 dwLen = 23;
748 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
749 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
750 "%08x, dwLen: %d\n", GetLastError(), dwLen);
751
752 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
753 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
754 "%08x, dwLen: %d\n", GetLastError(), dwLen);
755
756 dwMode = CRYPT_MODE_CBC;
757 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
758 ok(result, "%08x\n", GetLastError());
759
760 dwLen = 23;
761 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
762 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
763 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
764
765 dwLen = 23;
766 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
767 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
768 "%08x, dwLen: %d\n", GetLastError(), dwLen);
769
770 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
771 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
772 "%08x, dwLen: %d\n", GetLastError(), dwLen);
773
774 dwMode = CRYPT_MODE_CFB;
775 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
776 ok(result, "%08x\n", GetLastError());
777
778 dwLen = 16;
779 result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
780 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
781
782 dwLen = 7;
783 result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
784 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
785 "%08x, dwLen: %d\n", GetLastError(), dwLen);
786
787 dwLen = 8;
788 result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
789 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
790
791 dwLen = 16;
792 result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
793 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
794 "%08x, dwLen: %d\n", GetLastError(), dwLen);
795
796 dwMode = CRYPT_MODE_OFB;
797 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
798 if(!result && GetLastError() == ERROR_INTERNAL_ERROR)
799 {
800 ok(broken(1), "OFB mode not supported\n"); /* Windows 8 */
801 }
802 else
803 {
804 ok(result, "%08x\n", GetLastError());
805
806 dwLen = 23;
807 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
808 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
809 }
810
811 CryptDestroyKey(hKey);
812 }
813
814 static void test_3des112(void)
815 {
816 HCRYPTKEY hKey;
817 BOOL result;
818 DWORD dwLen;
819 unsigned char pbData[16], enc_data[16], bad_data[16];
820 static const BYTE des112[16] = {
821 0x8e, 0x0c, 0x3c, 0xa3, 0x05, 0x88, 0x5f, 0x7a,
822 0x32, 0xa1, 0x06, 0x52, 0x64, 0xd2, 0x44, 0x1c };
823 int i;
824
825 result = derive_key(CALG_3DES_112, &hKey, 0);
826 if (!result) {
827 /* rsaenh compiled without OpenSSL */
828 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
829 return;
830 }
831
832 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
833
834 dwLen = 13;
835 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
836 ok(result, "%08x\n", GetLastError());
837
838 ok(!memcmp(pbData, des112, sizeof(des112)), "3DES_112 encryption failed!\n");
839
840 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
841 ok(result, "%08x\n", GetLastError());
842
843 for (i=0; i<4; i++)
844 {
845 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
846
847 dwLen = cTestData[i].enclen;
848 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
849 ok(result, "%08x\n", GetLastError());
850 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
851 memcpy(enc_data, pbData, cTestData[i].buflen);
852
853 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
854 ok(result, "%08x\n", GetLastError());
855 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
856 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
857 if((dwLen != cTestData[i].enclen) ||
858 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
859 {
860 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
861 printBytes("got",pbData,dwLen);
862 }
863
864 /* Test bad data:
865 Decrypting a block of bad data with Final = TRUE should restore the
866 initial state of the key as well as decrypting a block of good data.
867 */
868
869 /* Changing key state by setting Final = FALSE */
870 dwLen = cTestData[i].buflen;
871 memcpy(pbData, enc_data, cTestData[i].buflen);
872 result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
873 ok(result, "%08x\n", GetLastError());
874
875 /* Restoring key state by decrypting bad_data with Final = TRUE */
876 memcpy(bad_data, enc_data, cTestData[i].buflen);
877 bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
878 SetLastError(0xdeadbeef);
879 result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
880 ok(!result, "CryptDecrypt should failed!\n");
881 ok(GetLastError() == NTE_BAD_DATA, "%08x\n", GetLastError());
882 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
883 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
884
885 /* Checking key state */
886 dwLen = cTestData[i].buflen;
887 memcpy(pbData, enc_data, cTestData[i].buflen);
888 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
889 ok(result, "%08x\n", GetLastError());
890 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
891 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
892 if((dwLen != cTestData[i].enclen) ||
893 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
894 {
895 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
896 printBytes("got",pbData,dwLen);
897 }
898 }
899 result = CryptDestroyKey(hKey);
900 ok(result, "%08x\n", GetLastError());
901 }
902
903 static void test_des(void)
904 {
905 HCRYPTKEY hKey;
906 BOOL result;
907 DWORD dwLen, dwMode;
908 unsigned char pbData[16], enc_data[16], bad_data[16];
909 static const BYTE des[16] = {
910 0x58, 0x86, 0x42, 0x46, 0x65, 0x4b, 0x92, 0x62,
911 0xcf, 0x0f, 0x65, 0x37, 0x43, 0x7a, 0x82, 0xb9 };
912 static const BYTE des_old_behavior[16] = {
913 0xb0, 0xfd, 0x11, 0x69, 0x76, 0xb1, 0xa1, 0x03,
914 0xf7, 0xbc, 0x23, 0xaa, 0xd4, 0xc1, 0xc9, 0x55 };
915 static const BYTE des_old_strong[16] = {
916 0x9b, 0xc1, 0x2a, 0xec, 0x4a, 0xf9, 0x0f, 0x14,
917 0x0a, 0xed, 0xf6, 0xd3, 0xdc, 0xad, 0xf7, 0x0c };
918 int i;
919
920 result = derive_key(CALG_DES, &hKey, 0);
921 if (!result) {
922 /* rsaenh compiled without OpenSSL */
923 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
924 return;
925 }
926
927 dwMode = CRYPT_MODE_ECB;
928 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
929 ok(result, "%08x\n", GetLastError());
930
931 dwLen = sizeof(DWORD);
932 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
933 ok(result, "%08x\n", GetLastError());
934 ok(dwMode == CRYPT_MODE_ECB, "Expected CRYPT_MODE_ECB, got %d\n", dwMode);
935
936 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
937
938 dwLen = 13;
939 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
940 ok(result, "%08x\n", GetLastError());
941
942 ok(!memcmp(pbData, des, sizeof(des)), "DES encryption failed!\n");
943
944 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
945 ok(result, "%08x\n", GetLastError());
946
947 for (i=0; i<4; i++)
948 {
949 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
950
951 dwLen = cTestData[i].enclen;
952 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
953 ok(result, "%08x\n", GetLastError());
954 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
955 memcpy(enc_data, pbData, cTestData[i].buflen);
956
957 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
958 ok(result, "%08x\n", GetLastError());
959 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
960 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
961 if((dwLen != cTestData[i].enclen) ||
962 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
963 {
964 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
965 printBytes("got",pbData,dwLen);
966 }
967
968 /* Test bad data:
969 Decrypting a block of bad data with Final = TRUE should restore the
970 initial state of the key as well as decrypting a block of good data.
971 */
972
973 /* Changing key state by setting Final = FALSE */
974 dwLen = cTestData[i].buflen;
975 memcpy(pbData, enc_data, cTestData[i].buflen);
976 result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
977 ok(result, "%08x\n", GetLastError());
978
979 /* Restoring key state by decrypting bad_data with Final = TRUE */
980 memcpy(bad_data, enc_data, cTestData[i].buflen);
981 bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
982 SetLastError(0xdeadbeef);
983 result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
984 ok(!result, "CryptDecrypt should failed!\n");
985 ok(GetLastError() == NTE_BAD_DATA, "%08x\n", GetLastError());
986 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
987 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
988
989 /* Checking key state */
990 dwLen = cTestData[i].buflen;
991 memcpy(pbData, enc_data, cTestData[i].buflen);
992 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
993 ok(result, "%08x\n", GetLastError());
994 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
995 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
996 if((dwLen != cTestData[i].enclen) ||
997 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
998 {
999 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1000 printBytes("got",pbData,dwLen);
1001 }
1002 }
1003
1004 result = CryptDestroyKey(hKey);
1005 ok(result, "%08x\n", GetLastError());
1006
1007 /* Windows >= XP changed the way DES keys are derived, this test ensures we don't break that */
1008 derive_key(CALG_DES, &hKey, 56);
1009
1010 dwMode = CRYPT_MODE_ECB;
1011 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
1012 ok(result, "%08x\n", GetLastError());
1013
1014 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
1015
1016 dwLen = 13;
1017 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
1018 ok(result, "%08x\n", GetLastError());
1019 ok(!memcmp(pbData, des, sizeof(des)) || broken(
1020 !memcmp(pbData, des_old_behavior, sizeof(des)) ||
1021 (STRONG_PROV && !memcmp(pbData, des_old_strong, sizeof(des)))) /* <= 2000 */,
1022 "DES encryption failed!\n");
1023
1024 result = CryptDestroyKey(hKey);
1025 ok(result, "%08x\n", GetLastError());
1026 }
1027
1028 static void test_3des(void)
1029 {
1030 HCRYPTKEY hKey;
1031 BOOL result;
1032 DWORD dwLen;
1033 unsigned char pbData[16], enc_data[16], bad_data[16];
1034 static const BYTE des3[16] = {
1035 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
1036 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
1037 int i;
1038
1039 result = derive_key(CALG_3DES, &hKey, 0);
1040 if (!result) return;
1041
1042 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
1043
1044 dwLen = 13;
1045 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
1046 ok(result, "%08x\n", GetLastError());
1047
1048 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
1049
1050 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1051 ok(result, "%08x\n", GetLastError());
1052
1053 for (i=0; i<4; i++)
1054 {
1055 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
1056
1057 dwLen = cTestData[i].enclen;
1058 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
1059 ok(result, "%08x\n", GetLastError());
1060 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
1061 memcpy(enc_data, pbData, cTestData[i].buflen);
1062
1063 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1064 ok(result, "%08x\n", GetLastError());
1065 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
1066 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
1067 if((dwLen != cTestData[i].enclen) ||
1068 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1069 {
1070 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1071 printBytes("got",pbData,dwLen);
1072 }
1073
1074 /* Test bad data:
1075 Decrypting a block of bad data with Final = TRUE should restore the
1076 initial state of the key as well as decrypting a block of good data.
1077 */
1078
1079 /* Changing key state by setting Final = FALSE */
1080 dwLen = cTestData[i].buflen;
1081 memcpy(pbData, enc_data, cTestData[i].buflen);
1082 result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
1083 ok(result, "%08x\n", GetLastError());
1084
1085 /* Restoring key state by decrypting bad_data with Final = TRUE */
1086 memcpy(bad_data, enc_data, cTestData[i].buflen);
1087 bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
1088 SetLastError(0xdeadbeef);
1089 result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
1090 ok(!result, "CryptDecrypt should failed!\n");
1091 ok(GetLastError() == NTE_BAD_DATA, "%08x\n", GetLastError());
1092 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
1093 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1094
1095 /* Checking key state */
1096 dwLen = cTestData[i].buflen;
1097 memcpy(pbData, enc_data, cTestData[i].buflen);
1098 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1099 ok(result, "%08x\n", GetLastError());
1100 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
1101 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1102 if((dwLen != cTestData[i].enclen) ||
1103 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1104 {
1105 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1106 printBytes("got",pbData,dwLen);
1107 }
1108 }
1109 result = CryptDestroyKey(hKey);
1110 ok(result, "%08x\n", GetLastError());
1111 }
1112
1113 static void test_aes(int keylen)
1114 {
1115 HCRYPTKEY hKey;
1116 BOOL result;
1117 DWORD dwLen, dwMode;
1118 unsigned char pbData[48], enc_data[16], bad_data[16];
1119 int i;
1120 static const BYTE aes_plain[32] = {
1121 "AES Test With 2 Blocks Of Data." };
1122 static const BYTE aes_cbc_enc[3][48] = {
1123 /* 128 bit key encrypted text */
1124 { 0xfe, 0x85, 0x3b, 0xe1, 0xf5, 0xe1, 0x58, 0x75, 0xd5, 0xa9, 0x74, 0xe3, 0x09, 0xea, 0xa5, 0x04,
1125 0x23, 0x35, 0xa2, 0x3b, 0x5c, 0xf1, 0x6c, 0x6f, 0xb9, 0xcd, 0x64, 0x06, 0x3e, 0x41, 0x83, 0xef,
1126 0x2a, 0xfe, 0xea, 0xb5, 0x6c, 0x17, 0x20, 0x79, 0x8c, 0x51, 0x3e, 0x56, 0xed, 0xe1, 0x47, 0x68 },
1127 /* 192 bit key encrypted text */
1128 { 0x6b, 0xf0, 0xfd, 0x32, 0xee, 0xc6, 0x06, 0x13, 0xa8, 0xe6, 0x3c, 0x81, 0x85, 0xb8, 0x2e, 0xa1,
1129 0xd4, 0x3b, 0xe8, 0x22, 0xa5, 0x74, 0x4a, 0xbe, 0x9d, 0xcf, 0xcc, 0x37, 0x26, 0x19, 0x5a, 0xd1,
1130 0x7f, 0x76, 0xbf, 0x94, 0x28, 0xce, 0x27, 0x21, 0x61, 0x87, 0xeb, 0xb9, 0x8b, 0xa8, 0xb4, 0x57 },
1131 /* 256 bit key encrypted text */
1132 { 0x20, 0x57, 0x17, 0x0b, 0x17, 0x76, 0xd8, 0x3b, 0x26, 0x90, 0x8b, 0x4c, 0xf2, 0x00, 0x79, 0x33,
1133 0x29, 0x2b, 0x13, 0x9c, 0xe2, 0x95, 0x09, 0xc1, 0xcd, 0x20, 0x87, 0x22, 0x32, 0x70, 0x9d, 0x75,
1134 0x9a, 0x94, 0xf5, 0x76, 0x5c, 0xb1, 0x62, 0x2c, 0xe1, 0x76, 0x7c, 0x86, 0x73, 0xe6, 0x7a, 0x23 }
1135 };
1136 switch (keylen)
1137 {
1138 case 256:
1139 result = derive_key(CALG_AES_256, &hKey, 0);
1140 i = 2;
1141 break;
1142 case 192:
1143 result = derive_key(CALG_AES_192, &hKey, 0);
1144 i = 1;
1145 break;
1146 default:
1147 case 128:
1148 result = derive_key(CALG_AES_128, &hKey, 0);
1149 i = 0;
1150 break;
1151 }
1152 if (!result) return;
1153
1154 dwLen = sizeof(aes_plain);
1155 memcpy(pbData, aes_plain, dwLen);
1156 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, sizeof(pbData));
1157 ok(result, "Expected OK, got last error %d\n", GetLastError());
1158 ok(dwLen == 48, "Expected dwLen 48, got %d\n", dwLen);
1159 ok(!memcmp(aes_cbc_enc[i], pbData, dwLen), "Expected equal data sequences\n");
1160
1161 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1162 ok(result && dwLen == 32 && !memcmp(aes_plain, pbData, dwLen),
1163 "%08x, dwLen: %d\n", GetLastError(), dwLen);
1164
1165 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
1166
1167 /* Does AES provider support salt? */
1168 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1169 ok((!result && GetLastError() == NTE_BAD_KEY) || result /* Win7 */,
1170 "expected NTE_BAD_KEY, got %08x\n", GetLastError());
1171 if (result)
1172 ok(!dwLen, "unexpected salt length %d\n", dwLen);
1173
1174 /* test default chaining mode */
1175 dwMode = 0xdeadbeef;
1176 dwLen = sizeof(dwMode);
1177 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1178 ok(result, "%08x\n", GetLastError());
1179 ok(dwMode == CRYPT_MODE_CBC, "Wrong default chaining\n");
1180
1181 dwLen = 13;
1182 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
1183 ok(result, "%08x\n", GetLastError());
1184
1185 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1186 ok(result, "%08x\n", GetLastError());
1187
1188 for (i=0; i<4; i++)
1189 {
1190 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
1191
1192 dwLen = cTestData[i].enclen;
1193 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
1194 ok(result, "%08x\n", GetLastError());
1195 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
1196 memcpy(enc_data, pbData, cTestData[i].buflen);
1197
1198 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1199 ok(result, "%08x\n", GetLastError());
1200 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
1201 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1202 if((dwLen != cTestData[i].enclen) ||
1203 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1204 {
1205 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1206 printBytes("got",pbData,dwLen);
1207 }
1208
1209 /* Test bad data:
1210 Decrypting a block of bad data with Final = TRUE should restore the
1211 initial state of the key as well as decrypting a block of good data.
1212 */
1213
1214 /* Changing key state by setting Final = FALSE */
1215 dwLen = cTestData[i].buflen;
1216 memcpy(pbData, enc_data, cTestData[i].buflen);
1217 result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
1218 ok(result, "%08x\n", GetLastError());
1219
1220 /* Restoring key state by decrypting bad_data with Final = TRUE */
1221 memcpy(bad_data, enc_data, cTestData[i].buflen);
1222 bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
1223 SetLastError(0xdeadbeef);
1224 result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
1225 ok(!result, "CryptDecrypt should failed!\n");
1226 ok(GetLastError() == NTE_BAD_DATA, "%08x\n", GetLastError());
1227 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
1228 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1229
1230 /* Checking key state */
1231 dwLen = cTestData[i].buflen;
1232 memcpy(pbData, enc_data, cTestData[i].buflen);
1233 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1234 ok(result, "%08x\n", GetLastError());
1235 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
1236 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1237 if((dwLen != cTestData[i].enclen) ||
1238 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1239 {
1240 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1241 printBytes("got",pbData,dwLen);
1242 }
1243 }
1244 result = CryptDestroyKey(hKey);
1245 ok(result, "%08x\n", GetLastError());
1246 }
1247
1248 static void test_sha2(void)
1249 {
1250 static const unsigned char sha256hash[32] = {
1251 0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
1252 0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
1253 0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
1254 0x1a, 0x08
1255 };
1256 static const unsigned char sha384hash[48] = {
1257 0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
1258 0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
1259 0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
1260 0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
1261 0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
1262 };
1263 static const unsigned char sha512hash[64] = {
1264 0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
1265 0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
1266 0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
1267 0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
1268 0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
1269 0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
1270 0xb7, 0xf4, 0x81, 0xd4
1271 };
1272 unsigned char pbData[2048];
1273 BOOL result;
1274 HCRYPTHASH hHash;
1275 BYTE pbHashValue[64];
1276 DWORD hashlen, len;
1277 int i;
1278
1279 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
1280
1281 /* SHA-256 hash */
1282 SetLastError(0xdeadbeef);
1283 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
1284 if (!result && GetLastError() == NTE_BAD_ALGID) {
1285 win_skip("SHA-256/384/512 hashes are not supported before Windows XP SP3\n");
1286 return;
1287 }
1288 ok(result, "%08x\n", GetLastError());
1289 if (result) {
1290 len = sizeof(DWORD);
1291 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1292 ok(result && (hashlen == 32), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1293
1294 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1295 ok(result, "%08x\n", GetLastError());
1296
1297 len = 32;
1298 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1299 ok(result, "%08x\n", GetLastError());
1300
1301 ok(!memcmp(pbHashValue, sha256hash, 32), "Wrong SHA-256 hash!\n");
1302
1303 result = CryptDestroyHash(hHash);
1304 ok(result, "%08x\n", GetLastError());
1305 }
1306
1307 /* SHA-384 hash */
1308 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
1309 ok(result, "%08x\n", GetLastError());
1310 if (result) {
1311 len = sizeof(DWORD);
1312 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1313 ok(result && (hashlen == 48), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1314
1315 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1316 ok(result, "%08x\n", GetLastError());
1317
1318 len = 48;
1319 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1320 ok(result, "%08x\n", GetLastError());
1321
1322 ok(!memcmp(pbHashValue, sha384hash, 48), "Wrong SHA-384 hash!\n");
1323
1324 result = CryptDestroyHash(hHash);
1325 ok(result, "%08x\n", GetLastError());
1326 }
1327
1328 /* SHA-512 hash */
1329 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
1330 ok(result, "%08x\n", GetLastError());
1331 if (result) {
1332 len = sizeof(DWORD);
1333 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1334 ok(result && (hashlen == 64), "%08x, hashlen: %d\n", GetLastError(), hashlen);
1335
1336 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1337 ok(result, "%08x\n", GetLastError());
1338
1339 len = 64;
1340 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1341 ok(result, "%08x\n", GetLastError());
1342
1343 ok(!memcmp(pbHashValue, sha512hash, 64), "Wrong SHA-512 hash!\n");
1344
1345 result = CryptDestroyHash(hHash);
1346 ok(result, "%08x\n", GetLastError());
1347 }
1348 }
1349
1350 static void test_rc2(void)
1351 {
1352 static const BYTE rc2_40_encrypted[16] = {
1353 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
1354 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
1355 static const BYTE rc2_128_encrypted[] = {
1356 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,
1357 0x2a,0x2a,0xc0,0xce,0x4c,0x89,0xb6,0x66 };
1358 static const BYTE rc2_40def_encrypted[] = {
1359 0x23,0xc8,0x70,0x13,0x42,0x2e,0xa8,0x98,
1360 0x5c,0xdf,0x7a,0x9b,0xea,0xdb,0x96,0x1b };
1361 static const BYTE rc2_40_salt_enh[24] = {
1362 0xA3, 0xD7, 0x41, 0x87, 0x7A, 0xD0, 0x18, 0xDB,
1363 0xD4, 0x6A, 0x4F, 0xEE, 0xF3, 0xCA, 0xCD, 0x34,
1364 0xB3, 0x15, 0x9A, 0x2A, 0x88, 0x5F, 0x43, 0xA5 };
1365 static const BYTE rc2_40_salt_base[24] = {
1366 0x8C, 0x4E, 0xA6, 0x00, 0x9B, 0x15, 0xEF, 0x9E,
1367 0x88, 0x81, 0xD0, 0x65, 0xD6, 0x53, 0x57, 0x08,
1368 0x0A, 0x77, 0x80, 0xFA, 0x7E, 0x89, 0x14, 0x55 };
1369 static const BYTE rc2_40_salt_strong[24] = {
1370 0xB9, 0x33, 0xB6, 0x7A, 0x35, 0xC3, 0x06, 0x88,
1371 0xBF, 0xD5, 0xCC, 0xAF, 0x14, 0xAE, 0xE2, 0x31,
1372 0xC6, 0x9A, 0xAA, 0x3F, 0x05, 0x2F, 0x22, 0xDA };
1373 HCRYPTHASH hHash;
1374 HCRYPTKEY hKey;
1375 BOOL result;
1376 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits, error;
1377 unsigned char pbData[2000], pbHashValue[16], pszBuffer[256];
1378 int i;
1379
1380 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1381
1382 /* MD2 Hashing */
1383 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1384 if (!result) {
1385 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1386 } else {
1387 CRYPT_INTEGER_BLOB salt;
1388
1389 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1390 ok(result, "%08x\n", GetLastError());
1391
1392 dwLen = 16;
1393 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1394 ok(result, "%08x\n", GetLastError());
1395
1396 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
1397 ok(result, "%08x\n", GetLastError());
1398
1399 dwLen = sizeof(DWORD);
1400 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1401 ok(result, "%08x\n", GetLastError());
1402
1403 /* test default chaining mode */
1404 dwMode = 0xdeadbeef;
1405 dwLen = sizeof(dwMode);
1406 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1407 ok(result, "%08x\n", GetLastError());
1408 ok(dwMode == CRYPT_MODE_CBC, "Wrong default chaining mode\n");
1409
1410 dwMode = CRYPT_MODE_CBC;
1411 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
1412 ok(result, "%08x\n", GetLastError());
1413
1414 dwLen = sizeof(DWORD);
1415 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
1416 ok(result, "%08x\n", GetLastError());
1417
1418 dwModeBits = 0xdeadbeef;
1419 dwLen = sizeof(DWORD);
1420 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1421 ok(result, "%08x\n", GetLastError());
1422 ok(dwModeBits ==
1423 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1424 broken(dwModeBits == 0xffffffff), /* Win9x/NT4 */
1425 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1426 " got %08x\n", dwModeBits);
1427
1428 dwLen = sizeof(DWORD);
1429 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1430 ok(result, "%08x\n", GetLastError());
1431
1432 dwLen = sizeof(DWORD);
1433 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
1434 ok(result, "%08x\n", GetLastError());
1435 ok(dwLen == 4, "Expected 4, got %d\n", dwLen);
1436
1437 dwLen = 0;
1438 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1439 ok(result, "%08x\n", GetLastError());
1440 result = CryptGetKeyParam(hKey, KP_IV, pszBuffer, &dwLen, 0);
1441 ok(result, "%08x\n", GetLastError());
1442 ok(dwLen == 8, "Expected 8, got %d\n", dwLen);
1443
1444 dwLen = 0;
1445 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1446 ok(result, "%08x\n", GetLastError());
1447 /* The default salt length is always 11... */
1448 ok(dwLen == 11, "unexpected salt length %d\n", dwLen);
1449 /* and the default salt is always empty. */
1450 result = CryptGetKeyParam(hKey, KP_SALT, pszBuffer, &dwLen, 0);
1451 ok(result, "%08x\n", GetLastError());
1452 for (i=0; i<dwLen; i++)
1453 ok(!pszBuffer[i], "unexpected salt value %02x @ %d\n", pszBuffer[i], i);
1454
1455 dwLen = sizeof(DWORD);
1456 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1457 ok(result, "%08x\n", GetLastError());
1458 ok(dwMode == CRYPT_MODE_CBC, "Expected CRYPT_MODE_CBC, got %d\n", dwMode);
1459
1460 result = CryptDestroyHash(hHash);
1461 ok(result, "%08x\n", GetLastError());
1462
1463 dwDataLen = 13;
1464 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1465 ok(result, "%08x\n", GetLastError());
1466
1467 ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
1468
1469 dwLen = 0;
1470 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1471 ok(result, "%08x\n", GetLastError());
1472 result = CryptGetKeyParam(hKey, KP_IV, pszBuffer, &dwLen, 0);
1473 ok(result, "%08x\n", GetLastError());
1474
1475 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1476 ok(result, "%08x\n", GetLastError());
1477
1478 /* Setting the salt value will not reset the salt length in base or strong providers */
1479 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1480 ok(result, "setting salt failed: %08x\n", GetLastError());
1481 dwLen = 0;
1482 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1483 ok(result, "%08x\n", GetLastError());
1484 if (BASE_PROV || STRONG_PROV)
1485 ok(dwLen == 11, "expected salt length 11, got %d\n", dwLen);
1486 else
1487 ok(dwLen == 0 || broken(nt4 && dwLen == 11), "expected salt length 0, got %d\n", dwLen);
1488 /* What sizes salt can I set? */
1489 salt.pbData = pbData;
1490 for (i=0; i<24; i++)
1491 {
1492 salt.cbData = i;
1493 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1494 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1495 /* The returned salt length is the same as the set salt length */
1496 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1497 ok(result, "%08x\n", GetLastError());
1498 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1499 }
1500 salt.cbData = 25;
1501 SetLastError(0xdeadbeef);
1502 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1503 ok(!result ||
1504 broken(result), /* Win9x, WinMe, NT4, W2K */
1505 "%08x\n", GetLastError());
1506
1507 result = CryptDestroyKey(hKey);
1508 ok(result, "%08x\n", GetLastError());
1509 }
1510
1511 /* Again, but test setting the effective key len */
1512 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1513
1514 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1515 if (!result) {
1516 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
1517 } else {
1518 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1519 ok(result, "%08x\n", GetLastError());
1520
1521 dwLen = 16;
1522 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1523 ok(result, "%08x\n", GetLastError());
1524
1525 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
1526 ok(result, "%08x\n", GetLastError());
1527
1528 SetLastError(0xdeadbeef);
1529 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
1530 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
1531 dwKeyLen = 0;
1532 SetLastError(0xdeadbeef);
1533 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1534 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
1535 dwKeyLen = 1025;
1536 SetLastError(0xdeadbeef);
1537 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1538 ok(!result, "CryptSetKeyParam failed: %08x\n", GetLastError());
1539
1540 dwLen = sizeof(dwKeyLen);
1541 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1542 ok(result, "%08x\n", GetLastError());
1543 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1544 result = CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1545 ok(result, "%08x\n", GetLastError());
1546 ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%d (%08x)\n", dwKeyLen, GetLastError());
1547
1548 dwKeyLen = 128;
1549 SetLastError(0xdeadbeef);
1550 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1551 if (!BASE_PROV)
1552 {
1553 dwKeyLen = 12345;
1554 ok(result, "expected success, got error 0x%08X\n", GetLastError());
1555 result = CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1556 ok(result, "%08x\n", GetLastError());
1557 ok(dwKeyLen == 128, "Expected 128, got %d\n", dwKeyLen);
1558 }
1559 else
1560 {
1561 ok(!result, "expected error\n");
1562 ok(GetLastError() == NTE_BAD_DATA, "Expected 0x80009005, got 0x%08X\n", GetLastError());
1563 result = CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1564 ok(result, "%08x\n", GetLastError());
1565 ok(dwKeyLen == 40, "Expected 40, got %d\n", dwKeyLen);
1566 }
1567
1568 dwLen = sizeof(dwKeyLen);
1569 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1570 ok(result, "%08x\n", GetLastError());
1571 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
1572 result = CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1573 ok(result, "%08x\n", GetLastError());
1574 ok((!BASE_PROV && dwKeyLen == 128) || (BASE_PROV && dwKeyLen == 40),
1575 "%d (%08x)\n", dwKeyLen, GetLastError());
1576
1577 result = CryptDestroyHash(hHash);
1578 ok(result, "%08x\n", GetLastError());
1579
1580 dwDataLen = 13;
1581 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1582 ok(result, "%08x\n", GetLastError());
1583 ok(!memcmp(pbData, !BASE_PROV ? rc2_128_encrypted : rc2_40def_encrypted,
1584 sizeof(rc2_128_encrypted)), "RC2 encryption failed!\n");
1585
1586 /* Oddly enough this succeeds, though it should have no effect */
1587 dwKeyLen = 40;
1588 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
1589 ok(result, "%d\n", GetLastError());
1590
1591 result = CryptDestroyKey(hKey);
1592 ok(result, "%08x\n", GetLastError());
1593
1594 /* Test a 40 bit key with salt */
1595 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1596 ok(result, "%08x\n", GetLastError());
1597
1598 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1599 ok(result, "%08x\n", GetLastError());
1600
1601 result = CryptDeriveKey(hProv, CALG_RC2, hHash, (40<<16)|CRYPT_CREATE_SALT, &hKey);
1602 ok(result, "%08x\n", GetLastError());
1603
1604 dwDataLen = 16;
1605 memset(pbData, 0xAF, dwDataLen);
1606 SetLastError(0xdeadbeef);
1607 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1608 if(result)
1609 {
1610 ok((ENHANCED_PROV && !memcmp(pbData, rc2_40_salt_enh, dwDataLen)) ||
1611 (STRONG_PROV && !memcmp(pbData, rc2_40_salt_strong, dwDataLen)) ||
1612 (BASE_PROV && !memcmp(pbData, rc2_40_salt_base, dwDataLen)),
1613 "RC2 encryption failed!\n");
1614 }
1615 else /* <= XP */
1616 {
1617 error = GetLastError();
1618 ok(error == NTE_BAD_DATA || broken(error == NTE_DOUBLE_ENCRYPT),
1619 "Expected 0x80009005, got 0x%08X\n", error);
1620 }
1621 dwLen = sizeof(DWORD);
1622 dwKeyLen = 12345;
1623 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1624 ok(result, "%08x\n", GetLastError());
1625 ok(dwKeyLen == 40, "Expected 40, got %d\n", dwKeyLen);
1626
1627 dwLen = sizeof(pszBuffer);
1628 memset(pszBuffer, 0xAF, dwLen);
1629 result = CryptGetKeyParam(hKey, KP_SALT, pszBuffer, &dwLen, 0);
1630 ok(result, "%08x\n", GetLastError());
1631 if (!ENHANCED_PROV)
1632 ok(dwLen == 11, "Expected 11, got %d\n", dwLen);
1633 else
1634 ok(dwLen == 0, "Expected 0, got %d\n", dwLen);
1635
1636 result = CryptDestroyKey(hKey);
1637 ok(result, "%08x\n", GetLastError());
1638
1639 result = CryptDestroyHash(hHash);
1640 ok(result, "%08x\n", GetLastError());
1641 }
1642 }
1643
1644 static void test_rc4(void)
1645 {
1646 static const BYTE rc4[16] = {
1647 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
1648 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
1649 static const BYTE rc4_40_salt[16] = {
1650 0x41, 0xE6, 0x33, 0xC9, 0x50, 0xA1, 0xBF, 0x88,
1651 0x12, 0x4D, 0xD3, 0xE3, 0x47, 0x88, 0x6D, 0xA5 };
1652 static const BYTE rc4_40_salt_base[16] = {
1653 0x2F, 0xAC, 0xEA, 0xEA, 0xFF, 0x68, 0x7E, 0x77,
1654 0xF4, 0xB9, 0x48, 0x7C, 0x4E, 0x79, 0xA6, 0xB5 };
1655 BOOL result;
1656 HCRYPTHASH hHash;
1657 HCRYPTKEY hKey;
1658 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1659 unsigned char pbData[2000];
1660 unsigned char pszBuffer[256];
1661 int i;
1662
1663 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1664
1665 /* MD2 Hashing */
1666 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1667 if (!result) {
1668 /* rsaenh compiled without OpenSSL */
1669 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
1670 } else {
1671 CRYPT_INTEGER_BLOB salt;
1672
1673 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1674 ok(result, "%08x\n", GetLastError());
1675
1676 dwLen = 16;
1677 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1678 ok(result, "%08x\n", GetLastError());
1679
1680 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1681 ok(result, "%08x\n", GetLastError());
1682
1683 dwLen = sizeof(DWORD);
1684 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1685 ok(result, "%08x\n", GetLastError());
1686 ok(dwKeyLen == 56, "Expected 56, got %d\n", dwKeyLen);
1687
1688 dwLen = sizeof(DWORD);
1689 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1690 ok(result, "%08x\n", GetLastError());
1691 ok(dwKeyLen == 0, "Expected 0, got %d\n", dwKeyLen);
1692
1693 dwLen = 0;
1694 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1695 ok(result, "%08x\n", GetLastError());
1696 result = CryptGetKeyParam(hKey, KP_IV, pszBuffer, &dwLen, 0);
1697
1698 dwLen = 0;
1699 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1700 ok(result, "%08x\n", GetLastError());
1701 result = CryptGetKeyParam(hKey, KP_SALT, pszBuffer, &dwLen, 0);
1702 ok(result, "%08x\n", GetLastError());
1703
1704 dwLen = sizeof(DWORD);
1705 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1706 ok(result, "%08x\n", GetLastError());
1707 ok(dwMode == 0 || broken(dwMode == CRYPT_MODE_CBC) /* <= 2000 */,
1708 "Expected 0, got %d\n", dwMode);
1709
1710 result = CryptDestroyHash(hHash);
1711 ok(result, "%08x\n", GetLastError());
1712
1713 dwDataLen = 16;
1714 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1715 ok(result, "%08x\n", GetLastError());
1716 dwDataLen = 16;
1717 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1718 ok(result, "%08x\n", GetLastError());
1719
1720 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1721
1722 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1723 ok(result, "%08x\n", GetLastError());
1724
1725 /* Setting the salt value will not reset the salt length in base or strong providers */
1726 result = CryptSetKeyParam(hKey, KP_SALT, pbData, 0);
1727 ok(result, "setting salt failed: %08x\n", GetLastError());
1728 dwLen = 0;
1729 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1730 ok(result, "%08x\n", GetLastError());
1731 if (BASE_PROV || STRONG_PROV)
1732 ok(dwLen == 11, "expected salt length 11, got %d\n", dwLen);
1733 else
1734 ok(dwLen == 0 || broken(nt4 && dwLen == 11), "expected salt length 0, got %d\n", dwLen);
1735 /* What sizes salt can I set? */
1736 salt.pbData = pbData;
1737 for (i=0; i<24; i++)
1738 {
1739 salt.cbData = i;
1740 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1741 ok(result, "setting salt failed for size %d: %08x\n", i, GetLastError());
1742 /* The returned salt length is the same as the set salt length */
1743 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1744 ok(result, "%08x\n", GetLastError());
1745 ok(dwLen == i, "size %d: unexpected salt length %d\n", i, dwLen);
1746 }
1747 salt.cbData = 25;
1748 SetLastError(0xdeadbeef);
1749 result = CryptSetKeyParam(hKey, KP_SALT_EX, (BYTE *)&salt, 0);
1750 ok(!result ||
1751 broken(result), /* Win9x, WinMe, NT4, W2K */
1752 "%08x\n", GetLastError());
1753
1754 result = CryptDestroyKey(hKey);
1755 ok(result, "%08x\n", GetLastError());
1756
1757 /* Test a 40 bit key with salt */
1758 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1759 ok(result, "%08x\n", GetLastError());
1760
1761 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1762 ok(result, "%08x\n", GetLastError());
1763
1764 result = CryptDeriveKey(hProv, CALG_RC4, hHash, (40<<16)|CRYPT_CREATE_SALT, &hKey);
1765 ok(result, "%08x\n", GetLastError());
1766 dwDataLen = 16;
1767 memset(pbData, 0xAF, dwDataLen);
1768 SetLastError(0xdeadbeef);
1769 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1770 ok(result, "%08x\n", GetLastError());
1771 ok((ENHANCED_PROV && !memcmp(pbData, rc4_40_salt, dwDataLen)) ||
1772 (!ENHANCED_PROV && !memcmp(pbData, rc4_40_salt_base, dwDataLen)),
1773 "RC4 encryption failed!\n");
1774
1775 dwLen = sizeof(DWORD);
1776 dwKeyLen = 12345;
1777 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1778 ok(result, "%08x\n", GetLastError());
1779 ok(dwKeyLen == 40, "Expected 40, got %d\n", dwKeyLen);
1780
1781 dwLen = sizeof(pszBuffer);
1782 memset(pszBuffer, 0xAF, dwLen);
1783 result = CryptGetKeyParam(hKey, KP_SALT, pszBuffer, &dwLen, 0);
1784 ok(result, "%08x\n", GetLastError());
1785 if (!ENHANCED_PROV)
1786 ok(dwLen == 11, "Expected 11, got %d\n", dwLen);
1787 else
1788 ok(dwLen == 0, "Expected 0, got %d\n", dwLen);
1789
1790 result = CryptDestroyKey(hKey);
1791 ok(result, "%08x\n", GetLastError());
1792
1793 result = CryptDestroyHash(hHash);
1794 ok(result, "%08x\n", GetLastError());
1795 }
1796 }
1797
1798 static void test_hmac(void) {
1799 HCRYPTKEY hKey;
1800 HCRYPTHASH hHash;
1801 BOOL result;
1802 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1803 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1804 DWORD dwLen;
1805 BYTE abData[256];
1806 static const BYTE hmac[16] = {
1807 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1808 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1809 int i;
1810
1811 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1812
1813 if (!derive_key(CALG_RC2, &hKey, 56)) return;
1814
1815 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1816 ok(result, "%08x\n", GetLastError());
1817 if (!result) return;
1818
1819 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1820 ok(result, "%08x\n", GetLastError());
1821
1822 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1823 ok(result, "%08x\n", GetLastError());
1824
1825 dwLen = sizeof(abData)/sizeof(BYTE);
1826 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1827 ok(result, "%08x\n", GetLastError());
1828
1829 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1830
1831 result = CryptDestroyHash(hHash);
1832 ok(result, "%08x\n", GetLastError());
1833
1834 result = CryptDestroyKey(hKey);
1835 ok(result, "%08x\n", GetLastError());
1836
1837 /* Provoke errors */
1838 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1839 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1840 }
1841
1842 static void test_mac(void) {
1843 HCRYPTKEY hKey;
1844 HCRYPTHASH hHash;
1845 BOOL result;
1846 DWORD dwLen;
1847 BYTE abData[256], abEnc[264];
1848 static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1849 int i;
1850
1851 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1852 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1853
1854 if (!derive_key(CALG_RC2, &hKey, 40)) return;
1855
1856 dwLen = 256;
1857 result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
1858 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1859
1860 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1861 ok(result, "%08x\n", GetLastError());
1862 if (!result) return;
1863
1864 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1865 ok(result, "%08x\n", GetLastError());
1866
1867 dwLen = sizeof(abData)/sizeof(BYTE);
1868 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1869 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1870
1871 ok(!memcmp(abData, mac_40, sizeof(mac_40)), "MAC failed!\n");
1872
1873 result = CryptDestroyHash(hHash);
1874 ok(result, "%08x\n", GetLastError());
1875
1876 result = CryptDestroyKey(hKey);
1877 ok(result, "%08x\n", GetLastError());
1878
1879 /* Provoke errors */
1880 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1881
1882 SetLastError(0xdeadbeef);
1883 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1884 ok((!result && GetLastError() == NTE_BAD_KEY) ||
1885 broken(result), /* Win9x, WinMe, NT4, W2K */
1886 "%08x\n", GetLastError());
1887
1888 result = CryptDestroyKey(hKey);
1889 ok(result, "%08x\n", GetLastError());
1890 }
1891
1892 static void test_import_private(void)
1893 {
1894 DWORD dwLen, dwVal;
1895 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1896 BOOL result;
1897 static BYTE abSessionKey[148] = {
1898 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1899 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1900 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1901 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1902 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1903 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1904 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1905 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1906 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1907 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1908 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1909 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1910 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1911 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1912 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1913 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1914 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1915 0x04, 0x8c, 0x49, 0x92
1916 };
1917 static BYTE abEncryptedMessage[12] = {
1918 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1919 0x1c, 0xfd, 0xde, 0x71
1920 };
1921 BLOBHEADER *blobHeader = (BLOBHEADER *)abPlainPrivateKey;
1922 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(blobHeader+1);
1923
1924 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1925 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1926 if (!result) {
1927 /* rsaenh compiled without OpenSSL */
1928 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1929 return;
1930 }
1931
1932 dwLen = (DWORD)sizeof(abSessionKey);
1933 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1934 ok(result, "%08x\n", GetLastError());
1935 if (!result) return;
1936
1937 dwVal = 0xdeadbeef;
1938 dwLen = sizeof(DWORD);
1939 result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
1940 ok(result, "%08x\n", GetLastError());
1941 ok(dwVal ==
1942 (CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT) ||
1943 broken(dwVal == 0xffffffff), /* Win9x/NT4 */
1944 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT,"
1945 " got %08x\n", dwVal);
1946
1947 dwLen = (DWORD)sizeof(abEncryptedMessage);
1948 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1949 ok(result, "%08x\n", GetLastError());
1950 ok(dwLen == 12, "expected 12, got %d\n", dwLen);
1951 ok(!memcmp(abEncryptedMessage, "Wine rocks!", 12), "decrypt failed\n");
1952 CryptDestroyKey(hSessionKey);
1953
1954 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1955
1956 dwLen = (DWORD)sizeof(abSessionKey);
1957 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1958 ok(result, "%08x\n", GetLastError());
1959 CryptDestroyKey(hSessionKey);
1960 if (!result) return;
1961
1962 dwLen = (DWORD)sizeof(abSessionKey);
1963 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1964 ok(result, "%08x\n", GetLastError());
1965 if (!result) return;
1966
1967 CryptDestroyKey(hSessionKey);
1968 CryptDestroyKey(hKeyExchangeKey);
1969
1970 /* Test importing a private key with a buffer that's smaller than the
1971 * actual buffer. The private exponent can be omitted, its length is
1972 * inferred from the passed-in length parameter.
1973 */
1974 dwLen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
1975 rsaPubKey->bitlen / 8 + 5 * rsaPubKey->bitlen / 16;
1976 for (; dwLen < sizeof(abPlainPrivateKey); dwLen++)
1977 {
1978 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1979 ok(result, "CryptImportKey failed at size %d: %d (%08x)\n", dwLen,
1980 GetLastError(), GetLastError());
1981 if (result)
1982 CryptDestroyKey(hKeyExchangeKey);
1983 }
1984 }
1985
1986 static void test_verify_signature(void) {
1987 HCRYPTHASH hHash;
1988 HCRYPTKEY hPubSignKey;
1989 BYTE abData[] = "Wine rocks!";
1990 BOOL result;
1991 BYTE abPubKey[148] = {
1992 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1993 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1994 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1995 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1996 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1997 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1998 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1999 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
2000 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
2001 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
2002 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
2003 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
2004 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
2005 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
2006 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
2007 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
2008 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
2009 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
2010 0xe1, 0x21, 0x50, 0xac
2011 };
2012 /* md2 with hash oid */
2013 BYTE abSignatureMD2[128] = {
2014 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
2015 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
2016 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
2017 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
2018 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
2019 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
2020 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
2021 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
2022 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
2023 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
2024 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
2025 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
2026 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
2027 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
2028 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
2029 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
2030 };
2031 /* md2 without hash oid */
2032 BYTE abSignatureMD2NoOID[128] = {
2033 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
2034 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
2035 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
2036 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
2037 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
2038 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
2039 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
2040 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
2041 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
2042 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
2043 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
2044 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
2045 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
2046 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
2047 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
2048 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
2049 };
2050 /* md4 with hash oid */
2051 BYTE abSignatureMD4[128] = {
2052 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
2053 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
2054 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
2055 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
2056 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
2057 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
2058 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
2059 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
2060 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
2061 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
2062 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
2063 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
2064 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
2065 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
2066 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
2067 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
2068 };
2069 /* md4 without hash oid */
2070 BYTE abSignatureMD4NoOID[128] = {
2071 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
2072 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
2073 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
2074 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
2075 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
2076 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
2077 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
2078 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
2079 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
2080 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
2081 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
2082 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
2083 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
2084 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
2085 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
2086 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
2087 };
2088 /* md5 with hash oid */
2089 BYTE abSignatureMD5[128] = {
2090 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
2091 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
2092 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
2093 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
2094 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
2095 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
2096 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
2097 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
2098 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
2099 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
2100 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
2101 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
2102 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
2103 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
2104 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
2105 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
2106 };
2107 /* md5 without hash oid */
2108 BYTE abSignatureMD5NoOID[128] = {
2109 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
2110 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
2111 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
2112 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
2113 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
2114 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
2115 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
2116 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
2117 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
2118 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
2119 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
2120 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
2121 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
2122 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
2123 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
2124 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
2125 };
2126 /* sha with hash oid */
2127 BYTE abSignatureSHA[128] = {
2128 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
2129 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
2130 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
2131 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
2132 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
2133 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
2134 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
2135 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
2136 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
2137 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
2138 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
2139 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
2140 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
2141 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
2142 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
2143 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
2144 };
2145 /* sha without hash oid */
2146 BYTE abSignatureSHANoOID[128] = {
2147 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
2148 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
2149 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
2150 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
2151 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
2152 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
2153 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
2154 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
2155 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
2156 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
2157 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
2158 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
2159 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
2160 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
2161 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
2162 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
2163 };
2164
2165 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
2166 ok(result, "%08x\n", GetLastError());
2167 if (!result) return;
2168
2169 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
2170 ok(result, "%08x\n", GetLastError());
2171 if (!result) return;
2172
2173 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
2174 ok(result, "%08x\n", GetLastError());
2175 if (!result) return;
2176
2177 /*check that a NULL pointer signature is correctly handled*/
2178 result = CryptVerifySignatureA(hHash, NULL, 128, hPubSignKey, NULL, 0);
2179 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
2180 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
2181 if (result) return;
2182
2183 /* check that we get a bad signature error when the signature is too short*/
2184 SetLastError(0xdeadbeef);
2185 result = CryptVerifySignatureA(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
2186 ok((!result && NTE_BAD_SIGNATURE == GetLastError()) ||
2187 broken(result), /* Win9x, WinMe, NT4 */
2188 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
2189
2190 result = CryptVerifySignatureA(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
2191 ok(result, "%08x\n", GetLastError());
2192 if (!result) return;
2193
2194 /* It seems that CPVerifySignature doesn't care about the OID at all. */
2195 result = CryptVerifySignatureA(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
2196 ok(result, "%08x\n", GetLastError());
2197 if (!result) return;
2198
2199 result = CryptVerifySignatureA(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
2200 ok(result, "%08x\n", GetLastError());
2201 if (!result) return;
2202
2203 CryptDestroyHash(hHash);
2204
2205 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
2206 ok(result, "%08x\n", GetLastError());
2207 if (!result) return;
2208
2209 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
2210 ok(result, "%08x\n", GetLastError());
2211 if (!result) return;
2212
2213 result = CryptVerifySignatureA(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
2214 ok(result, "%08x\n", GetLastError());
2215 if (!result) return;
2216
2217 result = CryptVerifySignatureA(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, 0);
2218 ok(result, "%08x\n", GetLastError());
2219 if (!result) return;
2220
2221 result = CryptVerifySignatureA(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
2222 ok(result, "%08x\n", GetLastError());
2223 if (!result) return;
2224
2225 CryptDestroyHash(hHash);
2226
2227 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
2228 ok(result, "%08x\n", GetLastError());
2229 if (!result) return;
2230
2231 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
2232 ok(result, "%08x\n", GetLastError());
2233 if (!result) return;
2234
2235 result = CryptVerifySignatureA(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
2236 ok(result, "%08x\n", GetLastError());
2237 if (!result) return;
2238
2239 result = CryptVerifySignatureA(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, 0);
2240 ok(result, "%08x\n", GetLastError());
2241 if (!result) return;
2242
2243 result = CryptVerifySignatureA(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
2244 ok(result, "%08x\n", GetLastError());
2245 if (!result) return;
2246
2247 CryptDestroyHash(hHash);
2248
2249 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
2250 ok(result, "%08x\n", GetLastError());
2251 if (!result) return;
2252
2253 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
2254 ok(result, "%08x\n", GetLastError());
2255 if (!result) return;
2256
2257 result = CryptVerifySignatureA(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
2258 ok(result, "%08x\n", GetLastError());
2259 if (!result) return;
2260
2261 result = CryptVerifySignatureA(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, 0);
2262 ok(result, "%08x\n", GetLastError());
2263 if (!result) return;
2264
2265 result = CryptVerifySignatureA(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
2266 ok(result, "%08x\n", GetLastError());
2267 if (!result) return;
2268
2269 CryptDestroyHash(hHash);
2270 CryptDestroyKey(hPubSignKey);
2271 }
2272
2273 static void test_rsa_encrypt(void)
2274 {
2275 HCRYPTKEY hRSAKey;
2276 BYTE abData[2048] = "Wine rocks!";
2277 BOOL result;
2278 DWORD dwVal, dwLen;
2279
2280 /* It is allowed to use the key exchange key for encryption/decryption */
2281 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
2282 ok (result, "%08x\n", GetLastError());
2283 if (!result) return;
2284
2285 dwLen = 12;
2286 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
2287 if(!ENHANCED_PROV && !result && GetLastError() == NTE_BAD_KEY)
2288 {
2289 CryptDestroyKey(hRSAKey);
2290 return;
2291 }
2292 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
2293 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
2294 dwLen = 12;
2295 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
2296 ok (result, "%08x\n", GetLastError());
2297 if (!result)