2 * Unit tests for rsaenh functions
4 * Copyright (c) 2004 Michael Jung
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/test.h"
29 static HCRYPTPROV hProv;
30 static const char szContainer[] = "winetest";
31 static const unsigned char pbData[] = "Wine rocks totally!";
32 static const char szProvider[] = MS_ENHANCED_PROV_A;
34 static BOOL (WINAPI *pCryptDuplicateHash) (HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
37 static void trace_hex(BYTE *pbData, DWORD dwLen) {
41 for (i = 0; i < dwLen-7; i+=8) {
42 sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
43 pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5],
44 pbData[i+6], pbData[i+7]);
47 for (j=0; i<dwLen; j++,i++) {
48 sprintf(szTemp+6*j, "0x%02x, \n", pbData[i]);
54 static int init_environment(void)
59 pCryptDuplicateHash = (void *)GetProcAddress(GetModuleHandleA("advapi32.dll"), "CryptDuplicateHash");
61 hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
63 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
64 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08lx\n", result, GetLastError());
66 if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
68 ok(GetLastError()==NTE_BAD_KEYSET, "%08lx\n", GetLastError());
69 if (GetLastError()!=NTE_BAD_KEYSET) return 0;
70 result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL,
72 ok(result, "%08lx\n", GetLastError());
73 if (!result) return 0;
74 result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
75 ok(result, "%08lx\n", GetLastError());
76 if (result) CryptDestroyKey(hKey);
77 result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
78 ok(result, "%08lx\n", GetLastError());
79 if (result) CryptDestroyKey(hKey);
84 static void clean_up_environment(void)
88 result = CryptReleaseContext(hProv, 1);
89 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08lx\n", GetLastError());
91 CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
94 static void test_prov(void)
99 dwLen = (DWORD)sizeof(DWORD);
100 result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
101 ok(result && dwInc==8, "%08lx, %ld\n", GetLastError(), dwInc);
103 dwLen = (DWORD)sizeof(DWORD);
104 result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
105 ok(result && dwInc==8, "%08lx, %ld\n", GetLastError(), dwInc);
108 static void test_gen_random(void)
111 BYTE rnd1[16], rnd2[16];
113 memset(rnd1, 0, sizeof(rnd1));
114 memset(rnd2, 0, sizeof(rnd2));
116 result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
117 if (!result && GetLastError() == NTE_FAIL) {
118 /* rsaenh compiled without OpenSSL */
122 ok(result, "%08lx\n", GetLastError());
124 result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
125 ok(result, "%08lx\n", GetLastError());
127 ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
130 static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
134 unsigned char pbData[2000];
137 *phKey = (HCRYPTKEY)NULL;
138 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
139 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
141 /* rsaenh compiled without OpenSSL */
142 ok(GetLastError()==NTE_BAD_ALGID, "%08lx\n", GetLastError());
145 ok(result, "%08lx\n", GetLastError());
146 if (!result) return FALSE;
147 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
148 ok(result, "%08lx\n", GetLastError());
149 if (!result) return FALSE;
150 result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
151 ok(result, "%08lx\n", GetLastError());
152 if (!result) return FALSE;
154 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
155 ok(result, "%08lx\n", GetLastError());
156 CryptDestroyHash(hHash);
160 static void test_hashes(void)
162 static const unsigned char md2hash[16] = {
163 0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
164 0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
165 static const unsigned char md4hash[16] = {
166 0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
167 0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
168 static const unsigned char md5hash[16] = {
169 0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
170 0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
171 static const unsigned char sha1hash[20] = {
172 0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
173 0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
174 unsigned char pbData[2048];
176 HCRYPTHASH hHash, hHashClone;
177 BYTE pbHashValue[36];
181 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
184 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
186 /* rsaenh compiled without OpenSSL */
187 ok(GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
189 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
190 ok(result, "%08lx\n", GetLastError());
193 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
194 ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
197 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
198 ok(result, "%08lx\n", GetLastError());
200 ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
202 result = CryptDestroyHash(hHash);
203 ok(result, "%08lx\n", GetLastError());
207 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
208 ok(result, "%08lx\n", GetLastError());
210 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
211 ok(result, "%08lx\n", GetLastError());
214 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
215 ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
218 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
219 ok(result, "%08lx\n", GetLastError());
221 ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
223 result = CryptDestroyHash(hHash);
224 ok(result, "%08lx\n", GetLastError());
227 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
228 ok(result, "%08lx\n", GetLastError());
230 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
231 ok(result, "%08lx\n", GetLastError());
234 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
235 ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
238 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
239 ok(result, "%08lx\n", GetLastError());
241 ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
243 result = CryptDestroyHash(hHash);
244 ok(result, "%08lx\n", GetLastError());
247 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
248 ok(result, "%08lx\n", GetLastError());
250 result = CryptHashData(hHash, (BYTE*)pbData, 5, 0);
251 ok(result, "%08lx\n", GetLastError());
253 if(pCryptDuplicateHash) {
254 result = pCryptDuplicateHash(hHash, 0, 0, &hHashClone);
255 ok(result, "%08lx\n", GetLastError());
257 result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
258 ok(result, "%08lx\n", GetLastError());
261 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
262 ok(result && (hashlen == 20), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
265 result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
266 ok(result, "%08lx\n", GetLastError());
268 ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
270 result = CryptDestroyHash(hHashClone);
271 ok(result, "%08lx\n", GetLastError());
274 result = CryptDestroyHash(hHash);
275 ok(result, "%08lx\n", GetLastError());
278 static void test_block_cipher_modes(void)
280 static const BYTE plain[23] = {
281 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
282 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
283 static const BYTE ecb[24] = {
284 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
285 0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
286 static const BYTE cbc[24] = {
287 0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
288 0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
289 static const BYTE cfb[24] = {
290 0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
291 0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
297 result = derive_key(CALG_RC2, &hKey, 40);
300 memcpy(abData, plain, sizeof(abData));
302 dwMode = CRYPT_MODE_ECB;
303 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
304 ok(result, "%08lx\n", GetLastError());
306 SetLastError(ERROR_SUCCESS);
308 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
309 ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
310 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
312 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
313 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
314 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
316 dwMode = CRYPT_MODE_CBC;
317 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
318 ok(result, "%08lx\n", GetLastError());
321 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
322 ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
323 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
325 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
326 ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
327 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
329 dwMode = CRYPT_MODE_CFB;
330 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
331 ok(result, "%08lx\n", GetLastError());
334 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen, 24);
335 ok(result && dwLen == 16, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
338 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+16, &dwLen, 8);
339 ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
340 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
343 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen);
344 ok(result && dwLen == 8, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
347 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+8, &dwLen);
348 ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
349 "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
351 dwMode = CRYPT_MODE_OFB;
352 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
353 ok(result, "%08lx\n", GetLastError());
356 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
357 ok(!result && GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
360 static void test_3des112(void)
365 unsigned char pbData[16];
368 result = derive_key(CALG_3DES_112, &hKey, 0);
370 /* rsaenh compiled without OpenSSL */
371 ok(GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
375 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
378 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
379 ok(result, "%08lx\n", GetLastError());
381 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
382 ok(result, "%08lx\n", GetLastError());
384 result = CryptDestroyKey(hKey);
385 ok(result, "%08lx\n", GetLastError());
388 static void test_des(void)
393 unsigned char pbData[16];
396 result = derive_key(CALG_DES, &hKey, 56);
398 /* rsaenh compiled without OpenSSL */
399 ok(GetLastError()==NTE_BAD_ALGID, "%08lx\n", GetLastError());
403 dwMode = CRYPT_MODE_ECB;
404 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
405 ok(result, "%08lx\n", GetLastError());
407 dwLen = sizeof(DWORD);
408 result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
409 ok(result, "%08lx\n", GetLastError());
411 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
414 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
415 ok(result, "%08lx\n", GetLastError());
417 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
418 ok(result, "%08lx\n", GetLastError());
420 result = CryptDestroyKey(hKey);
421 ok(result, "%08lx\n", GetLastError());
424 static void test_3des(void)
429 unsigned char pbData[16];
430 static const BYTE des3[16] = {
431 0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
432 0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
435 result = derive_key(CALG_3DES, &hKey, 0);
438 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
441 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
442 ok(result, "%08lx\n", GetLastError());
444 ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
446 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
447 ok(result, "%08lx\n", GetLastError());
449 result = CryptDestroyKey(hKey);
450 ok(result, "%08lx\n", GetLastError());
453 static void test_rc2(void)
455 static const BYTE rc2encrypted[16] = {
456 0x02, 0x34, 0x7d, 0xf6, 0x1d, 0xc5, 0x9b, 0x8b,
457 0x2e, 0x0d, 0x63, 0x80, 0x72, 0xc1, 0xc2, 0xb1 };
461 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
463 unsigned char pbData[2000], pbHashValue[16];
466 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
469 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
471 ok(GetLastError()==NTE_BAD_ALGID, "%08lx\n", GetLastError());
473 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
474 ok(result, "%08lx\n", GetLastError());
477 result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
478 ok(result, "%08lx\n", GetLastError());
480 result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
481 ok(result, "%08lx\n", GetLastError());
483 dwLen = sizeof(DWORD);
484 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
485 ok(result, "%08lx\n", GetLastError());
487 dwMode = CRYPT_MODE_CBC;
488 result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
489 ok(result, "%08lx\n", GetLastError());
491 dwLen = sizeof(DWORD);
492 result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
493 ok(result, "%08lx\n", GetLastError());
495 dwLen = sizeof(DWORD);
496 result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
497 ok(result, "%08lx\n", GetLastError());
499 dwLen = sizeof(DWORD);
500 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
501 ok(result, "%08lx\n", GetLastError());
503 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
504 ok(result, "%08lx\n", GetLastError());
505 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
506 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
507 HeapFree(GetProcessHeap(), 0, pbTemp);
509 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
510 ok(result, "%08lx\n", GetLastError());
511 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
512 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
513 HeapFree(GetProcessHeap(), 0, pbTemp);
515 dwLen = sizeof(DWORD);
516 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
518 result = CryptDestroyHash(hHash);
519 ok(result, "%08lx\n", GetLastError());
522 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
523 ok(result, "%08lx\n", GetLastError());
525 ok(!memcmp(pbData, rc2encrypted, 8), "RC2 encryption failed!\n");
527 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
528 ok(result, "%08lx\n", GetLastError());
529 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
530 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
531 HeapFree(GetProcessHeap(), 0, pbTemp);
533 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
534 ok(result, "%08lx\n", GetLastError());
536 result = CryptDestroyKey(hKey);
537 ok(result, "%08lx\n", GetLastError());
541 static void test_rc4(void)
543 static const BYTE rc4[16] = {
544 0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
545 0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
549 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
550 unsigned char pbData[2000], *pbTemp;
551 unsigned char pszBuffer[256];
554 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
557 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
559 /* rsaenh compiled without OpenSSL */
560 ok(GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
562 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
563 ok(result, "%08lx\n", GetLastError());
566 result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
567 ok(result, "%08lx\n", GetLastError());
569 result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
570 ok(result, "%08lx\n", GetLastError());
572 dwLen = sizeof(DWORD);
573 result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
574 ok(result, "%08lx\n", GetLastError());
576 dwLen = sizeof(DWORD);
577 result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
578 ok(result, "%08lx\n", GetLastError());
580 result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
581 ok(result, "%08lx\n", GetLastError());
582 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
583 CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
584 HeapFree(GetProcessHeap(), 0, pbTemp);
586 result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
587 ok(result, "%08lx\n", GetLastError());
588 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
589 CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
590 HeapFree(GetProcessHeap(), 0, pbTemp);
592 dwLen = sizeof(DWORD);
593 CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
595 result = CryptDestroyHash(hHash);
596 ok(result, "%08lx\n", GetLastError());
599 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
600 ok(result, "%08lx\n", GetLastError());
602 ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
604 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
605 ok(result, "%08lx\n", GetLastError());
607 result = CryptDestroyKey(hKey);
608 ok(result, "%08lx\n", GetLastError());
612 static void test_hmac(void) {
616 HMAC_INFO hmacInfo = { CALG_MD2, NULL, 0, NULL, 0 };
619 static const BYTE hmac[16] = {
620 0xfd, 0x16, 0xb5, 0xb6, 0x13, 0x1c, 0x2b, 0xd6,
621 0x0a, 0xc7, 0xae, 0x92, 0x76, 0xa3, 0x05, 0x71 };
624 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
626 if (!derive_key(CALG_RC2, &hKey, 56)) return;
628 result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
629 ok(result, "%08lx\n", GetLastError());
632 result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
633 ok(result, "%08lx\n", GetLastError());
635 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
636 ok(result, "%08lx\n", GetLastError());
638 dwLen = sizeof(abData)/sizeof(BYTE);
639 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
640 ok(result, "%08lx\n", GetLastError());
642 ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
644 result = CryptDestroyHash(hHash);
645 ok(result, "%08lx\n", GetLastError());
647 result = CryptDestroyKey(hKey);
648 ok(result, "%08lx\n", GetLastError());
651 result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
652 ok(!result && GetLastError() == NTE_BAD_KEY, "%08lx\n", GetLastError());
655 static void test_mac(void) {
660 BYTE abData[256], abEnc[264];
661 static const BYTE mac[8] = { 0x0d, 0x3e, 0x15, 0x6b, 0x85, 0x63, 0x5c, 0x11 };
664 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
665 for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
667 if (!derive_key(CALG_RC2, &hKey, 56)) return;
670 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abEnc, &dwLen, 264);
671 ok (result && dwLen == 264, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
673 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
674 ok(result, "%08lx\n", GetLastError());
677 result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
678 ok(result, "%08lx\n", GetLastError());
680 dwLen = sizeof(abData)/sizeof(BYTE);
681 result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
682 ok(result && dwLen == 8, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
684 ok(!memcmp(abData, mac, sizeof(mac)), "MAC failed!\n");
686 result = CryptDestroyHash(hHash);
687 ok(result, "%08lx\n", GetLastError());
689 result = CryptDestroyKey(hKey);
690 ok(result, "%08lx\n", GetLastError());
693 if (!derive_key(CALG_RC4, &hKey, 56)) return;
695 result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
696 ok(!result && GetLastError() == NTE_BAD_KEY, "%08lx\n", GetLastError());
698 result = CryptDestroyKey(hKey);
699 ok(result, "%08lx\n", GetLastError());
702 static void test_import_private(void)
705 HCRYPTKEY hKeyExchangeKey, hSessionKey;
707 BYTE abPlainPrivateKey[596] = {
708 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
709 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
710 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
711 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
712 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
713 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
714 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
715 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
716 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
717 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
718 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
719 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
720 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
721 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
722 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
723 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
724 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
725 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
726 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
727 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
728 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
729 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
730 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
731 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
732 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
733 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
734 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
735 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
736 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
737 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
738 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
739 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
740 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
741 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
742 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
743 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
744 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
745 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
746 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
747 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
748 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
749 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
750 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
751 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
752 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
753 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
754 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
755 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
756 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
757 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
758 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
759 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
760 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
761 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
762 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
763 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
764 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
765 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
766 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
767 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
768 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
769 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
770 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
771 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
772 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
773 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
774 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
775 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
776 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
777 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
778 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
779 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
780 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
781 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
782 0xf2, 0x5d, 0x58, 0x07
784 BYTE abSessionKey[148] = {
785 0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
786 0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
787 0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
788 0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
789 0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
790 0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
791 0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
792 0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
793 0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
794 0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
795 0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
796 0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
797 0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
798 0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
799 0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
800 0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
801 0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
802 0x04, 0x8c, 0x49, 0x92
804 BYTE abEncryptedMessage[12] = {
805 0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
806 0x1c, 0xfd, 0xde, 0x71
809 dwLen = (DWORD)sizeof(abPlainPrivateKey);
810 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
812 /* rsaenh compiled without OpenSSL */
813 ok(GetLastError() == NTE_FAIL, "%08lx\n", GetLastError());
817 dwLen = (DWORD)sizeof(abSessionKey);
818 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
819 ok(result, "%08lx\n", GetLastError());
822 dwLen = (DWORD)sizeof(abEncryptedMessage);
823 result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
824 ok(result && dwLen == 12 && !memcmp(abEncryptedMessage, "Wine rocks!",12),
825 "%08lx, len: %ld\n", GetLastError(), dwLen);
827 if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
829 dwLen = (DWORD)sizeof(abSessionKey);
830 result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
831 ok(result, "%08lx\n", GetLastError());
834 dwLen = (DWORD)sizeof(abSessionKey);
835 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
836 ok(result, "%08lx\n", GetLastError());
840 static void test_verify_signature(void) {
842 HCRYPTKEY hPubSignKey;
843 BYTE abData[] = "Wine rocks!";
845 BYTE abPubKey[148] = {
846 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
847 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
848 0x01, 0x00, 0x01, 0x00, 0x71, 0x64, 0x9f, 0x19,
849 0x89, 0x1c, 0x21, 0xcc, 0x36, 0xa3, 0xc9, 0x27,
850 0x08, 0x8a, 0x09, 0xc6, 0xbe, 0xeb, 0xd3, 0xf8,
851 0x19, 0xa9, 0x92, 0x57, 0xe4, 0xb9, 0x5d, 0xda,
852 0x88, 0x93, 0xe4, 0x6b, 0x38, 0x77, 0x14, 0x8a,
853 0x96, 0xc0, 0xb6, 0x4e, 0x42, 0xf5, 0x01, 0xdc,
854 0xf0, 0xeb, 0x3c, 0xc7, 0x7b, 0xc4, 0xfd, 0x7c,
855 0xde, 0x93, 0x34, 0x0a, 0x92, 0xe5, 0x97, 0x9c,
856 0x3e, 0x65, 0xb8, 0x91, 0x2f, 0xe3, 0xf3, 0x89,
857 0xcd, 0x6c, 0x26, 0xa4, 0x6c, 0xc7, 0x6d, 0x0b,
858 0x2c, 0xa2, 0x0b, 0x29, 0xe2, 0xfc, 0x30, 0xfa,
859 0x20, 0xdb, 0x4c, 0xb8, 0x91, 0xb8, 0x69, 0x63,
860 0x96, 0x41, 0xc2, 0xb4, 0x60, 0xeb, 0xcd, 0xff,
861 0x3a, 0x1f, 0x94, 0xb1, 0x23, 0xcf, 0x0f, 0x49,
862 0xad, 0xd5, 0x33, 0x85, 0x71, 0xaf, 0x12, 0x87,
863 0x84, 0xef, 0xa0, 0xea, 0xe1, 0xc1, 0xd4, 0xc7,
864 0xe1, 0x21, 0x50, 0xac
866 /* md2 with hash oid */
867 BYTE abSignatureMD2[128] = {
868 0x4a, 0x4e, 0xb7, 0x5e, 0x32, 0xda, 0xdb, 0x67,
869 0x9f, 0x77, 0x84, 0x32, 0x00, 0xba, 0x5f, 0x6b,
870 0x0d, 0xcf, 0xd9, 0x99, 0xbd, 0x96, 0x31, 0xda,
871 0x23, 0x4c, 0xd9, 0x4a, 0x90, 0x84, 0x20, 0x59,
872 0x51, 0xdc, 0xd4, 0x93, 0x3a, 0xae, 0x0a, 0x0a,
873 0xa1, 0x76, 0xfa, 0xb5, 0x68, 0xee, 0xc7, 0x34,
874 0x41, 0xd3, 0xe7, 0x5a, 0x0e, 0x22, 0x61, 0x40,
875 0xea, 0x24, 0x56, 0xf1, 0x91, 0x5a, 0xf7, 0xa7,
876 0x5b, 0xf4, 0x98, 0x6b, 0xc3, 0xef, 0xad, 0xc0,
877 0x5e, 0x6b, 0x87, 0x76, 0xcb, 0x1f, 0x62, 0x06,
878 0x7c, 0xf6, 0x48, 0x97, 0x81, 0x8d, 0xef, 0x51,
879 0x51, 0xdc, 0x21, 0x91, 0x57, 0x1e, 0x79, 0x6f,
880 0x49, 0xb5, 0xde, 0x31, 0x07, 0x45, 0x99, 0x46,
881 0xc3, 0x4f, 0xca, 0x2d, 0x0e, 0x4c, 0x10, 0x25,
882 0xcb, 0x1a, 0x98, 0x63, 0x41, 0x93, 0x47, 0xc0,
883 0xb2, 0xbc, 0x10, 0x3c, 0xe7, 0xd4, 0x3c, 0x1e
885 /* md2 without hash oid */
886 BYTE abSignatureMD2NoOID[128] = {
887 0x0c, 0x21, 0x3e, 0x60, 0xf9, 0xd0, 0x36, 0x2d,
888 0xe1, 0x10, 0x45, 0x45, 0x85, 0x03, 0x29, 0x19,
889 0xef, 0x19, 0xd9, 0xa6, 0x7e, 0x9c, 0x0d, 0xbd,
890 0x03, 0x0e, 0xb9, 0x51, 0x9e, 0x74, 0x79, 0xc4,
891 0xde, 0x25, 0xf2, 0x35, 0x74, 0x55, 0xbc, 0x65,
892 0x7e, 0x33, 0x28, 0xa8, 0x1e, 0x72, 0xaa, 0x99,
893 0xdd, 0xf5, 0x26, 0x20, 0x29, 0xf8, 0xa6, 0xdf,
894 0x28, 0x4b, 0x1c, 0xdb, 0xa1, 0x41, 0x56, 0xbc,
895 0xf9, 0x9c, 0x66, 0xc0, 0x37, 0x41, 0x55, 0xa0,
896 0xe2, 0xec, 0xbf, 0x71, 0xf0, 0x5d, 0x25, 0x01,
897 0x75, 0x91, 0xe2, 0x81, 0xb2, 0x9f, 0x57, 0xa7,
898 0x5c, 0xd2, 0xfa, 0x66, 0xdb, 0x71, 0x2b, 0x1f,
899 0xad, 0x30, 0xde, 0xea, 0x49, 0x73, 0x30, 0x6a,
900 0x22, 0x54, 0x49, 0x4e, 0xae, 0xf6, 0x88, 0xc9,
901 0xff, 0x71, 0xba, 0xbf, 0x27, 0xc5, 0xfa, 0x06,
902 0xe2, 0x91, 0x71, 0x8a, 0x7e, 0x0c, 0xc2, 0x07
904 /* md4 with hash oid */
905 BYTE abSignatureMD4[128] = {
906 0x1c, 0x78, 0xaa, 0xea, 0x74, 0xf4, 0x83, 0x51,
907 0xae, 0x66, 0xe3, 0xa9, 0x1c, 0x03, 0x39, 0x1b,
908 0xac, 0x7e, 0x4e, 0x85, 0x7e, 0x1c, 0x38, 0xd2,
909 0x82, 0x43, 0xb3, 0x6f, 0x6f, 0x46, 0x45, 0x8e,
910 0x17, 0x74, 0x58, 0x29, 0xca, 0xe1, 0x03, 0x13,
911 0x45, 0x79, 0x34, 0xdf, 0x5c, 0xd6, 0xc3, 0xf9,
912 0x7a, 0x1c, 0x9d, 0xff, 0x6f, 0x03, 0x7d, 0x0f,
913 0x59, 0x1a, 0x2d, 0x0e, 0x94, 0xb4, 0x75, 0x96,
914 0xd1, 0x48, 0x63, 0x6e, 0xb2, 0xc4, 0x5c, 0xd9,
915 0xab, 0x49, 0xb4, 0x90, 0xd9, 0x57, 0x04, 0x6e,
916 0x4c, 0xb6, 0xea, 0x00, 0x94, 0x4a, 0x34, 0xa0,
917 0xd9, 0x63, 0xef, 0x2c, 0xde, 0x5b, 0xb9, 0xbe,
918 0x35, 0xc8, 0xc1, 0x31, 0xb5, 0x31, 0x15, 0x18,
919 0x90, 0x39, 0xf5, 0x2a, 0x34, 0x6d, 0xb4, 0xab,
920 0x09, 0x34, 0x69, 0x54, 0x4d, 0x11, 0x2f, 0xf3,
921 0xa2, 0x36, 0x0e, 0xa8, 0x45, 0xe7, 0x36, 0xac
923 /* md4 without hash oid */
924 BYTE abSignatureMD4NoOID[128] = {
925 0xd3, 0x60, 0xb2, 0xb0, 0x22, 0x0a, 0x99, 0xda,
926 0x04, 0x85, 0x64, 0xc6, 0xc6, 0xdb, 0x11, 0x24,
927 0xe9, 0x68, 0x2d, 0xf7, 0x09, 0xef, 0xb6, 0xa0,
928 0xa2, 0xfe, 0x45, 0xee, 0x85, 0x49, 0xcd, 0x36,
929 0xf7, 0xc7, 0x9d, 0x2b, 0x4c, 0x68, 0xda, 0x85,
930 0x8c, 0x50, 0xcc, 0x4f, 0x4b, 0xe1, 0x82, 0xc3,
931 0xbe, 0xa3, 0xf1, 0x78, 0x6b, 0x60, 0x42, 0x3f,
932 0x67, 0x22, 0x14, 0xe4, 0xe1, 0xa4, 0x6e, 0xa9,
933 0x4e, 0xf1, 0xd4, 0xb0, 0xce, 0x82, 0xac, 0x06,
934 0xba, 0x2c, 0xbc, 0xf7, 0xcb, 0xf6, 0x0c, 0x3f,
935 0xf6, 0x79, 0xfe, 0xb3, 0xd8, 0x5a, 0xbc, 0xdb,
936 0x05, 0x41, 0xa4, 0x07, 0x57, 0x9e, 0xa2, 0x96,
937 0xfc, 0x60, 0x4b, 0xf7, 0x6f, 0x86, 0x26, 0x1f,
938 0xc2, 0x2c, 0x67, 0x08, 0xcd, 0x7f, 0x91, 0xe9,
939 0x16, 0xb5, 0x0e, 0xd9, 0xc4, 0xc4, 0x97, 0xeb,
940 0x91, 0x3f, 0x20, 0x6c, 0xf0, 0x68, 0x86, 0x7f
942 /* md5 with hash oid */
943 BYTE abSignatureMD5[128] = {
944 0x4f, 0xe0, 0x8c, 0x9b, 0x43, 0xdd, 0x02, 0xe5,
945 0xf4, 0xa1, 0xdd, 0x88, 0x4c, 0x9c, 0x40, 0x0f,
946 0x6c, 0x43, 0x86, 0x64, 0x00, 0xe6, 0xac, 0xf7,
947 0xd0, 0x92, 0xaa, 0xc4, 0x62, 0x9a, 0x48, 0x98,
948 0x1a, 0x56, 0x6d, 0x75, 0xec, 0x04, 0x89, 0xec,
949 0x69, 0x93, 0xd6, 0x61, 0x37, 0xb2, 0x36, 0xb5,
950 0xb2, 0xba, 0xf2, 0xf5, 0x21, 0x0c, 0xf1, 0x04,
951 0xc8, 0x2d, 0xf5, 0xa0, 0x8d, 0x6d, 0x10, 0x0b,
952 0x68, 0x63, 0xf2, 0x08, 0x68, 0xdc, 0xbd, 0x95,
953 0x25, 0x7d, 0xee, 0x63, 0x5c, 0x3b, 0x98, 0x4c,
954 0xea, 0x41, 0xdc, 0x6a, 0x8b, 0x6c, 0xbb, 0x29,
955 0x2b, 0x1c, 0x5c, 0x8b, 0x7d, 0x94, 0x24, 0xa9,
956 0x7a, 0x62, 0x94, 0xf3, 0x3a, 0x6a, 0xb2, 0x4c,
957 0x33, 0x59, 0x00, 0xcd, 0x7d, 0x37, 0x79, 0x90,
958 0x31, 0xd1, 0xd9, 0x84, 0x12, 0xe5, 0x08, 0x5e,
959 0xb3, 0x60, 0x61, 0x27, 0x78, 0x37, 0x63, 0x01
961 /* md5 without hash oid */
962 BYTE abSignatureMD5NoOID[128] = {
963 0xc6, 0xad, 0x5c, 0x2b, 0x9b, 0xe0, 0x99, 0x2f,
964 0x5e, 0x55, 0x04, 0x32, 0x65, 0xe0, 0xb5, 0x75,
965 0x01, 0x9a, 0x11, 0x4d, 0x0e, 0x9a, 0xe1, 0x9f,
966 0xc7, 0xbf, 0x77, 0x6d, 0xa9, 0xfd, 0xcc, 0x9d,
967 0x8b, 0xd1, 0x31, 0xed, 0x5a, 0xd2, 0xe5, 0x5f,
968 0x42, 0x3b, 0xb5, 0x3c, 0x32, 0x30, 0x88, 0x49,
969 0xcb, 0x67, 0xb8, 0x2e, 0xc9, 0xf5, 0x2b, 0xc8,
970 0x35, 0x71, 0xb5, 0x1b, 0x32, 0x3f, 0x44, 0x4c,
971 0x66, 0x93, 0xcb, 0xe8, 0x48, 0x7c, 0x14, 0x23,
972 0xfb, 0x12, 0xa5, 0xb7, 0x86, 0x94, 0x6b, 0x19,
973 0x17, 0x20, 0xc6, 0xb8, 0x09, 0xe8, 0xbb, 0xdb,
974 0x00, 0x2b, 0x96, 0x4a, 0x93, 0x00, 0x26, 0xd3,
975 0x07, 0xa0, 0x06, 0xce, 0x5a, 0x13, 0x69, 0x6b,
976 0x62, 0x5a, 0x56, 0x61, 0x6a, 0xd8, 0x11, 0x3b,
977 0xd5, 0x67, 0xc7, 0x4d, 0xf6, 0x66, 0x63, 0xc5,
978 0xe3, 0x8f, 0x7c, 0x7c, 0xb1, 0x3e, 0x55, 0x43
980 /* sha with hash oid */
981 BYTE abSignatureSHA[128] = {
982 0x5a, 0x4c, 0x66, 0xc9, 0x30, 0x67, 0xcb, 0x91,
983 0x3c, 0x4d, 0xd5, 0x8d, 0xea, 0x4e, 0x85, 0xcd,
984 0xd9, 0x68, 0x3a, 0xf3, 0x24, 0x3c, 0x99, 0x24,
985 0x25, 0x32, 0x93, 0x3d, 0xd6, 0x2f, 0x86, 0x94,
986 0x23, 0x09, 0xee, 0x02, 0xd4, 0x15, 0xdc, 0x5f,
987 0x0e, 0x44, 0x45, 0x13, 0x5f, 0x18, 0x5d, 0x1a,
988 0xd7, 0x0b, 0xd1, 0x23, 0xd6, 0x35, 0x98, 0x52,
989 0x57, 0x45, 0x74, 0x92, 0xe3, 0x50, 0xb4, 0x20,
990 0x28, 0x2a, 0x11, 0xbf, 0x49, 0xb4, 0x2c, 0xc5,
991 0xd4, 0x1a, 0x27, 0x4e, 0xdf, 0xa0, 0xb5, 0x7a,
992 0xc8, 0x14, 0xdd, 0x9b, 0xb6, 0xca, 0xd6, 0xff,
993 0xb2, 0x6b, 0xd8, 0x98, 0x67, 0x80, 0xab, 0x53,
994 0x52, 0xbb, 0xe1, 0x2a, 0xce, 0x79, 0x2f, 0x00,
995 0x53, 0x26, 0xd8, 0xa7, 0x43, 0xca, 0x72, 0x0e,
996 0x68, 0x97, 0x37, 0x71, 0x87, 0xc2, 0x6a, 0x98,
997 0xbb, 0x6c, 0xa0, 0x01, 0xff, 0x04, 0x9d, 0xa6
999 /* sha without hash oid */
1000 BYTE abSignatureSHANoOID[128] = {
1001 0x86, 0xa6, 0x2b, 0x9a, 0x04, 0xda, 0x47, 0xc6,
1002 0x4f, 0x97, 0x8a, 0x8a, 0xf4, 0xfa, 0x63, 0x1a,
1003 0x32, 0x89, 0x56, 0x41, 0x37, 0x91, 0x15, 0x2f,
1004 0x2d, 0x1c, 0x8f, 0xdc, 0x88, 0x40, 0xbb, 0x37,
1005 0x3e, 0x06, 0x33, 0x1b, 0xde, 0xda, 0x7c, 0x65,
1006 0x91, 0x35, 0xca, 0x45, 0x17, 0x0e, 0x24, 0xbe,
1007 0x9e, 0xf6, 0x4e, 0x8a, 0xa4, 0x3e, 0xca, 0xe6,
1008 0x11, 0x36, 0xb8, 0x3a, 0xf0, 0xde, 0x71, 0xfe,
1009 0xdd, 0xb3, 0xcb, 0x6c, 0x39, 0xe0, 0x5f, 0x0c,
1010 0x9e, 0xa8, 0x40, 0x26, 0x9c, 0x81, 0xe9, 0xc4,
1011 0x15, 0x90, 0xbf, 0x4f, 0xd2, 0xc1, 0xa1, 0x80,
1012 0x52, 0xfd, 0xf6, 0x3d, 0x99, 0x1b, 0x9c, 0x8a,
1013 0x27, 0x1b, 0x0c, 0x9a, 0xf3, 0xf9, 0xa2, 0x00,
1014 0x3e, 0x5b, 0xdf, 0xc2, 0xb4, 0x71, 0xa5, 0xbd,
1015 0xf8, 0xae, 0x63, 0xbb, 0x4a, 0xc9, 0xdd, 0x67,
1016 0xc1, 0x3e, 0x93, 0xee, 0xf1, 0x1f, 0x24, 0x5b
1019 result = CryptImportKey(hProv, abPubKey, 148, 0, 0, &hPubSignKey);
1020 ok(result, "%08lx\n", GetLastError());
1021 if (!result) return;
1023 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
1024 ok(result, "%08lx\n", GetLastError());
1025 if (!result) return;
1027 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1028 ok(result, "%08lx\n", GetLastError());
1029 if (!result) return;
1031 result = CryptVerifySignature(hHash, abSignatureMD2, 128, hPubSignKey, NULL, 0);
1032 ok(result, "%08lx\n", GetLastError());
1033 if (!result) return;
1035 result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1036 ok(result, "%08lx\n", GetLastError());
1037 if (!result) return;
1039 /* Next test fails on WinXP SP2. It seems that CPVerifySignature doesn't care about
1040 * the OID at all. */
1041 /*result = CryptVerifySignature(hHash, abSignatureMD2NoOID, 128, hPubSignKey, NULL, 0);
1042 ok(!result && GetLastError()==NTE_BAD_SIGNATURE, "%08lx\n", GetLastError());
1043 if (result) return;*/
1045 result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
1046 ok(result, "%08lx\n", GetLastError());
1047 if (!result) return;
1049 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1050 ok(result, "%08lx\n", GetLastError());
1051 if (!result) return;
1053 result = CryptVerifySignature(hHash, abSignatureMD4, 128, hPubSignKey, NULL, 0);
1054 ok(result, "%08lx\n", GetLastError());
1055 if (!result) return;
1057 result = CryptVerifySignature(hHash, abSignatureMD4NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1058 ok(result, "%08lx\n", GetLastError());
1059 if (!result) return;
1061 result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
1062 ok(result, "%08lx\n", GetLastError());
1063 if (!result) return;
1065 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1066 ok(result, "%08lx\n", GetLastError());
1067 if (!result) return;
1069 result = CryptVerifySignature(hHash, abSignatureMD5, 128, hPubSignKey, NULL, 0);
1070 ok(result, "%08lx\n", GetLastError());
1071 if (!result) return;
1073 result = CryptVerifySignature(hHash, abSignatureMD5NoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1074 ok(result, "%08lx\n", GetLastError());
1075 if (!result) return;
1077 result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
1078 ok(result, "%08lx\n", GetLastError());
1079 if (!result) return;
1081 result = CryptHashData(hHash, abData, (DWORD)sizeof(abData), 0);
1082 ok(result, "%08lx\n", GetLastError());
1083 if (!result) return;
1085 result = CryptVerifySignature(hHash, abSignatureSHA, 128, hPubSignKey, NULL, 0);
1086 ok(result, "%08lx\n", GetLastError());
1087 if (!result) return;
1089 result = CryptVerifySignature(hHash, abSignatureSHANoOID, 128, hPubSignKey, NULL, CRYPT_NOHASHOID);
1090 ok(result, "%08lx\n", GetLastError());
1091 if (!result) return;
1094 static void test_rsa_encrypt(void)
1097 BYTE abData[2048] = "Wine rocks!";
1101 /* It is allowed to use the key exchange key for encryption/decryption */
1102 result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey);
1103 ok (result, "%08lx\n", GetLastError());
1104 if (!result) return;
1107 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1108 ok (result, "%08lx\n", GetLastError());
1109 if (!result) return;
1111 result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen);
1112 ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08lx\n", GetLastError());
1114 CryptDestroyKey(hRSAKey);
1116 /* It is not allowed to use the signature key for encryption/decryption */
1117 result = CryptGetUserKey(hProv, AT_SIGNATURE, &hRSAKey);
1118 ok (result, "%08lx\n", GetLastError());
1119 if (!result) return;
1122 result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData));
1123 ok (!result && GetLastError() == NTE_BAD_KEY, "%08lx\n", GetLastError());
1125 CryptDestroyKey(hRSAKey);
1128 static void test_schannel_provider(void)
1131 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1132 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1135 SCHANNEL_ALG saSChannelAlg;
1136 CRYPT_DATA_BLOB data_blob;
1137 HMAC_INFO hmacInfo = { CALG_MD5, NULL, 0, NULL, 0 };
1138 BYTE abPlainPrivateKey[596] = {
1139 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
1140 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
1141 0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
1142 0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
1143 0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
1144 0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
1145 0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
1146 0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
1147 0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
1148 0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
1149 0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
1150 0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
1151 0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
1152 0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
1153 0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
1154 0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
1155 0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
1156 0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
1157 0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
1158 0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
1159 0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
1160 0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
1161 0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
1162 0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
1163 0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
1164 0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
1165 0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
1166 0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
1167 0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
1168 0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
1169 0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
1170 0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
1171 0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
1172 0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
1173 0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
1174 0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
1175 0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
1176 0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
1177 0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
1178 0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
1179 0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
1180 0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
1181 0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
1182 0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
1183 0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
1184 0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
1185 0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
1186 0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
1187 0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
1188 0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
1189 0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
1190 0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
1191 0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
1192 0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
1193 0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
1194 0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
1195 0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
1196 0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
1197 0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
1198 0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
1199 0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
1200 0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
1201 0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
1202 0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
1203 0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
1204 0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
1205 0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
1206 0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
1207 0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
1208 0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
1209 0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
1210 0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
1211 0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
1212 0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
1213 0xf2, 0x5d, 0x58, 0x07
1215 BYTE abTLS1Master[140] = {
1216 0x01, 0x02, 0x00, 0x00, 0x06, 0x4c, 0x00, 0x00,
1217 0x00, 0xa4, 0x00, 0x00, 0x5b, 0x13, 0xc7, 0x68,
1218 0xd8, 0x55, 0x23, 0x5d, 0xbc, 0xa6, 0x9d, 0x97,
1219 0x0e, 0xcd, 0x6b, 0xcf, 0xc0, 0xdc, 0xc5, 0x53,
1220 0x28, 0xa0, 0xca, 0xc1, 0x63, 0x4e, 0x3a, 0x24,
1221 0x22, 0xe5, 0x4d, 0x15, 0xbb, 0xa5, 0x06, 0xc3,
1222 0x98, 0x25, 0xdc, 0x35, 0xd3, 0xdb, 0xab, 0xb8,
1223 0x44, 0x1b, 0xfe, 0x63, 0x88, 0x7c, 0x2e, 0x6d,
1224 0x34, 0xd9, 0x0f, 0x7e, 0x2f, 0xc2, 0xb2, 0x6e,
1225 0x56, 0xfa, 0xab, 0xb2, 0x88, 0xf6, 0x15, 0x6e,
1226 0xa8, 0xcd, 0x70, 0x16, 0x94, 0x61, 0x07, 0x40,
1227 0x9e, 0x25, 0x22, 0xf8, 0x64, 0x9f, 0xcc, 0x0b,
1228 0xf1, 0x92, 0x4d, 0xfe, 0xc3, 0x5d, 0x52, 0xdb,
1229 0x0f, 0xff, 0x12, 0x0f, 0x49, 0x43, 0x7d, 0xc6,
1230 0x52, 0x61, 0xb0, 0x06, 0xc8, 0x1b, 0x90, 0xac,
1231 0x09, 0x7e, 0x4b, 0x95, 0x69, 0x3b, 0x0d, 0x41,
1232 0x1b, 0x4c, 0x65, 0x75, 0x4d, 0x85, 0x16, 0xc4,
1233 0xd3, 0x1e, 0x82, 0xb3
1235 BYTE abServerSecret[33] = "Super Secret Server Secret 12345";
1236 BYTE abClientSecret[33] = "Super Secret Client Secret 12345";
1237 BYTE abHashedHandshakes[37] = "123456789012345678901234567890123456";
1238 BYTE abClientFinished[16] = "client finished";
1239 BYTE abData[16] = "Wine rocks!";
1241 static const BYTE abEncryptedData[16] = {
1242 0x13, 0xd2, 0xdd, 0xeb, 0x6c, 0x3f, 0xbe, 0xb2,
1243 0x04, 0x86, 0xb5, 0xe5, 0x08, 0xe5, 0xf3, 0x0d
1245 static const BYTE abPRF[16] = {
1246 0xa8, 0xb2, 0xa6, 0xef, 0x83, 0x4e, 0x74, 0xb1,
1247 0xf3, 0xb1, 0x51, 0x5a, 0x1a, 0x2b, 0x11, 0x31
1249 static const BYTE abMD5[16] = {
1250 0xe1, 0x65, 0x3f, 0xdb, 0xbb, 0x3d, 0x99, 0x3c,
1251 0x3d, 0xca, 0x6a, 0x6f, 0xfa, 0x15, 0x4e, 0xaa
1254 result = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
1255 ok (result, "%08lx\n", GetLastError());
1256 if (!result) return;
1258 /* To get deterministic results, we import the TLS1 master secret (which
1259 * is typically generated from a random generator). Therefore, we need
1261 dwLen = (DWORD)sizeof(abPlainPrivateKey);
1262 result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hRSAKey);
1263 ok (result, "%08lx\n", GetLastError());
1264 if (!result) return;
1266 dwLen = (DWORD)sizeof(abTLS1Master);
1267 result = CryptImportKey(hProv, abTLS1Master, dwLen, hRSAKey, 0, &hMasterSecret);
1268 ok (result, "%08lx\n", GetLastError());
1269 if (!result) return;
1271 /* Setting the TLS1 client and server random parameters, as well as the
1272 * MAC and encryption algorithm parameters. */
1273 data_blob.cbData = 33;
1274 data_blob.pbData = abClientSecret;
1275 result = CryptSetKeyParam(hMasterSecret, KP_CLIENT_RANDOM, (BYTE*)&data_blob, 0);
1276 ok (result, "%08lx\n", GetLastError());
1277 if (!result) return;
1279 data_blob.cbData = 33;
1280 data_blob.pbData = abServerSecret;
1281 result = CryptSetKeyParam(hMasterSecret, KP_SERVER_RANDOM, (BYTE*)&data_blob, 0);
1282 ok (result, "%08lx\n", GetLastError());
1283 if (!result) return;
1285 saSChannelAlg.dwUse = SCHANNEL_ENC_KEY;
1286 saSChannelAlg.Algid = CALG_DES;
1287 saSChannelAlg.cBits = 64;
1288 saSChannelAlg.dwFlags = 0;
1289 saSChannelAlg.dwReserved = 0;
1290 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1291 ok (result, "%08lx\n", GetLastError());
1292 if (!result) return;
1294 saSChannelAlg.dwUse = SCHANNEL_MAC_KEY;
1295 saSChannelAlg.Algid = CALG_MD5;
1296 saSChannelAlg.cBits = 128;
1297 saSChannelAlg.dwFlags = 0;
1298 saSChannelAlg.dwReserved = 0;
1299 result = CryptSetKeyParam(hMasterSecret, KP_SCHANNEL_ALG, (PBYTE)&saSChannelAlg, 0);
1300 ok (result, "%08lx\n", GetLastError());
1301 if (!result) return;
1303 /* Deriving a hash from the master secret. This is due to the CryptoAPI architecture.
1304 * (Keys can only be derived from hashes, not from other keys.) */
1305 result = CryptCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, hMasterSecret, 0, &hMasterHash);
1306 ok (result, "%08lx\n", GetLastError());
1307 if (!result) return;
1309 /* Deriving the server write encryption key from the master hash */
1310 result = CryptDeriveKey(hProv, CALG_SCHANNEL_ENC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteKey);
1311 ok (result, "%08lx\n", GetLastError());
1312 if (!result) return;
1314 /* Encrypting some data with the server write encryption key and checking the result. */
1316 result = CryptEncrypt(hServerWriteKey, 0, TRUE, 0, abData, &dwLen, 16);
1317 ok (result && (dwLen == 16) && !memcmp(abData, abEncryptedData, 16), "%08lx\n", GetLastError());
1319 /* Second test case: Test the TLS1 pseudo random number function. */
1320 result = CryptCreateHash(hProv, CALG_TLS1PRF, hMasterSecret, 0, &hTLS1PRF);
1321 ok (result, "%08lx\n", GetLastError());
1322 if (!result) return;
1324 /* Set the label and seed parameters for the random number function */
1325 data_blob.cbData = 36;
1326 data_blob.pbData = abHashedHandshakes;
1327 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_SEED, (BYTE*)&data_blob, 0);
1328 ok (result, "%08lx\n", GetLastError());
1329 if (!result) return;
1331 data_blob.cbData = 15;
1332 data_blob.pbData = abClientFinished;
1333 result = CryptSetHashParam(hTLS1PRF, HP_TLS1PRF_LABEL, (BYTE*)&data_blob, 0);
1334 ok (result, "%08lx\n", GetLastError());
1335 if (!result) return;
1337 /* Generate some pseudo random bytes and check if they are correct. */
1338 dwLen = (DWORD)sizeof(abData);
1339 result = CryptGetHashParam(hTLS1PRF, HP_HASHVAL, abData, &dwLen, 0);
1340 ok (result && (dwLen==(DWORD)sizeof(abData)) && !memcmp(abData, abPRF, sizeof(abData)),
1341 "%08lx\n", GetLastError());
1343 /* Third test case. Derive the server write mac key. Derive an HMAC object from this one.
1344 * Hash some data with the HMAC. Compare results. */
1345 result = CryptDeriveKey(hProv, CALG_SCHANNEL_MAC_KEY, hMasterHash, CRYPT_SERVER, &hServerWriteMACKey);
1346 ok (result, "%08lx\n", GetLastError());
1347 if (!result) return;
1349 result = CryptCreateHash(hProv, CALG_HMAC, hServerWriteMACKey, 0, &hHMAC);
1350 ok (result, "%08lx\n", GetLastError());
1351 if (!result) return;
1353 result = CryptSetHashParam(hHMAC, HP_HMAC_INFO, (PBYTE)&hmacInfo, 0);
1354 ok (result, "%08lx\n", GetLastError());
1355 if (!result) return;
1357 result = CryptHashData(hHMAC, abData, (DWORD)sizeof(abData), 0);
1358 ok (result, "%08lx\n", GetLastError());
1359 if (!result) return;
1361 dwLen = (DWORD)sizeof(abMD5Hash);
1362 result = CryptGetHashParam(hHMAC, HP_HASHVAL, abMD5Hash, &dwLen, 0);
1363 ok (result && (dwLen == 16) && !memcmp(abMD5Hash, abMD5, 16), "%08lx\n", GetLastError());
1365 CryptDestroyHash(hHMAC);
1366 CryptDestroyHash(hTLS1PRF);
1367 CryptDestroyHash(hMasterHash);
1368 CryptDestroyKey(hServerWriteMACKey);
1369 CryptDestroyKey(hServerWriteKey);
1370 CryptDestroyKey(hRSAKey);
1371 CryptDestroyKey(hMasterSecret);
1372 CryptReleaseContext(hProv, 0);
1375 static void test_enum_container(void)
1377 BYTE abContainerName[256];
1379 BOOL result, fFound = FALSE;
1381 /* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
1382 * the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
1383 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
1384 ok (result && dwBufferLen == MAX_PATH + 1, "%08lx\n", GetLastError());
1386 /* If the result fits into abContainerName dwBufferLen is left untouched */
1387 dwBufferLen = (DWORD)sizeof(abContainerName);
1388 result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
1389 ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08lx\n", GetLastError());
1391 /* We only check, if the currently open 'winetest' container is among the enumerated. */
1393 if (!strcmp((const char*)abContainerName, "winetest")) fFound = TRUE;
1394 dwBufferLen = (DWORD)sizeof(abContainerName);
1395 } while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
1397 ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08lx\n", fFound, GetLastError());
1402 if (!init_environment())
1414 test_block_cipher_modes();
1415 test_import_private();
1416 test_verify_signature();
1418 test_enum_container();
1419 clean_up_environment();
1420 test_schannel_provider();