tools/c2man.pl: Generate correct html.
[wine/testsucceed.git] / dlls / rsaenh / tests / rsaenh.c
blobf92fb9714a8cbb78077dc2270934d18b3a669419
1 /*
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <string.h>
22 #include <stdio.h>
23 #include "wine/test.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "wincrypt.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) {
38 char szTemp[256];
39 DWORD i, j;
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]);
45 trace(szTemp);
47 for (j=0; i<dwLen; j++,i++) {
48 sprintf(szTemp+6*j, "0x%02x, \n", pbData[i]);
50 trace(szTemp);
54 static int init_environment(void)
56 HCRYPTKEY hKey;
57 BOOL result;
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,
71 CRYPT_NEWKEYSET);
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);
81 return 1;
84 static void clean_up_environment(void)
86 BOOL result;
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)
96 BOOL result;
97 DWORD dwLen, dwInc;
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)
110 BOOL result;
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 */
119 return;
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)
132 HCRYPTHASH hHash;
133 BOOL result;
134 unsigned char pbData[2000];
135 int i;
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);
140 if (!result) {
141 /* rsaenh compiled without OpenSSL */
142 ok(GetLastError()==NTE_BAD_ALGID, "%08lx\n", GetLastError());
143 return FALSE;
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;
153 len = 2000;
154 result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
155 ok(result, "%08lx\n", GetLastError());
156 CryptDestroyHash(hHash);
157 return TRUE;
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];
175 BOOL result;
176 HCRYPTHASH hHash, hHashClone;
177 BYTE pbHashValue[36];
178 DWORD hashlen, len;
179 int i;
181 for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
183 /* MD2 Hashing */
184 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
185 if (!result) {
186 /* rsaenh compiled without OpenSSL */
187 ok(GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
188 } else {
189 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
190 ok(result, "%08lx\n", GetLastError());
192 len = sizeof(DWORD);
193 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
194 ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
196 len = 16;
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());
206 /* MD4 Hashing */
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());
213 len = sizeof(DWORD);
214 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
215 ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
217 len = 16;
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());
226 /* MD5 Hashing */
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());
233 len = sizeof(DWORD);
234 result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
235 ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
237 len = 16;
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());
246 /* SHA1 Hashing */
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());
260 len = sizeof(DWORD);
261 result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
262 ok(result && (hashlen == 20), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
264 len = 20;
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 };
292 HCRYPTKEY hKey;
293 BOOL result;
294 BYTE abData[24];
295 DWORD dwMode, dwLen;
297 result = derive_key(CALG_RC2, &hKey, 40);
298 if (!result) return;
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);
307 dwLen = 23;
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());
320 dwLen = 23;
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());
333 dwLen = 16;
334 result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen, 24);
335 ok(result && dwLen == 16, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
337 dwLen = 7;
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);
342 dwLen = 8;
343 result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen);
344 ok(result && dwLen == 8, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
346 dwLen = 16;
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());
355 dwLen = 23;
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)
362 HCRYPTKEY hKey;
363 BOOL result;
364 DWORD dwLen;
365 unsigned char pbData[16];
366 int i;
368 result = derive_key(CALG_3DES_112, &hKey, 0);
369 if (!result) {
370 /* rsaenh compiled without OpenSSL */
371 ok(GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
372 return;
375 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
377 dwLen = 13;
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)
390 HCRYPTKEY hKey;
391 BOOL result;
392 DWORD dwLen, dwMode;
393 unsigned char pbData[16];
394 int i;
396 result = derive_key(CALG_DES, &hKey, 56);
397 if (!result) {
398 /* rsaenh compiled without OpenSSL */
399 ok(GetLastError()==NTE_BAD_ALGID, "%08lx\n", GetLastError());
400 return;
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;
413 dwLen = 13;
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)
426 HCRYPTKEY hKey;
427 BOOL result;
428 DWORD dwLen;
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 };
433 int i;
435 result = derive_key(CALG_3DES, &hKey, 0);
436 if (!result) return;
438 for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
440 dwLen = 13;
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 };
458 HCRYPTHASH hHash;
459 HCRYPTKEY hKey;
460 BOOL result;
461 DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
462 BYTE *pbTemp;
463 unsigned char pbData[2000], pbHashValue[16];
464 int i;
466 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
468 /* MD2 Hashing */
469 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
470 if (!result) {
471 ok(GetLastError()==NTE_BAD_ALGID, "%08lx\n", GetLastError());
472 } else {
473 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
474 ok(result, "%08lx\n", GetLastError());
476 dwLen = 16;
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());
521 dwDataLen = 13;
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 };
546 BOOL result;
547 HCRYPTHASH hHash;
548 HCRYPTKEY hKey;
549 DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
550 unsigned char pbData[2000], *pbTemp;
551 unsigned char pszBuffer[256];
552 int i;
554 for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
556 /* MD2 Hashing */
557 result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
558 if (!result) {
559 /* rsaenh compiled without OpenSSL */
560 ok(GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
561 } else {
562 result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
563 ok(result, "%08lx\n", GetLastError());
565 dwLen = 16;
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());
598 dwDataLen = 16;
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) {
613 HCRYPTKEY hKey;
614 HCRYPTHASH hHash;
615 BOOL result;
616 HMAC_INFO hmacInfo = { CALG_MD2, NULL, 0, NULL, 0 };
617 DWORD dwLen;
618 BYTE abData[256];
619 static const BYTE hmac[16] = {
620 0xfd, 0x16, 0xb5, 0xb6, 0x13, 0x1c, 0x2b, 0xd6,
621 0x0a, 0xc7, 0xae, 0x92, 0x76, 0xa3, 0x05, 0x71 };
622 int i;
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());
630 if (!result) return;
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());
650 /* Provoke errors */
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) {
656 HCRYPTKEY hKey;
657 HCRYPTHASH hHash;
658 BOOL result;
659 DWORD dwLen;
660 BYTE abData[256], abEnc[264];
661 static const BYTE mac[8] = { 0x0d, 0x3e, 0x15, 0x6b, 0x85, 0x63, 0x5c, 0x11 };
662 int i;
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;
669 dwLen = 256;
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());
675 if (!result) return;
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());
692 /* Provoke errors */
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)
704 DWORD dwLen;
705 HCRYPTKEY hKeyExchangeKey, hSessionKey;
706 BOOL result;
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);
811 if (!result) {
812 /* rsaenh compiled without OpenSSL */
813 ok(GetLastError() == NTE_FAIL, "%08lx\n", GetLastError());
814 return;
817 dwLen = (DWORD)sizeof(abSessionKey);
818 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
819 ok(result, "%08lx\n", GetLastError());
820 if (!result) return;
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());
832 if (!result) return;
834 dwLen = (DWORD)sizeof(abSessionKey);
835 result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
836 ok(result, "%08lx\n", GetLastError());
837 if (!result) return;
840 static void test_verify_signature(void) {
841 HCRYPTHASH hHash;
842 HCRYPTKEY hPubSignKey;
843 BYTE abData[] = "Wine rocks!";
844 BOOL result;
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)
1096 HCRYPTKEY hRSAKey;
1097 BYTE abData[2048] = "Wine rocks!";
1098 BOOL result;
1099 DWORD dwLen;
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;
1106 dwLen = 12;
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;
1121 dwLen = 12;
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)
1130 HCRYPTPROV hProv;
1131 HCRYPTKEY hRSAKey, hMasterSecret, hServerWriteKey, hServerWriteMACKey;
1132 HCRYPTHASH hMasterHash, hTLS1PRF, hHMAC;
1133 BOOL result;
1134 DWORD dwLen;
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!";
1240 BYTE abMD5Hash[16];
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
1260 * an RSA key. */
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. */
1315 dwLen = 12;
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];
1378 DWORD dwBufferLen;
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. */
1392 do {
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());
1400 START_TEST(rsaenh)
1402 if (!init_environment())
1403 return;
1404 test_prov();
1405 test_gen_random();
1406 test_hashes();
1407 test_rc4();
1408 test_rc2();
1409 test_des();
1410 test_3des112();
1411 test_3des();
1412 test_hmac();
1413 test_mac();
1414 test_block_cipher_modes();
1415 test_import_private();
1416 test_verify_signature();
1417 test_rsa_encrypt();
1418 test_enum_container();
1419 clean_up_environment();
1420 test_schannel_provider();