Release 0.9.61.
[wine/gsoc-2012-control.git] / dlls / rsaenh / tests / rsaenh.c
blob0119f287a57cc360ed0d8816dea24c10ae2551c8
1 /*
2 * Unit tests for rsaenh functions
4 * Copyright (c) 2004 Michael Jung
5 * Copyright (c) 2006 Juan Lang
6 * Copyright (c) 2007 Vijay Kiran Kamuju
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include <string.h>
24 #include <stdio.h>
25 #include "wine/test.h"
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winerror.h"
29 #include "wincrypt.h"
30 #include "winreg.h"
32 static HCRYPTPROV hProv;
33 static const char szContainer[] = "winetest";
34 static const char szProvider[] = MS_ENHANCED_PROV_A;
36 typedef struct _ctdatatype {
37 unsigned char origstr[32];
38 unsigned char decstr[32];
39 int strlen;
40 int enclen;
41 int buflen;
42 } cryptdata;
44 static const cryptdata cTestData[4] = {
45 {"abcdefghijkl",
46 {'a','b','c','d','e','f','g','h',0x2,0x2,'k','l',0},
47 12,8,16},
48 {"abcdefghij",
49 {'a','b','c','d','e','f','g','h',0x2,0x2,0},
50 10,8,16},
51 {"abcdefgh",
52 {'a','b','c','d','e','f','g','h',0},
53 8,8,16},
54 {"abcdefghijkl",
55 {'a','b','c','d','e','f','g','h','i','j','k','l',0},
56 12,12,16}
60 * 1. Take the MD5 Hash of the container name (with an extra null byte)
61 * 2. Turn the hash into a 4 DWORD hex value
62 * 3. Append a '_'
63 * 4. Add the MachineGuid
66 static void uniquecontainer(char *unique)
68 /* MD5 hash of "winetest\0" in 4 DWORD hex */
69 static const char szContainer_md5[] = "9d20fd8d05ed2b8455d125d0bf6d6a70";
70 static const char szCryptography[] = "Software\\Microsoft\\Cryptography";
71 static const char szMachineGuid[] = "MachineGuid";
72 HKEY hkey;
73 char guid[MAX_PATH];
74 DWORD size = MAX_PATH;
76 /* Get the MachineGUID */
77 RegOpenKeyA(HKEY_LOCAL_MACHINE, szCryptography, &hkey);
78 RegQueryValueExA(hkey, szMachineGuid, NULL, NULL, (LPBYTE)guid, &size);
79 RegCloseKey(hkey);
81 lstrcpy(unique, szContainer_md5);
82 lstrcat(unique, "_");
83 lstrcat(unique, guid);
86 static void printBytes(const char *heading, const BYTE *pb, size_t cb)
88 size_t i;
89 printf("%s: ",heading);
90 for(i=0;i<cb;i++)
91 printf("0x%02x,",pb[i]);
92 putchar('\n');
95 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
98 static void trace_hex(BYTE *pbData, DWORD dwLen) {
99 char szTemp[256];
100 DWORD i, j;
102 for (i = 0; i < dwLen-7; i+=8) {
103 sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
104 pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5],
105 pbData[i+6], pbData[i+7]);
106 trace(szTemp);
108 for (j=0; i<dwLen; j++,i++) {
109 sprintf(szTemp+6*j, "0x%02x, \n", pbData[i]);
111 trace(szTemp);
115 static int init_base_environment(void)
117 HCRYPTKEY hKey;
118 BOOL result;
120 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
122 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
124 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
125 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
127 if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
129 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
130 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
131 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL,
132 CRYPT_NEWKEYSET);
133 ok(result, "%08x\n", GetLastError());
134 if (!result) return 0;
135 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
136 ok(result, "%08x\n", GetLastError());
137 if (result) CryptDestroyKey(hKey);
138 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
139 ok(result, "%08x\n", GetLastError());
140 if (result) CryptDestroyKey(hKey);
142 return 1;
145 static void clean_up_base_environment(void)
147 BOOL result;
149 result = CryptReleaseContext(hProv, 1);
150 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
152 CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
155 static int init_aes_environment(void)
157 HCRYPTKEY hKey;
158 BOOL result;
160 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
162 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
164 /* we are using NULL as provider name for RSA_AES provider as the provider
165 * names are different in Windows XP and Vista. Its different as to what
166 * its defined in the SDK on Windows XP.
167 * This provider is available on Windows XP, Windows 2003 and Vista. */
169 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
170 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
172 if (!CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, 0))
174 ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
175 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
176 result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES,
177 CRYPT_NEWKEYSET);
178 ok(result, "%08x\n", GetLastError());
179 if (!result) return 0;
180 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
181 ok(result, "%08x\n", GetLastError());
182 if (result) CryptDestroyKey(hKey);
183 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
184 ok(result, "%08x\n", GetLastError());
185 if (result) CryptDestroyKey(hKey);
187 return 1;
190 static void clean_up_aes_environment(void)
192 BOOL result;
194 result = CryptReleaseContext(hProv, 1);
195 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
197 CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_DELETEKEYSET);
200 static void test_prov(void)
202 BOOL result;
203 DWORD dwLen, dwInc;
205 dwLen = (DWORD)sizeof(DWORD);
206 SetLastError(0xdeadbeef);
207 result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
208 if (!result && GetLastError() == NTE_BAD_TYPE)
209 skip("PP_SIG_KEYSIZE_INC is not supported (win9x or NT)\n");
210 else
211 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
213 dwLen = (DWORD)sizeof(DWORD);
214 SetLastError(0xdeadbeef);
215 result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
216 if (!result && GetLastError() == NTE_BAD_TYPE)
217 skip("PP_KEYX_KEYSIZE_INC is not supported (win9x or NT)\n");
218 else
219 ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
222 static void test_gen_random(void)
224 BOOL result;
225 BYTE rnd1[16], rnd2[16];
227 memset(rnd1, 0, sizeof(rnd1));
228 memset(rnd2, 0, sizeof(rnd2));
230 result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
231 if (!result && GetLastError() == NTE_FAIL) {
232 /* rsaenh compiled without OpenSSL */
233 return;
236 ok(result, "%08x\n", GetLastError());
238 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
239 ok(result, "%08x\n", GetLastError());
241 ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
244 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
246 HCRYPTHASH hHash;
247 BOOL result;
248 unsigned char pbData[2000];
249 int i;
251 *phKey = (HCRYPTKEY)NULL;
252 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
253 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
254 if (!result) {
255 /* rsaenh compiled without OpenSSL */
256 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
257 return FALSE;
259 ok(result, "%08x\n", GetLastError());
260 if (!result) return FALSE;
261 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
262 ok(result, "%08x\n", GetLastError());
263 if (!result) return FALSE;
264 result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
265 ok(result, "%08x\n", GetLastError());
266 if (!result) return FALSE;
267 len = 2000;
268 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
269 ok(result, "%08x\n", GetLastError());
270 CryptDestroyHash(hHash);
271 return TRUE;
274 static void test_hashes(void)
276 static const unsigned char md2hash[16] = {
277 0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
278 0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
279 static const unsigned char md4hash[16] = {
280 0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
281 0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
282 static const unsigned char empty_md5hash[16] = {
283 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
284 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
285 static const unsigned char md5hash[16] = {
286 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
287 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
288 static const unsigned char sha1hash[20] = {
289 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
290 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
291 unsigned char pbData[2048];
292 BOOL result;
293 HCRYPTHASH hHash, hHashClone;
294 BYTE pbHashValue[36];
295 DWORD hashlen, len;
296 int i;
298 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
300 /* MD2 Hashing */
301 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
302 if (!result) {
303 /* rsaenh compiled without OpenSSL */
304 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
305 } else {
306 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
307 ok(result, "%08x\n", GetLastError());
309 len = sizeof(DWORD);
310 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
311 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
313 len = 16;
314 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
315 ok(result, "%08x\n", GetLastError());
317 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
319 result = CryptDestroyHash(hHash);
320 ok(result, "%08x\n", GetLastError());
323 /* MD4 Hashing */
324 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
325 ok(result, "%08x\n", GetLastError());
327 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
328 ok(result, "%08x\n", GetLastError());
330 len = sizeof(DWORD);
331 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
332 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
334 len = 16;
335 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
336 ok(result, "%08x\n", GetLastError());
338 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
340 result = CryptDestroyHash(hHash);
341 ok(result, "%08x\n", GetLastError());
343 /* MD5 Hashing */
344 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
345 ok(result, "%08x\n", GetLastError());
347 len = sizeof(DWORD);
348 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
349 ok(result && (hashlen == 16), "%08x, hashlen: %d\n", GetLastError(), hashlen);
351 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
352 ok(result, "%08x\n", GetLastError());
354 len = 16;
355 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
356 ok(result, "%08x\n", GetLastError());
358 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
360 result = CryptDestroyHash(hHash);
361 ok(result, "%08x\n", GetLastError());
363 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
364 ok(result, "%08x\n", GetLastError());
366 /* The hash is available even if CryptHashData hasn't been called */
367 len = 16;
368 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
369 ok(result, "%08x\n", GetLastError());
371 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
373 /* It's also stable: getting it twice results in the same value */
374 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
375 ok(result, "%08x\n", GetLastError());
377 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
379 /* Can't add data after the hash been retrieved */
380 SetLastError(0xdeadbeef);
381 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
382 ok(!result && GetLastError() == NTE_BAD_HASH_STATE, "%08x\n", GetLastError());
384 /* You can still retrieve the hash, its value just hasn't changed */
385 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
386 ok(result, "%08x\n", GetLastError());
388 ok(!memcmp(pbHashValue, empty_md5hash, 16), "Wrong MD5 hash!\n");
390 result = CryptDestroyHash(hHash);
391 ok(result, "%08x\n", GetLastError());
393 /* SHA1 Hashing */
394 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
395 ok(result, "%08x\n", GetLastError());
397 result = CryptHashData(hHash, (BYTE*)pbData, 5, 0);
398 ok(result, "%08x\n", GetLastError());
400 if(pCryptDuplicateHash) {
401 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
402 ok(result, "%08x\n", GetLastError());
404 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
405 ok(result, "%08x\n", GetLastError());
407 len = sizeof(DWORD);
408 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
409 ok(result && (hashlen == 20), "%08x, hashlen: %d\n", GetLastError(), hashlen);
411 len = 20;
412 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
413 ok(result, "%08x\n", GetLastError());
415 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
417 result = CryptDestroyHash(hHashClone);
418 ok(result, "%08x\n", GetLastError());
421 result = CryptDestroyHash(hHash);
422 ok(result, "%08x\n", GetLastError());
425 static void test_block_cipher_modes(void)
427 static const BYTE plain[23] = {
428 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
429 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
430 static const BYTE ecb[24] = {
431 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
432 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
433 static const BYTE cbc[24] = {
434 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
435 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
436 static const BYTE cfb[24] = {
437 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
438 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
439 HCRYPTKEY hKey;
440 BOOL result;
441 BYTE abData[24];
442 DWORD dwMode, dwLen;
444 result = derive_key(CALG_RC2, &hKey, 40);
445 if (!result) return;
447 memcpy(abData, plain, sizeof(abData));
449 dwMode = CRYPT_MODE_ECB;
450 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
451 ok(result, "%08x\n", GetLastError());
453 dwLen = 23;
454 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
455 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
456 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
458 SetLastError(ERROR_SUCCESS);
459 dwLen = 23;
460 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
461 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
462 "%08x, dwLen: %d\n", GetLastError(), dwLen);
464 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
465 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
466 "%08x, dwLen: %d\n", GetLastError(), dwLen);
468 dwMode = CRYPT_MODE_CBC;
469 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
470 ok(result, "%08x\n", GetLastError());
472 dwLen = 23;
473 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwLen, 24);
474 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
475 ok(dwLen == 24, "Unexpected length %d\n", dwLen);
477 dwLen = 23;
478 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
479 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
480 "%08x, dwLen: %d\n", GetLastError(), dwLen);
482 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
483 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
484 "%08x, dwLen: %d\n", GetLastError(), dwLen);
486 dwMode = CRYPT_MODE_CFB;
487 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
488 ok(result, "%08x\n", GetLastError());
490 dwLen = 16;
491 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen, 24);
492 ok(result && dwLen == 16, "%08x, dwLen: %d\n", GetLastError(), dwLen);
494 dwLen = 7;
495 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+16, &dwLen, 8);
496 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
497 "%08x, dwLen: %d\n", GetLastError(), dwLen);
499 dwLen = 8;
500 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen);
501 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
503 dwLen = 16;
504 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+8, &dwLen);
505 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
506 "%08x, dwLen: %d\n", GetLastError(), dwLen);
508 dwMode = CRYPT_MODE_OFB;
509 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
510 ok(result, "%08x\n", GetLastError());
512 dwLen = 23;
513 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
514 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
516 CryptDestroyKey(hKey);
519 static void test_3des112(void)
521 HCRYPTKEY hKey;
522 BOOL result;
523 DWORD dwLen;
524 unsigned char pbData[16];
525 int i;
527 result = derive_key(CALG_3DES_112, &hKey, 0);
528 if (!result) {
529 /* rsaenh compiled without OpenSSL */
530 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
531 return;
534 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
536 dwLen = 13;
537 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
538 ok(result, "%08x\n", GetLastError());
540 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
541 ok(result, "%08x\n", GetLastError());
543 for (i=0; i<4; i++)
545 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
547 dwLen = cTestData[i].enclen;
548 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
549 ok(result, "%08x\n", GetLastError());
550 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
552 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
553 ok(result, "%08x\n", GetLastError());
554 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
555 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
556 if((dwLen != cTestData[i].enclen) ||
557 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
559 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
560 printBytes("got",pbData,dwLen);
563 result = CryptDestroyKey(hKey);
564 ok(result, "%08x\n", GetLastError());
567 static void test_des(void)
569 HCRYPTKEY hKey;
570 BOOL result;
571 DWORD dwLen, dwMode;
572 unsigned char pbData[16];
573 int i;
575 result = derive_key(CALG_DES, &hKey, 56);
576 if (!result) {
577 /* rsaenh compiled without OpenSSL */
578 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
579 return;
582 dwMode = CRYPT_MODE_ECB;
583 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
584 ok(result, "%08x\n", GetLastError());
586 dwLen = sizeof(DWORD);
587 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
588 ok(result, "%08x\n", GetLastError());
590 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
592 dwLen = 13;
593 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
594 ok(result, "%08x\n", GetLastError());
596 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
597 ok(result, "%08x\n", GetLastError());
599 for (i=0; i<4; i++)
601 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
603 dwLen = cTestData[i].enclen;
604 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
605 ok(result, "%08x\n", GetLastError());
606 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
608 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
609 ok(result, "%08x\n", GetLastError());
610 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
611 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
612 if((dwLen != cTestData[i].enclen) ||
613 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
615 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
616 printBytes("got",pbData,dwLen);
620 result = CryptDestroyKey(hKey);
621 ok(result, "%08x\n", GetLastError());
624 static void test_3des(void)
626 HCRYPTKEY hKey;
627 BOOL result;
628 DWORD dwLen;
629 unsigned char pbData[16];
630 static const BYTE des3[16] = {
631 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
632 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
633 int i;
635 result = derive_key(CALG_3DES, &hKey, 0);
636 if (!result) return;
638 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
640 dwLen = 13;
641 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
642 ok(result, "%08x\n", GetLastError());
644 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
646 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
647 ok(result, "%08x\n", GetLastError());
649 for (i=0; i<4; i++)
651 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
653 dwLen = cTestData[i].enclen;
654 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
655 ok(result, "%08x\n", GetLastError());
656 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
658 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
659 ok(result, "%08x\n", GetLastError());
660 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
661 ok(memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen)==0,"decryption incorrect %d\n",i);
662 if((dwLen != cTestData[i].enclen) ||
663 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
665 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
666 printBytes("got",pbData,dwLen);
669 result = CryptDestroyKey(hKey);
670 ok(result, "%08x\n", GetLastError());
673 static void test_aes(int keylen)
675 HCRYPTKEY hKey;
676 BOOL result;
677 DWORD dwLen;
678 unsigned char pbData[16];
679 int i;
681 switch (keylen)
683 case 256:
684 result = derive_key(CALG_AES_256, &hKey, 0);
685 break;
686 case 192:
687 result = derive_key(CALG_AES_192, &hKey, 0);
688 break;
689 default:
690 case 128:
691 result = derive_key(CALG_AES_128, &hKey, 0);
692 break;
694 if (!result) return;
696 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
698 dwLen = 13;
699 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
700 ok(result, "%08x\n", GetLastError());
702 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
703 ok(result, "%08x\n", GetLastError());
705 for (i=0; i<4; i++)
707 memcpy(pbData,cTestData[i].origstr,cTestData[i].strlen);
709 dwLen = cTestData[i].enclen;
710 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
711 ok(result, "%08x\n", GetLastError());
712 ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
714 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
715 ok(result, "%08x\n", GetLastError());
716 ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
717 ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
718 if((dwLen != cTestData[i].enclen) ||
719 memcmp(pbData,cTestData[i].decstr,cTestData[i].enclen))
721 printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
722 printBytes("got",pbData,dwLen);
725 result = CryptDestroyKey(hKey);
726 ok(result, "%08x\n", GetLastError());
729 static void test_rc2(void)
731 static const BYTE rc2encrypted[16] = {
732 0x02, 0x34, 0x7d, 0xf6, 0x1d, 0xc5, 0x9b, 0x8b,
733 0x2e, 0x0d, 0x63, 0x80, 0x72, 0xc1, 0xc2, 0xb1 };
734 static const BYTE rc2_128_encrypted[] = {
735 0x82,0x81,0xf7,0xff,0xdd,0xd7,0x88,0x8c,0x2a,0x2a,0xc0,0xce,0x4c,0x89,
736 0xb6,0x66 };
737 HCRYPTHASH hHash;
738 HCRYPTKEY hKey;
739 BOOL result;
740 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
741 BYTE *pbTemp;
742 unsigned char pbData[2000], pbHashValue[16];
743 int i;
745 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
747 /* MD2 Hashing */
748 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
749 if (!result) {
750 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
751 } else {
752 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
753 ok(result, "%08x\n", GetLastError());
755 dwLen = 16;
756 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
757 ok(result, "%08x\n", GetLastError());
759 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
760 ok(result, "%08x\n", GetLastError());
762 dwLen = sizeof(DWORD);
763 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
764 ok(result, "%08x\n", GetLastError());
766 dwMode = CRYPT_MODE_CBC;
767 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
768 ok(result, "%08x\n", GetLastError());
770 dwLen = sizeof(DWORD);
771 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
772 ok(result, "%08x\n", GetLastError());
774 dwLen = sizeof(DWORD);
775 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
776 ok(result, "%08x\n", GetLastError());
778 dwLen = sizeof(DWORD);
779 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
780 ok(result, "%08x\n", GetLastError());
782 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
783 ok(result, "%08x\n", GetLastError());
784 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
785 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
786 HeapFree(GetProcessHeap(), 0, pbTemp);
788 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
789 ok(result, "%08x\n", GetLastError());
790 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
791 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
792 HeapFree(GetProcessHeap(), 0, pbTemp);
794 dwLen = sizeof(DWORD);
795 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
797 result = CryptDestroyHash(hHash);
798 ok(result, "%08x\n", GetLastError());
800 dwDataLen = 13;
801 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
802 ok(result, "%08x\n", GetLastError());
804 ok(!memcmp(pbData, rc2encrypted, 8), "RC2 encryption failed!\n");
806 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
807 ok(result, "%08x\n", GetLastError());
808 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
809 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
810 HeapFree(GetProcessHeap(), 0, pbTemp);
812 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
813 ok(result, "%08x\n", GetLastError());
815 result = CryptDestroyKey(hKey);
816 ok(result, "%08x\n", GetLastError());
819 /* Again, but test setting the effective key len */
820 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
822 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
823 if (!result) {
824 ok(GetLastError()==NTE_BAD_ALGID, "%08x\n", GetLastError());
825 } else {
826 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
827 ok(result, "%08x\n", GetLastError());
829 dwLen = 16;
830 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
831 ok(result, "%08x\n", GetLastError());
833 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
834 ok(result, "%08x\n", GetLastError());
836 SetLastError(0xdeadbeef);
837 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, NULL, 0);
838 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", GetLastError());
839 dwKeyLen = 0;
840 SetLastError(0xdeadbeef);
841 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
842 ok(!result && GetLastError()==NTE_BAD_DATA, "%08x\n", GetLastError());
843 dwKeyLen = 1025;
844 SetLastError(0xdeadbeef);
845 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
847 dwLen = sizeof(dwKeyLen);
848 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
849 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
850 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
851 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
853 dwKeyLen = 128;
854 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
855 ok(result, "%d\n", GetLastError());
857 dwLen = sizeof(dwKeyLen);
858 CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
859 ok(dwKeyLen == 56, "%d (%08x)\n", dwKeyLen, GetLastError());
860 CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLen, &dwLen, 0);
861 ok(dwKeyLen == 128, "%d (%08x)\n", dwKeyLen, GetLastError());
863 result = CryptDestroyHash(hHash);
864 ok(result, "%08x\n", GetLastError());
866 dwDataLen = 13;
867 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
868 ok(result, "%08x\n", GetLastError());
870 ok(!memcmp(pbData, rc2_128_encrypted, sizeof(rc2_128_encrypted)),
871 "RC2 encryption failed!\n");
873 /* Oddly enough this succeeds, though it should have no effect */
874 dwKeyLen = 40;
875 result = CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (LPBYTE)&dwKeyLen, 0);
876 ok(result, "%d\n", GetLastError());
878 result = CryptDestroyKey(hKey);
879 ok(result, "%08x\n", GetLastError());
883 static void test_rc4(void)
885 static const BYTE rc4[16] = {
886 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
887 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
888 BOOL result;
889 HCRYPTHASH hHash;
890 HCRYPTKEY hKey;
891 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
892 unsigned char pbData[2000], *pbTemp;
893 unsigned char pszBuffer[256];
894 int i;
896 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
898 /* MD2 Hashing */
899 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
900 if (!result) {
901 /* rsaenh compiled without OpenSSL */
902 ok(GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
903 } else {
904 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
905 ok(result, "%08x\n", GetLastError());
907 dwLen = 16;
908 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
909 ok(result, "%08x\n", GetLastError());
911 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
912 ok(result, "%08x\n", GetLastError());
914 dwLen = sizeof(DWORD);
915 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
916 ok(result, "%08x\n", GetLastError());
918 dwLen = sizeof(DWORD);
919 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
920 ok(result, "%08x\n", GetLastError());
922 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
923 ok(result, "%08x\n", GetLastError());
924 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
925 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
926 HeapFree(GetProcessHeap(), 0, pbTemp);
928 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
929 ok(result, "%08x\n", GetLastError());
930 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
931 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
932 HeapFree(GetProcessHeap(), 0, pbTemp);
934 dwLen = sizeof(DWORD);
935 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
937 result = CryptDestroyHash(hHash);
938 ok(result, "%08x\n", GetLastError());
940 dwDataLen = 16;
941 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, NULL, &dwDataLen, 24);
942 ok(result, "%08x\n", GetLastError());
943 dwDataLen = 16;
944 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
945 ok(result, "%08x\n", GetLastError());
947 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
949 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
950 ok(result, "%08x\n", GetLastError());
952 result = CryptDestroyKey(hKey);
953 ok(result, "%08x\n", GetLastError());
957 static void test_hmac(void) {
958 HCRYPTKEY hKey;
959 HCRYPTHASH hHash;
960 BOOL result;
961 /* Using CALG_MD2 here fails on Windows 2003, why ? */
962 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
963 DWORD dwLen;
964 BYTE abData[256];
965 static const BYTE hmac[16] = {
966 0x1a, 0x7d, 0x49, 0xc5, 0x9b, 0x2d, 0x0b, 0x9c,
967 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 };
968 int i;
970 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
972 if (!derive_key(CALG_RC2, &hKey, 56)) return;
974 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
975 ok(result, "%08x\n", GetLastError());
976 if (!result) return;
978 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
979 ok(result, "%08x\n", GetLastError());
981 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
982 ok(result, "%08x\n", GetLastError());
984 dwLen = sizeof(abData)/sizeof(BYTE);
985 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
986 ok(result, "%08x\n", GetLastError());
988 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
990 result = CryptDestroyHash(hHash);
991 ok(result, "%08x\n", GetLastError());
993 result = CryptDestroyKey(hKey);
994 ok(result, "%08x\n", GetLastError());
996 /* Provoke errors */
997 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
998 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1001 static void test_mac(void) {
1002 HCRYPTKEY hKey;
1003 HCRYPTHASH hHash;
1004 BOOL result;
1005 DWORD dwLen;
1006 BYTE abData[256], abEnc[264];
1007 static const BYTE mac[8] = { 0x0d, 0x3e, 0x15, 0x6b, 0x85, 0x63, 0x5c, 0x11 };
1008 int i;
1010 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
1011 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
1013 if (!derive_key(CALG_RC2, &hKey, 56)) return;
1015 dwLen = 256;
1016 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abEnc, &dwLen, 264);
1017 ok (result && dwLen == 264, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1019 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1020 ok(result, "%08x\n", GetLastError());
1021 if (!result) return;
1023 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
1024 ok(result, "%08x\n", GetLastError());
1026 dwLen = sizeof(abData)/sizeof(BYTE);
1027 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
1028 ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen);
1030 ok(!memcmp(abData, mac, sizeof(mac)), "MAC failed!\n");
1032 result = CryptDestroyHash(hHash);
1033 ok(result, "%08x\n", GetLastError());
1035 result = CryptDestroyKey(hKey);
1036 ok(result, "%08x\n", GetLastError());
1038 /* Provoke errors */
1039 if (!derive_key(CALG_RC4, &hKey, 56)) return;
1041 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
1042 ok(!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1044 result = CryptDestroyKey(hKey);
1045 ok(result, "%08x\n", GetLastError());
1048 static BYTE abPlainPrivateKey[596] = {
1049 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1050 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1051 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1052 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1053 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1054 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1055 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1056 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1057 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1058 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1059 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1060 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1061 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1062 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1063 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1064 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1065 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1066 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1067 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1068 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1069 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1070 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1071 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1072 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1073 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1074 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1075 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1076 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1077 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1078 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1079 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1080 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1081 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1082 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1083 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1084 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1085 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1086 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1087 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1088 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1089 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1090 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1091 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1092 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1093 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1094 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1095 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1096 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1097 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1098 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1099 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1100 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1101 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1102 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1103 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1104 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1105 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1106 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1107 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1108 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1109 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1110 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1111 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1112 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1113 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1114 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1115 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1116 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1117 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1118 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1119 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1120 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1121 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1122 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1123 0xf2, 0x5d, 0x58, 0x07
1126 static void test_import_private(void)
1128 DWORD dwLen;
1129 HCRYPTKEY hKeyExchangeKey, hSessionKey;
1130 BOOL result;
1131 static BYTE abSessionKey[148] = {
1132 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
1133 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
1134 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
1135 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
1136 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
1137 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
1138 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
1139 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
1140 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
1141 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
1142 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
1143 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
1144 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
1145 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
1146 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
1147 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
1148 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
1149 0x04, 0x8c, 0x49, 0x92
1151 static BYTE abEncryptedMessage[12] = {
1152 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
1153 0x1c, 0xfd, 0xde, 0x71
1156 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1157 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
1158 if (!result) {
1159 /* rsaenh compiled without OpenSSL */
1160 ok(GetLastError() == NTE_FAIL, "%08x\n", GetLastError());
1161 return;
1164 dwLen = (DWORD)sizeof(abSessionKey);
1165 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1166 ok(result, "%08x\n", GetLastError());
1167 if (!result) return;
1169 dwLen = (DWORD)sizeof(abEncryptedMessage);
1170 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
1171 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
1172 "%08x, len: %d\n", GetLastError(), dwLen);
1173 CryptDestroyKey(hSessionKey);
1175 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
1177 dwLen = (DWORD)sizeof(abSessionKey);
1178 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
1179 ok(result, "%08x\n", GetLastError());
1180 CryptDestroyKey(hSessionKey);
1181 if (!result) return;
1183 dwLen = (DWORD)sizeof(abSessionKey);
1184 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
1185 ok(result, "%08x\n", GetLastError());
1186 if (!result) return;
1188 CryptDestroyKey(hSessionKey);
1189 CryptDestroyKey(hKeyExchangeKey);
1192 static void test_verify_signature(void) {
1193 HCRYPTHASH hHash;
1194 HCRYPTKEY hPubSignKey;
1195 BYTE abData[] = "Wine rocks!";
1196 BOOL result;
1197 BYTE abPubKey[148] = {
1198 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
1199 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
1200 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
1201 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
1202 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
1203 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
1204 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
1205 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
1206 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
1207 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
1208 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
1209 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
1210 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
1211 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
1212 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
1213 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
1214 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
1215 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
1216 0xe1, 0x21, 0x50, 0xac
1218 /* md2 with hash oid */
1219 BYTE abSignatureMD2[128] = {
1220 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
1221 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
1222 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
1223 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
1224 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
1225 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
1226 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
1227 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
1228 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
1229 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
1230 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
1231 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
1232 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
1233 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
1234 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
1235 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
1237 /* md2 without hash oid */
1238 BYTE abSignatureMD2NoOID[128] = {
1239 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
1240 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
1241 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
1242 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
1243 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
1244 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
1245 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
1246 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
1247 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
1248 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
1249 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
1250 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
1251 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
1252 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
1253 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
1254 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
1256 /* md4 with hash oid */
1257 BYTE abSignatureMD4[128] = {
1258 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
1259 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
1260 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
1261 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
1262 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
1263 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
1264 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
1265 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
1266 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
1267 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
1268 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
1269 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
1270 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
1271 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
1272 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
1273 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
1275 /* md4 without hash oid */
1276 BYTE abSignatureMD4NoOID[128] = {
1277 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
1278 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
1279 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
1280 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
1281 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
1282 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
1283 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
1284 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
1285 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
1286 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
1287 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
1288 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
1289 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
1290 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
1291 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
1292 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
1294 /* md5 with hash oid */
1295 BYTE abSignatureMD5[128] = {
1296 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
1297 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
1298 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
1299 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
1300 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
1301 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
1302 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
1303 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
1304 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
1305 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
1306 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
1307 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
1308 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
1309 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
1310 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
1311 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
1313 /* md5 without hash oid */
1314 BYTE abSignatureMD5NoOID[128] = {
1315 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
1316 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
1317 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
1318 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
1319 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
1320 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
1321 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
1322 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
1323 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
1324 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
1325 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
1326 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
1327 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
1328 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
1329 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
1330 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
1332 /* sha with hash oid */
1333 BYTE abSignatureSHA[128] = {
1334 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
1335 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
1336 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
1337 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
1338 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
1339 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
1340 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
1341 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
1342 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
1343 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
1344 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
1345 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
1346 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
1347 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
1348 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
1349 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
1351 /* sha without hash oid */
1352 BYTE abSignatureSHANoOID[128] = {
1353 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1354 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1355 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1356 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1357 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1358 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1359 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1360 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1361 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1362 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1363 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1364 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1365 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1366 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1367 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1368 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1371 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1372 ok(result, "%08x\n", GetLastError());
1373 if (!result) return;
1375 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1376 ok(result, "%08x\n", GetLastError());
1377 if (!result) return;
1379 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1380 ok(result, "%08x\n", GetLastError());
1381 if (!result) return;
1383 /*check that a NULL pointer signature is correctly handled*/
1384 result = CryptVerifySignature(hHash, NULL, 128, hPubSignKey, NULL, 0);
1385 ok(!result && ERROR_INVALID_PARAMETER == GetLastError(),
1386 "Expected ERROR_INVALID_PARAMETER error, got %08x\n", GetLastError());
1387 if (result) return;
1389 /* check that we get a bad signature error when the signature is too short*/
1390 result = CryptVerifySignature(hHash, abSignatureMD2, 64, hPubSignKey, NULL, 0);
1391 ok(!result && NTE_BAD_SIGNATURE == GetLastError(),
1392 "Expected NTE_BAD_SIGNATURE error, got %08x\n", GetLastError());
1393 if (result) return;
1395 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1396 ok(result, "%08x\n", GetLastError());
1397 if (!result) return;
1399 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1400 ok(result, "%08x\n", GetLastError());
1401 if (!result) return;
1403 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1404 * the OID at all. */
1405 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1406 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1407 if (result) return;*/
1409 CryptDestroyHash(hHash);
1411 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1412 ok(result, "%08x\n", GetLastError());
1413 if (!result) return;
1415 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1416 ok(result, "%08x\n", GetLastError());
1417 if (!result) return;
1419 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1420 ok(result, "%08x\n", GetLastError());
1421 if (!result) return;
1423 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1424 ok(result, "%08x\n", GetLastError());
1425 if (!result) return;
1427 CryptDestroyHash(hHash);
1429 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1430 ok(result, "%08x\n", GetLastError());
1431 if (!result) return;
1433 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1434 ok(result, "%08x\n", GetLastError());
1435 if (!result) return;
1437 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1438 ok(result, "%08x\n", GetLastError());
1439 if (!result) return;
1441 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1442 ok(result, "%08x\n", GetLastError());
1443 if (!result) return;
1445 CryptDestroyHash(hHash);
1447 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1448 ok(result, "%08x\n", GetLastError());
1449 if (!result) return;
1451 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1452 ok(result, "%08x\n", GetLastError());
1453 if (!result) return;
1455 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1456 ok(result, "%08x\n", GetLastError());
1457 if (!result) return;
1459 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1460 ok(result, "%08x\n", GetLastError());
1461 if (!result) return;
1463 CryptDestroyHash(hHash);
1464 CryptDestroyKey(hPubSignKey);
1467 static void test_rsa_encrypt(void)
1469 HCRYPTKEY hRSAKey;
1470 BYTE abData[2048] = "Wine rocks!";
1471 BOOL result;
1472 DWORD dwLen;
1474 /* It is allowed to use the key exchange key for encryption/decryption */
1475 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1476 ok (result, "%08x\n", GetLastError());
1477 if (!result) return;
1479 dwLen = 12;
1480 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, NULL, &dwLen, (DWORD)sizeof(abData));
1481 ok(result, "CryptEncrypt failed: %08x\n", GetLastError());
1482 ok(dwLen == 128, "Unexpected length %d\n", dwLen);
1483 dwLen = 12;
1484 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1485 ok (result, "%08x\n", GetLastError());
1486 if (!result) return;
1488 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1489 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError());
1491 CryptDestroyKey(hRSAKey);
1493 /* It is not allowed to use the signature key for encryption/decryption */
1494 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1495 ok (result, "%08x\n", GetLastError());
1496 if (!result) return;
1498 dwLen = 12;
1499 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1500 ok (!result && GetLastError() == NTE_BAD_KEY, "%08x\n", GetLastError());
1502 CryptDestroyKey(hRSAKey);
1505 static void test_import_export(void)
1507 DWORD dwLen, dwDataLen;
1508 HCRYPTKEY hPublicKey;
1509 BOOL result;
1510 ALG_ID algID;
1511 BYTE emptyKey[2048];
1512 static BYTE abPlainPublicKey[84] = {
1513 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1514 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
1515 0x01, 0x00, 0x01, 0x00, 0x11, 0x11, 0x11, 0x11,
1516 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1517 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1518 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1519 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1520 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1521 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1522 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1523 0x11, 0x11, 0x11, 0x11
1526 dwLen=84;
1527 result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey);
1528 ok(result, "failed to import the public key\n");
1530 dwDataLen=sizeof(algID);
1531 result = CryptGetKeyParam(hPublicKey, KP_ALGID, (LPBYTE)&algID, &dwDataLen, 0);
1532 ok(result, "failed to get the KP_ALGID from the imported public key\n");
1533 ok(algID == CALG_RSA_KEYX, "Expected CALG_RSA_KEYX, got %x\n", algID);
1535 result = CryptExportKey(hPublicKey, 0, PUBLICKEYBLOB, 0, emptyKey, &dwLen);
1536 ok(result, "failed to export the fresh imported public key\n");
1537 ok(dwLen == 84, "Expected exported key to be 84 bytes long but got %d bytes.\n",dwLen);
1538 ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n");
1540 CryptDestroyKey(hPublicKey);
1543 static void test_schannel_provider(void)
1545 HCRYPTPROV hProv;
1546 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1547 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1548 BOOL result;
1549 DWORD dwLen;
1550 SCHANNEL_ALG saSChannelAlg;
1551 CRYPT_DATA_BLOB data_blob;
1552 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1553 BYTE abTLS1Master[140] = {
1554 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
1555 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
1556 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
1557 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
1558 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
1559 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
1560 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
1561 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
1562 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
1563 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
1564 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
1565 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
1566 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
1567 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
1568 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
1569 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
1570 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
1571 0xd3, 0x1e, 0x82, 0xb3
1573 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1574 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1575 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1576 BYTE abClientFinished[16] = "client finished";
1577 BYTE abData[16] = "Wine rocks!";
1578 BYTE abMD5Hash[16];
1579 static const BYTE abEncryptedData[16] = {
1580 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1581 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
1583 static const BYTE abPRF[16] = {
1584 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1585 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1587 static const BYTE abMD5[16] = {
1588 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1589 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1592 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET);
1593 ok (result, "%08x\n", GetLastError());
1594 if (result)
1595 CryptReleaseContext(hProv, 0);
1597 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1598 ok (result, "%08x\n", GetLastError());
1599 if (!result) return;
1601 /* To get deterministic results, we import the TLS1 master secret (which
1602 * is typically generated from a random generator). Therefore, we need
1603 * an RSA key. */
1604 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1605 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1606 ok (result, "%08x\n", GetLastError());
1607 if (!result) return;
1609 dwLen = (DWORD)sizeof(abTLS1Master);
1610 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1611 ok (result, "%08x\n", GetLastError());
1612 if (!result) return;
1614 /* Setting the TLS1 client and server random parameters, as well as the
1615 * MAC and encryption algorithm parameters. */
1616 data_blob.cbData = 33;
1617 data_blob.pbData = abClientSecret;
1618 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1619 ok (result, "%08x\n", GetLastError());
1620 if (!result) return;
1622 data_blob.cbData = 33;
1623 data_blob.pbData = abServerSecret;
1624 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1625 ok (result, "%08x\n", GetLastError());
1626 if (!result) return;
1628 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1629 saSChannelAlg.Algid = CALG_DES;
1630 saSChannelAlg.cBits = 64;
1631 saSChannelAlg.dwFlags = 0;
1632 saSChannelAlg.dwReserved = 0;
1633 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1634 ok (result, "%08x\n", GetLastError());
1635 if (!result) return;
1637 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1638 saSChannelAlg.Algid = CALG_MD5;
1639 saSChannelAlg.cBits = 128;
1640 saSChannelAlg.dwFlags = 0;
1641 saSChannelAlg.dwReserved = 0;
1642 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1643 ok (result, "%08x\n", GetLastError());
1644 if (!result) return;
1646 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1647 * (Keys can only be derived from hashes, not from other keys.) */
1648 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1649 ok (result, "%08x\n", GetLastError());
1650 if (!result) return;
1652 /* Deriving the server write encryption key from the master hash */
1653 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1654 ok (result, "%08x\n", GetLastError());
1655 if (!result) return;
1657 /* Encrypting some data with the server write encryption key and checking the result. */
1658 dwLen = 12;
1659 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1660 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08x\n", GetLastError());
1662 /* Second test case: Test the TLS1 pseudo random number function. */
1663 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1664 ok (result, "%08x\n", GetLastError());
1665 if (!result) return;
1667 /* Set the label and seed parameters for the random number function */
1668 data_blob.cbData = 36;
1669 data_blob.pbData = abHashedHandshakes;
1670 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1671 ok (result, "%08x\n", GetLastError());
1672 if (!result) return;
1674 data_blob.cbData = 15;
1675 data_blob.pbData = abClientFinished;
1676 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1677 ok (result, "%08x\n", GetLastError());
1678 if (!result) return;
1680 /* Generate some pseudo random bytes and check if they are correct. */
1681 dwLen = (DWORD)sizeof(abData);
1682 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1683 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
1684 "%08x\n", GetLastError());
1686 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1687 * Hash some data with the HMAC. Compare results. */
1688 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
1689 ok (result, "%08x\n", GetLastError());
1690 if (!result) return;
1692 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
1693 ok (result, "%08x\n", GetLastError());
1694 if (!result) return;
1696 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
1697 ok (result, "%08x\n", GetLastError());
1698 if (!result) return;
1700 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
1701 ok (result, "%08x\n", GetLastError());
1702 if (!result) return;
1704 dwLen = (DWORD)sizeof(abMD5Hash);
1705 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
1706 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08x\n", GetLastError());
1708 CryptDestroyHash(hHMAC);
1709 CryptDestroyHash(hTLS1PRF);
1710 CryptDestroyHash(hMasterHash);
1711 CryptDestroyKey(hServerWriteMACKey);
1712 CryptDestroyKey(hServerWriteKey);
1713 CryptDestroyKey(hRSAKey);
1714 CryptDestroyKey(hMasterSecret);
1715 CryptReleaseContext(hProv, 0);
1716 CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET);
1719 static void test_enum_container(void)
1721 BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */
1722 DWORD dwBufferLen;
1723 BOOL result, fFound = FALSE;
1725 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1726 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1727 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
1728 ok (result && dwBufferLen == MAX_PATH + 1, "%08x\n", GetLastError());
1730 /* If the result fits into abContainerName dwBufferLen is left untouched */
1731 dwBufferLen = (DWORD)sizeof(abContainerName);
1732 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
1733 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08x\n", GetLastError());
1735 /* We only check, if the currently open 'winetest' container is among the enumerated. */
1736 do {
1737 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
1738 dwBufferLen = (DWORD)sizeof(abContainerName);
1739 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
1741 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08x\n", fFound, GetLastError());
1744 static BYTE signBlob[] = {
1745 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00,0x00,
1746 0x01,0x00,0x01,0x00,0xf1,0x82,0x9e,0x84,0xb5,0x79,0x9a,0xbe,0x4d,0x06,0x20,0x21,
1747 0xb1,0x89,0x0c,0xca,0xb0,0x35,0x72,0x18,0xc6,0x92,0xa8,0xe2,0xb1,0xe1,0xf6,0x56,
1748 0x53,0x99,0x47,0x10,0x6e,0x1c,0x81,0xaf,0xb8,0xf9,0x5f,0xfe,0x76,0x7f,0x2c,0x93,
1749 0xec,0x54,0x7e,0x5e,0xc2,0x25,0x3c,0x50,0x56,0x10,0x20,0x72,0x4a,0x93,0x03,0x12,
1750 0x29,0x98,0xcc,0xc9,0x47,0xbf,0xbf,0x93,0xcc,0xb0,0xe5,0x53,0x14,0xc8,0x7e,0x1f,
1751 0xa4,0x03,0x2d,0x8e,0x84,0x7a,0xd2,0xeb,0xf7,0x92,0x5e,0xa2,0xc7,0x6b,0x35,0x7d,
1752 0xcb,0x60,0xae,0xfb,0x07,0x78,0x11,0x73,0xb5,0x79,0xe5,0x7e,0x96,0xe3,0x50,0x95,
1753 0x80,0x0e,0x1c,0xf6,0x56,0xc6,0xe9,0x0a,0xaf,0x03,0xc6,0xdc,0x9a,0x81,0xcf,0x7a,
1754 0x63,0x16,0x43,0xcd,0xab,0x74,0xa1,0x7d,0xe7,0xe0,0x75,0x6d,0xbd,0x19,0xae,0x0b,
1755 0xa3,0x7f,0x6a,0x7b,0x05,0x4e,0xbc,0xec,0x18,0xfc,0x19,0xc2,0x00,0xf0,0x6a,0x2e,
1756 0xc4,0x31,0x73,0xba,0x07,0xcc,0x9d,0x57,0xeb,0xc7,0x7c,0x00,0x7d,0x5d,0x11,0x16,
1757 0x42,0x4b,0xe5,0x3a,0xf5,0xc7,0xf8,0xee,0xc3,0x2c,0x0d,0x86,0x03,0xe2,0xaf,0xb2,
1758 0xd2,0x91,0xdb,0x71,0xcd,0xdf,0x81,0x5f,0x06,0xfc,0x48,0x0d,0xb6,0x88,0x9f,0xc1,
1759 0x5e,0x24,0xa2,0x05,0x4f,0x30,0x2e,0x8f,0x8b,0x0d,0x76,0xa1,0x84,0xda,0x7b,0x44,
1760 0x70,0x85,0xf1,0x50,0xb1,0x21,0x3d,0xe2,0x57,0x3d,0xd0,0x01,0x93,0x49,0x8e,0xc5,
1761 0x0b,0x8b,0x0d,0x7b,0x08,0xe9,0x14,0xec,0x20,0x0d,0xea,0x02,0x00,0x63,0xe8,0x0a,
1762 0x52,0xe8,0xfb,0x21,0xbd,0x37,0xde,0x4c,0x4d,0xc2,0xf6,0xb9,0x0d,0x2a,0xc3,0xe2,
1763 0xc9,0xdf,0x48,0x3e,0x55,0x3d,0xe3,0xc0,0x22,0x37,0xf9,0x52,0xc0,0xd7,0x61,0x22,
1764 0xb6,0x85,0x86,0x07 };
1766 static void test_null_provider(void)
1768 HCRYPTPROV prov;
1769 HCRYPTKEY key;
1770 BOOL result;
1771 DWORD keySpec, dataLen,dwParam;
1772 char szName[MAX_PATH];
1774 result = CryptAcquireContext(NULL, szContainer, NULL, 0, 0);
1775 ok(!result && GetLastError() == NTE_BAD_PROV_TYPE,
1776 "Expected NTE_BAD_PROV_TYPE, got %08x\n", GetLastError());
1777 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL, 0);
1778 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1779 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1780 result = CryptAcquireContext(NULL, szContainer, NULL, PROV_RSA_FULL,
1781 CRYPT_DELETEKEYSET);
1782 ok(!result && GetLastError() == ERROR_INVALID_PARAMETER,
1783 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1784 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1785 CRYPT_DELETEKEYSET);
1786 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1787 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1788 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1789 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1790 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1792 /* Delete the default container. */
1793 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1794 /* Once you've deleted the default container you can't open it as if it
1795 * already exists.
1797 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0);
1798 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1799 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1800 /* But you can always open the default container for CRYPT_VERIFYCONTEXT. */
1801 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1802 CRYPT_VERIFYCONTEXT);
1803 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1804 if (!result) return;
1805 dataLen = sizeof(keySpec);
1806 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1807 if (result)
1808 ok(keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1809 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1810 /* Even though PP_KEYSPEC says both AT_KEYEXCHANGE and AT_SIGNATURE are
1811 * supported, you can't get the keys from this container.
1813 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1814 ok(!result && GetLastError() == NTE_NO_KEY,
1815 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1816 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1817 ok(!result && GetLastError() == NTE_NO_KEY,
1818 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1819 result = CryptReleaseContext(prov, 0);
1820 ok(result, "CryptReleaseContext failed: %08x\n", GetLastError());
1821 /* You can create a new default container. */
1822 result = CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
1823 CRYPT_NEWKEYSET);
1824 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1825 /* But you still can't get the keys (until one's been generated.) */
1826 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1827 ok(!result && GetLastError() == NTE_NO_KEY,
1828 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1829 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1830 ok(!result && GetLastError() == NTE_NO_KEY,
1831 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1832 CryptReleaseContext(prov, 0);
1833 CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1835 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1836 CRYPT_DELETEKEYSET);
1837 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, 0);
1838 ok(!result && GetLastError() == NTE_BAD_KEYSET,
1839 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1840 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1841 CRYPT_VERIFYCONTEXT);
1842 ok(!result && GetLastError() == NTE_BAD_FLAGS,
1843 "Expected NTE_BAD_FLAGS, got %08x\n", GetLastError());
1844 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1845 CRYPT_NEWKEYSET);
1846 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1847 if (!result) return;
1848 /* Test provider parameters getter */
1849 dataLen = sizeof(dwParam);
1850 result = CryptGetProvParam(prov, PP_PROVTYPE, (LPBYTE)&dwParam, &dataLen, 0);
1851 ok(result && dataLen == sizeof(dwParam) && dwParam == PROV_RSA_FULL,
1852 "Expected PROV_RSA_FULL, got 0x%08X\n",dwParam);
1853 dataLen = sizeof(dwParam);
1854 result = CryptGetProvParam(prov, PP_KEYSET_TYPE, (LPBYTE)&dwParam, &dataLen, 0);
1855 ok(result && dataLen == sizeof(dwParam) && dwParam == 0,
1856 "Expected 0, got 0x%08X\n",dwParam);
1857 dataLen = sizeof(dwParam);
1858 result = CryptGetProvParam(prov, PP_KEYSTORAGE, (LPBYTE)&dwParam, &dataLen, 0);
1859 ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
1860 "Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
1861 dataLen = sizeof(keySpec);
1862 SetLastError(0xdeadbeef);
1863 result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
1864 if (!result && GetLastError() == NTE_BAD_TYPE)
1865 skip("PP_KEYSPEC is not supported (win9x or NT)\n");
1866 else
1867 ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
1868 "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
1869 /* PP_CONTAINER parameter */
1870 dataLen = sizeof(szName);
1871 result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1872 ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
1873 "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
1874 (result)? "TRUE":"FALSE",GetLastError(),dataLen);
1875 /* PP_UNIQUE_CONTAINER parameter */
1876 dataLen = sizeof(szName);
1877 SetLastError(0xdeadbeef);
1878 result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
1879 if (!result && GetLastError() == NTE_BAD_TYPE)
1881 skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
1883 else
1885 char container[MAX_PATH];
1887 ok(result, "failed getting PP_UNIQUE_CONTAINER : 0x%08X\n", GetLastError());
1888 uniquecontainer(container);
1889 todo_wine
1891 ok(dataLen == strlen(container)+1, "Expected a param length of 70, got %d\n", dataLen);
1892 ok(!strcmp(container, szName), "Wrong container name : %s\n", szName);
1895 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1896 ok(!result && GetLastError() == NTE_NO_KEY,
1897 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1898 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1899 ok(!result && GetLastError() == NTE_NO_KEY,
1900 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1902 /* Importing a key exchange blob.. */
1903 result = CryptImportKey(prov, abPlainPrivateKey, sizeof(abPlainPrivateKey),
1904 0, 0, &key);
1905 ok(result, "CryptImportKey failed: %08x\n", GetLastError());
1906 CryptDestroyKey(key);
1907 /* allows access to the key exchange key.. */
1908 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1909 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1910 CryptDestroyKey(key);
1911 /* but not to the private key. */
1912 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1913 ok(!result && GetLastError() == NTE_NO_KEY,
1914 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1915 CryptReleaseContext(prov, 0);
1916 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1917 CRYPT_DELETEKEYSET);
1919 /* Whereas importing a sign blob.. */
1920 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1921 CRYPT_NEWKEYSET);
1922 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1923 if (!result) return;
1924 result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key);
1925 ok(result, "CryptGenKey failed: %08x\n", GetLastError());
1926 CryptDestroyKey(key);
1927 /* doesn't allow access to the key exchange key.. */
1928 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1929 ok(!result && GetLastError() == NTE_NO_KEY,
1930 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1931 /* but does to the private key. */
1932 result = CryptGetUserKey(prov, AT_SIGNATURE, &key);
1933 ok(result, "CryptGetUserKey failed: %08x\n", GetLastError());
1934 CryptDestroyKey(key);
1935 CryptReleaseContext(prov, 0);
1937 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1938 CRYPT_DELETEKEYSET);
1941 /* test for the bug in accessing the user key in a container
1943 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1944 CRYPT_NEWKEYSET);
1945 ok(result, "CryptAcquireContext failed: %08x\n", GetLastError());
1946 result = CryptGenKey(prov, AT_KEYEXCHANGE, 0, &key);
1947 ok(result, "CryptGenKey with AT_KEYEXCHANGE failed with error %08x\n", GetLastError());
1948 CryptDestroyKey(key);
1949 CryptReleaseContext(prov,0);
1950 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,0);
1951 ok(result, "CryptAcquireContext failed: 0x%08x\n", GetLastError());
1952 result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
1953 ok (result, "CryptGetUserKey failed with error %08x\n", GetLastError());
1954 CryptDestroyKey(key);
1955 CryptReleaseContext(prov, 0);
1957 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1958 CRYPT_DELETEKEYSET);
1960 /* test the machine key set */
1961 CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1962 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1963 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1964 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET);
1965 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1966 CryptReleaseContext(prov, 0);
1967 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1968 CRYPT_MACHINE_KEYSET);
1969 ok(result, "CryptAcquireContext with CRYPT_MACHINE_KEYSET failed: %08x\n", GetLastError());
1970 CryptReleaseContext(prov,0);
1971 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1972 CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
1973 ok(result, "CryptAcquireContext with CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET failed: %08x\n",
1974 GetLastError());
1975 result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL,
1976 CRYPT_MACHINE_KEYSET);
1977 ok(!result && GetLastError() == NTE_BAD_KEYSET ,
1978 "Expected NTE_BAD_KEYSET, got %08x\n", GetLastError());
1982 START_TEST(rsaenh)
1984 if (!init_base_environment())
1985 return;
1986 test_prov();
1987 test_gen_random();
1988 test_hashes();
1989 test_rc4();
1990 test_rc2();
1991 test_des();
1992 test_3des112();
1993 test_3des();
1994 test_hmac();
1995 test_mac();
1996 test_block_cipher_modes();
1997 test_import_private();
1998 test_verify_signature();
1999 test_rsa_encrypt();
2000 test_import_export();
2001 test_enum_container();
2002 clean_up_base_environment();
2003 test_schannel_provider();
2004 test_null_provider();
2005 if (!init_aes_environment())
2006 return;
2007 test_aes(128);
2008 test_aes(192);
2009 test_aes(256);
2010 clean_up_aes_environment();