2 * Copyright 2009 Henri Verbeet for CodeWeavers
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.
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.
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
21 #include "wine/port.h"
24 #ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
25 #include <CommonCrypto/CommonDigest.h>
26 #include <CommonCrypto/CommonHMAC.h>
27 #elif defined(SONAME_LIBGNUTLS)
28 #include <gnutls/gnutls.h>
29 #include <gnutls/crypto.h>
33 #define WIN32_NO_STATUS
39 #include "wine/debug.h"
40 #include "wine/library.h"
41 #include "wine/unicode.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(bcrypt
);
45 static HINSTANCE instance
;
47 #if defined(HAVE_GNUTLS_HASH) && !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H)
48 WINE_DECLARE_DEBUG_CHANNEL(winediag
);
50 static void *libgnutls_handle
;
51 #define MAKE_FUNCPTR(f) static typeof(f) * p##f
52 MAKE_FUNCPTR(gnutls_global_deinit
);
53 MAKE_FUNCPTR(gnutls_global_init
);
54 MAKE_FUNCPTR(gnutls_global_set_log_function
);
55 MAKE_FUNCPTR(gnutls_global_set_log_level
);
56 MAKE_FUNCPTR(gnutls_hash
);
57 MAKE_FUNCPTR(gnutls_hash_deinit
);
58 MAKE_FUNCPTR(gnutls_hash_init
);
59 MAKE_FUNCPTR(gnutls_hmac
);
60 MAKE_FUNCPTR(gnutls_hmac_deinit
);
61 MAKE_FUNCPTR(gnutls_hmac_init
);
62 MAKE_FUNCPTR(gnutls_perror
);
65 static void gnutls_log( int level
, const char *msg
)
67 TRACE( "<%d> %s", level
, msg
);
70 static BOOL
gnutls_initialize(void)
74 if (!(libgnutls_handle
= wine_dlopen( SONAME_LIBGNUTLS
, RTLD_NOW
, NULL
, 0 )))
76 ERR_(winediag
)( "failed to load libgnutls, no support for crypto hashes\n" );
80 #define LOAD_FUNCPTR(f) \
81 if (!(p##f = wine_dlsym( libgnutls_handle, #f, NULL, 0 ))) \
83 ERR( "failed to load %s\n", #f ); \
87 LOAD_FUNCPTR(gnutls_global_deinit
)
88 LOAD_FUNCPTR(gnutls_global_init
)
89 LOAD_FUNCPTR(gnutls_global_set_log_function
)
90 LOAD_FUNCPTR(gnutls_global_set_log_level
)
91 LOAD_FUNCPTR(gnutls_hash
);
92 LOAD_FUNCPTR(gnutls_hash_deinit
);
93 LOAD_FUNCPTR(gnutls_hash_init
);
94 LOAD_FUNCPTR(gnutls_hmac
);
95 LOAD_FUNCPTR(gnutls_hmac_deinit
);
96 LOAD_FUNCPTR(gnutls_hmac_init
);
97 LOAD_FUNCPTR(gnutls_perror
)
100 if ((ret
= pgnutls_global_init()) != GNUTLS_E_SUCCESS
)
102 pgnutls_perror( ret
);
106 if (TRACE_ON( bcrypt
))
108 pgnutls_global_set_log_level( 4 );
109 pgnutls_global_set_log_function( gnutls_log
);
115 wine_dlclose( libgnutls_handle
, NULL
, 0 );
116 libgnutls_handle
= NULL
;
120 static void gnutls_uninitialize(void)
122 pgnutls_global_deinit();
123 wine_dlclose( libgnutls_handle
, NULL
, 0 );
124 libgnutls_handle
= NULL
;
126 #endif /* HAVE_GNUTLS_HASH && !HAVE_COMMONCRYPTO_COMMONDIGEST_H */
128 NTSTATUS WINAPI
BCryptEnumAlgorithms(ULONG dwAlgOperations
, ULONG
*pAlgCount
,
129 BCRYPT_ALGORITHM_IDENTIFIER
**ppAlgList
, ULONG dwFlags
)
131 FIXME("%08x, %p, %p, %08x - stub\n", dwAlgOperations
, pAlgCount
, ppAlgList
, dwFlags
);
136 return STATUS_NOT_IMPLEMENTED
;
139 NTSTATUS WINAPI
BCryptGenRandom(BCRYPT_ALG_HANDLE algorithm
, UCHAR
*buffer
, ULONG count
, ULONG flags
)
141 const DWORD supported_flags
= BCRYPT_USE_SYSTEM_PREFERRED_RNG
;
142 TRACE("%p, %p, %u, %08x - semi-stub\n", algorithm
, buffer
, count
, flags
);
146 /* It's valid to call without an algorithm if BCRYPT_USE_SYSTEM_PREFERRED_RNG
147 * is set. In this case the preferred system RNG is used.
149 if (!(flags
& BCRYPT_USE_SYSTEM_PREFERRED_RNG
))
150 return STATUS_INVALID_HANDLE
;
153 return STATUS_INVALID_PARAMETER
;
155 if (flags
& ~supported_flags
)
156 FIXME("unsupported flags %08x\n", flags
& ~supported_flags
);
159 FIXME("ignoring selected algorithm\n");
161 /* When zero bytes are requested the function returns success too. */
163 return STATUS_SUCCESS
;
165 if (flags
& BCRYPT_USE_SYSTEM_PREFERRED_RNG
)
167 if (RtlGenRandom(buffer
, count
))
168 return STATUS_SUCCESS
;
171 FIXME("called with unsupported parameters, returning error\n");
172 return STATUS_NOT_IMPLEMENTED
;
175 #define MAGIC_ALG (('A' << 24) | ('L' << 16) | ('G' << 8) | '0')
176 #define MAGIC_HASH (('H' << 24) | ('A' << 16) | ('S' << 8) | 'H')
191 static const struct {
193 const WCHAR
*alg_name
;
195 /* ALG_ID_MD5 */ { 16, BCRYPT_MD5_ALGORITHM
},
196 /* ALG_ID_SHA1 */ { 20, BCRYPT_SHA1_ALGORITHM
},
197 /* ALG_ID_SHA256 */ { 32, BCRYPT_SHA256_ALGORITHM
},
198 /* ALG_ID_SHA384 */ { 48, BCRYPT_SHA384_ALGORITHM
},
199 /* ALG_ID_SHA512 */ { 64, BCRYPT_SHA512_ALGORITHM
}
209 NTSTATUS WINAPI
BCryptOpenAlgorithmProvider( BCRYPT_ALG_HANDLE
*handle
, LPCWSTR id
, LPCWSTR implementation
, DWORD flags
)
211 struct algorithm
*alg
;
214 const DWORD supported_flags
= BCRYPT_ALG_HANDLE_HMAC_FLAG
;
216 TRACE( "%p, %s, %s, %08x\n", handle
, wine_dbgstr_w(id
), wine_dbgstr_w(implementation
), flags
);
218 if (!handle
|| !id
) return STATUS_INVALID_PARAMETER
;
219 if (flags
& ~supported_flags
)
221 FIXME( "unsupported flags %08x\n", flags
& ~supported_flags
);
222 return STATUS_NOT_IMPLEMENTED
;
225 if (!strcmpW( id
, BCRYPT_SHA1_ALGORITHM
)) alg_id
= ALG_ID_SHA1
;
226 else if (!strcmpW( id
, BCRYPT_MD5_ALGORITHM
)) alg_id
= ALG_ID_MD5
;
227 else if (!strcmpW( id
, BCRYPT_SHA256_ALGORITHM
)) alg_id
= ALG_ID_SHA256
;
228 else if (!strcmpW( id
, BCRYPT_SHA384_ALGORITHM
)) alg_id
= ALG_ID_SHA384
;
229 else if (!strcmpW( id
, BCRYPT_SHA512_ALGORITHM
)) alg_id
= ALG_ID_SHA512
;
232 FIXME( "algorithm %s not supported\n", debugstr_w(id
) );
233 return STATUS_NOT_IMPLEMENTED
;
235 if (implementation
&& strcmpW( implementation
, MS_PRIMITIVE_PROVIDER
))
237 FIXME( "implementation %s not supported\n", debugstr_w(implementation
) );
238 return STATUS_NOT_IMPLEMENTED
;
241 if (!(alg
= HeapAlloc( GetProcessHeap(), 0, sizeof(*alg
) ))) return STATUS_NO_MEMORY
;
242 alg
->hdr
.magic
= MAGIC_ALG
;
244 alg
->hmac
= flags
& BCRYPT_ALG_HANDLE_HMAC_FLAG
;
247 return STATUS_SUCCESS
;
250 NTSTATUS WINAPI
BCryptCloseAlgorithmProvider( BCRYPT_ALG_HANDLE handle
, DWORD flags
)
252 struct algorithm
*alg
= handle
;
254 TRACE( "%p, %08x\n", handle
, flags
);
256 if (!alg
|| alg
->hdr
.magic
!= MAGIC_ALG
) return STATUS_INVALID_HANDLE
;
257 HeapFree( GetProcessHeap(), 0, alg
);
258 return STATUS_SUCCESS
;
261 NTSTATUS WINAPI
BCryptGetFipsAlgorithmMode(BOOLEAN
*enabled
)
263 FIXME("%p - semi-stub\n", enabled
);
266 return STATUS_INVALID_PARAMETER
;
269 return STATUS_SUCCESS
;
272 #ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
281 CC_SHA1_CTX sha1_ctx
;
282 CC_SHA256_CTX sha256_ctx
;
283 CC_SHA512_CTX sha512_ctx
;
284 CCHmacContext hmac_ctx
;
288 static NTSTATUS
hash_init( struct hash
*hash
)
290 switch (hash
->alg_id
)
293 CC_MD5_Init( &hash
->u
.md5_ctx
);
297 CC_SHA1_Init( &hash
->u
.sha1_ctx
);
301 CC_SHA256_Init( &hash
->u
.sha256_ctx
);
305 CC_SHA384_Init( &hash
->u
.sha512_ctx
);
309 CC_SHA512_Init( &hash
->u
.sha512_ctx
);
313 ERR( "unhandled id %u\n", hash
->alg_id
);
314 return STATUS_NOT_IMPLEMENTED
;
316 return STATUS_SUCCESS
;
319 static NTSTATUS
hmac_init( struct hash
*hash
, UCHAR
*key
, ULONG key_size
)
321 CCHmacAlgorithm cc_algorithm
;
322 switch (hash
->alg_id
)
325 cc_algorithm
= kCCHmacAlgMD5
;
329 cc_algorithm
= kCCHmacAlgSHA1
;
333 cc_algorithm
= kCCHmacAlgSHA256
;
337 cc_algorithm
= kCCHmacAlgSHA384
;
341 cc_algorithm
= kCCHmacAlgSHA512
;
345 ERR( "unhandled id %u\n", hash
->alg_id
);
346 return STATUS_NOT_IMPLEMENTED
;
349 CCHmacInit( &hash
->u
.hmac_ctx
, cc_algorithm
, key
, key_size
);
350 return STATUS_SUCCESS
;
354 static NTSTATUS
hash_update( struct hash
*hash
, UCHAR
*input
, ULONG size
)
356 switch (hash
->alg_id
)
359 CC_MD5_Update( &hash
->u
.md5_ctx
, input
, size
);
363 CC_SHA1_Update( &hash
->u
.sha1_ctx
, input
, size
);
367 CC_SHA256_Update( &hash
->u
.sha256_ctx
, input
, size
);
371 CC_SHA384_Update( &hash
->u
.sha512_ctx
, input
, size
);
375 CC_SHA512_Update( &hash
->u
.sha512_ctx
, input
, size
);
379 ERR( "unhandled id %u\n", hash
->alg_id
);
380 return STATUS_NOT_IMPLEMENTED
;
382 return STATUS_SUCCESS
;
385 static NTSTATUS
hmac_update( struct hash
*hash
, UCHAR
*input
, ULONG size
)
387 CCHmacUpdate( &hash
->u
.hmac_ctx
, input
, size
);
388 return STATUS_SUCCESS
;
391 static NTSTATUS
hash_finish( struct hash
*hash
, UCHAR
*output
, ULONG size
)
393 switch (hash
->alg_id
)
396 CC_MD5_Final( output
, &hash
->u
.md5_ctx
);
400 CC_SHA1_Final( output
, &hash
->u
.sha1_ctx
);
404 CC_SHA256_Final( output
, &hash
->u
.sha256_ctx
);
408 CC_SHA384_Final( output
, &hash
->u
.sha512_ctx
);
412 CC_SHA512_Final( output
, &hash
->u
.sha512_ctx
);
416 ERR( "unhandled id %u\n", hash
->alg_id
);
419 return STATUS_SUCCESS
;
422 static NTSTATUS
hmac_finish( struct hash
*hash
, UCHAR
*output
, ULONG size
)
424 CCHmacFinal( &hash
->u
.hmac_ctx
, output
);
426 return STATUS_SUCCESS
;
428 #elif defined(HAVE_GNUTLS_HASH)
436 gnutls_hash_hd_t hash_handle
;
437 gnutls_hmac_hd_t hmac_handle
;
441 static NTSTATUS
hash_init( struct hash
*hash
)
443 gnutls_digest_algorithm_t alg
;
445 if (!libgnutls_handle
) return STATUS_INTERNAL_ERROR
;
447 switch (hash
->alg_id
)
450 alg
= GNUTLS_DIG_MD5
;
453 alg
= GNUTLS_DIG_SHA1
;
457 alg
= GNUTLS_DIG_SHA256
;
461 alg
= GNUTLS_DIG_SHA384
;
465 alg
= GNUTLS_DIG_SHA512
;
469 ERR( "unhandled id %u\n", hash
->alg_id
);
470 return STATUS_NOT_IMPLEMENTED
;
473 if (pgnutls_hash_init( &hash
->u
.hash_handle
, alg
)) return STATUS_INTERNAL_ERROR
;
474 return STATUS_SUCCESS
;
477 static NTSTATUS
hmac_init( struct hash
*hash
, UCHAR
*key
, ULONG key_size
)
479 gnutls_mac_algorithm_t alg
;
481 if (!libgnutls_handle
) return STATUS_INTERNAL_ERROR
;
483 switch (hash
->alg_id
)
486 alg
= GNUTLS_MAC_MD5
;
489 alg
= GNUTLS_MAC_SHA1
;
493 alg
= GNUTLS_MAC_SHA256
;
497 alg
= GNUTLS_MAC_SHA384
;
501 alg
= GNUTLS_MAC_SHA512
;
505 ERR( "unhandled id %u\n", hash
->alg_id
);
506 return STATUS_NOT_IMPLEMENTED
;
509 if (pgnutls_hmac_init( &hash
->u
.hmac_handle
, alg
, key
, key_size
)) return STATUS_INTERNAL_ERROR
;
510 return STATUS_SUCCESS
;
513 static NTSTATUS
hash_update( struct hash
*hash
, UCHAR
*input
, ULONG size
)
515 if (pgnutls_hash( hash
->u
.hash_handle
, input
, size
)) return STATUS_INTERNAL_ERROR
;
516 return STATUS_SUCCESS
;
519 static NTSTATUS
hmac_update( struct hash
*hash
, UCHAR
*input
, ULONG size
)
521 if (pgnutls_hmac( hash
->u
.hmac_handle
, input
, size
)) return STATUS_INTERNAL_ERROR
;
522 return STATUS_SUCCESS
;
525 static NTSTATUS
hash_finish( struct hash
*hash
, UCHAR
*output
, ULONG size
)
527 pgnutls_hash_deinit( hash
->u
.hash_handle
, output
);
528 return STATUS_SUCCESS
;
531 static NTSTATUS
hmac_finish( struct hash
*hash
, UCHAR
*output
, ULONG size
)
533 pgnutls_hmac_deinit( hash
->u
.hmac_handle
, output
);
534 return STATUS_SUCCESS
;
544 static NTSTATUS
hash_init( struct hash
*hash
)
546 ERR( "support for hashes not available at build time\n" );
547 return STATUS_NOT_IMPLEMENTED
;
550 static NTSTATUS
hmac_init( struct hash
*hash
, UCHAR
*key
, ULONG key_size
)
552 ERR( "support for hashes not available at build time\n" );
553 return STATUS_NOT_IMPLEMENTED
;
556 static NTSTATUS
hash_update( struct hash
*hash
, UCHAR
*input
, ULONG size
)
558 ERR( "support for hashes not available at build time\n" );
559 return STATUS_NOT_IMPLEMENTED
;
562 static NTSTATUS
hmac_update( struct hash
*hash
, UCHAR
*input
, ULONG size
)
564 ERR( "support for hashes not available at build time\n" );
565 return STATUS_NOT_IMPLEMENTED
;
568 static NTSTATUS
hash_finish( struct hash
*hash
, UCHAR
*output
, ULONG size
)
570 ERR( "support for hashes not available at build time\n" );
571 return STATUS_NOT_IMPLEMENTED
;
574 static NTSTATUS
hmac_finish( struct hash
*hash
, UCHAR
*output
, ULONG size
)
576 ERR( "support for hashes not available at build time\n" );
577 return STATUS_NOT_IMPLEMENTED
;
581 #define OBJECT_LENGTH_MD5 274
582 #define OBJECT_LENGTH_SHA1 278
583 #define OBJECT_LENGTH_SHA256 286
584 #define OBJECT_LENGTH_SHA384 382
585 #define OBJECT_LENGTH_SHA512 382
587 static NTSTATUS
generic_alg_property( enum alg_id id
, const WCHAR
*prop
, UCHAR
*buf
, ULONG size
, ULONG
*ret_size
)
589 if (!strcmpW( prop
, BCRYPT_HASH_LENGTH
))
591 *ret_size
= sizeof(ULONG
);
592 if (size
< sizeof(ULONG
))
593 return STATUS_BUFFER_TOO_SMALL
;
595 *(ULONG
*)buf
= alg_props
[id
].hash_length
;
596 return STATUS_SUCCESS
;
599 if (!strcmpW( prop
, BCRYPT_ALGORITHM_NAME
))
601 *ret_size
= (strlenW(alg_props
[id
].alg_name
)+1)*sizeof(WCHAR
);
602 if (size
< *ret_size
)
603 return STATUS_BUFFER_TOO_SMALL
;
605 memcpy(buf
, alg_props
[id
].alg_name
, *ret_size
);
606 return STATUS_SUCCESS
;
609 return STATUS_NOT_IMPLEMENTED
;
612 static NTSTATUS
get_alg_property( enum alg_id id
, const WCHAR
*prop
, UCHAR
*buf
, ULONG size
, ULONG
*ret_size
)
617 status
= generic_alg_property( id
, prop
, buf
, size
, ret_size
);
618 if (status
!= STATUS_NOT_IMPLEMENTED
)
624 if (!strcmpW( prop
, BCRYPT_OBJECT_LENGTH
))
626 value
= OBJECT_LENGTH_MD5
;
629 FIXME( "unsupported md5 algorithm property %s\n", debugstr_w(prop
) );
630 return STATUS_NOT_IMPLEMENTED
;
632 if (!strcmpW( prop
, BCRYPT_OBJECT_LENGTH
))
634 value
= OBJECT_LENGTH_SHA1
;
637 FIXME( "unsupported sha1 algorithm property %s\n", debugstr_w(prop
) );
638 return STATUS_NOT_IMPLEMENTED
;
641 if (!strcmpW( prop
, BCRYPT_OBJECT_LENGTH
))
643 value
= OBJECT_LENGTH_SHA256
;
646 FIXME( "unsupported sha256 algorithm property %s\n", debugstr_w(prop
) );
647 return STATUS_NOT_IMPLEMENTED
;
650 if (!strcmpW( prop
, BCRYPT_OBJECT_LENGTH
))
652 value
= OBJECT_LENGTH_SHA384
;
655 FIXME( "unsupported sha384 algorithm property %s\n", debugstr_w(prop
) );
656 return STATUS_NOT_IMPLEMENTED
;
659 if (!strcmpW( prop
, BCRYPT_OBJECT_LENGTH
))
661 value
= OBJECT_LENGTH_SHA512
;
664 FIXME( "unsupported sha512 algorithm property %s\n", debugstr_w(prop
) );
665 return STATUS_NOT_IMPLEMENTED
;
668 FIXME( "unsupported algorithm %u\n", id
);
669 return STATUS_NOT_IMPLEMENTED
;
672 if (size
< sizeof(ULONG
))
674 *ret_size
= sizeof(ULONG
);
675 return STATUS_BUFFER_TOO_SMALL
;
677 if (buf
) *(ULONG
*)buf
= value
;
678 *ret_size
= sizeof(ULONG
);
680 return STATUS_SUCCESS
;
683 static NTSTATUS
get_hash_property( enum alg_id id
, const WCHAR
*prop
, UCHAR
*buf
, ULONG size
, ULONG
*ret_size
)
687 status
= generic_alg_property( id
, prop
, buf
, size
, ret_size
);
688 if (status
== STATUS_NOT_IMPLEMENTED
)
689 FIXME( "unsupported property %s\n", debugstr_w(prop
) );
693 NTSTATUS WINAPI
BCryptGetProperty( BCRYPT_HANDLE handle
, LPCWSTR prop
, UCHAR
*buffer
, ULONG count
, ULONG
*res
, ULONG flags
)
695 struct object
*object
= handle
;
697 TRACE( "%p, %s, %p, %u, %p, %08x\n", handle
, wine_dbgstr_w(prop
), buffer
, count
, res
, flags
);
699 if (!object
) return STATUS_INVALID_HANDLE
;
700 if (!prop
|| !res
) return STATUS_INVALID_PARAMETER
;
702 switch (object
->magic
)
706 const struct algorithm
*alg
= (const struct algorithm
*)object
;
707 return get_alg_property( alg
->id
, prop
, buffer
, count
, res
);
711 const struct hash
*hash
= (const struct hash
*)object
;
712 return get_hash_property( hash
->alg_id
, prop
, buffer
, count
, res
);
715 WARN( "unknown magic %08x\n", object
->magic
);
716 return STATUS_INVALID_HANDLE
;
720 NTSTATUS WINAPI
BCryptCreateHash( BCRYPT_ALG_HANDLE algorithm
, BCRYPT_HASH_HANDLE
*handle
, UCHAR
*object
, ULONG objectlen
,
721 UCHAR
*secret
, ULONG secretlen
, ULONG flags
)
723 struct algorithm
*alg
= algorithm
;
727 TRACE( "%p, %p, %p, %u, %p, %u, %08x - stub\n", algorithm
, handle
, object
, objectlen
,
728 secret
, secretlen
, flags
);
731 FIXME( "unimplemented flags %08x\n", flags
);
732 return STATUS_NOT_IMPLEMENTED
;
735 if (!alg
|| alg
->hdr
.magic
!= MAGIC_ALG
) return STATUS_INVALID_HANDLE
;
736 if (object
) FIXME( "ignoring object buffer\n" );
738 if (!(hash
= HeapAlloc( GetProcessHeap(), 0, sizeof(*hash
) ))) return STATUS_NO_MEMORY
;
739 hash
->hdr
.magic
= MAGIC_HASH
;
740 hash
->alg_id
= alg
->id
;
741 hash
->hmac
= alg
->hmac
;
745 status
= hmac_init( hash
, secret
, secretlen
);
749 status
= hash_init( hash
);
752 if (status
!= STATUS_SUCCESS
)
754 HeapFree( GetProcessHeap(), 0, hash
);
759 return STATUS_SUCCESS
;
762 NTSTATUS WINAPI
BCryptDestroyHash( BCRYPT_HASH_HANDLE handle
)
764 struct hash
*hash
= handle
;
766 TRACE( "%p\n", handle
);
768 if (!hash
|| hash
->hdr
.magic
!= MAGIC_HASH
) return STATUS_INVALID_HANDLE
;
769 HeapFree( GetProcessHeap(), 0, hash
);
770 return STATUS_SUCCESS
;
773 NTSTATUS WINAPI
BCryptHashData( BCRYPT_HASH_HANDLE handle
, UCHAR
*input
, ULONG size
, ULONG flags
)
775 struct hash
*hash
= handle
;
777 TRACE( "%p, %p, %u, %08x\n", handle
, input
, size
, flags
);
779 if (!hash
|| hash
->hdr
.magic
!= MAGIC_HASH
) return STATUS_INVALID_HANDLE
;
780 if (!input
) return STATUS_SUCCESS
;
784 return hmac_update( hash
, input
, size
);
788 return hash_update( hash
, input
, size
);
792 NTSTATUS WINAPI
BCryptFinishHash( BCRYPT_HASH_HANDLE handle
, UCHAR
*output
, ULONG size
, ULONG flags
)
794 struct hash
*hash
= handle
;
796 TRACE( "%p, %p, %u, %08x\n", handle
, output
, size
, flags
);
798 if (!hash
|| hash
->hdr
.magic
!= MAGIC_HASH
) return STATUS_INVALID_HANDLE
;
799 if (!output
) return STATUS_INVALID_PARAMETER
;
803 return hmac_finish( hash
, output
, size
);
807 return hash_finish( hash
, output
, size
);
811 NTSTATUS WINAPI
BCryptHash( BCRYPT_ALG_HANDLE algorithm
, UCHAR
*secret
, ULONG secretlen
,
812 UCHAR
*input
, ULONG inputlen
, UCHAR
*output
, ULONG outputlen
)
815 BCRYPT_HASH_HANDLE handle
;
817 TRACE( "%p, %p, %u, %p, %u, %p, %u\n", algorithm
, secret
, secretlen
,
818 input
, inputlen
, output
, outputlen
);
820 status
= BCryptCreateHash( algorithm
, &handle
, NULL
, 0, secret
, secretlen
, 0);
821 if (status
!= STATUS_SUCCESS
)
826 status
= BCryptHashData( handle
, input
, inputlen
, 0 );
827 if (status
!= STATUS_SUCCESS
)
829 BCryptDestroyHash( handle
);
833 status
= BCryptFinishHash( handle
, output
, outputlen
, 0 );
834 if (status
!= STATUS_SUCCESS
)
836 BCryptDestroyHash( handle
);
840 return BCryptDestroyHash( handle
);
843 BOOL WINAPI
DllMain( HINSTANCE hinst
, DWORD reason
, LPVOID reserved
)
847 case DLL_PROCESS_ATTACH
:
849 DisableThreadLibraryCalls( hinst
);
850 #if defined(HAVE_GNUTLS_HASH) && !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H)
855 case DLL_PROCESS_DETACH
:
857 #if defined(HAVE_GNUTLS_HASH) && !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H)
858 gnutls_uninitialize();