ReactOS 0.4.17-dev-1190-g4c812f4
rsaenh.c
Go to the documentation of this file.
1/*
2 * Unit tests for rsaenh functions
3 *
4 * Copyright (c) 2004 Michael Jung
5 * Copyright (c) 2006 Juan Lang
6 * Copyright (c) 2007 Vijay Kiran Kamuju
7 * Copyright (c) 2025 Dmitry Timoshkov
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include <string.h>
25#include <stdio.h>
26#include "wine/test.h"
27#include "windef.h"
28#include "winbase.h"
29#include "winerror.h"
30#include "wincrypt.h"
31#include "winreg.h"
32
35static int iProv;
36static const char szContainer[] = "winetest";
37static const char *szProvider;
38
39#define ENHANCED_PROV (iProv == 0)
40#define BASE_PROV (iProv == 1)
41#define STRONG_PROV (iProv == 2)
42
43typedef struct _ctdatatype {
44 unsigned char origstr[32];
45 unsigned char decstr[32];
46 int strlen;
47 int enclen;
48 int buflen;
50
51static const cryptdata cTestData[4] = {
52 {"abcdefghijkl",
53 {'a','b','c','d','e','f','g','h',0x2,0x2,'k','l',0},
54 12,8,16},
55 {"abcdefghij",
56 {'a','b','c','d','e','f','g','h',0x2,0x2,0},
57 10,8,16},
58 {"abcdefgh",
59 {'a','b','c','d','e','f','g','h',0},
60 8,8,16},
61 {"abcdefghijkl",
62 {'a','b','c','d','e','f','g','h','i','j','k','l',0},
63 12,12,16}
64};
65
66/*
67 * 1. Take the MD5 Hash of the container name (with an extra null byte)
68 * 2. Turn the hash into a 4 DWORD hex value
69 * 3. Append a '_'
70 * 4. Add the MachineGuid
71 *
72 */
73static void uniquecontainer(char *unique)
74{
75 /* MD5 hash of "winetest\0" in 4 DWORD hex */
76 static const char szContainer_md5[] = "9d20fd8d05ed2b8455d125d0bf6d6a70";
77 static const char szCryptography[] = "Software\\Microsoft\\Cryptography";
78 static const char szMachineGuid[] = "MachineGuid";
79 HKEY hkey;
80 char guid[MAX_PATH];
82
83 /* Get the MachineGUID */
84 RegOpenKeyExA(HKEY_LOCAL_MACHINE, szCryptography, 0, KEY_READ | KEY_WOW64_64KEY, &hkey);
85 RegQueryValueExA(hkey, szMachineGuid, NULL, NULL, (LPBYTE)guid, &size);
86 RegCloseKey(hkey);
87
88 if (!unique) return;
89 lstrcpyA(unique, szContainer_md5);
90 lstrcatA(unique, "_");
92}
93
94static void printBytes(const char *heading, const BYTE *pb, size_t cb)
95{
96 size_t i;
97 printf("%s: ",heading);
98 for(i=0;i<cb;i++)
99 printf("0x%02x,",pb[i]);
100 putchar('\n');
101}
102
103static void trace_hex(BYTE *pbData, DWORD dwLen) {
104 char szTemp[256];
105 DWORD i, j;
106
107 for (i = 0; i < dwLen-7; i+=8) {
108 trace("0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
109 pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5],
110 pbData[i+6], pbData[i+7]);
111 }
112 for (j=0; i<dwLen; j++,i++) {
113 sprintf(szTemp+6*j, "0x%02x, ", pbData[i]);
114 }
115 if (j)
116 trace("%s\n", szTemp);
117}
118
119static BOOL init_base_environment(const char *provider, DWORD dwKeyFlags)
120{
122 BOOL result;
123
124 if (provider) szProvider = provider;
125
127
129 ok(!result && GetLastError() == NTE_BAD_FLAGS, "%d, %08lx\n", result, GetLastError());
130
132 {
134 broken(GetLastError() == NTE_TEMPORARY_PROFILE /* some Win7 setups */), "%08lx\n", GetLastError());
136 {
137 win_skip("RSA full provider not available\n");
138 return FALSE;
139 }
142 ok(result, "%08lx\n", GetLastError());
143 if (!result)
144 {
145 win_skip("Couldn't create crypto provider\n");
146 return FALSE;
147 }
148 result = CryptGenKey(hProv, AT_KEYEXCHANGE, dwKeyFlags, &hKey);
149 ok(result, "%08lx\n", GetLastError());
151 result = CryptGenKey(hProv, AT_SIGNATURE, dwKeyFlags, &hKey);
152 ok(result, "%08lx\n", GetLastError());
154 }
155 return TRUE;
156}
157
159{
160 BOOL result;
161
162 SetLastError(0xdeadbeef);
164 ok(!result, "Expected failure\n");
165 ok(GetLastError()==NTE_BAD_FLAGS, "Expected NTE_BAD_FLAGS, got %08lx\n", GetLastError());
166
167 /* Just to prove that Win98 also released the CSP */
168 SetLastError(0xdeadbeef);
171
173}
174
176{
178 BOOL result;
179
181
182 /* we are using NULL as provider name for RSA_AES provider as the provider
183 * names are different in Windows XP and Vista. This differs from what
184 * is defined in the SDK on Windows XP.
185 * This provider is available on Windows XP, Windows 2003 and Vista. */
186
189 {
190 win_skip("RSA_AES provider not supported\n");
191 return FALSE;
192 }
193 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08lx\n", result, GetLastError());
194
196 {
197 ok(GetLastError()==NTE_BAD_KEYSET, "%08lx\n", GetLastError());
198 if (GetLastError()!=NTE_BAD_KEYSET) return FALSE;
201 ok(result, "%08lx\n", GetLastError());
203 ok(result, "%08lx\n", GetLastError());
206 ok(result, "%08lx\n", GetLastError());
208
209 /* CALG_AES is not supported, but CALG_AES_128 is */
211 ok(!result && GetLastError() == NTE_BAD_ALGID, "%d %08lx\n", result, GetLastError());
212 result = CryptGenKey(hProv, CALG_AES, 128 << 16, &hKey);
213 ok(!result && GetLastError() == NTE_BAD_ALGID, "%d %08lx\n", result, GetLastError());
215 ok(result, "%08lx\n", GetLastError());
217 }
218 return TRUE;
219}
220
222{
223 BOOL result;
224
226 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08lx\n", GetLastError());
227
229}
230
231static void test_prov(void)
232{
233 BOOL result;
234 DWORD dwLen, dwInc;
235
236 dwLen = sizeof(DWORD);
237 SetLastError(0xdeadbeef);
238 result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
239 ok(result && dwInc==8, "%08lx, %ld\n", GetLastError(), dwInc);
240
241 dwLen = sizeof(DWORD);
242 SetLastError(0xdeadbeef);
243 result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
244 ok(result && dwInc == 8, "%08lx, %ld\n", GetLastError(), dwInc);
245}
246
247static void test_gen_random(void)
248{
249 BOOL result;
250 BYTE rnd1[16], rnd2[16];
251
252 memset(rnd1, 0, sizeof(rnd1));
253 memset(rnd2, 0, sizeof(rnd2));
254
255 result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
256 ok(result, "%08lx\n", GetLastError());
257
258 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
259 ok(result, "%08lx\n", GetLastError());
260
261 ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
262}
263
264static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
265{
266 HCRYPTHASH hHash;
267 BOOL result;
268 unsigned char pbData[2000];
269 int i;
270
271 *phKey = 0;
272 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
273 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
274 ok(result, "%08lx\n", GetLastError());
275 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
276 ok(result, "%08lx\n", GetLastError());
277 result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
278 ok(result, "%08lx\n", GetLastError());
279 len = 2000;
281 ok(result, "%08lx\n", GetLastError());
282 CryptDestroyHash(hHash);
283 return TRUE;
284}
285
286static BYTE abPlainPrivateKey[596] = {
287 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
288 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
289 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
290 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
291 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
292 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
293 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
294 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
295 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
296 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
297 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
298 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
299 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
300 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
301 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
302 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
303 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
304 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
305 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
306 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
307 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
308 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
309 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
310 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
311 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
312 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
313 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
314 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
315 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
316 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
317 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
318 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
319 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
320 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
321 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
322 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
323 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
324 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
325 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
326 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
327 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
328 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
329 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
330 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
331 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
332 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
333 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
334 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
335 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
336 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
337 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
338 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
339 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
340 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
341 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
342 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
343 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
344 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
345 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
346 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
347 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
348 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
349 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
350 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
351 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
352 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
353 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
354 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
355 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
356 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
357 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
358 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
359 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
360 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
361 0xf2, 0x5d, 0x58, 0x07
362};
363
364static void test_hashes(void)
365{
366 static const unsigned char md2hash[16] = {
367 0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
368 0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
369 static const unsigned char md4hash[16] = {
370 0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
371 0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
372 static const unsigned char empty_md5hash[16] = {
373 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
374 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
375 static const unsigned char md5hash[16] = {
376 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
377 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
378 static const unsigned char sha1hash[20] = {
379 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
380 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
381 static const unsigned char signed_ssl3_shamd5_hash[] = {
382 0x4f,0xcc,0x2f,0x33,0x44,0x60,0x76,0x16,0x13,0xc8,0xff,0xd4,0x59,0x19,
383 0xde,0x85,0x44,0x72,0x47,0x98,0x01,0xfb,0x67,0x5c,0x5b,0x35,0x15,0x0f,
384 0x91,0xda,0xc7,0x7c,0xfb,0xe2,0x18,0xef,0xac,0x31,0x40,0x7b,0xa9,0x83,
385 0xdb,0x30,0xcd,0x94,0x4b,0x8e,0x3b,0x6c,0x7a,0x86,0x59,0xf0,0xd1,0xd2,
386 0x5e,0xce,0xd4,0x1b,0x7f,0xed,0x24,0xee,0x53,0x5c,0x15,0x97,0x21,0x7c,
387 0x5c,0xea,0xab,0xf5,0xd6,0x4b,0xb3,0xbb,0x14,0xf5,0x59,0x9e,0x21,0x90,
388 0x21,0x99,0x19,0xad,0xa2,0xa6,0xea,0x61,0xc1,0x41,0xe2,0x70,0x77,0xf7,
389 0x15,0x68,0x96,0x1e,0x5c,0x84,0x97,0xe3,0x5c,0xd2,0xd9,0xfb,0x87,0x6f,
390 0x11,0x21,0x82,0x43,0x76,0x32,0xa4,0x38,0x7b,0x85,0x22,0x30,0x1e,0x55,
391 0x79,0x93 };
392 unsigned char pbData[2048];
393 BOOL result;
394 HCRYPTHASH hHash, hHashClone;
395 HCRYPTPROV prov;
396 BYTE pbHashValue[36];
397 BYTE pbSigValue[128];
398 HCRYPTKEY hKeyExchangeKey;
399 DWORD hashlen, len, error, cryptflags;
400 int i;
401
402 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
403
404 /* MD2 Hashing */
405 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
406 ok(result, "%08lx\n", GetLastError());
407
408 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
409 ok(result, "%08lx\n", GetLastError());
410
411 len = sizeof(DWORD);
412 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
413 ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
414
415 len = 16;
416 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
417 ok(result, "%08lx\n", GetLastError());
418 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
419
420 result = CryptDestroyHash(hHash);
421 ok(result, "%08lx\n", GetLastError());
422
423 /* MD4 Hashing */
424 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
425 ok(result, "%08lx\n", GetLastError());
426
427 result = CryptHashData(hHash, pbData, sizeof(pbData), ~0);
428 ok(!result && GetLastError() == NTE_BAD_FLAGS, "%08lx\n", GetLastError());
429
430 cryptflags = CRYPT_USERDATA;
431 result = CryptHashData(hHash, pbData, sizeof(pbData), cryptflags);
432 ok(result, "%08lx\n", GetLastError());
433
434 len = sizeof(DWORD);
435 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
436 ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
437
438 len = 16;
439 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
440 ok(result, "%08lx\n", GetLastError());
441
442 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
443
444 result = CryptDestroyHash(hHash);
445 ok(result, "%08lx\n", GetLastError());
446
447 /* MD5 Hashing */
448 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
449 ok(result, "%08lx\n", GetLastError());
450
451 len = sizeof(DWORD);
452 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
453 ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
454
455 result = CryptHashData(hHash, pbData, sizeof(pbData), ~0);
456 ok(!result && GetLastError() == NTE_BAD_FLAGS, "%08lx\n", GetLastError());
457
458 result = CryptHashData(hHash, pbData, sizeof(pbData), cryptflags);
459 ok(result, "%08lx\n", GetLastError());
460
461 len = 16;
462 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
463 ok(result, "%08lx\n", GetLastError());
464
465 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
466
467 result = CryptDestroyHash(hHash);
468 ok(result, "%08lx\n", GetLastError());
469
470 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
471 ok(result, "%08lx\n", GetLastError());
472
473 /* The hash is available even if CryptHashData hasn't been called */
474 len = 16;
475 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
476 ok(result, "%08lx\n", GetLastError());
477
478 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
479
480 /* It's also stable: getting it twice results in the same value */
481 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
482 ok(result, "%08lx\n", GetLastError());
483
484 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
485
486 /* Can't add data after the hash been retrieved */
487 SetLastError(0xdeadbeef);
488 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
489 ok(!result, "Expected failure\n");
491 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID, got %08lx\n", GetLastError());
492
493 /* You can still retrieve the hash, its value just hasn't changed */
494 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
495 ok(result, "%08lx\n", GetLastError());
496
497 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
498
499 result = CryptDestroyHash(hHash);
500 ok(result, "%08lx\n", GetLastError());
501
502 /* SHA1 Hashing */
503 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
504 ok(result, "%08lx\n", GetLastError());
505
506 result = CryptHashData(hHash, pbData, 5, cryptflags);
507 ok(result, "%08lx\n", GetLastError());
508
509 result = CryptDuplicateHash(hHash, 0, 0, &hHashClone);
510 ok(result, "%08lx\n", GetLastError());
511
512 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
513 ok(result, "%08lx\n", GetLastError());
514
515 len = sizeof(DWORD);
516 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
517 ok(result && (hashlen == 20), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
518
519 len = 20;
520 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
521 ok(result, "%08lx\n", GetLastError());
522
523 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
524 result = CryptDestroyHash(hHashClone);
525 ok(result, "%08lx\n", GetLastError());
526
527 result = CryptDestroyHash(hHash);
528 ok(result, "%08lx\n", GetLastError());
529
530 /* The SHA-2 variants aren't supported in the RSA full provider */
531 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
533 "expected NTE_BAD_ALGID, got %08lx\n", GetLastError());
534 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
536 "expected NTE_BAD_ALGID, got %08lx\n", GetLastError());
537 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
539 "expected NTE_BAD_ALGID, got %08lx\n", GetLastError());
540
542 ok(result, "CryptAcquireContextA failed 0x%08lx\n", GetLastError());
543
544 result = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hHash);
545 ok(result, "CryptCreateHash failed 0x%08lx\n", GetLastError());
546
547 /* release provider before using the hash */
548 result = CryptReleaseContext(prov, 0);
549 ok(result, "CryptReleaseContext failed 0x%08lx\n", GetLastError());
550
551 SetLastError(0xdeadbeef);
552 result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
554 ok(!result, "CryptHashData succeeded\n");
555 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %lu\n", error);
556
557 SetLastError(0xdeadbeef);
558 result = CryptDestroyHash(hHash);
560 ok(!result, "CryptDestroyHash succeeded\n");
561 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %lu\n", error);
562
564 ok(result, "CryptAcquireContextA failed 0x%08lx\n", GetLastError());
565
566 result = CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
567 ok(result, "CryptCreateHash failed 0x%08lx\n", GetLastError());
568
569 result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0);
570 ok(result, "CryptHashData failed 0x%08lx\n", GetLastError());
571
572 result = CryptDuplicateHash(hHash, NULL, 0, &hHashClone);
573 ok(result, "CryptDuplicateHash failed 0x%08lx\n", GetLastError());
574
575 len = 20;
576 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
577 ok(result, "CryptGetHashParam failed 0x%08lx\n", GetLastError());
578
579 /* add data after duplicating the hash */
580 result = CryptHashData(hHash, (const BYTE *)"more data", sizeof("more data"), 0);
581 ok(result, "CryptHashData failed 0x%08lx\n", GetLastError());
582
583 result = CryptDestroyHash(hHash);
584 ok(result, "CryptDestroyHash failed 0x%08lx\n", GetLastError());
585
586 result = CryptDestroyHash(hHashClone);
587 ok(result, "CryptDestroyHash failed 0x%08lx\n", GetLastError());
588
589 result = CryptReleaseContext(prov, 0);
590 ok(result, "CryptReleaseContext failed 0x%08lx\n", GetLastError());
591
592 /* Test CALG_SSL3_SHAMD5 */
594 ok(result, "CryptAcquireContextA failed 0x%08lx\n", GetLastError());
595
596 /* Step 1: create an MD5 hash of the data */
597 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
598 ok(result, "CryptCreateHash failed 0x%08lx\n", GetLastError());
599 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
600 ok(result, "%08lx\n", GetLastError());
601 len = 16;
602 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
603 ok(result, "CryptGetHashParam failed 0x%08lx\n", GetLastError());
604 result = CryptDestroyHash(hHash);
605 ok(result, "CryptDestroyHash failed 0x%08lx\n", GetLastError());
606 /* Step 2: create a SHA1 hash of the data */
607 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
608 ok(result, "CryptCreateHash failed 0x%08lx\n", GetLastError());
609 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
610 ok(result, "%08lx\n", GetLastError());
611 len = 20;
612 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue + 16, &len, 0);
613 ok(result, "CryptGetHashParam failed 0x%08lx\n", GetLastError());
614 result = CryptDestroyHash(hHash);
615 ok(result, "CryptDestroyHash failed 0x%08lx\n", GetLastError());
616 /* Step 3: create a CALG_SSL3_SHAMD5 hash handle */
618 ok(result, "CryptCreateHash failed 0x%08lx\n", GetLastError());
619 /* Test that CryptHashData fails on this hash */
620 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
622 "%08lx\n", GetLastError());
623 result = CryptSetHashParam(hHash, HP_HASHVAL, pbHashValue, 0);
624 ok(result, "%08lx\n", GetLastError());
625 len = sizeof(abPlainPrivateKey);
626 result = CryptImportKey(hProv, abPlainPrivateKey, len, 0, 0, &hKeyExchangeKey);
627 ok(result, "%08lx\n", GetLastError());
628 len = 0;
630 ok(result, "%08lx\n", GetLastError());
631 ok(len == 128, "expected len 128, got %ld\n", len);
632 result = CryptSignHashA(hHash, AT_KEYEXCHANGE, NULL, 0, pbSigValue, &len);
633 ok(result, "%08lx\n", GetLastError());
634 ok(!memcmp(pbSigValue, signed_ssl3_shamd5_hash, len), "unexpected value\n");
635 if (len != 128 || memcmp(pbSigValue, signed_ssl3_shamd5_hash, len))
636 {
637 printBytes("expected", signed_ssl3_shamd5_hash,
638 sizeof(signed_ssl3_shamd5_hash));
639 printBytes("got", pbSigValue, len);
640 }
641 result = CryptDestroyKey(hKeyExchangeKey);
642 ok(result, "CryptDestroyKey failed 0x%08lx\n", GetLastError());
643 result = CryptDestroyHash(hHash);
644 ok(result, "CryptDestroyHash failed 0x%08lx\n", GetLastError());
645 result = CryptReleaseContext(prov, 0);
646 ok(result, "CryptReleaseContext failed 0x%08lx\n", GetLastError());
647}
648
649static void test_block_cipher_modes(void)
650{
651 static const BYTE plain[23] = {
652 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
653 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
654 static const BYTE ecb[24] = {
655 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
656 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
657 static const BYTE cbc[24] = {
658 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
659 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
660 static const BYTE cfb[24] = {
661 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
662 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
664 BOOL result;
665 BYTE abData[24];
666 DWORD dwMode, dwLen;
667
669 if (!result) return;
670
671 memcpy(abData, plain, sizeof(plain));
672
673 /* test default chaining mode */
674 dwMode = 0xdeadbeef;
675 dwLen = sizeof(dwMode);
676 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
677 ok(result, "%08lx\n", GetLastError());
678 ok(dwMode == CRYPT_MODE_CBC, "Wrong default chaining mode\n");
679
680 dwMode = CRYPT_MODE_ECB;
681 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
682 ok(result, "%08lx\n", GetLastError());
683
684 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
685 ok(result, "%08lx\n", GetLastError());
686 ok(dwLen == 11, "unexpected salt length %ld\n", dwLen);
687
688 dwLen = 23;
689 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
690 ok(result, "CryptEncrypt failed: %08lx\n", GetLastError());
691 ok(dwLen == 24, "Unexpected length %ld\n", dwLen);
692
694 dwLen = 23;
695 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
696 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
697 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
698
699 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
700 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
701 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
702
703 dwMode = CRYPT_MODE_CBC;
704 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
705 ok(result, "%08lx\n", GetLastError());
706
707 dwLen = 23;
708 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24);
709 ok(result, "CryptEncrypt failed: %08lx\n", GetLastError());
710 ok(dwLen == 24, "Unexpected length %ld\n", dwLen);
711
712 dwLen = 23;
713 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
714 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
715 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
716
717 result = CryptDecrypt(hKey, 0, TRUE, 0, abData, &dwLen);
718 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
719 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
720
721 dwMode = CRYPT_MODE_CFB;
722 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
723 ok(result, "%08lx\n", GetLastError());
724
725 dwLen = 16;
726 result = CryptEncrypt(hKey, 0, FALSE, 0, abData, &dwLen, 24);
727 ok(result && dwLen == 16, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
728
729 dwLen = 7;
730 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 8);
731 ok(result && dwLen == 8, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
732
733 dwLen = 7;
734 result = CryptEncrypt(hKey, 0, TRUE, 0, abData+16, &dwLen, 8);
735 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
736 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
737
738 dwLen = 8;
739 result = CryptDecrypt(hKey, 0, FALSE, 0, abData, &dwLen);
740 ok(result && dwLen == 8, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
741
742 dwLen = 16;
743 result = CryptDecrypt(hKey, 0, TRUE, 0, abData+8, &dwLen);
744 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
745 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
746
747 dwMode = CRYPT_MODE_OFB;
748 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
750 {
751 ok(broken(1), "OFB mode not supported\n"); /* Windows 8 */
752 }
753 else
754 {
755 ok(result, "%08lx\n", GetLastError());
756
757 dwLen = 23;
758 result = CryptEncrypt(hKey, 0, TRUE, 0, abData, &dwLen, 24);
759 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
760 }
761
763}
764
765static void test_3des112(void)
766{
768 BOOL result;
769 DWORD dwLen;
770 unsigned char pbData[16], enc_data[16], bad_data[16];
771 static const BYTE des112[16] = {
772 0x8e, 0x0c, 0x3c, 0xa3, 0x05, 0x88, 0x5f, 0x7a,
773 0x32, 0xa1, 0x06, 0x52, 0x64, 0xd2, 0x44, 0x1c };
774 int i;
775
777 ok(result, "%08lx\n", GetLastError());
778
779 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
780
781 dwLen = 13;
782 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
783 ok(result, "%08lx\n", GetLastError());
784
785 ok(!memcmp(pbData, des112, sizeof(des112)), "3DES_112 encryption failed!\n");
786
787 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
788 ok(result, "%08lx\n", GetLastError());
789
790 for (i=0; i<4; i++)
791 {
793
794 dwLen = cTestData[i].enclen;
795 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
796 ok(result, "%08lx\n", GetLastError());
797 ok(dwLen==cTestData[i].buflen,"length incorrect, got %ld, expected %d\n",dwLen,cTestData[i].buflen);
798 memcpy(enc_data, pbData, cTestData[i].buflen);
799
800 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
801 ok(result, "%08lx\n", GetLastError());
802 ok(dwLen==cTestData[i].enclen,"length incorrect, got %ld, expected %d\n",dwLen,cTestData[i].enclen);
803 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
804 if((dwLen != cTestData[i].enclen) ||
805 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
806 {
807 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
808 printBytes("got",pbData,dwLen);
809 }
810
811 /* Test bad data:
812 Decrypting a block of bad data with Final = TRUE should restore the
813 initial state of the key as well as decrypting a block of good data.
814 */
815
816 /* Changing key state by setting Final = FALSE */
817 dwLen = cTestData[i].buflen;
818 memcpy(pbData, enc_data, cTestData[i].buflen);
819 result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
820 ok(result, "%08lx\n", GetLastError());
821
822 /* Restoring key state by decrypting bad_data with Final = TRUE */
823 memcpy(bad_data, enc_data, cTestData[i].buflen);
824 bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
825 SetLastError(0xdeadbeef);
826 result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
827 ok(!result, "CryptDecrypt should failed!\n");
828 ok(GetLastError() == NTE_BAD_DATA, "%08lx\n", GetLastError());
829 ok(dwLen==cTestData[i].buflen,"length incorrect, got %ld, expected %d\n",dwLen,cTestData[i].buflen);
830 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
831
832 /* Checking key state */
833 dwLen = cTestData[i].buflen;
834 memcpy(pbData, enc_data, cTestData[i].buflen);
835 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
836 ok(result, "%08lx\n", GetLastError());
837 ok(dwLen==cTestData[i].enclen,"length incorrect, got %ld, expected %d\n",dwLen,cTestData[i].enclen);
838 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
839 if((dwLen != cTestData[i].enclen) ||
840 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
841 {
842 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
843 printBytes("got",pbData,dwLen);
844 }
845 }
847 ok(result, "%08lx\n", GetLastError());
848}
849
850static void test_des(void)
851{
853 BOOL result;
854 DWORD dwLen, dwMode;
855 unsigned char pbData[16], enc_data[16], bad_data[16];
856 static const BYTE des[16] = {
857 0x58, 0x86, 0x42, 0x46, 0x65, 0x4b, 0x92, 0x62,
858 0xcf, 0x0f, 0x65, 0x37, 0x43, 0x7a, 0x82, 0xb9 };
859 int i;
860
862 ok(result, "%08lx\n", GetLastError());
863
864 dwMode = CRYPT_MODE_ECB;
865 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
866 ok(result, "%08lx\n", GetLastError());
867
868 dwLen = sizeof(DWORD);
869 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
870 ok(result, "%08lx\n", GetLastError());
871 ok(dwMode == CRYPT_MODE_ECB, "Expected CRYPT_MODE_ECB, got %ld\n", dwMode);
872
873 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
874
875 dwLen = 13;
876 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
877 ok(result, "%08lx\n", GetLastError());
878
879 ok(!memcmp(pbData, des, sizeof(des)), "DES encryption failed!\n");
880
881 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
882 ok(result, "%08lx\n", GetLastError());
883
884 for (i=0; i<4; i++)
885 {
887
888 dwLen = cTestData[i].enclen;
889 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
890 ok(result, "%08lx\n", GetLastError());
891 ok(dwLen==cTestData[i].buflen,"length incorrect, got %ld, expected %d\n",dwLen,cTestData[i].buflen);
892 memcpy(enc_data, pbData, cTestData[i].buflen);
893
894 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
895 ok(result, "%08lx\n", GetLastError());
896 ok(dwLen==cTestData[i].enclen,"length incorrect, got %ld, expected %d\n",dwLen,cTestData[i].enclen);
897 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
898 if((dwLen != cTestData[i].enclen) ||
899 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
900 {
901 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
902 printBytes("got",pbData,dwLen);
903 }
904
905 /* Test bad data:
906 Decrypting a block of bad data with Final = TRUE should restore the
907 initial state of the key as well as decrypting a block of good data.
908 */
909
910 /* Changing key state by setting Final = FALSE */
911 dwLen = cTestData[i].buflen;
912 memcpy(pbData, enc_data, cTestData[i].buflen);
913 result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
914 ok(result, "%08lx\n", GetLastError());
915
916 /* Restoring key state by decrypting bad_data with Final = TRUE */
917 memcpy(bad_data, enc_data, cTestData[i].buflen);
918 bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
919 SetLastError(0xdeadbeef);
920 result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
921 ok(!result, "CryptDecrypt should failed!\n");
922 ok(GetLastError() == NTE_BAD_DATA, "%08lx\n", GetLastError());
923 ok(dwLen==cTestData[i].buflen,"length incorrect, got %ld, expected %d\n",dwLen,cTestData[i].buflen);
924 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
925
926 /* Checking key state */
927 dwLen = cTestData[i].buflen;
928 memcpy(pbData, enc_data, cTestData[i].buflen);
929 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
930 ok(result, "%08lx\n", GetLastError());
931 ok(dwLen==cTestData[i].enclen,"length incorrect, got %ld, expected %d\n",dwLen,cTestData[i].enclen);
932 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
933 if((dwLen != cTestData[i].enclen) ||
934 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
935 {
936 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
937 printBytes("got",pbData,dwLen);
938 }
939 }
940
942 ok(result, "%08lx\n", GetLastError());
943
944 /* Windows >= XP changed the way DES keys are derived, this test ensures we don't break that */
945 derive_key(CALG_DES, &hKey, 56);
946
947 dwMode = CRYPT_MODE_ECB;
948 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
949 ok(result, "%08lx\n", GetLastError());
950
951 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
952
953 dwLen = 13;
954 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
955 ok(result, "%08lx\n", GetLastError());
956 ok(!memcmp(pbData, des, sizeof(des)), "DES encryption failed!\n");
957
959 ok(result, "%08lx\n", GetLastError());
960}
961
962static void test_3des(void)
963{
965 BOOL result;
966 DWORD dwLen;
967 unsigned char pbData[16], enc_data[16], bad_data[16];
968 static const BYTE des3[16] = {
969 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
970 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
971 int i;
972
974 if (!result) return;
975
976 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
977
978 dwLen = 13;
979 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
980 ok(result, "%08lx\n", GetLastError());
981
982 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
983
984 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
985 ok(result, "%08lx\n", GetLastError());
986
987 for (i=0; i<4; i++)
988 {
990
991 dwLen = cTestData[i].enclen;
992 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
993 ok(result, "%08lx\n", GetLastError());
994 ok(dwLen==cTestData[i].buflen,"length incorrect, got %ld, expected %d\n",dwLen,cTestData[i].buflen);
995 memcpy(enc_data, pbData, cTestData[i].buflen);
996
997 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
998 ok(result, "%08lx\n", GetLastError());
999 ok(dwLen==cTestData[i].enclen,"length incorrect, got %ld, expected %d\n",dwLen,cTestData[i].enclen);
1000 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
1001 if((dwLen != cTestData[i].enclen) ||
1002 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1003 {
1004 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1005 printBytes("got",pbData,dwLen);
1006 }
1007
1008 /* Test bad data:
1009 Decrypting a block of bad data with Final = TRUE should restore the
1010 initial state of the key as well as decrypting a block of good data.
1011 */
1012
1013 /* Changing key state by setting Final = FALSE */
1014 dwLen = cTestData[i].buflen;
1015 memcpy(pbData, enc_data, cTestData[i].buflen);
1016 result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
1017 ok(result, "%08lx\n", GetLastError());
1018
1019 /* Restoring key state by decrypting bad_data with Final = TRUE */
1020 memcpy(bad_data, enc_data, cTestData[i].buflen);
1021 bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
1022 SetLastError(0xdeadbeef);
1023 result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
1024 ok(!result, "CryptDecrypt should failed!\n");
1025 ok(GetLastError() == NTE_BAD_DATA, "%08lx\n", GetLastError());
1026 ok(dwLen==cTestData[i].buflen,"length incorrect, got %ld, expected %d\n",dwLen,cTestData[i].buflen);
1027 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1028
1029 /* Checking key state */
1030 dwLen = cTestData[i].buflen;
1031 memcpy(pbData, enc_data, cTestData[i].buflen);
1032 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1033 ok(result, "%08lx\n", GetLastError());
1034 ok(dwLen==cTestData[i].enclen,"length incorrect, got %ld, expected %d\n",dwLen,cTestData[i].enclen);
1035 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1036 if((dwLen != cTestData[i].enclen) ||
1037 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1038 {
1039 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1040 printBytes("got",pbData,dwLen);
1041 }
1042 }
1044 ok(result, "%08lx\n", GetLastError());
1045}
1046
1047static void test_aes_duplicate_key(int keylen)
1048{
1049 static const BYTE aes_plain[32] = { "AES Test With 2 Blocks Of Data." };
1050 HCRYPTKEY hKey, hDup;
1051 BYTE orig[48], dup[48];
1052 DWORD len_orig, len_dup;
1053 ALG_ID algid;
1054 BOOL result;
1055
1056 switch (keylen)
1057 {
1058 case 256: algid = CALG_AES_256; break;
1059 case 192: algid = CALG_AES_192; break;
1060 default: algid = CALG_AES_128; break;
1061 }
1062
1063 if (!derive_key(algid, &hKey, 0)) return;
1064
1065 result = CryptDuplicateKey(hKey, NULL, 0, &hDup);
1066 ok(result, "CryptDuplicateKey failed, got last error %ld\n", GetLastError());
1067 if (!result)
1068 {
1070 return;
1071 }
1072
1073 len_orig = sizeof(aes_plain);
1074 memcpy(orig, aes_plain, len_orig);
1075 result = CryptEncrypt(hKey, 0, TRUE, 0, orig, &len_orig, sizeof(orig));
1076 ok(result, "CryptEncrypt failed, got last error %ld\n", GetLastError());
1077
1078 len_dup = sizeof(aes_plain);
1079 memcpy(dup, aes_plain, len_dup);
1080 result = CryptEncrypt(hDup, 0, TRUE, 0, dup, &len_dup, sizeof(dup));
1081 ok(result, "CryptEncrypt on duplicated key failed, got last error %ld\n", GetLastError());
1082
1083 ok(len_orig == len_dup && !memcmp(orig, dup, len_orig),
1084 "AES-%d: duplicated key produced different ciphertext\n", keylen);
1085
1086 CryptDestroyKey(hDup);
1088}
1089
1090static void test_aes(int keylen)
1091{
1093 BOOL result;
1094 DWORD dwLen, dwMode;
1095 unsigned char pbData[48], enc_data[16], bad_data[16];
1096 int i;
1097 static const BYTE aes_plain[32] = {
1098 "AES Test With 2 Blocks Of Data." };
1099 static const BYTE aes_cbc_enc[3][48] = {
1100 /* 128 bit key encrypted text */
1101 { 0xfe, 0x85, 0x3b, 0xe1, 0xf5, 0xe1, 0x58, 0x75, 0xd5, 0xa9, 0x74, 0xe3, 0x09, 0xea, 0xa5, 0x04,
1102 0x23, 0x35, 0xa2, 0x3b, 0x5c, 0xf1, 0x6c, 0x6f, 0xb9, 0xcd, 0x64, 0x06, 0x3e, 0x41, 0x83, 0xef,
1103 0x2a, 0xfe, 0xea, 0xb5, 0x6c, 0x17, 0x20, 0x79, 0x8c, 0x51, 0x3e, 0x56, 0xed, 0xe1, 0x47, 0x68 },
1104 /* 192 bit key encrypted text */
1105 { 0x6b, 0xf0, 0xfd, 0x32, 0xee, 0xc6, 0x06, 0x13, 0xa8, 0xe6, 0x3c, 0x81, 0x85, 0xb8, 0x2e, 0xa1,
1106 0xd4, 0x3b, 0xe8, 0x22, 0xa5, 0x74, 0x4a, 0xbe, 0x9d, 0xcf, 0xcc, 0x37, 0x26, 0x19, 0x5a, 0xd1,
1107 0x7f, 0x76, 0xbf, 0x94, 0x28, 0xce, 0x27, 0x21, 0x61, 0x87, 0xeb, 0xb9, 0x8b, 0xa8, 0xb4, 0x57 },
1108 /* 256 bit key encrypted text */
1109 { 0x20, 0x57, 0x17, 0x0b, 0x17, 0x76, 0xd8, 0x3b, 0x26, 0x90, 0x8b, 0x4c, 0xf2, 0x00, 0x79, 0x33,
1110 0x29, 0x2b, 0x13, 0x9c, 0xe2, 0x95, 0x09, 0xc1, 0xcd, 0x20, 0x87, 0x22, 0x32, 0x70, 0x9d, 0x75,
1111 0x9a, 0x94, 0xf5, 0x76, 0x5c, 0xb1, 0x62, 0x2c, 0xe1, 0x76, 0x7c, 0x86, 0x73, 0xe6, 0x7a, 0x23 }
1112 };
1113 switch (keylen)
1114 {
1115 case 256:
1117 i = 2;
1118 break;
1119 case 192:
1121 i = 1;
1122 break;
1123 default:
1124 case 128:
1126 i = 0;
1127 break;
1128 }
1129 if (!result) return;
1130
1131 dwLen = sizeof(aes_plain);
1132 memcpy(pbData, aes_plain, dwLen);
1133 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, sizeof(pbData));
1134 ok(result, "Expected OK, got last error %ld\n", GetLastError());
1135 ok(dwLen == 48, "Expected dwLen 48, got %ld\n", dwLen);
1136 ok(!memcmp(aes_cbc_enc[i], pbData, dwLen), "Expected equal data sequences\n");
1137
1138 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1139 ok(result && dwLen == 32 && !memcmp(aes_plain, pbData, dwLen),
1140 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
1141
1142 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
1143
1144 /* Does AES provider support salt? */
1145 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1146 todo_wine ok(result, "Expected OK, got last error %ld\n", GetLastError());
1147 if (result)
1148 ok(!dwLen, "unexpected salt length %ld\n", dwLen);
1149
1150 /* test default chaining mode */
1151 dwMode = 0xdeadbeef;
1152 dwLen = sizeof(dwMode);
1153 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1154 ok(result, "%08lx\n", GetLastError());
1155 ok(dwMode == CRYPT_MODE_CBC, "Wrong default chaining\n");
1156
1157 dwLen = 13;
1158 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, 16);
1159 ok(result, "%08lx\n", GetLastError());
1160
1161 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1162 ok(result, "%08lx\n", GetLastError());
1163
1164 for (i=0; i<4; i++)
1165 {
1167
1168 dwLen = cTestData[i].enclen;
1169 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
1170 ok(result, "%08lx\n", GetLastError());
1171 ok(dwLen==cTestData[i].buflen,"length incorrect, got %ld, expected %d\n",dwLen,cTestData[i].buflen);
1172 memcpy(enc_data, pbData, cTestData[i].buflen);
1173
1174 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1175 ok(result, "%08lx\n", GetLastError());
1176 ok(dwLen==cTestData[i].enclen,"length incorrect, got %ld, expected %d\n",dwLen,cTestData[i].enclen);
1177 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1178 if((dwLen != cTestData[i].enclen) ||
1179 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1180 {
1181 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1182 printBytes("got",pbData,dwLen);
1183 }
1184
1185 /* Test bad data:
1186 Decrypting a block of bad data with Final = TRUE should restore the
1187 initial state of the key as well as decrypting a block of good data.
1188 */
1189
1190 /* Changing key state by setting Final = FALSE */
1191 dwLen = cTestData[i].buflen;
1192 memcpy(pbData, enc_data, cTestData[i].buflen);
1193 result = CryptDecrypt(hKey, 0, FALSE, 0, pbData, &dwLen);
1194 ok(result, "%08lx\n", GetLastError());
1195
1196 /* Restoring key state by decrypting bad_data with Final = TRUE */
1197 memcpy(bad_data, enc_data, cTestData[i].buflen);
1198 bad_data[cTestData[i].buflen - 1] = ~bad_data[cTestData[i].buflen - 1];
1199 SetLastError(0xdeadbeef);
1200 result = CryptDecrypt(hKey, 0, TRUE, 0, bad_data, &dwLen);
1201 ok(!result, "CryptDecrypt should failed!\n");
1202 ok(GetLastError() == NTE_BAD_DATA, "%08lx\n", GetLastError());
1203 ok(dwLen==cTestData[i].buflen,"length incorrect, got %ld, expected %d\n",dwLen,cTestData[i].buflen);
1204 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1205
1206 /* Checking key state */
1207 dwLen = cTestData[i].buflen;
1208 memcpy(pbData, enc_data, cTestData[i].buflen);
1209 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
1210 ok(result, "%08lx\n", GetLastError());
1211 ok(dwLen==cTestData[i].enclen,"length incorrect, got %ld, expected %d\n",dwLen,cTestData[i].enclen);
1212 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
1213 if((dwLen != cTestData[i].enclen) ||
1214 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
1215 {
1216 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
1217 printBytes("got",pbData,dwLen);
1218 }
1219 }
1221 ok(result, "%08lx\n", GetLastError());
1222}
1223
1224static void test_sha2(void)
1225{
1226 static const unsigned char sha256hash[32] = {
1227 0x10, 0xfc, 0x3c, 0x51, 0xa1, 0x52, 0xe9, 0x0e, 0x5b, 0x90,
1228 0x31, 0x9b, 0x60, 0x1d, 0x92, 0xcc, 0xf3, 0x72, 0x90, 0xef,
1229 0x53, 0xc3, 0x5f, 0xf9, 0x25, 0x07, 0x68, 0x7d, 0x8a, 0x91,
1230 0x1a, 0x08
1231 };
1232 static const unsigned char sha384hash[48] = {
1233 0x98, 0xd3, 0x3f, 0x89, 0x0b, 0x23, 0x33, 0x44, 0x61, 0x32,
1234 0x5a, 0x7c, 0xa3, 0x03, 0x89, 0xb5, 0x11, 0xd7, 0x41, 0xc8,
1235 0x54, 0x6b, 0x12, 0x0c, 0x40, 0x15, 0xb6, 0x2a, 0x03, 0x43,
1236 0xe5, 0x64, 0x7f, 0x10, 0x1e, 0xae, 0x47, 0xa9, 0x39, 0x05,
1237 0x6f, 0x40, 0x60, 0x94, 0xd6, 0xad, 0x80, 0x55
1238 };
1239 static const unsigned char sha512hash[64] = {
1240 0x37, 0x86, 0x0e, 0x7d, 0x25, 0xd9, 0xf9, 0x84, 0x3e, 0x3d,
1241 0xc7, 0x13, 0x95, 0x73, 0x42, 0x04, 0xfd, 0x13, 0xad, 0x23,
1242 0x39, 0x16, 0x32, 0x5f, 0x99, 0x3e, 0x3c, 0xee, 0x3f, 0x11,
1243 0x36, 0xf9, 0xc9, 0x66, 0x08, 0x70, 0xcc, 0x49, 0xd8, 0xe0,
1244 0x7d, 0xa1, 0x57, 0x62, 0x71, 0xa6, 0xc9, 0xa4, 0x24, 0x60,
1245 0xfc, 0xde, 0x9d, 0xb2, 0xf1, 0xd2, 0xc2, 0xfb, 0x2d, 0xbf,
1246 0xb7, 0xf4, 0x81, 0xd4
1247 };
1248 unsigned char pbData[2048];
1249 BOOL result;
1250 HCRYPTHASH hHash;
1251 BYTE pbHashValue[64];
1252 DWORD hashlen, len;
1253 int i;
1254
1255 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
1256
1257 /* SHA-256 hash */
1258 SetLastError(0xdeadbeef);
1259 result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
1260 if (!result && GetLastError() == NTE_BAD_ALGID) {
1261 win_skip("SHA-256/384/512 hashes are not supported before Windows XP SP3\n");
1262 return;
1263 }
1264 ok(result, "%08lx\n", GetLastError());
1265 if (result) {
1266 len = sizeof(DWORD);
1267 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1268 ok(result && (hashlen == 32), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
1269
1270 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1271 ok(result, "%08lx\n", GetLastError());
1272
1273 len = 32;
1274 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1275 ok(result, "%08lx\n", GetLastError());
1276
1277 ok(!memcmp(pbHashValue, sha256hash, 32), "Wrong SHA-256 hash!\n");
1278
1279 result = CryptDestroyHash(hHash);
1280 ok(result, "%08lx\n", GetLastError());
1281 }
1282
1283 /* SHA-384 hash */
1284 result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash);
1285 ok(result, "%08lx\n", GetLastError());
1286 if (result) {
1287 len = sizeof(DWORD);
1288 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1289 ok(result && (hashlen == 48), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
1290
1291 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1292 ok(result, "%08lx\n", GetLastError());
1293
1294 len = 48;
1295 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1296 ok(result, "%08lx\n", GetLastError());
1297
1298 ok(!memcmp(pbHashValue, sha384hash, 48), "Wrong SHA-384 hash!\n");
1299
1300 result = CryptDestroyHash(hHash);
1301 ok(result, "%08lx\n", GetLastError());
1302 }
1303
1304 /* SHA-512 hash */
1305 result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash);
1306 ok(result, "%08lx\n", GetLastError());
1307 if (result) {
1308 len = sizeof(DWORD);
1309 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
1310 ok(result && (hashlen == 64), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
1311
1312 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1313 ok(result, "%08lx\n", GetLastError());
1314
1315 len = 64;
1316 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
1317 ok(result, "%08lx\n", GetLastError());
1318
1319 ok(!memcmp(pbHashValue, sha512hash, 64), "Wrong SHA-512 hash!\n");
1320
1321 result = CryptDestroyHash(hHash);
1322 ok(result, "%08lx\n", GetLastError());
1323 }
1324}
1325
1326static void test_rc2(void)
1327{
1328 static const BYTE rc2_40_encrypted[16] = {
1329 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11,
1330 0xfb, 0x18, 0x87, 0xce, 0x0c, 0x75, 0x07, 0xb1 };
1331 static const BYTE rc2_128_encrypted[] = {
1332 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,
1333 0x2a,0x2a,0xc0,0xce,0x4c,0x89,0xb6,0x66 };
1334 static const BYTE rc2_40def_encrypted[] = {
1335 0x23,0xc8,0x70,0x13,0x42,0x2e,0xa8,0x98,
1336 0x5c,0xdf,0x7a,0x9b,0xea,0xdb,0x96,0x1b };
1337 static const BYTE rc2_40_salt_enh[24] = {
1338 0xA3, 0xD7, 0x41, 0x87, 0x7A, 0xD0, 0x18, 0xDB,
1339 0xD4, 0x6A, 0x4F, 0xEE, 0xF3, 0xCA, 0xCD, 0x34,
1340 0xB3, 0x15, 0x9A, 0x2A, 0x88, 0x5F, 0x43, 0xA5 };
1341 static const BYTE rc2_40_salt_base[24] = {
1342 0x8C, 0x4E, 0xA6, 0x00, 0x9B, 0x15, 0xEF, 0x9E,
1343 0x88, 0x81, 0xD0, 0x65, 0xD6, 0x53, 0x57, 0x08,
1344 0x0A, 0x77, 0x80, 0xFA, 0x7E, 0x89, 0x14, 0x55 };
1345 static const BYTE rc2_40_salt_strong[24] = {
1346 0xB9, 0x33, 0xB6, 0x7A, 0x35, 0xC3, 0x06, 0x88,
1347 0xBF, 0xD5, 0xCC, 0xAF, 0x14, 0xAE, 0xE2, 0x31,
1348 0xC6, 0x9A, 0xAA, 0x3F, 0x05, 0x2F, 0x22, 0xDA };
1349 HCRYPTHASH hHash;
1351 BOOL result;
1352 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
1353 unsigned char pbData[2000], pbHashValue[16], pszBuffer[256];
1354 int i;
1355
1356 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1357
1358 /* MD2 Hashing */
1359 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1360 if (!result) {
1361 ok(GetLastError()==NTE_BAD_ALGID, "%08lx\n", GetLastError());
1362 } else {
1364
1365 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1366 ok(result, "%08lx\n", GetLastError());
1367
1368 dwLen = 16;
1369 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1370 ok(result, "%08lx\n", GetLastError());
1371
1372 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &hKey);
1373 ok(result, "%08lx\n", GetLastError());
1374
1375 dwLen = sizeof(DWORD);
1376 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1377 ok(result, "%08lx\n", GetLastError());
1378
1379 /* test default chaining mode */
1380 dwMode = 0xdeadbeef;
1381 dwLen = sizeof(dwMode);
1382 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1383 ok(result, "%08lx\n", GetLastError());
1384 ok(dwMode == CRYPT_MODE_CBC, "Wrong default chaining mode\n");
1385
1386 dwMode = CRYPT_MODE_CBC;
1387 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
1388 ok(result, "%08lx\n", GetLastError());
1389
1390 dwLen = sizeof(DWORD);
1391 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
1392 ok(result, "%08lx\n", GetLastError());
1393
1394 dwModeBits = 0xdeadbeef;
1395 dwLen = sizeof(DWORD);
1396 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1397 ok(result, "%08lx\n", GetLastError());
1399 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT got %08lx\n", dwModeBits);
1400
1401 dwLen = sizeof(DWORD);
1402 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
1403 ok(result, "%08lx\n", GetLastError());
1404
1405 dwLen = sizeof(DWORD);
1406 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
1407 ok(result, "%08lx\n", GetLastError());
1408 ok(dwLen == 4, "Expected 4, got %ld\n", dwLen);
1409
1410 dwLen = 0;
1411 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1412 ok(result, "%08lx\n", GetLastError());
1413 result = CryptGetKeyParam(hKey, KP_IV, pszBuffer, &dwLen, 0);
1414 ok(result, "%08lx\n", GetLastError());
1415 ok(dwLen == 8, "Expected 8, got %ld\n", dwLen);
1416
1417 dwLen = 0;
1418 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1419 ok(result, "%08lx\n", GetLastError());
1420 /* The default salt length is always 11... */
1421 ok(dwLen == 11, "unexpected salt length %ld\n", dwLen);
1422 /* and the default salt is always empty. */
1423 result = CryptGetKeyParam(hKey, KP_SALT, pszBuffer, &dwLen, 0);
1424 ok(result, "%08lx\n", GetLastError());
1425 for (i=0; i<dwLen; i++)
1426 ok(!pszBuffer[i], "unexpected salt value %02x @ %d\n", pszBuffer[i], i);
1427
1428 dwLen = sizeof(DWORD);
1429 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1430 ok(result, "%08lx\n", GetLastError());
1431 ok(dwMode == CRYPT_MODE_CBC, "Expected CRYPT_MODE_CBC, got %ld\n", dwMode);
1432
1433 result = CryptDestroyHash(hHash);
1434 ok(result, "%08lx\n", GetLastError());
1435
1436 dwDataLen = 13;
1437 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1438 ok(result, "%08lx\n", GetLastError());
1439
1440 ok(!memcmp(pbData, rc2_40_encrypted, 16), "RC2 encryption failed!\n");
1441
1442 dwLen = 0;
1443 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1444 ok(result, "%08lx\n", GetLastError());
1445 result = CryptGetKeyParam(hKey, KP_IV, pszBuffer, &dwLen, 0);
1446 ok(result, "%08lx\n", GetLastError());
1447
1448 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1449 ok(result, "%08lx\n", GetLastError());
1450
1451 /* Setting the salt value will not reset the salt length in base or strong providers */
1453 ok(result, "setting salt failed: %08lx\n", GetLastError());
1454 dwLen = 0;
1455 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1456 ok(result, "%08lx\n", GetLastError());
1457 if (BASE_PROV || STRONG_PROV)
1458 ok(dwLen == 11, "expected salt length 11, got %ld\n", dwLen);
1459 else
1460 ok(dwLen == 0, "expected salt length 0, got %ld\n", dwLen);
1461 /* What sizes salt can I set? */
1462 salt.pbData = pbData;
1463 for (i=0; i<24; i++)
1464 {
1465 salt.cbData = i;
1467 ok(result, "setting salt failed for size %d: %08lx\n", i, GetLastError());
1468 /* The returned salt length is the same as the set salt length */
1469 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1470 ok(result, "%08lx\n", GetLastError());
1471 ok(dwLen == i, "size %d: unexpected salt length %ld\n", i, dwLen);
1472 }
1473 salt.cbData = 25;
1474 SetLastError(0xdeadbeef);
1476 ok(!result, "%08lx\n", GetLastError());
1477
1479 ok(result, "%08lx\n", GetLastError());
1480 }
1481
1482 /* Again, but test setting the effective key len */
1483 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1484
1485 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1486 if (!result) {
1487 ok(GetLastError()==NTE_BAD_ALGID, "%08lx\n", GetLastError());
1488 } else {
1489 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1490 ok(result, "%08lx\n", GetLastError());
1491
1492 dwLen = 16;
1493 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
1494 ok(result, "%08lx\n", GetLastError());
1495
1496 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
1497 ok(result, "%08lx\n", GetLastError());
1498
1499 SetLastError(0xdeadbeef);
1502 dwKeyLen = 0;
1503 SetLastError(0xdeadbeef);
1505 ok(!result && GetLastError()==NTE_BAD_DATA, "%08lx\n", GetLastError());
1506 dwKeyLen = 1025;
1507 SetLastError(0xdeadbeef);
1509 ok(!result, "CryptSetKeyParam failed: %08lx\n", GetLastError());
1510
1511 dwLen = sizeof(dwKeyLen);
1512 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1513 ok(result, "%08lx\n", GetLastError());
1514 ok(dwKeyLen == 56, "%ld (%08lx)\n", dwKeyLen, GetLastError());
1515 result = CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1516 ok(result, "%08lx\n", GetLastError());
1517 ok(dwKeyLen == 56 || broken(dwKeyLen == 40), "%ld (%08lx)\n", dwKeyLen, GetLastError());
1518
1519 dwKeyLen = 128;
1520 SetLastError(0xdeadbeef);
1522 if (!BASE_PROV)
1523 {
1524 dwKeyLen = 12345;
1525 ok(result, "expected success, got error 0x%08lX\n", GetLastError());
1526 result = CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1527 ok(result, "%08lx\n", GetLastError());
1528 ok(dwKeyLen == 128, "Expected 128, got %ld\n", dwKeyLen);
1529 }
1530 else
1531 {
1532 ok(!result, "expected error\n");
1533 ok(GetLastError() == NTE_BAD_DATA, "Expected 0x80009005, got 0x%08lX\n", GetLastError());
1534 result = CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1535 ok(result, "%08lx\n", GetLastError());
1536 ok(dwKeyLen == 40, "Expected 40, got %ld\n", dwKeyLen);
1537 }
1538
1539 dwLen = sizeof(dwKeyLen);
1540 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1541 ok(result, "%08lx\n", GetLastError());
1542 ok(dwKeyLen == 56, "%ld (%08lx)\n", dwKeyLen, GetLastError());
1543 result = CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
1544 ok(result, "%08lx\n", GetLastError());
1545 ok((!BASE_PROV && dwKeyLen == 128) || (BASE_PROV && dwKeyLen == 40),
1546 "%ld (%08lx)\n", dwKeyLen, GetLastError());
1547
1548 result = CryptDestroyHash(hHash);
1549 ok(result, "%08lx\n", GetLastError());
1550
1551 dwDataLen = 13;
1552 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1553 ok(result, "%08lx\n", GetLastError());
1554 ok(!memcmp(pbData, !BASE_PROV ? rc2_128_encrypted : rc2_40def_encrypted,
1555 sizeof(rc2_128_encrypted)), "RC2 encryption failed!\n");
1556
1557 /* Oddly enough this succeeds, though it should have no effect */
1558 dwKeyLen = 40;
1560 ok(result, "%ld\n", GetLastError());
1561
1563 ok(result, "%08lx\n", GetLastError());
1564
1565 /* Test a 40 bit key with salt */
1566 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1567 ok(result, "%08lx\n", GetLastError());
1568
1569 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1570 ok(result, "%08lx\n", GetLastError());
1571
1573 ok(result, "%08lx\n", GetLastError());
1574
1575 dwDataLen = 16;
1576 memset(pbData, 0xAF, dwDataLen);
1577 SetLastError(0xdeadbeef);
1578 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1579 ok((ENHANCED_PROV && !memcmp(pbData, rc2_40_salt_enh, dwDataLen)) ||
1580 (STRONG_PROV && !memcmp(pbData, rc2_40_salt_strong, dwDataLen)) ||
1581 (BASE_PROV && !memcmp(pbData, rc2_40_salt_base, dwDataLen)),
1582 "RC2 encryption failed!\n");
1583 dwLen = sizeof(DWORD);
1584 dwKeyLen = 12345;
1585 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1586 ok(result, "%08lx\n", GetLastError());
1587 ok(dwKeyLen == 40, "Expected 40, got %ld\n", dwKeyLen);
1588
1589 dwLen = sizeof(pszBuffer);
1590 memset(pszBuffer, 0xAF, dwLen);
1591 result = CryptGetKeyParam(hKey, KP_SALT, pszBuffer, &dwLen, 0);
1592 ok(result, "%08lx\n", GetLastError());
1593 if (!ENHANCED_PROV)
1594 ok(dwLen == 11, "Expected 11, got %ld\n", dwLen);
1595 else
1596 ok(dwLen == 0, "Expected 0, got %ld\n", dwLen);
1597
1599 ok(result, "%08lx\n", GetLastError());
1600
1601 result = CryptDestroyHash(hHash);
1602 ok(result, "%08lx\n", GetLastError());
1603 }
1604}
1605
1606static void test_rc4(void)
1607{
1608 static const BYTE rc4[16] = {
1609 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
1610 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
1611 static const BYTE rc4_40_salt[16] = {
1612 0x41, 0xE6, 0x33, 0xC9, 0x50, 0xA1, 0xBF, 0x88,
1613 0x12, 0x4D, 0xD3, 0xE3, 0x47, 0x88, 0x6D, 0xA5 };
1614 static const BYTE rc4_40_salt_base[16] = {
1615 0x2F, 0xAC, 0xEA, 0xEA, 0xFF, 0x68, 0x7E, 0x77,
1616 0xF4, 0xB9, 0x48, 0x7C, 0x4E, 0x79, 0xA6, 0xB5 };
1617 BOOL result;
1618 HCRYPTHASH hHash;
1620 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
1622 unsigned char pbData[2000];
1623 unsigned char pszBuffer[256];
1624 int i;
1625
1626 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
1627
1628 /* MD2 Hashing */
1629 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1630 ok(result, "%08lx\n", GetLastError());
1631
1632 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1633 ok(result, "%08lx\n", GetLastError());
1634
1635 dwLen = 16;
1636 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
1637 ok(result, "%08lx\n", GetLastError());
1638
1639 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
1640 ok(result, "%08lx\n", GetLastError());
1641
1642 dwLen = sizeof(DWORD);
1643 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1644 ok(result, "%08lx\n", GetLastError());
1645 ok(dwKeyLen == 56, "Expected 56, got %ld\n", dwKeyLen);
1646
1647 dwLen = sizeof(DWORD);
1648 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1649 ok(result, "%08lx\n", GetLastError());
1650 ok(dwKeyLen == 0, "Expected 0, got %ld\n", dwKeyLen);
1651
1652 dwLen = 0;
1653 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
1654 ok(result, "%08lx\n", GetLastError());
1655 result = CryptGetKeyParam(hKey, KP_IV, pszBuffer, &dwLen, 0);
1656
1657 dwLen = 0;
1658 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1659 ok(result, "%08lx\n", GetLastError());
1660 result = CryptGetKeyParam(hKey, KP_SALT, pszBuffer, &dwLen, 0);
1661 ok(result, "%08lx\n", GetLastError());
1662
1663 dwLen = sizeof(DWORD);
1664 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
1665 ok(result, "%08lx\n", GetLastError());
1666 ok(dwMode == 0, "Expected 0, got %ld\n", dwMode);
1667
1668 result = CryptDestroyHash(hHash);
1669 ok(result, "%08lx\n", GetLastError());
1670
1671 dwDataLen = 16;
1672 result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwDataLen, 24);
1673 ok(result, "%08lx\n", GetLastError());
1674 dwDataLen = 16;
1675 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1676 ok(result, "%08lx\n", GetLastError());
1677 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
1678
1679 result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen);
1680 ok(result, "%08lx\n", GetLastError());
1681
1682 /* Setting the salt value will not reset the salt length in base or strong providers */
1684 ok(result, "setting salt failed: %08lx\n", GetLastError());
1685 dwLen = 0;
1686 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1687 ok(result, "%08lx\n", GetLastError());
1688 if (BASE_PROV || STRONG_PROV)
1689 ok(dwLen == 11, "expected salt length 11, got %ld\n", dwLen);
1690 else
1691 ok(dwLen == 0, "expected salt length 0, got %ld\n", dwLen);
1692 /* What sizes salt can I set? */
1693 salt.pbData = pbData;
1694 for (i = 0; i < 24; i++)
1695 {
1696 salt.cbData = i;
1698 ok(result, "setting salt failed for size %d: %08lx\n", i, GetLastError());
1699 /* The returned salt length is the same as the set salt length */
1700 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
1701 ok(result, "%08lx\n", GetLastError());
1702 ok(dwLen == i, "size %d: unexpected salt length %ld\n", i, dwLen);
1703 }
1704 salt.cbData = 25;
1705 SetLastError(0xdeadbeef);
1707 ok(!result, "%08lx\n", GetLastError());
1708
1710 ok(result, "%08lx\n", GetLastError());
1711
1712 /* Test a 40 bit key with salt */
1713 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1714 ok(result, "%08lx\n", GetLastError());
1715
1716 result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
1717 ok(result, "%08lx\n", GetLastError());
1718
1720 ok(result, "%08lx\n", GetLastError());
1721 dwDataLen = 16;
1722 memset(pbData, 0xAF, dwDataLen);
1723 SetLastError(0xdeadbeef);
1724 result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwDataLen, 24);
1725 ok(result, "%08lx\n", GetLastError());
1726 ok((ENHANCED_PROV && !memcmp(pbData, rc4_40_salt, dwDataLen)) ||
1727 (!ENHANCED_PROV && !memcmp(pbData, rc4_40_salt_base, dwDataLen)),
1728 "RC4 encryption failed!\n");
1729
1730 dwLen = sizeof(DWORD);
1731 dwKeyLen = 12345;
1732 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
1733 ok(result, "%08lx\n", GetLastError());
1734 ok(dwKeyLen == 40, "Expected 40, got %ld\n", dwKeyLen);
1735
1736 dwLen = sizeof(pszBuffer);
1737 memset(pszBuffer, 0xAF, dwLen);
1738 result = CryptGetKeyParam(hKey, KP_SALT, pszBuffer, &dwLen, 0);
1739 ok(result, "%08lx\n", GetLastError());
1740 if (!ENHANCED_PROV)
1741 ok(dwLen == 11, "Expected 11, got %ld\n", dwLen);
1742 else
1743 ok(dwLen == 0, "Expected 0, got %ld\n", dwLen);
1744
1746 ok(result, "%08lx\n", GetLastError());
1747
1748 result = CryptDestroyHash(hHash);
1749 ok(result, "%08lx\n", GetLastError());
1750}
1751
1752static void test_hmac(void) {
1754 HCRYPTHASH hHash;
1755 BOOL result;
1756 /* Using CALG_MD2 here fails on Windows 2003, why ? */
1757 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1758 DWORD dwLen;
1759 BYTE abData[256];
1760 static const BYTE hmac[16] = {
1761 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
1762 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
1763 int i;
1764
1765 for (i=0; i < ARRAY_SIZE(abData); i++) abData[i] = (BYTE)i;
1766
1767 if (!derive_key(CALG_RC2, &hKey, 56)) return;
1768
1769 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
1770 ok(result, "%08lx\n", GetLastError());
1771
1772 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
1773 ok(result, "%08lx\n", GetLastError());
1774
1775 result = CryptHashData(hHash, abData, sizeof(abData), 0);
1776 ok(result, "%08lx\n", GetLastError());
1777
1778 dwLen = 0;
1779 result = CryptGetHashParam(hHash, HP_HASHVAL, NULL, &dwLen, 0);
1780 ok(result, "%08lx\n", GetLastError());
1781 ok(dwLen != 0, "Wrong value\n");
1782
1783 dwLen = ARRAY_SIZE(abData);
1784 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1785 ok(result, "%08lx\n", GetLastError());
1786
1787 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
1788
1789 result = CryptDestroyHash(hHash);
1790 ok(result, "%08lx\n", GetLastError());
1791
1793 ok(result, "%08lx\n", GetLastError());
1794
1795 /* Provoke errors */
1796 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
1797 ok(!result && GetLastError() == NTE_BAD_KEY, "%08lx\n", GetLastError());
1798}
1799
1800static void test_hmac_info(void)
1801{
1802 /* test cases 2 and 6 from RFC 4231, the MD2 digest is measured on Windows */
1803 static const struct hmac_test_case {
1804 ALG_ID algid;
1805 DWORD digest_len;
1806 const char *key;
1807 DWORD key_len;
1808 const char *data;
1809 const DWORD data_len;
1810 const char *digest;
1811 } cases[] = {
1812 { CALG_SHA_256, 32,
1813 "Jefe", 4,
1814 "what do ya want for nothing?", 28,
1815 "\x5b\xdc\xc1\x46\xbf\x60\x75\x4e\x6a\x04\x24\x26\x08\x95\x75\xc7"
1816 "\x5a\x00\x3f\x08\x9d\x27\x39\x83\x9d\xec\x58\xb9\x64\xec\x38\x43" },
1817
1818 { CALG_SHA_256, 32,
1819 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
1820 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
1821 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
1822 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
1823 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
1824 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
1825 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
1826 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
1827 "\xaa\xaa\xaa", 131,
1828 "Test Using Larger Than Block-Size Key - Hash Key First", 54,
1829 "\x60\xe4\x31\x59\x1e\xe0\xb6\x7f\x0d\x8a\x26\xaa\xcb\xf5\xb7\x7f"
1830 "\x8e\x0b\xc6\x21\x37\x28\xc5\x14\x05\x46\x04\x0f\x0e\xe3\x7f\x54" },
1831
1832 { CALG_SHA_512, 64,
1833 "Jefe", 4,
1834 "what do ya want for nothing?", 28,
1835 "\x16\x4b\x7a\x7b\xfc\xf8\x19\xe2\xe3\x95\xfb\xe7\x3b\x56\xe0\xa3"
1836 "\x87\xbd\x64\x22\x2e\x83\x1f\xd6\x10\x27\x0c\xd7\xea\x25\x05\x54"
1837 "\x97\x58\xbf\x75\xc0\x5a\x99\x4a\x6d\x03\x4f\x65\xf8\xf0\xe6\xfd"
1838 "\xca\xea\xb1\xa3\x4d\x4a\x6b\x4b\x63\x6e\x07\x0a\x38\xbc\xe7\x37" },
1839
1840 { CALG_MD2, 16,
1841 "Jefe", 4,
1842 "what do ya want for nothing?", 28,
1843 "\x29\x2f\x9d\x34\xf9\xe3\x11\x84\x6d\xe8\x6c\x49\x5d\x7a\xdf\xa2" }
1844 };
1845 static const ALG_ID bad_algs[] = { CALG_MAC, CALG_HMAC, 0xffff };
1847 DWORD i;
1848
1849 /* SHA-256 isn't supported as a hash by the PROV_RSA_FULL providers */
1850 SetLastError(0xdeadbeef);
1852 ok(GetLastError() == NTE_BAD_ALGID, "Unexpected error %08lx\n", GetLastError());
1853 else
1855
1856 /* but it is supported as the inner algorithm of an HMAC */
1857 for (i = 0; i < ARRAY_SIZE(cases); i++)
1858 {
1859 const struct hmac_test_case *test_case = &cases[i];
1860 DWORD size = sizeof(BLOBHEADER) + sizeof(DWORD) + test_case->key_len;
1862
1863 if (blob)
1864 {
1866 DWORD *key_len = (DWORD *)(header + 1);
1867 BYTE *key_bytes = (BYTE *)(key_len + 1);
1868 BOOL result;
1869 HCRYPTKEY key;
1870
1871 header->bType = PLAINTEXTKEYBLOB;
1872 header->bVersion = CUR_BLOB_VERSION;
1873 header->reserved = 0;
1874 header->aiKeyAlg = CALG_RC2;
1875 *key_len = test_case->key_len;
1876 memcpy(key_bytes, test_case->key, *key_len);
1877
1879 ok(result, "CryptImportKey failed on test case %ld: %08lx\n", i, GetLastError());
1880
1881 if (result)
1882 {
1884 HMAC_INFO hmac_info = { test_case->algid, 0 };
1885 BYTE digest[64];
1886 DWORD digest_size, hash_size;
1887
1889 ok(result, "CryptCreateHash failed on test case %ld: %08lx\n", i, GetLastError());
1890
1891 result = CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&hmac_info, 0);
1892 ok(result, "CryptSetHashParam failed on test case %ld: %08lx\n", i, GetLastError());
1893
1894 hash_size = 0;
1895 digest_size = sizeof(hash_size);
1896 result = CryptGetHashParam(hash, HP_HASHSIZE, (BYTE *)&hash_size, &digest_size, 0);
1897 ok(result, "CryptGetHashParam failed on test case %ld: %08lx\n", i, GetLastError());
1898 ok(hash_size == test_case->digest_len, "Unexpected hash size %ld on test case %ld\n", hash_size, i);
1899
1900 result = CryptHashData(hash, (const BYTE *)test_case->data, test_case->data_len, 0);
1901 ok(result, "CryptHashData failed on test case %ld: %08lx\n", i, GetLastError());
1902
1903 digest_size = sizeof(digest);
1904 result = CryptGetHashParam(hash, HP_HASHVAL, digest, &digest_size, 0);
1905 ok(result, "CryptGetHashParam failed on test case %ld: %08lx\n", i, GetLastError());
1906 ok(!memcmp(digest, test_case->digest, test_case->digest_len), "Unexpected value on test case %ld\n", i);
1907
1910 }
1912 }
1913 }
1914
1915 /* check that algorithms which aren't hashes are refused */
1916 for (i = 0; i < ARRAY_SIZE(bad_algs); i++)
1917 {
1918 HMAC_INFO hmac_info = { bad_algs[i], 0 };
1919 BYTE digest[64];
1920 DWORD digest_size, hash_size;
1922 HCRYPTKEY key;
1923 BOOL result;
1924
1925 if (!derive_key(CALG_RC2, &key, 56)) return;
1926
1928 ok(result, "CryptCreateHash failed on algorithm %#x: %08lx\n", bad_algs[i], GetLastError());
1929
1930 SetLastError(0xdeadbeef);
1931 result = CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&hmac_info, 0);
1932 ok(!result, "CryptSetHashParam succeeded on algorithm %#x\n", bad_algs[i]);
1933 ok(GetLastError() == NTE_BAD_ALGID, "Unexpected error %08lx on algorithm %#x\n",
1934 GetLastError(), bad_algs[i]);
1935
1936 hash_size = 0xdeadbeef;
1937 digest_size = sizeof(hash_size);
1938 result = CryptGetHashParam(hash, HP_HASHSIZE, (BYTE *)&hash_size, &digest_size, 0);
1939 ok(result, "CryptGetHashParam failed on algorithm %#x: %08lx\n", bad_algs[i], GetLastError());
1940 ok(!hash_size, "Unexpected hash size %ld on algorithm %#x\n", hash_size, bad_algs[i]);
1941
1942 SetLastError(0xdeadbeef);
1943 result = CryptHashData(hash, (const BYTE *)cases[0].data, cases[0].data_len, 0);
1944 ok(!result, "CryptHashData succeeded on algorithm %#x\n", bad_algs[i]);
1945 ok(GetLastError() == NTE_BAD_ALGID, "Unexpected error %08lx on algorithm %#x\n",
1946 GetLastError(), bad_algs[i]);
1947
1948 digest_size = sizeof(digest);
1949 SetLastError(0xdeadbeef);
1950 result = CryptGetHashParam(hash, HP_HASHVAL, digest, &digest_size, 0);
1951 ok(!result, "CryptGetHashParam succeeded on algorithm %#x\n", bad_algs[i]);
1952 ok(GetLastError() == NTE_BAD_ALGID, "Unexpected error %08lx on algorithm %#x\n",
1953 GetLastError(), bad_algs[i]);
1954
1957 }
1958
1959 /* check that an HMAC can't hash anything until HP_HMAC_INFO is set */
1960 {
1961 HMAC_INFO hmac_info = { CALG_SHA_256, 0 };
1962 BYTE digest[64];
1963 DWORD digest_size;
1965 HCRYPTKEY key;
1966 BOOL result;
1967
1968 if (!derive_key(CALG_RC2, &key, 56)) return;
1969
1971 ok(result, "CryptCreateHash failed: %08lx\n", GetLastError());
1972
1973 SetLastError(0xdeadbeef);
1974 result = CryptHashData(hash, (const BYTE *)cases[0].data, cases[0].data_len, 0);
1975 ok(!result, "CryptHashData succeeded\n");
1976 ok(GetLastError() == NTE_BAD_ALGID, "Unexpected error %08lx\n", GetLastError());
1977
1978 digest_size = sizeof(digest);
1979 SetLastError(0xdeadbeef);
1980 result = CryptGetHashParam(hash, HP_HASHVAL, digest, &digest_size, 0);
1981 ok(!result, "CryptGetHashParam succeeded\n");
1982 ok(GetLastError() == NTE_BAD_ALGID, "Unexpected error %08lx\n", GetLastError());
1983
1984 result = CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&hmac_info, 0);
1985 ok(result, "CryptSetHashParam failed: %08lx\n", GetLastError());
1986
1989 }
1990}
1991
1992static void test_mac(void) {
1994 HCRYPTHASH hHash;
1995 BOOL result;
1996 DWORD dwLen;
1997 BYTE abData[256], abEnc[264];
1998 static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad};
1999 static const BYTE mac_40_old[8] = { 0x44, 0x78, 0x38, 0xad, 0x10, 0x13, 0x60, 0x8e};
2000 static const BYTE mac_40_2[8] = { 0xef, 0x22, 0x0a, 0x3b, 0xd0, 0xab, 0x48, 0x49};
2001 static const BYTE mac_40_2_old[8] = { 0xa3, 0xf3, 0xfc, 0x70, 0xf4, 0xfa, 0xb0, 0x3e};
2002 int i;
2003
2004 for (i=0; i < ARRAY_SIZE(abData); i++) abData[i] = (BYTE)i;
2005 for (i=0; i < ARRAY_SIZE(abData); i++) abEnc[i] = (BYTE)i;
2006
2007 if (!derive_key(CALG_RC2, &hKey, 40)) return;
2008
2009 dwLen = 256;
2010 result = CryptEncrypt(hKey, 0, TRUE, 0, abEnc, &dwLen, 264);
2011 ok (result && dwLen == 264, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
2012
2013 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
2014 ok(result, "%08lx\n", GetLastError());
2015
2016 dwLen = 8;
2017 result = CryptEncrypt(hKey, 0, FALSE, 0, abEnc, &dwLen, dwLen);
2018 ok(result, "%08lx\n", GetLastError());
2019
2020 result = CryptHashData(hHash, abData, sizeof(abData), 0);
2021 ok(result, "%08lx\n", GetLastError());
2022
2023 dwLen = ARRAY_SIZE(abData);
2024 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
2025 ok(result && dwLen == 8, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
2026
2027 /* Hash state is affected by key state before Win8. */
2028 ok(!memcmp(abData, mac_40, sizeof(mac_40)) || broken(!memcmp(abData, mac_40_old, sizeof(mac_40_old))),
2029 "Hash does not match.\n");
2030
2031 for (i = 0; i < ARRAY_SIZE(abData); ++i)
2032 abData[i] = (BYTE)i;
2033
2034 result = CryptHashData(hHash, abData, 1, 0);
2035 ok(!result && GetLastError() == NTE_BAD_HASH_STATE, "Unexpected result %d, error %#lx\n", result, GetLastError());
2036
2037 result = CryptDestroyHash(hHash);
2038 ok(result, "%08lx\n", GetLastError());
2039
2040 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
2041 ok(result, "%08lx\n", GetLastError());
2042
2043 dwLen = 8;
2044 result = CryptEncrypt(hKey, 0, FALSE, 0, abEnc, &dwLen, dwLen);
2045 ok(result, "%08lx\n", GetLastError());
2046
2047 result = CryptHashData(hHash, abData, 1, 0);
2048 ok(result, "%08lx\n", GetLastError());
2049
2050 dwLen = 8;
2051 result = CryptDecrypt(hKey, 0, FALSE, 0, abEnc, &dwLen);
2052 ok(result, "%08lx\n", GetLastError());
2053
2054 result = CryptHashData(hHash, abData + 1, 1, 0);
2055 ok(result, "%08lx\n", GetLastError());
2056 result = CryptHashData(hHash, abData + 2, 6, 0);
2057 ok(result, "%08lx\n", GetLastError());
2058 result = CryptHashData(hHash, abData + 8, 9, 0);
2059 ok(result, "%08lx\n", GetLastError());
2060
2061 dwLen = 8;
2062 result = CryptDecrypt(hKey, 0, FALSE, 0, abEnc, &dwLen);
2063 ok(result, "%08lx\n", GetLastError());
2064
2065 dwLen = ARRAY_SIZE(abData);
2066 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
2067 ok(result && dwLen == 8, "%08lx, dwLen %ld\n", GetLastError(), dwLen);
2068
2069 /* Hash state is affected by key state before Win8. */
2070 ok(!memcmp(abData, mac_40_2, sizeof(mac_40_2))
2071 || broken(!memcmp(abData, mac_40_2_old, sizeof(mac_40_2_old))), "Hash does not match.\n");
2072
2073 result = CryptDestroyHash(hHash);
2074 ok(result, "%08lx\n", GetLastError());
2075
2077 ok(result, "%08lx\n", GetLastError());
2078
2079 /* Provoke errors */
2080 if (!derive_key(CALG_RC4, &hKey, 56)) return;
2081
2082 SetLastError(0xdeadbeef);
2083 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
2084 ok(!result && GetLastError() == NTE_BAD_KEY, "%08lx\n", GetLastError());
2085
2087 ok(result, "%08lx\n", GetLastError());
2088}
2089
2090static void test_import_private(void)
2091{
2092 DWORD dwLen, dwVal;
2093 HCRYPTKEY hKeyExchangeKey, hSessionKey;
2094 BOOL result;
2095 static BYTE abSessionKey[148] = {
2096 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
2097 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
2098 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
2099 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
2100 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
2101 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
2102 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
2103 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
2104 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
2105 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
2106 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
2107 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
2108 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
2109 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
2110 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
2111 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
2112 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
2113 0x04, 0x8c, 0x49, 0x92
2114 };
2115 static BYTE abEncryptedMessage[12] = {
2116 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
2117 0x1c, 0xfd, 0xde, 0x71
2118 };
2119 BLOBHEADER *blobHeader = (BLOBHEADER *)abPlainPrivateKey;
2120 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(blobHeader+1);
2121
2122 dwLen = sizeof(abPlainPrivateKey);
2123 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2124 ok(result, "%08lx\n", GetLastError());
2125
2126 dwLen = sizeof(abSessionKey);
2127 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2128 ok(result, "%08lx\n", GetLastError());
2129
2130 dwVal = 0xdeadbeef;
2131 dwLen = sizeof(DWORD);
2132 result = CryptGetKeyParam(hSessionKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2133 ok(result, "%08lx\n", GetLastError());
2135 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT got %08lx\n", dwVal);
2136
2137 dwLen = sizeof(abEncryptedMessage);
2138 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
2139 ok(result, "%08lx\n", GetLastError());
2140 ok(dwLen == 12, "expected 12, got %ld\n", dwLen);
2141 ok(!memcmp(abEncryptedMessage, "Wine rocks!", 12), "decrypt failed\n");
2142 CryptDestroyKey(hSessionKey);
2143
2144 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
2145
2146 dwLen = sizeof(abSessionKey);
2147 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
2148 ok(result, "%08lx\n", GetLastError());
2149 CryptDestroyKey(hSessionKey);
2150
2151 dwLen = sizeof(abSessionKey);
2152 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
2153 ok(result, "%08lx\n", GetLastError());
2154
2155 CryptDestroyKey(hSessionKey);
2156 CryptDestroyKey(hKeyExchangeKey);
2157
2158 /* Test importing a private key with a buffer that's smaller than the
2159 * actual buffer. The private exponent can be omitted, its length is
2160 * inferred from the passed-in length parameter.
2161 */
2162 dwLen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + rsaPubKey->bitlen / 2;
2163 for (; dwLen < sizeof(abPlainPrivateKey); dwLen++)
2164 {
2165 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
2166 ok(result, "CryptImportKey failed at size %ld: %ld (%08lx)\n", dwLen,
2168 if (result)
2169 CryptDestroyKey(hKeyExchangeKey);
2170 }
2171}
2172
2173static void test_verify_signature(void) {
2174 HCRYPTHASH hHash;
2175 HCRYPTKEY hPubSignKey;
2176 BYTE abData[] = "Wine rocks!", buf[148];
2177 DWORD len;
2178 BOOL result;
2179 BYTE abPubKey[148] = {
2180 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2181 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
2182 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
2183 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
2184 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
2185 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
2186 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
2187 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
2188 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
2189 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
2190 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
2191 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
2192 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
2193 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
2194 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
2195 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
2196 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
2197 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
2198 0xe1, 0x21, 0x50, 0xac
2199 };
2200 /* md2 with hash oid */
2201 BYTE abSignatureMD2[128] = {
2202 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
2203 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
2204 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
2205 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
2206 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
2207 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
2208 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
2209 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
2210 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
2211 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
2212 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
2213 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
2214 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
2215 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
2216 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
2217 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
2218 };
2219 /* md2 without hash oid */
2220 BYTE abSignatureMD2NoOID[128] = {
2221 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
2222 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
2223 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
2224 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
2225 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
2226 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
2227 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
2228 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
2229 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
2230 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
2231 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
2232 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
2233 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
2234 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
2235 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
2236 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
2237 };
2238 /* md4 with hash oid */
2239 BYTE abSignatureMD4[128] = {
2240 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
2241 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
2242 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
2243 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
2244 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
2245 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
2246 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
2247 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
2248 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
2249 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
2250 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
2251 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
2252 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
2253 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
2254 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
2255 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
2256 };
2257 /* md4 without hash oid */
2258 BYTE abSignatureMD4NoOID[128] = {
2259 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
2260 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
2261 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
2262 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
2263 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
2264 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
2265 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
2266 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
2267 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
2268 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
2269 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
2270 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
2271 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
2272 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
2273 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
2274 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
2275 };
2276 /* md5 with hash oid */
2277 BYTE abSignatureMD5[128] = {
2278 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
2279 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
2280 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
2281 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
2282 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
2283 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
2284 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
2285 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
2286 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
2287 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
2288 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
2289 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
2290 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
2291 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
2292 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
2293 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
2294 };
2295 /* md5 without hash oid */
2296 BYTE abSignatureMD5NoOID[128] = {
2297 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
2298 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
2299 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
2300 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
2301 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
2302 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
2303 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
2304 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
2305 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
2306 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
2307 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
2308 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
2309 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
2310 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
2311 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
2312 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
2313 };
2314 /* sha with hash oid */
2315 BYTE abSignatureSHA[128] = {
2316 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
2317 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
2318 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
2319 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
2320 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
2321 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
2322 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
2323 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
2324 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
2325 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
2326 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
2327 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
2328 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
2329 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
2330 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
2331 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
2332 };
2333 /* sha without hash oid */
2334 BYTE abSignatureSHANoOID[128] = {
2335 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
2336 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
2337 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
2338 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
2339 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
2340 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
2341 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
2342 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
2343 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
2344 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
2345 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
2346 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
2347 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
2348 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
2349 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
2350 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
2351 };
2352
2353 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
2354 ok(result, "%08lx\n", GetLastError());
2355
2356 len = sizeof(buf);
2357 result = CryptExportKey(hPubSignKey, 0, PUBLICKEYBLOB, 0, buf, &len);
2358 ok(result, "%08lx\n", GetLastError());
2359 ok(len == sizeof(buf), "got %lu\n", len);
2360 ok(!memcmp(abPubKey, buf, sizeof(buf)), "wrong data\n");
2361
2362 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
2363 ok(result, "%08lx\n", GetLastError());
2364
2365 result = CryptHashData(hHash, abData, sizeof(abData), 0);
2366 ok(result, "%08lx\n", GetLastError());
2367
2368 /*check that a NULL pointer signature is correctly handled*/
2369 result = CryptVerifySignatureA(hHash, NULL, 128, hPubSignKey, NULL, 0);
2371 "Expected ERROR_INVALID_PARAMETER error, got %08lx\n", GetLastError());
2372
2373 /* check that we get a bad signature error when the signature is too short*/
2374 SetLastError(0xdeadbeef);
2375 result = CryptVerifySignatureA(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
2376 ok(!result && NTE_BAD_SIGNATURE == GetLastError(), "Expected NTE_BAD_SIGNATURE, got %08lx\n",
2377 GetLastError());
2378
2379 result = CryptVerifySignatureA(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
2380 ok(result, "%08lx\n", GetLastError());
2381
2382 /* It seems that CPVerifySignature doesn't care about the OID at all. */
2383 result = CryptVerifySignatureA(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
2384 ok(result, "%08lx\n", GetLastError());
2385
2386 result = CryptVerifySignatureA(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
2387 ok(result, "%08lx\n", GetLastError());
2388
2389 CryptDestroyHash(hHash);
2390
2391 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
2392 ok(result, "%08lx\n", GetLastError());
2393
2394 result = CryptHashData(hHash, abData, sizeof(abData), 0);
2395 ok(result, "%08lx\n", GetLastError());
2396
2397 result = CryptVerifySignatureA(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
2398 ok(result, "%08lx\n", GetLastError());
2399
2400 result = CryptVerifySignatureA(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, 0);
2401 ok(result, "%08lx\n", GetLastError());
2402
2403 result = CryptVerifySignatureA(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
2404 ok(result, "%08lx\n", GetLastError());
2405
2406 CryptDestroyHash(hHash);
2407
2408 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
2409 ok(result, "%08lx\n", GetLastError());
2410
2411 result = CryptHashData(hHash, abData, sizeof(abData), 0);
2412 ok(result, "%08lx\n", GetLastError());
2413
2414 result = CryptVerifySignatureA(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
2415 ok(result, "%08lx\n", GetLastError());
2416
2417 result = CryptVerifySignatureA(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, 0);
2418 ok(result, "%08lx\n", GetLastError());
2419
2420 result = CryptVerifySignatureA(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
2421 ok(result, "%08lx\n", GetLastError());
2422
2423 CryptDestroyHash(hHash);
2424
2425 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
2426 ok(result, "%08lx\n", GetLastError());
2427
2428 result = CryptHashData(hHash, abData, sizeof(abData), 0);
2429 ok(result, "%08lx\n", GetLastError());
2430
2431 result = CryptVerifySignatureA(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
2432 ok(result, "%08lx\n", GetLastError());
2433
2434 result = CryptVerifySignatureA(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, 0);
2435 ok(result, "%08lx\n", GetLastError());
2436
2437 result = CryptVerifySignatureA(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
2438 ok(result, "%08lx\n", GetLastError());
2439
2440 CryptDestroyHash(hHash);
2441 CryptDestroyKey(hPubSignKey);
2442}
2443
2444static void test_rsa_encrypt(void)
2445{
2446 HCRYPTKEY hRSAKey;
2447 BYTE abData[2048] = "Wine rocks!";
2448 BOOL result;
2449 DWORD dwVal, dwLen;
2450 DWORD err;
2451
2452 /* It is allowed to use the key exchange key for encryption/decryption */
2454 ok (result, "%08lx\n", GetLastError());
2455
2456 dwLen = 12;
2457 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, sizeof(abData));
2459 {
2460 CryptDestroyKey(hRSAKey);
2461 return;
2462 }
2463 ok(result, "CryptEncrypt failed: %08lx\n", GetLastError());
2464 ok(dwLen == 128, "Unexpected length %ld\n", dwLen);
2465 /* PKCS1 V1.5 */
2466 dwLen = 12;
2467 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, sizeof(abData));
2468 ok (result, "%08lx\n", GetLastError());
2469
2470 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
2471 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08lx\n", GetLastError());
2472
2473 /* OAEP, RFC 8017 PKCS #1 V2.2 */
2474 /* Test minimal buffer length requirement */
2475 dwLen = 1;
2476 SetLastError(0xdeadbeef);
2477 result = CryptEncrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen, 20 * 2 + 2);
2478 err = GetLastError();
2479 ok(!result && err == ERROR_MORE_DATA, "%08lx\n", err);
2480
2481 /* Test data length limit */
2482 dwLen = sizeof(abData) - (20 * 2 + 2) + 1;
2483 result = CryptEncrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen, sizeof(abData));
2484 err = GetLastError();
2485 ok(!result && err == NTE_BAD_LEN, "%08lx\n", err);
2486
2487 /* Test malformed data */
2488 dwLen = 12;
2489 SetLastError(0xdeadbeef);
2490 memcpy(abData, "Wine rocks!", dwLen);
2491 result = CryptDecrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen);
2492 err = GetLastError();
2493 ok(!result && err == NTE_BAD_DATA, "%08lx\n", err);
2494
2495 /* Test decrypt with insufficient buffer */
2496 dwLen = 12;
2497 SetLastError(0xdeadbeef);
2498 memcpy(abData, "Wine rocks!", 12);
2499 result = CryptEncrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen, sizeof(abData));
2500 ok(result, "%08lx\n", GetLastError());
2501 dwLen = 11;
2502 SetLastError(0xdeadbeef);
2503 result = CryptDecrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen);
2504 err = GetLastError();
2505 ok(!result && dwLen == 11 && err == NTE_BAD_DATA, "%08x %ld %08lx\n", result, dwLen, err);
2506
2507 /* Test normal encryption and decryption */
2508 dwLen = 12;
2509 memcpy(abData, "Wine rocks!", dwLen);
2510 result = CryptEncrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen, sizeof(abData));
2511 ok(result, "%08lx\n", GetLastError());
2512 result = CryptDecrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen);
2513 ok(result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08lx\n", GetLastError());
2514
2515 dwVal = 0xdeadbeef;
2516 dwLen = sizeof(DWORD);
2517 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2518 ok(result, "%08lx\n", GetLastError());
2520 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT got %08lx\n", dwVal);
2521
2522 /* An RSA key doesn't support salt */
2523 result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
2524 ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == NTE_NOT_FOUND /* Win7 */),
2525 "expected NTE_BAD_KEY or NTE_NOT_FOUND, got %08lx\n", GetLastError());
2526
2527 /* The key exchange key's public key may be exported.. */
2528 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2529 ok(result, "%08lx\n", GetLastError());
2530 /* but its private key may not be. */
2531 SetLastError(0xdeadbeef);
2532 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2533 ok(!result && GetLastError() == NTE_BAD_KEY_STATE, "expected NTE_BAD_KEY_STATE, got %08lx\n",
2534 GetLastError());
2535 /* Setting the permissions of the key exchange key isn't allowed, either. */
2536 dwVal |= CRYPT_EXPORT;
2537 SetLastError(0xdeadbeef);
2538 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2540 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08lx\n", GetLastError());
2541
2542 CryptDestroyKey(hRSAKey);
2543
2544 /* It is not allowed to use the signature key for encryption/decryption */
2546 if (!result)
2547 {
2548 skip("No signature key in provider %s found, error %#lx.\n", szProviders[iProv], GetLastError());
2549 return;
2550 }
2551
2552 dwVal = 0xdeadbeef;
2553 dwLen = sizeof(DWORD);
2554 result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
2555 ok(result, "%08lx\n", GetLastError());
2557 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT got %08lx\n", dwVal);
2558
2559 /* The signature key's public key may also be exported.. */
2560 result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
2561 ok(result, "%08lx\n", GetLastError());
2562 /* but its private key may not be. */
2563 SetLastError(0xdeadbeef);
2564 result = CryptExportKey(hRSAKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
2565 ok(!result && GetLastError() == NTE_BAD_KEY_STATE, "expected NTE_BAD_KEY_STATE got %08lx\n",
2566 GetLastError());
2567 /* Setting the permissions of the signature key isn't allowed, either. */
2568 dwVal |= CRYPT_EXPORT;
2569 SetLastError(0xdeadbeef);
2570 result = CryptSetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
2572 "expected NTE_BAD_DATA or NTE_BAD_FLAGS, got %08lx\n", GetLastError());
2573
2574 dwLen = 12;
2575 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, sizeof(abData));
2576 ok (!result && GetLastError() == NTE_BAD_KEY, "%08lx\n", GetLastError());
2577
2578 CryptDestroyKey(hRSAKey);
2579}
2580
2581static void test_import_export(void)
2582{
2583 DWORD dwLen, dwDataLen, dwVal;
2584 HCRYPTKEY hPublicKey, hPrivKey;
2585 BOOL result;
2586 ALG_ID algID;
2587 BYTE emptyKey[2048], *exported_key, *exported_key2;
2588 static BYTE abPlainPublicKey[84] = {
2589 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
2590 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
2591 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
2592 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2593 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2594 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2595 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2596 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2597 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2598 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2599 0x11, 0x11, 0x11, 0x11
2600 };
2601 static BYTE priv_key_with_high_bit[] = {
2602 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2603 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
2604 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66,
2605 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58,
2606 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e,
2607 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03,
2608 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4,
2609 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91,
2610 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5,
2611 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1,
2612 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd,
2613 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8,
2614 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53,
2615 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37,
2616 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26,
2617 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1,
2618 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d,
2619 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e,
2620 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68,
2621 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b,
2622 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8,
2623 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b,
2624 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15,
2625 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78,
2626 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2,
2627 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2,
2628 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31,
2629 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c,
2630 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7,
2631 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d,
2632 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37,
2633 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a,
2634 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c,
2635 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99,
2636 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef,
2637 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9,
2638 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec,
2639 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d,
2640 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e,
2641 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42,
2642 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98,
2643 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12,
2644 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73,
2645 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d,
2646 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23,
2647 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0,
2648 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19,
2649 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0,
2650 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8,
2651 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa,
2652 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8,
2653 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c,
2654 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2,
2655 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12,
2656 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42,
2657 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d,
2658 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1,
2659 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4,
2660 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91,
2661 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15,
2662 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe,
2663 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7,
2664 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4,
2665 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60,
2666 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17,
2667 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e,
2668 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33,
2669 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98,
2670 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50,
2671 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6,
2672 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f,
2673 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98,
2674 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08,
2675 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59,
2676 0xb6, 0x5f, 0x01, 0x5e
2677 };
2678
2679 static const BYTE expected_exported_priv_key[] = {
2680 /* BLOBHEADER */
2681 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
2682 /* PUBKEY */
2683 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
2684 /* m */
2685 0xd5, 0xa2, 0x0d, 0x66, 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58, 0x04, 0x38, 0x2d, 0xf4,
2686 0xa3, 0x5a, 0xda, 0x9e, 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03, 0x77, 0x70, 0x79, 0x6e,
2687 0x6c, 0x26, 0x42, 0xa4, 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91, 0x90, 0x39, 0x5e, 0x49,
2688 0x56, 0xfd, 0x0a, 0xe5, 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1, 0x1f, 0x22, 0x07, 0x3e,
2689 0x4d, 0xc0, 0x73, 0xfd, 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8, 0x19, 0xd1, 0x93, 0x83,
2690 0xe0, 0xb8, 0x9f, 0x53, 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37, 0x02, 0xb4, 0xa5, 0xf7,
2691 0xa2, 0x28, 0x6e, 0x26, 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1, 0xda, 0x76, 0xd0, 0x12,
2692 0x84, 0xb7, 0x48, 0x7d, 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e, 0x7d, 0x32, 0x59, 0x92,
2693 /* p1 */
2694 0x01, 0xd6, 0x5b, 0x68, 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b, 0x4b, 0x13, 0xe2, 0xbd,
2695 0x7d, 0xbe, 0xce, 0xe8, 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b, 0xdf, 0xf6, 0x55, 0x6c,
2696 0x50, 0x11, 0xc8, 0x15, 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78, 0x7b, 0x22, 0x8d, 0x96,
2697 0x62, 0xe5, 0xda, 0xa2, 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2, 0x48, 0x06, 0x1a, 0xc6,
2698 /* p2 */
2699 0xd5, 0x94, 0xec, 0x31, 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c, 0x6f, 0xb7, 0x55, 0x3d,
2700 0x6b, 0x98, 0x05, 0xd7, 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d, 0x27, 0x18, 0x0d, 0x05,
2701 0xba, 0x23, 0x54, 0x37, 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a, 0x6a, 0x2f, 0x7f, 0x68,
2702 0x43, 0x86, 0xe7, 0x9c, 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99, 0x51, 0xfe, 0x1e, 0xbd,
2703 /* e1 */
2704 0x01, 0xc6, 0x10, 0xef, 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9, 0xe5, 0x86, 0xe2, 0x8d,
2705 0x85, 0x2e, 0x0d, 0xec, 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d, 0x2b, 0x90, 0x70, 0x7f,
2706 0x78, 0xb1, 0x33, 0x7e, 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42, 0x22, 0xd5, 0x5f, 0xbc,
2707 0xbd, 0xab, 0x26, 0x98, 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12, 0x9e, 0xa5, 0xa2, 0x90,
2708 /* e2 */
2709 0x85, 0xc5, 0xca, 0x73, 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d, 0xc1, 0xaa, 0x86, 0x53,
2710 0xd5, 0xde, 0xbb, 0x23, 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0, 0xe4, 0xdd, 0xd2, 0x03,
2711 0xfd, 0x67, 0x55, 0x19, 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0, 0x80, 0x9d, 0xdd, 0xda,
2712 0x9d, 0x30, 0x5c, 0xc8, 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa, 0x14, 0xaf, 0xe4, 0xba,
2713 /* u */
2714 0xb0, 0x84, 0x45, 0xd8, 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c, 0xfa, 0xe9, 0x65, 0xa4,
2715 0x21, 0x2d, 0x6b, 0xa2, 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12, 0xc2, 0x02, 0x3d, 0xd5,
2716 0x83, 0x1d, 0xfa, 0x42, 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d, 0x91, 0x59, 0xf9, 0x38,
2717 0x52, 0xe5, 0xdb, 0xc1, 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4, 0x8d, 0x5e, 0xc4, 0x00,
2718 /* d */
2719 0x01, 0xb8, 0xec, 0x91, 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15, 0xb6, 0x3e, 0xa2, 0xdf,
2720 0x62, 0x8d, 0xa8, 0xbe, 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7, 0xda, 0xdc, 0x71, 0x30,
2721 0xf1, 0x21, 0x71, 0xa4, 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60, 0x5b, 0x63, 0x35, 0xe3,
2722 0x37, 0x5b, 0x25, 0x17, 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e, 0x09, 0xef, 0xda, 0x90,
2723 0x3e, 0xd4, 0x09, 0x33, 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98, 0x30, 0x42, 0x03, 0x84,
2724 0x61, 0xeb, 0x8e, 0x50, 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6, 0xc2, 0x19, 0xb3, 0x5d,
2725 0xe2, 0xf8, 0xc5, 0x8f, 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98, 0x9c, 0x16, 0x8c, 0xc3,
2726 0xcd, 0xd9, 0xdb, 0x08, 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59, 0xb6, 0x5f, 0x01, 0x5e
2727 };
2728
2729 dwLen=84;
2730 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
2731 ok(result, "failed to import the public key\n");
2732
2733 dwDataLen=sizeof(algID);
2734 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
2735 ok(result, "failed to get the KP_ALGID from the imported public key\n");
2736 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
2737
2738 dwVal = 0xdeadbeef;
2739 dwDataLen = sizeof(DWORD);
2740 result = CryptGetKeyParam(hPublicKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwDataLen, 0);
2741 ok(result, "%08lx\n", GetLastError());
2743 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_DECRYPT|CRYPT_ENCRYPT," " got %08lx\n", dwVal);
2744 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
2745 ok(result, "failed to export the fresh imported public key\n");
2746 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %ld bytes.\n",dwLen);
2747 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
2748
2749 CryptDestroyKey(hPublicKey);
2750
2751 /* imports into AT_SIGNATURE key container */
2752 result = CryptImportKey(hProv, priv_key_with_high_bit,
2753 sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey);
2754 ok(result, "CryptImportKey failed: %08lx\n", GetLastError());
2755
2756 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
2757 ok(result, "CryptExportKey failed: %08lx\n", GetLastError());
2758 exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2759 result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key,
2760 &dwDataLen);
2761 ok(result, "CryptExportKey failed: %08lx\n", GetLastError());
2762
2763 ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %ld\n",
2764 dwDataLen);
2765 ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen),
2766 "unexpected value\n");
2767
2768 HeapFree(GetProcessHeap(), 0, exported_key);
2769
2770 CryptDestroyKey(hPrivKey);
2771
2772 /* imports into AT_KEYEXCHANGE key container */
2774 sizeof(abPlainPrivateKey), 0, 0, &hPrivKey);
2775 ok(result, "CryptImportKey failed: %08lx\n", GetLastError());
2776
2777 result = CryptExportKey(hPrivKey, 0, PUBLICKEYBLOB, 0, NULL, &dwDataLen);
2778 ok(result, "CryptExportKey failed: %08lx\n", GetLastError());
2779 exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2780 result = CryptExportKey(hPrivKey, 0, PUBLICKEYBLOB, 0, exported_key,
2781 &dwDataLen);
2782 ok(result, "CryptExportKey failed: %08lx\n", GetLastError());
2783 CryptDestroyKey(hPrivKey);
2784
2785 /* getting the public key from AT_KEYEXCHANGE, and compare it */
2787 ok(result, "CryptGetUserKey failed: %08lx\n", GetLastError());
2788 result = CryptExportKey(hPrivKey, 0, PUBLICKEYBLOB, 0, NULL, &dwDataLen);
2789 ok(result, "CryptExportKey failed: %08lx\n", GetLastError());
2790 exported_key2 = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2791 result = CryptExportKey(hPrivKey, 0, PUBLICKEYBLOB, 0, exported_key2,
2792 &dwDataLen);
2793 ok(result, "CryptExportKey failed: %08lx\n", GetLastError());
2794 CryptDestroyKey(hPrivKey);
2795
2796 result = !memcmp(exported_key, exported_key2, dwDataLen);
2797 ok(result, "unexpected value\n");
2798 if (!result && winetest_debug > 1) {
2799 trace("Expected public key (%lu):\n", dwDataLen);
2800 trace_hex(exported_key, dwDataLen);
2801 trace("AT_KEYEXCHANGE public key (%lu):\n", dwDataLen);
2802 trace_hex(exported_key2, dwDataLen);
2803 }
2804 HeapFree(GetProcessHeap(), 0, exported_key2);
2805
2806 /* importing a public key doesn't update key container at all */
2807 result = CryptImportKey(hProv, abPlainPublicKey,
2808 sizeof(abPlainPublicKey), 0, 0, &hPublicKey);
2809 ok(result, "failed to import the public key\n");
2810 CryptDestroyKey(hPublicKey);
2811
2812 /* getting the public key again, and compare it */
2814 ok(result, "CryptGetUserKey failed: %08lx\n", GetLastError());
2815 result = CryptExportKey(hPrivKey, 0, PUBLICKEYBLOB, 0, NULL, &dwDataLen);
2816 ok(result, "CryptExportKey failed: %08lx\n", GetLastError());
2817 exported_key2 = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
2818 result = CryptExportKey(hPrivKey, 0, PUBLICKEYBLOB, 0, exported_key2,
2819 &dwDataLen);
2820 ok(result, "CryptExportKey failed: %08lx\n", GetLastError());
2821 CryptDestroyKey(hPrivKey);
2822
2823 result = !memcmp(exported_key, exported_key2, dwDataLen);
2824 ok(result, "unexpected value\n");
2825 if (!result && winetest_debug > 1) {
2826 trace("Expected public key (%lu):\n", dwDataLen);
2827 trace_hex(exported_key, dwDataLen);
2828 trace("AT_KEYEXCHANGE public key (%lu):\n", dwDataLen);
2829 trace_hex(exported_key2, dwDataLen);
2830 }
2831
2832 HeapFree(GetProcessHeap(), 0, exported_key);
2833 HeapFree(GetProcessHeap(), 0, exported_key2);
2834}
2835
2836static void test_import_hmac(void)
2837{
2838 /* Test cases from RFC 2202, section 3 */
2839 static const struct rfc2202_test_case {
2840 const char *key;
2841 DWORD key_len;
2842 const char *data;
2843 const DWORD data_len;
2844 const char *digest;
2845 } cases[] = {
2846 { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
2847 "\x0b\x0b\x0b\x0b", 20,
2848 "Hi There", 8,
2849 "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e"
2850 "\xf1\x46\xbe\x00" },
2851 { "Jefe", 4,
2852 "what do ya want for nothing?", 28,
2853 "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c"
2854 "\x25\x9a\x7c\x79" },
2855 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2856 "\xaa\xaa\xaa\xaa", 20,
2857 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2858 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2859 "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
2860 "\xdd\xdd", 50,
2861 "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f"
2862 "\x63\xf1\x75\xd3" },
2863 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
2864 "\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25,
2865 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2866 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2867 "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
2868 "\xcd\xcd", 50,
2869 "\x4c\x90\x07\xF4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c"
2870 "\x2d\x72\x35\xda" },
2871 { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
2872 "\x0c\x0c\x0c\x0c", 20,
2873 "Test With Truncation", 20,
2874 "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32"
2875 "\x4a\x9a\x5a\x04" },
2876 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2877 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2878 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2879 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2880 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2881 80,
2882 "Test Using Larger Than Block-Size Key - Hash Key First", 54,
2883 "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55"
2884 "\xed\x40\x21\x12" },
2885 { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2886 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2887 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2888 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
2889 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
2890 80,
2891 "Test Using Larger Than Block-Size Key and Larger "
2892 "Than One Block-Size Data", 73,
2893 "\xe8\xe9\x9D\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08"
2894 "\xbb\xff\x1a\x91" }
2895 };
2896 DWORD i;
2897
2898 for (i = 0; i < ARRAY_SIZE(cases); i++)
2899 {
2900 const struct rfc2202_test_case *test_case = &cases[i];
2901 DWORD size = sizeof(BLOBHEADER) + sizeof(DWORD) + test_case->key_len;
2903
2904 if (blob)
2905 {
2907 DWORD *key_len = (DWORD *)(header + 1);
2908 BYTE *key_bytes = (BYTE *)(key_len + 1);
2909 BOOL result;
2910 HCRYPTKEY key;
2911
2912 header->bType = PLAINTEXTKEYBLOB;
2913 header->bVersion = CUR_BLOB_VERSION;
2914 header->reserved = 0;
2915 header->aiKeyAlg = CALG_RC2;
2916 *key_len = test_case->key_len;
2917 memcpy(key_bytes, test_case->key, *key_len);
2919 ok(result, "CryptImportKey failed on test case %ld: %08lx\n", i, GetLastError());
2920 if (result)
2921 {
2923 HMAC_INFO hmac_info = { CALG_SHA1, 0 };
2924 BYTE digest[20];
2925 DWORD digest_size;
2926
2928 ok(result, "CryptCreateHash failed on test case %ld: %08lx\n", i, GetLastError());
2929 result = CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&hmac_info, 0);
2930 ok(result, "CryptSetHashParam failed on test case %ld: %08lx\n", i, GetLastError());
2931 result = CryptHashData(hash, (const BYTE *)test_case->data, test_case->data_len, 0);
2932 ok(result, "CryptHashData failed on test case %ld: %08lx\n", i, GetLastError());
2933 digest_size = sizeof(digest);
2934 result = CryptGetHashParam(hash, HP_HASHVAL, digest, &digest_size, 0);
2935 ok(result, "CryptGetHashParam failed on test case %ld: %08lx\n", i, GetLastError());
2936 ok(!memcmp(digest, test_case->digest, sizeof(digest)), "Unexpected value on test case %ld\n", i);
2939 }
2941 }
2942 }
2943}
2944
2945static void test_schannel_provider(void)
2946{
2948 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
2949 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
2950 BOOL result;
2951 DWORD dwLen;
2952 SCHANNEL_ALG saSChannelAlg;
2953 CRYPT_DATA_BLOB data_blob;
2954 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
2955 BYTE abTLS1Master[140] = {
2956 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
2957 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
2958 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
2959 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
2960 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
2961 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
2962 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
2963 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
2964 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
2965 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
2966 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
2967 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
2968 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
2969 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
2970 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
2971 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
2972 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
2973 0xd3, 0x1e, 0x82, 0xb3
2974 };
2975 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
2976 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
2977 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
2978 BYTE abClientFinished[16] = "client finished";
2979 BYTE abData[16] = "Wine rocks!";
2980 BYTE abMD5Hash[16];
2981 static const BYTE abEncryptedData[16] = {
2982 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
2983 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
2984 };
2985 static const BYTE abPRF[16] = {
2986 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
2987 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
2988 };
2989 static const BYTE abMD5[16] = {
2990 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
2991 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
2992 };
2993
2995 ok (result, "%08lx\n", GetLastError());
2996 if (result)
2998
3000 ok (result, "%08lx\n", GetLastError());
3001
3002 /* To get deterministic results, we import the TLS1 master secret (which
3003 * is typically generated from a random generator). Therefore, we need
3004 * an RSA key. */
3005 dwLen = sizeof(abPlainPrivateKey);
3006 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
3007 ok (result, "%08lx\n", GetLastError());
3008
3009 dwLen = sizeof(abTLS1Master);
3010 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
3011 ok (result, "%08lx\n", GetLastError());
3012
3013 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
3014 * (Keys can only be derived from hashes, not from other keys.)
3015 * The hash can't be created yet because the key doesn't have the client
3016 * random or server random set.
3017 */
3018 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
3020 "expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError());
3021
3022 /* Setting the TLS1 client and server random parameters, as well as the
3023 * MAC and encryption algorithm parameters. */
3024 data_blob.cbData = 33;
3025 data_blob.pbData = abClientSecret;
3026 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
3027 ok (result, "%08lx\n", GetLastError());
3028
3029 data_blob.cbData = 33;
3030 data_blob.pbData = abServerSecret;
3031 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
3032 ok (result, "%08lx\n", GetLastError());
3033
3034 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
3035 ok (result ||
3036 broken(!result), /* Windows 8 and greater */
3037 "%08lx\n", GetLastError());
3038 if (!result)
3039 {
3040 win_skip("Broken TLS1 hash creation\n");
3041 CryptDestroyKey(hRSAKey);
3042 CryptDestroyKey(hMasterSecret);
3045 return;
3046 }
3047
3048 /* Deriving the server write encryption key from the master hash can't
3049 * succeed before the encryption key algorithm is set.
3050 */
3051 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
3053 "expected NTE_BAD_FLAGS, got %08lx\n", GetLastError());
3054
3055 CryptDestroyHash(hMasterHash);
3056
3057 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
3058 saSChannelAlg.Algid = CALG_DES;
3059 saSChannelAlg.cBits = 64;
3060 saSChannelAlg.dwFlags = 0;
3061 saSChannelAlg.dwReserved = 0;
3062 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
3063 ok (result, "%08lx\n", GetLastError());
3064
3065 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
3066 saSChannelAlg.Algid = CALG_MD5;
3067 saSChannelAlg.cBits = 128;
3068 saSChannelAlg.dwFlags = 0;
3069 saSChannelAlg.dwReserved = 0;
3070 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
3071 ok (result, "%08lx\n", GetLastError());
3072
3073 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
3074 ok (result, "%08lx\n", GetLastError());
3075
3076 /* Deriving the server write encryption key from the master hash */
3077 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
3078 ok (result, "%08lx\n", GetLastError());
3079
3080 /* Encrypting some data with the server write encryption key and checking the result. */
3081 dwLen = 12;
3082 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
3083 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08lx\n", GetLastError());
3084
3085 /* Second test case: Test the TLS1 pseudo random number function. */
3086 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
3087 ok (result, "%08lx\n", GetLastError());
3088
3089 /* Set the label and seed parameters for the random number function */
3090 data_blob.cbData = 36;
3091 data_blob.pbData = abHashedHandshakes;
3092 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
3093 ok (result, "%08lx\n", GetLastError());
3094
3095 data_blob.cbData = 15;
3096 data_blob.pbData = abClientFinished;
3097 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
3098 ok (result, "%08lx\n", GetLastError());
3099
3100 /* Generate some pseudo random bytes and check if they are correct. */
3101 dwLen = sizeof(abData);
3102 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
3103 ok (result && (dwLen==sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
3104 "%08lx\n", GetLastError());
3105
3106 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
3107 * Hash some data with the HMAC. Compare results. */
3108 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
3109 ok (result, "%08lx\n", GetLastError());
3110
3111 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
3112 ok (result, "%08lx\n", GetLastError());
3113
3114 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
3115 ok (result, "%08lx\n", GetLastError());
3116
3117 result = CryptHashData(hHMAC, abData, sizeof(abData), 0);
3118 ok (result, "%08lx\n", GetLastError());
3119
3120 dwLen = sizeof(abMD5Hash);
3121 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
3122 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08lx\n", GetLastError());
3123
3124 CryptDestroyHash(hHMAC);
3125 CryptDestroyHash(hTLS1PRF);
3126 CryptDestroyHash(hMasterHash);
3127 CryptDestroyKey(hServerWriteMACKey);
3128 CryptDestroyKey(hServerWriteKey);
3129 CryptDestroyKey(hRSAKey);
3130 CryptDestroyKey(hMasterSecret);
3133}
3134
3135/* Test that a key can be used to encrypt data and exported, and that, when
3136 * the exported key is imported again, can be used to decrypt the original
3137 * data again.
3138 */
3139static void test_rsa_round_trip(void)
3140{
3141 static const char test_string[] = "Well this is a fine how-do-you-do.";
3142 HCRYPTPROV prov;
3143 HCRYPTKEY signKey, keyExchangeKey;
3144 BOOL result;
3145 BYTE data[256], *exportedKey;
3146 DWORD dataLen, keyLen;
3147
3150
3151 /* Generate a new key... */
3154 ok(result, "CryptAcquireContextA failed: %08lx\n", GetLastError());
3156 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08lx\n", GetLastError());
3157 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey);
3158 ok(result, "CryptGetUserKey failed: %08lx\n", GetLastError());
3159 /* encrypt some data with it... */
3161 dataLen = strlen(test_string) + 1;
3162 result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen,
3163 sizeof(data));
3164 ok(result, "CryptEncrypt failed: %08lx\n", GetLastError());
3165 /* export the key... */
3166 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL,
3167 &keyLen);
3168 ok(result, "CryptExportKey failed: %08lx\n", GetLastError());
3169 exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen);
3170 result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey,
3171 &keyLen);
3172 ok(result, "CryptExportKey failed: %08lx\n", GetLastError());
3173
3174 CryptDestroyKey(keyExchangeKey);
3175 CryptDestroyKey(signKey);
3176
3177 result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey);
3178 ok(result, "CryptImportKey failed: %08lx\n", GetLastError());
3179 HeapFree(GetProcessHeap(), 0, exportedKey);
3180
3181 /* and decrypt the data encrypted with the original key with the imported
3182 * key.
3183 */
3184 result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen);
3185 ok(result, "CryptDecrypt failed: %08lx\n", GetLastError());
3186 if (result)
3187 {
3188 ok(dataLen == sizeof(test_string), "unexpected size %ld\n", dataLen);
3189 ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n");
3190 }
3191 CryptDestroyKey(keyExchangeKey);
3192 CryptReleaseContext(prov, 0);
3193
3196}
3197
3198static void test_enum_container(void)
3199{
3200 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
3201 DWORD dwBufferLen;
3202 BOOL result, fFound = FALSE;
3203
3204 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
3205 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
3206 SetLastError(0xdeadbeef);
3208 ok (result, "%08lx\n", GetLastError());
3209 ok (dwBufferLen == MAX_PATH + 1,
3210 "Expected dwBufferLen to be (MAX_PATH + 1), it was : %ld\n", dwBufferLen);
3211
3212 /* If the result fits into abContainerName dwBufferLen is left untouched */
3213 dwBufferLen = sizeof(abContainerName);
3214 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
3215 ok (result && dwBufferLen == sizeof(abContainerName), "%08lx\n", GetLastError());
3216
3217 /* We only check, if the currently open 'winetest' container is among the enumerated. */
3218 do {
3219 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
3220 dwBufferLen = sizeof(abContainerName);
3221 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
3222
3223 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08lx\n", fFound, GetLastError());
3224}
3225
3226static BYTE signBlob[] = {
32270x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
32280x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
32290xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
32300x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
32310xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
32320x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
32330xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
32340xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
32350x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
32360x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
32370xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
32380xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
32390x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
32400xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
32410x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
32420x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
32430x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
32440x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
32450xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
32460xb6,0x85,0x86,0x07 };
3247
3248static void test_null_provider(void)
3249{
3250 HCRYPTPROV prov;
3251 HCRYPTKEY key;
3252 BOOL result;
3253 DWORD keySpec, dataLen,dwParam;
3255
3258 "Expected NTE_BAD_PROV_TYPE, got %08lx\n", GetLastError());
3261 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08lx\n", GetLastError());
3265 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_KEYSET, got %08lx\n", GetLastError());
3269 "Expected NTE_BAD_KEYSET, got %08lx\n", GetLastError());
3272 "Expected NTE_BAD_KEYSET, got %08lx\n", GetLastError());
3273
3274 /* Delete the default container. */
3276 /* Once you've deleted the default container you can't open it as if it
3277 * already exists.
3278 */
3281 "Expected NTE_BAD_KEYSET, got %08lx\n", GetLastError());
3282 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
3285 ok(result, "CryptAcquireContextA failed: %08lx\n", GetLastError());
3286 dataLen = sizeof(keySpec);
3287 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
3288 if (result)
3289 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
3290 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08lx\n", keySpec);
3291 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
3292 * supported, you can't get the keys from this container.
3293 */
3296 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
3299 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
3300 result = CryptReleaseContext(prov, 0);
3301 ok(result, "CryptReleaseContext failed: %08lx\n", GetLastError());
3302 /* You can create a new default container. */
3305 ok(result, "CryptAcquireContextA failed: %08lx\n", GetLastError());
3306 /* But you still can't get the keys (until one's been generated.) */
3309 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
3312 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
3313 CryptReleaseContext(prov, 0);
3315
3320 "Expected NTE_BAD_KEYSET, got %08lx\n", GetLastError());
3324 "Expected NTE_BAD_FLAGS, got %08lx\n", GetLastError());
3327 ok(result, "CryptAcquireContextA failed: %08lx\n", GetLastError());
3328
3329 /* Test provider parameters getter */
3330 dataLen = sizeof(dwParam);
3331 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
3332 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
3333 "Expected PROV_RSA_FULL, got 0x%08lX\n",dwParam);
3334 dataLen = sizeof(dwParam);
3335 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
3336 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
3337 "Expected 0, got 0x%08lX\n",dwParam);
3338 dataLen = sizeof(dwParam);
3339 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
3340 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
3341 "Expected CRYPT_SEC_DESCR to be set, got 0x%08lX\n",dwParam);
3342 dataLen = sizeof(keySpec);
3343 SetLastError(0xdeadbeef);
3344 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
3345 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
3346 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08lx\n", keySpec);
3347 /* PP_CONTAINER parameter */
3348 dataLen = sizeof(szName);
3349 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
3350 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
3351 "failed getting PP_CONTAINER. result = %s. Error 0x%08lX. returned length = %ld\n",
3352 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
3353 /* PP_UNIQUE_CONTAINER parameter */
3354 dataLen = sizeof(szName);
3355 SetLastError(0xdeadbeef);
3357 ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08lX\n", GetLastError());
3359 todo_wine
3360 {
3361 ok(dataLen == strlen(container) + 1, "Expected a param length of 70, got %ld\n", dataLen);
3362 ok(!strcmp(container, szName), "Wrong container name : %s\n", szName);
3363 }
3366 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
3369 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
3370
3371 /* Importing a key exchange blob.. */
3373 0, 0, &key);
3374 ok(result, "CryptImportKey failed: %08lx\n", GetLastError());
3376 /* allows access to the key exchange key.. */
3378 ok(result, "CryptGetUserKey failed: %08lx\n", GetLastError());
3380 /* but not to the private key. */
3383 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
3384 CryptReleaseContext(prov, 0);
3387
3388 /* Whereas importing a sign blob.. */
3391 ok(result, "CryptAcquireContextA failed: %08lx\n", GetLastError());
3392
3393 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
3394 ok(result, "CryptImportKey failed: %08lx\n", GetLastError());
3396 /* doesn't allow access to the key exchange key.. */
3399 "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
3400 /* but does to the private key. */
3402 ok(result, "CryptGetUserKey failed: %08lx\n", GetLastError());
3404 CryptReleaseContext(prov, 0);
3405
3408
3409 /* Test for being able to get a key generated with CALG_RSA_SIGN. */
3412 ok(result, "CryptAcquireContextA failed: %08lx\n", GetLastError());
3413 result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key);
3414 ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08lx\n", GetLastError());
3417 ok(!result, "expected CryptGetUserKey to fail\n");
3419 ok(result, "CryptGetUserKey with AT_SIGNATURE failed: %08lx\n", GetLastError());
3421 CryptReleaseContext(prov, 0);
3422
3425
3426 /* Test for being able to get a key generated with CALG_RSA_KEYX. */
3429 ok(result, "CryptAcquireContextA failed: %08lx\n", GetLastError());
3430 result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key);
3431 ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08lx\n", GetLastError());
3434 ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08lx\n", GetLastError());
3437 ok(!result, "expected CryptGetUserKey to fail\n");
3438 CryptReleaseContext(prov, 0);
3439
3442
3443 /* test for the bug in accessing the user key in a container
3444 */
3447 ok(result, "CryptAcquireContextA failed: %08lx\n", GetLastError());
3448 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
3449 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08lx\n", GetLastError());
3451 CryptReleaseContext(prov,0);
3453 ok(result, "CryptAcquireContextA failed: 0x%08lx\n", GetLastError());
3455 ok (result, "CryptGetUserKey failed with error %08lx\n", GetLastError());
3457 CryptReleaseContext(prov, 0);
3458
3461
3462 /* test the machine key set */
3467 ok(result, "CryptAcquireContextA with CRYPT_MACHINE_KEYSET failed: %08lx\n", GetLastError());
3468 CryptReleaseContext(prov, 0);
3471 ok(result, "CryptAcquireContextA with CRYPT_MACHINE_KEYSET failed: %08lx\n", GetLastError());
3472 CryptReleaseContext(prov,0);
3475 ok(result, "CryptAcquireContextA with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08lx\n",
3476 GetLastError());
3480 "Expected NTE_BAD_KEYSET, got %08lx\n", GetLastError());
3481
3482}
3483
3484static void test_key_permissions(void)
3485{
3486 HCRYPTKEY hKey1, hKey2;
3487 DWORD dwVal, dwLen;
3488 BOOL result;
3489
3490 /* Create keys that are exportable */
3492 return;
3493
3495 ok (result, "%08lx\n", GetLastError());
3496
3497 dwVal = 0xdeadbeef;
3498 dwLen = sizeof(DWORD);
3499 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
3500 ok(result, "%08lx\n", GetLastError());
3502 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT got %08lx\n", dwVal);
3503
3504 /* The key exchange key's public key may be exported.. */
3505 result = CryptExportKey(hKey1, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);
3506 ok(result, "%08lx\n", GetLastError());
3507 /* and its private key may be too. */
3508 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
3509 ok(result, "%08lx\n", GetLastError());
3510 /* Turning off the key's export permissions is "allowed".. */
3511 dwVal &= ~CRYPT_EXPORT;
3512 result = CryptSetKeyParam(hKey1, KP_PERMISSIONS, (BYTE *)&dwVal, 0);
3513 ok(result, "%08lx\n", GetLastError());
3514 /* but it has no effect. */
3515 dwVal = 0xdeadbeef;
3516 dwLen = sizeof(DWORD);
3517 result = CryptGetKeyParam(hKey1, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
3518 ok(result, "%08lx\n", GetLastError());
3520 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT got %08lx\n", dwVal);
3521 /* Thus, changing the export flag of the key doesn't affect whether the key
3522 * may be exported.
3523 */
3524 result = CryptExportKey(hKey1, 0, PRIVATEKEYBLOB, 0, NULL, &dwLen);
3525 ok(result, "%08lx\n", GetLastError());
3526
3528 ok (result, "%08lx\n", GetLastError());
3529
3530 /* A subsequent get of the same key, into a different handle, also doesn't
3531 * show that the permissions have been changed.
3532 */
3533 dwVal = 0xdeadbeef;
3534 dwLen = sizeof(DWORD);
3535 result = CryptGetKeyParam(hKey2, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0);
3536 ok(result, "%08lx\n", GetLastError());
3538 "expected CRYPT_MAC|CRYPT_WRITE|CRYPT_READ|CRYPT_EXPORT|CRYPT_DECRYPT|CRYPT_ENCRYPT got %08lx\n", dwVal);
3539
3540 CryptDestroyKey(hKey2);
3541 CryptDestroyKey(hKey1);
3542
3544}
3545
3547{
3548 DWORD dwLen;
3549 HCRYPTPROV prov1, prov2;
3550 HCRYPTKEY hKeyExchangeKey, hSessionKey, hKey;
3551 BOOL result;
3552 static BYTE abSessionKey[148] = {
3553 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
3554 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
3555 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
3556 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
3557 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
3558 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
3559 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
3560 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
3561 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
3562 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
3563 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
3564 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
3565 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
3566 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
3567 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
3568 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
3569 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
3570 0x04, 0x8c, 0x49, 0x92
3571 };
3572
3573 /* Like init_base_environment, but doesn't generate new keys, as they'll
3574 * be imported instead.
3575 */
3577 {
3580 ok(result, "CryptAcquireContextA failed: %08lx\n", GetLastError());
3581 }
3582 dwLen = sizeof(abPlainPrivateKey);
3583 result = CryptImportKey(prov1, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
3584 ok(result, "CryptImportKey failed: %08lx\n", GetLastError());
3585
3586 dwLen = sizeof(abSessionKey);
3587 result = CryptImportKey(prov1, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
3588 ok(result, "CryptImportKey failed: %08lx\n", GetLastError());
3589
3590 /* Once the key has been imported, subsequently acquiring a context with
3591 * the same name will allow retrieving the key.
3592 */
3594 ok(result, "CryptAcquireContextA failed: %08lx\n", GetLastError());
3596 ok(result, "CryptGetUserKey failed: %08lx\n", GetLastError());
3598 CryptReleaseContext(prov2, 0);
3599
3600 CryptDestroyKey(hSessionKey);
3601 CryptDestroyKey(hKeyExchangeKey);
3602 CryptReleaseContext(prov1, 0);
3605}
3606
3607static void test_key_derivation(const char *prov)
3608{
3610 HCRYPTHASH hHash;
3611 BOOL result;
3612 unsigned char pbData[128], dvData[512];
3613 DWORD i, j, len, mode;
3614 struct
3615 {
3616 ALG_ID crypt_algo, hash_algo;
3617 int blocklen, hashlen, chain_mode;
3618 DWORD errorkey;
3619 const char *expected_hash, *expected_enc;
3620 } tests[] = {
3621 /* ================================================================== */
3622 { CALG_DES, CALG_MD2, 8, 16, CRYPT_MODE_CBC, 0,
3623 "\xBA\xBF\x93\xAE\xBC\x77\x45\xAA\x7E\x45\x69\xE5\x90\xE6\x04\x7F",
3624 "\x5D\xDA\x25\xA6\xB5\xC4\x43\xFB",
3625 /* 0 */
3626 },
3628 "\xDA\x4A\x9F\x5D\x2E\x7A\x3A\x4B\xBF\xDE\x47\x5B\x06\x84\x48\xA7",
3629 "\x6B\x18\x3B\xA1\x89\x27\xBF\xD4",
3630 /* 1 */
3631 },
3632 { CALG_3DES, CALG_MD2, 8, 16, CRYPT_MODE_CBC, 0,
3633 "\x38\xE5\x2E\x95\xA4\xA3\x73\x88\xF8\x1F\x87\xB7\x74\xB1\xA1\x56",
3634 "\x91\xAB\x17\xE5\xDA\x27\x11\x7D",
3635 /* 2 */
3636 },
3637 { CALG_RC2, CALG_MD2, 8, 16, CRYPT_MODE_CBC, 0,
3638 "\x7D\xA4\xB1\x10\x43\x26\x76\xB1\x0D\xB6\xE6\x9C\xA5\x8B\xCB\xE6",
3639 "\x7D\x45\x3D\x56\x00\xD7\xD1\x54",
3640 /* 3 */
3641 },
3642 { CALG_RC4, CALG_MD2, 4, 16, 0, 0,
3643 "\xFF\x32\xF1\x69\x62\xDE\xEB\x53\x8C\xFF\xA6\x92\x58\xA8\x22\xEA",
3644 "\xA9\x83\x73\xA9",
3645 /* 4 */
3646 },
3647 { CALG_RC5, CALG_MD2, 0, 16, 0, NTE_BAD_ALGID,
3648 "\x8A\xF2\xA3\xDA\xA5\x9A\x8B\x42\x4C\xE0\x2E\x00\xE5\x1E\x98\xE4",
3649 NULL,
3650 /* 5 */
3651 },
3652 { CALG_RSA_SIGN, CALG_MD2, 0, 16, 0, NTE_BAD_ALGID,
3653 "\xAE\xFE\xD6\xA5\x3E\x4B\xAC\xFA\x0E\x92\xC4\xC0\x06\xC9\x2B\xFD",
3654 NULL,
3655 /* 6 */
3656 },
3658 "\x30\xF4\xBC\x33\x93\xF3\x58\x19\xD1\x2B\x73\x4A\x92\xC7\xFC\xD7",
3659 NULL,
3660 /* 7 */
3661 },
3662 { CALG_AES, CALG_MD2, 0, 16, 0, NTE_BAD_ALGID,
3663 "\x07\x3B\x12\xE9\x96\x93\x85\xD7\xEC\xF4\xB1\xAC\x89\x2D\xC6\x9A",
3664 NULL,
3665 /* 8 */
3666 },
3668 "\xD2\x37\xE2\x49\xEB\x99\x23\xDA\x3E\x88\x55\x7E\x04\x5E\x15\x5D",
3669 "\xA1\x64\x3F\xFE\x99\x7F\x24\x13\x0C\xA9\x03\xEF\x9B\xC8\x1F\x2A",
3670 /* 9 */
3671 },
3673 "\x3E\x74\xED\xBF\x23\xAB\x03\x09\xBB\xD3\xE3\xAB\xCA\x12\x72\x7F",
3674 "\x5D\xEC\xF8\x72\xB2\xA6\x4D\x5C\xEA\x38\x9E\xF0\x86\xB6\x79\x34",
3675 /* 10 */
3676 },
3678 "\xBE\x9A\xE8\xF6\xCE\x79\x86\x5C\x1B\x01\x96\x4E\x5A\x8D\x09\x33",
3679 "\xD9\x4B\xC2\xE3\xCA\x89\x8B\x94\x0D\x87\xBB\xA2\xE8\x3D\x5C\x62",
3680 /* 11 */
3681 },
3682 /* ================================================================== */
3683 { CALG_DES, CALG_MD4, 8, 16, CRYPT_MODE_CBC, 0,
3684 "\xE8\x2F\x96\xC4\x6C\xC1\x91\xB4\x78\x40\x56\xD8\xA0\x25\xF5\x71",
3685 "\x21\x5A\xBD\x26\xB4\x3E\x86\x04",
3686 /* 12 */
3687 },
3689 "\x23\xBB\x6F\xE4\xB0\xF6\x35\xB6\x89\x2F\xEC\xDC\x06\xA9\xDF\x35",
3690 "\x9B\xE5\xD1\xEB\x8F\x13\x0B\xB3",
3691 /* 13 */
3692 },
3693 { CALG_3DES, CALG_MD4, 8, 16, CRYPT_MODE_CBC, 0,
3694 "\xE4\x72\x48\xC6\x6E\x38\x2F\x00\xC9\x2D\x01\x12\xB7\x8B\x64\x09",
3695 "\x7D\x5E\xAA\xEA\x10\xA4\xA4\x44",
3696 /* 14 */
3697 },
3698 { CALG_RC2, CALG_MD4, 8, 16, CRYPT_MODE_CBC, 0,
3699 "\xBF\x54\xDA\x3A\x56\x72\x0D\x9F\x30\x7D\x2F\x54\x13\xB2\xD7\xC6",
3700 "\x77\x42\x0E\xD2\x60\x29\x6F\x68",
3701 /* 15 */
3702 },
3703 { CALG_RC4, CALG_MD4, 4, 16, 0, 0,
3704 "\x9B\x74\x6D\x22\x11\x16\x05\x50\xA3\x75\x6B\xB2\x38\x8C\x2B\xC6",
3705 "\x5C\x7E\x99\x84",
3706 /* 16 */
3707 },
3708 { CALG_RC5, CALG_MD4, 0, 16, 0, NTE_BAD_ALGID,
3709 "\x51\xA8\x29\x8D\xE0\x36\xC1\xD3\x5E\x6A\x51\x4F\xE1\x65\xEE\xF1",
3710 NULL,
3711 /* 17 */
3712 },
3713 { CALG_RSA_SIGN, CALG_MD4, 0, 16, 0, NTE_BAD_ALGID,
3714 "\xA6\x83\x13\x4C\xB1\xAA\x06\x16\xE6\x4E\x7F\x0B\x8D\x19\xF5\x45",
3715 NULL,
3716 /* 18 */
3717 },
3719 "\x04\x24\xC8\x64\x98\x84\xE3\x3A\x7B\x9C\x50\x3E\xE7\xC4\x89\x82",
3720 NULL,
3721 /* 19 */
3722 },
3723 { CALG_AES, CALG_MD4, 0, 16, 0, NTE_BAD_ALGID,
3724 "\xF6\xEF\x81\xF8\xF2\xA3\xF6\x11\xFE\xA4\x7D\xC1\xD2\xF7\x7C\xDC",
3725 NULL,
3726 /* 20 */
3727 },
3729 "\xFF\xE9\x69\xFF\xC1\xDB\x08\xD4\x5B\xC8\x51\x71\x38\xEF\x8A\x5B",
3730 "\x8A\x24\xD0\x7A\x03\xE7\xA7\x02\xF2\x17\x4C\x01\xD5\x0E\x7F\x12",
3731 /* 21 */
3732 },
3734 "\x12\x01\xDD\x25\xBA\x8F\x1B\xCB\x7B\xAD\x3F\xDF\xB2\x68\x4F\x6A",
3735 "\xA9\x56\xBC\xA7\x97\x4E\x28\xAA\x4B\xE1\xA0\x6C\xE2\x43\x2C\x61",
3736 /* 22 */
3737 },
3739 "\x69\x08\x9F\x76\xD7\x9A\x93\x6F\xC7\x51\xA4\x00\xCF\x5A\xBB\x3D",
3740 "\x04\x07\xEA\xD9\x89\x0A\xD2\x65\x12\x13\x68\x9A\xD0\x86\x15\xED",
3741 /* 23 */
3742 },
3743 /* ================================================================== */
3744 { CALG_DES, CALG_MD5, 8, 16, CRYPT_MODE_CBC, 0,
3745 "\xEA\x01\x47\xA0\x7F\x96\x44\x6B\x0D\x95\x2C\x97\x4B\x28\x1C\x86",
3746 "\xF3\x75\xCC\x7C\x6C\x0B\xCF\x93",
3747 /* 24 */
3748 },
3750 "\xD2\xA2\xD7\x87\x32\x29\xF9\xE0\x45\x0D\xEC\x8D\xB5\xBC\x8A\xD9",
3751 "\x51\x70\xE0\xB7\x00\x0D\x3E\x21",
3752 /* 25 */
3753 },
3754 { CALG_3DES, CALG_MD5, 8, 16, CRYPT_MODE_CBC, 0,
3755 "\x2B\x36\xA2\x85\x85\xC0\xEC\xBE\x04\x56\x1D\x97\x8E\x82\xDB\xD8",
3756 "\x58\x23\x75\x25\x3F\x88\x25\xEB",
3757 /* 26 */
3758 },
3759 { CALG_RC2, CALG_MD5, 8, 16, CRYPT_MODE_CBC, 0,
3760 "\x3B\x89\x72\x3B\x8A\xD1\x2E\x13\x44\xD6\xD0\x97\xE6\xB8\x46\xCD",
3761 "\x90\x1C\x77\x45\x87\xDD\x1C\x2E",
3762 /* 27 */
3763 },
3764 { CALG_RC4, CALG_MD5, 4, 16, 0, 0,
3765 "\x00\x6D\xEF\xB1\xC8\xC6\x25\x5E\x45\x4F\x4E\x3D\xAF\x9C\x53\xD2",
3766 "\xC4\x4C\xD2\xF1",
3767 /* 28 */
3768 },
3769 { CALG_RC5, CALG_MD5, 0, 16, 0, NTE_BAD_ALGID,
3770 "\x56\x49\xDC\xBA\x32\xC6\x0D\x84\xE9\x2D\x42\x8C\xD6\x7C\x4A\x7A",
3771 NULL,
3772 /* 29 */
3773 },
3774 { CALG_RSA_SIGN, CALG_MD5, 0, 16, 0, NTE_BAD_ALGID,
3775 "\xDF\xD6\x3A\xE6\x3E\x8D\xB4\x17\x9F\x29\xF0\xFD\x6D\x98\x98\xAD",
3776 NULL,
3777 /* 30 */
3778 },
3780 "\xD4\x4D\x60\x9A\x39\x27\x88\xB7\xD7\xB4\x34\x2F\x92\x61\x3C\xA8",
3781 NULL,
3782 /* 31 */
3783 },
3784 { CALG_AES, CALG_MD5, 0, 16, 0, NTE_BAD_ALGID,
3785 "\xF4\x83\x2E\x02\xDE\xAE\x46\x1F\xE1\x31\x65\x03\x08\x58\xE0\x7D",
3786 NULL,
3787 /* 32 */
3788 },
3790 "\x0E\xA0\x40\x72\x55\xE5\x4C\xEB\x79\xCB\x48\xC3\xD1\xB1\xD0\xF4",
3791 "\x97\x66\x92\x02\x6D\xEC\x33\xF8\x4E\x82\x11\x20\xC7\xE2\xE6\xE8",
3792 /* 33 */
3793 },
3795 "\x3F\x91\x5E\x09\x19\x11\x14\x27\xCA\x6A\x20\x24\x3E\xF0\x02\x3E",
3796 "\x9B\xDA\x73\xF4\xF3\x06\x93\x07\xC9\x32\xF1\xD8\xD4\x96\xD1\x7D",
3797 /* 34 */
3798 },
3800 "\x27\x51\xD8\xB3\xC7\x14\x66\xE1\x99\xC3\x5C\x9C\x90\xF5\xE5\x94",
3801 "\x2A\x0F\xE9\xA9\x6F\x53\x7C\x9E\x07\xE6\xC3\xC9\x15\x99\x7C\xA8",
3802 /* 35 */
3803 },
3804 /* ================================================================== */
3805 { CALG_DES, CALG_SHA1, 8, 20, CRYPT_MODE_CBC, 0,
3806 "\xC1\x91\xF6\x5A\x81\x87\xAC\x6D\x48\x7C\x78\xF7\xEC\x37\xE2\x0C\xEC\xF7\xC0\xB8",
3807 "\xD4\xD8\xAA\x44\xAC\x5E\x0B\x8D",
3808 /* 36 */
3809 },
3811 "\x5D\x9B\xC3\x99\xC4\x73\x90\x78\xCB\x51\x6B\x61\x8A\xBE\x1A\xF3\x7A\x90\xF3\x34",
3812 "\xD8\x1C\xBC\x6C\x92\xD3\x09\xBF",
3813 /* 37 */
3814 },
3815 { CALG_3DES, CALG_SHA1, 8, 20, CRYPT_MODE_CBC, 0,
3816 "\x90\xB8\x01\x89\xEC\x9A\x6C\xAD\x1E\xAC\xB3\x17\x0A\x44\xA2\x4D\x80\xA5\x25\x97",
3817 "\xBD\x58\x5A\x88\x98\xF8\x69\x9A",
3818 /* 38 */
3819 },
3820 { CALG_RC2, CALG_SHA1, 8, 20, CRYPT_MODE_CBC, 0,
3821 "\x42\xBD\xB8\xF2\xB5\xC2\x28\x64\x85\x98\x8E\x49\xE6\xDC\x92\x80\xCD\xC1\x63\x00",
3822 "\xCC\xFB\x1A\x4D\x29\xAD\x3E\x65",
3823 /* 39 */
3824 },
3825 { CALG_RC4, CALG_SHA1, 4, 20, 0, 0,
3826 "\x67\x36\xE9\x57\x5E\xCD\x56\x5E\x8B\x25\x35\x23\x74\xBA\x20\x46\xD0\x21\xDE\x0A",
3827 "\x7A\x34\x3D\x3C",
3828 /* 40 */
3829 },
3830 { CALG_RC5, CALG_SHA1, 0, 20, 0, NTE_BAD_ALGID,
3831 "\x5F\x29\xA5\xA4\x10\x08\x56\x15\x92\xF9\x55\x3B\x4B\xF5\xAB\xBD\xE7\x4D\x47\x28",
3832 NULL,
3833 /* 41 */
3834 },
3836 "\xD3\xB7\xF8\xB9\xBE\x67\xD1\xFE\x10\x51\x23\x3B\x7D\xB7\x61\xF5\xA7\x1A\x02\x5E",
3837 NULL,
3838 /* 42 */
3839 },
3841 "\x09\x68\x97\x23\x11\x2B\x6A\x71\xBA\x33\x60\x43\xEE\xC9\x9B\xB7\x8F\x8A\x2E\x33",
3842 NULL,
3843 /* 43 */
3844 },
3845 { CALG_AES, CALG_SHA1, 0, 20, 0, NTE_BAD_ALGID,
3846 "\xCF\x28\x23\x83\x62\x87\x43\xF6\x50\x57\xED\x54\xEC\x93\x5E\xEC\x0E\xD3\x23\x9A",
3847 NULL,
3848 /* 44 */
3849 },
3851 "\x81\xC1\x7E\x42\xC3\x07\x1F\x5E\xF8\x75\xA3\x5A\xFC\x0B\x61\xBA\x0B\xD8\x53\x0D",
3852 "\x39\xCB\xAF\xD7\x8B\x75\x4A\x3B\xD2\x0E\x0D\xB1\x64\x57\x88\x58",
3853 /* 45 */
3854 },
3856 "\x93\xA7\xE8\x9E\x96\xB5\x97\x23\xD0\x58\x44\x8C\x4D\xBB\xAB\xB6\x3E\x1F\x2C\x1D",
3857 "\xA9\x13\x83\xCA\x21\xA2\xF0\xBE\x13\xBC\x55\x04\x38\x08\xA9\xC4",
3858 /* 46 */
3859 },
3861 "\x15\x6A\xB2\xDF\x32\x57\x14\x69\x09\x07\xAD\x24\x83\xA1\x74\x47\x41\x72\x69\xBC",
3862 "\xE1\x6C\xA8\x54\x0E\x24\x67\x6D\xCA\xA2\xFE\x84\xF0\x9B\x78\x66",
3863 /* 47 */
3864 },
3865 /* ================================================================== */
3866 { CALG_DES, CALG_SHA_256, 8, 32, CRYPT_MODE_CBC, 0,
3867 "\x20\x34\xf7\xbb\x7a\x3a\x79\xf0\xb9\x65\x18\x11\xaa\xfd\x26\x6b"
3868 "\x60\x5c\x6d\x4c\x81\x7c\x3f\xc4\xce\x94\xe3\x67\xdf\xf2\x16\xd8",
3869 "\x86\x0d\x8c\xf4\xc0\x22\x4a\xdd",
3870 /* 48 */
3871 },
3873 "\x09\x6e\x7f\xd5\xf2\x72\x4e\x18\x70\x09\xc1\x35\xf4\xd1\x3a\xe8"
3874 "\xe6\x1f\x91\xae\x2f\xfd\xa8\x8c\xce\x47\x0f\x7a\xf5\xef\xfd\xbe",
3875 "\x2d\xe7\x63\xf6\x58\x4d\x9a\xa6",
3876 /* 49 */
3877 },
3879 "\x54\x7f\x84\x7f\xfe\x83\xc6\x50\xbc\xd9\x92\x78\x32\x67\x50\x7d"
3880 "\xdf\x44\x55\x7d\x87\x74\xd2\x56\xff\xd9\x74\x44\xd5\x07\x9e\xdc",
3881 "\x20\xaa\x66\xd0\xac\x83\x9d\x99",
3882 /* 50 */
3883 },
3884 { CALG_RC2, CALG_SHA_256, 8, 32, CRYPT_MODE_CBC, 0,
3885 "\xc6\x22\x46\x15\xa1\x27\x38\x23\x91\xf2\x29\xda\x15\xc9\x5d\x92"
3886 "\x7c\x34\x4a\x1f\xb0\x8a\x81\xd6\x17\x09\xda\x52\x1f\xb9\x64\x60",
3887 "\x8c\x01\x19\x47\x7e\xd2\x10\x2c",
3888 /* 51 */
3889 },
3890 { CALG_RC4, CALG_SHA_256, 4, 32, 0, 0,
3891 "\xcd\x53\x95\xa6\xb6\x6e\x25\x92\x78\xac\xe6\x7e\xfc\xd3\x8d\xaa"
3892 "\xc3\x15\x83\xb5\xe6\xaf\xf9\x32\x4c\x17\xb8\x82\xdf\xc0\x45\x9e",
3893 "\xfa\x54\x13\x9c",
3894 /* 52 */
3895 },
3896 { CALG_RC5, CALG_SHA_256, 0, 32, 0, NTE_BAD_ALGID,
3897 "\x2a\x3b\x08\xe1\xec\xa7\x04\xf9\xc9\x42\x74\x9a\x82\xad\x99\xd2"
3898 "\x10\x51\xe3\x51\x6c\x67\xa4\xf2\xca\x99\x21\x43\xdf\xa0\xfc\xa1",
3899 NULL,
3900 /* 53 */
3901 },
3903 "\x10\x1d\x36\xc7\x38\x73\xc3\x80\xf0\x7a\x4e\x25\x52\x8a\x5c\x3f"
3904 "\xfc\x41\xa7\xe5\x20\xed\xd5\x1d\x00\x6e\x77\xf4\xa7\x71\x81\x6b",
3905 NULL,
3906 /* 54 */
3907 },
3909 "\x0a\x74\xde\x4f\x07\xce\x73\xd6\xd9\xa3\xba\xbb\x7c\x98\xe1\x94"
3910 "\x13\x93\xb1\xfd\x26\x31\x4b\xfc\x61\x27\xef\x4d\xd0\x48\x76\x67",
3911 NULL,
3912 /* 55 */
3913 },
3914 { CALG_AES, CALG_SHA_256, 0, 32, 0, NTE_BAD_ALGID,
3915 "\xf0\x13\xbc\x25\x2a\x2f\xba\xf1\x39\xe5\x7d\xb8\x5f\xaa\xd0\x19"
3916 "\xbd\x1c\xd8\x7b\x39\x5a\xb3\x85\x84\x80\xbd\xe0\x4a\x65\x03\xdd",
3917 NULL,
3918 /* 56 */
3919 },
3921 "\xc8\xc2\x6f\xe2\xbe\xa7\x38\x87\x04\xc7\x39\xcb\x9f\x57\xfc\xde"
3922 "\x14\x81\x46\xa4\xbb\xa7\x0f\x01\x1d\xc2\x6d\x7a\x43\x5f\x38\xc3",
3923 "\xf8\x75\xc6\x71\x8b\xb6\x54\xd3\xdc\xff\x0e\x84\x8a\x3f\x19\x46",
3924 /* 57 */
3925 },
3927 "\xb7\x3a\x43\x0f\xea\x90\x4f\x0f\xb9\x82\xf6\x1e\x07\xc4\x25\x4e"
3928 "\xdb\xe7\xf7\x1d\x7c\xd0\xe5\x51\xd8\x1b\x97\xc8\xc2\x46\xb9\xfe",
3929 "\x35\xf2\x20\xc7\x6c\xb2\x8e\x51\x3e\xc7\x6b\x3e\x64\xa5\x05\xdf",
3930 /* 58 */
3931 },
3933 "\xbd\xcc\x0c\x59\x99\x29\xa7\x24\xf3\xdc\x20\x40\x4e\xe8\xe5\x48"
3934 "\xdd\x27\x0e\xdf\x7e\x50\x65\x17\x34\x50\x47\x78\x9a\x23\x1b\x40",
3935 "\x8c\xeb\x1f\xd3\x78\x77\xf5\xbf\x7a\xde\x8d\x2c\xa5\x16\xcc\xe9",
3936 /* 59 */
3937 },
3938 };
3939 int old_broken[ARRAY_SIZE(tests)];
3940 memset(old_broken, 0, sizeof(old_broken));
3941 old_broken[3] = old_broken[4] = old_broken[15] = old_broken[16] = 1;
3942 old_broken[27] = old_broken[28] = old_broken[39] = old_broken[40] = 1;
3943 old_broken[48] = old_broken[49] = old_broken[50] = old_broken[51] = 1;
3944 old_broken[52] = old_broken[53] = old_broken[54] = old_broken[55] = 1;
3945 old_broken[56] = old_broken[57] = old_broken[58] = old_broken[59] = 1;
3947
3948 for (i=0; i < ARRAY_SIZE(tests); i++)
3949 {
3950 if (old_broken[i]) continue;
3951
3952 for (j=0; j<sizeof(dvData); j++) dvData[j] = (unsigned char)j+i;
3953 SetLastError(0xdeadbeef);
3954 result = CryptCreateHash(hProv, tests[i].hash_algo, 0, 0, &hHash);
3955 ok(result, "Test [%s %ld]: CryptCreateHash failed with error 0x%08lx\n", prov, i, GetLastError());
3956 if (!result)
3957 {
3958 /* not supported by provider */
3959 trace("hash %x not supported\n", tests[i].hash_algo);
3960 ok(GetLastError() == NTE_BAD_ALGID, "Test [%s %ld]: Expected NTE_BAD_ALGID, got 0x%08lx\n",
3961 prov, i, GetLastError());
3962 continue;
3963 }
3964 result = CryptHashData(hHash, dvData, sizeof(dvData), 0);
3965 ok(result, "Test [%s %ld]: CryptHashData failed with error 0x%08lx\n", prov, i, GetLastError());
3966
3967 len = sizeof(pbData);
3969 ok(result, "Test [%s %ld]: CryptGetHashParam failed with error 0x%08lx\n", prov, i, GetLastError());
3970 ok(len == tests[i].hashlen, "Test [%s %ld]: Expected hash len %d, got %ld\n",
3971 prov, i, tests[i].hashlen, len);
3972 ok(!tests[i].hashlen || !memcmp(pbData, tests[i].expected_hash, tests[i].hashlen),
3973 "Test [%s %ld]: Hash comparison failed\n", prov, i);
3974
3975 SetLastError(0xdeadbeef);
3976 result = CryptDeriveKey(hProv, tests[i].crypt_algo, hHash, 0, &hKey);
3977 /* the provider may not support the algorithm */
3978 if(!result && GetLastError() == tests[i].errorkey) goto err;
3979 ok(result, "Test [%s %ld]: CryptDeriveKey failed with error 0x%08lx\n", prov, i, GetLastError());
3980
3981 len = sizeof(mode);
3982 mode = 0xdeadbeef;
3984 ok(result, "Test [%s %ld]: CryptGetKeyParam failed with error %08lx\n", prov, i, GetLastError());
3985 ok(mode == tests[i].chain_mode, "Test [%s %ld]: Expected chaining mode %d, got %ld\n",
3986 prov, i, tests[i].chain_mode, mode);
3987
3988 SetLastError(0xdeadbeef);
3989 len = 4;
3990 result = CryptEncrypt(hKey, 0, TRUE, 0, dvData, &len, sizeof(dvData));
3991 ok(result, "Test [%s %ld]: CryptEncrypt failed with error 0x%08lx\n", prov, i, GetLastError());
3992 ok(len == tests[i].blocklen, "Test [%s %ld]: Expected block len %d, got %ld\n",
3993 prov, i, tests[i].blocklen, len);
3994 ok(!memcmp(dvData, tests[i].expected_enc, tests[i].blocklen),
3995 "Test [%s %ld]: Encrypted data comparison failed\n", prov, i);
3996
3998err:
3999 CryptDestroyHash(hHash);
4000 }
4001}
4002
4003static void test_rc2_import(void)
4004{
4005 static const DWORD test_lengths[] = { 128 + 8, 256, 512, 1024 };
4006 static const DWORD mac_results[ARRAY_SIZE(test_lengths)][2] =
4007 {
4008 {0xc13650cf, 0xa3e93efb},
4009 {0x6f7be248, 0x444b38b2},
4010 {0x2c3534d2, 0x29fca10c},
4011 {0x2c3534d2, 0x29fca10c},
4012 };
4013 static const DWORD mac_baseprov_results[ARRAY_SIZE(test_lengths)][2] =
4014 {
4015 {0x7e94a244, 0x12a9ae17},
4016 {0x2aaa6719, 0xa671d9a6},
4017 {0x2e730ce2, 0x9ebe6016},
4018 {0x2e730ce2, 0x9ebe6016},
4019 };
4020 static const DWORD mac_results_old[ARRAY_SIZE(test_lengths)][2] =
4021 {
4022 {0xebe2155a, 0xab2f58b7},
4023 {0x4394ccb2, 0xbe5c629b},
4024 {0xd7bc2195, 0x63fb2785},
4025 {0xd7bc2195, 0x63fb2785},
4026 };
4027 static const DWORD mac_baseprov_results_old[ARRAY_SIZE(test_lengths)][2] =
4028 {
4029 {0xe2ed2dec, 0x5ae837ed},
4030 {0x12f4b193, 0xe3f6afc1},
4031 {0x04d7f905, 0x686d357b},
4032 {0x04d7f905, 0x686d357b},
4033 };
4034 static const DWORD hmac_results[ARRAY_SIZE(test_lengths)][4] =
4035 {
4036 {0x2f44586d, 0x76d04c9f, 0xdae8fc03, 0x27e870bd},
4037 {0xbcde3186, 0xd9892cd5, 0x578c89f5, 0xc2cba8e5},
4038 {0xad2bf1cc, 0xae4e2c1f, 0xd1599a67, 0x0167d802},
4039 {0x6ee75968, 0x52a0eff5, 0x75340d85, 0x87b64962},
4040 };
4041 static const DWORD decrypt_baseprov_results[ARRAY_SIZE(test_lengths)][2] =
4042 {
4043 {0x48c4ff05, 0x9d880b90},
4044 {0xcfee0629, 0xfeab04a1},
4045 {0x23c9336c, 0x7f67b26e},
4046 {0x23c9336c, 0x7f67b26e},
4047 };
4048 static const DWORD decrypt_results[ARRAY_SIZE(test_lengths)][2] =
4049 {
4050 {0xb37e1be2, 0x1ed67048},
4051 {0x7c7d0b04, 0x3a74bb76},
4052 {0x7bfd232c, 0x93d52c4f},
4053 {0x7bfd232c, 0x93d52c4f},
4054 };
4055
4056 struct key_blob
4057 {
4058 BLOBHEADER h;
4059 union
4060 {
4061 DWORD key_size;
4062 DWORD alg_id;
4063 } param;
4064 BYTE data[512];
4065 }
4066 key_data;
4067 const DWORD *results, *broken_results;
4068 HCRYPTKEY exchange_key, key;
4071 BYTE data[2048];
4072 HCRYPTPROV prov;
4074 unsigned int i;
4075 HMAC_INFO hmac;
4076 BOOL ret;
4077
4079 ok(ret, "Failed, error %#lx.\n", GetLastError());
4080
4081 /* CryptGenKey() favours advertised key length limit. */
4082 ret = CryptGenKey(prov, CALG_RC2, 128 << 16, &key);
4083 ok(ret, "Failed, error %#lx.\n", GetLastError());
4084
4086
4087 ret = CryptGenKey(prov, CALG_RC2, (128 + 8) << 16, &key);
4088 ok(!ret, "Expected failure.\n");
4089
4090 CryptReleaseContext(prov, 0);
4091
4092 ret = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &exchange_key);
4093 ok(ret, "CryptGetUserKey failed.\n");
4094
4095 memset(&key_data.h, 0, sizeof(key_data.h));
4096 key_data.h.bVersion = CUR_BLOB_VERSION;
4097 key_data.h.aiKeyAlg = CALG_RC2;
4098
4099 for (i = 0; i < ARRAY_SIZE(test_lengths); ++i)
4100 {
4101 memset(key_data.data, 0xcc, sizeof(key_data.data));
4102 test_length = test_lengths[i];
4103 winetest_push_context("length %lu", test_length);
4104 len = min(test_length / 8, 64);
4105
4106
4107 ret = CryptEncrypt(exchange_key, 0, TRUE, 0, key_data.data, &len, sizeof(key_data) - 12);
4108 ok(ret, "Failed, error %#lx.\n", GetLastError());
4109 memset(key_data.data + len, 0xee, sizeof(key_data.data) - len);
4110
4111 /* Importing a larger key as plaintext fails. */
4112 key_data.h.bType = PLAINTEXTKEYBLOB;
4113 key_data.param.key_size = test_length / 8;
4114 ret = CryptImportKey(hProv, (BYTE *)&key_data, offsetof(struct key_blob, data[test_length / 8]), 0, 0, &key);
4115 ok(!ret, "Expected failure.\n");
4116
4117 /* Importing a larger key as SIMPLEBLOB succeeds. */
4118 key_data.h.bType = SIMPLEBLOB;
4119 key_data.param.alg_id = CALG_RSA_KEYX;
4120 ret = CryptImportKey(hProv, (BYTE *)&key_data, offsetof(struct key_blob, data[len]),
4121 exchange_key, 0, &key);
4122 ok(ret, "Failed, error %#lx.\n", GetLastError());
4123
4124 /* Effective key length is a public key decrypted length except for the base provider
4125 * where it is default length. */
4126 len = sizeof(value);
4127 value = 0xdeadbeef;
4129 ok(ret, "Failed, error %#lx.\n", GetLastError());
4131 expected = min(expected, 512);
4132 ok(value == expected, "Unexpected value %lu, expected %lu.\n", value, expected);
4133
4134 expected = min(test_length, 512);
4136 ok(ret, "Failed, error %#lx.\n", GetLastError());
4137 ok(value == expected, "Unexpected value %lu, expected %lu.\n", value, expected);
4138
4139 /* The resulting key is not good for encryption. */
4140 memset(data, 0xcc, 8);
4141 len = 8;
4142 ret = CryptEncrypt(key, 0, FALSE, 0, data, &len, sizeof(data));
4143 ok(!ret, "Expected failure.\n");
4144 ok(GetLastError() == NTE_BAD_KEY, "Unexpected error %#lx.\n", GetLastError());
4145 len = 8;
4146 ret = CryptEncrypt(key, 0, TRUE, 0, data, &len, sizeof(data));
4147 ok(!ret, "Expected failure.\n");
4148 ok(GetLastError() == NTE_BAD_KEY, "Unexpected error %#lx.\n", GetLastError());
4149 /* But decryption works. */
4150 len = 8;
4151 ret = CryptDecrypt(key, 0, FALSE, 0, data, &len);
4152 ok(ret, "Failed, error %#lx.\n", GetLastError());
4153 ok(len == 8, "Unexpected len %lu.\n", len);
4154 results = BASE_PROV ? decrypt_baseprov_results[i] : decrypt_results[i];
4155 ok(!memcmp(data, results, len), "Data does not match.\n");
4156
4158 ok(ret, "Failed, error %#lx.\n", GetLastError());
4159
4160 data[0] = 0;
4161 ret = CryptHashData(hash, data, 1, 0);
4162 ok(ret, "Failed, error %#lx.\n", GetLastError());
4163
4164 len = sizeof(value);
4166 ok(ret, "Failed, error %#lx.\n", GetLastError());
4167 ok(value == 8, "Unexpected value %lu.\n", value);
4168
4169 len = 32;
4170 memset(data, 0xcc, 8);
4172 ok(ret, "Failed, error %#lx.\n", GetLastError());
4173 ok(len == 8, "Unexpected len %lu.\n", len);
4174
4175 results = BASE_PROV ? mac_baseprov_results[i] : mac_results[i];
4176 broken_results = BASE_PROV ? mac_baseprov_results_old[i] : mac_results_old[i];
4177 /* Hash state is affected by key state before Win8. */
4178 ok(!memcmp(data, results, len) || broken(!memcmp(data, broken_results, len)), "Hash does not match.\n");
4179
4181
4183 ok(ret, "Failed, error %#lx.\n", GetLastError());
4184 memset(&hmac, 0, sizeof(hmac));
4185 hmac.HashAlgid = CALG_MD5;
4186 memset(data, 0, sizeof(data));
4187 hmac.pbInnerString = data;
4189 hmac.pbOuterString = data;
4191
4192 ret = CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&hmac, 0);
4193 ok(ret, "Failed, error %#lx.\n", GetLastError());
4194
4195 data[0] = 0;
4196 ret = CryptHashData(hash, data, 1, 0);
4197 ok(ret, "Failed, error %#lx.\n", GetLastError());
4198
4199 len = sizeof(value);
4201 ok(ret, "Failed, error %#lx.\n", GetLastError());
4202 ok(value == 16, "Unexpected value %lu.\n", value);
4203
4204 len = 16;
4206 ok(ret, "Failed, error %#lx.\n", GetLastError());
4207 ok(len == 16, "Unexpected len %lu.\n", len);
4208
4209 ok(!memcmp(data, hmac_results[i], len), "Hash does not match.\n");
4210
4214 }
4215 CryptDestroyKey(exchange_key);
4216}
4217
4218static const BYTE PRIVATE_EXCH_blob[308] = {
42190x07,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
42200x01,0x00,0x01,0x00,0x55,0x7b,0x36,0x13,0xae,0x4b,0xc9,0x6f,0x78,0x1e,0xff,0x38,
42210xd4,0x26,0x38,0x77,0x89,0x9b,0xf6,0x6b,0xf7,0xaa,0xea,0xad,0x27,0x11,0x1e,0xa5,
42220x98,0x23,0xcb,0xaa,0x32,0x34,0xaf,0x19,0xd8,0x24,0x95,0xe4,0xae,0x4e,0x03,0x1d,
42230x75,0xeb,0xec,0xc1,0x09,0xd0,0x02,0xed,0x1f,0x0e,0xcf,0x23,0xce,0xe9,0x09,0x34,
42240xe3,0xc9,0xb9,0xbb,0xef,0x59,0x26,0xab,0xf5,0x11,0xdb,0x8d,0x0f,0x07,0xaf,0x53,
42250x5c,0xaf,0xcd,0x8c,0xa2,0xaf,0x4e,0x3e,0xc9,0xe8,0x02,0x69,0x4b,0x87,0x1f,0xe1,
42260x62,0x65,0x0a,0xf8,0xfb,0x92,0xce,0x69,0xcc,0xea,0x86,0x41,0x43,0xe8,0x4a,0x41,
42270x75,0xf0,0xb6,0x17,0x64,0xa1,0x0e,0x52,0xd3,0x4c,0xdf,0x6f,0xa8,0x15,0x57,0x7c,
42280x00,0xeb,0xbf,0xc1,0x69,0xfe,0x6d,0x50,0x55,0x89,0xfe,0x8a,0x1c,0x14,0x60,0xff,
42290x5a,0xe6,0x80,0x22,0xa0,0xfc,0xe9,0x5f,0xa4,0x48,0xbb,0xc1,0xf0,0x4f,0xba,0x57,
42300xeb,0x83,0xe9,0xe9,0x21,0x23,0x9a,0x83,0x71,0xd7,0x2e,0xb9,0x88,0x24,0x37,0x6b,
42310x1d,0x73,0xcb,0x64,0xa4,0x6d,0xcf,0xed,0xbb,0x65,0x4c,0xf7,0xcc,0x86,0xf8,0x94,
42320x40,0x61,0xb2,0x09,0x2e,0xea,0xb7,0xa2,0x1d,0xc2,0x4b,0x37,0x5d,0xc1,0x54,0xdf,
42330x45,0x16,0x16,0xe1,0x08,0x6b,0xad,0x51,0xbf,0x62,0x0c,0xe0,0xe5,0x22,0x65,0xc5,
42340x6a,0xca,0xc7,0xb0,0x49,0x48,0xae,0x6b,0x27,0x86,0xe8,0xe9,0x90,0x15,0x38,0x4f,
42350x7f,0x3b,0x9e,0x38,0xd1,0x25,0x62,0x91,0xfe,0x18,0x08,0x79,0xcc,0x7c,0xaf,0x41,
42360x8d,0xd1,0xa1,0xd3,0x63,0x3c,0xb0,0x7b,0x2d,0xda,0x6f,0x72,0x9c,0xd1,0xa8,0xaa,
42370xb5,0x6a,0xde,0xed,0x00,0x0a,0x39,0xe9,0xc6,0x45,0x7a,0x39,0x6d,0x07,0x86,0xa9,
42380xe5,0x4f,0xb4,0x9b };
4239static const BYTE PUBLIC_EXCH_blob[84] = {
42400x06,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x31,0x00,0x02,0x00,0x00,
42410x01,0x00,0x01,0x00,0x55,0x7b,0x36,0x13,0xae,0x4b,0xc9,0x6f,0x78,0x1e,0xff,0x38,
42420xd4,0x26,0x38,0x77,0x89,0x9b,0xf6,0x6b,0xf7,0xaa,0xea,0xad,0x27,0x11,0x1e,0xa5,
42430x98,0x23,0xcb,0xaa,0x32,0x34,0xaf,0x19,0xd8,0x24,0x95,0xe4,0xae,0x4e,0x03,0x1d,
42440x75,0xeb,0xec,0xc1,0x09,0xd0,0x02,0xed,0x1f,0x0e,0xcf,0x23,0xce,0xe9,0x09,0x34,
42450xe3,0xc9,0xb9,0xbb };
4246
4247static void test_RC4_salt(void)
4248{
4249 static const BYTE zero[11];
4250 static const struct
4251 {
4252 const char *prov;
4253 DWORD flags, key_length, salt_length;
4254 } td[] =
4255 {
4256 { MS_DEF_PROV_A, 0, 0, 11 },
4257 { MS_DEF_PROV_A, 0, 40, 11 },
4258 { MS_DEF_PROV_A, CRYPT_NO_SALT, 40, 0 },
4259 { MS_DEF_PROV_A, 0, 56, 0 },
4260 { MS_DEF_PROV_A, CRYPT_CREATE_SALT, 56, 11 },
4261 { MS_ENHANCED_PROV_A, 0, 0, 0 },
4262 { MS_ENHANCED_PROV_A, 0, 40, 11 },
4267 };
4268 HCRYPTPROV hprov;
4269 HCRYPTKEY hkey, hkeyx;
4271 void *blob;
4272 BYTE salt[16];
4274 BOOL ret;
4275
4276 for (i = 0; i < ARRAY_SIZE(td); i++)
4277 {
4278 winetest_push_context("%lu", i);
4279
4281 ok(ret, "error %#lx\n", GetLastError());
4282
4283 ret = CryptGenKey(hprov, CALG_RC4, (td[i].key_length << 16) | td[i].flags | CRYPT_EXPORTABLE, &hkey);
4284 ok(ret, "error %#lx\n", GetLastError());
4285
4286 size = sizeof(key_length);
4287 ret = CryptGetKeyParam(hkey, KP_KEYLEN, (BYTE *)&key_length, &size, 0);
4288 ok(ret, "error %#lx\n", GetLastError());
4289 if (!strcmp(td[i].prov, MS_DEF_PROV_A))
4290 ok(key_length == (td[i].key_length ? td[i].key_length : 40), "got %lu, expected %lu\n", key_length, td[i].key_length);
4291 else
4292 ok(key_length == (td[i].key_length ? td[i].key_length : 128), "got %lu, expected %lu\n", key_length, td[i].key_length);
4293
4294 size = 0xdeadbeef;
4295 ret = CryptGetKeyParam(hkey, KP_SALT, NULL, &size, 0);
4296 ok(ret, "error %#lx\n", GetLastError());
4297 todo_wine_if(i == 4 || i == 9)
4298 ok(size == td[i].salt_length, "got %lu, expected %lu\n", size, td[i].salt_length);
4299 if (size)
4300 {
4301 ret = CryptGetKeyParam(hkey, KP_SALT, salt, &size, 0);
4302 ok(ret, "error %#lx\n", GetLastError());
4303 if (td[i].flags & CRYPT_CREATE_SALT)
4304 ok(memcmp(salt, zero, size) != 0, "wrong salt %.11s\n", salt);
4305 else
4306 ok(memcmp(salt, zero, size) == 0, "wrong salt %.11s\n", salt);
4307 }
4308
4309 memcpy(salt, (const BYTE *)"0123456789A", 11);
4310 data.pbData = salt;
4311 data.cbData = 11;
4312 ret = CryptSetKeyParam(hkey, KP_SALT_EX, (BYTE *)&data, 0);
4313 ok(ret, "error %#lx\n", GetLastError());
4314
4315 ret = CryptImportKey(hprov, PUBLIC_EXCH_blob, sizeof(PUBLIC_EXCH_blob), 0, 0, &hkeyx);
4316 ok(ret, "error %#lx\n", GetLastError());
4317
4318 ret = CryptExportKey(hkey, hkeyx, SIMPLEBLOB, 0, NULL, &blob_size);
4319 ok(ret, "error %#lx\n", GetLastError());
4321 ret = CryptExportKey(hkey, hkeyx, SIMPLEBLOB, 0, blob, &blob_size);
4322 ok(ret, "error %#lx\n", GetLastError());
4323
4324 CryptDestroyKey(hkey);
4325 CryptDestroyKey(hkeyx);
4326 CryptReleaseContext(hprov, 0);
4327
4329 ok(ret, "error %#lx\n", GetLastError());
4330
4331 ret = CryptImportKey(hprov, PRIVATE_EXCH_blob, sizeof(PRIVATE_EXCH_blob), 0, 0, &hkeyx);
4332 ok(ret, "error %#lx\n", GetLastError());
4333
4334 ret = CryptImportKey(hprov, blob, blob_size, hkeyx, 0, &hkey);
4335 ok(ret, "error %#lx\n", GetLastError());
4336 size = 0xdeadbeef;
4337 ret = CryptGetKeyParam(hkey, KP_SALT, NULL, &size, 0);
4338 ok(ret, "error %#lx\n", GetLastError());
4339 if ((!strcmp(td[i].prov, MS_DEF_PROV_A) && !td[i].key_length) || td[i].key_length == 40)
4340 ok(size == 11, "got %lu, expected 11\n", size);
4341 else
4342 ok(size == 0, "got %lu, expected 0\n", size);
4343 ret = CryptGetKeyParam(hkey, KP_SALT, salt, &size, 0);
4344 ok(ret, "error %#lx\n", GetLastError());
4345 ok(!memcmp(salt, zero, size), "wrong salt %.11s\n", salt);
4346
4347 free(blob);
4348 CryptDestroyKey(hkey);
4349 CryptDestroyKey(hkeyx);
4350 CryptReleaseContext(hprov, 0);
4351
4353 }
4354}
4355
4356static void test_RC4_session_key(void)
4357{
4358 static const BYTE zero[11];
4359 static const char hello_world[12] = "Hello World!";
4360 BYTE data[sizeof(hello_world)], salt[11];
4361 HCRYPTPROV hprov;
4362 HCRYPTKEY hkey, hkeyx;
4364 void *blob;
4365 BOOL ret;
4366
4368 ok(ret, "error %#lx\n", GetLastError());
4369
4370 /* Client: Generate session key */
4371 ret = CryptGenKey(hprov, CALG_RC4, CRYPT_EXPORTABLE, &hkey);
4372 ok(ret, "error %#lx\n", GetLastError());
4373 size = 0xdeadbeef;
4374 ret = CryptGetKeyParam(hkey, KP_SALT, NULL, &size, 0);
4375 ok(ret, "error %#lx\n", GetLastError());
4376 ok(size == 11, "got %lu\n", size);
4377 ret = CryptGetKeyParam(hkey, KP_SALT, salt, &size, 0);
4378 ok(ret, "error %#lx\n", GetLastError());
4379 ok(!memcmp(salt, zero, size), "wrong salt %.11s\n", salt);
4380
4381 /* Client: Import the server's public key */
4382 ret = CryptImportKey(hprov, PUBLIC_EXCH_blob, sizeof(PUBLIC_EXCH_blob), 0, 0, &hkeyx);
4383 ok(ret, "error %#lx\n", GetLastError());
4384
4385 /* Client: Export encrypted session key using the server's public key */
4386 ret = CryptExportKey(hkey, hkeyx, SIMPLEBLOB, 0, NULL, &blob_size);
4387 ok(ret, "error %#lx\n", GetLastError());
4389 ret = CryptExportKey(hkey, hkeyx, SIMPLEBLOB, 0, blob, &blob_size);
4390 ok(ret, "error %#lx\n", GetLastError());
4391
4392 /* Client: Encrypt data using the session key */
4393 size = sizeof(hello_world);
4395 ret = CryptEncrypt(hkey, 0, TRUE, 0, data, &size, size);
4396 ok(ret, "error %#lx\n", GetLastError());
4397
4398 CryptDestroyKey(hkeyx);
4399 CryptDestroyKey(hkey);
4400 CryptReleaseContext(hprov, 0);
4401
4403 ok(ret, "error %#lx\n", GetLastError());
4404
4405 /* Server: Use the server's private key */
4406 ret = CryptImportKey(hprov, PRIVATE_EXCH_blob, sizeof(PRIVATE_EXCH_blob), 0, 0, &hkeyx);
4407 ok(ret, "error %#lx\n", GetLastError());
4408
4409 /* Server: Import encrypted session key using the server's private key */
4410 ret = CryptImportKey(hprov, blob, blob_size, hkeyx, 0, &hkey);
4411 ok(ret, "error %#lx\n", GetLastError());
4412 size = 0xdeadbeef;
4413 ret = CryptGetKeyParam(hkey, KP_SALT, NULL, &size, 0);
4414 ok(ret, "error %#lx\n", GetLastError());
4415 ok(size == 11, "got %lu\n", size);
4416 ret = CryptGetKeyParam(hkey, KP_SALT, salt, &size, 0);
4417 ok(ret, "error %#lx\n", GetLastError());
4418 ok(!memcmp(salt, zero, size), "wrong salt %.11s\n", salt);
4419
4420 /* Server: Decrypt data using the session key */
4421 size = sizeof(hello_world);
4422 ret = CryptDecrypt(hkey, 0, TRUE, 0, data, &size);
4423 ok(ret, "error %#lx\n", GetLastError());
4424 ok(size == sizeof(hello_world), "got %lu\n", size);
4425 ok(!memcmp(data, hello_world, size), "wrong data\n");
4426
4427 free(blob);
4428 CryptDestroyKey(hkey);
4429 CryptDestroyKey(hkeyx);
4430 CryptReleaseContext(hprov, 0);
4431}
4432
4433/* RSA key with public exponent 1 */
4434static const BYTE rsa_blob[] =
4435{
4436 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00, 0x02, 0x00, 0x00,
4437 0x01, 0x00, 0x00, 0x00, 0xab, 0xef, 0xfa, 0xc6, 0x7d, 0xe8, 0xde, 0xfb, 0x68, 0x38, 0x09, 0x92,
4438 0xd9, 0x42, 0x7e, 0x6b, 0x89, 0x9e, 0x21, 0xd7, 0x52, 0x1c, 0x99, 0x3c, 0x17, 0x48, 0x4e, 0x3a,
4439 0x44, 0x02, 0xf2, 0xfa, 0x74, 0x57, 0xda, 0xe4, 0xd3, 0xc0, 0x35, 0x67, 0xfa, 0x6e, 0xdf, 0x78,
4440 0x4c, 0x75, 0x35, 0x1c, 0xa0, 0x74, 0x49, 0xe3, 0x20, 0x13, 0x71, 0x35, 0x65, 0xdf, 0x12, 0x20,
4441 0xf5, 0xf5, 0xf5, 0xc1, 0xed, 0x5c, 0x91, 0x36, 0x75, 0xb0, 0xa9, 0x9c, 0x04, 0xdb, 0x0c, 0x8c,
4442 0xbf, 0x99, 0x75, 0x13, 0x7e, 0x87, 0x80, 0x4b, 0x71, 0x94, 0xb8, 0x00, 0xa0, 0x7d, 0xb7, 0x53,
4443 0xdd, 0x20, 0x63, 0xee, 0xf7, 0x83, 0x41, 0xfe, 0x16, 0xa7, 0x6e, 0xdf, 0x21, 0x7d, 0x76, 0xc0,
4444 0x85, 0xd5, 0x65, 0x7f, 0x00, 0x23, 0x57, 0x45, 0x52, 0x02, 0x9d, 0xea, 0x69, 0xac, 0x1f, 0xfd,
4445 0x3f, 0x8c, 0x4a, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4446 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4447 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4448 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4449 0x00, 0x00, 0x00, 0x00, 0x64, 0xd5, 0xaa, 0xb1, 0xa6, 0x03, 0x18, 0x92, 0x03, 0xaa, 0x31, 0x2e,
4450 0x48, 0x4b, 0x65, 0x20, 0x99, 0xcd, 0xc6, 0x0c, 0x15, 0x0c, 0xbf, 0x3e, 0xff, 0x78, 0x95, 0x67,
4451 0xb1, 0x74, 0x5b, 0x60, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4452 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4453 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4454 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4455 0x00, 0x00, 0x00, 0x00,
4456};
4457
4458static void test_pubexp(void)
4459{
4460 static const BYTE modulus[] =
4461 {
4462 0xab, 0xef, 0xfa, 0xc6, 0x7d, 0xe8, 0xde, 0xfb, 0x68, 0x38, 0x09, 0x92, 0xd9, 0x42, 0x7e, 0x6b,
4463 0x89, 0x9e, 0x21, 0xd7, 0x52, 0x1c, 0x99, 0x3c, 0x17, 0x48, 0x4e, 0x3a, 0x44, 0x02, 0xf2, 0xfa,
4464 0x74, 0x57, 0xda, 0xe4, 0xd3, 0xc0, 0x35, 0x67, 0xfa, 0x6e, 0xdf, 0x78, 0x4c, 0x75, 0x35, 0x1c,
4465 0xa0, 0x74, 0x49, 0xe3, 0x20, 0x13, 0x71, 0x35, 0x65, 0xdf, 0x12, 0x20, 0xf5, 0xf5, 0xf5, 0xc1,
4466 };
4467 static const BYTE prime1[] =
4468 {
4469 0xed, 0x5c, 0x91, 0x36, 0x75, 0xb0, 0xa9, 0x9c, 0x04, 0xdb, 0x0c, 0x8c, 0xbf, 0x99, 0x75, 0x13,
4470 0x7e, 0x87, 0x80, 0x4b, 0x71, 0x94, 0xb8, 0x00, 0xa0, 0x7d, 0xb7, 0x53, 0xdd, 0x20, 0x63, 0xee,
4471 };
4472 static const BYTE prime2[] =
4473 {
4474 0xf7, 0x83, 0x41, 0xfe, 0x16, 0xa7, 0x6e, 0xdf, 0x21, 0x7d, 0x76, 0xc0, 0x85, 0xd5, 0x65, 0x7f,
4475 0x00, 0x23, 0x57, 0x45, 0x52, 0x02, 0x9d, 0xea, 0x69, 0xac, 0x1f, 0xfd, 0x3f, 0x8c, 0x4a, 0xd0,
4476 };
4477 static const BYTE exp1[] =
4478 {
4479 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4480 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4481 };
4482 static const BYTE exp2[] =
4483 {
4484 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4485 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4486 };
4487 static const BYTE coeff[] =
4488 {
4489 0x64, 0xd5, 0xaa, 0xb1, 0xa6, 0x03, 0x18, 0x92, 0x03, 0xaa, 0x31, 0x2e, 0x48, 0x4b, 0x65, 0x20,
4490 0x99, 0xcd, 0xc6, 0x0c, 0x15, 0x0c, 0xbf, 0x3e, 0xff, 0x78, 0x95, 0x67, 0xb1, 0x74, 0x5b, 0x60,
4491 };
4492 static const BYTE priv_exp[] =
4493 {
4494 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4495 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4496 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4497 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4498 };
4499
4500 BOOL ret;
4501 HCRYPTPROV hprov;
4502 HCRYPTKEY hkey;
4503 BYTE buf[512];
4504 DWORD size;
4506 RSAPUBKEY *pub_key = (RSAPUBKEY *)(header + 1);
4507 char *p = (char *)(pub_key + 1);
4508
4510 ok(ret, "got %#lx\n", GetLastError());
4511
4512 ret = CryptImportKey(hprov, rsa_blob, sizeof(rsa_blob), 0, CRYPT_EXPORTABLE, &hkey);
4513 ok(ret, "got %#lx\n", GetLastError());
4514
4515 size = sizeof(buf);
4516 ret = CryptExportKey(hkey, 0, PRIVATEKEYBLOB, 0, buf, &size);
4517 ok(ret, "got %#lx\n", GetLastError());
4518 ok(size == 308, "unexpected size: %ld\n", size);
4519
4520 ok(pub_key->bitlen == 512, "bitlen = %lx\n", pub_key->bitlen);
4521 ok(pub_key->pubexp == 1, "pubexp = %lx\n", pub_key->pubexp);
4522 ok(!memcmp(p, modulus, sizeof(modulus)), "modulus = %s\n", debugstr_an(p, sizeof(modulus)));
4523 p += sizeof(modulus);
4524 ok(!memcmp(p, prime1, sizeof(prime1)), "prime1 = %s\n", debugstr_an(p, sizeof(prime1)));
4525 p += sizeof(prime1);
4526 ok(!memcmp(p, prime2, sizeof(prime2)), "prime2 = %s\n", debugstr_an(p, sizeof(prime2)));
4527 p += sizeof(prime2);
4528 ok(!memcmp(p, exp1, sizeof(exp1)), "exp1 = %s\n", debugstr_an(p, sizeof(exp1)));
4529 p += sizeof(exp1);
4530 ok(!memcmp(p, exp2, sizeof(exp2)), "exp2 = %s\n", debugstr_an(p, sizeof(exp2)));
4531 p += sizeof(exp2);
4532 ok(!memcmp(p, coeff, sizeof(coeff)), "coeff = %s\n", debugstr_an(p, sizeof(coeff)));
4533 p += sizeof(coeff);
4534 ok(!memcmp(p, priv_exp, sizeof(priv_exp)), "priv_exp = %s\n", debugstr_an(p, sizeof(priv_exp)));
4535 p += sizeof(priv_exp);
4536
4537 CryptDestroyKey(hkey);
4538 CryptReleaseContext(hprov, 0);
4539}
4540
4541static void test_pp_provtype(void)
4542{
4543 /* `PP_PROVTYPE` must return the provider type the caller opened the
4544 * provider with. This matters because PFXImportCertStore reads
4545 * `PP_PROVTYPE` and writes it into the cert's
4546 * `CRYPT_KEY_PROV_INFO.dwProvType`; a later `CryptAcquireContext`
4547 * using that value must find the same container. */
4548 static const struct
4549 {
4550 const char *prov_name;
4551 DWORD prov_type;
4552 } providers[] =
4553 {
4559 };
4560 DWORD i;
4561
4562 for (i = 0; i < ARRAY_SIZE(providers); i++)
4563 {
4564 HCRYPTPROV hprov;
4565 DWORD got, len = sizeof(got);
4566 BOOL ret;
4567
4568 ret = CryptAcquireContextA(&hprov, NULL, providers[i].prov_name,
4569 providers[i].prov_type, CRYPT_VERIFYCONTEXT);
4570 ok(ret, "%s: CryptAcquireContextA failed: %#lx\n",
4571 providers[i].prov_name, GetLastError());
4572 if (!ret) continue;
4573
4574 got = 0;
4575 ret = CryptGetProvParam(hprov, PP_PROVTYPE, (BYTE *)&got, &len, 0);
4576 ok(ret, "%s: CryptGetProvParam(PP_PROVTYPE) failed: %#lx\n",
4577 providers[i].prov_name, GetLastError());
4578 ok(len == sizeof(got), "%s: wrong PP_PROVTYPE size %lu\n",
4579 providers[i].prov_name, len);
4580 ok(got == providers[i].prov_type,
4581 "%s: PP_PROVTYPE = %lu, expected %lu\n",
4582 providers[i].prov_name, got, providers[i].prov_type);
4583
4584 CryptReleaseContext(hprov, 0);
4585 }
4586}
4587
4589{
4590 test_RC4_salt();
4592
4593 for (iProv = 0; iProv < ARRAY_SIZE(szProviders); iProv++)
4594 {
4596 continue;
4597 trace("Testing '%s'\n", szProviders[iProv]);
4598 test_prov();
4600 test_hashes();
4601 test_rc4();
4602 test_rc2();
4603 test_des();
4604 if(!BASE_PROV)
4605 {
4606 test_3des112();
4607 test_3des();
4608 }
4609 if(ENHANCED_PROV)
4610 {
4612 }
4613 test_hmac();
4615 test_mac();
4622 if(!BASE_PROV) test_key_derivation(STRONG_PROV ? "STRONG" : "ENH");
4625 }
4626
4632 if (!init_aes_environment())
4633 return;
4634 trace("Testing AES provider.\n");
4635 test_aes(128);
4636 test_aes(192);
4637 test_aes(256);
4641 test_sha2();
4643 test_key_derivation("AES");
4645 test_pubexp();
4648}
static struct _test_info results[8]
Definition: SetCursorPos.c:31
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define ARRAY_SIZE(A)
Definition: main.h:20
BYTE exp2[512/16]
Definition: bcrypt.c:2641
BYTE prime1[512/16]
Definition: bcrypt.c:2638
BYTE prime2[512/16]
Definition: bcrypt.c:2639
static void test_aes(void)
Definition: bcrypt.c:602
static UCHAR salt[]
Definition: bcrypt.c:495
BYTE exp1[512/16]
Definition: bcrypt.c:2640
chain_mode
Definition: bcrypt_main.c:118
alg_id
Definition: bcrypt_main.c:55
#define RegCloseKey(hKey)
Definition: registry.h:49
#define sha256
Definition: compat-1.3.h:2272
int putchar(int c)
Definition: crtsupp.c:12
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3298
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4009
BOOL WINAPI CryptExportKey(HCRYPTKEY hKey, HCRYPTKEY hExpKey, DWORD dwBlobType, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen)
Definition: crypt.c:1383
BOOL WINAPI CryptCreateHash(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, DWORD dwFlags, HCRYPTHASH *phHash)
Definition: crypt.c:715
BOOL WINAPI CryptGenRandom(HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer)
Definition: crypt.c:684
BOOL WINAPI CryptGetHashParam(HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags)
Definition: crypt.c:1584
BOOL WINAPI CryptDestroyKey(HCRYPTKEY hKey)
Definition: crypt.c:911
BOOL WINAPI CryptDestroyHash(HCRYPTHASH hHash)
Definition: crypt.c:875
BOOL WINAPI CryptSignHashA(HCRYPTHASH hHash, DWORD dwKeySpec, LPCSTR sDescription, DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen)
Definition: crypt.c:1910
BOOL WINAPI CryptDuplicateKey(HCRYPTKEY hKey, DWORD *pdwReserved, DWORD dwFlags, HCRYPTKEY *phKey)
Definition: crypt.c:1007
BOOL WINAPI CryptVerifySignatureA(HCRYPTHASH hHash, const BYTE *pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey, LPCSTR sDescription, DWORD dwFlags)
Definition: crypt.c:2238
BOOL WINAPI CryptReleaseContext(HCRYPTPROV hProv, DWORD dwFlags)
Definition: crypt.c:641
BOOL WINAPI CryptDuplicateHash(HCRYPTHASH hHash, DWORD *pdwReserved, DWORD dwFlags, HCRYPTHASH *phHash)
Definition: crypt.c:950
BOOL WINAPI CryptHashData(HCRYPTHASH hHash, const BYTE *pbData, DWORD dwDataLen, DWORD dwFlags)
Definition: crypt.c:1745
BOOL WINAPI CryptAcquireContextA(HCRYPTPROV *phProv, LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
Definition: crypt.c:571
BOOL WINAPI CryptDeriveKey(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData, DWORD dwFlags, HCRYPTKEY *phKey)
Definition: crypt.c:822
BOOL WINAPI CryptGenKey(HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKEY *phKey)
Definition: crypt.c:1423
BOOL WINAPI CryptDecrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen)
Definition: crypt.c:780
BOOL WINAPI CryptGetUserKey(HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUserKey)
Definition: crypt.c:1694
BOOL WINAPI CryptGetKeyParam(HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags)
Definition: crypt.c:1626
BOOL WINAPI CryptSetKeyParam(HCRYPTKEY hKey, DWORD dwParam, const BYTE *pbData, DWORD dwFlags)
Definition: crypt.c:1977
BOOL WINAPI CryptSetHashParam(HCRYPTHASH hHash, DWORD dwParam, const BYTE *pbData, DWORD dwFlags)
Definition: crypt.c:1941
BOOL WINAPI CryptGetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags)
Definition: crypt.c:1667
BOOL WINAPI CryptEncrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen)
Definition: crypt.c:1071
BOOL WINAPI CryptImportKey(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey)
Definition: crypt.c:1820
static struct list providers
Definition: sip.c:532
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
GUID guid
Definition: version.c:147
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1597
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3324
return ret
Definition: mutex.c:147
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define printf
Definition: freeldr.h:103
FxAutoRegKey hKey
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLbitfield flags
Definition: glext.h:7161
GLenum mode
Definition: glext.h:6217
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint64EXT * result
Definition: glext.h:11304
GLfloat GLfloat p
Definition: glext.h:8902
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define dup
Definition: syshdrs.h:51
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
int winetest_debug
#define win_skip
Definition: minitest.h:67
#define todo_wine_if(is_todo)
Definition: minitest.h:81
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl void winetest_pop_context(void)
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl winetest_push_context(const char *fmt,...) __WINE_PRINTF_ATTR(1
Definition: test.h:539
#define todo_wine
Definition: minitest.h:80
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static struct test_info tests[]
#define sprintf
Definition: sprintf.c:45
#define key_length
Definition: crypt.c:1100
BOOL expected
Definition: store.c:2000
UINT blob_size
Definition: effect.c:1153
static const char pub_key[]
Definition: custom.c:1705
static void test_length(void)
Definition: schema.c:820
static int iProv
Definition: rsaenh.c:35
static const BYTE rsa_blob[]
Definition: rsaenh.c:4434
static const char szContainer[]
Definition: rsaenh.c:36
static void test_key_permissions(void)
Definition: rsaenh.c:3484
static void test_mac(void)
Definition: rsaenh.c:1992
static void trace_hex(BYTE *pbData, DWORD dwLen)
Definition: rsaenh.c:103
static BYTE abPlainPrivateKey[596]
Definition: rsaenh.c:286
#define STRONG_PROV
Definition: rsaenh.c:41
static void test_import_private(void)
Definition: rsaenh.c:2090
static void test_null_provider(void)
Definition: rsaenh.c:3248
#define ENHANCED_PROV
Definition: rsaenh.c:39
static void test_gen_random(void)
Definition: rsaenh.c:247
static void test_rc4(void)
Definition: rsaenh.c:1606
static HCRYPTPROV hProv
Definition: rsaenh.c:33
struct _ctdatatype cryptdata
static void test_pubexp(void)
Definition: rsaenh.c:4458
static void test_rc2(void)
Definition: rsaenh.c:1326
static BYTE signBlob[]
Definition: rsaenh.c:3226
static void test_hmac(void)
Definition: rsaenh.c:1752
static void test_enum_container(void)
Definition: rsaenh.c:3198
static void test_verify_signature(void)
Definition: rsaenh.c:2173
static void test_prov(void)
Definition: rsaenh.c:231
static const cryptdata cTestData[4]
Definition: rsaenh.c:51
static void test_des(void)
Definition: rsaenh.c:850
static void test_rsa_round_trip(void)
Definition: rsaenh.c:3139
static void test_RC4_salt(void)
Definition: rsaenh.c:4247
static const char * szProvider
Definition: rsaenh.c:37
static void uniquecontainer(char *unique)
Definition: rsaenh.c:73
static void test_block_cipher_modes(void)
Definition: rsaenh.c:649
static void test_aes_duplicate_key(int keylen)
Definition: rsaenh.c:1047
static void clean_up_base_environment(void)
Definition: rsaenh.c:158
static void test_import_export(void)
Definition: rsaenh.c:2581
static void printBytes(const char *heading, const BYTE *pb, size_t cb)
Definition: rsaenh.c:94
static const BYTE PRIVATE_EXCH_blob[308]
Definition: rsaenh.c:4218
static void test_rsa_encrypt(void)
Definition: rsaenh.c:2444
static void clean_up_aes_environment(void)
Definition: rsaenh.c:221
static const BYTE PUBLIC_EXCH_blob[84]
Definition: rsaenh.c:4239
static void test_pp_provtype(void)
Definition: rsaenh.c:4541
static void test_3des112(void)
Definition: rsaenh.c:765
static void test_key_derivation(const char *prov)
Definition: rsaenh.c:3607
static void test_import_hmac(void)
Definition: rsaenh.c:2836
static void test_RC4_session_key(void)
Definition: rsaenh.c:4356
static void test_3des(void)
Definition: rsaenh.c:962
static BOOL init_base_environment(const char *provider, DWORD dwKeyFlags)
Definition: rsaenh.c:119
static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
Definition: rsaenh.c:264
static void test_sha2(void)
Definition: rsaenh.c:1224
static void test_rc2_import(void)
Definition: rsaenh.c:4003
static const char * szProviders[]
Definition: rsaenh.c:34
static BOOL init_aes_environment(void)
Definition: rsaenh.c:175
#define BASE_PROV
Definition: rsaenh.c:40
static void test_schannel_provider(void)
Definition: rsaenh.c:2945
static void test_key_initialization(void)
Definition: rsaenh.c:3546
static void test_hmac_info(void)
Definition: rsaenh.c:1800
static void test_hashes(void)
Definition: rsaenh.c:364
#define min(a, b)
Definition: monoChain.cc:55
algid
#define KEY_READ
Definition: nt_native.h:1026
#define DWORD
Definition: nt_native.h:44
BYTE * PBYTE
Definition: pedump.c:66
static const WCHAR szName[]
Definition: powrprof.c:45
#define err(...)
#define offsetof(TYPE, MEMBER)
#define memset(x, y, z)
Definition: compat.h:39
int zero
Definition: sehframes.cpp:29
BYTE * pbData
Definition: wincrypt.h:112
DWORD cbInnerString
Definition: wincrypt.h:105
BYTE * pbOuterString
Definition: wincrypt.h:106
DWORD cbOuterString
Definition: wincrypt.h:107
BYTE * pbInnerString
Definition: wincrypt.h:104
ALG_ID HashAlgid
Definition: wincrypt.h:103
DWORD bitlen
Definition: wincrypt.h:153
DWORD cBits
Definition: wincrypt.h:94
DWORD dwUse
Definition: wincrypt.h:92
DWORD dwReserved
Definition: wincrypt.h:96
DWORD dwFlags
Definition: wincrypt.h:95
ALG_ID Algid
Definition: wincrypt.h:93
unsigned char decstr[32]
Definition: rsaenh.c:45
int strlen
Definition: rsaenh.c:46
unsigned char origstr[32]
Definition: rsaenh.c:44
int enclen
Definition: rsaenh.c:47
int buflen
Definition: rsaenh.c:48
Definition: image.c:229
Definition: copy.c:22
SYMCRYPT_MAGIC_FIELD union @5329 td
PCBYTE pbData
void test_string()
Definition: test_string.cpp:38
unsigned char * LPBYTE
Definition: typedefs.h:53
Definition: pdh_main.c:64
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define PLAINTEXTKEYBLOB
Definition: wincrypt.h:2446
#define MS_DEF_PROV_A
Definition: wincrypt.h:2115
#define PP_KEYSTORAGE
Definition: wincrypt.h:2301
#define CALG_RC2
Definition: wincrypt.h:2083
#define CRYPT_USERDATA
Definition: wincrypt.h:4336
#define KP_BLOCKLEN
Definition: wincrypt.h:2339
#define CRYPT_NEWKEYSET
Definition: wincrypt.h:2274
#define HP_HASHSIZE
Definition: wincrypt.h:2388
#define KP_MODE
Definition: wincrypt.h:2335
#define PROV_RSA_FULL
Definition: wincrypt.h:2243
#define CRYPT_VERIFYCONTEXT
Definition: wincrypt.h:2273
#define CALG_AES_128
Definition: wincrypt.h:2087
#define CALG_SHA1
Definition: wincrypt.h:2060
#define PROV_RSA_SCHANNEL
Definition: wincrypt.h:2249
#define KP_IV
Definition: wincrypt.h:2332
#define CRYPT_DECRYPT
Definition: wincrypt.h:2400
#define CALG_SCHANNEL_MASTER_HASH
Definition: wincrypt.h:2098
#define CALG_AES_192
Definition: wincrypt.h:2088
#define CALG_RSA_SIGN
Definition: wincrypt.h:2069
#define CRYPT_MODE_CBC
Definition: wincrypt.h:2394
ULONG_PTR HCRYPTPROV
Definition: wincrypt.h:55
#define HP_TLS1PRF_SEED
Definition: wincrypt.h:2391
#define CALG_RC5
Definition: wincrypt.h:2093
#define CALG_SHA_384
Definition: wincrypt.h:2067
#define CALG_RC4
Definition: wincrypt.h:2091
#define KP_SALT
Definition: wincrypt.h:2333
#define KP_SCHANNEL_ALG
Definition: wincrypt.h:2351
#define CALG_MD5
Definition: wincrypt.h:2058
#define PP_KEYSET_TYPE
Definition: wincrypt.h:2309
#define PROV_RSA_AES
Definition: wincrypt.h:2260
unsigned int ALG_ID
Definition: wincrypt.h:54
#define KP_CLIENT_RANDOM
Definition: wincrypt.h:2352
#define KP_SERVER_RANDOM
Definition: wincrypt.h:2353
#define CALG_MAC
Definition: wincrypt.h:2061
#define CALG_SHA_256
Definition: wincrypt.h:2066
#define CRYPT_DELETEKEYSET
Definition: wincrypt.h:2275
#define PRIVATEKEYBLOB
Definition: wincrypt.h:2445
#define CRYPT_EXPORT
Definition: wincrypt.h:2401
#define CRYPT_NOHASHOID
Definition: wincrypt.h:2381
#define PP_KEYSPEC
Definition: wincrypt.h:2318
#define CALG_MD2
Definition: wincrypt.h:2056
#define AT_KEYEXCHANGE
Definition: wincrypt.h:2239
#define CALG_3DES_112
Definition: wincrypt.h:2085
#define CALG_AES
Definition: wincrypt.h:2090
#define PP_ENUMCONTAINERS
Definition: wincrypt.h:2287
#define CRYPT_CREATE_SALT
Definition: wincrypt.h:2412
#define CALG_SCHANNEL_MAC_KEY
Definition: wincrypt.h:2099
#define HP_TLS1PRF_LABEL
Definition: wincrypt.h:2390
#define CRYPT_ENCRYPT
Definition: wincrypt.h:2399
#define PUBLICKEYBLOB
Definition: wincrypt.h:2444
#define CRYPT_SERVER
Definition: wincrypt.h:2416
#define CRYPT_MODE_ECB
Definition: wincrypt.h:2395
#define KP_EFFECTIVE_KEYLEN
Definition: wincrypt.h:2350
#define CRYPT_FIRST
Definition: wincrypt.h:2264
#define KP_ALGID
Definition: wincrypt.h:2338
#define CALG_RSA_KEYX
Definition: wincrypt.h:2080
#define KP_MODE_BITS
Definition: wincrypt.h:2336
#define CALG_AES_256
Definition: wincrypt.h:2089
#define SCHANNEL_ENC_KEY
Definition: wincrypt.h:89
#define PP_UNIQUE_CONTAINER
Definition: wincrypt.h:2315
#define SIMPLEBLOB
Definition: wincrypt.h:2443
#define HP_HMAC_INFO
Definition: wincrypt.h:2389
ULONG_PTR HCRYPTKEY
Definition: wincrypt.h:58
#define PP_SIG_KEYSIZE_INC
Definition: wincrypt.h:2313
ULONG_PTR HCRYPTHASH
Definition: wincrypt.h:59
#define CALG_3DES
Definition: wincrypt.h:2084
#define CALG_MD4
Definition: wincrypt.h:2057
#define CRYPT_MODE_OFB
Definition: wincrypt.h:2396
#define PP_KEYX_KEYSIZE_INC
Definition: wincrypt.h:2314
#define MS_STRONG_PROV_A
Definition: wincrypt.h:2135
#define CRYPT_SEC_DESCR
Definition: wincrypt.h:2327
#define SCHANNEL_MAC_KEY
Definition: wincrypt.h:88
#define CALG_SSL3_SHAMD5
Definition: wincrypt.h:2062
#define CALG_SHA
Definition: wincrypt.h:2059
struct _PUBLICKEYSTRUC BLOBHEADER
#define CALG_TLS1PRF
Definition: wincrypt.h:2064
#define MS_DEF_RSA_SCHANNEL_PROV_A
Definition: wincrypt.h:2155
#define CRYPT_WRITE
Definition: wincrypt.h:2403
#define CRYPT_OAEP
Definition: wincrypt.h:2422
#define PP_CONTAINER
Definition: wincrypt.h:2291
#define CRYPT_READ
Definition: wincrypt.h:2402
#define CALG_DES
Definition: wincrypt.h:2082
#define PP_PROVTYPE
Definition: wincrypt.h:2300
#define MS_ENHANCED_PROV_A
Definition: wincrypt.h:2125
#define KP_KEYLEN
Definition: wincrypt.h:2340
#define AT_SIGNATURE
Definition: wincrypt.h:2240
#define CRYPT_MAC
Definition: wincrypt.h:2404
#define CRYPT_MODE_CFB
Definition: wincrypt.h:2397
#define KP_PERMISSIONS
Definition: wincrypt.h:2337
#define CALG_SHA_512
Definition: wincrypt.h:2068
#define KP_SALT_EX
Definition: wincrypt.h:2341
#define CRYPT_IPSEC_HMAC_KEY
Definition: wincrypt.h:100
#define CALG_SCHANNEL_ENC_KEY
Definition: wincrypt.h:2100
#define CALG_HMAC
Definition: wincrypt.h:2063
#define HP_HASHVAL
Definition: wincrypt.h:2387
#define CRYPT_EXPORTABLE
Definition: wincrypt.h:2410
#define CRYPT_MACHINE_KEYSET
Definition: wincrypt.h:2276
#define CRYPT_NO_SALT
Definition: wincrypt.h:2414
#define MS_ENH_RSA_AES_PROV_A
Definition: wincrypt.h:2217
#define CUR_BLOB_VERSION
Definition: wincrypt.h:2451
#define NTE_BAD_DATA
Definition: winerror.h:4252
#define NTE_BAD_ALGID
Definition: winerror.h:4255
#define NTE_BAD_PROV_TYPE
Definition: winerror.h:4267
#define NTE_NO_KEY
Definition: winerror.h:4260
#define NTE_BAD_HASH_STATE
Definition: winerror.h:4259
#define NTE_NOT_FOUND
Definition: winerror.h:4264
#define NTE_BAD_LEN
Definition: winerror.h:4251
#define NTE_BAD_SIGNATURE
Definition: winerror.h:4253
#define NTE_BAD_KEY
Definition: winerror.h:4249
#define NTE_BAD_KEYSET
Definition: winerror.h:4269
#define NTE_TEMPORARY_PROFILE
Definition: winerror.h:4283
#define NTE_PROV_TYPE_NOT_DEF
Definition: winerror.h:4270
#define NTE_BAD_FLAGS
Definition: winerror.h:4256
#define ERROR_INTERNAL_ERROR
Definition: winerror.h:1185
#define NTE_BAD_KEY_STATE
Definition: winerror.h:4258
static const char hello_world[]
Definition: winhttp.c:2308
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
unsigned char BYTE
Definition: xxhash.c:193