ReactOS 0.4.17-dev-1190-g4c812f4
rsaenh.c
Go to the documentation of this file.
1/*
2 * dlls/rsaenh/rsaenh.c
3 * RSAENH - RSA encryption for Wine
4 *
5 * Copyright 2002 TransGaming Technologies (David Hammerton)
6 * Copyright 2004 Mike McCormack for CodeWeavers
7 * Copyright 2004, 2005 Michael Jung
8 * Copyright 2007 Vijay Kiran Kamuju
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <stdarg.h>
26#include <stdlib.h>
27#include <stdio.h>
28#include <assert.h>
29
30#include "windef.h"
31#include "winbase.h"
32#include "winreg.h"
33#include "ntsecapi.h"
34#include "wincrypt.h"
35#include "handle.h"
36#include "implglue.h"
37#include "objbase.h"
38#include "rpcproxy.h"
39#include "aclapi.h"
40#include "wine/debug.h"
41
43
44#define RSAENH_MAGIC_KEY 0x73620457u
45#define RSAENH_MAX_KEY_SIZE 64
46#define RSAENH_MAX_BLOCK_SIZE 24
47#define RSAENH_KEYSTATE_IDLE 0
48#define RSAENH_KEYSTATE_ENCRYPTING 1
49#define RSAENH_KEYSTATE_MASTERKEY 2
50
51/******************************************************************************
52 * CRYPTHASH - hash objects
53 */
54#define RSAENH_MAGIC_HASH 0x85938417u
55#define RSAENH_HASHSTATE_HASHING 1
56#define RSAENH_HASHSTATE_FINISHED 2
58{
62
63typedef struct tagCRYPTHASH
64{
71 struct hash hash;
80
81/******************************************************************************
82 * CRYPTKEY - key objects
83 */
84typedef struct _RSAENH_SCHANNEL_INFO
85{
91
92typedef struct tagCRYPTKEY
93{
112
113/******************************************************************************
114 * KEYCONTAINER - key containers
115 */
116#define RSAENH_PERSONALITY_BASE 0u
117#define RSAENH_PERSONALITY_STRONG 1u
118#define RSAENH_PERSONALITY_ENHANCED 2u
119#define RSAENH_PERSONALITY_SCHANNEL 3u
120#define RSAENH_PERSONALITY_AES 4u
121
122#define RSAENH_MAGIC_CONTAINER 0x26384993u
123typedef struct tagKEYCONTAINER
124{
135
136/******************************************************************************
137 * Some magic constants
138 */
139#define RSAENH_HMAC_DEF_IPAD_CHAR 0x36
140#define RSAENH_HMAC_DEF_OPAD_CHAR 0x5c
141#define RSAENH_HMAC_DEF_PAD_LEN 64
142#define RSAENH_HMAC_BLOCK_LEN 64
143#define RSAENH_DES_EFFECTIVE_KEYLEN 56
144#define RSAENH_DES_STORAGE_KEYLEN 64
145#define RSAENH_3DES112_EFFECTIVE_KEYLEN 112
146#define RSAENH_3DES112_STORAGE_KEYLEN 128
147#define RSAENH_3DES_EFFECTIVE_KEYLEN 168
148#define RSAENH_3DES_STORAGE_KEYLEN 192
149#define RSAENH_MAGIC_RSA2 0x32415352
150#define RSAENH_MAGIC_RSA1 0x31415352
151#define RSAENH_PKC_BLOCKTYPE 0x02
152#define RSAENH_SSL3_VERSION_MAJOR 3
153#define RSAENH_SSL3_VERSION_MINOR 0
154#define RSAENH_TLS1_VERSION_MAJOR 3
155#define RSAENH_TLS1_VERSION_MINOR 1
156#define RSAENH_REGKEY "Software\\Wine\\Crypto\\RSA\\%s"
157
158#define RSAENH_MIN(a,b) ((a)<(b)?(a):(b))
159/******************************************************************************
160 * aProvEnumAlgsEx - Defines the capabilities of the CSP personalities.
161 */
162#define RSAENH_MAX_ENUMALGS 24
163#define RSAENH_PCT1_SSL2_SSL3_TLS1 (CRYPT_FLAG_PCT1|CRYPT_FLAG_SSL2|CRYPT_FLAG_SSL3|CRYPT_FLAG_TLS1)
164#define S(s) sizeof(s), s
166{
167 {
168 {CALG_RC2, 40, 40, 56, 0, S("RC2"), S("RSA Data Security's RC2")},
169 {CALG_RC4, 40, 40, 56, 0, S("RC4"), S("RSA Data Security's RC4")},
170 {CALG_DES, 56, 56, 56, 0, S("DES"), S("Data Encryption Standard (DES)")},
171 {CALG_SHA, 160, 160, 160, CRYPT_FLAG_SIGNING, S("SHA-1"), S("Secure Hash Algorithm (SHA-1)")},
172 {CALG_MD2, 128, 128, 128, CRYPT_FLAG_SIGNING, S("MD2"), S("Message Digest 2 (MD2)")},
173 {CALG_MD4, 128, 128, 128, CRYPT_FLAG_SIGNING, S("MD4"), S("Message Digest 4 (MD4)")},
174 {CALG_MD5, 128, 128, 128, CRYPT_FLAG_SIGNING, S("MD5"), S("Message Digest 5 (MD5)")},
175 {CALG_SSL3_SHAMD5, 288, 288, 288, 0, S("SSL3 SHAMD5"), S("SSL3 SHAMD5")},
176 {CALG_MAC, 0, 0, 0, 0, S("MAC"), S("Message Authentication Code")},
177 {CALG_RSA_SIGN, 512, 384, 16384, CRYPT_FLAG_SIGNING|CRYPT_FLAG_IPSEC, S("RSA_SIGN"), S("RSA Signature")},
178 {CALG_RSA_KEYX, 512, 384, 1024, CRYPT_FLAG_SIGNING|CRYPT_FLAG_IPSEC, S("RSA_KEYX"), S("RSA Key Exchange")},
179 {CALG_HMAC, 0, 0, 0, 0, S("HMAC"), S("Hugo's MAC (HMAC)")},
180 {0, 0, 0, 0, 0, S(""), S("")}
181 },
182 {
183 {CALG_RC2, 128, 40, 128, 0, S("RC2"), S("RSA Data Security's RC2")},
184 {CALG_RC4, 128, 40, 128, 0, S("RC4"), S("RSA Data Security's RC4")},
185 {CALG_DES, 56, 56, 56, 0, S("DES"), S("Data Encryption Standard (DES)")},
186 {CALG_3DES_112, 112, 112, 112, 0, S("3DES TWO KEY"), S("Two Key Triple DES")},
187 {CALG_3DES, 168, 168, 168, 0, S("3DES"), S("Three Key Triple DES")},
188 {CALG_SHA, 160, 160, 160, CRYPT_FLAG_SIGNING, S("SHA-1"), S("Secure Hash Algorithm (SHA-1)")},
189 {CALG_MD2, 128, 128, 128, CRYPT_FLAG_SIGNING, S("MD2"), S("Message Digest 2 (MD2)")},
190 {CALG_MD4, 128, 128, 128, CRYPT_FLAG_SIGNING, S("MD4"), S("Message Digest 4 (MD4)")},
191 {CALG_MD5, 128, 128, 128, CRYPT_FLAG_SIGNING, S("MD5"), S("Message Digest 5 (MD5)")},
192 {CALG_SSL3_SHAMD5, 288, 288, 288, 0, S("SSL3 SHAMD5"), S("SSL3 SHAMD5")},
193 {CALG_MAC, 0, 0, 0, 0, S("MAC"), S("Message Authentication Code")},
194 {CALG_RSA_SIGN, 1024, 384, 16384, CRYPT_FLAG_SIGNING|CRYPT_FLAG_IPSEC, S("RSA_SIGN"), S("RSA Signature")},
195 {CALG_RSA_KEYX, 1024, 384, 16384, CRYPT_FLAG_SIGNING|CRYPT_FLAG_IPSEC, S("RSA_KEYX"), S("RSA Key Exchange")},
196 {CALG_HMAC, 0, 0, 0, 0, S("HMAC"), S("Hugo's MAC (HMAC)")},
197 {0, 0, 0, 0, 0, S(""), S("")}
198 },
199 {
200 {CALG_RC2, 128, 40, 128, 0, S("RC2"), S("RSA Data Security's RC2")},
201 {CALG_RC4, 128, 40, 128, 0, S("RC4"), S("RSA Data Security's RC4")},
202 {CALG_DES, 56, 56, 56, 0, S("DES"), S("Data Encryption Standard (DES)")},
203 {CALG_3DES_112, 112, 112, 112, 0, S("3DES TWO KEY"), S("Two Key Triple DES")},
204 {CALG_3DES, 168, 168, 168, 0, S("3DES"), S("Three Key Triple DES")},
205 {CALG_SHA, 160, 160, 160, CRYPT_FLAG_SIGNING, S("SHA-1"), S("Secure Hash Algorithm (SHA-1)")},
206 {CALG_MD2, 128, 128, 128, CRYPT_FLAG_SIGNING, S("MD2"), S("Message Digest 2 (MD2)")},
207 {CALG_MD4, 128, 128, 128, CRYPT_FLAG_SIGNING, S("MD4"), S("Message Digest 4 (MD4)")},
208 {CALG_MD5, 128, 128, 128, CRYPT_FLAG_SIGNING, S("MD5"), S("Message Digest 5 (MD5)")},
209 {CALG_SSL3_SHAMD5, 288, 288, 288, 0, S("SSL3 SHAMD5"), S("SSL3 SHAMD5")},
210 {CALG_MAC, 0, 0, 0, 0, S("MAC"), S("Message Authentication Code")},
211 {CALG_RSA_SIGN, 1024, 384, 16384, CRYPT_FLAG_SIGNING|CRYPT_FLAG_IPSEC, S("RSA_SIGN"), S("RSA Signature")},
212 {CALG_RSA_KEYX, 1024, 384, 16384, CRYPT_FLAG_SIGNING|CRYPT_FLAG_IPSEC, S("RSA_KEYX"), S("RSA Key Exchange")},
213 {CALG_HMAC, 0, 0, 0, 0, S("HMAC"), S("Hugo's MAC (HMAC)")},
214 {0, 0, 0, 0, 0, S(""), S("")}
215 },
216 {
217 {CALG_RC2, 128, 40, 128, RSAENH_PCT1_SSL2_SSL3_TLS1, S("RC2"), S("RSA Data Security's RC2")},
218 {CALG_RC4, 128, 40, 128, RSAENH_PCT1_SSL2_SSL3_TLS1, S("RC4"), S("RSA Data Security's RC4")},
219 {CALG_DES, 56, 56, 56, RSAENH_PCT1_SSL2_SSL3_TLS1, S("DES"), S("Data Encryption Standard (DES)")},
220 {CALG_3DES_112, 112, 112, 112, RSAENH_PCT1_SSL2_SSL3_TLS1, S("3DES TWO KEY"), S("Two Key Triple DES")},
221 {CALG_3DES, 168, 168, 168, RSAENH_PCT1_SSL2_SSL3_TLS1, S("3DES"), S("Three Key Triple DES")},
222 {CALG_SHA, 160, 160, 160, CRYPT_FLAG_SIGNING|RSAENH_PCT1_SSL2_SSL3_TLS1, S("SHA-1"), S("Secure Hash Algorithm (SHA-1)")},
223 {CALG_MD5, 128, 128, 128, CRYPT_FLAG_SIGNING|RSAENH_PCT1_SSL2_SSL3_TLS1, S("MD5"), S("Message Digest 5 (MD5)")},
224 {CALG_SSL3_SHAMD5, 288, 288, 288, 0, S("SSL3 SHAMD5"), S("SSL3 SHAMD5")},
225 {CALG_MAC, 0, 0, 0, 0, S("MAC"), S("Message Authentication Code")},
226 {CALG_RSA_SIGN, 1024, 384, 16384, CRYPT_FLAG_SIGNING|RSAENH_PCT1_SSL2_SSL3_TLS1, S("RSA_SIGN"), S("RSA Signature")},
227 {CALG_RSA_KEYX, 1024, 384, 16384, CRYPT_FLAG_SIGNING|RSAENH_PCT1_SSL2_SSL3_TLS1, S("RSA_KEYX"), S("RSA Key Exchange")},
228 {CALG_HMAC, 0, 0, 0, 0, S("HMAC"), S("Hugo's MAC (HMAC)")},
229 {CALG_PCT1_MASTER, 128, 128, 128, CRYPT_FLAG_PCT1, S("PCT1 MASTER"), S("PCT1 Master")},
230 {CALG_SSL2_MASTER, 40, 40, 192, CRYPT_FLAG_SSL2, S("SSL2 MASTER"), S("SSL2 Master")},
231 {CALG_SSL3_MASTER, 384, 384, 384, CRYPT_FLAG_SSL3, S("SSL3 MASTER"), S("SSL3 Master")},
232 {CALG_TLS1_MASTER, 384, 384, 384, CRYPT_FLAG_TLS1, S("TLS1 MASTER"), S("TLS1 Master")},
233 {CALG_SCHANNEL_MASTER_HASH, 0, 0, -1, 0, S("SCH MASTER HASH"), S("SChannel Master Hash")},
234 {CALG_SCHANNEL_MAC_KEY, 0, 0, -1, 0, S("SCH MAC KEY"), S("SChannel MAC Key")},
235 {CALG_SCHANNEL_ENC_KEY, 0, 0, -1, 0, S("SCH ENC KEY"), S("SChannel Encryption Key")},
236 {CALG_TLS1PRF, 0, 0, -1, 0, S("TLS1 PRF"), S("TLS1 Pseudo Random Function")},
237 {0, 0, 0, 0, 0, S(""), S("")}
238 },
239 {
240 {CALG_RC2, 128, 40, 128, 0, S("RC2"), S("RSA Data Security's RC2")},
241 {CALG_RC4, 128, 40, 128, 0, S("RC4"), S("RSA Data Security's RC4")},
242 {CALG_DES, 56, 56, 56, 0, S("DES"), S("Data Encryption Standard (DES)")},
243 {CALG_3DES_112, 112, 112, 112, 0, S("3DES TWO KEY"), S("Two Key Triple DES")},
244 {CALG_3DES, 168, 168, 168, 0, S("3DES"), S("Three Key Triple DES")},
245 {CALG_AES_128, 128, 128, 128, 0, S("AES-128"), S("Advanced Encryption Standard (AES-128)")},
246 {CALG_AES_192, 192, 192, 192, 0, S("AES-192"), S("Advanced Encryption Standard (AES-192)")},
247 {CALG_AES_256, 256, 256, 256, 0, S("AES-256"), S("Advanced Encryption Standard (AES-256)")},
248 {CALG_SHA, 160, 160, 160, CRYPT_FLAG_SIGNING, S("SHA-1"), S("Secure Hash Algorithm (SHA-1)")},
249 {CALG_SHA_256, 256, 256, 256, CRYPT_FLAG_SIGNING, S("SHA-256"), S("Secure Hash Algorithm (SHA-256)")},
250 {CALG_SHA_384, 384, 384, 384, CRYPT_FLAG_SIGNING, S("SHA-384"), S("Secure Hash Algorithm (SHA-384)")},
251 {CALG_SHA_512, 512, 512, 512, CRYPT_FLAG_SIGNING, S("SHA-512"), S("Secure Hash Algorithm (SHA-512)")},
252 {CALG_MD2, 128, 128, 128, CRYPT_FLAG_SIGNING, S("MD2"), S("Message Digest 2 (MD2)")},
253 {CALG_MD4, 128, 128, 128, CRYPT_FLAG_SIGNING, S("MD4"), S("Message Digest 4 (MD4)")},
254 {CALG_MD5, 128, 128, 128, CRYPT_FLAG_SIGNING, S("MD5"), S("Message Digest 5 (MD5)")},
255 {CALG_SSL3_SHAMD5, 288, 288, 288, 0, S("SSL3 SHAMD5"), S("SSL3 SHAMD5")},
256 {CALG_MAC, 0, 0, 0, 0, S("MAC"), S("Message Authentication Code")},
257 {CALG_RSA_SIGN, 1024, 384, 16384, CRYPT_FLAG_SIGNING|CRYPT_FLAG_IPSEC, S("RSA_SIGN"), S("RSA Signature")},
258 {CALG_RSA_KEYX, 1024, 384, 16384, CRYPT_FLAG_SIGNING|CRYPT_FLAG_IPSEC, S("RSA_KEYX"), S("RSA Key Exchange")},
259 {CALG_HMAC, 0, 0, 0, 0, S("HMAC"), S("Hugo's MAC (HMAC)")},
260 {0, 0, 0, 0, 0, S(""), S("")}
261 }
262};
263#undef S
264
265/******************************************************************************
266 * API forward declarations
267 */
272 DWORD dwParam,
273 BYTE *pbData,
274 DWORD *pdwDataLen,
276);
277
281 ALG_ID Algid,
283 DWORD dwFlags,
284 HCRYPTHASH *phHash
285);
286
290 HCRYPTHASH hHash,
291 DWORD dwParam,
293);
294
298 HCRYPTHASH hHash,
299 DWORD dwParam,
300 BYTE *pbData,
301 DWORD *pdwDataLen,
303);
304
308 HCRYPTHASH hHash
309);
310
312 CRYPTKEY *pCryptKey,
313 HCRYPTKEY hPubKey,
314 DWORD dwBlobType,
315 DWORD dwFlags,
316 BOOL force,
317 BYTE *pbData,
318 DWORD *pdwDataLen
319);
320
321static BOOL import_key(
323 const BYTE *pbData,
324 DWORD dwDataLen,
325 HCRYPTKEY hPubKey,
326 DWORD dwFlags,
327 BOOL fStoreKey,
328 HCRYPTKEY *phKey
329);
330
334 HCRYPTHASH hHash,
335 const BYTE *pbData,
336 DWORD dwDataLen,
338);
339
340/******************************************************************************
341 * CSP's handle table (used by all acquired key containers)
342 */
344
345/******************************************************************************
346 * DllMain (RSAENH.@)
347 *
348 * Initializes and destroys the handle table for the CSP's handles.
349 */
351{
352 switch (fdwReason)
353 {
357 SymCryptInit();
358 break;
359
361 if (reserved) break;
363 break;
364 }
365 return TRUE;
366}
367
368/******************************************************************************
369 * copy_param [Internal]
370 *
371 * Helper function that supports the standard WINAPI protocol for querying data
372 * of dynamic size.
373 *
374 * PARAMS
375 * pbBuffer [O] Buffer where the queried parameter is copied to, if it is large enough.
376 * May be NUL if the required buffer size is to be queried only.
377 * pdwBufferSize [I/O] In: Size of the buffer at pbBuffer
378 * Out: Size of parameter pbParam
379 * pbParam [I] Parameter value.
380 * dwParamSize [I] Size of pbParam
381 *
382 * RETURN
383 * Success: TRUE (pbParam was copied into pbBuffer or pbBuffer is NULL)
384 * Failure: FALSE (pbBuffer is not large enough to hold pbParam). Last error: ERROR_MORE_DATA
385 */
386static inline BOOL copy_param(BYTE *pbBuffer, DWORD *pdwBufferSize, const BYTE *pbParam,
387 DWORD dwParamSize)
388{
389 if (pbBuffer)
390 {
391 if (dwParamSize > *pdwBufferSize)
392 {
394 *pdwBufferSize = dwParamSize;
395 return FALSE;
396 }
397 memcpy(pbBuffer, pbParam, dwParamSize);
398 }
399 *pdwBufferSize = dwParamSize;
400 return TRUE;
401}
402
404{
405 KEYCONTAINER *pKeyContainer;
406
408 (OBJECTHDR**)&pKeyContainer))
409 {
411 return NULL;
412 }
413 return pKeyContainer;
414}
415
416/******************************************************************************
417 * get_algid_info [Internal]
418 *
419 * Query CSP capabilities for a given crypto algorithm.
420 *
421 * PARAMS
422 * hProv [I] Handle to a key container of the CSP whose capabilities are to be queried.
423 * algid [I] Identifier of the crypto algorithm about which information is requested.
424 *
425 * RETURNS
426 * Success: Pointer to a PROV_ENUMALGS_EX struct containing information about the crypto algorithm.
427 * Failure: NULL (algid not supported)
428 */
431 KEYCONTAINER *pKeyContainer;
432
433 if (!(pKeyContainer = get_key_container(hProv))) return NULL;
434
435 for (iterator = aProvEnumAlgsEx[pKeyContainer->dwPersonality]; iterator->aiAlgid; iterator++) {
436 if (iterator->aiAlgid == algid) return iterator;
437 }
438
440 return NULL;
441}
442
443/******************************************************************************
444 * copy_data_blob [Internal]
445 *
446 * deeply copies a DATA_BLOB
447 *
448 * PARAMS
449 * dst [O] That's where the blob will be copied to
450 * src [I] Source blob
451 *
452 * RETURNS
453 * Success: TRUE
454 * Failure: FALSE (GetLastError() == NTE_NO_MEMORY
455 *
456 * NOTES
457 * Use free_data_blob to release resources occupied by copy_data_blob.
458 */
460{
461 dst->pbData = malloc(src->cbData);
462 if (!dst->pbData) {
464 return FALSE;
465 }
466 dst->cbData = src->cbData;
467 memcpy(dst->pbData, src->pbData, src->cbData);
468 return TRUE;
469}
470
471/******************************************************************************
472 * concat_data_blobs [Internal]
473 *
474 * Concatenates two blobs
475 *
476 * PARAMS
477 * dst [O] The new blob will be copied here
478 * src1 [I] Prefix blob
479 * src2 [I] Appendix blob
480 *
481 * RETURNS
482 * Success: TRUE
483 * Failure: FALSE (GetLastError() == NTE_NO_MEMORY)
484 *
485 * NOTES
486 * Release resources occupied by concat_data_blobs with free_data_blobs
487 */
489 const PCRYPT_DATA_BLOB src2)
490{
491 dst->cbData = src1->cbData + src2->cbData;
492 dst->pbData = malloc(dst->cbData);
493 if (!dst->pbData) {
495 return FALSE;
496 }
497 memcpy(dst->pbData, src1->pbData, src1->cbData);
498 memcpy(dst->pbData + src1->cbData, src2->pbData, src2->cbData);
499 return TRUE;
500}
501
502/******************************************************************************
503 * free_data_blob [Internal]
504 *
505 * releases resource occupied by a dynamically allocated CRYPT_DATA_BLOB
506 *
507 * PARAMS
508 * pBlob [I] Heap space occupied by pBlob->pbData is released
509 */
510static inline void free_data_blob(PCRYPT_DATA_BLOB pBlob) {
511 free(pBlob->pbData);
512}
513
514/******************************************************************************
515 * init_data_blob [Internal]
516 */
517static inline void init_data_blob(PCRYPT_DATA_BLOB pBlob) {
518 pBlob->pbData = NULL;
519 pBlob->cbData = 0;
520}
521
522/******************************************************************************
523 * block_encrypt [Internal]
524 */
526 BOOL final, KEY_CONTEXT *context, BYTE *chain_vector)
527{
529 unsigned int encrypted_len, i, j, k;
530
531 if (!final && (*data_len % key->dwBlockLen))
532 {
534 return FALSE;
535 }
536
537 encrypted_len = (*data_len / key->dwBlockLen + (final ? 1 : 0)) * key->dwBlockLen;
538
539 if (data == NULL)
540 {
541 *data_len = encrypted_len;
542 return TRUE;
543 }
544 if (encrypted_len > buf_len)
545 {
546 *data_len = encrypted_len;
548 return FALSE;
549 }
550
551 /* Pad final block with length bytes */
552 for (i = *data_len; i < encrypted_len; i++) data[i] = encrypted_len - *data_len;
553 *data_len = encrypted_len;
554
555 for (i = 0, in = data; i < *data_len; i += key->dwBlockLen, in += key->dwBlockLen)
556 {
557 switch (key->dwMode) {
558 case CRYPT_MODE_ECB:
559 encrypt_block_impl(key->aiAlgid, context, in, out);
560 break;
561 case CRYPT_MODE_CBC:
562 for (j = 0; j < key->dwBlockLen; j++)
563 in[j] ^= chain_vector[j];
564 encrypt_block_impl(key->aiAlgid, context, in, out);
565 memcpy(chain_vector, out, key->dwBlockLen);
566 break;
567 case CRYPT_MODE_CFB:
568 for (j = 0; j < key->dwBlockLen; j++)
569 {
570 encrypt_block_impl(key->aiAlgid, context, chain_vector, o);
571 out[j] = in[j] ^ o[0];
572 for (k = 0; k < key->dwBlockLen - 1; k++)
573 chain_vector[k] = chain_vector[k+1];
574 chain_vector[k] = out[j];
575 }
576 break;
577 default:
579 return FALSE;
580 }
581 memcpy(in, out, key->dwBlockLen);
582 }
583 return TRUE;
584}
585
586/******************************************************************************
587 * free_hmac_info [Internal]
588 *
589 * Deeply free an HMAC_INFO struct.
590 *
591 * PARAMS
592 * hmac_info [I] Pointer to the HMAC_INFO struct to be freed.
593 *
594 * NOTES
595 * See Internet RFC 2104 for details on the HMAC algorithm.
596 */
597static inline void free_hmac_info(PHMAC_INFO hmac_info) {
598 if (!hmac_info) return;
599 free(hmac_info->pbInnerString);
600 free(hmac_info->pbOuterString);
601 free(hmac_info);
602}
603
604/******************************************************************************
605 * copy_hmac_info [Internal]
606 *
607 * Deeply copy an HMAC_INFO struct
608 *
609 * PARAMS
610 * dst [O] Pointer to a location where the pointer to the HMAC_INFO copy will be stored.
611 * src [I] Pointer to the HMAC_INFO struct to be copied.
612 *
613 * RETURNS
614 * Success: TRUE
615 * Failure: FALSE
616 *
617 * NOTES
618 * See Internet RFC 2104 for details on the HMAC algorithm.
619 */
620static BOOL copy_hmac_info(PHMAC_INFO *dst, const HMAC_INFO *src, DWORD block_len) {
621 if (!src) return FALSE;
622 *dst = malloc(sizeof(HMAC_INFO));
623 if (!*dst) return FALSE;
624 **dst = *src;
625 (*dst)->pbInnerString = NULL;
626 (*dst)->pbOuterString = NULL;
627 if ((*dst)->cbInnerString == 0) (*dst)->cbInnerString = block_len;
628 (*dst)->pbInnerString = malloc((*dst)->cbInnerString);
629 if (!(*dst)->pbInnerString) {
631 return FALSE;
632 }
633 if (src->cbInnerString)
634 memcpy((*dst)->pbInnerString, src->pbInnerString, src->cbInnerString);
635 else
636 memset((*dst)->pbInnerString, RSAENH_HMAC_DEF_IPAD_CHAR, block_len);
637 if ((*dst)->cbOuterString == 0) (*dst)->cbOuterString = block_len;
638 (*dst)->pbOuterString = malloc((*dst)->cbOuterString);
639 if (!(*dst)->pbOuterString) {
641 return FALSE;
642 }
643 if (src->cbOuterString)
644 memcpy((*dst)->pbOuterString, src->pbOuterString, src->cbOuterString);
645 else
646 memset((*dst)->pbOuterString, RSAENH_HMAC_DEF_OPAD_CHAR, block_len);
647 return TRUE;
648}
649
650/******************************************************************************
651 * destroy_hash [Internal]
652 *
653 * Destructor for hash objects
654 *
655 * PARAMS
656 * pCryptHash [I] Pointer to the hash object to be destroyed.
657 * Will be invalid after function returns!
658 */
660{
661 CRYPTHASH *pCryptHash = (CRYPTHASH*)pObject;
662
663 free_hmac_info(pCryptHash->pHMACInfo);
665 free_data_blob(&pCryptHash->tpPRFParams.blobSeed);
666 if (pCryptHash->aiAlgid == CALG_MAC)
667 free_key_impl(pCryptHash->key_alg_id, &pCryptHash->key_context);
668 free(pCryptHash);
669}
670
671/******************************************************************************
672 * init_hash [Internal]
673 *
674 * Initialize (or reset) a hash object
675 *
676 * PARAMS
677 * pCryptHash [I] The hash object to be initialized.
678 */
679static inline BOOL init_hash(CRYPTHASH *pCryptHash) {
680 DWORD dwLen;
681
682 switch (pCryptHash->aiAlgid)
683 {
684 case CALG_HMAC:
685 if (pCryptHash->pHMACInfo) {
686 /* the algorithm doesn't have to be listed by the provider */
687 init_hash_impl(pCryptHash->pHMACInfo->HashAlgid, &pCryptHash->hash);
688 if (!pCryptHash->hash.desc)
689 {
691 return FALSE;
692 }
693
694 pCryptHash->dwHashSize = hash_len_impl(&pCryptHash->hash);
695 update_hash_impl(&pCryptHash->hash, pCryptHash->pHMACInfo->pbInnerString,
696 pCryptHash->pHMACInfo->cbInnerString);
697 }
698 return TRUE;
699
700 case CALG_MAC:
701 dwLen = sizeof(DWORD);
702 RSAENH_CPGetKeyParam(pCryptHash->hProv, pCryptHash->hKey, KP_BLOCKLEN,
703 (BYTE*)&pCryptHash->dwHashSize, &dwLen, 0);
704 pCryptHash->dwHashSize >>= 3;
705 return TRUE;
706
707 default:
708 return init_hash_impl(pCryptHash->aiAlgid, &pCryptHash->hash);
709 }
710}
711
712/******************************************************************************
713 * update_hash [Internal]
714 *
715 * Hashes the given data and updates the hash object's state accordingly
716 *
717 * PARAMS
718 * pCryptHash [I] Hash object to be updated.
719 * pbData [I] Pointer to data stream to be hashed.
720 * dwDataLen [I] Length of data stream.
721 */
722static inline void update_hash(CRYPTHASH *pCryptHash, const BYTE *pbData, DWORD dwDataLen)
723{
724 CRYPTKEY *key;
725 BYTE *pbTemp;
726 DWORD len;
727
728 switch (pCryptHash->aiAlgid)
729 {
730 case CALG_HMAC:
731 if (pCryptHash->pHMACInfo)
732 update_hash_impl(&pCryptHash->hash, pbData, dwDataLen);
733 break;
734
735 case CALG_MAC:
737 {
738 FIXME("Key lookup failed.\n");
739 return;
740 }
741 if (pCryptHash->buffered_hash_bytes)
742 {
743 len = min(pCryptHash->dwHashSize - pCryptHash->buffered_hash_bytes, dwDataLen);
744 memcpy(pCryptHash->abHashValue + pCryptHash->buffered_hash_bytes, pbData, len);
745 pbData += len;
746 dwDataLen -= len;
747 pCryptHash->buffered_hash_bytes += len;
748 if (pCryptHash->buffered_hash_bytes < pCryptHash->dwHashSize)
749 return;
750 pCryptHash->buffered_hash_bytes = 0;
751 len = pCryptHash->dwHashSize;
752 if (!block_encrypt(key, pCryptHash->abHashValue, &len, len, FALSE,
753 &pCryptHash->key_context, pCryptHash->abChainVector))
754 {
755 FIXME("block_encrypt failed.\n");
756 return;
757 }
758 }
759 len = dwDataLen - dwDataLen % pCryptHash->dwHashSize;
760 if (len)
761 {
762 pbTemp = malloc(len);
763 if (!pbTemp)
764 {
765 ERR("No memory.\n");
766 return;
767 }
768 memcpy(pbTemp, pbData, len);
769 pbData += len;
770 dwDataLen -= len;
771 if (!block_encrypt(key, pbTemp, &len, len, FALSE,
772 &pCryptHash->key_context, pCryptHash->abChainVector))
773 {
774 FIXME("block_encrypt failed.\n");
775 return;
776 }
777 free(pbTemp);
778 }
779 if (dwDataLen)
780 {
781 memcpy(pCryptHash->abHashValue, pbData, dwDataLen);
782 pCryptHash->buffered_hash_bytes = dwDataLen;
783 }
784 break;
785
786 default:
787 update_hash_impl(&pCryptHash->hash, pbData, dwDataLen);
788 }
789}
790
791/******************************************************************************
792 * finalize_hash [Internal]
793 *
794 * Finalizes the hash, after all data has been hashed with update_hash.
795 * No additional data can be hashed afterwards until the hash gets initialized again.
796 *
797 * PARAMS
798 * pCryptHash [I] Hash object to be finalized.
799 */
800static inline void finalize_hash(CRYPTHASH *pCryptHash)
801{
802 DWORD dwDataLen;
803 CRYPTKEY *key;
804
805 switch (pCryptHash->aiAlgid)
806 {
807 case CALG_HMAC:
808 if (pCryptHash->pHMACInfo) {
809 BYTE abHashValue[RSAENH_MAX_HASH_SIZE];
810
811 finalize_hash_impl(&pCryptHash->hash, pCryptHash->abHashValue, pCryptHash->dwHashSize);
812 memcpy(abHashValue, pCryptHash->abHashValue, pCryptHash->dwHashSize);
813 init_hash_impl(pCryptHash->pHMACInfo->HashAlgid, &pCryptHash->hash);
814 update_hash_impl(&pCryptHash->hash, pCryptHash->pHMACInfo->pbOuterString,
815 pCryptHash->pHMACInfo->cbOuterString);
816 update_hash_impl(&pCryptHash->hash, abHashValue, pCryptHash->dwHashSize);
817 finalize_hash_impl(&pCryptHash->hash, pCryptHash->abHashValue, pCryptHash->dwHashSize);
818 memset(&pCryptHash->hash, 0, sizeof(pCryptHash->hash));
819 }
820 break;
821
822 case CALG_MAC:
824 {
825 FIXME("Key lookup failed.\n");
826 return;
827 }
828 dwDataLen = pCryptHash->buffered_hash_bytes;
829 if (!block_encrypt(key, pCryptHash->abHashValue, &dwDataLen, pCryptHash->dwHashSize, TRUE,
830 &pCryptHash->key_context, pCryptHash->abChainVector))
831 FIXME("block_encrypt failed.\n");
832 break;
833
834 default:
835 finalize_hash_impl(&pCryptHash->hash, pCryptHash->abHashValue, pCryptHash->dwHashSize);
836 memset(&pCryptHash->hash, 0, sizeof(pCryptHash->hash));
837 }
838}
839
840/******************************************************************************
841 * destroy_key [Internal]
842 *
843 * Destructor for key objects
844 *
845 * PARAMS
846 * pCryptKey [I] Pointer to the key object to be destroyed.
847 * Will be invalid after function returns!
848 */
850{
851 CRYPTKEY *pCryptKey = (CRYPTKEY*)pObject;
852
853 free_key_impl(pCryptKey->aiAlgid, &pCryptKey->context);
856 free_data_blob(&pCryptKey->blobHmacKey);
857 free(pCryptKey);
858}
859
860/******************************************************************************
861 * setup_key [Internal]
862 *
863 * Initialize (or reset) a key object
864 *
865 * PARAMS
866 * pCryptKey [I] The key object to be initialized.
867 */
868static inline void setup_key(CRYPTKEY *pCryptKey) {
869 pCryptKey->dwState = RSAENH_KEYSTATE_IDLE;
870 memcpy(pCryptKey->abChainVector, pCryptKey->abInitVector, sizeof(pCryptKey->abChainVector));
871 setup_key_impl(pCryptKey->aiAlgid, &pCryptKey->context, pCryptKey->dwKeyLen,
872 pCryptKey->dwEffectiveKeyLen, pCryptKey->dwSaltLen,
873 pCryptKey->abKeyValue);
874}
875
876/******************************************************************************
877 * alloc_key [Internal]
878 *
879 */
881{
882 KEYCONTAINER *key_container = get_key_container(hprov);
883 HCRYPTKEY hkey;
884 CRYPTKEY *key;
885
888 if (hkey == (HCRYPTKEY)INVALID_HANDLE_VALUE)
889 return hkey;
890
891 key->aiAlgid = alg_id;
892 key->hProv = hprov;
893 key->dwModeBits = 0;
896 key->dwPermissions |= CRYPT_EXPORT;
897 key->dwKeyLen = key_len >> 3;
898 key->dwEffectiveKeyLen = 0;
899
900 /*
901 * For compatibility reasons a 40 bit key on the Enhanced
902 * provider will not have salt
903 */
904 if (key_container->dwPersonality == RSAENH_PERSONALITY_ENHANCED
905 && (alg_id == CALG_RC2 || alg_id == CALG_RC4)
906 && (flags & CRYPT_CREATE_SALT) && key_len == 40)
907 key->dwSaltLen = 0;
908 else if ((flags & CRYPT_CREATE_SALT) || (key_len == 40 && !(flags & CRYPT_NO_SALT)))
909 key->dwSaltLen = 16 /*FIXME*/ - key->dwKeyLen;
910 else
911 key->dwSaltLen = 0;
912 memset(key->abKeyValue, 0, sizeof(key->abKeyValue));
913 memset(key->abInitVector, 0, sizeof(key->abInitVector));
914 memset(&key->siSChannelInfo.saEncAlg, 0, sizeof(key->siSChannelInfo.saEncAlg));
915 memset(&key->siSChannelInfo.saMACAlg, 0, sizeof(key->siSChannelInfo.saMACAlg));
916 init_data_blob(&key->siSChannelInfo.blobClientRandom);
917 init_data_blob(&key->siSChannelInfo.blobServerRandom);
918 init_data_blob(&key->blobHmacKey);
919
920 switch(alg_id)
921 {
922 case CALG_PCT1_MASTER:
923 case CALG_SSL2_MASTER:
924 case CALG_SSL3_MASTER:
925 case CALG_TLS1_MASTER:
926 case CALG_RC4:
927 key->dwBlockLen = 0;
928 key->dwMode = 0;
929 break;
930
931 case CALG_RC2:
932 case CALG_DES:
933 case CALG_3DES_112:
934 case CALG_3DES:
935 key->dwBlockLen = 8;
936 key->dwMode = CRYPT_MODE_CBC;
937 break;
938
939 case CALG_AES_128:
940 case CALG_AES_192:
941 case CALG_AES_256:
942 key->dwBlockLen = 16;
943 key->dwMode = CRYPT_MODE_CBC;
944 break;
945
946 case CALG_RSA_KEYX:
947 case CALG_RSA_SIGN:
948 key->dwBlockLen = key_len >> 3;
949 key->dwMode = 0;
950 break;
951
952 case CALG_HMAC:
953 key->dwBlockLen = 0;
954 key->dwMode = 0;
955 break;
956 }
957
958 *ret_key = key;
959 return hkey;
960}
961
962/******************************************************************************
963 * new_key [Internal]
964 *
965 * Creates a new key object without assigning the actual binary key value.
966 * This is done by CPDeriveKey, CPGenKey or CPImportKey, which call this function.
967 *
968 * PARAMS
969 * hProv [I] Handle to the provider to which the created key will belong.
970 * aiAlgid [I] The new key shall use the crypto algorithm identified by aiAlgid.
971 * dwFlags [I] Upper 16 bits give the key length.
972 * Lower 16 bits: CRYPT_EXPORTABLE, CRYPT_CREATE_SALT,
973 * CRYPT_NO_SALT
974 * ppCryptKey [O] Pointer to the created key
975 *
976 * RETURNS
977 * Success: Handle to the created key.
978 * Failure: INVALID_HANDLE_VALUE
979 */
981{
982 DWORD dwKeyLen = HIWORD(dwFlags);
983 const PROV_ENUMALGS_EX *peaAlgidInfo;
984
985 *ppCryptKey = NULL;
986
987 /*
988 * Retrieve the CSP's capabilities for the given ALG_ID value
989 */
990 peaAlgidInfo = get_algid_info(hProv, aiAlgid);
991 if (!peaAlgidInfo) return (HCRYPTKEY)INVALID_HANDLE_VALUE;
992
993 TRACE("alg = %s, dwKeyLen = %ld\n", debugstr_a(peaAlgidInfo->szName),
994 dwKeyLen);
995 /*
996 * Assume the default key length, if none is specified explicitly
997 */
998 if (dwKeyLen == 0) dwKeyLen = peaAlgidInfo->dwDefaultLen;
999
1000 /*
1001 * Check if the requested key length is supported by the current CSP.
1002 * Adjust key length's for DES algorithms.
1003 */
1004 switch (aiAlgid) {
1005 case CALG_DES:
1006 if (dwKeyLen == RSAENH_DES_EFFECTIVE_KEYLEN) {
1007 dwKeyLen = RSAENH_DES_STORAGE_KEYLEN;
1008 }
1009 if (dwKeyLen != RSAENH_DES_STORAGE_KEYLEN) {
1012 }
1013 break;
1014
1015 case CALG_3DES_112:
1016 if (dwKeyLen == RSAENH_3DES112_EFFECTIVE_KEYLEN) {
1018 }
1019 if (dwKeyLen != RSAENH_3DES112_STORAGE_KEYLEN) {
1022 }
1023 break;
1024
1025 case CALG_3DES:
1026 if (dwKeyLen == RSAENH_3DES_EFFECTIVE_KEYLEN) {
1027 dwKeyLen = RSAENH_3DES_STORAGE_KEYLEN;
1028 }
1029 if (dwKeyLen != RSAENH_3DES_STORAGE_KEYLEN) {
1032 }
1033 break;
1034
1035 case CALG_HMAC:
1036 /* Avoid the key length check for HMAC keys, which have unlimited
1037 * length.
1038 */
1039 break;
1040
1041 default:
1042 if (dwKeyLen % 8 ||
1043 dwKeyLen > peaAlgidInfo->dwMaxLen ||
1044 dwKeyLen < peaAlgidInfo->dwMinLen)
1045 {
1046 TRACE("key len %ld out of bounds (%ld, %ld)\n", dwKeyLen,
1047 peaAlgidInfo->dwMinLen, peaAlgidInfo->dwMaxLen);
1050 }
1051 }
1052
1053 return alloc_key(hProv, aiAlgid, dwFlags, dwKeyLen, ppCryptKey);
1054}
1055
1056/******************************************************************************
1057 * map_key_spec_to_key_pair_name [Internal]
1058 *
1059 * Returns the name of the registry value associated with a key spec.
1060 *
1061 * PARAMS
1062 * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE
1063 *
1064 * RETURNS
1065 * Success: Name of registry value.
1066 * Failure: NULL
1067 */
1069{
1070 LPCSTR szValueName;
1071
1072 switch (dwKeySpec)
1073 {
1074 case AT_KEYEXCHANGE:
1075 szValueName = "KeyExchangeKeyPair";
1076 break;
1077 case AT_SIGNATURE:
1078 szValueName = "SignatureKeyPair";
1079 break;
1080 default:
1081 WARN("invalid key spec %ld\n", dwKeySpec);
1082 szValueName = NULL;
1083 }
1084 return szValueName;
1085}
1086
1087/******************************************************************************
1088 * store_key_pair [Internal]
1089 *
1090 * Stores a key pair to the registry
1091 *
1092 * PARAMS
1093 * hCryptKey [I] Handle to the key to be stored
1094 * hKey [I] Registry key where the key pair is to be stored
1095 * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE
1096 * dwFlags [I] Flags for protecting the key
1097 */
1098static void store_key_pair(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpec, DWORD dwFlags)
1099{
1100 LPCSTR szValueName;
1101 DATA_BLOB blobIn, blobOut;
1102 CRYPTKEY *pKey;
1103 DWORD dwLen;
1104 BYTE *pbKey;
1105
1106 if (!(szValueName = map_key_spec_to_key_pair_name(dwKeySpec)))
1107 return;
1109 (OBJECTHDR**)&pKey))
1110 {
1111 if (crypt_export_key(pKey, 0, PRIVATEKEYBLOB, 0, TRUE, 0, &dwLen))
1112 {
1113 pbKey = malloc(dwLen);
1114 if (pbKey)
1115 {
1117 &dwLen))
1118 {
1119 blobIn.pbData = pbKey;
1120 blobIn.cbData = dwLen;
1121
1122 if (CryptProtectData(&blobIn, NULL, NULL, NULL, NULL,
1123 dwFlags, &blobOut))
1124 {
1125 RegSetValueExA(hKey, szValueName, 0, REG_BINARY,
1126 blobOut.pbData, blobOut.cbData);
1127 LocalFree(blobOut.pbData);
1128 }
1129 }
1130 free(pbKey);
1131 }
1132 }
1133 }
1134}
1135
1136/******************************************************************************
1137 * map_key_spec_to_permissions_name [Internal]
1138 *
1139 * Returns the name of the registry value associated with the permissions for
1140 * a key spec.
1141 *
1142 * PARAMS
1143 * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE
1144 *
1145 * RETURNS
1146 * Success: Name of registry value.
1147 * Failure: NULL
1148 */
1150{
1151 LPCSTR szValueName;
1152
1153 switch (dwKeySpec)
1154 {
1155 case AT_KEYEXCHANGE:
1156 szValueName = "KeyExchangePermissions";
1157 break;
1158 case AT_SIGNATURE:
1159 szValueName = "SignaturePermissions";
1160 break;
1161 default:
1162 WARN("invalid key spec %ld\n", dwKeySpec);
1163 szValueName = NULL;
1164 }
1165 return szValueName;
1166}
1167
1168/******************************************************************************
1169 * store_key_permissions [Internal]
1170 *
1171 * Stores a key's permissions to the registry
1172 *
1173 * PARAMS
1174 * hCryptKey [I] Handle to the key whose permissions are to be stored
1175 * hKey [I] Registry key where the key permissions are to be stored
1176 * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE
1177 */
1178static void store_key_permissions(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpec)
1179{
1180 LPCSTR szValueName;
1181 CRYPTKEY *pKey;
1182
1183 if (!(szValueName = map_key_spec_to_permissions_name(dwKeySpec)))
1184 return;
1186 (OBJECTHDR**)&pKey))
1187 RegSetValueExA(hKey, szValueName, 0, REG_DWORD,
1188 (BYTE *)&pKey->dwPermissions,
1189 sizeof(pKey->dwPermissions));
1190}
1191
1192/******************************************************************************
1193 * create_container_key [Internal]
1194 *
1195 * Creates the registry key for a key container's persistent storage.
1196 *
1197 * PARAMS
1198 * pKeyContainer [I] Pointer to the key container
1199 * sam [I] Desired registry access
1200 * phKey [O] Returned key
1201 */
1202static BOOL create_container_key(KEYCONTAINER *pKeyContainer, REGSAM sam, HKEY *phKey)
1203{
1204 CHAR szRSABase[sizeof(RSAENH_REGKEY) + MAX_PATH];
1205 HKEY hRootKey;
1206
1207 sprintf(szRSABase, RSAENH_REGKEY, pKeyContainer->szName);
1208
1209 if (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET)
1210 hRootKey = HKEY_LOCAL_MACHINE;
1211 else
1212 hRootKey = HKEY_CURRENT_USER;
1213
1214 /* @@ Wine registry key: HKLM\Software\Wine\Crypto\RSA */
1215 /* @@ Wine registry key: HKCU\Software\Wine\Crypto\RSA */
1216 return RegCreateKeyExA(hRootKey, szRSABase, 0, NULL,
1218 == ERROR_SUCCESS;
1219}
1220
1221/******************************************************************************
1222 * open_container_key [Internal]
1223 *
1224 * Opens a key container's persistent storage for reading.
1225 *
1226 * PARAMS
1227 * pszContainerName [I] Name of the container to be opened. May be the empty
1228 * string if the parent key of all containers is to be
1229 * opened.
1230 * dwFlags [I] Flags indicating which keyset to be opened.
1231 * phKey [O] Returned key
1232 */
1233static BOOL open_container_key(LPCSTR pszContainerName, DWORD dwFlags, REGSAM access, HKEY *phKey)
1234{
1235 CHAR szRSABase[sizeof(RSAENH_REGKEY) + MAX_PATH];
1236 HKEY hRootKey;
1237
1238 sprintf(szRSABase, RSAENH_REGKEY, pszContainerName);
1239
1241 hRootKey = HKEY_LOCAL_MACHINE;
1242 else
1243 hRootKey = HKEY_CURRENT_USER;
1244
1245 /* @@ Wine registry key: HKLM\Software\Wine\Crypto\RSA */
1246 /* @@ Wine registry key: HKCU\Software\Wine\Crypto\RSA */
1247 return RegOpenKeyExA(hRootKey, szRSABase, 0, access, phKey) ==
1249}
1250
1251/******************************************************************************
1252 * delete_container_key [Internal]
1253 *
1254 * Deletes a key container's persistent storage.
1255 *
1256 * PARAMS
1257 * pszContainerName [I] Name of the container to be opened.
1258 * dwFlags [I] Flags indicating which keyset to be opened.
1259 */
1261{
1262 CHAR szRegKey[sizeof(RSAENH_REGKEY) + MAX_PATH];
1263 HKEY hRootKey;
1264
1265 sprintf(szRegKey, RSAENH_REGKEY, pszContainerName);
1266
1268 hRootKey = HKEY_LOCAL_MACHINE;
1269 else
1270 hRootKey = HKEY_CURRENT_USER;
1271 if (!RegDeleteKeyA(hRootKey, szRegKey)) {
1273 return TRUE;
1274 } else {
1276 return FALSE;
1277 }
1278}
1279
1280/******************************************************************************
1281 * store_key_container_keys [Internal]
1282 *
1283 * Stores key container's keys in a persistent location.
1284 *
1285 * PARAMS
1286 * pKeyContainer [I] Pointer to the key container whose keys are to be saved
1287 */
1288static void store_key_container_keys(KEYCONTAINER *pKeyContainer)
1289{
1290 HKEY hKey;
1291 DWORD dwFlags;
1292
1293 /* On WinXP, persistent keys are stored in a file located at:
1294 * $AppData$\\Microsoft\\Crypto\\RSA\\$SID$\\some_hex_string
1295 */
1296
1297 if (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET)
1299 else
1300 dwFlags = 0;
1301
1302 if (create_container_key(pKeyContainer, KEY_WRITE, &hKey))
1303 {
1304 store_key_pair(pKeyContainer->hKeyExchangeKeyPair, hKey,
1306 store_key_pair(pKeyContainer->hSignatureKeyPair, hKey,
1309 }
1310}
1311
1312/******************************************************************************
1313 * store_key_container_permissions [Internal]
1314 *
1315 * Stores key container's key permissions in a persistent location.
1316 *
1317 * PARAMS
1318 * pKeyContainer [I] Pointer to the key container whose key permissions are to
1319 * be saved
1320 */
1322{
1323 HKEY hKey;
1324
1325 if (create_container_key(pKeyContainer, KEY_WRITE, &hKey))
1326 {
1330 AT_SIGNATURE);
1332 }
1333}
1334
1335/******************************************************************************
1336 * release_key_container_keys [Internal]
1337 *
1338 * Releases key container's keys.
1339 *
1340 * PARAMS
1341 * pKeyContainer [I] Pointer to the key container whose keys are to be released.
1342 */
1343static void release_key_container_keys(KEYCONTAINER *pKeyContainer)
1344{
1349}
1350
1351/******************************************************************************
1352 * destroy_key_container [Internal]
1353 *
1354 * Destructor for key containers.
1355 *
1356 * PARAMS
1357 * pObjectHdr [I] Pointer to the key container to be destroyed.
1358 */
1359static void destroy_key_container(OBJECTHDR *pObjectHdr)
1360{
1361 KEYCONTAINER *pKeyContainer = (KEYCONTAINER*)pObjectHdr;
1362
1363 if (!(pKeyContainer->dwFlags & CRYPT_VERIFYCONTEXT))
1364 {
1365 store_key_container_keys(pKeyContainer);
1366 store_key_container_permissions(pKeyContainer);
1367 release_key_container_keys(pKeyContainer);
1368 }
1369 else
1370 release_key_container_keys(pKeyContainer);
1371 free( pKeyContainer );
1372}
1373
1374/******************************************************************************
1375 * new_key_container [Internal]
1376 *
1377 * Create a new key container. The personality (RSA Base, Strong or Enhanced CP)
1378 * of the CSP is determined via the pVTable->pszProvName string.
1379 *
1380 * PARAMS
1381 * pszContainerName [I] Name of the key container.
1382 * pVTable [I] Callback functions and context info provided by the OS
1383 *
1384 * RETURNS
1385 * Success: Handle to the new key container.
1386 * Failure: INVALID_HANDLE_VALUE
1387 */
1388static HCRYPTPROV new_key_container(PCCH pszContainerName, DWORD dwFlags, const VTableProvStruc *pVTable)
1389{
1390 KEYCONTAINER *pKeyContainer;
1391 HCRYPTPROV hKeyContainer;
1392
1394 destroy_key_container, (OBJECTHDR**)&pKeyContainer);
1395 if (hKeyContainer != (HCRYPTPROV)INVALID_HANDLE_VALUE)
1396 {
1397 lstrcpynA(pKeyContainer->szName, pszContainerName, MAX_PATH);
1398 pKeyContainer->dwFlags = dwFlags;
1399 pKeyContainer->dwEnumAlgsCtr = 0;
1402 if (pVTable && pVTable->pszProvName) {
1403 lstrcpynA(pKeyContainer->szProvName, pVTable->pszProvName, MAX_PATH);
1404 if (!strcmp(pVTable->pszProvName, MS_DEF_PROV_A)) {
1405 pKeyContainer->dwPersonality = RSAENH_PERSONALITY_BASE;
1406 } else if (!strcmp(pVTable->pszProvName, MS_ENHANCED_PROV_A)) {
1408 } else if (!strcmp(pVTable->pszProvName, MS_DEF_RSA_SCHANNEL_PROV_A)) {
1410 } else if (!strcmp(pVTable->pszProvName, MS_ENH_RSA_AES_PROV_A) ||
1412 pKeyContainer->dwPersonality = RSAENH_PERSONALITY_AES;
1413 } else {
1415 }
1416 }
1417
1418 /* The new key container has to be inserted into the CSP immediately
1419 * after creation to be available for CPGetProvParam's PP_ENUMCONTAINERS. */
1420 if (!(dwFlags & CRYPT_VERIFYCONTEXT)) {
1421 HKEY hKey;
1422
1423 if (create_container_key(pKeyContainer, KEY_WRITE, &hKey))
1425 }
1426 }
1427
1428 return hKeyContainer;
1429}
1430
1431/******************************************************************************
1432 * read_key_value [Internal]
1433 *
1434 * Reads a key pair value from the registry
1435 *
1436 * PARAMS
1437 * hKeyContainer [I] Crypt provider to use to import the key
1438 * hKey [I] Registry key from which to read the key pair
1439 * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE
1440 * dwFlags [I] Flags for unprotecting the key
1441 * phCryptKey [O] Returned key
1442 */
1443static BOOL read_key_value(HCRYPTPROV hKeyContainer, HKEY hKey, DWORD dwKeySpec, DWORD dwFlags, HCRYPTKEY *phCryptKey)
1444{
1445 LPCSTR szValueName;
1446 DWORD dwValueType, dwLen;
1447 BYTE *pbKey;
1448 DATA_BLOB blobIn, blobOut;
1449 BOOL ret = FALSE;
1450
1451 if (!(szValueName = map_key_spec_to_key_pair_name(dwKeySpec)))
1452 return FALSE;
1453 if (RegQueryValueExA(hKey, szValueName, 0, &dwValueType, NULL, &dwLen) ==
1455 {
1456 pbKey = malloc(dwLen);
1457 if (pbKey)
1458 {
1459 if (RegQueryValueExA(hKey, szValueName, 0, &dwValueType, pbKey, &dwLen) ==
1461 {
1462 blobIn.pbData = pbKey;
1463 blobIn.cbData = dwLen;
1464
1465 if (CryptUnprotectData(&blobIn, NULL, NULL, NULL, NULL,
1466 dwFlags, &blobOut))
1467 {
1468 ret = import_key(hKeyContainer, blobOut.pbData, blobOut.cbData, 0, 0,
1469 FALSE, phCryptKey);
1470 LocalFree(blobOut.pbData);
1471 }
1472 }
1473 free(pbKey);
1474 }
1475 }
1476 if (ret)
1477 {
1478 CRYPTKEY *pKey;
1479
1480 if (lookup_handle(&handle_table, *phCryptKey, RSAENH_MAGIC_KEY,
1481 (OBJECTHDR**)&pKey))
1482 {
1483 if ((szValueName = map_key_spec_to_permissions_name(dwKeySpec)))
1484 {
1485 dwLen = sizeof(pKey->dwPermissions);
1486 RegQueryValueExA(hKey, szValueName, 0, NULL,
1487 (BYTE *)&pKey->dwPermissions, &dwLen);
1488 }
1489 }
1490 }
1491 return ret;
1492}
1493
1494/******************************************************************************
1495 * read_key_container [Internal]
1496 *
1497 * Tries to read the persistent state of the key container (mainly the signature
1498 * and key exchange private keys) given by pszContainerName.
1499 *
1500 * PARAMS
1501 * pszContainerName [I] Name of the key container to read from the registry
1502 * pVTable [I] Pointer to context data provided by the operating system
1503 *
1504 * RETURNS
1505 * Success: Handle to the key container read from the registry
1506 * Failure: INVALID_HANDLE_VALUE
1507 */
1508static HCRYPTPROV read_key_container(PCHAR pszContainerName, DWORD dwFlags, const VTableProvStruc *pVTable)
1509{
1510 HKEY hKey;
1511 KEYCONTAINER *pKeyContainer;
1512 HCRYPTPROV hKeyContainer;
1513 HCRYPTKEY hCryptKey;
1514
1515 if (!open_container_key(pszContainerName, dwFlags, KEY_READ, &hKey))
1516 {
1519 }
1520
1521 hKeyContainer = new_key_container(pszContainerName, dwFlags, pVTable);
1522 if (hKeyContainer != (HCRYPTPROV)INVALID_HANDLE_VALUE)
1523 {
1524 DWORD dwProtectFlags = (dwFlags & CRYPT_MACHINE_KEYSET) ?
1526
1527 if (!lookup_handle(&handle_table, hKeyContainer, RSAENH_MAGIC_CONTAINER,
1528 (OBJECTHDR**)&pKeyContainer))
1530
1531 /* read_key_value calls import_key, which calls import_private_key,
1532 * which implicitly installs the key value into the appropriate key
1533 * container key. Thus the ref count is incremented twice, once for
1534 * the output key value, and once for the implicit install, and needs
1535 * to be decremented to balance the two.
1536 */
1537 if (read_key_value(hKeyContainer, hKey, AT_KEYEXCHANGE,
1538 dwProtectFlags, &hCryptKey))
1540 if (read_key_value(hKeyContainer, hKey, AT_SIGNATURE,
1541 dwProtectFlags, &hCryptKey))
1543 }
1544
1545 return hKeyContainer;
1546}
1547
1548/******************************************************************************
1549 * build_hash_signature [Internal]
1550 *
1551 * Builds a padded version of a hash to match the length of the RSA key modulus.
1552 *
1553 * PARAMS
1554 * pbSignature [O] The padded hash object is stored here.
1555 * dwLen [I] Length of the pbSignature buffer.
1556 * aiAlgid [I] Algorithm identifier of the hash to be padded.
1557 * abHashValue [I] The value of the hash object.
1558 * dwHashLen [I] Length of the hash value.
1559 * dwFlags [I] Selection of padding algorithm.
1560 *
1561 * RETURNS
1562 * Success: TRUE
1563 * Failure: FALSE (NTE_BAD_ALGID)
1564 */
1565static BOOL build_hash_signature(BYTE *pbSignature, DWORD dwLen, ALG_ID aiAlgid,
1566 const BYTE *abHashValue, DWORD dwHashLen, DWORD dwFlags)
1567{
1568 /* These prefixes are meant to be concatenated with hash values of the
1569 * respective kind to form a PKCS #7 DigestInfo. */
1570 static const struct tagOIDDescriptor {
1571 ALG_ID aiAlgid;
1572 DWORD dwLen;
1573 const BYTE abOID[19];
1574 } aOIDDescriptor[] = {
1575 { CALG_MD2, 18, { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48,
1576 0x86, 0xf7, 0x0d, 0x02, 0x02, 0x05, 0x00, 0x04, 0x10 } },
1577 { CALG_MD4, 18, { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48,
1578 0x86, 0xf7, 0x0d, 0x02, 0x04, 0x05, 0x00, 0x04, 0x10 } },
1579 { CALG_MD5, 18, { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48,
1580 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 } },
1581 { CALG_SHA, 15, { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
1582 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 } },
1583 { CALG_SHA_256, 19, { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
1584 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
1585 0x05, 0x00, 0x04, 0x20 } },
1586 { CALG_SHA_384, 19, { 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
1587 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
1588 0x05, 0x00, 0x04, 0x30 } },
1589 { CALG_SHA_512, 19, { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
1590 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
1591 0x05, 0x00, 0x04, 0x40 } },
1592 { CALG_SSL3_SHAMD5, 0, { 0 } },
1593 { 0, 0, { 0 } }
1594 };
1595 DWORD dwIdxOID, i, j;
1596
1597 for (dwIdxOID = 0; aOIDDescriptor[dwIdxOID].aiAlgid; dwIdxOID++) {
1598 if (aOIDDescriptor[dwIdxOID].aiAlgid == aiAlgid) break;
1599 }
1600
1601 if (!aOIDDescriptor[dwIdxOID].aiAlgid) {
1603 return FALSE;
1604 }
1605
1606 /* Build the padded signature */
1607 if (dwFlags & CRYPT_X931_FORMAT) {
1608 pbSignature[0] = 0x6b;
1609 for (i=1; i < dwLen - dwHashLen - 3; i++) {
1610 pbSignature[i] = 0xbb;
1611 }
1612 pbSignature[i++] = 0xba;
1613 for (j=0; j < dwHashLen; j++, i++) {
1614 pbSignature[i] = abHashValue[j];
1615 }
1616 pbSignature[i++] = 0x33;
1617 pbSignature[i++] = 0xcc;
1618 } else {
1619 pbSignature[0] = 0x00;
1620 pbSignature[1] = 0x01;
1621 if (dwFlags & CRYPT_NOHASHOID) {
1622 for (i=2; i < dwLen - 1 - dwHashLen; i++) {
1623 pbSignature[i] = 0xff;
1624 }
1625 pbSignature[i++] = 0x00;
1626 } else {
1627 for (i=2; i < dwLen - 1 - aOIDDescriptor[dwIdxOID].dwLen - dwHashLen; i++) {
1628 pbSignature[i] = 0xff;
1629 }
1630 pbSignature[i++] = 0x00;
1631 for (j=0; j < aOIDDescriptor[dwIdxOID].dwLen; j++) {
1632 pbSignature[i++] = aOIDDescriptor[dwIdxOID].abOID[j];
1633 }
1634 }
1635 for (j=0; j < dwHashLen; j++) {
1636 pbSignature[i++] = abHashValue[j];
1637 }
1638 }
1639
1640 return TRUE;
1641}
1642
1643/******************************************************************************
1644 * tls1_p [Internal]
1645 *
1646 * This is an implementation of the 'P_hash' helper function for TLS1's PRF.
1647 * It is used exclusively by tls1_prf. For details see RFC 2246, chapter 5.
1648 * The pseudo random stream generated by this function is exclusive or'ed with
1649 * the data in pbBuffer.
1650 *
1651 * PARAMS
1652 * hHMAC [I] HMAC object, which will be used in pseudo random generation
1653 * pblobSeed [I] Seed value
1654 * pbBuffer [I/O] Pseudo random stream will be xor'ed to the provided data
1655 * dwBufferLen [I] Number of pseudo random bytes desired
1656 *
1657 * RETURNS
1658 * Success: TRUE
1659 * Failure: FALSE
1660 */
1661static BOOL tls1_p(HCRYPTHASH hHMAC, const PCRYPT_DATA_BLOB pblobSeed, BYTE *pbBuffer,
1662 DWORD dwBufferLen)
1663{
1664 CRYPTHASH *pHMAC;
1666 DWORD i = 0;
1667
1668 if (!lookup_handle(&handle_table, hHMAC, RSAENH_MAGIC_HASH, (OBJECTHDR**)&pHMAC)) {
1670 return FALSE;
1671 }
1672
1673 /* compute A_1 = HMAC(seed) */
1674 init_hash(pHMAC);
1675 update_hash(pHMAC, pblobSeed->pbData, pblobSeed->cbData);
1676 finalize_hash(pHMAC);
1677 memcpy(abAi, pHMAC->abHashValue, pHMAC->dwHashSize);
1678
1679 do {
1680 /* compute HMAC(A_i + seed) */
1681 init_hash(pHMAC);
1682 update_hash(pHMAC, abAi, pHMAC->dwHashSize);
1683 update_hash(pHMAC, pblobSeed->pbData, pblobSeed->cbData);
1684 finalize_hash(pHMAC);
1685
1686 /* pseudo random stream := CONCAT_{i=1..n} ( HMAC(A_i + seed) ) */
1687 do {
1688 if (i >= dwBufferLen) break;
1689 pbBuffer[i] ^= pHMAC->abHashValue[i % pHMAC->dwHashSize];
1690 i++;
1691 } while (i % pHMAC->dwHashSize);
1692
1693 /* compute A_{i+1} = HMAC(A_i) */
1694 init_hash(pHMAC);
1695 update_hash(pHMAC, abAi, pHMAC->dwHashSize);
1696 finalize_hash(pHMAC);
1697 memcpy(abAi, pHMAC->abHashValue, pHMAC->dwHashSize);
1698 } while (i < dwBufferLen);
1699
1700 return TRUE;
1701}
1702
1703/******************************************************************************
1704 * tls1_prf [Internal]
1705 *
1706 * TLS1 pseudo random function as specified in RFC 2246, chapter 5
1707 *
1708 * PARAMS
1709 * hProv [I] Key container used to compute the pseudo random stream
1710 * hSecret [I] Key that holds the (pre-)master secret
1711 * pblobLabel [I] Descriptive label
1712 * pblobSeed [I] Seed value
1713 * pbBuffer [O] Pseudo random numbers will be stored here
1714 * dwBufferLen [I] Number of pseudo random bytes desired
1715 *
1716 * RETURNS
1717 * Success: TRUE
1718 * Failure: FALSE
1719 */
1720static BOOL tls1_prf(HCRYPTPROV hProv, HCRYPTPROV hSecret, const PCRYPT_DATA_BLOB pblobLabel,
1721 const PCRYPT_DATA_BLOB pblobSeed, BYTE *pbBuffer, DWORD dwBufferLen)
1722{
1723 HMAC_INFO hmacInfo = { 0, NULL, 0, NULL, 0 };
1726 CRYPTKEY *pHalfSecret, *pSecret;
1727 DWORD dwHalfSecretLen;
1728 BOOL result = FALSE;
1729 CRYPT_DATA_BLOB blobLabelSeed;
1730
1731 TRACE("(hProv=%08Ix, hSecret=%08Ix, pblobLabel=%p, pblobSeed=%p, pbBuffer=%p, dwBufferLen=%ld)\n",
1732 hProv, hSecret, pblobLabel, pblobSeed, pbBuffer, dwBufferLen);
1733
1734 if (!lookup_handle(&handle_table, hSecret, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pSecret)) {
1736 return FALSE;
1737 }
1738
1739 dwHalfSecretLen = (pSecret->dwKeyLen+1)/2;
1740
1741 /* concatenation of the label and the seed */
1742 if (!concat_data_blobs(&blobLabelSeed, pblobLabel, pblobSeed)) goto exit;
1743
1744 /* zero out the buffer, since two random streams will be xor'ed into it. */
1745 memset(pbBuffer, 0, dwBufferLen);
1746
1747 /* build a 'fake' key, to hold the secret. CALG_SSL2_MASTER is used since it provides
1748 * the biggest range of valid key lengths. */
1749 hHalfSecret = new_key(hProv, CALG_SSL2_MASTER, MAKELONG(0,dwHalfSecretLen*8), &pHalfSecret);
1750 if (hHalfSecret == (HCRYPTKEY)INVALID_HANDLE_VALUE) goto exit;
1751
1752 /* Derive an HMAC_MD5 hash and call the helper function. */
1753 memcpy(pHalfSecret->abKeyValue, pSecret->abKeyValue, dwHalfSecretLen);
1754 if (!RSAENH_CPCreateHash(hProv, CALG_HMAC, hHalfSecret, 0, &hHMAC)) goto exit;
1755 hmacInfo.HashAlgid = CALG_MD5;
1756 if (!RSAENH_CPSetHashParam(hProv, hHMAC, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0)) goto exit;
1757 if (!tls1_p(hHMAC, &blobLabelSeed, pbBuffer, dwBufferLen)) goto exit;
1758
1759 /* Reconfigure to HMAC_SHA hash and call helper function again. */
1760 memcpy(pHalfSecret->abKeyValue, pSecret->abKeyValue + (pSecret->dwKeyLen/2), dwHalfSecretLen);
1761 hmacInfo.HashAlgid = CALG_SHA;
1762 if (!RSAENH_CPSetHashParam(hProv, hHMAC, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0)) goto exit;
1763 if (!tls1_p(hHMAC, &blobLabelSeed, pbBuffer, dwBufferLen)) goto exit;
1764
1765 result = TRUE;
1766exit:
1769 free_data_blob(&blobLabelSeed);
1770 return result;
1771}
1772
1773/******************************************************************************
1774 * pad_data_pkcs1 [Internal]
1775 *
1776 * Helper function for data padding according to PKCS1 #2
1777 *
1778 * PARAMS
1779 * abData [I] The data to be padded
1780 * dwDataLen [I] Length of the data
1781 * abBuffer [O] Padded data will be stored here
1782 * dwBufferLen [I] Length of the buffer (also length of padded data)
1783 * dwFlags [I] Padding format (CRYPT_SSL2_FALLBACK)
1784 *
1785 * RETURN
1786 * Success: TRUE
1787 * Failure: FALSE (NTE_BAD_LEN, too much data to pad)
1788 */
1789static BOOL pad_data_pkcs1(const BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, DWORD dwBufferLen, DWORD dwFlags)
1790{
1791 DWORD i;
1792
1793 /* Ensure there is enough space for PKCS1 #2 padding */
1794 if (dwDataLen > dwBufferLen-11) {
1796 return FALSE;
1797 }
1798
1799 memmove(abBuffer + dwBufferLen - dwDataLen, abData, dwDataLen);
1800
1801 abBuffer[0] = 0x00;
1802 abBuffer[1] = RSAENH_PKC_BLOCKTYPE;
1803 for (i=2; i < dwBufferLen - dwDataLen - 1; i++)
1804 do RtlGenRandom(&abBuffer[i], 1); while (!abBuffer[i]);
1806 for (i-=8; i < dwBufferLen - dwDataLen - 1; i++)
1807 abBuffer[i] = 0x03;
1808 abBuffer[i] = 0x00;
1809
1810 return TRUE;
1811}
1812
1813/******************************************************************************
1814 * pkcs1_mgf1 [Internal]
1815 *
1816 * MGF function for RSA EM-OAEP as specified in RFC 8017 PKCS #1 V2.2, Appendix B.2.1. MGF1
1817 *
1818 * PARAMS
1819 * hProv [I] Cryptographic provider handle
1820 * pbSeed [I] Seed from which mask is generated
1821 * dwSeedLength [I] Length of pbSeed
1822 * dwLength [I] Intended length in octets of the mask
1823 * pbMask [O] Generated mask if success. Caller is responsible for freeing the mask when it's done
1824 *
1825 * RETURNS
1826 * Success: TRUE
1827 * Failure: FALSE
1828 */
1830{
1831 HCRYPTHASH hHash;
1832 BYTE *pbHashInput, *pbCounter;
1834 DWORD dwLen, dwHashLen;
1835
1836 RSAENH_CPCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
1837 RSAENH_CPHashData(hProv, hHash, 0, 0, 0);
1838 dwLen = sizeof(dwHashLen);
1839 RSAENH_CPGetHashParam(hProv, hHash, HP_HASHSIZE, (BYTE *)&dwHashLen, &dwLen, 0);
1841
1842 /* Allocate multiples of hash value */
1843 pbMask->pbData = malloc((dwLength + dwHashLen - 1) / dwHashLen * dwHashLen);
1844 if (!pbMask->pbData)
1845 {
1847 return FALSE;
1848 }
1849 pbMask->cbData = dwLength;
1850
1851 pbHashInput = malloc(dwSeedLength + sizeof(DWORD));
1852 if (!pbHashInput)
1853 {
1854 free_data_blob(pbMask);
1856 return FALSE;
1857 }
1858
1859 dwLen = dwHashLen;
1860 memcpy(pbHashInput, pbSeed, dwSeedLength);
1861 pbCounter = pbHashInput + dwSeedLength;
1862 for (dwCounter = 0; dwCounter < (dwLength + dwHashLen - 1) / dwHashLen; dwCounter++)
1863 {
1864 *(pbCounter) = (BYTE)((dwCounter >> 24) & 0xff);
1865 *(pbCounter + 1) = (BYTE)((dwCounter >> 16) & 0xff);
1866 *(pbCounter + 2) = (BYTE)((dwCounter >> 8) & 0xff);
1867 *(pbCounter + 3) = (BYTE)(dwCounter & 0xff);
1868 RSAENH_CPCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
1869 RSAENH_CPHashData(hProv, hHash, pbHashInput, dwSeedLength + sizeof(DWORD), 0);
1870 /* pbMask->pbData = old pbMask->pbData || Hash(Seed || Counter) */
1871 RSAENH_CPGetHashParam(hProv, hHash, HP_HASHVAL, pbMask->pbData + dwCounter * dwHashLen, &dwLen, 0);
1873 }
1874
1875 free(pbHashInput);
1876 return TRUE;
1877}
1878
1879/******************************************************************************
1880 * pad_data_oaep [Internal]
1881 *
1882 * Helper function for data OAEP padding scheme according to RFC 8017 PKCS #1 V2.2
1883 *
1884 * PARAMS
1885 * hProv [I] Cryptographic provider handle
1886 * abData [I] The data to be padded
1887 * dwDataLen [I] Length of the data
1888 * abBuffer [O] Padded data will be stored here
1889 * dwBufferLen [I] Length of the buffer (also length of padded data)
1890 * dwFlags [I] Currently only CRYPT_OAEP is defined
1891 *
1892 * RETURN
1893 * Success: TRUE
1894 * Failure: FALSE
1895 */
1896static BOOL pad_data_oaep(HCRYPTPROV hProv, const BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, DWORD dwBufferLen,
1897 DWORD dwFlags)
1898{
1899 CRYPT_DATA_BLOB blobDbMask = {0}, blobSeedMask = {0};
1900 HCRYPTHASH hHash;
1901 BYTE *pbPadded = NULL, *pbDb, *pbSeed;
1902 DWORD dwLen, dwHashLen;
1903 DWORD dwDbLen, dwSeedLen;
1904 BOOL result, ret = FALSE;
1905 DWORD i;
1906
1907 RSAENH_CPCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
1908 /* Empty label */
1909 RSAENH_CPHashData(hProv, hHash, 0, 0, 0);
1910 dwLen = sizeof(dwHashLen);
1911 RSAENH_CPGetHashParam(hProv, hHash, HP_HASHSIZE, (BYTE *)&dwHashLen, &dwLen, 0);
1912
1913 if (dwDataLen > dwBufferLen - 2 * dwHashLen - 2)
1914 {
1916 goto done;
1917 }
1918
1919 if (dwBufferLen < 2 * dwHashLen + 2)
1920 {
1922 goto done;
1923 }
1924
1925 pbPadded = malloc(dwBufferLen);
1926 if (!pbPadded)
1927 {
1929 goto done;
1930 }
1931
1932 /* EM = 00 || maskedSeed || maskedDB */
1933 pbPadded[0] = 0;
1934 pbSeed = pbPadded + 1;
1935 dwSeedLen = dwHashLen;
1936 pbDb = pbPadded + 1 + dwHashLen;
1937 dwDbLen = dwBufferLen - dwSeedLen - 1;
1938
1939 /* DB = pHash || PS || 01 || M */
1940 /* Set pHash in DB */
1941 dwLen = dwHashLen;
1942 RSAENH_CPGetHashParam(hProv, hHash, HP_HASHVAL, pbDb, &dwLen, 0);
1943 /* Set PS(zeros) in DB */
1944 memset(pbDb + dwHashLen, 0, dwDbLen - dwHashLen - 1 - dwDataLen);
1945 /* Set 01 in DB */
1946 pbDb[dwDbLen - dwDataLen - 1] = 1;
1947 /* Set M in DB */
1948 memcpy(pbDb + dwDbLen - dwDataLen, abData, dwDataLen);
1949
1950 /* Get seed */
1951 RtlGenRandom(pbSeed, dwHashLen);
1952 /* Get masked DB */
1953 result = pkcs1_mgf1(hProv, pbSeed, dwHashLen, dwDbLen, &blobDbMask);
1954 if (!result) goto done;
1955 for (i = 0; i < dwDbLen; i++) pbDb[i] ^= blobDbMask.pbData[i];
1956
1957 /* Get masked seed */
1958 result = pkcs1_mgf1(hProv, pbDb, dwDbLen, dwHashLen, &blobSeedMask);
1959 if (!result) goto done;
1960 for (i = 0; i < dwHashLen; i++) pbSeed[i] ^= blobSeedMask.pbData[i];
1961
1962 memcpy(abBuffer, pbPadded, dwBufferLen);
1963 ret = TRUE;
1964done:
1966 free(pbPadded);
1967 free_data_blob(&blobDbMask);
1968 free_data_blob(&blobSeedMask);
1969 return ret;
1970}
1971
1972/******************************************************************************
1973 * pad_data [Internal]
1974 *
1975 * Helper function for data padding according to padding format
1976 *
1977 * PARAMS
1978 * hProv [I] Cryptographic provider handle
1979 * abData [I] The data to be padded
1980 * dwDataLen [I] Length of the data
1981 * abBuffer [O] Padded data will be stored here
1982 * dwBufferLen [I] Length of the buffer (also length of padded data)
1983 * dwFlags [I] 0, CRYPT_SSL2_FALLBACK or CRYPT_OAEP
1984 *
1985 * RETURN
1986 * Success: TRUE
1987 * Failure: FALSE
1988 */
1989static BOOL pad_data(HCRYPTPROV hProv, const BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, DWORD dwBufferLen,
1990 DWORD dwFlags)
1991{
1992 if (dwFlags == CRYPT_OAEP)
1993 return pad_data_oaep(hProv, abData, dwDataLen, abBuffer, dwBufferLen, dwFlags);
1994 else
1995 return pad_data_pkcs1(abData, dwDataLen, abBuffer, dwBufferLen, dwFlags);
1996}
1997
1998/******************************************************************************
1999 * unpad_data_pkcs1 [Internal]
2000 *
2001 * Remove the PKCS1 padding from RSA decrypted data
2002 *
2003 * PARAMS
2004 * abData [I] The padded data
2005 * dwDataLen [I] Length of the padded data
2006 * abBuffer [O] Data without padding will be stored here
2007 * dwBufferLen [I/O] I: Length of the buffer, O: Length of unpadded data
2008 * dwFlags [I] Currently none defined
2009 *
2010 * RETURNS
2011 * Success: TRUE
2012 * Failure: FALSE, (NTE_BAD_DATA, no valid PKCS1 padding or buffer too small)
2013 */
2014static BOOL unpad_data_pkcs1(const BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, DWORD *dwBufferLen, DWORD dwFlags)
2015{
2016 DWORD i;
2017
2018 if (dwDataLen < 3)
2019 {
2021 return FALSE;
2022 }
2023 for (i=2; i<dwDataLen; i++)
2024 if (!abData[i])
2025 break;
2026
2027 if ((i == dwDataLen) || (*dwBufferLen < dwDataLen - i - 1) ||
2028 (abData[0] != 0x00) || (abData[1] != RSAENH_PKC_BLOCKTYPE))
2029 {
2031 return FALSE;
2032 }
2033
2034 *dwBufferLen = dwDataLen - i - 1;
2035 memmove(abBuffer, abData + i + 1, *dwBufferLen);
2036 return TRUE;
2037}
2038
2039/******************************************************************************
2040 * unpad_data_oaep [Internal]
2041 *
2042 * Remove the OAEP padding from RSA decrypted data
2043 *
2044 * PARAMS
2045 * hProv [I] Cryptographic provider handle
2046 * abData [I] The padded data
2047 * dwDataLen [I] Length of the padded data
2048 * abBuffer [O] Data without padding will be stored here
2049 * dwBufferLen [I/O] I: Length of the buffer, O: Length of unpadded data
2050 * dwFlags [I] Currently only CRYPT_OAEP is defined
2051 *
2052 * RETURNS
2053 * Success: TRUE
2054 * Failure: FALSE
2055 */
2056static BOOL unpad_data_oaep(HCRYPTPROV hProv, const BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, DWORD *dwBufferLen,
2057 DWORD dwFlags)
2058{
2059 CRYPT_DATA_BLOB blobDbMask = {0}, blobSeedMask = {0};
2060 HCRYPTHASH hHash;
2061 BYTE *pbBuffer = NULL, *pbHashValue = NULL;
2062 const BYTE *pbPaddedSeed, *pbPaddedDb;
2063 BYTE *pbUnpaddedSeed, *pbUnpaddedDb;
2064 DWORD dwLen, dwHashLen;
2065 DWORD dwSeedLen, dwDbLen;
2066 DWORD dwZeroCount, dwMsgCount;
2067 BOOL result, ret = FALSE;
2068 DWORD i;
2069
2070 RSAENH_CPCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
2071 RSAENH_CPHashData(hProv, hHash, 0, 0, 0);
2072 dwLen = sizeof(dwHashLen);
2073 RSAENH_CPGetHashParam(hProv, hHash, HP_HASHSIZE, (BYTE *)&dwHashLen, &dwLen, 0);
2074 if (dwDataLen < 2 * dwHashLen + 2)
2075 {
2077 goto done;
2078 }
2079
2080 /* Get default hash value */
2081 pbHashValue = malloc(dwHashLen);
2082 if (!pbHashValue)
2083 {
2085 goto done;
2086 }
2087 dwLen = dwHashLen;
2088 RSAENH_CPGetHashParam(hProv, hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
2089
2090 /* Store seed and DB */
2091 pbBuffer = malloc(dwDataLen - 1);
2092 if (!pbBuffer)
2093 {
2095 goto done;
2096 }
2097
2098 pbPaddedSeed = abData + 1;
2099 pbPaddedDb = abData + 1 + dwHashLen;
2100 pbUnpaddedSeed = pbBuffer;
2101 pbUnpaddedDb = pbBuffer + dwHashLen;
2102 dwSeedLen = dwHashLen;
2103 dwDbLen = dwDataLen - dwHashLen - 1;
2104
2105 /* Get unpadded seed */
2106 result = pkcs1_mgf1(hProv, pbPaddedDb, dwDbLen, dwSeedLen, &blobSeedMask);
2107 if (!result) goto done;
2108 for (i = 0; i < dwSeedLen; i++) pbUnpaddedSeed[i] = pbPaddedSeed[i] ^ blobSeedMask.pbData[i];
2109
2110 /* Get unpadded DB */
2111 result = pkcs1_mgf1(hProv, pbUnpaddedSeed, dwSeedLen, dwDbLen, &blobDbMask);
2112 if (!result) goto done;
2113 for (i = 0; i < dwDbLen; i++) pbUnpaddedDb[i] = pbPaddedDb[i] ^ blobDbMask.pbData[i];
2114
2115 /* Compare hash in DB */
2116 result = memcmp(pbUnpaddedDb, pbHashValue, dwHashLen);
2117
2118 /* Get count of zero paddings(PS) */
2119 dwZeroCount = 0;
2120 while (dwHashLen + dwZeroCount + 1 <= dwDbLen && pbUnpaddedDb[dwHashLen + dwZeroCount] == 0) dwZeroCount++;
2121 dwMsgCount = dwDbLen - dwHashLen - dwZeroCount - 1;
2122
2123 if (dwHashLen + dwZeroCount + 1 > dwDbLen || abData[0] || result || pbUnpaddedDb[dwHashLen + dwZeroCount] != 1
2124 || *dwBufferLen < dwMsgCount)
2125 {
2127 goto done;
2128 }
2129
2130 *dwBufferLen = dwMsgCount;
2131 memcpy(abBuffer, pbUnpaddedDb + dwHashLen + dwZeroCount + 1, dwMsgCount);
2132 ret = TRUE;
2133done:
2135 free(pbHashValue);
2136 free(pbBuffer);
2137 free_data_blob(&blobDbMask);
2138 free_data_blob(&blobSeedMask);
2139 return ret;
2140}
2141
2142/******************************************************************************
2143 * unpad_data [Internal]
2144 *
2145 * Remove the padding from RSA decrypted data according to padding format
2146 *
2147 * PARAMS
2148 * hProv [I] Cryptographic provider handle
2149 * abData [I] The padded data
2150 * dwDataLen [I] Length of the padded data
2151 * abBuffer [O] Data without padding will be stored here
2152 * dwBufferLen [I/O] I: Length of the buffer, O: Length of unpadded data
2153 * dwFlags [I] 0 or CRYPT_OAEP
2154 *
2155 * RETURNS
2156 * Success: TRUE
2157 * Failure: FALSE
2158 */
2159static BOOL unpad_data(HCRYPTPROV hProv, const BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, DWORD *dwBufferLen,
2160 DWORD dwFlags)
2161{
2162 if (dwFlags == CRYPT_OAEP)
2163 return unpad_data_oaep(hProv, abData, dwDataLen, abBuffer, dwBufferLen, dwFlags);
2164 else
2165 return unpad_data_pkcs1(abData, dwDataLen, abBuffer, dwBufferLen, dwFlags);
2166}
2167
2168/******************************************************************************
2169 * CPAcquireContext (RSAENH.@)
2170 *
2171 * Acquire a handle to the key container specified by pszContainer
2172 *
2173 * PARAMS
2174 * phProv [O] Pointer to the location the acquired handle will be written to.
2175 * pszContainer [I] Name of the desired key container. See Notes
2176 * dwFlags [I] Flags. See Notes.
2177 * pVTable [I] Pointer to a PVTableProvStruct containing callbacks.
2178 *
2179 * RETURNS
2180 * Success: TRUE
2181 * Failure: FALSE
2182 *
2183 * NOTES
2184 * If pszContainer is NULL or points to a zero length string the user's login
2185 * name will be used as the key container name.
2186 *
2187 * If the CRYPT_NEW_KEYSET flag is set in dwFlags a new keyset will be created.
2188 * If a keyset with the given name already exists, the function fails and sets
2189 * last error to NTE_EXISTS. If CRYPT_NEW_KEYSET is not set and the specified
2190 * key container does not exist, function fails and sets last error to
2191 * NTE_BAD_KEYSET.
2192 */
2195{
2196 CHAR szKeyContainerName[MAX_PATH];
2197
2198 TRACE("(phProv=%p, pszContainer=%s, dwFlags=%08lx, pVTable=%p)\n", phProv,
2199 debugstr_a(pszContainer), dwFlags, pVTable);
2200
2201 if (pszContainer && *pszContainer)
2202 {
2203 lstrcpynA(szKeyContainerName, pszContainer, MAX_PATH);
2204 }
2205 else
2206 {
2207 DWORD dwLen = sizeof(szKeyContainerName);
2208 if (!GetUserNameA(szKeyContainerName, &dwLen)) return FALSE;
2209 }
2210
2212 {
2213 case 0:
2214 *phProv = read_key_container(szKeyContainerName, dwFlags, pVTable);
2215 break;
2216
2217 case CRYPT_DELETEKEYSET:
2218 return delete_container_key(szKeyContainerName, dwFlags);
2219
2220 case CRYPT_NEWKEYSET:
2221 *phProv = read_key_container(szKeyContainerName, dwFlags, pVTable);
2222 if (*phProv != (HCRYPTPROV)INVALID_HANDLE_VALUE)
2223 {
2225 TRACE("Can't create new keyset, already exists\n");
2227 return FALSE;
2228 }
2229 *phProv = new_key_container(szKeyContainerName, dwFlags, pVTable);
2230 break;
2231
2234 if (pszContainer && *pszContainer) {
2235 TRACE("pszContainer should be empty\n");
2237 return FALSE;
2238 }
2239 *phProv = new_key_container("", dwFlags, pVTable);
2240 break;
2241
2242 default:
2245 return FALSE;
2246 }
2247
2248 if (*phProv != (HCRYPTPROV)INVALID_HANDLE_VALUE) {
2250 return TRUE;
2251 } else {
2252 return FALSE;
2253 }
2254}
2255
2256/******************************************************************************
2257 * CPCreateHash (RSAENH.@)
2258 *
2259 * CPCreateHash creates and initializes a new hash object.
2260 *
2261 * PARAMS
2262 * hProv [I] Handle to the key container to which the new hash will belong.
2263 * Algid [I] Identifies the hash algorithm, which will be used for the hash.
2264 * hKey [I] Handle to a session key applied for keyed hashes.
2265 * dwFlags [I] Currently no flags defined. Must be zero.
2266 * phHash [O] Points to the location where a handle to the new hash will be stored.
2267 *
2268 * RETURNS
2269 * Success: TRUE
2270 * Failure: FALSE
2271 *
2272 * NOTES
2273 * hKey is a handle to a session key applied in keyed hashes like MAC and HMAC.
2274 * If a normal hash object is to be created (like e.g. MD2 or SHA1) hKey must be zero.
2275 */
2277 HCRYPTHASH *phHash)
2278{
2279 CRYPTKEY *pCryptKey = NULL;
2280 CRYPTHASH *pCryptHash;
2281 const PROV_ENUMALGS_EX *peaAlgidInfo;
2282
2283 TRACE("(hProv=%08Ix, Algid=%08x, hKey=%08Ix, dwFlags=%08lx, phHash=%p)\n", hProv, Algid, hKey,
2284 dwFlags, phHash);
2285
2286 peaAlgidInfo = get_algid_info(hProv, Algid);
2287 if (!peaAlgidInfo) return FALSE;
2288
2289 if (dwFlags)
2290 {
2292 return FALSE;
2293 }
2294
2295 if (Algid == CALG_MAC || Algid == CALG_HMAC || Algid == CALG_SCHANNEL_MASTER_HASH ||
2296 Algid == CALG_TLS1PRF)
2297 {
2298 if (!lookup_handle(&handle_table, hKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pCryptKey)) {
2300 return FALSE;
2301 }
2302
2303 if ((Algid == CALG_MAC) && (GET_ALG_TYPE(pCryptKey->aiAlgid) != ALG_TYPE_BLOCK)) {
2305 return FALSE;
2306 }
2307
2308 if ((Algid == CALG_SCHANNEL_MASTER_HASH || Algid == CALG_TLS1PRF) &&
2309 (pCryptKey->aiAlgid != CALG_TLS1_MASTER))
2310 {
2312 return FALSE;
2313 }
2314 if (Algid == CALG_SCHANNEL_MASTER_HASH &&
2315 ((!pCryptKey->siSChannelInfo.blobClientRandom.cbData) ||
2316 (!pCryptKey->siSChannelInfo.blobServerRandom.cbData)))
2317 {
2319 return FALSE;
2320 }
2321
2322 if ((Algid == CALG_TLS1PRF) && (pCryptKey->dwState != RSAENH_KEYSTATE_MASTERKEY)) {
2324 return FALSE;
2325 }
2326 }
2327
2329 destroy_hash, (OBJECTHDR**)&pCryptHash);
2330 if (!pCryptHash) return FALSE;
2331
2332 pCryptHash->aiAlgid = Algid;
2333 pCryptHash->hKey = hKey;
2334 if (Algid == CALG_MAC)
2335 {
2336 pCryptHash->key_alg_id = pCryptKey->aiAlgid;
2337 setup_key(pCryptKey);
2338 duplicate_key_impl(pCryptKey->aiAlgid, &pCryptKey->context, &pCryptHash->key_context);
2339 memcpy(pCryptHash->abChainVector, pCryptKey->abChainVector, sizeof(pCryptHash->abChainVector));
2340 }
2341 pCryptHash->hProv = hProv;
2342 pCryptHash->dwState = RSAENH_HASHSTATE_HASHING;
2343 pCryptHash->pHMACInfo = NULL;
2344 memset(&pCryptHash->hash, 0, sizeof(pCryptHash->hash));
2345 pCryptHash->dwHashSize = peaAlgidInfo->dwDefaultLen >> 3;
2346 pCryptHash->buffered_hash_bytes = 0;
2347 init_data_blob(&pCryptHash->tpPRFParams.blobLabel);
2348 init_data_blob(&pCryptHash->tpPRFParams.blobSeed);
2349
2350 if (Algid == CALG_SCHANNEL_MASTER_HASH) {
2351 static const char keyex[] = "key expansion";
2352 BYTE key_expansion[sizeof keyex];
2353 CRYPT_DATA_BLOB blobRandom, blobKeyExpansion = { 13, key_expansion };
2354
2355 memcpy( key_expansion, keyex, sizeof keyex );
2356
2357 if (pCryptKey->dwState != RSAENH_KEYSTATE_MASTERKEY) {
2358 static const char msec[] = "master secret";
2359 BYTE master_secret[sizeof msec];
2360 CRYPT_DATA_BLOB blobLabel = { 13, master_secret };
2361 BYTE abKeyValue[48];
2362
2363 memcpy( master_secret, msec, sizeof msec );
2364
2365 /* See RFC 2246, chapter 8.1 */
2366 if (!concat_data_blobs(&blobRandom,
2367 &pCryptKey->siSChannelInfo.blobClientRandom,
2368 &pCryptKey->siSChannelInfo.blobServerRandom))
2369 {
2370 return FALSE;
2371 }
2372 tls1_prf(hProv, hKey, &blobLabel, &blobRandom, abKeyValue, 48);
2373 pCryptKey->dwState = RSAENH_KEYSTATE_MASTERKEY;
2374 memcpy(pCryptKey->abKeyValue, abKeyValue, 48);
2375 free_data_blob(&blobRandom);
2376 }
2377
2378 /* See RFC 2246, chapter 6.3 */
2379 if (!concat_data_blobs(&blobRandom,
2380 &pCryptKey->siSChannelInfo.blobServerRandom,
2381 &pCryptKey->siSChannelInfo.blobClientRandom))
2382 {
2383 return FALSE;
2384 }
2385 tls1_prf(hProv, hKey, &blobKeyExpansion, &blobRandom, pCryptHash->abHashValue,
2387 free_data_blob(&blobRandom);
2388 }
2389
2390 return init_hash(pCryptHash);
2391}
2392
2393/******************************************************************************
2394 * CPDestroyHash (RSAENH.@)
2395 *
2396 * Releases the handle to a hash object. The object is destroyed if its reference
2397 * count reaches zero.
2398 *
2399 * PARAMS
2400 * hProv [I] Handle to the key container to which the hash object belongs.
2401 * hHash [I] Handle to the hash object to be released.
2402 *
2403 * RETURNS
2404 * Success: TRUE
2405 * Failure: FALSE
2406 */
2408{
2409 TRACE("(hProv=%08Ix, hHash=%08Ix)\n", hProv, hHash);
2410
2412 {
2414 return FALSE;
2415 }
2416
2418 {
2420 return FALSE;
2421 }
2422
2423 return TRUE;
2424}
2425
2426/******************************************************************************
2427 * CPDestroyKey (RSAENH.@)
2428 *
2429 * Releases the handle to a key object. The object is destroyed if its reference
2430 * count reaches zero.
2431 *
2432 * PARAMS
2433 * hProv [I] Handle to the key container to which the key object belongs.
2434 * hKey [I] Handle to the key object to be released.
2435 *
2436 * RETURNS
2437 * Success: TRUE
2438 * Failure: FALSE
2439 */
2441{
2442 TRACE("(hProv=%08Ix, hKey=%08Ix)\n", hProv, hKey);
2443
2445 {
2447 return FALSE;
2448 }
2449
2451 {
2453 return FALSE;
2454 }
2455
2456 return TRUE;
2457}
2458
2459/******************************************************************************
2460 * CPDuplicateHash (RSAENH.@)
2461 *
2462 * Clones a hash object including its current state.
2463 *
2464 * PARAMS
2465 * hUID [I] Handle to the key container the hash belongs to.
2466 * hHash [I] Handle to the hash object to be cloned.
2467 * pdwReserved [I] Reserved. Must be NULL.
2468 * dwFlags [I] No flags are currently defined. Must be 0.
2469 * phHash [O] Handle to the cloned hash object.
2470 *
2471 * RETURNS
2472 * Success: TRUE.
2473 * Failure: FALSE.
2474 */
2476 DWORD dwFlags, HCRYPTHASH *phHash)
2477{
2478 CRYPTHASH *pSrcHash, *pDestHash;
2479
2480 TRACE("(hUID=%08Ix, hHash=%08Ix, pdwReserved=%p, dwFlags=%08lx, phHash=%p)\n", hUID, hHash,
2481 pdwReserved, dwFlags, phHash);
2482
2484 {
2486 return FALSE;
2487 }
2488
2489 if (!lookup_handle(&handle_table, hHash, RSAENH_MAGIC_HASH, (OBJECTHDR**)&pSrcHash))
2490 {
2492 return FALSE;
2493 }
2494
2495 if (!phHash || pdwReserved || dwFlags)
2496 {
2498 return FALSE;
2499 }
2500
2502 destroy_hash, (OBJECTHDR**)&pDestHash);
2503 if (*phHash != (HCRYPTHASH)INVALID_HANDLE_VALUE)
2504 {
2505 *pDestHash = *pSrcHash;
2506 copy_hmac_info(&pDestHash->pHMACInfo, pSrcHash->pHMACInfo, 0);
2507 copy_data_blob(&pDestHash->tpPRFParams.blobLabel, &pSrcHash->tpPRFParams.blobLabel);
2508 copy_data_blob(&pDestHash->tpPRFParams.blobSeed, &pSrcHash->tpPRFParams.blobSeed);
2509 }
2510
2511 return *phHash != (HCRYPTHASH)INVALID_HANDLE_VALUE;
2512}
2513
2514/******************************************************************************
2515 * CPDuplicateKey (RSAENH.@)
2516 *
2517 * Clones a key object including its current state.
2518 *
2519 * PARAMS
2520 * hUID [I] Handle to the key container the hash belongs to.
2521 * hKey [I] Handle to the key object to be cloned.
2522 * pdwReserved [I] Reserved. Must be NULL.
2523 * dwFlags [I] No flags are currently defined. Must be 0.
2524 * phHash [O] Handle to the cloned key object.
2525 *
2526 * RETURNS
2527 * Success: TRUE.
2528 * Failure: FALSE.
2529 */
2531 DWORD dwFlags, HCRYPTKEY *phKey)
2532{
2533 CRYPTKEY *pSrcKey, *pDestKey;
2534
2535 TRACE("(hUID=%08Ix, hKey=%08Ix, pdwReserved=%p, dwFlags=%08lx, phKey=%p)\n", hUID, hKey,
2536 pdwReserved, dwFlags, phKey);
2537
2539 {
2541 return FALSE;
2542 }
2543
2545 {
2547 return FALSE;
2548 }
2549
2550 if (!phKey || pdwReserved || dwFlags)
2551 {
2553 return FALSE;
2554 }
2555
2557 (OBJECTHDR**)&pDestKey);
2558 if (*phKey != (HCRYPTKEY)INVALID_HANDLE_VALUE)
2559 {
2560 *pDestKey = *pSrcKey;
2565 duplicate_key_impl(pSrcKey->aiAlgid, &pSrcKey->context, &pDestKey->context);
2566 return TRUE;
2567 }
2568 else
2569 {
2570 return FALSE;
2571 }
2572}
2573
2574/******************************************************************************
2575 * CPEncrypt (RSAENH.@)
2576 *
2577 * Encrypt data.
2578 *
2579 * PARAMS
2580 * hProv [I] The key container hKey and hHash belong to.
2581 * hKey [I] The key used to encrypt the data.
2582 * hHash [I] An optional hash object for parallel hashing. See notes.
2583 * Final [I] Indicates if this is the last block of data to encrypt.
2584 * dwFlags [I] Must be zero or CRYPT_OAEP
2585 * pbData [I/O] Pointer to the data to encrypt. Encrypted data will also be stored there.
2586 * pdwDataLen [I/O] I: Length of data to encrypt, O: Length of encrypted data.
2587 * dwBufLen [I] Size of the buffer at pbData.
2588 *
2589 * RETURNS
2590 * Success: TRUE.
2591 * Failure: FALSE.
2592 *
2593 * NOTES
2594 * If a hash object handle is provided in hHash, it will be updated with the plaintext.
2595 * This is useful for message signatures.
2596 *
2597 * This function uses the standard WINAPI protocol for querying data of dynamic length.
2598 */
2600 BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen)
2601{
2602 CRYPTKEY *pCryptKey;
2603
2604 TRACE("(hProv=%08Ix, hKey=%08Ix, hHash=%08Ix, Final=%d, dwFlags=%08lx, pbData=%p, "
2605 "pdwDataLen=%p, dwBufLen=%ld)\n", hProv, hKey, hHash, Final, dwFlags, pbData, pdwDataLen,
2606 dwBufLen);
2607
2609 {
2611 return FALSE;
2612 }
2613
2614 if (dwFlags != 0 && dwFlags != CRYPT_OAEP)
2615 {
2617 return FALSE;
2618 }
2619
2621 {
2623 return FALSE;
2624 }
2625
2626 if (pCryptKey->aiAlgid == CALG_RC2)
2627 {
2628 const PROV_ENUMALGS_EX *info;
2629
2630 if (!(info = get_algid_info(hProv, pCryptKey->aiAlgid)))
2631 {
2632 FIXME("Can't get algid info.\n");
2634 return FALSE;
2635 }
2636 if (pCryptKey->dwKeyLen > info->dwMaxLen / 8)
2637 {
2639 return FALSE;
2640 }
2641 }
2642
2643 if (pCryptKey->dwState == RSAENH_KEYSTATE_IDLE)
2645
2646 if (pCryptKey->dwState != RSAENH_KEYSTATE_ENCRYPTING)
2647 {
2649 return FALSE;
2650 }
2651
2653 if (!RSAENH_CPHashData(hProv, hHash, pbData, *pdwDataLen, 0)) return FALSE;
2654 }
2655
2656 if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_BLOCK) {
2657 if (!block_encrypt(pCryptKey, pbData, pdwDataLen, dwBufLen, Final,
2658 &pCryptKey->context, pCryptKey->abChainVector))
2659 return FALSE;
2660 if (!pbData) return TRUE;
2661 } else if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_STREAM) {
2662 if (pbData == NULL) {
2663 *pdwDataLen = dwBufLen;
2664 return TRUE;
2665 }
2666 encrypt_stream_impl(pCryptKey->aiAlgid, &pCryptKey->context, pbData, *pdwDataLen);
2667 } else if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_RSA) {
2668 if (pCryptKey->aiAlgid == CALG_RSA_SIGN) {
2670 return FALSE;
2671 }
2672 if (!pbData) {
2673 *pdwDataLen = pCryptKey->dwBlockLen;
2674 return TRUE;
2675 }
2676 if (dwBufLen < pCryptKey->dwBlockLen) {
2678 return FALSE;
2679 }
2680 if (!pad_data(hProv, pbData, *pdwDataLen, pbData, pCryptKey->dwBlockLen, dwFlags)) return FALSE;
2681 encrypt_block_impl(pCryptKey->aiAlgid, &pCryptKey->context, pbData, pbData);
2682 *pdwDataLen = pCryptKey->dwBlockLen;
2683 Final = TRUE;
2684 } else {
2686 return FALSE;
2687 }
2688
2689 if (Final) setup_key(pCryptKey);
2690
2691 return TRUE;
2692}
2693
2694/******************************************************************************
2695 * CPDecrypt (RSAENH.@)
2696 *
2697 * Decrypt data.
2698 *
2699 * PARAMS
2700 * hProv [I] The key container hKey and hHash belong to.
2701 * hKey [I] The key used to decrypt the data.
2702 * hHash [I] An optional hash object for parallel hashing. See notes.
2703 * Final [I] Indicates if this is the last block of data to decrypt.
2704 * dwFlags [I] Must be zero or CRYPT_OAEP
2705 * pbData [I/O] Pointer to the data to decrypt. Plaintext will also be stored there.
2706 * pdwDataLen [I/O] I: Length of ciphertext, O: Length of plaintext.
2707 *
2708 * RETURNS
2709 * Success: TRUE.
2710 * Failure: FALSE.
2711 *
2712 * NOTES
2713 * If a hash object handle is provided in hHash, it will be updated with the plaintext.
2714 * This is useful for message signatures.
2715 *
2716 * This function uses the standard WINAPI protocol for querying data of dynamic length.
2717 */
2719 DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen)
2720{
2721 CRYPTKEY *pCryptKey;
2723 DWORD i, j, k;
2724 DWORD dwMax;
2725
2726 TRACE("(hProv=%08Ix, hKey=%08Ix, hHash=%08Ix, Final=%d, dwFlags=%08lx, pbData=%p, "
2727 "pdwDataLen=%p)\n", hProv, hKey, hHash, Final, dwFlags, pbData, pdwDataLen);
2728
2730 {
2732 return FALSE;
2733 }
2734
2735 if (dwFlags != 0 && dwFlags != CRYPT_OAEP)
2736 {
2738 return FALSE;
2739 }
2740
2742 {
2744 return FALSE;
2745 }
2746
2747 if (pCryptKey->dwState == RSAENH_KEYSTATE_IDLE)
2749
2750 if (pCryptKey->dwState != RSAENH_KEYSTATE_ENCRYPTING)
2751 {
2753 return FALSE;
2754 }
2755
2756 if (Final && !*pdwDataLen)
2757 {
2759 return FALSE;
2760 }
2761
2762 dwMax=*pdwDataLen;
2763
2764 if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_BLOCK) {
2765 for (i=0, in=pbData; i<*pdwDataLen; i+=pCryptKey->dwBlockLen, in+=pCryptKey->dwBlockLen) {
2766 switch (pCryptKey->dwMode) {
2767 case CRYPT_MODE_ECB:
2768 decrypt_block_impl(pCryptKey->aiAlgid, &pCryptKey->context, in, out);
2769 break;
2770
2771 case CRYPT_MODE_CBC:
2772 decrypt_block_impl(pCryptKey->aiAlgid, &pCryptKey->context, in, out);
2773 for (j=0; j<pCryptKey->dwBlockLen; j++) out[j] ^= pCryptKey->abChainVector[j];
2774 memcpy(pCryptKey->abChainVector, in, pCryptKey->dwBlockLen);
2775 break;
2776
2777 case CRYPT_MODE_CFB:
2778 for (j=0; j<pCryptKey->dwBlockLen; j++) {
2779 encrypt_block_impl(pCryptKey->aiAlgid, &pCryptKey->context, pCryptKey->abChainVector, o);
2780 out[j] = in[j] ^ o[0];
2781 for (k=0; k<pCryptKey->dwBlockLen-1; k++)
2782 pCryptKey->abChainVector[k] = pCryptKey->abChainVector[k+1];
2783 pCryptKey->abChainVector[k] = in[j];
2784 }
2785 break;
2786
2787 default:
2789 return FALSE;
2790 }
2791 memcpy(in, out, pCryptKey->dwBlockLen);
2792 }
2793 if (Final) {
2794 if (pbData[*pdwDataLen-1] &&
2795 pbData[*pdwDataLen-1] <= pCryptKey->dwBlockLen &&
2796 pbData[*pdwDataLen-1] <= *pdwDataLen) {
2797 BOOL padOkay = TRUE;
2798
2799 /* check that every pad byte has the same value */
2800 for (i = 1; padOkay && i < pbData[*pdwDataLen-1]; i++)
2801 if (pbData[*pdwDataLen - i - 1] != pbData[*pdwDataLen - 1])
2802 padOkay = FALSE;
2803 if (padOkay)
2804 *pdwDataLen -= pbData[*pdwDataLen-1];
2805 else {
2807 setup_key(pCryptKey);
2808 return FALSE;
2809 }
2810 }
2811 else {
2813 setup_key(pCryptKey);
2814 return FALSE;
2815 }
2816 }
2817
2818 } else if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_STREAM) {
2819 encrypt_stream_impl(pCryptKey->aiAlgid, &pCryptKey->context, pbData, *pdwDataLen);
2820 } else if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_RSA) {
2821 if (pCryptKey->aiAlgid == CALG_RSA_SIGN) {
2823 return FALSE;
2824 }
2825 decrypt_block_impl(pCryptKey->aiAlgid, &pCryptKey->context, pbData, pbData);
2826 if (!unpad_data(hProv, pbData, pCryptKey->dwBlockLen, pbData, pdwDataLen, dwFlags)) return FALSE;
2827 Final = TRUE;
2828 } else {
2830 return FALSE;
2831 }
2832
2833 if (Final) setup_key(pCryptKey);
2834
2836 if (*pdwDataLen>dwMax ||
2837 !RSAENH_CPHashData(hProv, hHash, pbData, *pdwDataLen, 0)) return FALSE;
2838 }
2839
2840 return TRUE;
2841}
2842
2843static BOOL crypt_export_simple(CRYPTKEY *pCryptKey, CRYPTKEY *pPubKey,
2844 DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen)
2845{
2846 BLOBHEADER *pBlobHeader = (BLOBHEADER*)pbData;
2847 ALG_ID *pAlgid = (ALG_ID*)(pBlobHeader+1);
2848 DWORD dwDataLen;
2849
2851 SetLastError(NTE_BAD_KEY); /* FIXME: error code? */
2852 return FALSE;
2853 }
2854
2855 dwDataLen = sizeof(BLOBHEADER) + sizeof(ALG_ID) + pPubKey->dwBlockLen;
2856 if (pbData) {
2857 if (*pdwDataLen < dwDataLen) {
2859 *pdwDataLen = dwDataLen;
2860 return FALSE;
2861 }
2862
2863 pBlobHeader->bType = SIMPLEBLOB;
2864 pBlobHeader->bVersion = CUR_BLOB_VERSION;
2865 pBlobHeader->reserved = 0;
2866 pBlobHeader->aiKeyAlg = pCryptKey->aiAlgid;
2867
2868 *pAlgid = pPubKey->aiAlgid;
2869
2870 if (!pad_data(pCryptKey->hProv, pCryptKey->abKeyValue, pCryptKey->dwKeyLen, (BYTE*)(pAlgid+1),
2871 pPubKey->dwBlockLen, dwFlags))
2872 {
2873 return FALSE;
2874 }
2875
2876 encrypt_block_impl(pPubKey->aiAlgid, &pPubKey->context, (BYTE *)(pAlgid + 1), (BYTE *)(pAlgid + 1));
2877 }
2878 *pdwDataLen = dwDataLen;
2879 return TRUE;
2880}
2881
2883 DWORD *pdwDataLen)
2884{
2885 BLOBHEADER *pBlobHeader = (BLOBHEADER*)pbData;
2886 RSAPUBKEY *pRSAPubKey = (RSAPUBKEY*)(pBlobHeader+1);
2887 DWORD dwDataLen;
2888
2889 if ((pCryptKey->aiAlgid != CALG_RSA_KEYX) && (pCryptKey->aiAlgid != CALG_RSA_SIGN)) {
2891 return FALSE;
2892 }
2893
2894 dwDataLen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + pCryptKey->dwKeyLen;
2895 if (pbData) {
2896 if (*pdwDataLen < dwDataLen) {
2898 *pdwDataLen = dwDataLen;
2899 return FALSE;
2900 }
2901
2902 pBlobHeader->bType = PUBLICKEYBLOB;
2903 pBlobHeader->bVersion = CUR_BLOB_VERSION;
2904 pBlobHeader->reserved = 0;
2905 pBlobHeader->aiKeyAlg = pCryptKey->aiAlgid;
2906
2907 pRSAPubKey->magic = RSAENH_MAGIC_RSA1;
2908 pRSAPubKey->bitlen = pCryptKey->dwKeyLen << 3;
2909
2910 export_public_key_impl(&pCryptKey->context, (BYTE *)(pRSAPubKey + 1), &pRSAPubKey->pubexp);
2911 }
2912 *pdwDataLen = dwDataLen;
2913 return TRUE;
2914}
2915
2917 BYTE *pbData, DWORD *pdwDataLen)
2918{
2919 BLOBHEADER *pBlobHeader = (BLOBHEADER*)pbData;
2920 RSAPUBKEY *pRSAPubKey = (RSAPUBKEY*)(pBlobHeader+1);
2921 DWORD dwDataLen;
2922
2923 if ((pCryptKey->aiAlgid != CALG_RSA_KEYX) && (pCryptKey->aiAlgid != CALG_RSA_SIGN)) {
2925 return FALSE;
2926 }
2927 if (!force && !(pCryptKey->dwPermissions & CRYPT_EXPORT))
2928 {
2930 return FALSE;
2931 }
2932
2933 dwDataLen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2934 2 * pCryptKey->dwKeyLen + 5 * ((pCryptKey->dwKeyLen + 1) >> 1);
2935 if (pbData) {
2936 if (*pdwDataLen < dwDataLen) {
2938 *pdwDataLen = dwDataLen;
2939 return FALSE;
2940 }
2941
2942 pBlobHeader->bType = PRIVATEKEYBLOB;
2943 pBlobHeader->bVersion = CUR_BLOB_VERSION;
2944 pBlobHeader->reserved = 0;
2945 pBlobHeader->aiKeyAlg = pCryptKey->aiAlgid;
2946
2947 pRSAPubKey->magic = RSAENH_MAGIC_RSA2;
2948 pRSAPubKey->bitlen = pCryptKey->dwKeyLen << 3;
2949 export_private_key_impl(&pCryptKey->context, (BYTE *)(pRSAPubKey + 1), &pRSAPubKey->pubexp);
2950 }
2951 *pdwDataLen = dwDataLen;
2952 return TRUE;
2953}
2954
2956 DWORD *pdwDataLen)
2957{
2958 BLOBHEADER *pBlobHeader = (BLOBHEADER*)pbData;
2959 DWORD *pKeyLen = (DWORD*)(pBlobHeader+1);
2960 BYTE *pbKey = (BYTE*)(pKeyLen+1);
2961 DWORD dwDataLen;
2962
2963 dwDataLen = sizeof(BLOBHEADER) + sizeof(DWORD) + pCryptKey->dwKeyLen;
2964 if (pbData) {
2965 if (*pdwDataLen < dwDataLen) {
2967 *pdwDataLen = dwDataLen;
2968 return FALSE;
2969 }
2970
2971 pBlobHeader->bType = PLAINTEXTKEYBLOB;
2972 pBlobHeader->bVersion = CUR_BLOB_VERSION;
2973 pBlobHeader->reserved = 0;
2974 pBlobHeader->aiKeyAlg = pCryptKey->aiAlgid;
2975
2976 *pKeyLen = pCryptKey->dwKeyLen;
2977 memcpy(pbKey, pCryptKey->abKeyValue, pCryptKey->dwKeyLen);
2978 }
2979 *pdwDataLen = dwDataLen;
2980 return TRUE;
2981}
2982/******************************************************************************
2983 * crypt_export_key [Internal]
2984 *
2985 * Export a key into a binary large object (BLOB). Called by CPExportKey and
2986 * by store_key_pair.
2987 *
2988 * PARAMS
2989 * pCryptKey [I] Key to be exported.
2990 * hPubKey [I] Key used to encrypt sensitive BLOB data.
2991 * dwBlobType [I] SIMPLEBLOB, PUBLICKEYBLOB or PRIVATEKEYBLOB.
2992 * dwFlags [I] Currently none defined.
2993 * force [I] If TRUE, the key is written no matter what the key's
2994 * permissions are. Otherwise the key's permissions are
2995 * checked before exporting.
2996 * pbData [O] Pointer to a buffer where the BLOB will be written to.
2997 * pdwDataLen [I/O] I: Size of buffer at pbData, O: Size of BLOB
2998 *
2999 * RETURNS
3000 * Success: TRUE.
3001 * Failure: FALSE.
3002 */
3003static BOOL crypt_export_key(CRYPTKEY *pCryptKey, HCRYPTKEY hPubKey,
3004 DWORD dwBlobType, DWORD dwFlags, BOOL force,
3005 BYTE *pbData, DWORD *pdwDataLen)
3006{
3007 CRYPTKEY *pPubKey;
3008
3010 if (pCryptKey->aiAlgid != CALG_SSL2_MASTER) {
3012 return FALSE;
3013 }
3014 }
3015
3016 switch ((BYTE)dwBlobType)
3017 {
3018 case SIMPLEBLOB:
3019 if (!lookup_handle(&handle_table, hPubKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pPubKey)){
3020 SetLastError(NTE_BAD_PUBLIC_KEY); /* FIXME: error_code? */
3021 return FALSE;
3022 }
3023 return crypt_export_simple(pCryptKey, pPubKey, dwFlags, pbData,
3024 pdwDataLen);
3025
3026 case PUBLICKEYBLOB:
3028 SetLastError(NTE_BAD_KEY); /* FIXME: error code? */
3029 return FALSE;
3030 }
3031
3032 return crypt_export_public_key(pCryptKey, pbData, pdwDataLen);
3033
3034 case PRIVATEKEYBLOB:
3035 return crypt_export_private_key(pCryptKey, force, pbData, pdwDataLen);
3036
3037 case PLAINTEXTKEYBLOB:
3038 return crypt_export_plaintext_key(pCryptKey, pbData, pdwDataLen);
3039
3040 default:
3041 SetLastError(NTE_BAD_TYPE); /* FIXME: error code? */
3042 return FALSE;
3043 }
3044}
3045
3046/******************************************************************************
3047 * CPExportKey (RSAENH.@)
3048 *
3049 * Export a key into a binary large object (BLOB).
3050 *
3051 * PARAMS
3052 * hProv [I] Key container from which a key is to be exported.
3053 * hKey [I] Key to be exported.
3054 * hPubKey [I] Key used to encrypt sensitive BLOB data.
3055 * dwBlobType [I] SIMPLEBLOB, PUBLICKEYBLOB or PRIVATEKEYBLOB.
3056 * dwFlags [I] Currently none defined.
3057 * pbData [O] Pointer to a buffer where the BLOB will be written to.
3058 * pdwDataLen [I/O] I: Size of buffer at pbData, O: Size of BLOB
3059 *
3060 * RETURNS
3061 * Success: TRUE.
3062 * Failure: FALSE.
3063 */
3065 DWORD dwBlobType, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen)
3066{
3067 CRYPTKEY *pCryptKey;
3068
3069 TRACE("(hProv=%08Ix, hKey=%08Ix, hPubKey=%08Ix, dwBlobType=%08lx, dwFlags=%08lx, pbData=%p,"
3070 "pdwDataLen=%p)\n", hProv, hKey, hPubKey, dwBlobType, dwFlags, pbData, pdwDataLen);
3071
3073 {
3075 return FALSE;
3076 }
3077
3079 {
3081 return FALSE;
3082 }
3083
3084 return crypt_export_key(pCryptKey, hPubKey, dwBlobType, dwFlags, FALSE,
3085 pbData, pdwDataLen);
3086}
3087
3088/******************************************************************************
3089 * release_and_install_key [Internal]
3090 *
3091 * Release an existing key, if present, and replaces it with a new one.
3092 *
3093 * PARAMS
3094 * hProv [I] Key container into which the key is to be imported.
3095 * src [I] Key which will replace *dest
3096 * dest [I] Points to key to be released and replaced with src
3097 * fStoreKey [I] If TRUE, the newly installed key is stored to the registry.
3098 */
3100 HCRYPTKEY *dest, DWORD fStoreKey)
3101{
3104 if (fStoreKey)
3105 {
3106 KEYCONTAINER *pKeyContainer;
3107
3108 if ((pKeyContainer = get_key_container(hProv)))
3109 {
3110 store_key_container_keys(pKeyContainer);
3111 store_key_container_permissions(pKeyContainer);
3112 }
3113 }
3114}
3115
3116/******************************************************************************
3117 * import_private_key [Internal]
3118 *
3119 * Import a BLOB'ed private key into a key container.
3120 *
3121 * PARAMS
3122 * hProv [I] Key container into which the private key is to be imported.
3123 * pbData [I] Pointer to a buffer which holds the private key BLOB.
3124 * dwDataLen [I] Length of data in buffer at pbData.
3125 * dwFlags [I] One of:
3126 * CRYPT_EXPORTABLE: the imported key is marked exportable
3127 * fStoreKey [I] If TRUE, the imported key is stored to the registry.
3128 * phKey [O] Handle to the imported key.
3129 *
3130 *
3131 * NOTES
3132 * Assumes the caller has already checked the BLOBHEADER at pbData to ensure
3133 * it's a PRIVATEKEYBLOB.
3134 *
3135 * RETURNS
3136 * Success: TRUE.
3137 * Failure: FALSE.
3138 */
3140 DWORD dwFlags, BOOL fStoreKey, HCRYPTKEY *phKey)
3141{
3142 KEYCONTAINER *pKeyContainer;
3143 CRYPTKEY *pCryptKey;
3144 const BLOBHEADER *pBlobHeader = (const BLOBHEADER*)pbData;
3145 const RSAPUBKEY *pRSAPubKey = (const RSAPUBKEY*)(pBlobHeader+1);
3146 BOOL ret;
3147
3149 {
3150 FIXME("unimplemented for CRYPT_IPSEC_HMAC_KEY\n");
3152 return FALSE;
3153 }
3154 if (!(pKeyContainer = get_key_container(hProv)))
3155 return FALSE;
3156
3157 if ((dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY)))
3158 {
3159 ERR("datalen %ld not long enough for a BLOBHEADER + RSAPUBKEY\n",
3160 dwDataLen);
3162 return FALSE;
3163 }
3164 if (pRSAPubKey->magic != RSAENH_MAGIC_RSA2)
3165 {
3166 ERR("unexpected magic %08lx\n", pRSAPubKey->magic);
3168 return FALSE;
3169 }
3170 if ((dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
3171 (pRSAPubKey->bitlen >> 3) + (5 * ((pRSAPubKey->bitlen+8)>>4))))
3172 {
3173 DWORD expectedLen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
3174 (pRSAPubKey->bitlen >> 3) + (5 * ((pRSAPubKey->bitlen+8)>>4));
3175
3176 ERR("blob too short for pub key: expect %ld, got %ld\n",
3177 expectedLen, dwDataLen);
3179 return FALSE;
3180 }
3181
3182 *phKey = new_key(hProv, pBlobHeader->aiKeyAlg, MAKELONG(0,pRSAPubKey->bitlen), &pCryptKey);
3183 if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) return FALSE;
3184 setup_key(pCryptKey);
3185 ret = import_private_key_impl(pBlobHeader->aiKeyAlg, (const BYTE *)(pRSAPubKey + 1),
3186 pRSAPubKey->bitlen / 8, pRSAPubKey->pubexp, &pCryptKey->context);
3187 if (ret) {
3189 pCryptKey->dwPermissions |= CRYPT_EXPORT;
3190 switch (pBlobHeader->aiKeyAlg)
3191 {
3192 case AT_SIGNATURE:
3193 case CALG_RSA_SIGN:
3194 TRACE("installing signing key\n");
3195 release_and_install_key(hProv, *phKey, &pKeyContainer->hSignatureKeyPair,
3196 fStoreKey);
3197 break;
3198 case AT_KEYEXCHANGE:
3199 case CALG_RSA_KEYX:
3200 TRACE("installing key exchange key\n");
3201 release_and_install_key(hProv, *phKey, &pKeyContainer->hKeyExchangeKeyPair,
3202 fStoreKey);
3203 break;
3204 }
3205 }
3206 return ret;
3207}
3208
3209/******************************************************************************
3210 * import_public_key [Internal]
3211 *
3212 * Import a BLOB'ed public key.
3213 *
3214 * PARAMS
3215 * hProv [I] A CSP.
3216 * pbData [I] Pointer to a buffer which holds the public key BLOB.
3217 * dwDataLen [I] Length of data in buffer at pbData.
3218 * dwFlags [I] One of:
3219 * CRYPT_EXPORTABLE: the imported key is marked exportable
3220 * phKey [O] Handle to the imported key.
3221 *
3222 *
3223 * NOTES
3224 * Assumes the caller has already checked the BLOBHEADER at pbData to ensure
3225 * it's a PUBLICKEYBLOB.
3226 *
3227 * RETURNS
3228 * Success: TRUE.
3229 * Failure: FALSE.
3230 */
3232 DWORD dwFlags, HCRYPTKEY *phKey)
3233{
3234 CRYPTKEY *pCryptKey;
3235 const BLOBHEADER *pBlobHeader = (const BLOBHEADER*)pbData;
3236 const RSAPUBKEY *pRSAPubKey = (const RSAPUBKEY*)(pBlobHeader+1);
3237 ALG_ID algID;
3238 BOOL ret;
3239
3241 {
3242 FIXME("unimplemented for CRYPT_IPSEC_HMAC_KEY\n");
3244 return FALSE;
3245 }
3246
3247 if ((dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY)) ||
3248 (pRSAPubKey->magic != RSAENH_MAGIC_RSA1) ||
3249 (dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + (pRSAPubKey->bitlen >> 3)))
3250 {
3252 return FALSE;
3253 }
3254
3255 /* Since this is a public key blob, only the public key is
3256 * available, so only signature verification is possible.
3257 */
3258 algID = pBlobHeader->aiKeyAlg;
3259 *phKey = new_key(hProv, algID, MAKELONG(0,pRSAPubKey->bitlen), &pCryptKey);
3260 if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) return FALSE;
3261 setup_key(pCryptKey);
3262 ret = import_public_key_impl(algID, (const BYTE *)(pRSAPubKey + 1), pRSAPubKey->bitlen / 8,
3263 pRSAPubKey->pubexp, &pCryptKey->context);
3264 if (ret) {
3266 pCryptKey->dwPermissions |= CRYPT_EXPORT;
3267 }
3268 return ret;
3269}
3270
3271/******************************************************************************
3272 * import_symmetric_key [Internal]
3273 *
3274 * Import a BLOB'ed symmetric key into a key container.
3275 *
3276 * PARAMS
3277 * hProv [I] Key container into which the symmetric key is to be imported.
3278 * pbData [I] Pointer to a buffer which holds the symmetric key BLOB.
3279 * dwDataLen [I] Length of data in buffer at pbData.
3280 * hPubKey [I] Key used to decrypt sensitive BLOB data.
3281 * dwFlags [I] One of:
3282 * CRYPT_EXPORTABLE: the imported key is marked exportable
3283 * phKey [O] Handle to the imported key.
3284 *
3285 *
3286 * NOTES
3287 * Assumes the caller has already checked the BLOBHEADER at pbData to ensure
3288 * it's a SIMPLEBLOB.
3289 *
3290 * RETURNS
3291 * Success: TRUE.
3292 * Failure: FALSE.
3293 */
3295 HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey)
3296{
3297 CRYPTKEY *pCryptKey, *pPubKey;
3298 const BLOBHEADER *pBlobHeader = (const BLOBHEADER*)pbData;
3299 const ALG_ID *pAlgid = (const ALG_ID*)(pBlobHeader+1);
3300 const BYTE *pbKeyStream = (const BYTE*)(pAlgid + 1);
3301 BYTE *pbDecrypted;
3302 DWORD dwKeyLen;
3303
3305 {
3306 FIXME("unimplemented for CRYPT_IPSEC_HMAC_KEY\n");
3308 return FALSE;
3309 }
3310 if (!lookup_handle(&handle_table, hPubKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pPubKey) ||
3311 pPubKey->aiAlgid != CALG_RSA_KEYX)
3312 {
3313 SetLastError(NTE_BAD_PUBLIC_KEY); /* FIXME: error code? */
3314 return FALSE;
3315 }
3316
3317 if (dwDataLen < sizeof(BLOBHEADER)+sizeof(ALG_ID)+pPubKey->dwBlockLen)
3318 {
3319 SetLastError(NTE_BAD_DATA); /* FIXME: error code */
3320 return FALSE;
3321 }
3322
3323 pbDecrypted = malloc(pPubKey->dwBlockLen);
3324 if (!pbDecrypted) return FALSE;
3325 decrypt_block_impl(pPubKey->aiAlgid, &pPubKey->context, pbKeyStream, pbDecrypted);
3326
3327 dwKeyLen = RSAENH_MAX_KEY_SIZE;
3328 if (!unpad_data(hProv, pbDecrypted, pPubKey->dwBlockLen, pbDecrypted, &dwKeyLen, dwFlags)) {
3329 free(pbDecrypted);
3330 return FALSE;
3331 }
3332
3333 if (pBlobHeader->aiKeyAlg == CALG_RC2)
3334 {
3335 const PROV_ENUMALGS_EX *info;
3336
3338 assert(info);
3339 if (!dwKeyLen)
3340 dwKeyLen = info->dwDefaultLen;
3341 if (dwKeyLen < info->dwMinLen / 8 || dwKeyLen > 128)
3342 {
3343 WARN("Invalid RC2 key, len %ld.\n", dwKeyLen);
3346 }
3347 else if ((*phKey = alloc_key(hProv, pBlobHeader->aiKeyAlg, 0, dwKeyLen << 3, &pCryptKey))
3348 != (HCRYPTKEY)INVALID_HANDLE_VALUE && info->dwDefaultLen == 40 && dwKeyLen > info->dwMaxLen / 8)
3349 {
3350 pCryptKey->dwEffectiveKeyLen = 40;
3351 }
3352 }
3353 else
3354 {
3355 *phKey = new_key(hProv, pBlobHeader->aiKeyAlg, dwKeyLen<<19, &pCryptKey);
3356 }
3357 if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE)
3358 {
3359 free(pbDecrypted);
3360 return FALSE;
3361 }
3362 memcpy(pCryptKey->abKeyValue, pbDecrypted, dwKeyLen);
3363 free(pbDecrypted);
3364 setup_key(pCryptKey);
3366 pCryptKey->dwPermissions |= CRYPT_EXPORT;
3367 return TRUE;
3368}
3369
3370/******************************************************************************
3371 * import_plaintext_key [Internal]
3372 *
3373 * Import a plaintext key into a key container.
3374 *
3375 * PARAMS
3376 * hProv [I] Key container into which the symmetric key is to be imported.
3377 * pbData [I] Pointer to a buffer which holds the plaintext key BLOB.
3378 * dwDataLen [I] Length of data in buffer at pbData.
3379 * dwFlags [I] One of:
3380 * CRYPT_EXPORTABLE: the imported key is marked exportable
3381 * phKey [O] Handle to the imported key.
3382 *
3383 *
3384 * NOTES
3385 * Assumes the caller has already checked the BLOBHEADER at pbData to ensure
3386 * it's a PLAINTEXTKEYBLOB.
3387 *
3388 * RETURNS
3389 * Success: TRUE.
3390 * Failure: FALSE.
3391 */
3393 DWORD dwFlags, HCRYPTKEY *phKey)
3394{
3395 CRYPTKEY *pCryptKey;
3396 const BLOBHEADER *pBlobHeader = (const BLOBHEADER*)pbData;
3397 const DWORD *pKeyLen = (const DWORD *)(pBlobHeader + 1);
3398 const BYTE *pbKeyStream = (const BYTE*)(pKeyLen + 1);
3399
3400 if (dwDataLen < sizeof(BLOBHEADER)+sizeof(DWORD)+*pKeyLen)
3401 {
3402 SetLastError(NTE_BAD_DATA); /* FIXME: error code */
3403 return FALSE;
3404 }
3405
3407 {
3408 *phKey = new_key(hProv, CALG_HMAC, 0, &pCryptKey);
3409 if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE)
3410 return FALSE;
3411 if (*pKeyLen <= RSAENH_MIN(sizeof(pCryptKey->abKeyValue), RSAENH_HMAC_BLOCK_LEN))
3412 {
3413 memcpy(pCryptKey->abKeyValue, pbKeyStream, *pKeyLen);
3414 pCryptKey->dwKeyLen = *pKeyLen;
3415 }
3416 else
3417 {
3418 CRYPT_DATA_BLOB blobHmacKey = { *pKeyLen, (BYTE *)pbKeyStream };
3419
3420 /* In order to initialize an HMAC key, the key material is hashed,
3421 * and the output of the hash function is used as the key material.
3422 * Unfortunately, the way the Crypto API is designed, we don't know
3423 * the hash algorithm yet, so we have to copy the entire key
3424 * material.
3425 */
3426 if (!copy_data_blob(&pCryptKey->blobHmacKey, &blobHmacKey))
3427 {
3430 return FALSE;
3431 }
3432 }
3433 setup_key(pCryptKey);
3435 pCryptKey->dwPermissions |= CRYPT_EXPORT;
3436 }
3437 else
3438 {
3439 *phKey = new_key(hProv, pBlobHeader->aiKeyAlg, *pKeyLen<<19, &pCryptKey);
3440 if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE)
3441 return FALSE;
3442 memcpy(pCryptKey->abKeyValue, pbKeyStream, *pKeyLen);
3443 setup_key(pCryptKey);
3445 pCryptKey->dwPermissions |= CRYPT_EXPORT;
3446 }
3447 return TRUE;
3448}
3449
3450/******************************************************************************
3451 * import_key [Internal]
3452 *
3453 * Import a BLOB'ed key into a key container, optionally storing the key's
3454 * value to the registry.
3455 *
3456 * PARAMS
3457 * hProv [I] Key container into which the key is to be imported.
3458 * pbData [I] Pointer to a buffer which holds the BLOB.
3459 * dwDataLen [I] Length of data in buffer at pbData.
3460 * hPubKey [I] Key used to decrypt sensitive BLOB data.
3461 * dwFlags [I] One of:
3462 * CRYPT_EXPORTABLE: the imported key is marked exportable
3463 * fStoreKey [I] If TRUE, the imported key is stored to the registry.
3464 * phKey [O] Handle to the imported key.
3465 *
3466 * RETURNS
3467 * Success: TRUE.
3468 * Failure: FALSE.
3469 */
3470static BOOL import_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey,
3471 DWORD dwFlags, BOOL fStoreKey, HCRYPTKEY *phKey)
3472{
3473 KEYCONTAINER *pKeyContainer;
3474 const BLOBHEADER *pBlobHeader = (const BLOBHEADER*)pbData;
3475
3476 if (!(pKeyContainer = get_key_container(hProv)))
3477 return FALSE;
3478
3479 if (dwDataLen < sizeof(BLOBHEADER) ||
3480 pBlobHeader->bVersion != CUR_BLOB_VERSION)
3481 {
3482 TRACE("bVersion = %d", pBlobHeader->bVersion);
3484 return FALSE;
3485 }
3486 if (pBlobHeader->reserved != 0)
3487 WARN("reserved != 0: %d\n", pBlobHeader->reserved);
3488
3489 /* If this is a verify-only context, the key is not persisted regardless of
3490 * fStoreKey's original value.
3491 */
3492 fStoreKey = fStoreKey && !(dwFlags & CRYPT_VERIFYCONTEXT);
3493 TRACE("blob type: %x\n", pBlobHeader->bType);
3494 switch (pBlobHeader->bType)
3495 {
3496 case PRIVATEKEYBLOB:
3497 return import_private_key(hProv, pbData, dwDataLen, dwFlags,
3498 fStoreKey, phKey);
3499
3500 case PUBLICKEYBLOB:
3501 return import_public_key(hProv, pbData, dwDataLen, dwFlags,
3502 phKey);
3503
3504 case SIMPLEBLOB:
3505 return import_symmetric_key(hProv, pbData, dwDataLen, hPubKey,
3506 dwFlags, phKey);
3507
3508 case PLAINTEXTKEYBLOB:
3509 return import_plaintext_key(hProv, pbData, dwDataLen, dwFlags,
3510 phKey);
3511
3512 default:
3513 SetLastError(NTE_BAD_TYPE); /* FIXME: error code? */
3514 return FALSE;
3515 }
3516}
3517
3518/******************************************************************************
3519 * CPImportKey (RSAENH.@)
3520 *
3521 * Import a BLOB'ed key into a key container.
3522 *
3523 * PARAMS
3524 * hProv [I] Key container into which the key is to be imported.
3525 * pbData [I] Pointer to a buffer which holds the BLOB.
3526 * dwDataLen [I] Length of data in buffer at pbData.
3527 * hPubKey [I] Key used to decrypt sensitive BLOB data.
3528 * dwFlags [I] One of:
3529 * CRYPT_EXPORTABLE: the imported key is marked exportable
3530 * phKey [O] Handle to the imported key.
3531 *
3532 * RETURNS
3533 * Success: TRUE.
3534 * Failure: FALSE.
3535 */
3537 HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey)
3538{
3539 TRACE("(hProv=%08Ix, pbData=%p, dwDataLen=%ld, hPubKey=%08Ix, dwFlags=%08lx, phKey=%p)\n",
3540 hProv, pbData, dwDataLen, hPubKey, dwFlags, phKey);
3541
3542 return import_key(hProv, pbData, dwDataLen, hPubKey, dwFlags, TRUE, phKey);
3543}
3544
3545/******************************************************************************
3546 * CPGenKey (RSAENH.@)
3547 *
3548 * Generate a key in the key container
3549 *
3550 * PARAMS
3551 * hProv [I] Key container for which a key is to be generated.
3552 * Algid [I] Crypto algorithm identifier for the key to be generated.
3553 * dwFlags [I] Upper 16 bits: Binary length of key. Lower 16 bits: Flags. See Notes
3554 * phKey [O] Handle to the generated key.
3555 *
3556 * RETURNS
3557 * Success: TRUE.
3558 * Failure: FALSE.
3559 *
3560 * FIXME
3561 * Flags currently not considered.
3562 *
3563 * NOTES
3564 * Private key-exchange- and signature-keys can be generated with Algid AT_KEYEXCHANGE
3565 * and AT_SIGNATURE values.
3566 */
3568{
3569 KEYCONTAINER *pKeyContainer;
3570 CRYPTKEY *pCryptKey;
3571
3572 TRACE("(hProv=%08Ix, aiAlgid=%d, dwFlags=%08lx, phKey=%p)\n", hProv, Algid, dwFlags, phKey);
3573
3574 if (!(pKeyContainer = get_key_container(hProv)))
3575 {
3576 /* MSDN: hProv not containing valid context handle */
3577 return FALSE;
3578 }
3579
3580 switch (Algid)
3581 {
3582 case AT_SIGNATURE:
3583 case CALG_RSA_SIGN:
3584 *phKey = new_key(hProv, CALG_RSA_SIGN, dwFlags, &pCryptKey);
3585 if (pCryptKey) {
3586 new_key_impl(pCryptKey->aiAlgid, &pCryptKey->context, pCryptKey->dwKeyLen);
3587 setup_key(pCryptKey);
3589 &pKeyContainer->hSignatureKeyPair,
3590 FALSE);
3591 }
3592 break;
3593
3594 case AT_KEYEXCHANGE:
3595 case CALG_RSA_KEYX:
3596 *phKey = new_key(hProv, CALG_RSA_KEYX, dwFlags, &pCryptKey);
3597 if (pCryptKey) {
3598 new_key_impl(pCryptKey->aiAlgid, &pCryptKey->context, pCryptKey->dwKeyLen);
3599 setup_key(pCryptKey);
3601 &pKeyContainer->hKeyExchangeKeyPair,
3602 FALSE);
3603 }
3604 break;
3605
3606 case CALG_RC2:
3607 case CALG_RC4:
3608 case CALG_DES:
3609 case CALG_3DES_112:
3610 case CALG_3DES:
3611 case CALG_AES_128:
3612 case CALG_AES_192:
3613 case CALG_AES_256:
3614 case CALG_PCT1_MASTER:
3615 case CALG_SSL2_MASTER:
3616 case CALG_SSL3_MASTER:
3617 case CALG_TLS1_MASTER:
3618 *phKey = new_key(hProv, Algid, dwFlags, &pCryptKey);
3619 if (pCryptKey) {
3621 switch (Algid) {
3622 case CALG_SSL3_MASTER:
3623 pCryptKey->abKeyValue[0] = RSAENH_SSL3_VERSION_MAJOR;
3624 pCryptKey->abKeyValue[1] = RSAENH_SSL3_VERSION_MINOR;
3625 break;
3626
3627 case CALG_TLS1_MASTER:
3628 pCryptKey->abKeyValue[0] = RSAENH_TLS1_VERSION_MAJOR;
3629 pCryptKey->abKeyValue[1] = RSAENH_TLS1_VERSION_MINOR;
3630 break;
3631 case CALG_RC4:
3632 if (!(dwFlags & CRYPT_CREATE_SALT))
3633 memset(pCryptKey->abKeyValue + pCryptKey->dwKeyLen, 0, pCryptKey->dwSaltLen);
3634 break;
3635 }
3636 setup_key(pCryptKey);
3637 }
3638 break;
3639
3640 default:
3641 /* MSDN: Algorithm not supported specified by Algid */
3643 return FALSE;
3644 }
3645
3646 return *phKey != (HCRYPTKEY)INVALID_HANDLE_VALUE;
3647}
3648
3649/******************************************************************************
3650 * CPGenRandom (RSAENH.@)
3651 *
3652 * Generate a random byte stream.
3653 *
3654 * PARAMS
3655 * hProv [I] Key container that is used to generate random bytes.
3656 * dwLen [I] Specifies the number of requested random data bytes.
3657 * pbBuffer [O] Random bytes will be stored here.
3658 *
3659 * RETURNS
3660 * Success: TRUE
3661 * Failure: FALSE
3662 */
3664{
3665 TRACE("(hProv=%08Ix, dwLen=%ld, pbBuffer=%p)\n", hProv, dwLen, pbBuffer);
3666
3668 {
3669 /* MSDN: hProv not containing valid context handle */
3671 return FALSE;
3672 }
3673
3674 return RtlGenRandom(pbBuffer, dwLen);
3675}
3676
3677/******************************************************************************
3678 * CPGetHashParam (RSAENH.@)
3679 *
3680 * Query parameters of an hash object.
3681 *
3682 * PARAMS
3683 * hProv [I] The kea container, which the hash belongs to.
3684 * hHash [I] The hash object that is to be queried.
3685 * dwParam [I] Specifies the parameter that is to be queried.
3686 * pbData [I] Pointer to the buffer where the parameter value will be stored.
3687 * pdwDataLen [I/O] I: Buffer length at pbData, O: Length of the parameter value.
3688 * dwFlags [I] None currently defined.
3689 *
3690 * RETURNS
3691 * Success: TRUE
3692 * Failure: FALSE
3693 *
3694 * NOTES
3695 * Valid dwParams are: HP_ALGID, HP_HASHSIZE, HP_HASHVALUE. The hash will be
3696 * finalized if HP_HASHVALUE is queried.
3697 */
3699 DWORD *pdwDataLen, DWORD dwFlags)
3700{
3701 CRYPTHASH *pCryptHash;
3702
3703 TRACE("(hProv=%08Ix, hHash=%08Ix, dwParam=%08lx, pbData=%p, pdwDataLen=%p, dwFlags=%08lx)\n",
3704 hProv, hHash, dwParam, pbData, pdwDataLen, dwFlags);
3705
3707 {
3709 return FALSE;
3710 }
3711
3712 if (dwFlags)
3713 {
3715 return FALSE;
3716 }
3717
3719 (OBJECTHDR**)&pCryptHash))
3720 {
3722 return FALSE;
3723 }
3724
3725 if (!pdwDataLen)
3726 {
3728 return FALSE;
3729 }
3730
3731 switch (dwParam)
3732 {
3733 case HP_ALGID:
3734 return copy_param(pbData, pdwDataLen, (const BYTE*)&pCryptHash->aiAlgid,
3735 sizeof(ALG_ID));
3736
3737 case HP_HASHSIZE:
3738 return copy_param(pbData, pdwDataLen, (const BYTE*)&pCryptHash->dwHashSize,
3739 sizeof(DWORD));
3740
3741 case HP_HASHVAL:
3742 if (pCryptHash->aiAlgid == CALG_TLS1PRF) {
3743 return tls1_prf(hProv, pCryptHash->hKey, &pCryptHash->tpPRFParams.blobLabel,
3744 &pCryptHash->tpPRFParams.blobSeed, pbData, *pdwDataLen);
3745 }
3746
3747 if (pCryptHash->aiAlgid == CALG_HMAC && !pCryptHash->hash.desc)
3748 {
3750 return FALSE;
3751 }
3752
3753 if (!pbData)
3754 {
3755 *pdwDataLen = pCryptHash->dwHashSize;
3756 return TRUE;
3757 }
3758
3759 if (pCryptHash->dwState != RSAENH_HASHSTATE_FINISHED)
3760 {
3761 finalize_hash(pCryptHash);
3762 pCryptHash->dwState = RSAENH_HASHSTATE_FINISHED;
3763 }
3764
3765 return copy_param(pbData, pdwDataLen, pCryptHash->abHashValue,
3766 pCryptHash->dwHashSize);
3767
3768 default:
3770 return FALSE;
3771 }
3772}
3773
3774/******************************************************************************
3775 * CPSetKeyParam (RSAENH.@)
3776 *
3777 * Set a parameter of a key object
3778 *
3779 * PARAMS
3780 * hProv [I] The key container to which the key belongs.
3781 * hKey [I] The key for which a parameter is to be set.
3782 * dwParam [I] Parameter type. See Notes.
3783 * pbData [I] Pointer to the parameter value.
3784 * dwFlags [I] Currently none defined.
3785 *
3786 * RETURNS
3787 * Success: TRUE.
3788 * Failure: FALSE.
3789 *
3790 * NOTES:
3791 * Defined dwParam types are:
3792 * - KP_MODE: Values MODE_CBC, MODE_ECB, MODE_CFB.
3793 * - KP_MODE_BITS: Shift width for cipher feedback mode. (Currently ignored by MS CSP's)
3794 * - KP_PERMISSIONS: Or'ed combination of CRYPT_ENCRYPT, CRYPT_DECRYPT,
3795 * CRYPT_EXPORT, CRYPT_READ, CRYPT_WRITE, CRYPT_MAC
3796 * - KP_IV: Initialization vector
3797 */
3799 DWORD dwFlags)
3800{
3801 CRYPTKEY *pCryptKey;
3802
3803 TRACE("(hProv=%08Ix, hKey=%08Ix, dwParam=%08lx, pbData=%p, dwFlags=%08lx)\n", hProv, hKey,
3804 dwParam, pbData, dwFlags);
3805
3807 {
3809 return FALSE;
3810 }
3811
3812 if (dwFlags) {
3814 return FALSE;
3815 }
3816
3818 {
3820 return FALSE;
3821 }
3822
3823 if (!pbData)
3824 {
3826 return FALSE;
3827 }
3828
3829 switch (dwParam) {
3830 case KP_PADDING:
3831 /* The MS providers only support PKCS5_PADDING */
3832 if (*(DWORD *)pbData != PKCS5_PADDING) {
3834 return FALSE;
3835 }
3836 return TRUE;
3837
3838 case KP_MODE:
3839 pCryptKey->dwMode = *(DWORD*)pbData;
3840 return TRUE;
3841
3842 case KP_MODE_BITS:
3843 pCryptKey->dwModeBits = *(DWORD*)pbData;
3844 return TRUE;
3845
3846 case KP_PERMISSIONS:
3847 {
3848 DWORD perms = *(DWORD *)pbData;
3849
3850 if ((perms & CRYPT_EXPORT) &&
3851 !(pCryptKey->dwPermissions & CRYPT_EXPORT))
3852 {
3854 return FALSE;
3855 }
3856 else if (!(perms & CRYPT_EXPORT) &&
3857 (pCryptKey->dwPermissions & CRYPT_EXPORT))
3858 {
3859 /* Clearing the export permission appears to be ignored,
3860 * see tests.
3861 */
3862 perms |= CRYPT_EXPORT;
3863 }
3864 pCryptKey->dwPermissions = perms;
3865 return TRUE;
3866 }
3867
3868 case KP_IV:
3869 memcpy(pCryptKey->abInitVector, pbData, pCryptKey->dwBlockLen);
3870 setup_key(pCryptKey);
3871 return TRUE;
3872
3873 case KP_SALT:
3874 switch (pCryptKey->aiAlgid) {
3875 case CALG_RC2:
3876 case CALG_RC4:
3877 {
3878 KEYCONTAINER *pKeyContainer = get_key_container(pCryptKey->hProv);
3879 if (!pKeyContainer)
3880 {
3882 return FALSE;
3883 }
3884 if (!pbData)
3885 {
3887 return FALSE;
3888 }
3889 /* MSDN: the base provider always sets eleven bytes of
3890 * salt value.
3891 */
3892 memcpy(pCryptKey->abKeyValue + pCryptKey->dwKeyLen,
3893 pbData, 11);
3894 pCryptKey->dwSaltLen = 11;
3895 setup_key(pCryptKey);
3896 /* After setting the salt value if the provider is not base or
3897 * strong the salt length will be reset. */
3898 if (pKeyContainer->dwPersonality != RSAENH_PERSONALITY_BASE &&
3899 pKeyContainer->dwPersonality != RSAENH_PERSONALITY_STRONG)
3900 pCryptKey->dwSaltLen = 0;
3901 break;
3902 }
3903 default:
3905 return FALSE;
3906 }
3907 return TRUE;
3908
3909 case KP_SALT_EX:
3910 {
3912
3913 /* salt length can't be greater than 184 bits = 24 bytes */
3914 if (blob->cbData > 24)
3915 {
3917 return FALSE;
3918 }
3919 memcpy(pCryptKey->abKeyValue + pCryptKey->dwKeyLen, blob->pbData,
3920 blob->cbData);
3921 pCryptKey->dwSaltLen = blob->cbData;
3922 setup_key(pCryptKey);
3923 return TRUE;
3924 }
3925
3927 switch (pCryptKey->aiAlgid) {
3928 case CALG_RC2:
3929 {
3930 DWORD keylen, deflen;
3931 BOOL ret = TRUE;
3932 KEYCONTAINER *pKeyContainer = get_key_container(pCryptKey->hProv);
3933 if (!pKeyContainer)
3934 {
3936 return FALSE;
3937 }
3938 if (!pbData)
3939 {
3941 return FALSE;
3942 }
3943 keylen = *(DWORD *)pbData;
3944 if (!keylen || keylen > 1024)
3945 {
3947 return FALSE;
3948 }
3949
3950 /*
3951 * The Base provider will force the key length to default
3952 * and set an error state if a key length different from
3953 * the default is tried.
3954 */
3955 deflen = aProvEnumAlgsEx[pKeyContainer->dwPersonality]->dwDefaultLen;
3956 if (pKeyContainer->dwPersonality == RSAENH_PERSONALITY_BASE
3957 && keylen != deflen)
3958 {
3959 keylen = deflen;
3961 ret = FALSE;
3962 }
3963 pCryptKey->dwEffectiveKeyLen = keylen;
3964 setup_key(pCryptKey);
3965 return ret;
3966 }
3967 default:
3969 return FALSE;
3970 }
3971 return TRUE;
3972
3973 case KP_SCHANNEL_ALG:
3974 switch (((PSCHANNEL_ALG)pbData)->dwUse) {
3975 case SCHANNEL_ENC_KEY:
3976 memcpy(&pCryptKey->siSChannelInfo.saEncAlg, pbData, sizeof(SCHANNEL_ALG));
3977 break;
3978
3979 case SCHANNEL_MAC_KEY:
3980 memcpy(&pCryptKey->siSChannelInfo.saMACAlg, pbData, sizeof(SCHANNEL_ALG));
3981 break;
3982
3983 default:
3984 SetLastError(NTE_FAIL); /* FIXME: error code */
3985 return FALSE;
3986 }
3987 return TRUE;
3988
3989 case KP_CLIENT_RANDOM:
3991
3992 case KP_SERVER_RANDOM:
3994
3995 default:
3997 return FALSE;
3998 }
3999}
4000
4001/******************************************************************************
4002 * CPGetKeyParam (RSAENH.@)
4003 *
4004 * Query a key parameter.
4005 *
4006 * PARAMS
4007 * hProv [I] The key container, which the key belongs to.
4008 * hHash [I] The key object that is to be queried.
4009 * dwParam [I] Specifies the parameter that is to be queried.
4010 * pbData [I] Pointer to the buffer where the parameter value will be stored.
4011 * pdwDataLen [I/O] I: Buffer length at pbData, O: Length of the parameter value.
4012 * dwFlags [I] None currently defined.
4013 *
4014 * RETURNS
4015 * Success: TRUE
4016 * Failure: FALSE
4017 *
4018 * NOTES
4019 * Defined dwParam types are:
4020 * - KP_MODE: Values MODE_CBC, MODE_ECB, MODE_CFB.
4021 * - KP_MODE_BITS: Shift width for cipher feedback mode.
4022 * (Currently ignored by MS CSP's - always eight)
4023 * - KP_PERMISSIONS: Or'ed combination of CRYPT_ENCRYPT, CRYPT_DECRYPT,
4024 * CRYPT_EXPORT, CRYPT_READ, CRYPT_WRITE, CRYPT_MAC
4025 * - KP_IV: Initialization vector.
4026 * - KP_KEYLEN: Bitwidth of the key.
4027 * - KP_BLOCKLEN: Size of a block cipher block.
4028 * - KP_SALT: Salt value.
4029 */
4031 DWORD *pdwDataLen, DWORD dwFlags)
4032{
4033 CRYPTKEY *pCryptKey;
4034 DWORD dwValue;
4035
4036 TRACE("(hProv=%08Ix, hKey=%08Ix, dwParam=%08lx, pbData=%p, pdwDataLen=%p dwFlags=%08lx)\n",
4037 hProv, hKey, dwParam, pbData, pdwDataLen, dwFlags);
4038
4040 {
4042 return FALSE;
4043 }
4044
4045 if (dwFlags) {
4047 return FALSE;
4048 }
4049
4051 {
4053 return FALSE;
4054 }
4055
4056 switch (dwParam)
4057 {
4058 case KP_IV:
4059 return copy_param(pbData, pdwDataLen, pCryptKey->abInitVector,
4060 pCryptKey->dwBlockLen);
4061
4062 case KP_SALT:
4063 switch (pCryptKey->aiAlgid) {
4064 case CALG_RC2:
4065 case CALG_RC4:
4066 return copy_param(pbData, pdwDataLen,
4067 &pCryptKey->abKeyValue[pCryptKey->dwKeyLen],
4068 pCryptKey->dwSaltLen);
4069 default:
4071 return FALSE;
4072 }
4073
4074 case KP_PADDING:
4075 dwValue = PKCS5_PADDING;
4076 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwValue, sizeof(DWORD));
4077
4078 case KP_KEYLEN:
4079 dwValue = pCryptKey->dwKeyLen << 3;
4080 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwValue, sizeof(DWORD));
4081
4083 if (pCryptKey->dwEffectiveKeyLen)
4084 dwValue = pCryptKey->dwEffectiveKeyLen;
4085 else
4086 dwValue = pCryptKey->dwKeyLen << 3;
4087 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwValue, sizeof(DWORD));
4088
4089 case KP_BLOCKLEN:
4090 dwValue = pCryptKey->dwBlockLen << 3;
4091 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwValue, sizeof(DWORD));
4092
4093 case KP_MODE:
4094 return copy_param(pbData, pdwDataLen, (const BYTE*)&pCryptKey->dwMode, sizeof(DWORD));
4095
4096 case KP_MODE_BITS:
4097 return copy_param(pbData, pdwDataLen, (const BYTE*)&pCryptKey->dwModeBits,
4098 sizeof(DWORD));
4099
4100 case KP_PERMISSIONS:
4101 return copy_param(pbData, pdwDataLen, (const BYTE*)&pCryptKey->dwPermissions,
4102 sizeof(DWORD));
4103
4104 case KP_ALGID:
4105 return copy_param(pbData, pdwDataLen, (const BYTE*)&pCryptKey->aiAlgid, sizeof(DWORD));
4106
4107 default:
4109 return FALSE;
4110 }
4111}
4112
4113/******************************************************************************
4114 * CPGetProvParam (RSAENH.@)
4115 *
4116 * Query a CSP parameter.
4117 *
4118 * PARAMS
4119 * hProv [I] The key container that is to be queried.
4120 * dwParam [I] Specifies the parameter that is to be queried.
4121 * pbData [I] Pointer to the buffer where the parameter value will be stored.
4122 * pdwDataLen [I/O] I: Buffer length at pbData, O: Length of the parameter value.
4123 * dwFlags [I] CRYPT_FIRST: Start enumeration (for PP_ENUMALGS{_EX}).
4124 *
4125 * RETURNS
4126 * Success: TRUE
4127 * Failure: FALSE
4128 * NOTES:
4129 * Defined dwParam types:
4130 * - PP_CONTAINER: Name of the key container.
4131 * - PP_NAME: Name of the cryptographic service provider.
4132 * - PP_SIG_KEYSIZE_INC: RSA signature keywidth granularity in bits.
4133 * - PP_KEYX_KEYSIZE_INC: RSA key-exchange keywidth granularity in bits.
4134 * - PP_ENUMALGS{_EX}: Query provider capabilities.
4135 * - PP_KEYSET_SEC_DESCR: Retrieve security descriptor on container.
4136 */
4138 DWORD *pdwDataLen, DWORD dwFlags)
4139{
4140 KEYCONTAINER *pKeyContainer;
4141 PROV_ENUMALGS provEnumalgs;
4142 DWORD dwTemp;
4143 HKEY hKey;
4144
4145 /* This is for dwParam PP_CRYPT_COUNT_KEY_USE.
4146 * IE6 SP1 asks for it in the 'About' dialog.
4147 * Returning this BLOB seems to satisfy IE. The marked 0x00 seem
4148 * to be 'don't care's. If you know anything more specific about
4149 * this provider parameter, please contact the Wine developers */
4150 static const BYTE abWTF[96] = {
4151 0xb0, 0x25, 0x63, 0x86, 0x9c, 0xab, 0xb6, 0x37,
4152 0xe8, 0x82, 0x00, 0x72, 0x06, 0xb2, 0x00, 0x3b,
4153 0x60, 0x35, 0x00, 0x3b, 0x88, 0xce, 0x00, 0x82,
4154 0xbc, 0x7a, 0x00, 0xb7, 0x4f, 0x7e, 0x00, 0xde,
4155 0x92, 0xf1, 0x00, 0x83, 0xea, 0x5e, 0x00, 0xc8,
4156 0x12, 0x1e, 0xd4, 0x06, 0xf7, 0x66, 0x00, 0x01,
4157 0x29, 0xa4, 0x00, 0xf8, 0x24, 0x0c, 0x00, 0x33,
4158 0x06, 0x80, 0x00, 0x02, 0x46, 0x0b, 0x00, 0x6d,
4159 0x5b, 0xca, 0x00, 0x9a, 0x10, 0xf0, 0x00, 0x05,
4160 0x19, 0xd0, 0x00, 0x2c, 0xf6, 0x27, 0x00, 0xaa,
4161 0x7c, 0x6f, 0x00, 0xb9, 0xd8, 0x72, 0x00, 0x03,
4162 0xf3, 0x81, 0x00, 0xfa, 0xe8, 0x26, 0x00, 0xca
4163 };
4164
4165 TRACE("(hProv=%08Ix, dwParam=%08lx, pbData=%p, pdwDataLen=%p, dwFlags=%08lx)\n",
4166 hProv, dwParam, pbData, pdwDataLen, dwFlags);
4167
4168 if (!pdwDataLen) {
4170 return FALSE;
4171 }
4172
4173 if (!(pKeyContainer = get_key_container(hProv)))
4174 {
4175 /* MSDN: hProv not containing valid context handle */
4176 return FALSE;
4177 }
4178
4179 switch (dwParam)
4180 {
4181 case PP_CONTAINER:
4182 case PP_UNIQUE_CONTAINER:/* MSDN says we can return the same value as PP_CONTAINER */
4183 return copy_param(pbData, pdwDataLen, (const BYTE*)pKeyContainer->szName,
4184 strlen(pKeyContainer->szName)+1);
4185
4186 case PP_NAME:
4187 return copy_param(pbData, pdwDataLen, (const BYTE*)pKeyContainer->szProvName,
4188 strlen(pKeyContainer->szProvName)+1);
4189
4190 case PP_PROVTYPE:
4191 switch (pKeyContainer->dwPersonality) {
4192 case RSAENH_PERSONALITY_SCHANNEL: dwTemp = PROV_RSA_SCHANNEL; break;
4193 case RSAENH_PERSONALITY_AES: dwTemp = PROV_RSA_AES; break;
4194 default: dwTemp = PROV_RSA_FULL; break;
4195 }
4196 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwTemp, sizeof(dwTemp));
4197
4198 case PP_KEYSPEC:
4199 dwTemp = AT_SIGNATURE | AT_KEYEXCHANGE;
4200 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwTemp, sizeof(dwTemp));
4201
4202 case PP_KEYSET_TYPE:
4203 dwTemp = pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET;
4204 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwTemp, sizeof(dwTemp));
4205
4206 case PP_KEYSTORAGE:
4207 dwTemp = CRYPT_SEC_DESCR;
4208 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwTemp, sizeof(dwTemp));
4209
4210 case PP_SIG_KEYSIZE_INC:
4212 dwTemp = 8;
4213 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwTemp, sizeof(dwTemp));
4214
4215 case PP_IMPTYPE:
4216 dwTemp = CRYPT_IMPL_SOFTWARE;
4217 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwTemp, sizeof(dwTemp));
4218
4219 case PP_VERSION:
4220 dwTemp = 0x00000200;
4221 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwTemp, sizeof(dwTemp));
4222
4223 case PP_ENUMCONTAINERS:
4224 if ((dwFlags & CRYPT_FIRST) == CRYPT_FIRST) pKeyContainer->dwEnumContainersCtr = 0;
4225
4226 if (!pbData) {
4227 *pdwDataLen = (DWORD)MAX_PATH + 1;
4228 return TRUE;
4229 }
4230
4232 {
4234 return FALSE;
4235 }
4236
4237 dwTemp = *pdwDataLen;
4238 switch (RegEnumKeyExA(hKey, pKeyContainer->dwEnumContainersCtr, (LPSTR)pbData, &dwTemp,
4239 NULL, NULL, NULL, NULL))
4240 {
4241 case ERROR_MORE_DATA:
4242 *pdwDataLen = (DWORD)MAX_PATH + 1;
4243
4244 case ERROR_SUCCESS:
4245 pKeyContainer->dwEnumContainersCtr++;
4247 return TRUE;
4248
4250 default:
4253 return FALSE;
4254 }
4255
4256 case PP_ENUMALGS:
4257 case PP_ENUMALGS_EX:
4258 if (((pKeyContainer->dwEnumAlgsCtr >= RSAENH_MAX_ENUMALGS-1) ||
4259 (!aProvEnumAlgsEx[pKeyContainer->dwPersonality]
4260 [pKeyContainer->dwEnumAlgsCtr+1].aiAlgid)) &&
4262 {
4264 return FALSE;
4265 }
4266
4267 if (dwParam == PP_ENUMALGS) {
4268 if (pbData && (*pdwDataLen >= sizeof(PROV_ENUMALGS)))
4269 pKeyContainer->dwEnumAlgsCtr = ((dwFlags & CRYPT_FIRST) == CRYPT_FIRST) ?
4270 0 : pKeyContainer->dwEnumAlgsCtr+1;
4271
4272 provEnumalgs.aiAlgid = aProvEnumAlgsEx
4273 [pKeyContainer->dwPersonality][pKeyContainer->dwEnumAlgsCtr].aiAlgid;
4274 provEnumalgs.dwBitLen = aProvEnumAlgsEx
4275 [pKeyContainer->dwPersonality][pKeyContainer->dwEnumAlgsCtr].dwDefaultLen;
4276 provEnumalgs.dwNameLen = aProvEnumAlgsEx
4277 [pKeyContainer->dwPersonality][pKeyContainer->dwEnumAlgsCtr].dwNameLen;
4278 memcpy(provEnumalgs.szName, aProvEnumAlgsEx
4279 [pKeyContainer->dwPersonality][pKeyContainer->dwEnumAlgsCtr].szName,
4280 20*sizeof(CHAR));
4281
4282 return copy_param(pbData, pdwDataLen, (const BYTE*)&provEnumalgs,
4283 sizeof(PROV_ENUMALGS));
4284 } else {
4285 if (pbData && (*pdwDataLen >= sizeof(PROV_ENUMALGS_EX)))
4286 pKeyContainer->dwEnumAlgsCtr = ((dwFlags & CRYPT_FIRST) == CRYPT_FIRST) ?
4287 0 : pKeyContainer->dwEnumAlgsCtr+1;
4288
4289 return copy_param(pbData, pdwDataLen,
4290 (const BYTE*)&aProvEnumAlgsEx
4291 [pKeyContainer->dwPersonality][pKeyContainer->dwEnumAlgsCtr],
4292 sizeof(PROV_ENUMALGS_EX));
4293 }
4294
4295 case PP_CRYPT_COUNT_KEY_USE: /* Asked for by IE About dialog */
4296 return copy_param(pbData, pdwDataLen, abWTF, sizeof(abWTF));
4297
4299 {
4301 DWORD err, len, flags = (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET);
4302
4303 if (!open_container_key(pKeyContainer->szName, flags, KEY_READ, &hKey))
4304 {
4306 return FALSE;
4307 }
4308
4311 if (err)
4312 {
4314 return FALSE;
4315 }
4316
4318 if (*pdwDataLen >= len) memcpy(pbData, sd, len);
4320 *pdwDataLen = len;
4321
4322 LocalFree(sd);
4323 return TRUE;
4324 }
4325
4326 default:
4327 /* MSDN: Unknown parameter number in dwParam */
4329 return FALSE;
4330 }
4331}
4332
4333/******************************************************************************
4334 * CPDeriveKey (RSAENH.@)
4335 *
4336 * Derives a key from a hash value.
4337 *
4338 * PARAMS
4339 * hProv [I] Key container for which a key is to be generated.
4340 * Algid [I] Crypto algorithm identifier for the key to be generated.
4341 * hBaseData [I] Hash from whose value the key will be derived.
4342 * dwFlags [I] See Notes.
4343 * phKey [O] The generated key.
4344 *
4345 * RETURNS
4346 * Success: TRUE
4347 * Failure: FALSE
4348 *
4349 * NOTES
4350 * Defined flags:
4351 * - CRYPT_EXPORTABLE: Key can be exported.
4352 * - CRYPT_NO_SALT: No salt is used for 40 bit keys.
4353 * - CRYPT_CREATE_SALT: Use remaining bits as salt value.
4354 */
4356 DWORD dwFlags, HCRYPTKEY *phKey)
4357{
4358 CRYPTKEY *pCryptKey, *pMasterKey;
4359 CRYPTHASH *pCryptHash;
4360 BYTE abHashValue[RSAENH_MAX_HASH_SIZE*2];
4361 DWORD dwLen;
4362
4363 TRACE("(hProv=%08Ix, Algid=%d, hBaseData=%08Ix, dwFlags=%08lx phKey=%p)\n", hProv, Algid,
4364 hBaseData, dwFlags, phKey);
4365
4367 {
4369 return FALSE;
4370 }
4371
4373 (OBJECTHDR**)&pCryptHash))
4374 {
4376 return FALSE;
4377 }
4378
4379 if (!phKey)
4380 {
4382 return FALSE;
4383 }
4384
4385 switch (GET_ALG_CLASS(Algid))
4386 {
4388 {
4389 int need_padding, copy_len;
4390 *phKey = new_key(hProv, Algid, dwFlags, &pCryptKey);
4391 if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) return FALSE;
4392
4393 /*
4394 * We derive the key material from the hash.
4395 * If the hash value is not large enough for the claimed key, we have to construct
4396 * a larger binary value based on the hash. This is documented in MSDN: CryptDeriveKey.
4397 */
4398 dwLen = RSAENH_MAX_HASH_SIZE;
4399 RSAENH_CPGetHashParam(pCryptHash->hProv, hBaseData, HP_HASHVAL, abHashValue, &dwLen, 0);
4400
4401 /*
4402 * The usage of padding seems to vary from algorithm to algorithm.
4403 * For now the only different case found was for AES with 128 bit key.
4404 */
4405 switch(Algid)
4406 {
4407 case CALG_AES_128:
4408 /* To reduce the chance of regressions we will only deviate
4409 * from the old behavior for the tested hash lengths */
4410 if (dwLen == 16 || dwLen == 20)
4411 {
4412 need_padding = 1;
4413 break;
4414 }
4415 default:
4416 need_padding = dwLen < pCryptKey->dwKeyLen;
4417 }
4418
4419 copy_len = pCryptKey->dwKeyLen;
4420 if (need_padding)
4421 {
4423 BYTE old_hashval[RSAENH_MAX_HASH_SIZE];
4424 DWORD i;
4425
4426 memcpy(old_hashval, pCryptHash->abHashValue, RSAENH_MAX_HASH_SIZE);
4427
4428 for (i=0; i<RSAENH_HMAC_DEF_PAD_LEN; i++) {
4429 pad1[i] = RSAENH_HMAC_DEF_IPAD_CHAR ^ (i<dwLen ? abHashValue[i] : 0);
4430 pad2[i] = RSAENH_HMAC_DEF_OPAD_CHAR ^ (i<dwLen ? abHashValue[i] : 0);
4431 }
4432
4433 init_hash(pCryptHash);
4434 update_hash(pCryptHash, pad1, RSAENH_HMAC_DEF_PAD_LEN);
4435 finalize_hash(pCryptHash);
4436 memcpy(abHashValue, pCryptHash->abHashValue, pCryptHash->dwHashSize);
4437
4438 init_hash(pCryptHash);
4439 update_hash(pCryptHash, pad2, RSAENH_HMAC_DEF_PAD_LEN);
4440 finalize_hash(pCryptHash);
4441 memcpy(abHashValue+pCryptHash->dwHashSize, pCryptHash->abHashValue,
4442 pCryptHash->dwHashSize);
4443
4444 memcpy(pCryptHash->abHashValue, old_hashval, RSAENH_MAX_HASH_SIZE);
4445 }
4446 /*
4447 * Padding was not required, we have more hash than needed.
4448 * Do we need to use the remaining hash as salt?
4449 */
4450 else if((dwFlags & CRYPT_CREATE_SALT) &&
4451 (Algid == CALG_RC2 || Algid == CALG_RC4))
4452 {
4453 copy_len += pCryptKey->dwSaltLen;
4454 }
4455
4456 memcpy(pCryptKey->abKeyValue, abHashValue,
4457 RSAENH_MIN(copy_len, sizeof(pCryptKey->abKeyValue)));
4458 break;
4459 }
4461 if (!lookup_handle(&handle_table, pCryptHash->hKey, RSAENH_MAGIC_KEY,
4462 (OBJECTHDR**)&pMasterKey))
4463 {
4464 SetLastError(NTE_FAIL); /* FIXME error code */
4465 return FALSE;
4466 }
4467
4468 switch (Algid)
4469 {
4470 /* See RFC 2246, chapter 6.3 Key calculation */
4472 if (!pMasterKey->siSChannelInfo.saEncAlg.Algid ||
4473 !pMasterKey->siSChannelInfo.saEncAlg.cBits)
4474 {
4476 return FALSE;
4477 }
4478 *phKey = new_key(hProv, pMasterKey->siSChannelInfo.saEncAlg.Algid,
4479 MAKELONG(LOWORD(dwFlags),pMasterKey->siSChannelInfo.saEncAlg.cBits),
4480 &pCryptKey);
4481 if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) return FALSE;
4482 memcpy(pCryptKey->abKeyValue,
4483 pCryptHash->abHashValue + (
4484 2 * (pMasterKey->siSChannelInfo.saMACAlg.cBits / 8) +
4485 ((dwFlags & CRYPT_SERVER) ?
4486 (pMasterKey->siSChannelInfo.saEncAlg.cBits / 8) : 0)),
4487 pMasterKey->siSChannelInfo.saEncAlg.cBits / 8);
4488 memcpy(pCryptKey->abInitVector,
4489 pCryptHash->abHashValue + (
4490 2 * (pMasterKey->siSChannelInfo.saMACAlg.cBits / 8) +
4491 2 * (pMasterKey->siSChannelInfo.saEncAlg.cBits / 8) +
4492 ((dwFlags & CRYPT_SERVER) ? pCryptKey->dwBlockLen : 0)),
4493 pCryptKey->dwBlockLen);
4494 break;
4495
4497 *phKey = new_key(hProv, Algid,
4498 MAKELONG(LOWORD(dwFlags),pMasterKey->siSChannelInfo.saMACAlg.cBits),
4499 &pCryptKey);
4500 if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) return FALSE;
4501 memcpy(pCryptKey->abKeyValue,
4502 pCryptHash->abHashValue + ((dwFlags & CRYPT_SERVER) ?
4503 pMasterKey->siSChannelInfo.saMACAlg.cBits / 8 : 0),
4504 pMasterKey->siSChannelInfo.saMACAlg.cBits / 8);
4505 break;
4506
4507 default:
4509 return FALSE;
4510 }
4511 break;
4512
4513 default:
4515 return FALSE;
4516 }
4517
4518 setup_key(pCryptKey);
4519 return TRUE;
4520}
4521
4522/******************************************************************************
4523 * CPGetUserKey (RSAENH.@)
4524 *
4525 * Returns a handle to the user's private key-exchange- or signature-key.
4526 *
4527 * PARAMS
4528 * hProv [I] The key container from which a user key is requested.
4529 * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE
4530 * phUserKey [O] Handle to the requested key or INVALID_HANDLE_VALUE in case of failure.
4531 *
4532 * RETURNS
4533 * Success: TRUE.
4534 * Failure: FALSE.
4535 *
4536 * NOTE
4537 * A newly created key container does not contain private user key. Create them with CPGenKey.
4538 */
4540{
4541 KEYCONTAINER *pKeyContainer;
4542
4543 TRACE("(hProv=%08Ix, dwKeySpec=%08lx, phUserKey=%p)\n", hProv, dwKeySpec, phUserKey);
4544
4545 if (!(pKeyContainer = get_key_container(hProv)))
4546 {
4547 /* MSDN: hProv not containing valid context handle */
4548 return FALSE;
4549 }
4550
4551 switch (dwKeySpec)
4552 {
4553 case AT_KEYEXCHANGE:
4555 phUserKey);
4556 break;
4557
4558 case AT_SIGNATURE:
4560 phUserKey);
4561 break;
4562
4563 default:
4564 *phUserKey = (HCRYPTKEY)INVALID_HANDLE_VALUE;
4565 }
4566
4567 if (*phUserKey == (HCRYPTKEY)INVALID_HANDLE_VALUE)
4568 {
4569 /* MSDN: dwKeySpec parameter specifies nonexistent key */
4571 return FALSE;
4572 }
4573
4574 return TRUE;
4575}
4576
4577/******************************************************************************
4578 * CPHashData (RSAENH.@)
4579 *
4580 * Updates a hash object with the given data.
4581 *
4582 * PARAMS
4583 * hProv [I] Key container to which the hash object belongs.
4584 * hHash [I] Hash object which is to be updated.
4585 * pbData [I] Pointer to data with which the hash object is to be updated.
4586 * dwDataLen [I] Length of the data.
4587 * dwFlags [I] Currently none defined.
4588 *
4589 * RETURNS
4590 * Success: TRUE.
4591 * Failure: FALSE.
4592 *
4593 * NOTES
4594 * The actual hash value is queried with CPGetHashParam, which will finalize
4595 * the hash. Updating a finalized hash will fail with a last error NTE_BAD_HASH_STATE.
4596 */
4598 DWORD dwDataLen, DWORD dwFlags)
4599{
4600 CRYPTHASH *pCryptHash;
4601
4602 TRACE("(hProv=%08Ix, hHash=%08Ix, pbData=%p, dwDataLen=%ld, dwFlags=%08lx)\n",
4603 hProv, hHash, pbData, dwDataLen, dwFlags);
4604
4605 if (dwFlags & ~CRYPT_USERDATA)
4606 {
4608 return FALSE;
4609 }
4610
4612 (OBJECTHDR**)&pCryptHash))
4613 {
4615 return FALSE;
4616 }
4617
4618 if (!get_algid_info(hProv, pCryptHash->aiAlgid) || pCryptHash->aiAlgid == CALG_SSL3_SHAMD5)
4619 {
4621 return FALSE;
4622 }
4623
4624 if (pCryptHash->aiAlgid == CALG_HMAC && !pCryptHash->hash.desc)
4625 {
4627 return FALSE;
4628 }
4629
4630 if (pCryptHash->dwState != RSAENH_HASHSTATE_HASHING)
4631 {
4633 return FALSE;
4634 }
4635
4636 update_hash(pCryptHash, pbData, dwDataLen);
4637 return TRUE;
4638}
4639
4640/******************************************************************************
4641 * CPHashSessionKey (RSAENH.@)
4642 *
4643 * Updates a hash object with the binary representation of a symmetric key.
4644 *
4645 * PARAMS
4646 * hProv [I] Key container to which the hash object belongs.
4647 * hHash [I] Hash object which is to be updated.
4648 * hKey [I] The symmetric key, whose binary value will be added to the hash.
4649 * dwFlags [I] CRYPT_LITTLE_ENDIAN, if the binary key value shall be interpreted as little endian.
4650 *
4651 * RETURNS
4652 * Success: TRUE.
4653 * Failure: FALSE.
4654 */
4656 DWORD dwFlags)
4657{
4658 BYTE abKeyValue[RSAENH_MAX_KEY_SIZE], bTemp;
4659 CRYPTKEY *pKey;
4660 DWORD i;
4661
4662 TRACE("(hProv=%08Ix, hHash=%08Ix, hKey=%08Ix, dwFlags=%08lx)\n", hProv, hHash, hKey, dwFlags);
4663
4666 {
4668 return FALSE;
4669 }
4670
4673 return FALSE;
4674 }
4675
4676 memcpy(abKeyValue, pKey->abKeyValue, pKey->dwKeyLen);
4677 if (!(dwFlags & CRYPT_LITTLE_ENDIAN)) {
4678 for (i=0; i<pKey->dwKeyLen/2; i++) {
4679 bTemp = abKeyValue[i];
4680 abKeyValue[i] = abKeyValue[pKey->dwKeyLen-i-1];
4681 abKeyValue[pKey->dwKeyLen-i-1] = bTemp;
4682 }
4683 }
4684
4685 return RSAENH_CPHashData(hProv, hHash, abKeyValue, pKey->dwKeyLen, 0);
4686}
4687
4688/******************************************************************************
4689 * CPReleaseContext (RSAENH.@)
4690 *
4691 * Release a key container.
4692 *
4693 * PARAMS
4694 * hProv [I] Key container to be released.
4695 * dwFlags [I] Currently none defined.
4696 *
4697 * RETURNS
4698 * Success: TRUE
4699 * Failure: FALSE
4700 */
4702{
4703 TRACE("(hProv=%08Ix, dwFlags=%08lx)\n", hProv, dwFlags);
4704
4706 {
4707 /* MSDN: hProv not containing valid context handle */
4709 return FALSE;
4710 }
4711
4712 if (dwFlags) {
4714 return FALSE;
4715 }
4716
4717 return TRUE;
4718}
4719
4720/******************************************************************************
4721 * CPSetHashParam (RSAENH.@)
4722 *
4723 * Set a parameter of a hash object
4724 *
4725 * PARAMS
4726 * hProv [I] The key container to which the key belongs.
4727 * hHash [I] The hash object for which a parameter is to be set.
4728 * dwParam [I] Parameter type. See Notes.
4729 * pbData [I] Pointer to the parameter value.
4730 * dwFlags [I] Currently none defined.
4731 *
4732 * RETURNS
4733 * Success: TRUE.
4734 * Failure: FALSE.
4735 *
4736 * NOTES
4737 * Currently only the HP_HMAC_INFO dwParam type is defined.
4738 * The HMAC_INFO struct will be deep copied into the hash object.
4739 * See Internet RFC 2104 for details on the HMAC algorithm.
4740 */
4743{
4744 CRYPTHASH *pCryptHash;
4745 CRYPTKEY *pCryptKey;
4746 struct hash inner;
4747 DWORD block_len, i;
4748
4749 TRACE("(hProv=%08Ix, hHash=%08Ix, dwParam=%08lx, pbData=%p, dwFlags=%08lx)\n",
4750 hProv, hHash, dwParam, pbData, dwFlags);
4751
4753 {
4755 return FALSE;
4756 }
4757
4758 if (dwFlags) {
4760 return FALSE;
4761 }
4762
4764 (OBJECTHDR**)&pCryptHash))
4765 {
4767 return FALSE;
4768 }
4769
4770 switch (dwParam) {
4771 case HP_HMAC_INFO:
4772 init_hash_impl(((const HMAC_INFO *)pbData)->HashAlgid, &inner);
4773 if (!inner.desc)
4774 {
4776 return FALSE;
4777 }
4778
4779 block_len = hash_block_len_impl(&inner);
4780
4781 free_hmac_info(pCryptHash->pHMACInfo);
4782 if (!copy_hmac_info(&pCryptHash->pHMACInfo, (PHMAC_INFO)pbData, block_len)) return FALSE;
4783
4784 if (!lookup_handle(&handle_table, pCryptHash->hKey, RSAENH_MAGIC_KEY,
4785 (OBJECTHDR**)&pCryptKey))
4786 {
4787 SetLastError(NTE_FAIL); /* FIXME: correct error code? */
4788 return FALSE;
4789 }
4790
4791 if (pCryptKey->aiAlgid == CALG_HMAC && !pCryptKey->dwKeyLen) {
4792 update_hash_impl(&inner, pCryptKey->blobHmacKey.pbData,
4793 pCryptKey->blobHmacKey.cbData);
4794 pCryptKey->dwKeyLen = hash_len_impl(&inner);
4795 finalize_hash_impl(&inner, pCryptKey->abKeyValue, pCryptKey->dwKeyLen);
4796 }
4797
4798 for (i=0; i<RSAENH_MIN(pCryptKey->dwKeyLen,pCryptHash->pHMACInfo->cbInnerString); i++) {
4799 pCryptHash->pHMACInfo->pbInnerString[i] ^= pCryptKey->abKeyValue[i];
4800 }
4801 for (i=0; i<RSAENH_MIN(pCryptKey->dwKeyLen,pCryptHash->pHMACInfo->cbOuterString); i++) {
4802 pCryptHash->pHMACInfo->pbOuterString[i] ^= pCryptKey->abKeyValue[i];
4803 }
4804
4805 init_hash(pCryptHash);
4806 return TRUE;
4807
4808 case HP_HASHVAL:
4809 memcpy(pCryptHash->abHashValue, pbData, pCryptHash->dwHashSize);
4810 pCryptHash->dwState = RSAENH_HASHSTATE_FINISHED;
4811 return TRUE;
4812
4813 case HP_TLS1PRF_SEED:
4815
4816 case HP_TLS1PRF_LABEL:
4818
4819 default:
4821 return FALSE;
4822 }
4823}
4824
4825/******************************************************************************
4826 * CPSetProvParam (RSAENH.@)
4827 */
4829{
4830 KEYCONTAINER *pKeyContainer;
4831 HKEY hKey;
4832
4833 TRACE("(hProv=%08Ix, dwParam=%08lx, pbData=%p, dwFlags=%08lx)\n", hProv, dwParam, pbData, dwFlags);
4834
4835 if (!(pKeyContainer = get_key_container(hProv)))
4836 return FALSE;
4837
4838 switch (dwParam)
4839 {
4841 {
4843 DWORD err, flags = (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET);
4844 BOOL def, present;
4846 PSID owner = NULL, group = NULL;
4847 PACL dacl = NULL, sacl = NULL;
4848
4849 if (!open_container_key(pKeyContainer->szName, flags, access, &hKey))
4850 {
4852 return FALSE;
4853 }
4854
4858 (dwFlags & SACL_SECURITY_INFORMATION && !GetSecurityDescriptorSacl(sd, &present, &sacl, &def)))
4859 {
4861 return FALSE;
4862 }
4863
4866 if (err)
4867 {
4869 return FALSE;
4870 }
4871 return TRUE;
4872 }
4873 default:
4874 FIXME("unimplemented parameter %08lx\n", dwParam);
4875 return FALSE;
4876 }
4877}
4878
4879/******************************************************************************
4880 * CPSignHash (RSAENH.@)
4881 *
4882 * Sign a hash object
4883 *
4884 * PARAMS
4885 * hProv [I] The key container, to which the hash object belongs.
4886 * hHash [I] The hash object to be signed.
4887 * dwKeySpec [I] AT_SIGNATURE or AT_KEYEXCHANGE: Key used to generate the signature.
4888 * sDescription [I] Should be NULL for security reasons.
4889 * dwFlags [I] 0, CRYPT_NOHASHOID or CRYPT_X931_FORMAT: Format of the signature.
4890 * pbSignature [O] Buffer, to which the signature will be stored. May be NULL to query SigLen.
4891 * pdwSigLen [I/O] Size of the buffer (in), Length of the signature (out)
4892 *
4893 * RETURNS
4894 * Success: TRUE
4895 * Failure: FALSE
4896 */
4898 LPCWSTR sDescription, DWORD dwFlags, BYTE *pbSignature,
4899 DWORD *pdwSigLen)
4900{
4902 CRYPTKEY *pCryptKey;
4903 DWORD dwHashLen;
4904 BYTE abHashValue[RSAENH_MAX_HASH_SIZE];
4905 ALG_ID aiAlgid;
4906 BOOL ret = FALSE;
4907
4908 TRACE("(hProv=%08Ix, hHash=%08Ix, dwKeySpec=%08lx, sDescription=%s, dwFlags=%08lx, "
4909 "pbSignature=%p, pdwSigLen=%p)\n", hProv, hHash, dwKeySpec, debugstr_w(sDescription),
4910 dwFlags, pbSignature, pdwSigLen);
4911
4914 return FALSE;
4915 }
4916
4917 if (!RSAENH_CPGetUserKey(hProv, dwKeySpec, &hCryptKey)) return FALSE;
4918
4920 (OBJECTHDR**)&pCryptKey))
4921 {
4923 goto out;
4924 }
4925
4926 if (!pbSignature) {
4927 *pdwSigLen = pCryptKey->dwKeyLen;
4928 ret = TRUE;
4929 goto out;
4930 }
4931 if (pCryptKey->dwKeyLen > *pdwSigLen)
4932 {
4934 *pdwSigLen = pCryptKey->dwKeyLen;
4935 goto out;
4936 }
4937 *pdwSigLen = pCryptKey->dwKeyLen;
4938
4939 if (sDescription) {
4940 if (!RSAENH_CPHashData(hProv, hHash, (const BYTE*)sDescription,
4941 (DWORD)lstrlenW(sDescription)*sizeof(WCHAR), 0))
4942 {
4943 goto out;
4944 }
4945 }
4946
4947 dwHashLen = sizeof(DWORD);
4948 if (!RSAENH_CPGetHashParam(hProv, hHash, HP_ALGID, (BYTE*)&aiAlgid, &dwHashLen, 0)) goto out;
4949
4950 dwHashLen = RSAENH_MAX_HASH_SIZE;
4951 if (!RSAENH_CPGetHashParam(hProv, hHash, HP_HASHVAL, abHashValue, &dwHashLen, 0)) goto out;
4952
4953 if (!build_hash_signature(pbSignature, *pdwSigLen, aiAlgid, abHashValue, dwHashLen, dwFlags)) {
4954 goto out;
4955 }
4956
4957 ret = sign_hash_impl(&pCryptKey->context, pbSignature, pbSignature);
4958out:
4959 RSAENH_CPDestroyKey(hProv, hCryptKey);
4960 return ret;
4961}
4962
4963/******************************************************************************
4964 * CPVerifySignature (RSAENH.@)
4965 *
4966 * Verify the signature of a hash object.
4967 *
4968 * PARAMS
4969 * hProv [I] The key container, to which the hash belongs.
4970 * hHash [I] The hash for which the signature is verified.
4971 * pbSignature [I] The binary signature.
4972 * dwSigLen [I] Length of the signature BLOB.
4973 * hPubKey [I] Public key used to verify the signature.
4974 * sDescription [I] Should be NULL for security reasons.
4975 * dwFlags [I] 0, CRYPT_NOHASHOID or CRYPT_X931_FORMAT: Format of the signature.
4976 *
4977 * RETURNS
4978 * Success: TRUE (Signature is valid)
4979 * Failure: FALSE (GetLastError() == NTE_BAD_SIGNATURE, if signature is invalid)
4980 */
4982 DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags)
4983{
4984 BYTE *pbConstructed = NULL, *pbDecrypted = NULL;
4985 CRYPTKEY *pCryptKey;
4986 DWORD dwHashLen;
4987 ALG_ID aiAlgid;
4988 BYTE abHashValue[RSAENH_MAX_HASH_SIZE];
4989 BOOL res = FALSE;
4990
4991 TRACE("(hProv=%08Ix, hHash=%08Ix, pbSignature=%p, dwSigLen=%ld, hPubKey=%08Ix, sDescription=%s, "
4992 "dwFlags=%08lx)\n", hProv, hHash, pbSignature, dwSigLen, hPubKey, debugstr_w(sDescription),
4993 dwFlags);
4994
4997 return FALSE;
4998 }
4999
5001 {
5003 return FALSE;
5004 }
5005
5007 (OBJECTHDR**)&pCryptKey))
5008 {
5010 return FALSE;
5011 }
5012
5013 /* in Microsoft implementation, the signature length is checked before
5014 * the signature pointer.
5015 */
5016 if (dwSigLen != pCryptKey->dwKeyLen)
5017 {
5019 return FALSE;
5020 }
5021
5022 if (!hHash || !pbSignature)
5023 {
5025 return FALSE;
5026 }
5027
5028 if (sDescription) {
5029 if (!RSAENH_CPHashData(hProv, hHash, (const BYTE*)sDescription,
5030 (DWORD)lstrlenW(sDescription)*sizeof(WCHAR), 0))
5031 {
5032 return FALSE;
5033 }
5034 }
5035
5036 dwHashLen = sizeof(DWORD);
5037 if (!RSAENH_CPGetHashParam(hProv, hHash, HP_ALGID, (BYTE*)&aiAlgid, &dwHashLen, 0)) return FALSE;
5038
5039 dwHashLen = RSAENH_MAX_HASH_SIZE;
5040 if (!RSAENH_CPGetHashParam(hProv, hHash, HP_HASHVAL, abHashValue, &dwHashLen, 0)) return FALSE;
5041
5042 pbConstructed = malloc(dwSigLen);
5043 if (!pbConstructed) {
5045 goto cleanup;
5046 }
5047
5048 pbDecrypted = malloc(dwSigLen);
5049 if (!pbDecrypted) {
5051 goto cleanup;
5052 }
5053
5054 if (!verify_signature_impl(&pCryptKey->context, pbSignature, pbDecrypted)) goto cleanup;
5055
5056 if (build_hash_signature(pbConstructed, dwSigLen, aiAlgid, abHashValue, dwHashLen, dwFlags) &&
5057 !memcmp(pbDecrypted, pbConstructed, dwSigLen)) {
5058 res = TRUE;
5059 goto cleanup;
5060 }
5061
5062 if (!(dwFlags & CRYPT_NOHASHOID) &&
5063 build_hash_signature(pbConstructed, dwSigLen, aiAlgid, abHashValue, dwHashLen, dwFlags|CRYPT_NOHASHOID) &&
5064 !memcmp(pbDecrypted, pbConstructed, dwSigLen)) {
5065 res = TRUE;
5066 goto cleanup;
5067 }
5068
5070
5071cleanup:
5072 free(pbConstructed);
5073 free(pbDecrypted);
5074 return res;
5075}
@ SE_REGISTRY_KEY
Definition: accctrl.h:163
static DWORD const fdwReason
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static REGSAM sam
Definition: query.c:143
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
alg_id
Definition: bcrypt_main.c:55
#define RegCloseKey(hKey)
Definition: registry.h:49
HINSTANCE hInstance
Definition: charmap.c:19
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4799
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3298
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4009
LONG WINAPI RegCreateKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD Reserved, _In_ LPSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_ LPDWORD lpdwDisposition)
Definition: reg.c:1034
LONG WINAPI RegEnumKeyExA(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2419
LONG WINAPI RegDeleteKeyA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey)
Definition: reg.c:1224
DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo, PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
Definition: misc.c:1295
DWORD WINAPI GetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner, PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl, PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
Definition: misc.c:1244
BOOL WINAPI GetUserNameA(LPSTR lpszName, LPDWORD lpSize)
Definition: misc.c:246
static const WCHAR setup_key[]
Definition: advpack.c:44
BOOL WINAPI CryptUnprotectData(DATA_BLOB *pDataIn, LPWSTR *ppszDataDescr, DATA_BLOB *pOptionalEntropy, PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct, DWORD dwFlags, DATA_BLOB *pDataOut)
Definition: protectdata.c:989
BOOL WINAPI CryptProtectData(DATA_BLOB *pDataIn, LPCWSTR szDataDescr, DATA_BLOB *pOptionalEntropy, PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct, DWORD dwFlags, DATA_BLOB *pDataOut)
Definition: protectdata.c:821
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
#define DLL_PROCESS_DETACH
Definition: compat.h:130
#define lstrcpynA
Definition: compat.h:751
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define MAX_PATH
Definition: compat.h:34
#define lstrlenW
Definition: compat.h:750
static DWORD DWORD * dwLength
Definition: fusion.c:86
static void cleanup(void)
Definition: main.c:1335
BOOL WINAPI DisableThreadLibraryCalls(IN HMODULE hLibModule)
Definition: loader.c:85
DWORD WINAPI GetSecurityDescriptorLength(PSECURITY_DESCRIPTOR descr)
Definition: security.c:1076
BOOL force
Definition: metahost.c:100
#define assert(_expr)
Definition: assert.h:32
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1597
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3324
BOOL lookup_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType, OBJECTHDR **lplpObject)
Definition: handle.c:273
BOOL release_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType)
Definition: handle.c:228
void destroy_handle_table(struct handle_table *lpTable)
Definition: handle.c:70
void init_handle_table(struct handle_table *lpTable)
Definition: handle.c:51
BOOL is_valid_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType)
Definition: handle.c:94
HCRYPTKEY new_object(struct handle_table *lpTable, size_t cbSize, DWORD dwType, DESTRUCTOR destructor, OBJECTHDR **ppObject)
Definition: handle.c:351
BOOL copy_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType, HCRYPTKEY *copy)
Definition: handle.c:308
BOOL WINAPI RSAENH_CPEncrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen)
Definition: rsaenh.c:2599
static BOOL unpad_data_oaep(HCRYPTPROV hProv, const BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, DWORD *dwBufferLen, DWORD dwFlags)
Definition: rsaenh.c:2056
static BOOL build_hash_signature(BYTE *pbSignature, DWORD dwLen, ALG_ID aiAlgid, const BYTE *abHashValue, DWORD dwHashLen, DWORD dwFlags)
Definition: rsaenh.c:1565
BOOL WINAPI RSAENH_CPDecrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen)
Definition: rsaenh.c:2718
#define RSAENH_KEYSTATE_IDLE
Definition: rsaenh.c:47
BOOL WINAPI RSAENH_CPSignHash(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescription, DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen)
Definition: rsaenh.c:4897
BOOL block_encrypt(CRYPTKEY *key, BYTE *data, DWORD *data_len, DWORD buf_len, BOOL final, KEY_CONTEXT *context, BYTE *chain_vector)
Definition: rsaenh.c:525
static const PROV_ENUMALGS_EX * get_algid_info(HCRYPTPROV hProv, ALG_ID algid)
Definition: rsaenh.c:429
static void release_key_container_keys(KEYCONTAINER *pKeyContainer)
Definition: rsaenh.c:1343
static BOOL crypt_export_key(CRYPTKEY *pCryptKey, HCRYPTKEY hPubKey, DWORD dwBlobType, DWORD dwFlags, BOOL force, BYTE *pbData, DWORD *pdwDataLen)
Definition: rsaenh.c:3003
#define RSAENH_MAGIC_HASH
Definition: rsaenh.c:54
BOOL WINAPI RSAENH_CPGenKey(HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKEY *phKey)
Definition: rsaenh.c:3567
static void store_key_permissions(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpec)
Definition: rsaenh.c:1178
BOOL WINAPI RSAENH_CPExportKey(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTKEY hPubKey, DWORD dwBlobType, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen)
Definition: rsaenh.c:3064
static void store_key_container_permissions(KEYCONTAINER *pKeyContainer)
Definition: rsaenh.c:1321
BOOL WINAPI RSAENH_CPGenRandom(HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer)
Definition: rsaenh.c:3663
static BOOL crypt_export_simple(CRYPTKEY *pCryptKey, CRYPTKEY *pPubKey, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen)
Definition: rsaenh.c:2843
BOOL WINAPI RSAENH_CPAcquireContext(HCRYPTPROV *phProv, LPSTR pszContainer, DWORD dwFlags, PVTableProvStruc pVTable)
Definition: rsaenh.c:2193
#define RSAENH_SSL3_VERSION_MINOR
Definition: rsaenh.c:153
static BOOL unpad_data(HCRYPTPROV hProv, const BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, DWORD *dwBufferLen, DWORD dwFlags)
Definition: rsaenh.c:2159
#define RSAENH_3DES112_EFFECTIVE_KEYLEN
Definition: rsaenh.c:145
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID reserved)
Definition: rsaenh.c:350
#define RSAENH_MAGIC_RSA2
Definition: rsaenh.c:149
BOOL WINAPI RSAENH_CPSetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD dwFlags)
Definition: rsaenh.c:3798
BOOL WINAPI RSAENH_CPVerifySignature(HCRYPTPROV hProv, HCRYPTHASH hHash, const BYTE *pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags)
Definition: rsaenh.c:4981
static void free_data_blob(PCRYPT_DATA_BLOB pBlob)
Definition: rsaenh.c:510
BOOL WINAPI RSAENH_CPGetHashParam(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags)
Definition: rsaenh.c:3698
BOOL WINAPI RSAENH_CPDeriveKey(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData, DWORD dwFlags, HCRYPTKEY *phKey)
Definition: rsaenh.c:4355
#define RSAENH_DES_STORAGE_KEYLEN
Definition: rsaenh.c:144
BOOL WINAPI RSAENH_CPSetHashParam(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD dwFlags)
Definition: rsaenh.c:4741
static BOOL pad_data(HCRYPTPROV hProv, const BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, DWORD dwBufferLen, DWORD dwFlags)
Definition: rsaenh.c:1989
static BOOL concat_data_blobs(PCRYPT_DATA_BLOB dst, const PCRYPT_DATA_BLOB src1, const PCRYPT_DATA_BLOB src2)
Definition: rsaenh.c:488
#define RSAENH_KEYSTATE_ENCRYPTING
Definition: rsaenh.c:48
static BOOL pad_data_oaep(HCRYPTPROV hProv, const BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, DWORD dwBufferLen, DWORD dwFlags)
Definition: rsaenh.c:1896
static LPCSTR map_key_spec_to_key_pair_name(DWORD dwKeySpec)
Definition: rsaenh.c:1068
static void release_and_install_key(HCRYPTPROV hProv, HCRYPTKEY src, HCRYPTKEY *dest, DWORD fStoreKey)
Definition: rsaenh.c:3099
#define RSAENH_PERSONALITY_SCHANNEL
Definition: rsaenh.c:119
#define RSAENH_HMAC_DEF_OPAD_CHAR
Definition: rsaenh.c:140
BOOL WINAPI RSAENH_CPGetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags)
Definition: rsaenh.c:4030
#define RSAENH_PERSONALITY_STRONG
Definition: rsaenh.c:117
static BOOL crypt_export_private_key(CRYPTKEY *pCryptKey, BOOL force, BYTE *pbData, DWORD *pdwDataLen)
Definition: rsaenh.c:2916
static HCRYPTKEY new_key(HCRYPTPROV hProv, ALG_ID aiAlgid, DWORD dwFlags, CRYPTKEY **ppCryptKey)
Definition: rsaenh.c:980
BOOL WINAPI RSAENH_CPReleaseContext(HCRYPTPROV hProv, DWORD dwFlags)
Definition: rsaenh.c:4701
BOOL WINAPI RSAENH_CPGetUserKey(HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUserKey)
Definition: rsaenh.c:4539
struct tagKEYCONTAINER KEYCONTAINER
BOOL WINAPI RSAENH_CPDestroyHash(HCRYPTPROV hProv, HCRYPTHASH hHash)
Definition: rsaenh.c:2407
#define RSAENH_3DES112_STORAGE_KEYLEN
Definition: rsaenh.c:146
static BOOL copy_param(BYTE *pbBuffer, DWORD *pdwBufferSize, const BYTE *pbParam, DWORD dwParamSize)
Definition: rsaenh.c:386
#define RSAENH_MAGIC_KEY
Definition: rsaenh.c:44
BOOL WINAPI RSAENH_CPHashSessionKey(HCRYPTPROV hProv, HCRYPTHASH hHash, HCRYPTKEY hKey, DWORD dwFlags)
Definition: rsaenh.c:4655
BOOL WINAPI RSAENH_CPDuplicateKey(HCRYPTPROV hUID, HCRYPTKEY hKey, DWORD *pdwReserved, DWORD dwFlags, HCRYPTKEY *phKey)
Definition: rsaenh.c:2530
static BOOL open_container_key(LPCSTR pszContainerName, DWORD dwFlags, REGSAM access, HKEY *phKey)
Definition: rsaenh.c:1233
static BOOL delete_container_key(LPCSTR pszContainerName, DWORD dwFlags)
Definition: rsaenh.c:1260
struct tagCRYPTHASH CRYPTHASH
#define RSAENH_TLS1_VERSION_MINOR
Definition: rsaenh.c:155
static void destroy_key(OBJECTHDR *pObject)
Definition: rsaenh.c:849
#define RSAENH_SSL3_VERSION_MAJOR
Definition: rsaenh.c:152
static void store_key_container_keys(KEYCONTAINER *pKeyContainer)
Definition: rsaenh.c:1288
static BOOL tls1_prf(HCRYPTPROV hProv, HCRYPTPROV hSecret, const PCRYPT_DATA_BLOB pblobLabel, const PCRYPT_DATA_BLOB pblobSeed, BYTE *pbBuffer, DWORD dwBufferLen)
Definition: rsaenh.c:1720
#define S(s)
Definition: rsaenh.c:164
static BOOL import_plaintext_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, DWORD dwFlags, HCRYPTKEY *phKey)
Definition: rsaenh.c:3392
#define RSAENH_MIN(a, b)
Definition: rsaenh.c:158
static BOOL pad_data_pkcs1(const BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, DWORD dwBufferLen, DWORD dwFlags)
Definition: rsaenh.c:1789
static BOOL create_container_key(KEYCONTAINER *pKeyContainer, REGSAM sam, HKEY *phKey)
Definition: rsaenh.c:1202
#define RSAENH_MAX_KEY_SIZE
Definition: rsaenh.c:45
#define RSAENH_PCT1_SSL2_SSL3_TLS1
Definition: rsaenh.c:163
#define RSAENH_MAGIC_CONTAINER
Definition: rsaenh.c:122
#define RSAENH_PERSONALITY_AES
Definition: rsaenh.c:120
#define RSAENH_REGKEY
Definition: rsaenh.c:156
static KEYCONTAINER * get_key_container(HCRYPTPROV hProv)
Definition: rsaenh.c:403
#define RSAENH_DES_EFFECTIVE_KEYLEN
Definition: rsaenh.c:143
#define RSAENH_MAX_ENUMALGS
Definition: rsaenh.c:162
static BOOL import_private_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, DWORD dwFlags, BOOL fStoreKey, HCRYPTKEY *phKey)
Definition: rsaenh.c:3139
static BOOL tls1_p(HCRYPTHASH hHMAC, const PCRYPT_DATA_BLOB pblobSeed, BYTE *pbBuffer, DWORD dwBufferLen)
Definition: rsaenh.c:1661
#define RSAENH_HASHSTATE_FINISHED
Definition: rsaenh.c:56
struct tagCRYPTKEY CRYPTKEY
BOOL WINAPI RSAENH_CPCreateHash(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, DWORD dwFlags, HCRYPTHASH *phHash)
Definition: rsaenh.c:2276
#define RSAENH_MAX_BLOCK_SIZE
Definition: rsaenh.c:46
static BOOL copy_hmac_info(PHMAC_INFO *dst, const HMAC_INFO *src, DWORD block_len)
Definition: rsaenh.c:620
static BOOL pkcs1_mgf1(HCRYPTPROV hProv, const BYTE *pbSeed, DWORD dwSeedLength, DWORD dwLength, PCRYPT_DATA_BLOB pbMask)
Definition: rsaenh.c:1829
BOOL WINAPI RSAENH_CPSetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD dwFlags)
Definition: rsaenh.c:4828
static const PROV_ENUMALGS_EX aProvEnumAlgsEx[5][RSAENH_MAX_ENUMALGS+1]
Definition: rsaenh.c:165
static BOOL copy_data_blob(PCRYPT_DATA_BLOB dst, const PCRYPT_DATA_BLOB src)
Definition: rsaenh.c:459
#define RSAENH_PERSONALITY_BASE
Definition: rsaenh.c:116
BOOL WINAPI RSAENH_CPDuplicateHash(HCRYPTPROV hUID, HCRYPTHASH hHash, DWORD *pdwReserved, DWORD dwFlags, HCRYPTHASH *phHash)
Definition: rsaenh.c:2475
static HCRYPTPROV read_key_container(PCHAR pszContainerName, DWORD dwFlags, const VTableProvStruc *pVTable)
Definition: rsaenh.c:1508
static BOOL unpad_data_pkcs1(const BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, DWORD *dwBufferLen, DWORD dwFlags)
Definition: rsaenh.c:2014
static HCRYPTPROV new_key_container(PCCH pszContainerName, DWORD dwFlags, const VTableProvStruc *pVTable)
Definition: rsaenh.c:1388
BOOL WINAPI RSAENH_CPGetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags)
Definition: rsaenh.c:4137
#define RSAENH_3DES_STORAGE_KEYLEN
Definition: rsaenh.c:148
#define RSAENH_TLS1_VERSION_MAJOR
Definition: rsaenh.c:154
static BOOL import_public_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, DWORD dwFlags, HCRYPTKEY *phKey)
Definition: rsaenh.c:3231
static HCRYPTKEY alloc_key(HCRYPTPROV hprov, ALG_ID alg_id, DWORD flags, DWORD key_len, CRYPTKEY **ret_key)
Definition: rsaenh.c:880
BOOL WINAPI RSAENH_CPImportKey(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey)
Definition: rsaenh.c:3536
#define RSAENH_HMAC_BLOCK_LEN
Definition: rsaenh.c:142
BOOL WINAPI RSAENH_CPDestroyKey(HCRYPTPROV hProv, HCRYPTKEY hKey)
Definition: rsaenh.c:2440
static void destroy_hash(OBJECTHDR *pObject)
Definition: rsaenh.c:659
static void finalize_hash(CRYPTHASH *pCryptHash)
Definition: rsaenh.c:800
#define RSAENH_KEYSTATE_MASTERKEY
Definition: rsaenh.c:49
#define RSAENH_3DES_EFFECTIVE_KEYLEN
Definition: rsaenh.c:147
static void update_hash(CRYPTHASH *pCryptHash, const BYTE *pbData, DWORD dwDataLen)
Definition: rsaenh.c:722
static BOOL crypt_export_public_key(CRYPTKEY *pCryptKey, BYTE *pbData, DWORD *pdwDataLen)
Definition: rsaenh.c:2882
static BOOL import_symmetric_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey)
Definition: rsaenh.c:3294
static BOOL init_hash(CRYPTHASH *pCryptHash)
Definition: rsaenh.c:679
static BOOL import_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, BOOL fStoreKey, HCRYPTKEY *phKey)
Definition: rsaenh.c:3470
#define RSAENH_MAGIC_RSA1
Definition: rsaenh.c:150
#define RSAENH_HMAC_DEF_IPAD_CHAR
Definition: rsaenh.c:139
static void init_data_blob(PCRYPT_DATA_BLOB pBlob)
Definition: rsaenh.c:517
static void free_hmac_info(PHMAC_INFO hmac_info)
Definition: rsaenh.c:597
static BOOL read_key_value(HCRYPTPROV hKeyContainer, HKEY hKey, DWORD dwKeySpec, DWORD dwFlags, HCRYPTKEY *phCryptKey)
Definition: rsaenh.c:1443
static LPCSTR map_key_spec_to_permissions_name(DWORD dwKeySpec)
Definition: rsaenh.c:1149
#define RSAENH_HMAC_DEF_PAD_LEN
Definition: rsaenh.c:141
#define RSAENH_HASHSTATE_HASHING
Definition: rsaenh.c:55
static BOOL crypt_export_plaintext_key(CRYPTKEY *pCryptKey, BYTE *pbData, DWORD *pdwDataLen)
Definition: rsaenh.c:2955
struct _RSAENH_TLS1PRF_PARAMS RSAENH_TLS1PRF_PARAMS
static void store_key_pair(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpec, DWORD dwFlags)
Definition: rsaenh.c:1098
static void destroy_key_container(OBJECTHDR *pObjectHdr)
Definition: rsaenh.c:1359
struct _RSAENH_SCHANNEL_INFO RSAENH_SCHANNEL_INFO
#define RSAENH_PKC_BLOCKTYPE
Definition: rsaenh.c:151
#define RSAENH_PERSONALITY_ENHANCED
Definition: rsaenh.c:118
BOOL WINAPI RSAENH_CPHashData(HCRYPTPROV hProv, HCRYPTHASH hHash, const BYTE *pbData, DWORD dwDataLen, DWORD dwFlags)
Definition: rsaenh.c:4597
return ret
Definition: mutex.c:147
r reserved
Definition: btrfs.c:3006
static const uint32_t k[]
Definition: sha256.c:24
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
FxObject * pObject
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLuint in
Definition: glext.h:9616
GLenum GLenum dst
Definition: glext.h:6340
GLboolean GLuint group
Definition: glext.h:11120
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
GLuint64EXT * result
Definition: glext.h:11304
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
BOOL import_public_key_impl(ALG_ID algid, const BYTE *src, DWORD keylen, DWORD pubexp, KEY_CONTEXT *ctx)
Definition: implglue.c:470
BOOL new_key_impl(ALG_ID algid, KEY_CONTEXT *ctx, DWORD keylen)
Definition: implglue.c:95
BOOL sign_hash_impl(KEY_CONTEXT *ctx, const BYTE *in, BYTE *out)
Definition: implglue.c:426
BOOL setup_key_impl(ALG_ID algid, KEY_CONTEXT *ctx, DWORD keylen, DWORD effective_keylen, DWORD saltlen, const BYTE *secret)
Definition: implglue.c:147
BOOL free_key_impl(ALG_ID algid, KEY_CONTEXT *ctx)
Definition: implglue.c:129
BOOL export_public_key_impl(const KEY_CONTEXT *ctx, BYTE *dst, DWORD *pubexp)
Definition: implglue.c:450
BOOL duplicate_key_impl(ALG_ID algid, const KEY_CONTEXT *src, KEY_CONTEXT *dst)
Definition: implglue.c:183
BOOL import_private_key_impl(ALG_ID algid, const BYTE *src, DWORD keylen, DWORD pubexp, KEY_CONTEXT *ctx)
Definition: implglue.c:533
BOOL init_hash_impl(ALG_ID algid, struct hash *hash)
Definition: implglue.c:63
BOOL decrypt_block_impl(ALG_ID algid, KEY_CONTEXT *ctx, const BYTE *in, BYTE *out)
Definition: implglue.c:395
BOOL encrypt_block_impl(ALG_ID algid, KEY_CONTEXT *ctx, const BYTE *in, BYTE *out)
Definition: implglue.c:301
BOOL export_private_key_impl(const KEY_CONTEXT *ctx, BYTE *dst, DWORD *pubexp)
Definition: implglue.c:493
BOOL verify_signature_impl(KEY_CONTEXT *ctx, const BYTE *in, BYTE *out)
Definition: implglue.c:431
BOOL encrypt_stream_impl(ALG_ID algid, KEY_CONTEXT *ctx, BYTE *stream, DWORD len)
Definition: implglue.c:436
static DWORD hash_len_impl(const struct hash *hash)
Definition: implglue.h:66
#define RSAENH_MAX_HASH_SIZE
Definition: implglue.h:30
static void update_hash_impl(struct hash *hash, const BYTE *data, DWORD len)
Definition: implglue.h:56
static void finalize_hash_impl(struct hash *hash, BYTE *hash_value, DWORD hash_size)
Definition: implglue.h:61
static DWORD hash_block_len_impl(const struct hash *hash)
Definition: implglue.h:71
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define sprintf
Definition: sprintf.c:45
DWORD dwCounter
Definition: mutex.c:10
static const WCHAR sd[]
Definition: suminfo.c:432
static char * dest
Definition: rtl.c:149
static HCRYPTPROV hProv
Definition: rsaenh.c:33
#define min(a, b)
Definition: monoChain.cc:55
algid
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
#define WRITE_DAC
Definition: nt_native.h:59
#define REG_BINARY
Definition: nt_native.h:1499
#define ACCESS_SYSTEM_SECURITY
Definition: nt_native.h:77
#define KEY_READ
Definition: nt_native.h:1026
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1060
#define KEY_WRITE
Definition: nt_native.h:1034
#define WRITE_OWNER
Definition: nt_native.h:60
#define DWORD
Definition: nt_native.h:44
CONST CHAR * PCCH
Definition: ntbasedef.h:404
#define LOWORD(l)
Definition: pedump.c:82
short WCHAR
Definition: pedump.c:58
char CHAR
Definition: pedump.c:57
#define RtlGenRandom
Definition: ntsecapi.h:691
#define err(...)
#define REG_DWORD
Definition: sdbapi.c:615
#define exit(n)
Definition: config.h:202
#define memset(x, y, z)
Definition: compat.h:39
BOOL WINAPI GetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID *pGroup, LPBOOL lpbGroupDefaulted)
Definition: sec.c:76
BOOL WINAPI GetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, LPBOOL lpbSaclPresent, PACL *pSacl, LPBOOL lpbSaclDefaulted)
Definition: sec.c:146
BOOL WINAPI GetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, LPBOOL lpbDaclPresent, PACL *pDacl, LPBOOL lpbDaclDefaulted)
Definition: sec.c:45
BOOL WINAPI GetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID *pOwner, LPBOOL lpbOwnerDefaulted)
Definition: sec.c:103
#define TRACE(s)
Definition: solgame.cpp:4
BYTE * pbData
Definition: wincrypt.h:112
DWORD cbInnerString
Definition: wincrypt.h:105
BYTE * pbOuterString
Definition: wincrypt.h:106
DWORD cbOuterString
Definition: wincrypt.h:107
BYTE * pbInnerString
Definition: wincrypt.h:104
ALG_ID HashAlgid
Definition: wincrypt.h:103
CHAR szName[20]
Definition: wincrypt.h:83
DWORD dwDefaultLen
Definition: wincrypt.h:78
ALG_ID aiAlgid
Definition: wincrypt.h:77
DWORD dwNameLen
Definition: wincrypt.h:72
DWORD dwBitLen
Definition: wincrypt.h:71
ALG_ID aiAlgid
Definition: wincrypt.h:70
CHAR szName[20]
Definition: wincrypt.h:73
ALG_ID aiKeyAlg
Definition: wincrypt.h:148
SCHANNEL_ALG saMACAlg
Definition: rsaenh.c:87
CRYPT_DATA_BLOB blobServerRandom
Definition: rsaenh.c:89
CRYPT_DATA_BLOB blobClientRandom
Definition: rsaenh.c:88
SCHANNEL_ALG saEncAlg
Definition: rsaenh.c:86
CRYPT_DATA_BLOB blobSeed
Definition: rsaenh.c:60
CRYPT_DATA_BLOB blobLabel
Definition: rsaenh.c:59
DWORD pubexp
Definition: wincrypt.h:154
DWORD bitlen
Definition: wincrypt.h:153
DWORD magic
Definition: wincrypt.h:152
LPSTR pszProvName
Definition: wincrypt.h:820
Definition: image.c:229
Definition: http.c:7783
Definition: security.c:35
const SYMCRYPT_HASH * desc
Definition: bcrypt_main.c:111
Definition: copy.c:22
ALG_ID key_alg_id
Definition: rsaenh.c:76
BYTE abHashValue[RSAENH_MAX_HASH_SIZE]
Definition: rsaenh.c:72
BYTE abChainVector[RSAENH_MAX_BLOCK_SIZE]
Definition: rsaenh.c:78
RSAENH_TLS1PRF_PARAMS tpPRFParams
Definition: rsaenh.c:74
PHMAC_INFO pHMACInfo
Definition: rsaenh.c:73
OBJECTHDR header
Definition: rsaenh.c:65
DWORD dwHashSize
Definition: rsaenh.c:69
KEY_CONTEXT key_context
Definition: rsaenh.c:77
ALG_ID aiAlgid
Definition: rsaenh.c:66
DWORD buffered_hash_bytes
Definition: rsaenh.c:75
HCRYPTPROV hProv
Definition: rsaenh.c:68
HCRYPTKEY hKey
Definition: rsaenh.c:67
struct hash hash
Definition: rsaenh.c:71
DWORD dwState
Definition: rsaenh.c:70
CRYPT_DATA_BLOB blobHmacKey
Definition: rsaenh.c:110
RSAENH_SCHANNEL_INFO siSChannelInfo
Definition: rsaenh.c:109
DWORD dwMode
Definition: rsaenh.c:97
DWORD dwEffectiveKeyLen
Definition: rsaenh.c:101
BYTE abInitVector[RSAENH_MAX_BLOCK_SIZE]
Definition: rsaenh.c:107
OBJECTHDR header
Definition: rsaenh.c:94
ALG_ID aiAlgid
Definition: rsaenh.c:95
DWORD dwPermissions
Definition: rsaenh.c:99
KEY_CONTEXT context
Definition: rsaenh.c:105
DWORD dwState
Definition: rsaenh.c:104
BYTE abKeyValue[RSAENH_MAX_KEY_SIZE]
Definition: rsaenh.c:106
DWORD dwSaltLen
Definition: rsaenh.c:102
DWORD dwModeBits
Definition: rsaenh.c:98
DWORD dwKeyLen
Definition: rsaenh.c:100
DWORD dwBlockLen
Definition: rsaenh.c:103
BYTE abChainVector[RSAENH_MAX_BLOCK_SIZE]
Definition: rsaenh.c:108
HCRYPTPROV hProv
Definition: rsaenh.c:96
OBJECTHDR header
Definition: rsaenh.c:125
CHAR szName[MAX_PATH]
Definition: rsaenh.c:130
DWORD dwEnumAlgsCtr
Definition: rsaenh.c:128
CHAR szProvName[MAX_PATH]
Definition: rsaenh.c:131
DWORD dwFlags
Definition: rsaenh.c:126
DWORD dwPersonality
Definition: rsaenh.c:127
HCRYPTKEY hSignatureKeyPair
Definition: rsaenh.c:133
HCRYPTKEY hKeyExchangeKeyPair
Definition: rsaenh.c:132
DWORD dwEnumContainersCtr
Definition: rsaenh.c:129
VOID SYMCRYPT_CALL SymCryptInit(void)
PCBYTE pbKey
PCSYMCRYPT_HMAC_MD5_EXPANDED_KEY pKey
PCBYTE pbData
PBYTE pbSeed
const char * LPCSTR
Definition: typedefs.h:52
const uint16_t * LPCWSTR
Definition: typedefs.h:57
char * LPSTR
Definition: typedefs.h:51
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define HIWORD(l)
Definition: typedefs.h:247
char * PCHAR
Definition: typedefs.h:51
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
#define PLAINTEXTKEYBLOB
Definition: wincrypt.h:2446
#define PP_KEYSET_SEC_DESCR
Definition: wincrypt.h:2293
#define CALG_PCT1_MASTER
Definition: wincrypt.h:2101
#define MS_DEF_PROV_A
Definition: wincrypt.h:2115
#define MS_ENH_RSA_AES_PROV_XP_A
Definition: wincrypt.h:2227
#define PP_KEYSTORAGE
Definition: wincrypt.h:2301
#define ALG_CLASS_MSG_ENCRYPT
Definition: wincrypt.h:1969
#define CALG_RC2
Definition: wincrypt.h:2083
#define CRYPT_USERDATA
Definition: wincrypt.h:4336
#define KP_BLOCKLEN
Definition: wincrypt.h:2339
#define CRYPT_NEWKEYSET
Definition: wincrypt.h:2274
#define CRYPTPROTECT_LOCAL_MACHINE
Definition: wincrypt.h:2432
#define HP_HASHSIZE
Definition: wincrypt.h:2388
#define KP_MODE
Definition: wincrypt.h:2335
#define HP_ALGID
Definition: wincrypt.h:2386
#define PROV_RSA_FULL
Definition: wincrypt.h:2243
#define CRYPT_VERIFYCONTEXT
Definition: wincrypt.h:2273
#define CALG_AES_128
Definition: wincrypt.h:2087
#define CALG_SHA1
Definition: wincrypt.h:2060
#define PROV_RSA_SCHANNEL
Definition: wincrypt.h:2249
#define KP_IV
Definition: wincrypt.h:2332
#define PP_ENUMALGS_EX
Definition: wincrypt.h:2305
#define CRYPT_DECRYPT
Definition: wincrypt.h:2400
#define CALG_SCHANNEL_MASTER_HASH
Definition: wincrypt.h:2098
#define CRYPT_FLAG_SIGNING
Definition: wincrypt.h:2112
#define CALG_AES_192
Definition: wincrypt.h:2088
#define CALG_RSA_SIGN
Definition: wincrypt.h:2069
#define CRYPT_MODE_CBC
Definition: wincrypt.h:2394
ULONG_PTR HCRYPTPROV
Definition: wincrypt.h:55
#define CALG_SSL2_MASTER
Definition: wincrypt.h:2102
#define CRYPT_X931_FORMAT
Definition: wincrypt.h:2383
#define HP_TLS1PRF_SEED
Definition: wincrypt.h:2391
#define CALG_SHA_384
Definition: wincrypt.h:2067
#define CALG_RC4
Definition: wincrypt.h:2091
#define KP_SALT
Definition: wincrypt.h:2333
#define KP_SCHANNEL_ALG
Definition: wincrypt.h:2351
#define CALG_MD5
Definition: wincrypt.h:2058
#define ALG_CLASS_DATA_ENCRYPT
Definition: wincrypt.h:1970
#define CRYPT_FLAG_PCT1
Definition: wincrypt.h:2107
#define PP_KEYSET_TYPE
Definition: wincrypt.h:2309
#define PROV_RSA_AES
Definition: wincrypt.h:2260
unsigned int ALG_ID
Definition: wincrypt.h:54
#define KP_CLIENT_RANDOM
Definition: wincrypt.h:2352
#define KP_SERVER_RANDOM
Definition: wincrypt.h:2353
#define CRYPT_FLAG_SSL2
Definition: wincrypt.h:2108
#define CALG_MAC
Definition: wincrypt.h:2061
#define CRYPT_FLAG_TLS1
Definition: wincrypt.h:2110
#define CALG_SHA_256
Definition: wincrypt.h:2066
#define CRYPT_FLAG_SSL3
Definition: wincrypt.h:2109
#define KP_PADDING
Definition: wincrypt.h:2334
#define CRYPT_DELETEKEYSET
Definition: wincrypt.h:2275
#define PRIVATEKEYBLOB
Definition: wincrypt.h:2445
#define CRYPT_EXPORT
Definition: wincrypt.h:2401
#define CRYPT_NOHASHOID
Definition: wincrypt.h:2381
#define PP_KEYSPEC
Definition: wincrypt.h:2318
#define CALG_MD2
Definition: wincrypt.h:2056
#define AT_KEYEXCHANGE
Definition: wincrypt.h:2239
#define CALG_3DES_112
Definition: wincrypt.h:2085
#define PP_ENUMCONTAINERS
Definition: wincrypt.h:2287
#define CRYPT_CREATE_SALT
Definition: wincrypt.h:2412
#define CALG_SCHANNEL_MAC_KEY
Definition: wincrypt.h:2099
#define HP_TLS1PRF_LABEL
Definition: wincrypt.h:2390
#define CRYPT_ENCRYPT
Definition: wincrypt.h:2399
#define PUBLICKEYBLOB
Definition: wincrypt.h:2444
#define PP_ENUMALGS
Definition: wincrypt.h:2286
#define PP_VERSION
Definition: wincrypt.h:2290
#define CRYPT_SERVER
Definition: wincrypt.h:2416
#define CRYPT_MODE_ECB
Definition: wincrypt.h:2395
#define CALG_SSL3_MASTER
Definition: wincrypt.h:2097
#define KP_EFFECTIVE_KEYLEN
Definition: wincrypt.h:2350
#define CRYPT_FIRST
Definition: wincrypt.h:2264
#define ALG_TYPE_RSA
Definition: wincrypt.h:1977
#define KP_ALGID
Definition: wincrypt.h:2338
#define CALG_RSA_KEYX
Definition: wincrypt.h:2080
#define KP_MODE_BITS
Definition: wincrypt.h:2336
#define CALG_AES_256
Definition: wincrypt.h:2089
#define SCHANNEL_ENC_KEY
Definition: wincrypt.h:89
#define PP_UNIQUE_CONTAINER
Definition: wincrypt.h:2315
#define PP_NAME
Definition: wincrypt.h:2289
#define SIMPLEBLOB
Definition: wincrypt.h:2443
#define HP_HMAC_INFO
Definition: wincrypt.h:2389
ULONG_PTR HCRYPTKEY
Definition: wincrypt.h:58
#define PP_SIG_KEYSIZE_INC
Definition: wincrypt.h:2313
ULONG_PTR HCRYPTHASH
Definition: wincrypt.h:59
#define CALG_3DES
Definition: wincrypt.h:2084
#define GET_ALG_TYPE(x)
Definition: wincrypt.h:1963
#define CALG_MD4
Definition: wincrypt.h:2057
#define PP_KEYX_KEYSIZE_INC
Definition: wincrypt.h:2314
#define PKCS5_PADDING
Definition: wincrypt.h:2376
#define CRYPT_SEC_DESCR
Definition: wincrypt.h:2327
#define SCHANNEL_MAC_KEY
Definition: wincrypt.h:88
#define CALG_SSL3_SHAMD5
Definition: wincrypt.h:2062
#define CALG_SHA
Definition: wincrypt.h:2059
struct _PUBLICKEYSTRUC BLOBHEADER
#define CALG_TLS1PRF
Definition: wincrypt.h:2064
#define PP_IMPTYPE
Definition: wincrypt.h:2288
#define MS_DEF_RSA_SCHANNEL_PROV_A
Definition: wincrypt.h:2155
#define CRYPT_WRITE
Definition: wincrypt.h:2403
#define CRYPT_OAEP
Definition: wincrypt.h:2422
#define PP_CONTAINER
Definition: wincrypt.h:2291
#define CRYPT_READ
Definition: wincrypt.h:2402
#define GET_ALG_CLASS(x)
Definition: wincrypt.h:1962
#define CALG_DES
Definition: wincrypt.h:2082
#define PP_PROVTYPE
Definition: wincrypt.h:2300
#define MS_ENHANCED_PROV_A
Definition: wincrypt.h:2125
#define KP_KEYLEN
Definition: wincrypt.h:2340
#define CRYPT_IMPL_SOFTWARE
Definition: wincrypt.h:2268
#define AT_SIGNATURE
Definition: wincrypt.h:2240
#define CRYPT_MAC
Definition: wincrypt.h:2404
#define ALG_TYPE_BLOCK
Definition: wincrypt.h:1978
#define CRYPT_MODE_CFB
Definition: wincrypt.h:2397
#define KP_PERMISSIONS
Definition: wincrypt.h:2337
#define CALG_TLS1_MASTER
Definition: wincrypt.h:2103
#define CALG_SHA_512
Definition: wincrypt.h:2068
#define CRYPT_SSL2_FALLBACK
Definition: wincrypt.h:2420
#define KP_SALT_EX
Definition: wincrypt.h:2341
#define CRYPT_LITTLE_ENDIAN
Definition: wincrypt.h:2425
#define CRYPT_IPSEC_HMAC_KEY
Definition: wincrypt.h:100
#define PP_CRYPT_COUNT_KEY_USE
Definition: wincrypt.h:2320
#define ALG_TYPE_STREAM
Definition: wincrypt.h:1979
#define CALG_SCHANNEL_ENC_KEY
Definition: wincrypt.h:2100
#define CALG_HMAC
Definition: wincrypt.h:2063
#define HP_HASHVAL
Definition: wincrypt.h:2387
#define CRYPT_EXPORTABLE
Definition: wincrypt.h:2410
#define CRYPT_MACHINE_KEYSET
Definition: wincrypt.h:2276
#define CRYPT_NO_SALT
Definition: wincrypt.h:2414
#define CRYPT_FLAG_IPSEC
Definition: wincrypt.h:2111
#define MS_ENH_RSA_AES_PROV_A
Definition: wincrypt.h:2217
#define CUR_BLOB_VERSION
Definition: wincrypt.h:2451
#define WINAPI
Definition: msvc.h:6
#define NTE_BAD_DATA
Definition: winerror.h:4252
#define NTE_BAD_ALGID
Definition: winerror.h:4255
#define NTE_BAD_UID
Definition: winerror.h:4245
#define NTE_NO_KEY
Definition: winerror.h:4260
#define NTE_FAIL
Definition: winerror.h:4279
#define NTE_BAD_HASH_STATE
Definition: winerror.h:4259
#define NTE_BAD_PUBLIC_KEY
Definition: winerror.h:4268
#define NTE_BAD_LEN
Definition: winerror.h:4251
#define NTE_BAD_SIGNATURE
Definition: winerror.h:4253
#define NTE_BAD_KEY
Definition: winerror.h:4249
#define NTE_EXISTS
Definition: winerror.h:4262
#define NTE_BAD_KEYSET
Definition: winerror.h:4269
#define NTE_BAD_TYPE
Definition: winerror.h:4257
#define NTE_BAD_HASH
Definition: winerror.h:4247
#define NTE_BAD_FLAGS
Definition: winerror.h:4256
#define NTE_BAD_KEY_STATE
Definition: winerror.h:4258
#define NTE_NO_MEMORY
Definition: winerror.h:4261
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
ACCESS_MASK REGSAM
Definition: winreg.h:76
#define DACL_SECURITY_INFORMATION
Definition: setypes.h:125
#define OWNER_SECURITY_INFORMATION
Definition: setypes.h:123
#define GROUP_SECURITY_INFORMATION
Definition: setypes.h:124
#define SACL_SECURITY_INFORMATION
Definition: setypes.h:126
unsigned char BYTE
Definition: xxhash.c:193