ReactOS 0.4.17-dev-804-g023d8af
bcrypt_main.c
Go to the documentation of this file.
1/*
2 * Copyright 2009 Henri Verbeet for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 *
18 */
19
20#ifndef __REACTOS__
21#include <wine/config.h>
22#include <wine/port.h>
23
24#include <ntstatus.h>
25#define WIN32_NO_STATUS
26#include <windef.h>
27#include <winbase.h>
28#include <ntsecapi.h>
29#include <bcrypt.h>
30
31#include <wine/debug.h>
32#include <wine/unicode.h>
33#include <wine/library.h>
34
35#ifdef SONAME_LIBMBEDTLS
36#include <mbedtls/md.h>
37#include <mbedtls/md5.h>
38#include <mbedtls/sha1.h>
39#include <mbedtls/sha256.h>
40#include <mbedtls/sha512.h>
41#endif
42#else
43#include "precomp.h"
44#endif
45
47
49
51{
52 FIXME( "%#lx, %s, %#lx, %s, %lu: stub\n", table, debugstr_w(ctx), iface, debugstr_w(func), pos );
53 return STATUS_SUCCESS;
54}
55
57 const WCHAR *provider, ULONG pos )
58{
59 FIXME( "%#lx, %s, %#lx, %s, %s, %lu: stub\n", table, debugstr_w(ctx), iface, debugstr_w(func),
60 debugstr_w(provider), pos );
61 return STATUS_SUCCESS;
62}
63
65{
66 FIXME( "%#lx, %s, %#lx, %s: stub\n", table, debugstr_w(ctx), iface, debugstr_w(func) );
68}
69
71 const WCHAR *provider )
72{
73 FIXME( "%#lx, %s, %#lx, %s, %s: stub\n", table, debugstr_w(ctx), iface, debugstr_w(func), debugstr_w(provider) );
75}
76
79{
80 FIXME( "%#lx, %s, %#lx, %p, %p\n", table, debugstr_w(ctx), iface, buflen, buffer );
82}
83
85{
86 free( buffer );
87}
88
90{
91 FIXME( "%s, %#lx, %p: stub\n", debugstr_w(provider), flags, reg );
92 return STATUS_SUCCESS;
93}
94
96{
97 FIXME( "%s: stub\n", debugstr_w(provider) );
99}
100
101#define MAX_HASH_OUTPUT_BYTES 64
102#define MAX_HASH_BLOCK_BITS 1024
103
104/* ordered by class, keep in sync with enum alg_id */
105static const struct
106{
107 const WCHAR *name;
108 ULONG class;
112}
114{
136
137static inline BOOL is_symmetric_key( const struct key *key )
138{
141}
142
143static inline BOOL is_asymmetric_encryption_key( struct key *key )
144{
146}
147
148static inline BOOL is_agreement_key( struct key *key )
149{
151}
152
153static inline BOOL is_signature_key( struct key *key )
154{
156}
157
159{
160 if (!type) return TRUE;
161 switch (class)
162 {
170 default: break;
171 }
172 return FALSE;
173}
174
176{
177 static const ULONG supported = BCRYPT_CIPHER_OPERATION |\
185 ULONG i, j, count = 0;
186
187 TRACE( "%#lx, %p, %p, %#lx\n", type, ret_count, ret_list, flags );
188
189 if (!ret_count || !ret_list || (type & ~supported)) return STATUS_INVALID_PARAMETER;
190
191 for (i = 0; i < ARRAY_SIZE( builtin_algorithms ); i++)
192 {
194 }
195
196 if (!(list = malloc( count * sizeof(*list) ))) return STATUS_NO_MEMORY;
197
198 for (i = 0, j = 0; i < ARRAY_SIZE( builtin_algorithms ); i++)
199 {
200 if (!match_operation_type( type, builtin_algorithms[i].class )) continue;
201 list[j].pszName = (WCHAR *)builtin_algorithms[i].name;
202 list[j].dwClass = builtin_algorithms[i].class;
203 list[j].dwFlags = 0;
204 j++;
205 }
206
207 *ret_count = count;
208 *ret_list = list;
209 return STATUS_SUCCESS;
210}
211
212static const struct algorithm pseudo_algorithms[] =
213{
214 {{ MAGIC_ALG }, ALG_ID_MD2 },
215 {{ MAGIC_ALG }, ALG_ID_MD4 },
216 {{ MAGIC_ALG }, ALG_ID_MD5 },
217 {{ MAGIC_ALG }, ALG_ID_SHA1 },
218 {{ MAGIC_ALG }, ALG_ID_SHA256 },
219 {{ MAGIC_ALG }, ALG_ID_SHA384 },
220 {{ MAGIC_ALG }, ALG_ID_SHA512 },
221 {{ MAGIC_ALG }, ALG_ID_RC4 },
222 {{ MAGIC_ALG }, ALG_ID_RNG },
228 {{ MAGIC_ALG }, ALG_ID_RSA },
229 {{ 0 }}, /* ECDSA */
230 {{ 0 }}, /* AES_CMAC */
231 {{ 0 }}, /* AES_GMAC */
237 {{ 0 }}, /* 3DES_112_CBC */
238 {{ 0 }}, /* 3DES_112_ECB */
239 {{ 0 }}, /* 3DES_112_CFB */
245 {{ 0 }}, /* DES_CBC */
246 {{ 0 }}, /* DES_ECB */
247 {{ 0 }}, /* DES_CFB */
248 {{ 0 }}, /* DESX_CBC */
249 {{ 0 }}, /* DESX_ECB */
250 {{ 0 }}, /* DESX_CFB */
251 {{ 0 }}, /* RC2_CBC */
252 {{ 0 }}, /* RC2_ECB */
253 {{ 0 }}, /* RC2_CFB */
254 {{ MAGIC_ALG }, ALG_ID_DH },
255 {{ 0 }}, /* ECDH */
258 {{ 0 }}, /* ECDH_P512 */
259 {{ MAGIC_ALG }, ALG_ID_DSA },
262 {{ 0 }}, /* ECDSA_P512 */
264};
265
266/* Algorithm pseudo-handles are denoted by having the lowest bit set.
267 * An aligned algorithm pointer will never have this bit set.
268 */
270{
271 return (((ULONG_PTR)handle & 1) == 1);
272}
273
275{
276 ULONG idx;
277
278 if (!handle) return NULL;
279
281 {
282 struct object *obj = handle;
283 if (magic && obj->magic != magic) return NULL;
284 return obj;
285 }
286
287 idx = (ULONG_PTR)handle >> 4;
289 {
290 FIXME( "pseudo-handle %p not supported\n", handle );
291 return NULL;
292 }
293 return (struct object *)&pseudo_algorithms[idx];
294}
295
297{
298 return (struct algorithm *)get_object( handle, MAGIC_ALG );
299}
300
302{
303 return (struct hash *)get_object( handle, MAGIC_HASH );
304}
305
307{
308 return (struct key *)get_object( handle, MAGIC_KEY );
309}
310
312{
313 return (struct secret *)get_object( handle, MAGIC_SECRET );
314}
315
317{
318 const DWORD supported_flags = BCRYPT_USE_SYSTEM_PREFERRED_RNG;
319 struct algorithm *alg = get_alg_object( handle );
320
321 TRACE("%p, %p, %lu, %#lx - semi-stub\n", handle, buffer, count, flags);
322
323 if (!handle)
324 {
325 /* It's valid to call without an algorithm if BCRYPT_USE_SYSTEM_PREFERRED_RNG
326 * is set. In this case the preferred system RNG is used.
327 */
330 }
332 {
333 FIXME( "pseudo-handle %p not supported\n", handle );
335 }
336 else if (!alg || alg->id != ALG_ID_RNG)
338
339 if (!buffer)
341
342 if (flags & ~supported_flags)
343 FIXME("unsupported flags %#lx\n", flags & ~supported_flags);
344
345 if (alg)
346 FIXME("ignoring selected algorithm\n");
347
348 /* When zero bytes are requested the function returns success too. */
349 if (!count)
350 return STATUS_SUCCESS;
351
353 {
355 }
356
357 FIXME("called with unsupported parameters, returning error\n");
359}
360
362{
363 struct algorithm *ret;
364 if (!(ret = calloc( 1, sizeof(*ret) ))) return NULL;
365 ret->hdr.magic = MAGIC_ALG;
366 ret->id = id;
367 ret->mode = mode;
368 ret->flags = flags;
369 return ret;
370}
371
373 DWORD flags )
374{
376 struct algorithm *alg;
377 enum alg_id alg_id;
378 ULONG i;
379
380 TRACE( "%p, %s, %s, %#lx\n", handle, wine_dbgstr_w(id), wine_dbgstr_w(implementation), flags );
381
382 if (!handle || !id) return STATUS_INVALID_PARAMETER;
383 if (flags & ~supported_flags)
384 {
385 FIXME( "unsupported flags %#lx\n", flags & ~supported_flags );
387 }
388
389 for (i = 0; i < ARRAY_SIZE( builtin_algorithms ); i++)
390 {
391 if (!wcscmp( id, builtin_algorithms[i].name))
392 {
393 alg_id = i;
394 break;
395 }
396 }
398 {
399 FIXME( "algorithm %s not supported\n", debugstr_w(id) );
401 }
402
403 if (implementation && wcscmp( implementation, MS_PRIMITIVE_PROVIDER ))
404 {
405 FIXME( "implementation %s not supported\n", debugstr_w(implementation) );
407 }
408
409 if (!(alg = create_algorithm( alg_id, 0, flags ))) return STATUS_NO_MEMORY;
410 *handle = alg;
411 TRACE( "returning handle %p\n", *handle );
412 return STATUS_SUCCESS;
413}
414
415static void destroy_object( struct object *obj )
416{
417 SecureZeroMemory( &obj->magic, sizeof(obj->magic) );
418 free( obj );
419}
420
422{
423 struct algorithm *alg = handle;
424
425 TRACE( "%p, %#lx\n", handle, flags );
426
427 if (!handle || is_alg_pseudo_handle( handle ) || alg->hdr.magic != MAGIC_ALG) return STATUS_INVALID_HANDLE;
428 destroy_object( &alg->hdr );
429 return STATUS_SUCCESS;
430}
431
433{
434 FIXME("%p - semi-stub\n", enabled);
435
436 if (!enabled)
438
439 *enabled = FALSE;
440 return STATUS_SUCCESS;
441}
442
444{
445 if (!wcscmp( prop, BCRYPT_OBJECT_LENGTH ))
446 {
449 *ret_size = sizeof(ULONG);
450 if (size < sizeof(ULONG))
452 if (buf)
454 return STATUS_SUCCESS;
455 }
456
457 if (!wcscmp( prop, BCRYPT_HASH_LENGTH ))
458 {
461 *ret_size = sizeof(ULONG);
462 if (size < sizeof(ULONG))
464 if(buf)
466 return STATUS_SUCCESS;
467 }
468
469 if (!wcscmp( prop, BCRYPT_ALGORITHM_NAME ))
470 {
471 *ret_size = (lstrlenW(builtin_algorithms[id].name) + 1) * sizeof(WCHAR);
472 if (size < *ret_size)
474 if(buf)
476 return STATUS_SUCCESS;
477 }
478
480}
481
483{
484 if (!wcscmp( prop, BCRYPT_BLOCK_LENGTH ))
485 {
486 *ret_size = sizeof(ULONG);
487 if (size < sizeof(ULONG)) return STATUS_BUFFER_TOO_SMALL;
488 if (buf) *(ULONG *)buf = BLOCK_LENGTH_3DES;
489 return STATUS_SUCCESS;
490 }
491 if (!wcscmp( prop, BCRYPT_CHAINING_MODE ))
492 {
493 const WCHAR *str;
494 switch (mode)
495 {
497 default: return STATUS_NOT_IMPLEMENTED;
498 }
499
500 *ret_size = 64;
502 memcpy( buf, str, (lstrlenW(str) + 1) * sizeof(WCHAR) );
503 return STATUS_SUCCESS;
504 }
505 if (!wcscmp( prop, BCRYPT_KEY_LENGTHS ))
506 {
507 BCRYPT_KEY_LENGTHS_STRUCT *key_lengths = (void *)buf;
508 *ret_size = sizeof(*key_lengths);
509 if (key_lengths && size < *ret_size) return STATUS_BUFFER_TOO_SMALL;
510 if (key_lengths)
511 {
512 key_lengths->dwMinLength = 192;
513 key_lengths->dwMaxLength = 192;
514 key_lengths->dwIncrement = 0;
515 }
516 return STATUS_SUCCESS;
517 }
518 FIXME( "unsupported property %s\n", debugstr_w(prop) );
520}
521
523{
524 if (!wcscmp( prop, BCRYPT_BLOCK_LENGTH ))
525 {
526 *ret_size = sizeof(ULONG);
527 if (size < sizeof(ULONG)) return STATUS_BUFFER_TOO_SMALL;
528 if (buf) *(ULONG *)buf = BLOCK_LENGTH_AES;
529 return STATUS_SUCCESS;
530 }
531 if (!wcscmp( prop, BCRYPT_CHAINING_MODE ))
532 {
533 const WCHAR *str;
534 switch (mode)
535 {
540 default: return STATUS_NOT_IMPLEMENTED;
541 }
542
543 *ret_size = 64;
545 memcpy( buf, str, (lstrlenW(str) + 1) * sizeof(WCHAR) );
546 return STATUS_SUCCESS;
547 }
548 if (!wcscmp( prop, BCRYPT_KEY_LENGTHS ))
549 {
550 BCRYPT_KEY_LENGTHS_STRUCT *key_lengths = (void *)buf;
551 *ret_size = sizeof(*key_lengths);
552 if (key_lengths && size < *ret_size) return STATUS_BUFFER_TOO_SMALL;
553 if (key_lengths)
554 {
555 key_lengths->dwMinLength = 128;
556 key_lengths->dwMaxLength = 256;
557 key_lengths->dwIncrement = 64;
558 }
559 return STATUS_SUCCESS;
560 }
561 if (!wcscmp( prop, BCRYPT_AUTH_TAG_LENGTH ))
562 {
563 BCRYPT_AUTH_TAG_LENGTHS_STRUCT *tag_length = (void *)buf;
565 *ret_size = sizeof(*tag_length);
566 if (tag_length && size < *ret_size) return STATUS_BUFFER_TOO_SMALL;
567 if (tag_length)
568 {
569 tag_length->dwMinLength = 12;
570 tag_length->dwMaxLength = 16;
571 tag_length->dwIncrement = 1;
572 }
573 return STATUS_SUCCESS;
574 }
575
576 FIXME( "unsupported property %s\n", debugstr_w(prop) );
578}
579
581{
582 if (!wcscmp( prop, BCRYPT_BLOCK_LENGTH ))
583 {
584 *ret_size = sizeof(ULONG);
585 if (size < sizeof(ULONG)) return STATUS_BUFFER_TOO_SMALL;
586 if (buf) *(ULONG *)buf = BLOCK_LENGTH_RC4;
587 return STATUS_SUCCESS;
588 }
589
590 FIXME( "unsupported property %s\n", debugstr_w(prop) );
592}
593
595{
596 if (!wcscmp( prop, BCRYPT_PADDING_SCHEMES ))
597 {
598 *ret_size = sizeof(ULONG);
599 if (size < sizeof(ULONG)) return STATUS_BUFFER_TOO_SMALL;
601 return STATUS_SUCCESS;
602 }
603
604 FIXME( "unsupported property %s\n", debugstr_w(prop) );
606}
607
609{
611 FIXME( "unsupported property %s\n", debugstr_w(prop) );
613}
614
616{
617 if (!wcscmp( prop, BCRYPT_BLOCK_LENGTH )) return STATUS_NOT_SUPPORTED;
618 if (!wcscmp( prop, BCRYPT_KEY_LENGTHS ))
619 {
620 BCRYPT_KEY_LENGTHS_STRUCT *key_lengths = (void *)buf;
621 *ret_size = sizeof(*key_lengths);
622 if (key_lengths && size < *ret_size) return STATUS_BUFFER_TOO_SMALL;
623 if (key_lengths)
624 {
625 key_lengths->dwMinLength = 0;
626 key_lengths->dwMaxLength = 16384;
627 key_lengths->dwIncrement = 8;
628 }
629 return STATUS_SUCCESS;
630 }
631 FIXME( "unsupported property %s\n", debugstr_w(prop) );
633}
634
635static NTSTATUS get_alg_property( const struct algorithm *alg, const WCHAR *prop, UCHAR *buf, ULONG size,
636 ULONG *ret_size )
637{
639
640 status = generic_alg_property( alg->id, prop, buf, size, ret_size );
642 return status;
643
644 switch (alg->id)
645 {
646 case ALG_ID_3DES:
647 return get_3des_property( alg->mode, prop, buf, size, ret_size );
648
649 case ALG_ID_AES:
650 return get_aes_property( alg->mode, prop, buf, size, ret_size );
651
652 case ALG_ID_RC4:
653 return get_rc4_property( alg->mode, prop, buf, size, ret_size );
654
655 case ALG_ID_RSA:
656 return get_rsa_property( alg->mode, prop, buf, size, ret_size );
657
658 case ALG_ID_DSA:
659 return get_dsa_property( alg->mode, prop, buf, size, ret_size );
660
661 case ALG_ID_PBKDF2:
662 return get_pbkdf2_property( alg->mode, prop, buf, size, ret_size );
663
664 default:
665 break;
666 }
667
668 FIXME( "unsupported property %s algorithm %u\n", debugstr_w(prop), alg->id );
670}
671
672static NTSTATUS set_alg_property( struct algorithm *alg, const WCHAR *prop, UCHAR *value, ULONG size, ULONG flags )
673{
674 switch (alg->id)
675 {
676 case ALG_ID_3DES:
677 if (!wcscmp( prop, BCRYPT_CHAINING_MODE ))
678 {
680 {
681 alg->mode = CHAIN_MODE_CBC;
682 return STATUS_SUCCESS;
683 }
684 else
685 {
686 FIXME( "unsupported mode %s\n", debugstr_w((WCHAR *)value) );
688 }
689 }
690 FIXME( "unsupported 3des algorithm property %s\n", debugstr_w(prop) );
692
693 case ALG_ID_AES:
694 if (!wcscmp( prop, BCRYPT_CHAINING_MODE ))
695 {
697 {
698 alg->mode = CHAIN_MODE_ECB;
699 return STATUS_SUCCESS;
700 }
701 else if (!wcscmp( (WCHAR *)value, BCRYPT_CHAIN_MODE_CBC ))
702 {
703 alg->mode = CHAIN_MODE_CBC;
704 return STATUS_SUCCESS;
705 }
706 else if (!wcscmp( (WCHAR *)value, BCRYPT_CHAIN_MODE_GCM ))
707 {
708 alg->mode = CHAIN_MODE_GCM;
709 return STATUS_SUCCESS;
710 }
711 else if (!wcscmp( (WCHAR *)value, BCRYPT_CHAIN_MODE_CFB ))
712 {
713 alg->mode = CHAIN_MODE_CFB;
714 return STATUS_SUCCESS;
715 }
716 else
717 {
718 FIXME( "unsupported mode %s\n", debugstr_w((WCHAR *)value) );
720 }
721 }
722 FIXME( "unsupported aes algorithm property %s\n", debugstr_w(prop) );
724
725 case ALG_ID_RC4:
726 if (!wcscmp( prop, BCRYPT_CHAINING_MODE ))
727 {
729
730 FIXME( "unsupported mode %s\n", debugstr_w((WCHAR *)value) );
732 }
733 FIXME( "unsupported rc4 algorithm property %s\n", debugstr_w(prop) );
735
736 default:
737 FIXME( "unsupported algorithm %u\n", alg->id );
739 }
740}
741
743{
744 if (!wcscmp( prop, BCRYPT_CHAINING_MODE ))
745 {
747 {
748 key->u.s.mode = CHAIN_MODE_ECB;
749 return STATUS_SUCCESS;
750 }
751 else if (!wcscmp( (WCHAR *)value, BCRYPT_CHAIN_MODE_CBC ))
752 {
753 key->u.s.mode = CHAIN_MODE_CBC;
754 return STATUS_SUCCESS;
755 }
756 else if (!wcscmp( (WCHAR *)value, BCRYPT_CHAIN_MODE_GCM ))
757 {
758 key->u.s.mode = CHAIN_MODE_GCM;
759 return STATUS_SUCCESS;
760 }
761 else if (!wcscmp( (WCHAR *)value, BCRYPT_CHAIN_MODE_CFB ))
762 {
763 key->u.s.mode = CHAIN_MODE_CFB;
764 return STATUS_SUCCESS;
765 }
766 else
767 {
768 FIXME( "unsupported mode %s\n", debugstr_w((WCHAR *)value) );
770 }
771 }
772 else if (!wcscmp( prop, BCRYPT_KEY_LENGTH ))
773 {
774 if (size < sizeof(DWORD)) return STATUS_INVALID_PARAMETER;
775 key->u.a.bitlen = *(DWORD*)value;
776 return STATUS_SUCCESS;
777 }
778 else if (!wcscmp( prop, BCRYPT_DH_PARAMETERS ))
779 {
782
783 if (key->u.a.flags & KEY_FLAG_FINALIZED) return STATUS_INVALID_HANDLE;
784 if (key->alg_id != ALG_ID_DH || size < sizeof(*hdr) || hdr->cbLength != size ||
785 hdr->dwMagic != BCRYPT_DH_PARAMETERS_MAGIC || hdr->cbKeyLength != key->u.a.bitlen / 8)
787
788 params.key = key;
790 params.buf = value;
791 params.len = size;
792 return key_asymmetric_import( &params );
793 }
794
795 FIXME( "unsupported key property %s\n", debugstr_w(prop) );
797}
798
799static NTSTATUS get_hash_property( const struct hash *hash, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size )
800{
802
805 FIXME( "unsupported property %s\n", debugstr_w(prop) );
806 return status;
807}
808
809static NTSTATUS get_dh_property( const struct key *key, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size )
810{
812
814 if (!(key->u.a.flags & KEY_FLAG_FINALIZED)) return STATUS_INVALID_HANDLE;
815
816 params.key = (struct key *)key;
818 params.buf = buf;
819 params.len = size;
820 params.ret_len = ret_size;
821 return key_asymmetric_export( &params );
822}
823
824static NTSTATUS get_key_property( const struct key *key, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size )
825{
826 if (!wcscmp( prop, BCRYPT_KEY_STRENGTH ))
827 {
828 *ret_size = sizeof(DWORD);
829 if (size < sizeof(DWORD)) return STATUS_BUFFER_TOO_SMALL;
830 if (buf)
831 {
832 if (is_symmetric_key(key)) *(DWORD *)buf = key->u.s.block_size * 8;
833 else *(DWORD *)buf = key->u.a.bitlen;
834 }
835 return STATUS_SUCCESS;
836 }
837
838 switch (key->alg_id)
839 {
840 case ALG_ID_3DES:
841 return get_3des_property( key->u.s.mode, prop, buf, size, ret_size );
842
843 case ALG_ID_AES:
845 return get_aes_property( key->u.s.mode, prop, buf, size, ret_size );
846
847 case ALG_ID_DH:
848 return get_dh_property( key, prop, buf, size, ret_size );
849
850 default:
851 FIXME( "unsupported algorithm %u\n", key->alg_id );
853 }
854}
855
857 ULONG flags )
858{
859 struct object *object = get_object( handle, 0 );
860
861 TRACE( "%p, %s, %p, %lu, %p, %#lx\n", handle, wine_dbgstr_w(prop), buffer, count, res, flags );
862
863 if (!object) return STATUS_INVALID_HANDLE;
864 if (!prop || !res) return STATUS_INVALID_PARAMETER;
865
866 switch (object->magic)
867 {
868 case MAGIC_ALG:
869 {
870 const struct algorithm *alg = (const struct algorithm *)object;
871 return get_alg_property( alg, prop, buffer, count, res );
872 }
873 case MAGIC_KEY:
874 {
875 const struct key *key = (const struct key *)object;
876 return get_key_property( key, prop, buffer, count, res );
877 }
878 case MAGIC_HASH:
879 {
880 const struct hash *hash = (const struct hash *)object;
881 return get_hash_property( hash, prop, buffer, count, res );
882 }
883 default:
884 WARN( "unknown magic %#lx\n", object->magic );
886 }
887}
888
889static void hash_prepare( struct hash *hash )
890{
891#ifndef __REACTOS__
893 ULONG block_bytes, i;
894 struct hash *hash_temp;
895#endif
896
897 /* initialize hash */
898 hash_init( hash );
899 if (!(hash->flags & HASH_FLAG_HMAC)) return;
900
901#ifndef __REACTOS__
902 /* initialize hmac */
903 hmac_init( hash );
904 hash_get_size(hash, &block_bytes);
905 memset( buffer, 0, sizeof(buffer) );
906 if (hash->secret_len > block_bytes)
907 {
908 if (!(hash_temp = calloc( 1, sizeof(*hash_temp) ))) return;
909 hash_temp->hdr.magic = MAGIC_HASH;
910 hash_temp->alg_id = hash->alg_id;
911
912 hash_init( hash_temp );
913 hash_update( hash_temp, hash->secret, hash->secret_len );
914 hash_finish( hash_temp, buffer );
915 free( hash_temp );
916 }
918
919 for (i = 0; i < block_bytes; i++) buffer[i] ^= 0x5c;
920 hmac_update( hash, buffer, block_bytes );
921 for (i = 0; i < block_bytes; i++) buffer[i] ^= (0x5c ^ 0x36);
922 hash_update( hash, buffer, block_bytes );
923#endif
924}
925
927 struct hash **ret_hash )
928{
929 struct hash *hash;
930 if (!(hash = calloc( 1, sizeof(*hash) ))) return STATUS_NO_MEMORY;
931 hash->hdr.magic = MAGIC_HASH;
932 hash->alg_id = alg->id;
933
937
938 if (secret_len && !(hash->secret = malloc( secret_len )))
939 {
940 free( hash );
941 return STATUS_NO_MEMORY;
942 }
945
947 *ret_hash = hash;
948 return STATUS_SUCCESS;
949}
950
952 ULONG object_len, UCHAR *secret, ULONG secret_len, ULONG flags )
953{
954 struct algorithm *alg = get_alg_object( handle );
955 struct hash *hash;
957
958 TRACE( "%p, %p, %p, %lu, %p, %lu, %#lx\n", handle, ret_handle, object, object_len, secret, secret_len, flags );
960 {
961 FIXME( "unimplemented flags %#lx\n", flags );
963 }
964 if (object) FIXME( "ignoring object buffer\n" );
965
966 if (!alg) return STATUS_INVALID_HANDLE;
967 if (!ret_handle) return STATUS_INVALID_PARAMETER;
968
969 if ((status = hash_create( alg, secret, secret_len, flags, &hash ))) return status;
970 *ret_handle = hash;
971 TRACE( "returning handle %p\n", *ret_handle );
972 return STATUS_SUCCESS;
973}
974
976 UCHAR *object, ULONG objectlen, ULONG flags )
977{
978 struct hash *hash_orig = get_hash_object( handle );
979 struct hash *hash_copy;
980
981 TRACE( "%p, %p, %p, %lu, %#lx\n", handle, handle_copy, object, objectlen, flags );
982
983 if (!hash_orig) return STATUS_INVALID_HANDLE;
984 if (!handle_copy) return STATUS_INVALID_PARAMETER;
985 if (object) FIXME( "ignoring object buffer\n" );
986
987 if (!(hash_copy = malloc( sizeof(*hash_copy) ))) return STATUS_NO_MEMORY;
988
989 memcpy( hash_copy, hash_orig, sizeof(*hash_orig) );
990 if (hash_orig->secret && !(hash_copy->secret = malloc( hash_orig->secret_len )))
991 {
992 free( hash_copy );
993 return STATUS_NO_MEMORY;
994 }
995 memcpy( hash_copy->secret, hash_orig->secret, hash_orig->secret_len );
996
997 *handle_copy = hash_copy;
998 TRACE( "returning handle %p\n", *handle_copy );
999 return STATUS_SUCCESS;
1000}
1001
1002static void hash_destroy( struct hash *hash )
1003{
1004 if (!hash) return;
1005 free( hash->secret );
1006 destroy_object( &hash->hdr );
1007}
1008
1010{
1011 struct hash *hash = get_hash_object( handle );
1012
1013 TRACE( "%p\n", handle );
1014
1015 if (!hash) return STATUS_INVALID_PARAMETER;
1016 hash_destroy( hash );
1017 return STATUS_SUCCESS;
1018}
1019
1021{
1022 struct hash *hash = get_hash_object( handle );
1023
1024 TRACE( "%p, %p, %lu, %#lx\n", handle, input, size, flags );
1025
1026 if (!hash) return STATUS_INVALID_HANDLE;
1027 if (!input) return STATUS_SUCCESS;
1028
1030
1031 return STATUS_SUCCESS;
1032}
1033
1034static void hash_finalize( struct hash *hash, UCHAR *output, ULONG size )
1035{
1036#ifndef __REACTOS__
1038 ULONG hash_size;
1039
1040 if (!(hash->flags & HASH_FLAG_HMAC))
1041 {
1042#endif
1043 hash_finish( hash, output );
1045#ifndef __REACTOS__
1046 return;
1047 }
1048
1049 hash_get_size( hash, &hash_size );
1051 hmac_update( hash, buffer, hash_size );
1052 hmac_finish( hash, output );
1053
1055#endif
1056}
1057
1059{
1060 struct hash *hash = get_hash_object( handle );
1061 ULONG hash_size;
1062
1063 TRACE( "%p, %p, %lu, %#lx\n", handle, output, size, flags );
1064
1065 if (!hash) return STATUS_INVALID_HANDLE;
1066 if (!output) return STATUS_INVALID_PARAMETER;
1067 hash_get_size( hash, &hash_size );
1068 if (size != hash_size) return STATUS_INVALID_PARAMETER;
1069
1070 hash_finalize( hash, output, size );
1071 return STATUS_SUCCESS;
1072}
1073
1075 UCHAR *output, ULONG output_len )
1076{
1077 struct hash *hash;
1079
1080 if ((status = hash_create( alg, secret, secret_len, 0, &hash ))) return status;
1081 if (input_len && hash_update( hash, input, input_len ))
1082 {
1083 hash_destroy( hash );
1085 }
1086 hash_finalize( hash, output, output_len );
1087 hash_destroy( hash );
1088 return STATUS_SUCCESS;
1089}
1090
1092 UCHAR *output, ULONG output_len )
1093{
1094 struct algorithm *alg = get_alg_object( handle );
1095
1096 TRACE( "%p, %p, %lu, %p, %lu, %p, %lu\n", handle, secret, secret_len, input, input_len, output, output_len );
1097
1098 if (!alg) return STATUS_INVALID_HANDLE;
1099 if (!output || output_len != builtin_algorithms[alg->id].hash_length) return STATUS_INVALID_PARAMETER;
1100
1101 return hash_single(alg, secret, secret_len, input, input_len, output, output_len );
1102}
1103
1104static NTSTATUS key_asymmetric_create( enum alg_id alg_id, ULONG bitlen, struct key **ret_key )
1105{
1106 struct key *key;
1107
1108 if (alg_id == ALG_ID_DH && bitlen < 512) return STATUS_INVALID_PARAMETER;
1109
1110 if (!(key = calloc( 1, sizeof(*key) ))) return STATUS_NO_MEMORY;
1111 key->hdr.magic = MAGIC_KEY;
1112 key->alg_id = alg_id;
1113 key->u.a.bitlen = bitlen;
1114
1115 *ret_key = key;
1116 return STATUS_SUCCESS;
1117}
1118
1119static BOOL is_equal_vector( const UCHAR *vector, ULONG len, const UCHAR *vector2, ULONG len2 )
1120{
1121 if (!vector && !vector2) return TRUE;
1122 if (len != len2) return FALSE;
1123 return !memcmp( vector, vector2, len );
1124}
1125
1126static NTSTATUS key_symmetric_set_vector( struct key *key, UCHAR *vector, ULONG vector_len, BOOL force_reset )
1127{
1128 BOOL needs_reset = force_reset || !is_equal_vector( key->u.s.vector, key->u.s.vector_len, vector, vector_len );
1129 if (vector)
1130 {
1131 free( key->u.s.vector );
1132 key->u.s.vector = NULL;
1133 key->u.s.vector_len = 0;
1134
1135 if (!(key->u.s.vector = malloc( vector_len ))) return STATUS_NO_MEMORY;
1136 memcpy( key->u.s.vector, vector, vector_len );
1137 key->u.s.vector_len = vector_len;
1138 }
1139 if (needs_reset) key_symmetric_vector_reset( key );
1140 return STATUS_SUCCESS;
1141}
1142
1144 ULONG secret_len )
1145{
1146 struct key *ret;
1147
1148 if (!(ret = calloc( 1, sizeof(*ret) ))) return NULL;
1149 InitializeCriticalSection( &ret->u.s.cs );
1150 ret->hdr.magic = MAGIC_KEY;
1151 ret->alg_id = alg;
1152 ret->u.s.mode = mode;
1153 ret->u.s.block_size = block_size;
1154
1155 if (!(ret->u.s.secret = malloc( secret_len )))
1156 {
1157 DeleteCriticalSection( &ret->u.s.cs );
1158 free( ret );
1159 return NULL;
1160 }
1161 memcpy( ret->u.s.secret, secret, secret_len );
1162 ret->u.s.secret_len = secret_len;
1163
1164 return ret;
1165}
1166
1167static void key_destroy( struct key *key )
1168{
1169 if (is_symmetric_key( key ))
1170 {
1172 free( key->u.s.vector );
1173 free( key->u.s.secret );
1174 DeleteCriticalSection( &key->u.s.cs );
1175 }
1176 else
1178
1179 destroy_object( &key->hdr );
1180}
1181
1182static ULONG get_block_size( struct algorithm *alg )
1183{
1184 ULONG ret = 0, size = sizeof(ret);
1185 get_alg_property( alg, BCRYPT_BLOCK_LENGTH, (UCHAR *)&ret, sizeof(ret), &size );
1186 return ret;
1187}
1188
1190 ULONG secret_len )
1191{
1192 BCRYPT_KEY_LENGTHS_STRUCT key_lengths;
1194 struct key *key;
1196
1197 if (alg->id == ALG_ID_PBKDF2 &&
1198 !get_alg_property( alg, BCRYPT_KEY_LENGTHS, (UCHAR *)&key_lengths, sizeof(key_lengths), &size ))
1199 {
1200 if (secret_len > key_lengths.dwMaxLength / 8 || secret_len < key_lengths.dwMinLength / 8)
1202 block_size = secret_len;
1203 }
1204 else if (!(block_size = get_block_size( alg ))) return STATUS_INVALID_PARAMETER;
1205 else if (!get_alg_property( alg, BCRYPT_KEY_LENGTHS, (UCHAR *)&key_lengths, sizeof(key_lengths), &size ))
1206 {
1207 if (secret_len > (size = key_lengths.dwMaxLength / 8))
1208 {
1209 WARN( "secret_len %lu exceeds key max length %lu, setting to maximum\n", secret_len, size );
1210 secret_len = size;
1211 }
1212 else if (secret_len < (size = key_lengths.dwMinLength / 8))
1213 {
1214 WARN( "secret_len %lu is less than minimum key length %lu\n", secret_len, size );
1216 }
1217 else if (key_lengths.dwIncrement && (secret_len * 8 - key_lengths.dwMinLength) % key_lengths.dwIncrement)
1218 {
1219 WARN( "secret_len %lu is not a valid key length\n", secret_len );
1221 }
1222 }
1223
1224 if (!(key = key_symmetric_create( alg->id, alg->mode, block_size, secret, secret_len ))) status = STATUS_NO_MEMORY;
1225 else
1226 {
1227 *ret_handle = key;
1229 }
1230
1231 return status;
1232}
1233
1234static NTSTATUS key_symmetric_decrypt( struct key *key, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv,
1235 ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags )
1236{
1237 struct key_symmetric_set_auth_data_params auth_params;
1238 struct key_symmetric_decrypt_params decrypt_params;
1239 struct key_symmetric_get_tag_params tag_params;
1240 ULONG bytes_left = input_len;
1242
1243 if (key->u.s.mode == CHAIN_MODE_GCM)
1244 {
1246#ifndef __REACTOS__
1247 UCHAR tag[16];
1248#endif
1249
1250 if (!auth_info) return STATUS_INVALID_PARAMETER;
1251 if (!auth_info->pbNonce) return STATUS_INVALID_PARAMETER;
1252 if (!auth_info->pbTag) return STATUS_INVALID_PARAMETER;
1253 if (auth_info->cbTag < 12 || auth_info->cbTag > 16) return STATUS_INVALID_PARAMETER;
1254
1255 if ((status = key_symmetric_set_vector( key, auth_info->pbNonce, auth_info->cbNonce, TRUE )))
1256 return status;
1257
1258 *ret_len = input_len;
1260 if (!output) return STATUS_SUCCESS;
1261 if (output_len < *ret_len) return STATUS_BUFFER_TOO_SMALL;
1262
1263 auth_params.key = key;
1264 auth_params.auth_data = auth_info->pbAuthData;
1265 auth_params.len = auth_info->cbAuthData;
1266#ifdef __REACTOS__
1267 auth_params.encrypt = FALSE;
1268#endif
1269 if ((status = key_symmetric_set_auth_data( &auth_params ))) return status;
1270
1271 decrypt_params.key = key;
1272 decrypt_params.input = input;
1273 decrypt_params.input_len = input_len;
1274 decrypt_params.output = output;
1275 decrypt_params.output_len = output_len;
1276 if ((status = key_symmetric_decrypt_internal( &decrypt_params ))) return status;
1277
1278#ifndef __REACTOS__
1279 tag_params.key = key;
1280 tag_params.tag = tag;
1281 tag_params.len = sizeof(tag);
1282 if ((status = key_symmetric_get_tag( &tag_params ))) return status;
1283 if (memcmp( tag, auth_info->pbTag, auth_info->cbTag )) return STATUS_AUTH_TAG_MISMATCH;
1284#else
1285 tag_params.key = key;
1286 tag_params.tag = auth_info->pbTag;
1287 tag_params.len = auth_info->cbTag;
1288 if ((status = key_symmetric_get_tag( &tag_params ))) return status;
1289#endif
1290
1291 return STATUS_SUCCESS;
1292 }
1293
1294 *ret_len = input_len;
1295
1296 if (input_len & (key->u.s.block_size - 1)) return STATUS_INVALID_BUFFER_SIZE;
1297 if (!output) return STATUS_SUCCESS;
1299 {
1300 if (output_len + key->u.s.block_size < *ret_len) return STATUS_BUFFER_TOO_SMALL;
1301 if (input_len < key->u.s.block_size) return STATUS_BUFFER_TOO_SMALL;
1302 bytes_left -= key->u.s.block_size;
1303 }
1304 else if (output_len < *ret_len) return STATUS_BUFFER_TOO_SMALL;
1305
1306 if (key->u.s.mode == CHAIN_MODE_ECB && iv) return STATUS_INVALID_PARAMETER;
1307 if ((status = key_symmetric_set_vector( key, iv, iv_len, flags & BCRYPT_BLOCK_PADDING ))) return status;
1308
1309 decrypt_params.key = key;
1310 decrypt_params.input = input;
1311 decrypt_params.input_len = key->u.s.block_size;
1312 decrypt_params.output = output;
1313 decrypt_params.output_len = key->u.s.block_size;
1314 while (bytes_left >= key->u.s.block_size)
1315 {
1316 if ((status = key_symmetric_decrypt_internal( &decrypt_params ))) return status;
1317 if (key->u.s.mode == CHAIN_MODE_ECB && (status = key_symmetric_set_vector( key, NULL, 0, TRUE )))
1318 return status;
1319 bytes_left -= key->u.s.block_size;
1320 decrypt_params.input += key->u.s.block_size;
1321 decrypt_params.output += key->u.s.block_size;
1322 }
1323
1325 {
1326 UCHAR *buf, *dst = decrypt_params.output;
1327 if (!(buf = malloc( key->u.s.block_size ))) return STATUS_NO_MEMORY;
1328 decrypt_params.output = buf;
1329 status = key_symmetric_decrypt_internal( &decrypt_params );
1330 if (!status && buf[ key->u.s.block_size - 1 ] <= key->u.s.block_size)
1331 {
1332 *ret_len -= buf[ key->u.s.block_size - 1 ];
1333 if (output_len < *ret_len) status = STATUS_BUFFER_TOO_SMALL;
1334 else memcpy( dst, buf, key->u.s.block_size - buf[ key->u.s.block_size - 1 ] );
1335 }
1336 else status = STATUS_UNSUCCESSFUL; /* FIXME: invalid padding */
1337 free( buf );
1338 }
1339
1340 if (!status)
1341 {
1342 if (key->u.s.vector && input_len >= key->u.s.vector_len)
1343 {
1344 memcpy( key->u.s.vector, input + input_len - key->u.s.vector_len, key->u.s.vector_len );
1345 if (iv) memcpy( iv, key->u.s.vector, min( iv_len, key->u.s.vector_len ));
1346 }
1347 else if (key->u.s.vector)
1348 FIXME( "Unexpected vector len %lu, *ret_len %lu.\n", key->u.s.vector_len, *ret_len );
1349 }
1350
1351 return status;
1352}
1353
1354/* AES Key Wrap Algorithm (RFC3394) */
1355static NTSTATUS aes_unwrap( const UCHAR *secret, ULONG secret_len, const UCHAR *cipher, ULONG cipher_len, UCHAR *plain )
1356{
1357 UCHAR a[8], *r, b[16];
1358 ULONG len, t, i, n = cipher_len / 8;
1359 int j;
1360 struct key *key;
1361
1362 memcpy( a, cipher, 8 );
1363 r = plain;
1364 memcpy( r, cipher + 8, 8 * n );
1365
1366 if (!(key = key_symmetric_create( ALG_ID_AES, CHAIN_MODE_ECB, 16, secret, secret_len ))) return STATUS_NO_MEMORY;
1367
1368 for (j = 5; j >= 0; j--)
1369 {
1370 r = plain + (n - 1) * 8;
1371 for (i = n; i >= 1; i--)
1372 {
1373 memcpy( b, a, 8 );
1374 t = n * j + i;
1375 b[7] ^= t;
1376 b[6] ^= t >> 8;
1377 b[5] ^= t >> 16;
1378 b[4] ^= t >> 24;
1379
1380 memcpy( b + 8, r, 8 );
1381 key_symmetric_decrypt( key, b, 16, NULL, NULL, 0, b, 16, &len, 0 );
1382 memcpy( a, b, 8 );
1383 memcpy( r, b + 8, 8 );
1384 r -= 8;
1385 }
1386 }
1387
1388 key_destroy( key );
1389
1390 for (i = 0; i < 8; i++) if (a[i] != 0xa6) return STATUS_UNSUCCESSFUL;
1391 return STATUS_SUCCESS;
1392}
1393
1394static NTSTATUS key_import( struct algorithm *alg, struct key *decrypt_key, const WCHAR *type, BCRYPT_KEY_HANDLE *key,
1395 UCHAR *object, ULONG object_len, UCHAR *input, ULONG input_len )
1396{
1397 ULONG len;
1399
1400 if (decrypt_key && wcscmp( type, BCRYPT_AES_WRAP_KEY_BLOB ))
1401 {
1402 FIXME( "decryption of key not supported\n" );
1404 }
1405
1407 {
1409
1410 if (input_len < sizeof(BCRYPT_KEY_DATA_BLOB_HEADER)) return STATUS_BUFFER_TOO_SMALL;
1412 if (header->dwVersion != BCRYPT_KEY_DATA_BLOB_VERSION1)
1413 {
1414 FIXME( "unknown key data blob version %lu\n", header->dwVersion );
1416 }
1417 len = header->cbKeyData;
1418 if (len + sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) > input_len) return STATUS_INVALID_PARAMETER;
1419
1420 return key_symmetric_generate( alg, key, (UCHAR *)&header[1], len );
1421 }
1422 else if (!wcscmp( type, BCRYPT_OPAQUE_KEY_BLOB ))
1423 {
1424 if (input_len < sizeof(len)) return STATUS_BUFFER_TOO_SMALL;
1425 len = *(ULONG *)input;
1426 if (len + sizeof(len) > input_len) return STATUS_INVALID_PARAMETER;
1427
1428 return key_symmetric_generate( alg, key, input + sizeof(len), len );
1429 }
1430 else if (!wcscmp( type, BCRYPT_AES_WRAP_KEY_BLOB ))
1431 {
1432 UCHAR output[32];
1433
1434 if (!decrypt_key || input_len < 8) return STATUS_INVALID_PARAMETER;
1435
1436 len = input_len - 8;
1438
1439 if ((status = aes_unwrap( decrypt_key->u.s.secret, decrypt_key->u.s.secret_len, input, len, output )))
1440 return status;
1441
1442 return key_symmetric_generate( alg, key, output, len );
1443 }
1444
1445 FIXME( "unsupported key type %s\n", debugstr_w(type) );
1447}
1448
1449static NTSTATUS key_symmetric_encrypt( struct key *key, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv,
1450 ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags )
1451{
1452 struct key_symmetric_set_auth_data_params auth_params;
1453 struct key_symmetric_encrypt_params encrypt_params;
1454 struct key_symmetric_get_tag_params tag_params;
1455 ULONG bytes_left = input_len;
1456 UCHAR *buf;
1458
1459 if (key->u.s.mode == CHAIN_MODE_GCM)
1460 {
1462
1463 if (!auth_info) return STATUS_INVALID_PARAMETER;
1464 if (!auth_info->pbNonce) return STATUS_INVALID_PARAMETER;
1465 if (!auth_info->pbTag) return STATUS_INVALID_PARAMETER;
1466 if (auth_info->cbTag < 12 || auth_info->cbTag > 16) return STATUS_INVALID_PARAMETER;
1468 FIXME( "call chaining not implemented\n" );
1469
1470 if ((status = key_symmetric_set_vector( key, auth_info->pbNonce, auth_info->cbNonce, TRUE )))
1471 return status;
1472
1473 *ret_len = input_len;
1475 if (input && !output) return STATUS_SUCCESS;
1476 if (output_len < *ret_len) return STATUS_BUFFER_TOO_SMALL;
1477
1478 auth_params.key = key;
1479 auth_params.auth_data = auth_info->pbAuthData;
1480 auth_params.len = auth_info->cbAuthData;
1481#ifdef __REACTOS__
1482 auth_params.encrypt = TRUE;
1483#endif
1484 if ((status = key_symmetric_set_auth_data( &auth_params ))) return status;
1485
1486 encrypt_params.key = key;
1487 encrypt_params.input = input;
1488 encrypt_params.input_len = input_len;
1489 encrypt_params.output = output;
1490 encrypt_params.output_len = output_len;
1491 if ((status = key_symmetric_encrypt_internal( &encrypt_params ))) return status;
1492
1493 tag_params.key = key;
1494 tag_params.tag = auth_info->pbTag;
1495 tag_params.len = auth_info->cbTag;
1496 return key_symmetric_get_tag( &tag_params );
1497 }
1498
1499 *ret_len = input_len;
1500
1502 *ret_len = (input_len + key->u.s.block_size) & ~(key->u.s.block_size - 1);
1503 else if (input_len & (key->u.s.block_size - 1))
1505
1506 if (!output) return STATUS_SUCCESS;
1507 if (output_len < *ret_len) return STATUS_BUFFER_TOO_SMALL;
1508 if (key->u.s.mode == CHAIN_MODE_ECB && iv) return STATUS_INVALID_PARAMETER;
1509 if ((status = key_symmetric_set_vector( key, iv, iv_len, flags & BCRYPT_BLOCK_PADDING ))) return status;
1510
1511 encrypt_params.key = key;
1512 encrypt_params.input = input;
1513 encrypt_params.input_len = key->u.s.block_size;
1514 encrypt_params.output = output;
1515 encrypt_params.output_len = key->u.s.block_size;
1516 while (bytes_left >= key->u.s.block_size)
1517 {
1518 if ((status = key_symmetric_encrypt_internal( &encrypt_params )))
1519 return status;
1520 if (key->u.s.mode == CHAIN_MODE_ECB && (status = key_symmetric_set_vector( key, NULL, 0, TRUE )))
1521 return status;
1522 bytes_left -= key->u.s.block_size;
1523 encrypt_params.input += key->u.s.block_size;
1524 encrypt_params.output += key->u.s.block_size;
1525 }
1526
1528 {
1529 if (!(buf = malloc( key->u.s.block_size ))) return STATUS_NO_MEMORY;
1530 memcpy( buf, encrypt_params.input, bytes_left );
1531 memset( buf + bytes_left, key->u.s.block_size - bytes_left, key->u.s.block_size - bytes_left );
1532 encrypt_params.input = buf;
1533 status = key_symmetric_encrypt_internal( &encrypt_params );
1534 free( buf );
1535 }
1536
1537 if (!status)
1538 {
1539 if (key->u.s.vector && *ret_len >= key->u.s.vector_len)
1540 {
1541 memcpy( key->u.s.vector, output + *ret_len - key->u.s.vector_len, key->u.s.vector_len );
1542 if (iv) memcpy( iv, key->u.s.vector, min( iv_len, key->u.s.vector_len ));
1543 }
1544 else if (key->u.s.vector)
1545 FIXME( "Unexpected vector len %lu, *ret_len %lu.\n", key->u.s.vector_len, *ret_len );
1546 }
1547
1548 return status;
1549}
1550
1551/* AES Key Wrap Algorithm (RFC3394) */
1552static NTSTATUS aes_wrap( const UCHAR *secret, ULONG secret_len, const UCHAR *plain, ULONG plain_len, UCHAR *cipher )
1553{
1554 UCHAR *a, *r, b[16];
1555 ULONG len, t, i, j, n = plain_len / 8;
1556 struct key *key;
1557
1558 a = cipher;
1559 r = cipher + 8;
1560
1561 memset( a, 0xa6, 8 );
1562 memcpy( r, plain, 8 * n );
1563
1564 if (!(key = key_symmetric_create( ALG_ID_AES, CHAIN_MODE_ECB, 16, secret, secret_len ))) return STATUS_NO_MEMORY;
1565
1566 for (j = 0; j <= 5; j++)
1567 {
1568 r = cipher + 8;
1569 for (i = 1; i <= n; i++)
1570 {
1571 memcpy( b, a, 8 );
1572 memcpy( b + 8, r, 8 );
1573 key_symmetric_encrypt( key, b, 16, NULL, NULL, 0, b, 16, &len, 0 );
1574 memcpy( a, b, 8 );
1575 t = n * j + i;
1576 a[7] ^= t;
1577 a[6] ^= t >> 8;
1578 a[5] ^= t >> 16;
1579 a[4] ^= t >> 24;
1580 memcpy( r, b + 8, 8 );
1581 r += 8;
1582 }
1583 }
1584
1585 key_destroy( key );
1586 return STATUS_SUCCESS;
1587}
1588
1589static NTSTATUS key_export( struct key *key, struct key *encrypt_key, const WCHAR *type, UCHAR *output,
1590 ULONG output_len, ULONG *size )
1591{
1594
1595 if (encrypt_key && wcscmp( type, BCRYPT_AES_WRAP_KEY_BLOB ))
1596 {
1597 FIXME( "encryption of key not supported\n" );
1599 }
1600
1602 {
1604 ULONG req_size = sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + key->u.s.secret_len;
1605
1606 *size = req_size;
1607 if (output_len < req_size) return STATUS_BUFFER_TOO_SMALL;
1608 if (output)
1609 {
1612 header->cbKeyData = key->u.s.secret_len;
1613 memcpy( &header[1], key->u.s.secret, key->u.s.secret_len );
1614 }
1615 return STATUS_SUCCESS;
1616 }
1617 else if (!wcscmp( type, BCRYPT_OPAQUE_KEY_BLOB ))
1618 {
1619 ULONG len, req_size = sizeof(len) + key->u.s.secret_len;
1620
1621 *size = req_size;
1622 if (output_len < req_size) return STATUS_BUFFER_TOO_SMALL;
1623 if (output)
1624 {
1625 *(ULONG *)output = key->u.s.secret_len;
1626 memcpy( output + sizeof(len), key->u.s.secret, key->u.s.secret_len );
1627 }
1628 return STATUS_SUCCESS;
1629 }
1632 {
1633 params.key = key;
1634 params.flags = 0;
1635 params.buf = output;
1636 params.len = output_len;
1637 params.ret_len = size;
1638 return key_asymmetric_export( &params );
1639 }
1641 {
1642 params.key = key;
1644 params.buf = output;
1645 params.len = output_len;
1646 params.ret_len = size;
1647 return key_asymmetric_export( &params );
1648 }
1652 {
1653 params.key = key;
1655 params.buf = output;
1656 params.len = output_len;
1657 params.ret_len = size;
1658 return key_asymmetric_export( &params );
1659 }
1660 else if (!wcscmp( type, BCRYPT_AES_WRAP_KEY_BLOB ))
1661 {
1662 ULONG req_size = key->u.s.secret_len + 8;
1663
1664 if (!encrypt_key) return STATUS_INVALID_PARAMETER;
1665
1666 *size = req_size;
1667 if (output)
1668 {
1669 if (output_len < req_size) return STATUS_BUFFER_TOO_SMALL;
1670 if ((status = aes_wrap( encrypt_key->u.s.secret, encrypt_key->u.s.secret_len, key->u.s.secret, key->u.s.secret_len, output )))
1671 return status;
1672 }
1673 return STATUS_SUCCESS;
1674 }
1675
1676 FIXME( "unsupported key type %s\n", debugstr_w(type) );
1678}
1679
1681 ULONG *rsa_len, UCHAR *input, ULONG input_len )
1682{
1683 struct {
1686 } *blob = (void *)input;
1687 ULONG len, pos;
1688 UCHAR *conv;
1689 int i;
1690
1691 if (alg->id != ALG_ID_RSA) return STATUS_NOT_SUPPORTED;
1692 if (input_len < sizeof(*blob)) return NTE_BAD_DATA;
1693 if (blob->header.bType != PRIVATEKEYBLOB || blob->header.bVersion != CUR_BLOB_VERSION ||
1694 blob->header.aiKeyAlg != CALG_RSA_KEYX ||
1695 blob->rsapubkey.magic != BCRYPT_RSAPRIVATE_MAGIC ||
1696 input_len != sizeof(*blob) + blob->rsapubkey.bitlen / 16 * 9) return NTE_BAD_DATA;
1697 if (blob->rsapubkey.bitlen & 0xf) return STATUS_INVALID_PARAMETER;
1698
1699 len = sizeof(**rsa_data) + sizeof(blob->rsapubkey.pubexp) + blob->rsapubkey.bitlen / 4;
1700 if (!(conv = malloc( len ))) return STATUS_NO_MEMORY;
1701
1702 *rsa_data = (BCRYPT_RSAKEY_BLOB *)conv;
1703 (*rsa_data)->Magic = blob->rsapubkey.magic;
1704 (*rsa_data)->BitLength = blob->rsapubkey.bitlen;
1705 (*rsa_data)->cbPublicExp = sizeof(blob->rsapubkey.pubexp);
1706 (*rsa_data)->cbModulus = blob->rsapubkey.bitlen / 8;
1707 (*rsa_data)->cbPrime1 = blob->rsapubkey.bitlen / 16;
1708 (*rsa_data)->cbPrime2 = blob->rsapubkey.bitlen / 16;
1709 len = sizeof(**rsa_data);
1710
1711 for(i = 0; i < (*rsa_data)->cbPublicExp; i++)
1712 conv[len++] = ((UCHAR *)&blob->rsapubkey.pubexp)[(*rsa_data)->cbPublicExp - i - 1];
1713 pos = sizeof(*blob);
1714 for(i = 0; i < (*rsa_data)->cbModulus; i++)
1715 conv[len++] = input[pos + (*rsa_data)->cbModulus - i - 1];
1716 pos += (*rsa_data)->cbModulus;
1717 for(i = 0; i < (*rsa_data)->cbPrime1; i++)
1718 conv[len++] = input[pos + (*rsa_data)->cbPrime1 - i - 1];
1719 pos += (*rsa_data)->cbPrime1;
1720 for(i = 0; i < (*rsa_data)->cbPrime2; i++)
1721 conv[len++] = input[pos + (*rsa_data)->cbPrime2 - i - 1];
1722
1723 *rsa_len = len;
1724 return STATUS_SUCCESS;
1725}
1726
1728 ULONG input_len )
1729{
1731 struct key *key;
1733 ULONG size;
1734
1736 {
1738 DWORD key_size, magic;
1739
1740 if (input_len < sizeof(*ecc_blob)) return STATUS_INVALID_PARAMETER;
1741
1742 switch (alg->id)
1743 {
1744 case ALG_ID_ECDH_P256:
1745 key_size = 32;
1747 break;
1748
1749 case ALG_ID_ECDH_P384:
1750 key_size = 48;
1752 break;
1753
1754 case ALG_ID_ECDSA_P256:
1755 key_size = 32;
1757 break;
1758
1759 case ALG_ID_ECDSA_P384:
1760 key_size = 48;
1762 break;
1763
1764 default:
1765 FIXME( "algorithm %u does not yet support importing blob of type %s\n", alg->id, debugstr_w(type) );
1766 return STATUS_NOT_SUPPORTED;
1767 }
1768
1769 if (ecc_blob->dwMagic != magic) return STATUS_INVALID_PARAMETER;
1770 if (ecc_blob->cbKey != key_size || input_len < sizeof(*ecc_blob) + ecc_blob->cbKey * 2)
1772
1773 if ((status = key_asymmetric_create( alg->id, key_size * 8, &key ))) return status;
1774 params.key = key;
1776 params.buf = input;
1777 params.len = input_len;
1779 {
1780 key_destroy( key );
1781 return status;
1782 }
1783 }
1784 else if (!wcscmp( type, BCRYPT_ECCPRIVATE_BLOB ))
1785 {
1787 DWORD key_size, magic;
1788
1789 if (input_len < sizeof(*ecc_blob)) return STATUS_INVALID_PARAMETER;
1790
1791 switch (alg->id)
1792 {
1793 case ALG_ID_ECDH_P256:
1794 key_size = 32;
1796 break;
1797
1798 case ALG_ID_ECDH_P384:
1799 key_size = 48;
1801 break;
1802
1803 case ALG_ID_ECDSA_P256:
1804 key_size = 32;
1806 break;
1807
1808 default:
1809 FIXME( "algorithm %u does not yet support importing blob of type %s\n", alg->id, debugstr_w(type) );
1810 return STATUS_NOT_SUPPORTED;
1811 }
1812
1813 if (ecc_blob->dwMagic != magic) return STATUS_INVALID_PARAMETER;
1814 if (ecc_blob->cbKey != key_size || input_len < sizeof(*ecc_blob) + ecc_blob->cbKey * 3)
1816
1817 if ((status = key_asymmetric_create( alg->id, key_size * 8, &key ))) return status;
1818 params.key = key;
1819 params.flags = 0;
1820 params.buf = input;
1821 params.len = input_len;
1823 {
1824 key_destroy( key );
1825 return status;
1826 }
1827 }
1828 else if (!wcscmp( type, BCRYPT_RSAPUBLIC_BLOB ))
1829 {
1831
1832 if (input_len < sizeof(*rsa_blob)) return STATUS_INVALID_PARAMETER;
1833 if ((alg->id != ALG_ID_RSA && alg->id != ALG_ID_RSA_SIGN) || rsa_blob->Magic != BCRYPT_RSAPUBLIC_MAGIC)
1834 return STATUS_NOT_SUPPORTED;
1835
1836 size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
1837 if (size != input_len) return NTE_BAD_DATA;
1838
1839 if ((status = key_asymmetric_create( alg->id, rsa_blob->BitLength, &key ))) return status;
1840 params.key = key;
1842 params.buf = input;
1843 params.len = input_len;
1845 {
1846 key_destroy( key );
1847 return status;
1848 }
1849 }
1851 {
1853
1854 if (input_len < sizeof(*rsa_blob)) return STATUS_INVALID_PARAMETER;
1855 if (alg->id != ALG_ID_RSA || (rsa_blob->Magic != BCRYPT_RSAPRIVATE_MAGIC &&
1857
1858 if ((status = key_asymmetric_create( alg->id, rsa_blob->BitLength, &key ))) return status;
1859 params.key = key;
1860 params.flags = 0;
1861 params.buf = input;
1862 params.len = input_len;
1864 {
1865 key_destroy( key );
1866 return status;
1867 }
1868 }
1869 else if (!wcscmp( type, LEGACY_RSAPRIVATE_BLOB ))
1870 {
1871 BCRYPT_RSAKEY_BLOB *rsa_blob;
1872
1873 status = convert_legacy_rsaprivate_blob( alg, &rsa_blob, &input_len, input, input_len );
1874 if (status != STATUS_SUCCESS)
1875 return status;
1876
1877 status = key_import_pair( alg, BCRYPT_RSAPRIVATE_BLOB, ret_key, (UCHAR *)rsa_blob, input_len );
1878 SecureZeroMemory( rsa_blob, input_len );
1879 free( rsa_blob );
1880 return status;
1881 }
1882 else if (!wcscmp( type, BCRYPT_DSA_PUBLIC_BLOB ))
1883 {
1885
1886 if (input_len < sizeof(*dsa_blob)) return STATUS_INVALID_PARAMETER;
1887 if (alg->id != ALG_ID_DSA || dsa_blob->dwMagic != BCRYPT_DSA_PUBLIC_MAGIC)
1888 return STATUS_NOT_SUPPORTED;
1889
1890 if ((status = key_asymmetric_create( alg->id, dsa_blob->cbKey * 8, &key ))) return status;
1891 params.key = key;
1893 params.buf = input;
1894 params.len = input_len;
1896 {
1897 key_destroy( key );
1898 return status;
1899 }
1900 }
1902 {
1905
1906 if (input_len < sizeof(*hdr)) return STATUS_INVALID_PARAMETER;
1907
1908 if (hdr->bType != PRIVATEKEYBLOB && hdr->bVersion != 2 && hdr->aiKeyAlg != CALG_DSS_SIGN)
1909 {
1910 FIXME( "blob type %u version %u alg id %u not supported\n", hdr->bType, hdr->bVersion, hdr->aiKeyAlg );
1911 return STATUS_NOT_SUPPORTED;
1912 }
1913 if (alg->id != ALG_ID_DSA)
1914 {
1915 FIXME( "algorithm %u does not support importing blob of type %s\n", alg->id, debugstr_w(type) );
1916 return STATUS_NOT_SUPPORTED;
1917 }
1918
1919 if (input_len < sizeof(*hdr) + sizeof(*pubkey)) return STATUS_INVALID_PARAMETER;
1920 pubkey = (DSSPUBKEY *)(hdr + 1);
1921 if (pubkey->magic != MAGIC_DSS2) return STATUS_NOT_SUPPORTED;
1922
1923 if (input_len < sizeof(*hdr) + sizeof(*pubkey) + (pubkey->bitlen / 8) * 2 + 40 + sizeof(DSSSEED))
1925
1926 if ((status = key_asymmetric_create( alg->id, pubkey->bitlen, &key ))) return status;
1927 key->u.a.flags |= KEY_FLAG_LEGACY_DSA_V2;
1928 params.key = key;
1929 params.flags = 0;
1930 params.buf = input;
1931 params.len = input_len;
1933 {
1934 key_destroy( key );
1935 return status;
1936 }
1937 }
1938 else if (!wcscmp( type, LEGACY_DSA_V2_PUBLIC_BLOB )) /* not supported on native */
1939 {
1942
1943 if (alg->id != ALG_ID_DSA) return STATUS_NOT_SUPPORTED;
1944 if (input_len < sizeof(*hdr)) return STATUS_INVALID_PARAMETER;
1945
1946 if (hdr->bType != PUBLICKEYBLOB && hdr->bVersion != 2 && hdr->aiKeyAlg != CALG_DSS_SIGN)
1947 {
1948 FIXME( "blob type %u version %u alg id %u not supported\n", hdr->bType, hdr->bVersion, hdr->aiKeyAlg );
1949 return STATUS_NOT_SUPPORTED;
1950 }
1951
1952 if (input_len < sizeof(*hdr) + sizeof(*pubkey)) return STATUS_INVALID_PARAMETER;
1953 pubkey = (DSSPUBKEY *)(hdr + 1);
1954 if (pubkey->magic != MAGIC_DSS1) return STATUS_NOT_SUPPORTED;
1955
1956 size = sizeof(*hdr) + sizeof(*pubkey) + (pubkey->bitlen / 8) * 3 + 20 + sizeof(DSSSEED);
1957 if (input_len < size) return STATUS_INVALID_PARAMETER;
1958
1959 if ((status = key_asymmetric_create( alg->id, pubkey->bitlen, &key ))) return status;
1960 key->u.a.flags |= KEY_FLAG_LEGACY_DSA_V2;
1961 params.key = key;
1963 params.buf = input;
1964 params.len = input_len;
1966 {
1967 key_destroy( key );
1968 return status;
1969 }
1970 }
1971 else if (!wcscmp( type, BCRYPT_DH_PRIVATE_BLOB ))
1972 {
1974
1975 if (input_len != sizeof(*dh_blob) + dh_blob->cbKey * 4) return STATUS_INVALID_PARAMETER;
1976 if (alg->id != ALG_ID_DH || dh_blob->dwMagic != BCRYPT_DH_PRIVATE_MAGIC)
1977 return STATUS_NOT_SUPPORTED;
1978
1979 if ((status = key_asymmetric_create( alg->id, dh_blob->cbKey * 8, &key ))) return status;
1980 params.key = key;
1981 params.flags = 0;
1982 params.buf = input;
1983 params.len = input_len;
1985 {
1986 key_destroy( key );
1987 return status;
1988 }
1989 }
1990 else if (!wcscmp( type, BCRYPT_DH_PUBLIC_BLOB ))
1991 {
1993
1994 if (input_len != sizeof(*dh_blob) + dh_blob->cbKey * 3) return STATUS_INVALID_PARAMETER;
1995 if (alg->id != ALG_ID_DH || dh_blob->dwMagic != BCRYPT_DH_PUBLIC_MAGIC)
1996 return STATUS_NOT_SUPPORTED;
1997
1998 if ((status = key_asymmetric_create( alg->id, dh_blob->cbKey * 8, &key ))) return status;
1999 params.key = key;
2001 params.buf = input;
2002 params.len = input_len;
2004 {
2005 key_destroy( key );
2006 return status;
2007 }
2008 }
2009 else
2010 {
2011 FIXME( "unsupported key type %s\n", debugstr_w(type) );
2012 return STATUS_NOT_SUPPORTED;
2013 }
2014
2015 if (!status)
2016 {
2017 key->u.a.flags |= KEY_FLAG_FINALIZED;
2018 *ret_key = key;
2019 }
2020 return status;
2021}
2022
2024 UCHAR *object, ULONG object_len, UCHAR *secret, ULONG secret_len,
2025 ULONG flags )
2026{
2027 struct algorithm *alg = get_alg_object( handle );
2029
2030 TRACE( "%p, %p, %p, %lu, %p, %lu, %#lx\n", handle, ret_handle, object, object_len, secret, secret_len, flags );
2031 if (object) FIXME( "ignoring object buffer\n" );
2032 if (!alg) return STATUS_INVALID_HANDLE;
2033 if ((status = key_symmetric_generate( alg, ret_handle, secret, secret_len ))) return status;
2034 TRACE( "returning handle %p\n", *ret_handle );
2035 return STATUS_SUCCESS;
2036}
2037
2039 ULONG flags )
2040{
2041 struct algorithm *alg = get_alg_object( handle );
2042 struct key *key;
2044
2045 TRACE( "%p, %p, %lu, %#lx\n", handle, ret_handle, key_len, flags );
2046
2047 if (!alg) return STATUS_INVALID_HANDLE;
2048 if (!ret_handle) return STATUS_INVALID_PARAMETER;
2049
2050 if ((status = key_asymmetric_create( alg->id, key_len, &key ))) return status;
2051 *ret_handle = key;
2052 TRACE( "returning handle %p\n", *ret_handle );
2053 return STATUS_SUCCESS;
2054}
2055
2057{
2058 struct key *key = get_key_object( handle );
2059 NTSTATUS ret;
2060
2061 TRACE( "%p, %#lx\n", key, flags );
2062
2063 if (!key || key->u.a.flags & KEY_FLAG_FINALIZED) return STATUS_INVALID_HANDLE;
2064
2065 if (!(ret = key_asymmetric_generate( key ))) key->u.a.flags |= KEY_FLAG_FINALIZED;
2066 return ret;
2067}
2068
2070 BCRYPT_KEY_HANDLE *ret_handle, UCHAR *object, ULONG object_len, UCHAR *input,
2071 ULONG input_len, ULONG flags )
2072{
2073 struct algorithm *alg = get_alg_object( handle );
2074 struct key *decrypt_key = NULL;
2076
2077 TRACE( "%p, %p, %s, %p, %p, %lu, %p, %lu, %#lx\n", handle, decrypt_key_handle, debugstr_w(type), ret_handle,
2078 object, object_len, input, input_len, flags );
2079
2080 if (!alg) return STATUS_INVALID_HANDLE;
2081 if (!ret_handle || !type || !input) return STATUS_INVALID_PARAMETER;
2082 if (decrypt_key_handle && !(decrypt_key = get_key_object( decrypt_key_handle ))) return STATUS_INVALID_HANDLE;
2083
2084 if ((status = key_import( alg, decrypt_key, type, ret_handle, object, object_len, input, input_len ))) return status;
2085 TRACE( "returning handle %p\n", *ret_handle );
2086 return STATUS_SUCCESS;
2087}
2088
2090 const WCHAR *type, UCHAR *output, ULONG output_len, ULONG *size, ULONG flags )
2091{
2092 struct key *key = get_key_object( export_key_handle );
2093 struct key *encrypt_key = NULL;
2094
2095 TRACE( "%p, %p, %s, %p, %lu, %p, %#lx\n", export_key_handle, encrypt_key_handle, debugstr_w(type), output,
2096 output_len, size, flags );
2097
2098 if (!key) return STATUS_INVALID_HANDLE;
2099 if (!type || !size) return STATUS_INVALID_PARAMETER;
2100 if (encrypt_key_handle && !(encrypt_key = get_key_object( encrypt_key_handle ))) return STATUS_INVALID_HANDLE;
2101
2102 return key_export( key, encrypt_key, type, output, output_len, size );
2103}
2104
2105static NTSTATUS key_duplicate( struct key *key_orig, struct key **ret_key )
2106{
2108 struct key *key_copy;
2110 UCHAR *buffer;
2111
2112 if (!(key_copy = calloc( 1, sizeof(*key_copy) ))) return STATUS_NO_MEMORY;
2113 key_copy->hdr = key_orig->hdr;
2114 key_copy->alg_id = key_orig->alg_id;
2115
2116 if (is_symmetric_key( key_orig ))
2117 {
2118 if (!(buffer = malloc( key_orig->u.s.secret_len )))
2119 {
2120 free( key_copy );
2121 return STATUS_NO_MEMORY;
2122 }
2123 memcpy( buffer, key_orig->u.s.secret, key_orig->u.s.secret_len );
2124
2125 key_copy->u.s.mode = key_orig->u.s.mode;
2126 key_copy->u.s.block_size = key_orig->u.s.block_size;
2127 key_copy->u.s.secret = buffer;
2128 key_copy->u.s.secret_len = key_orig->u.s.secret_len;
2129 InitializeCriticalSection( &key_copy->u.s.cs );
2130 *ret_key = key_copy;
2131 return STATUS_SUCCESS;
2132 }
2133
2134 key_copy->u.a.bitlen = key_orig->u.a.bitlen;
2135 key_copy->u.a.flags = key_orig->u.a.flags;
2136 key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
2137
2138 params.key_orig = key_orig;
2139 params.key_copy = key_copy;
2140 if (!(status = key_asymmetric_duplicate ( &params ))) *ret_key = key_copy;
2141 else free( key_copy );
2142 return status;
2143}
2144
2146 ULONG object_len, ULONG flags )
2147{
2148 struct key *key_orig = get_key_object( handle );
2149 struct key *key_copy;
2151
2152 TRACE( "%p, %p, %p, %lu, %#lx\n", handle, handle_copy, object, object_len, flags );
2153 if (object) FIXME( "ignoring object buffer\n" );
2154
2155 if (!key_orig) return STATUS_INVALID_HANDLE;
2156 if (!handle_copy) return STATUS_INVALID_PARAMETER;
2157
2158 if ((status = key_duplicate( key_orig, &key_copy ))) return status;
2159
2160 *handle_copy = key_copy;
2161 TRACE( "returning handle %p\n", *handle_copy );
2162 return STATUS_SUCCESS;
2163}
2164
2165static const WCHAR *resolve_blob_type( const WCHAR *type, UCHAR *input, ULONG input_len )
2166{
2168
2169 if (!type) return NULL;
2170 if (wcscmp( type, BCRYPT_PUBLIC_KEY_BLOB )) return type;
2171 if (input_len < sizeof(*blob)) return NULL;
2172
2173 switch (blob->Magic)
2174 {
2179 return BCRYPT_ECCPUBLIC_BLOB;
2180
2182 return BCRYPT_RSAPUBLIC_BLOB;
2183
2186
2187 default:
2188 FIXME( "unsupported key magic %#lx\n", blob->Magic );
2189 return NULL;
2190 }
2191}
2192
2194 BCRYPT_KEY_HANDLE *ret_handle, UCHAR *input, ULONG input_len, ULONG flags )
2195{
2196 struct algorithm *alg = get_alg_object( handle );
2198
2199 TRACE( "%p, %p, %s, %p, %p, %lu, %#lx\n", handle, decrypt_key_handle, debugstr_w(type), ret_handle, input,
2200 input_len, flags );
2201
2202 if (!alg) return STATUS_INVALID_HANDLE;
2203 if (!ret_handle || !input || !(type = resolve_blob_type( type, input, input_len )))
2205 if (decrypt_key_handle)
2206 {
2207 FIXME( "decryption of key not yet supported\n" );
2209 }
2210
2211 if ((status = key_import_pair( alg, type, ret_handle, input, input_len ))) return status;
2212 TRACE( "returning handle %p\n", *ret_handle );
2213 return STATUS_SUCCESS;
2214}
2215
2217 UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags )
2218{
2220 struct key *key = get_key_object( handle );
2221
2222 TRACE( "%p, %p, %p, %lu, %p, %lu, %p, %#lx\n", handle, padding, input, input_len, output, output_len,
2223 ret_len, flags );
2224
2225 if (!key) return STATUS_INVALID_HANDLE;
2227
2228 params.key = key;
2229 params.padding = padding;
2230 params.input = input;
2231 params.input_len = input_len;
2232 params.output = output;
2233 params.output_len = output_len;
2234 params.ret_len = ret_len;
2235 params.flags = flags;
2236 return key_asymmetric_sign( &params );
2237}
2238
2240 UCHAR *signature, ULONG signature_len, ULONG flags )
2241{
2243 struct key *key = get_key_object( handle );
2244
2245 TRACE( "%p, %p, %p, %lu, %p, %lu, %#lx\n", handle, padding, hash, hash_len, signature, signature_len, flags );
2246
2247 if (!key) return STATUS_INVALID_HANDLE;
2249 if (!hash || !hash_len || !signature || !signature_len) return STATUS_INVALID_PARAMETER;
2250
2251 params.key = key;
2252 params.padding = padding;
2253 params.hash = hash;
2254 params.hash_len = hash_len;
2255 params.signature = signature;
2256 params.signature_len = signature_len;
2257 params.flags = flags;
2258 return key_asymmetric_verify( &params );
2259}
2260
2262{
2263 struct key *key = get_key_object( handle );
2264
2265 TRACE( "%p\n", handle );
2266
2267 if (!key) return STATUS_INVALID_HANDLE;
2268 key_destroy( key );
2269 return STATUS_SUCCESS;
2270}
2271
2273 ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags )
2274{
2275 struct key *key = get_key_object( handle );
2276 struct key_asymmetric_encrypt_params asymmetric_params;
2277 NTSTATUS ret;
2278
2279 TRACE( "%p, %p, %lu, %p, %p, %lu, %p, %lu, %p, %#lx\n", handle, input, input_len, padding, iv, iv_len, output,
2281
2282 if (!key) return STATUS_INVALID_HANDLE;
2283
2284 if (is_symmetric_key( key ))
2285 {
2287 {
2288 FIXME( "flags %#lx not implemented\n", flags );
2290 }
2291 EnterCriticalSection( &key->u.s.cs );
2293 LeaveCriticalSection( &key->u.s.cs );
2294 }
2295 else
2296 {
2297 if (flags & BCRYPT_PAD_NONE)
2298 {
2299 FIXME( "flags %#lx not implemented\n", flags );
2301 }
2303
2304 asymmetric_params.input = input;
2305 asymmetric_params.input_len = input_len;
2306 asymmetric_params.padding = padding;
2307 asymmetric_params.key = key;
2308 asymmetric_params.output = output;
2309 asymmetric_params.output_len = output_len;
2310 asymmetric_params.ret_len = ret_len;
2311 asymmetric_params.flags = flags;
2312 ret = key_asymmetric_encrypt( &asymmetric_params );
2313 }
2314
2315 return ret;
2316}
2317
2320{
2321 struct key *key = get_key_object( handle );
2323 NTSTATUS ret;
2324
2325 TRACE( "%p, %p, %lu, %p, %p, %lu, %p, %lu, %p, %#lx\n", handle, input, input_len, padding, iv, iv_len, output,
2327
2328 if (!key) return STATUS_INVALID_HANDLE;
2329
2330 if (is_symmetric_key( key ))
2331 {
2333 {
2334 FIXME( "flags %#lx not supported\n", flags );
2336 }
2337
2338 EnterCriticalSection( &key->u.s.cs );
2340 LeaveCriticalSection( &key->u.s.cs );
2341 }
2342 else
2343 {
2344 if (flags & BCRYPT_PAD_NONE)
2345 {
2346 FIXME( "flags %#lx not implemented\n", flags );
2348 }
2350
2351 params.key = key;
2352 params.input = input;
2353 params.input_len = input_len;
2354 params.padding = padding;
2355 params.output = output;
2356 params.output_len = output_len;
2357 params.ret_len = ret_len;
2358 params.flags = flags;
2360 }
2361
2362 return ret;
2363}
2364
2366{
2367 struct object *object = get_object( handle, 0 );
2368
2369 TRACE( "%p, %s, %p, %lu, %#lx\n", handle, debugstr_w(prop), value, size, flags );
2370
2371 if (!handle) return STATUS_INVALID_HANDLE;
2373
2374 switch (object->magic)
2375 {
2376 case MAGIC_ALG:
2377 {
2378 struct algorithm *alg = (struct algorithm *)object;
2379 return set_alg_property( alg, prop, value, size, flags );
2380 }
2381 case MAGIC_KEY:
2382 {
2383 struct key *key = (struct key *)object;
2384 return set_key_property( key, prop, value, size, flags );
2385 }
2386 default:
2387 WARN( "unknown magic %#lx\n", object->magic );
2388 return STATUS_INVALID_HANDLE;
2389 }
2390}
2391
2392#define HMAC_PAD_LEN 64
2394{
2395 struct hash *hash = get_hash_object( handle );
2397 ULONG len, hash_size;
2398
2399 TRACE( "%p, %p, %p, %lu, %#lx\n", handle, halg, key, keylen, flags );
2400
2401 if (!hash) return STATUS_INVALID_HANDLE;
2402 if (!key || !keylen) return STATUS_INVALID_PARAMETER;
2403 hash_get_size( hash, &hash_size );
2404 if (keylen > hash_size * 2) return STATUS_INVALID_PARAMETER;
2405 if (halg)
2406 {
2407 FIXME( "algorithm handle not supported\n" );
2409 }
2410
2411 hash_finalize( hash, buf, sizeof(buf) );
2412 len = hash_size;
2413 if (len < keylen)
2414 {
2415 UCHAR pad1[HMAC_PAD_LEN], pad2[HMAC_PAD_LEN];
2416 ULONG i;
2417
2418 for (i = 0; i < sizeof(pad1); i++)
2419 {
2420 pad1[i] = 0x36 ^ (i < len ? buf[i] : 0);
2421 pad2[i] = 0x5c ^ (i < len ? buf[i] : 0);
2422 }
2423
2424 hash_prepare( hash );
2425 hash_update( hash, pad1, sizeof(pad1) );
2426 hash_finish( hash, buf );
2427
2428 hash_prepare( hash );
2429 hash_update( hash, pad2, sizeof(pad2) );
2430 hash_finish( hash, buf + len );
2431 }
2432 memcpy( key, buf, keylen );
2433 return STATUS_SUCCESS;
2434}
2435
2437 ULONGLONG iterations, ULONG i, UCHAR *dst, ULONG hash_len )
2438{
2439 UCHAR bytes[4], *buf;
2440 ULONG j, k;
2441
2443 if (!(buf = malloc( hash_len ))) return STATUS_NO_MEMORY;
2444
2445 for (j = 0; j < iterations; j++)
2446 {
2447 if (j == 0)
2448 {
2449 /* use salt || INT(i) */
2451 {
2452 free( buf );
2454 }
2455 bytes[0] = (i >> 24) & 0xff;
2456 bytes[1] = (i >> 16) & 0xff;
2457 bytes[2] = (i >> 8) & 0xff;
2458 bytes[3] = i & 0xff;
2459 hash_update( hash, bytes, 4 );
2460 }
2461 else hash_update( hash, buf, hash_len ); /* use U_j */
2462
2463 hash_finalize( hash, buf, hash_len );
2464 if (j == 0) memcpy( dst, buf, hash_len );
2465 else for (k = 0; k < hash_len; k++) dst[k] ^= buf[k];
2466 }
2467
2468 free( buf );
2469 return STATUS_SUCCESS;
2470}
2471
2474{
2475 ULONG hash_len, block_count, bytes_left, i;
2476 struct hash *hash;
2477 UCHAR *partial;
2479
2480 hash_len = builtin_algorithms[alg->id].hash_length;
2481 if (dk_len <= 0 || dk_len > ((((ULONGLONG)1) << 32) - 1) * hash_len) return STATUS_INVALID_PARAMETER;
2482
2483 block_count = 1 + ((dk_len - 1) / hash_len); /* ceil(dk_len / hash_len) */
2484 bytes_left = dk_len - (block_count - 1) * hash_len;
2485
2487
2488 /* full blocks */
2489 for (i = 1; i < block_count; i++)
2490 {
2491 if ((status = pbkdf2( hash, pwd, pwd_len, salt, salt_len, iterations, i, dk + ((i - 1) * hash_len), hash_len )))
2492 {
2493 hash_destroy( hash );
2494 return status;
2495 }
2496 }
2497
2498 /* final partial block */
2499 if (!(partial = malloc( hash_len )))
2500 {
2501 hash_destroy( hash );
2502 return STATUS_NO_MEMORY;
2503 }
2504
2505 if ((status = pbkdf2( hash, pwd, pwd_len, salt, salt_len, iterations, block_count, partial, hash_len )))
2506 {
2507 hash_destroy( hash );
2508 free( partial );
2509 return status;
2510 }
2511 memcpy( dk + ((block_count - 1) * hash_len), partial, bytes_left );
2512
2513 hash_destroy( hash );
2514 free( partial );
2515 return STATUS_SUCCESS;
2516}
2517
2520{
2521 struct algorithm *alg = get_alg_object( handle );
2522
2523 TRACE( "%p, %p, %lu, %p, %lu, %s, %p, %lu, %#lx\n", handle, pwd, pwd_len, salt, salt_len,
2525
2526 if (!alg) return STATUS_INVALID_HANDLE;
2528}
2529
2531 BCRYPT_SECRET_HANDLE *ret_handle, ULONG flags )
2532{
2533 struct key *privkey = get_key_object( privkey_handle );
2534 struct key *pubkey = get_key_object( pubkey_handle );
2535 struct secret *secret;
2537
2538 TRACE( "%p, %p, %p, %#lx\n", privkey_handle, pubkey_handle, ret_handle, flags );
2539
2540 if (!privkey || !pubkey) return STATUS_INVALID_HANDLE;
2542 if (!ret_handle) return STATUS_INVALID_PARAMETER;
2543
2544 if (!(secret = calloc( 1, sizeof(*secret) ))) return STATUS_NO_MEMORY;
2545 secret->hdr.magic = MAGIC_SECRET;
2547 {
2548 free( secret );
2549 return status;
2550 }
2551 if ((status = key_duplicate( pubkey, &secret->pubkey )))
2552 {
2554 free( secret );
2555 return status;
2556 }
2557
2558 *ret_handle = secret;
2559 TRACE( "returning handle %p\n", *ret_handle );
2560 return STATUS_SUCCESS;
2561}
2562
2564{
2566
2567 TRACE( "%p\n", handle );
2568
2569 if (!secret) return STATUS_INVALID_HANDLE;
2573 return STATUS_SUCCESS;
2574}
2575
2577{
2578 ULONG i;
2579 for (i = 0; i < len / 2; i++)
2580 {
2581 UCHAR tmp = buf[i];
2582 buf[i] = buf[len - i - 1];
2583 buf[len - i - 1] = tmp;
2584 }
2585}
2586
2587static NTSTATUS derive_key_raw( struct secret *secret, UCHAR *output, ULONG output_len, ULONG *ret_len )
2588{
2591
2592 params.privkey = secret->privkey;
2593 params.pubkey = secret->pubkey;
2594 params.output = output;
2595 params.output_len = output_len;
2596 params.ret_len = ret_len;
2598 return status;
2599}
2600
2602{
2603 const WCHAR *str = buf->pvBuffer;
2605
2608 else if (!wcscmp( str, BCRYPT_SHA256_ALGORITHM ))
2610 else if (!wcscmp( str, BCRYPT_SHA384_ALGORITHM ))
2612 else if (!wcscmp( str, BCRYPT_SHA512_ALGORITHM ))
2614
2615 if (handle) return get_alg_object( handle );
2616 FIXME( "hash algorithm %s not supported\n", debugstr_w(str) );
2617 return NULL;
2618}
2619
2620static NTSTATUS derive_key_hash( struct secret *secret, BCryptBufferDesc *desc, UCHAR *output, ULONG output_len,
2621 ULONG *ret_len )
2622{
2624 ULONG hash_len, derived_key_len = secret->privkey->u.a.bitlen / 8;
2625 UCHAR hash_buf[MAX_HASH_OUTPUT_BYTES];
2626 struct algorithm *alg = NULL;
2627 UCHAR *derived_key;
2629 ULONG i;
2630
2631 for (i = 0; i < (desc ? desc->cBuffers : 0); i++)
2632 {
2633 if (desc->pBuffers[i].BufferType == KDF_HASH_ALGORITHM)
2634 {
2635 alg = get_hash_alg( desc->pBuffers + i, FALSE );
2636 if (!alg) return STATUS_NOT_SUPPORTED;
2637 }
2638 else FIXME( "buffer type %lu not supported\n", desc->pBuffers[i].BufferType );
2639 }
2640 if (!alg) alg = get_alg_object( BCRYPT_SHA1_ALG_HANDLE );
2641
2642 if (!(derived_key = malloc( derived_key_len ))) return STATUS_NO_MEMORY;
2643
2644 params.privkey = secret->privkey;
2645 params.pubkey = secret->pubkey;
2646 params.output = derived_key;
2647 params.output_len = derived_key_len;
2648 params.ret_len = ret_len;
2650 {
2651 free( derived_key );
2652 return status;
2653 }
2654
2655 hash_len = builtin_algorithms[alg->id].hash_length;
2656#if !defined(__REACTOS__)
2657 assert( hash_len <= sizeof(hash_buf) );
2658#endif
2659 if (!(status = hash_single( alg, NULL, 0, derived_key, *params.ret_len, hash_buf, hash_len )))
2660 {
2661 if (!output) *ret_len = hash_len;
2662 else
2663 {
2664 *ret_len = min( hash_len, output_len );
2665 memcpy( output, hash_buf, *ret_len );
2666 }
2667 }
2668
2669 free( derived_key );
2670 return status;
2671}
2672
2674 UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags )
2675{
2677
2678 TRACE( "%p, %s, %p, %p, %lu, %p, %#lx\n", secret, debugstr_w(kdf), desc, output, output_len,
2679 ret_len, flags );
2680
2681 if (!secret) return STATUS_INVALID_HANDLE;
2682 if (!kdf || !ret_len) return STATUS_INVALID_PARAMETER;
2683
2684 if (!wcscmp(kdf, BCRYPT_KDF_RAW_SECRET))
2685 {
2686 return derive_key_raw( secret, output, output_len, ret_len );
2687 }
2688 else if (!wcscmp(kdf, BCRYPT_KDF_HASH))
2689 {
2690 return derive_key_hash( secret, desc, output, output_len, ret_len );
2691 }
2692
2693 FIXME( "kdf %s not supportedi\n", debugstr_w(kdf) );
2694 return STATUS_NOT_SUPPORTED;
2695}
2696
2698 UCHAR *output, ULONG output_size, ULONG *ret_len, ULONG flags )
2699{
2700 struct key *key = get_key_object( handle );
2701 struct algorithm *alg = NULL;
2702 ULONGLONG iter_count = 10000;
2703 ULONG salt_size = 0;
2704 UCHAR *salt = NULL;
2706 ULONG i;
2707
2708 TRACE( "%p, %p, %p, %lu, %p, %#lx\n", key, desc, output, output_size, ret_len, flags );
2709
2710 if (!key || !desc || !ret_len) return STATUS_INVALID_PARAMETER;
2711 if (key->alg_id != ALG_ID_PBKDF2)
2712 {
2713 FIXME( "unsupported key %d\n", key->alg_id );
2715 }
2716
2717 for (i = 0; i < desc->cBuffers; i++)
2718 {
2719 switch (desc->pBuffers[i].BufferType)
2720 {
2721 case KDF_HASH_ALGORITHM:
2722 alg = get_hash_alg( desc->pBuffers + i, TRUE );
2723 break;
2724 case KDF_SALT:
2725 salt = desc->pBuffers[i].pvBuffer;
2726 salt_size = desc->pBuffers[i].cbBuffer;
2727 break;
2729 if (desc->pBuffers[i].cbBuffer != sizeof(ULONGLONG)) return STATUS_INVALID_PARAMETER;
2730 iter_count = *(ULONGLONG *)desc->pBuffers[i].pvBuffer;
2731 break;
2732 default:
2733 FIXME( "buffer type %lu not supported\n", desc->pBuffers[i].BufferType );
2734 break;
2735 }
2736 }
2737
2738 status = derive_key_pbkdf2( alg, key->u.s.secret, key->u.s.secret_len,
2739 salt, salt_size, iter_count, output, output_size );
2740 if (!status) *ret_len = output_size;
2741 return status;
2742}
2743
2745{
2746 switch (reason)
2747 {
2748 case DLL_PROCESS_ATTACH:
2749 instance = hinst;
2752 break;
2753 case DLL_PROCESS_DETACH:
2754 if (reserved) break;
2756 break;
2757 }
2758 return TRUE;
2759}
unsigned char BOOLEAN
Definition: actypes.h:127
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
LONG NTSTATUS
Definition: precomp.h:26
#define ARRAY_SIZE(A)
Definition: main.h:20
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
RSAPUBKEY rsapubkey
Definition: bcrypt.c:2457
ULONG pwd_len
Definition: bcrypt.c:537
ULONGLONG iterations
Definition: bcrypt.c:539
const UCHAR * dk
Definition: bcrypt.c:543
UCHAR * pwd
Definition: bcrypt.c:541
ULONG dk_len
Definition: bcrypt.c:540
ULONG salt_len
Definition: bcrypt.c:538
static UCHAR salt[]
Definition: bcrypt.c:521
#define BCRYPT_MD4_ALGORITHM
Definition: bcrypt.h:97
#define BCRYPT_KEY_LENGTHS
Definition: bcrypt.h:53
#define LEGACY_RSAPRIVATE_BLOB
Definition: bcrypt.h:81
#define BCRYPT_RSAPUBLIC_BLOB
Definition: bcrypt.h:67
#define BCRYPT_RNG_ALG_HANDLE
Definition: bcrypt.h:385
#define LEGACY_DSA_V2_PRIVATE_BLOB
Definition: bcrypt.h:79
#define BCRYPT_KDF_HASH
Definition: bcrypt.h:117
#define BCRYPT_ECDH_P384_ALGORITHM
Definition: bcrypt.h:92
#define BCRYPT_SECRET_AGREEMENT_OPERATION
Definition: bcrypt.h:142
#define BCRYPT_3DES_ALGORITHM
Definition: bcrypt.h:86
#define BCRYPT_CHAIN_MODE_GCM
Definition: bcrypt.h:115
#define BCRYPT_SIGNATURE_OPERATION
Definition: bcrypt.h:143
#define BCRYPT_HASH_OPERATION
Definition: bcrypt.h:140
#define BCRYPT_DH_PUBLIC_MAGIC
Definition: bcrypt.h:280
#define BCRYPT_ECDH_PRIVATE_P256_MAGIC
Definition: bcrypt.h:133
#define BCRYPT_KEY_DATA_BLOB_MAGIC
Definition: bcrypt.h:367
#define BCRYPT_HMAC_SHA1_ALG_HANDLE
Definition: bcrypt.h:387
#define BCRYPT_ECDSA_PUBLIC_P256_MAGIC
Definition: bcrypt.h:125
#define BCRYPT_ECDSA_P384_ALGORITHM
Definition: bcrypt.h:94
#define BCRYPT_ECCPUBLIC_BLOB
Definition: bcrypt.h:65
#define BCRYPT_RSA_ALGORITHM
Definition: bcrypt.h:102
#define BCRYPT_KEY_DERIVATION_INTERFACE
Definition: bcrypt.h:153
#define BCRYPT_ECDH_PUBLIC_P384_MAGIC
Definition: bcrypt.h:134
#define BCRYPT_SHA256_ALG_HANDLE
Definition: bcrypt.h:381
#define LEGACY_DSA_V2_PUBLIC_BLOB
Definition: bcrypt.h:78
#define BCRYPT_SHA384_ALG_HANDLE
Definition: bcrypt.h:382
#define BCRYPT_OBJECT_LENGTH
Definition: bcrypt.h:56
#define BCRYPT_RC4_ALGORITHM
Definition: bcrypt.h:100
#define BCRYPT_ECDSA_PUBLIC_P384_MAGIC
Definition: bcrypt.h:127
#define KDF_SALT
Definition: bcrypt.h:348
#define BCRYPT_KEY_LENGTH
Definition: bcrypt.h:52
#define BCRYPT_AUTH_TAG_LENGTH
Definition: bcrypt.h:44
#define BCRYPT_CHAINING_MODE
Definition: bcrypt.h:47
#define BCRYPT_CHAIN_MODE_CFB
Definition: bcrypt.h:113
#define BCRYPT_CHAIN_MODE_CBC
Definition: bcrypt.h:111
#define KDF_ITERATION_COUNT
Definition: bcrypt.h:349
#define BCRYPT_KEY_DATA_BLOB
Definition: bcrypt.h:63
#define BCRYPT_SHA512_ALGORITHM
Definition: bcrypt.h:107
#define BCRYPT_ALGORITHM_NAME
Definition: bcrypt.h:43
#define BCRYPT_DH_PARAMETERS
Definition: bcrypt.h:123
#define BCRYPT_DSA_ALGORITHM
Definition: bcrypt.h:90
#define BCRYPT_KEY_STRENGTH
Definition: bcrypt.h:55
#define BCRYPT_AES_ALGORITHM
Definition: bcrypt.h:87
#define BCRYPT_PBKDF2_ALGORITHM
Definition: bcrypt.h:108
#define BCRYPT_SUPPORTED_PAD_PKCS1_SIG
Definition: bcrypt.h:157
struct _BCRYPT_KEY_DATA_BLOB_HEADER BCRYPT_KEY_DATA_BLOB_HEADER
#define BCRYPT_RSAFULLPRIVATE_MAGIC
Definition: bcrypt.h:205
#define BCRYPT_BLOCK_LENGTH
Definition: bcrypt.h:45
#define BCRYPT_MD2_ALGORITHM
Definition: bcrypt.h:96
#define BCRYPT_SECRET_AGREEMENT_INTERFACE
Definition: bcrypt.h:150
#define BCRYPT_PUBLIC_KEY_BLOB
Definition: bcrypt.h:72
#define BCRYPT_SHA256_ALGORITHM
Definition: bcrypt.h:105
#define BCRYPT_HMAC_SHA256_ALG_HANDLE
Definition: bcrypt.h:388
#define BCRYPT_CHAIN_MODE_NA
Definition: bcrypt.h:110
#define BCRYPT_RSAPRIVATE_MAGIC
Definition: bcrypt.h:204
#define BCRYPT_CIPHER_INTERFACE
Definition: bcrypt.h:147
#define BCRYPT_RSAPRIVATE_BLOB
Definition: bcrypt.h:68
#define BCRYPT_DSA_PUBLIC_BLOB
Definition: bcrypt.h:70
#define BCRYPT_SUPPORTED_PAD_OAEP
Definition: bcrypt.h:158
#define BCRYPT_ASYMMETRIC_ENCRYPTION_INTERFACE
Definition: bcrypt.h:149
#define BCRYPT_RNG_OPERATION
Definition: bcrypt.h:144
#define BCRYPT_ECDH_PUBLIC_P256_MAGIC
Definition: bcrypt.h:132
#define BCRYPT_ALG_HANDLE_HMAC_FLAG
Definition: bcrypt.h:441
#define BCRYPT_ECCPRIVATE_BLOB
Definition: bcrypt.h:66
#define KDF_HASH_ALGORITHM
Definition: bcrypt.h:333
#define BCRYPT_CIPHER_OPERATION
Definition: bcrypt.h:139
#define BCRYPT_ECDSA_P256_ALGORITHM
Definition: bcrypt.h:93
#define BCRYPT_RNG_ALGORITHM
Definition: bcrypt.h:101
#define BCRYPT_AES_WRAP_KEY_BLOB
Definition: bcrypt.h:64
#define BCRYPT_DSA_PRIVATE_BLOB
Definition: bcrypt.h:71
#define BCRYPT_HASH_LENGTH
Definition: bcrypt.h:50
#define BCRYPT_ECDSA_PRIVATE_P256_MAGIC
Definition: bcrypt.h:126
#define BCRYPT_SIGNATURE_INTERFACE
Definition: bcrypt.h:151
#define BCRYPT_KDF_RAW_SECRET
Definition: bcrypt.h:121
#define BCRYPT_BLOCK_PADDING
Definition: bcrypt.h:444
#define BCRYPT_SHA512_ALG_HANDLE
Definition: bcrypt.h:383
#define BCRYPT_PADDING_SCHEMES
Definition: bcrypt.h:57
#define BCRYPT_DH_PARAMETERS_MAGIC
Definition: bcrypt.h:289
#define BCRYPT_RSAPUBLIC_MAGIC
Definition: bcrypt.h:203
#define BCRYPT_ECDH_PRIVATE_P384_MAGIC
Definition: bcrypt.h:135
#define BCRYPT_KEY_DERIVATION_OPERATION
Definition: bcrypt.h:145
#define BCRYPT_HASH_REUSABLE_FLAG
Definition: bcrypt.h:447
#define BCRYPT_KEY_DATA_BLOB_VERSION1
Definition: bcrypt.h:368
#define BCRYPT_HASH_INTERFACE
Definition: bcrypt.h:148
#define MS_PRIMITIVE_PROVIDER
Definition: bcrypt.h:83
#define BCRYPT_HMAC_SHA384_ALG_HANDLE
Definition: bcrypt.h:389
#define BCRYPT_DH_PRIVATE_BLOB
Definition: bcrypt.h:75
#define BCRYPT_AUTH_MODE_CHAIN_CALLS_FLAG
Definition: bcrypt.h:300
#define BCRYPT_ECDH_P256_ALGORITHM
Definition: bcrypt.h:91
#define BCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION
Definition: bcrypt.h:141
#define BCRYPT_RSA_SIGN_ALGORITHM
Definition: bcrypt.h:103
#define BCRYPT_SHA384_ALGORITHM
Definition: bcrypt.h:106
#define BCRYPT_DSA_PUBLIC_MAGIC
Definition: bcrypt.h:241
#define BCRYPT_OPAQUE_KEY_BLOB
Definition: bcrypt.h:62
#define BCRYPT_DH_ALGORITHM
Definition: bcrypt.h:89
#define BCRYPT_CHAIN_MODE_ECB
Definition: bcrypt.h:112
#define BCRYPT_SHA1_ALGORITHM
Definition: bcrypt.h:104
#define BCRYPT_RNG_INTERFACE
Definition: bcrypt.h:152
#define BCRYPT_PAD_NONE
Definition: bcrypt.h:235
#define BCRYPT_RSAFULLPRIVATE_BLOB
Definition: bcrypt.h:69
#define BCRYPT_MD5_ALGORITHM
Definition: bcrypt.h:98
#define BCRYPT_HMAC_SHA512_ALG_HANDLE
Definition: bcrypt.h:390
#define BCRYPT_SHA1_ALG_HANDLE
Definition: bcrypt.h:380
#define BCRYPT_DH_PUBLIC_BLOB
Definition: bcrypt.h:74
#define BCRYPT_DH_PRIVATE_MAGIC
Definition: bcrypt.h:281
#define BCRYPT_USE_SYSTEM_PREFERRED_RNG
Definition: bcrypt.h:438
#define MAGIC_ALG
NTSTATUS hmac_init(struct hash *hash, UCHAR *key, ULONG key_size)
#define BLOCK_LENGTH_AES
#define MAGIC_SECRET
NTSTATUS key_symmetric_vector_reset(void *args)
NTSTATUS key_symmetric_encrypt_internal(void *args)
NTSTATUS key_asymmetric_export(void *args)
#define KEY_FLAG_FINALIZED
NTSTATUS key_symmetric_set_auth_data(void *args)
#define MAGIC_KEY
NTSTATUS key_symmetric_get_tag(void *args)
NTSTATUS hash_update(struct hash *hash, UCHAR *input, ULONG size)
NTSTATUS key_asymmetric_encrypt(void *args)
NTSTATUS key_symmetric_destroy(void *args)
#define MAGIC_DSS1
chain_mode
@ CHAIN_MODE_ECB
@ CHAIN_MODE_CCM
@ CHAIN_MODE_CBC
@ CHAIN_MODE_GCM
@ CHAIN_MODE_CFB
#define BLOCK_LENGTH_3DES
#define KEY_EXPORT_FLAG_DH_PARAMETERS
NTSTATUS key_symmetric_decrypt_internal(void *args)
NTSTATUS hmac_update(struct hash *hash, UCHAR *input, ULONG size)
#define MAGIC_HASH
NTSTATUS hash_get_size(struct hash *hash, ULONG *output)
NTSTATUS hash_finish(struct hash *hash, UCHAR *output)
#define BLOCK_LENGTH_RC4
#define KEY_IMPORT_FLAG_PUBLIC
NTSTATUS key_asymmetric_generate(void *args)
NTSTATUS key_asymmetric_destroy(void *args)
NTSTATUS process_attach(void *args)
#define KEY_EXPORT_FLAG_RSA_FULL
#define HASH_FLAG_HMAC
NTSTATUS key_asymmetric_verify(void *args)
NTSTATUS key_asymmetric_derive_key(void *args)
#define MAGIC_DSS2
NTSTATUS key_asymmetric_import(void *args)
NTSTATUS hash_init(struct hash *hash)
#define KEY_IMPORT_FLAG_DH_PARAMETERS
#define KEY_FLAG_LEGACY_DSA_V2
NTSTATUS key_asymmetric_sign(void *args)
NTSTATUS key_asymmetric_decrypt(void *args)
#define HASH_FLAG_REUSABLE
NTSTATUS key_asymmetric_duplicate(void *args)
NTSTATUS hmac_finish(struct hash *hash, UCHAR *output)
alg_id
@ ALG_ID_RSA
@ ALG_ID_DSA
@ ALG_ID_RSA_SIGN
@ ALG_ID_3DES
@ ALG_ID_ECDSA_P256
@ ALG_ID_SHA512
@ ALG_ID_PBKDF2
@ ALG_ID_ECDH_P256
@ ALG_ID_SHA384
@ ALG_ID_SHA1
@ ALG_ID_DH
@ ALG_ID_RC4
@ ALG_ID_MD2
@ ALG_ID_ECDSA_P384
@ ALG_ID_SHA256
@ ALG_ID_MD4
@ ALG_ID_ECDH_P384
@ ALG_ID_AES
@ ALG_ID_MD5
@ ALG_ID_RNG
#define KEY_EXPORT_FLAG_PUBLIC
static struct algorithm * create_algorithm(enum alg_id id, enum chain_mode mode, DWORD flags)
Definition: bcrypt_main.c:361
NTSTATUS WINAPI BCryptAddContextFunctionProvider(ULONG table, const WCHAR *ctx, ULONG iface, const WCHAR *func, const WCHAR *provider, ULONG pos)
Definition: bcrypt_main.c:56
#define MAX_HASH_OUTPUT_BYTES
Definition: bcrypt_main.c:101
static const struct algorithm pseudo_algorithms[]
Definition: bcrypt_main.c:212
NTSTATUS WINAPI BCryptSecretAgreement(BCRYPT_KEY_HANDLE privkey_handle, BCRYPT_KEY_HANDLE pubkey_handle, BCRYPT_SECRET_HANDLE *ret_handle, ULONG flags)
Definition: bcrypt_main.c:2530
NTSTATUS WINAPI BCryptRemoveContextFunctionProvider(ULONG table, const WCHAR *ctx, ULONG iface, const WCHAR *func, const WCHAR *provider)
Definition: bcrypt_main.c:70
static const WCHAR * resolve_blob_type(const WCHAR *type, UCHAR *input, ULONG input_len)
Definition: bcrypt_main.c:2165
static NTSTATUS key_symmetric_decrypt(struct key *key, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv, ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags)
Definition: bcrypt_main.c:1234
NTSTATUS WINAPI BCryptGenRandom(BCRYPT_ALG_HANDLE handle, UCHAR *buffer, ULONG count, ULONG flags)
Definition: bcrypt_main.c:316
NTSTATUS WINAPI BCryptDuplicateKey(BCRYPT_KEY_HANDLE handle, BCRYPT_KEY_HANDLE *handle_copy, UCHAR *object, ULONG object_len, ULONG flags)
Definition: bcrypt_main.c:2145
static struct key * key_symmetric_create(enum alg_id alg, enum chain_mode mode, ULONG block_size, const UCHAR *secret, ULONG secret_len)
Definition: bcrypt_main.c:1143
static NTSTATUS get_key_property(const struct key *key, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size)
Definition: bcrypt_main.c:824
NTSTATUS WINAPI BCryptHashData(BCRYPT_HASH_HANDLE handle, UCHAR *input, ULONG size, ULONG flags)
Definition: bcrypt_main.c:1020
static NTSTATUS generic_alg_property(enum alg_id id, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size)
Definition: bcrypt_main.c:443
NTSTATUS WINAPI BCryptGetProperty(BCRYPT_HANDLE handle, const WCHAR *prop, UCHAR *buffer, ULONG count, ULONG *res, ULONG flags)
Definition: bcrypt_main.c:856
static NTSTATUS set_key_property(struct key *key, const WCHAR *prop, UCHAR *value, ULONG size, ULONG flags)
Definition: bcrypt_main.c:742
NTSTATUS WINAPI BCryptCreateHash(BCRYPT_ALG_HANDLE handle, BCRYPT_HASH_HANDLE *ret_handle, UCHAR *object, ULONG object_len, UCHAR *secret, ULONG secret_len, ULONG flags)
Definition: bcrypt_main.c:951
NTSTATUS WINAPI BCryptDecrypt(BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv, ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags)
Definition: bcrypt_main.c:2318
NTSTATUS WINAPI BCryptUnregisterProvider(const WCHAR *provider)
Definition: bcrypt_main.c:95
static void hash_finalize(struct hash *hash, UCHAR *output, ULONG size)
Definition: bcrypt_main.c:1034
static NTSTATUS key_export(struct key *key, struct key *encrypt_key, const WCHAR *type, UCHAR *output, ULONG output_len, ULONG *size)
Definition: bcrypt_main.c:1589
NTSTATUS WINAPI BCryptRemoveContextFunction(ULONG table, const WCHAR *ctx, ULONG iface, const WCHAR *func)
Definition: bcrypt_main.c:64
static struct algorithm * get_alg_object(BCRYPT_ALG_HANDLE handle)
Definition: bcrypt_main.c:296
NTSTATUS WINAPI BCryptDeriveKeyPBKDF2(BCRYPT_ALG_HANDLE handle, UCHAR *pwd, ULONG pwd_len, UCHAR *salt, ULONG salt_len, ULONGLONG iterations, UCHAR *dk, ULONG dk_len, ULONG flags)
Definition: bcrypt_main.c:2518
NTSTATUS WINAPI BCryptImportKeyPair(BCRYPT_ALG_HANDLE handle, BCRYPT_KEY_HANDLE decrypt_key_handle, const WCHAR *type, BCRYPT_KEY_HANDLE *ret_handle, UCHAR *input, ULONG input_len, ULONG flags)
Definition: bcrypt_main.c:2193
static NTSTATUS get_3des_property(enum chain_mode mode, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size)
Definition: bcrypt_main.c:482
static NTSTATUS key_asymmetric_create(enum alg_id alg_id, ULONG bitlen, struct key **ret_key)
Definition: bcrypt_main.c:1104
NTSTATUS WINAPI BCryptRegisterProvider(const WCHAR *provider, ULONG flags, CRYPT_PROVIDER_REG *reg)
Definition: bcrypt_main.c:89
NTSTATUS WINAPI BCryptDestroyHash(BCRYPT_HASH_HANDLE handle)
Definition: bcrypt_main.c:1009
static NTSTATUS pbkdf2(struct hash *hash, UCHAR *pwd, ULONG pwd_len, UCHAR *salt, ULONG salt_len, ULONGLONG iterations, ULONG i, UCHAR *dst, ULONG hash_len)
Definition: bcrypt_main.c:2436
static NTSTATUS derive_key_pbkdf2(struct algorithm *alg, UCHAR *pwd, ULONG pwd_len, UCHAR *salt, ULONG salt_len, ULONGLONG iterations, UCHAR *dk, ULONG dk_len)
Definition: bcrypt_main.c:2472
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
Definition: bcrypt_main.c:2744
static BOOL is_asymmetric_encryption_key(struct key *key)
Definition: bcrypt_main.c:143
NTSTATUS WINAPI BCryptGenerateSymmetricKey(BCRYPT_ALG_HANDLE handle, BCRYPT_KEY_HANDLE *ret_handle, UCHAR *object, ULONG object_len, UCHAR *secret, ULONG secret_len, ULONG flags)
Definition: bcrypt_main.c:2023
static NTSTATUS get_alg_property(const struct algorithm *alg, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size)
Definition: bcrypt_main.c:635
static NTSTATUS aes_wrap(const UCHAR *secret, ULONG secret_len, const UCHAR *plain, ULONG plain_len, UCHAR *cipher)
Definition: bcrypt_main.c:1552
static void destroy_object(struct object *obj)
Definition: bcrypt_main.c:415
#define MAX_HASH_BLOCK_BITS
Definition: bcrypt_main.c:102
static NTSTATUS derive_key_hash(struct secret *secret, BCryptBufferDesc *desc, UCHAR *output, ULONG output_len, ULONG *ret_len)
Definition: bcrypt_main.c:2620
ULONG block_bits
Definition: bcrypt_main.c:111
NTSTATUS WINAPI BCryptExportKey(BCRYPT_KEY_HANDLE export_key_handle, BCRYPT_KEY_HANDLE encrypt_key_handle, const WCHAR *type, UCHAR *output, ULONG output_len, ULONG *size, ULONG flags)
Definition: bcrypt_main.c:2089
static void key_destroy(struct key *key)
Definition: bcrypt_main.c:1167
static NTSTATUS set_alg_property(struct algorithm *alg, const WCHAR *prop, UCHAR *value, ULONG size, ULONG flags)
Definition: bcrypt_main.c:672
static NTSTATUS get_hash_property(const struct hash *hash, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size)
Definition: bcrypt_main.c:799
static HINSTANCE instance
Definition: bcrypt_main.c:48
static BOOL is_signature_key(struct key *key)
Definition: bcrypt_main.c:153
static NTSTATUS get_dh_property(const struct key *key, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size)
Definition: bcrypt_main.c:809
#define HMAC_PAD_LEN
Definition: bcrypt_main.c:2392
static struct secret * get_secret_object(BCRYPT_SECRET_HANDLE handle)
Definition: bcrypt_main.c:311
NTSTATUS WINAPI BCryptEncrypt(BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv, ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags)
Definition: bcrypt_main.c:2272
static NTSTATUS derive_key_raw(struct secret *secret, UCHAR *output, ULONG output_len, ULONG *ret_len)
Definition: bcrypt_main.c:2587
ULONG object_length
Definition: bcrypt_main.c:109
NTSTATUS WINAPI BCryptOpenAlgorithmProvider(BCRYPT_ALG_HANDLE *handle, const WCHAR *id, const WCHAR *implementation, DWORD flags)
Definition: bcrypt_main.c:372
NTSTATUS WINAPI BCryptEnumAlgorithms(ULONG type, ULONG *ret_count, BCRYPT_ALGORITHM_IDENTIFIER **ret_list, ULONG flags)
Definition: bcrypt_main.c:175
static NTSTATUS get_rsa_property(enum chain_mode mode, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size)
Definition: bcrypt_main.c:594
NTSTATUS WINAPI BCryptAddContextFunction(ULONG table, const WCHAR *ctx, ULONG iface, const WCHAR *func, ULONG pos)
Definition: bcrypt_main.c:50
static void hash_prepare(struct hash *hash)
Definition: bcrypt_main.c:889
const WCHAR * name
Definition: bcrypt_main.c:107
NTSTATUS WINAPI BCryptGenerateKeyPair(BCRYPT_ALG_HANDLE handle, BCRYPT_KEY_HANDLE *ret_handle, ULONG key_len, ULONG flags)
Definition: bcrypt_main.c:2038
NTSTATUS WINAPI BCryptSetProperty(BCRYPT_HANDLE handle, const WCHAR *prop, UCHAR *value, ULONG size, ULONG flags)
Definition: bcrypt_main.c:2365
static struct hash * get_hash_object(BCRYPT_HASH_HANDLE handle)
Definition: bcrypt_main.c:301
static NTSTATUS key_import_pair(struct algorithm *alg, const WCHAR *type, BCRYPT_KEY_HANDLE *ret_key, UCHAR *input, ULONG input_len)
Definition: bcrypt_main.c:1727
static NTSTATUS hash_create(const struct algorithm *alg, UCHAR *secret, ULONG secret_len, ULONG flags, struct hash **ret_hash)
Definition: bcrypt_main.c:926
static void reverse_bytes(UCHAR *buf, ULONG len)
Definition: bcrypt_main.c:2576
static BOOL is_agreement_key(struct key *key)
Definition: bcrypt_main.c:148
static NTSTATUS aes_unwrap(const UCHAR *secret, ULONG secret_len, const UCHAR *cipher, ULONG cipher_len, UCHAR *plain)
Definition: bcrypt_main.c:1355
static BOOL is_symmetric_key(const struct key *key)
Definition: bcrypt_main.c:137
NTSTATUS WINAPI BCryptFinalizeKeyPair(BCRYPT_KEY_HANDLE handle, ULONG flags)
Definition: bcrypt_main.c:2056
static NTSTATUS key_duplicate(struct key *key_orig, struct key **ret_key)
Definition: bcrypt_main.c:2105
NTSTATUS WINAPI BCryptDeriveKeyCapi(BCRYPT_HASH_HANDLE handle, BCRYPT_ALG_HANDLE halg, UCHAR *key, ULONG keylen, ULONG flags)
Definition: bcrypt_main.c:2393
NTSTATUS WINAPI BCryptCloseAlgorithmProvider(BCRYPT_ALG_HANDLE handle, DWORD flags)
Definition: bcrypt_main.c:421
static NTSTATUS get_dsa_property(enum chain_mode mode, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size)
Definition: bcrypt_main.c:608
NTSTATUS WINAPI BCryptDeriveKey(BCRYPT_SECRET_HANDLE handle, const WCHAR *kdf, BCryptBufferDesc *desc, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags)
Definition: bcrypt_main.c:2673
NTSTATUS WINAPI BCryptDestroySecret(BCRYPT_SECRET_HANDLE handle)
Definition: bcrypt_main.c:2563
NTSTATUS WINAPI BCryptVerifySignature(BCRYPT_KEY_HANDLE handle, void *padding, UCHAR *hash, ULONG hash_len, UCHAR *signature, ULONG signature_len, ULONG flags)
Definition: bcrypt_main.c:2239
ULONG hash_length
Definition: bcrypt_main.c:110
static void hash_destroy(struct hash *hash)
Definition: bcrypt_main.c:1002
NTSTATUS WINAPI BCryptImportKey(BCRYPT_ALG_HANDLE handle, BCRYPT_KEY_HANDLE decrypt_key_handle, const WCHAR *type, BCRYPT_KEY_HANDLE *ret_handle, UCHAR *object, ULONG object_len, UCHAR *input, ULONG input_len, ULONG flags)
Definition: bcrypt_main.c:2069
static NTSTATUS key_symmetric_set_vector(struct key *key, UCHAR *vector, ULONG vector_len, BOOL force_reset)
Definition: bcrypt_main.c:1126
static NTSTATUS key_import(struct algorithm *alg, struct key *decrypt_key, const WCHAR *type, BCRYPT_KEY_HANDLE *key, UCHAR *object, ULONG object_len, UCHAR *input, ULONG input_len)
Definition: bcrypt_main.c:1394
static NTSTATUS convert_legacy_rsaprivate_blob(struct algorithm *alg, BCRYPT_RSAKEY_BLOB **rsa_data, ULONG *rsa_len, UCHAR *input, ULONG input_len)
Definition: bcrypt_main.c:1680
NTSTATUS WINAPI BCryptKeyDerivation(BCRYPT_KEY_HANDLE handle, BCryptBufferDesc *desc, UCHAR *output, ULONG output_size, ULONG *ret_len, ULONG flags)
Definition: bcrypt_main.c:2697
static NTSTATUS hash_single(struct algorithm *alg, UCHAR *secret, ULONG secret_len, UCHAR *input, ULONG input_len, UCHAR *output, ULONG output_len)
Definition: bcrypt_main.c:1074
static struct object * get_object(BCRYPT_HANDLE handle, ULONG magic)
Definition: bcrypt_main.c:274
NTSTATUS WINAPI BCryptDestroyKey(BCRYPT_KEY_HANDLE handle)
Definition: bcrypt_main.c:2261
static NTSTATUS key_symmetric_encrypt(struct key *key, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv, ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags)
Definition: bcrypt_main.c:1449
static struct algorithm * get_hash_alg(BCryptBuffer *buf, BOOL hmac)
Definition: bcrypt_main.c:2601
static NTSTATUS key_symmetric_generate(struct algorithm *alg, BCRYPT_KEY_HANDLE *ret_handle, const UCHAR *secret, ULONG secret_len)
Definition: bcrypt_main.c:1189
static BOOL is_alg_pseudo_handle(BCRYPT_ALG_HANDLE handle)
Definition: bcrypt_main.c:269
static struct key * get_key_object(BCRYPT_KEY_HANDLE handle)
Definition: bcrypt_main.c:306
static BOOL is_equal_vector(const UCHAR *vector, ULONG len, const UCHAR *vector2, ULONG len2)
Definition: bcrypt_main.c:1119
NTSTATUS WINAPI BCryptFinishHash(BCRYPT_HASH_HANDLE handle, UCHAR *output, ULONG size, ULONG flags)
Definition: bcrypt_main.c:1058
void WINAPI BCryptFreeBuffer(void *buffer)
Definition: bcrypt_main.c:84
static BOOL match_operation_type(ULONG type, ULONG class)
Definition: bcrypt_main.c:158
NTSTATUS WINAPI BCryptHash(BCRYPT_ALG_HANDLE handle, UCHAR *secret, ULONG secret_len, UCHAR *input, ULONG input_len, UCHAR *output, ULONG output_len)
Definition: bcrypt_main.c:1091
NTSTATUS WINAPI BCryptDuplicateHash(BCRYPT_HASH_HANDLE handle, BCRYPT_HASH_HANDLE *handle_copy, UCHAR *object, ULONG objectlen, ULONG flags)
Definition: bcrypt_main.c:975
static NTSTATUS get_aes_property(enum chain_mode mode, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size)
Definition: bcrypt_main.c:522
static NTSTATUS get_rc4_property(enum chain_mode mode, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size)
Definition: bcrypt_main.c:580
static const struct @319 builtin_algorithms[]
NTSTATUS WINAPI BCryptGetFipsAlgorithmMode(BOOLEAN *enabled)
Definition: bcrypt_main.c:432
NTSTATUS WINAPI BCryptSignHash(BCRYPT_KEY_HANDLE handle, void *padding, UCHAR *input, ULONG input_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags)
Definition: bcrypt_main.c:2216
static ULONG get_block_size(struct algorithm *alg)
Definition: bcrypt_main.c:1182
static NTSTATUS get_pbkdf2_property(enum chain_mode mode, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size)
Definition: bcrypt_main.c:615
NTSTATUS WINAPI BCryptEnumContextFunctions(ULONG table, const WCHAR *ctx, ULONG iface, ULONG *buflen, CRYPT_CONTEXT_FUNCTIONS **buffer)
Definition: bcrypt_main.c:77
struct object obj[50]
Definition: butterflies.c:34
Definition: list.h:37
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int idx
Definition: utils.c:41
static WCHAR reason[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1971
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
#define DLL_PROCESS_DETACH
Definition: compat.h:130
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define lstrlenW
Definition: compat.h:750
static const WCHAR pubkey[]
Definition: asmname.c:68
BOOL WINAPI DisableThreadLibraryCalls(IN HMODULE hLibModule)
Definition: loader.c:85
static void process_detach(void)
Definition: main.c:94
#define assert(_expr)
Definition: assert.h:32
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
return ret
Definition: mutex.c:147
r reserved
Definition: btrfs.c:3006
#define ULONG_PTR
Definition: config.h:101
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble GLdouble t
Definition: gl.h:2047
GLenum func
Definition: glext.h:6028
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: glext.h:7750
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum mode
Definition: glext.h:6217
GLenum const GLfloat * params
Definition: glext.h:5645
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLenum GLenum GLenum input
Definition: glext.h:9031
GLuint id
Definition: glext.h:5910
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 * u
Definition: glfuncs.h:240
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
static int reg
Definition: i386-dis.c:1290
char hdr[14]
Definition: iptest.cpp:33
static DWORD block_size(DWORD block)
Definition: jsutils.c:61
#define a
Definition: ke_i.h:78
#define debugstr_w
Definition: kernel32.h:32
#define wine_dbgstr_w
Definition: kernel32.h:34
if(dx< 0)
Definition: linetemp.h:194
This file contains the generic message-digest wrapper.
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static HINSTANCE hinst
Definition: edit.c:551
static DATA_BLOB cipher
Definition: protectdata.c:34
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1204
static JOBOBJECTINFOCLASS LPVOID DWORD LPDWORD ret_len
Definition: process.c:81
static const DWORD padding[]
Definition: mciwnd.c:89
static void ULONG ULONG * ret_size
Definition: time.c:40
#define min(a, b)
Definition: monoChain.cc:55
int k
Definition: mpi.c:3369
#define DWORD
Definition: nt_native.h:44
#define STATUS_AUTH_TAG_MISMATCH
Definition: ntstatus.h:1399
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:772
short WCHAR
Definition: pedump.c:58
#define RtlGenRandom
Definition: ntsecapi.h:691
#define calloc
Definition: rosglue.h:14
#define list
Definition: rosglue.h:35
const WCHAR * str
MD5 message digest algorithm (hash function)
This file contains SHA-1 definitions and functions.
#define memset(x, y, z)
Definition: compat.h:39
This file contains SHA-224 and SHA-256 definitions and functions.
This file contains SHA-384 and SHA-512 definitions and functions.
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define TRACE(s)
Definition: solgame.cpp:4
enum chain_mode mode
struct object hdr
enum alg_id id
Definition: image.c:134
struct object hdr
ULONG secret_len
enum alg_id alg_id
ULONG flags
UCHAR * secret
Definition: copy.c:22
union key::@318 u
struct key_asymmetric a
struct object hdr
enum alg_id alg_id
struct key_symmetric s
Definition: name.c:39
ULONG magic
struct object hdr
struct key * privkey
struct key * pubkey
Definition: ps.c:97
Definition: ecma_167.h:138
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:687
unsigned char UCHAR
Definition: typedefs.h:53
uint64_t ULONGLONG
Definition: typedefs.h:67
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
Definition: pdh_main.c:96
#define SecureZeroMemory
Definition: winbase.h:1443
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define PRIVATEKEYBLOB
Definition: wincrypt.h:2445
#define PUBLICKEYBLOB
Definition: wincrypt.h:2444
#define CALG_RSA_KEYX
Definition: wincrypt.h:2080
#define CALG_DSS_SIGN
Definition: wincrypt.h:2070
#define CUR_BLOB_VERSION
Definition: wincrypt.h:2451
#define WINAPI
Definition: msvc.h:6
#define NTE_BAD_DATA
Definition: winerror.h:4252