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