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 #define MAGIC_ALG (('A' << 24) | ('L' << 16) | ('G' << 8) | '0')
140 #define MAGIC_HASH (('H' << 24) | ('A' << 16) | ('S' << 8) | 'H')
156 static const struct {
158 const WCHAR
*alg_name
;
160 /* ALG_ID_MD5 */ { 16, BCRYPT_MD5_ALGORITHM
},
161 /* ALG_ID_RNG */ { 0, BCRYPT_RNG_ALGORITHM
},
162 /* ALG_ID_SHA1 */ { 20, BCRYPT_SHA1_ALGORITHM
},
163 /* ALG_ID_SHA256 */ { 32, BCRYPT_SHA256_ALGORITHM
},
164 /* ALG_ID_SHA384 */ { 48, BCRYPT_SHA384_ALGORITHM
},
165 /* ALG_ID_SHA512 */ { 64, BCRYPT_SHA512_ALGORITHM
}
175 NTSTATUS WINAPI
BCryptGenRandom(BCRYPT_ALG_HANDLE handle
, UCHAR
*buffer
, ULONG count
, ULONG flags
)
177 const DWORD supported_flags
= BCRYPT_USE_SYSTEM_PREFERRED_RNG
;
178 struct algorithm
*algorithm
= handle
;
180 TRACE("%p, %p, %u, %08x - semi-stub\n", handle
, buffer
, count
, flags
);
184 /* It's valid to call without an algorithm if BCRYPT_USE_SYSTEM_PREFERRED_RNG
185 * is set. In this case the preferred system RNG is used.
187 if (!(flags
& BCRYPT_USE_SYSTEM_PREFERRED_RNG
))
188 return STATUS_INVALID_HANDLE
;
190 else if (algorithm
->hdr
.magic
!= MAGIC_ALG
|| algorithm
->id
!= ALG_ID_RNG
)
191 return STATUS_INVALID_HANDLE
;
194 return STATUS_INVALID_PARAMETER
;
196 if (flags
& ~supported_flags
)
197 FIXME("unsupported flags %08x\n", flags
& ~supported_flags
);
200 FIXME("ignoring selected algorithm\n");
202 /* When zero bytes are requested the function returns success too. */
204 return STATUS_SUCCESS
;
206 if (algorithm
|| (flags
& BCRYPT_USE_SYSTEM_PREFERRED_RNG
))
208 if (RtlGenRandom(buffer
, count
))
209 return STATUS_SUCCESS
;
212 FIXME("called with unsupported parameters, returning error\n");
213 return STATUS_NOT_IMPLEMENTED
;
216 NTSTATUS WINAPI
BCryptOpenAlgorithmProvider( BCRYPT_ALG_HANDLE
*handle
, LPCWSTR id
, LPCWSTR implementation
, DWORD flags
)
218 struct algorithm
*alg
;
221 const DWORD supported_flags
= BCRYPT_ALG_HANDLE_HMAC_FLAG
;
223 TRACE( "%p, %s, %s, %08x\n", handle
, wine_dbgstr_w(id
), wine_dbgstr_w(implementation
), flags
);
225 if (!handle
|| !id
) return STATUS_INVALID_PARAMETER
;
226 if (flags
& ~supported_flags
)
228 FIXME( "unsupported flags %08x\n", flags
& ~supported_flags
);
229 return STATUS_NOT_IMPLEMENTED
;
232 if (!strcmpW( id
, BCRYPT_SHA1_ALGORITHM
)) alg_id
= ALG_ID_SHA1
;
233 else if (!strcmpW( id
, BCRYPT_MD5_ALGORITHM
)) alg_id
= ALG_ID_MD5
;
234 else if (!strcmpW( id
, BCRYPT_RNG_ALGORITHM
)) alg_id
= ALG_ID_RNG
;
235 else if (!strcmpW( id
, BCRYPT_SHA256_ALGORITHM
)) alg_id
= ALG_ID_SHA256
;
236 else if (!strcmpW( id
, BCRYPT_SHA384_ALGORITHM
)) alg_id
= ALG_ID_SHA384
;
237 else if (!strcmpW( id
, BCRYPT_SHA512_ALGORITHM
)) alg_id
= ALG_ID_SHA512
;
240 FIXME( "algorithm %s not supported\n", debugstr_w(id
) );
241 return STATUS_NOT_IMPLEMENTED
;
243 if (implementation
&& strcmpW( implementation
, MS_PRIMITIVE_PROVIDER
))
245 FIXME( "implementation %s not supported\n", debugstr_w(implementation
) );
246 return STATUS_NOT_IMPLEMENTED
;
249 if (!(alg
= HeapAlloc( GetProcessHeap(), 0, sizeof(*alg
) ))) return STATUS_NO_MEMORY
;
250 alg
->hdr
.magic
= MAGIC_ALG
;
252 alg
->hmac
= flags
& BCRYPT_ALG_HANDLE_HMAC_FLAG
;
255 return STATUS_SUCCESS
;
258 NTSTATUS WINAPI
BCryptCloseAlgorithmProvider( BCRYPT_ALG_HANDLE handle
, DWORD flags
)
260 struct algorithm
*alg
= handle
;
262 TRACE( "%p, %08x\n", handle
, flags
);
264 if (!alg
|| alg
->hdr
.magic
!= MAGIC_ALG
) return STATUS_INVALID_HANDLE
;
265 HeapFree( GetProcessHeap(), 0, alg
);
266 return STATUS_SUCCESS
;
269 NTSTATUS WINAPI
BCryptGetFipsAlgorithmMode(BOOLEAN
*enabled
)
271 FIXME("%p - semi-stub\n", enabled
);
274 return STATUS_INVALID_PARAMETER
;
277 return STATUS_SUCCESS
;
280 #ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
289 CC_SHA1_CTX sha1_ctx
;
290 CC_SHA256_CTX sha256_ctx
;
291 CC_SHA512_CTX sha512_ctx
;
292 CCHmacContext hmac_ctx
;
296 static NTSTATUS
hash_init( struct hash
*hash
)
298 switch (hash
->alg_id
)
301 CC_MD5_Init( &hash
->u
.md5_ctx
);
305 CC_SHA1_Init( &hash
->u
.sha1_ctx
);
309 CC_SHA256_Init( &hash
->u
.sha256_ctx
);
313 CC_SHA384_Init( &hash
->u
.sha512_ctx
);
317 CC_SHA512_Init( &hash
->u
.sha512_ctx
);
321 ERR( "unhandled id %u\n", hash
->alg_id
);
322 return STATUS_NOT_IMPLEMENTED
;
324 return STATUS_SUCCESS
;
327 static NTSTATUS
hmac_init( struct hash
*hash
, UCHAR
*key
, ULONG key_size
)
329 CCHmacAlgorithm cc_algorithm
;
330 switch (hash
->alg_id
)
333 cc_algorithm
= kCCHmacAlgMD5
;
337 cc_algorithm
= kCCHmacAlgSHA1
;
341 cc_algorithm
= kCCHmacAlgSHA256
;
345 cc_algorithm
= kCCHmacAlgSHA384
;
349 cc_algorithm
= kCCHmacAlgSHA512
;
353 ERR( "unhandled id %u\n", hash
->alg_id
);
354 return STATUS_NOT_IMPLEMENTED
;
357 CCHmacInit( &hash
->u
.hmac_ctx
, cc_algorithm
, key
, key_size
);
358 return STATUS_SUCCESS
;
362 static NTSTATUS
hash_update( struct hash
*hash
, UCHAR
*input
, ULONG size
)
364 switch (hash
->alg_id
)
367 CC_MD5_Update( &hash
->u
.md5_ctx
, input
, size
);
371 CC_SHA1_Update( &hash
->u
.sha1_ctx
, input
, size
);
375 CC_SHA256_Update( &hash
->u
.sha256_ctx
, input
, size
);
379 CC_SHA384_Update( &hash
->u
.sha512_ctx
, input
, size
);
383 CC_SHA512_Update( &hash
->u
.sha512_ctx
, input
, size
);
387 ERR( "unhandled id %u\n", hash
->alg_id
);
388 return STATUS_NOT_IMPLEMENTED
;
390 return STATUS_SUCCESS
;
393 static NTSTATUS
hmac_update( struct hash
*hash
, UCHAR
*input
, ULONG size
)
395 CCHmacUpdate( &hash
->u
.hmac_ctx
, input
, size
);
396 return STATUS_SUCCESS
;
399 static NTSTATUS
hash_finish( struct hash
*hash
, UCHAR
*output
, ULONG size
)
401 switch (hash
->alg_id
)
404 CC_MD5_Final( output
, &hash
->u
.md5_ctx
);
408 CC_SHA1_Final( output
, &hash
->u
.sha1_ctx
);
412 CC_SHA256_Final( output
, &hash
->u
.sha256_ctx
);
416 CC_SHA384_Final( output
, &hash
->u
.sha512_ctx
);
420 CC_SHA512_Final( output
, &hash
->u
.sha512_ctx
);
424 ERR( "unhandled id %u\n", hash
->alg_id
);
427 return STATUS_SUCCESS
;
430 static NTSTATUS
hmac_finish( struct hash
*hash
, UCHAR
*output
, ULONG size
)
432 CCHmacFinal( &hash
->u
.hmac_ctx
, output
);
434 return STATUS_SUCCESS
;
436 #elif defined(HAVE_GNUTLS_HASH)
444 gnutls_hash_hd_t hash_handle
;
445 gnutls_hmac_hd_t hmac_handle
;
449 static NTSTATUS
hash_init( struct hash
*hash
)
451 gnutls_digest_algorithm_t alg
;
453 if (!libgnutls_handle
) return STATUS_INTERNAL_ERROR
;
455 switch (hash
->alg_id
)
458 alg
= GNUTLS_DIG_MD5
;
461 alg
= GNUTLS_DIG_SHA1
;
465 alg
= GNUTLS_DIG_SHA256
;
469 alg
= GNUTLS_DIG_SHA384
;
473 alg
= GNUTLS_DIG_SHA512
;
477 ERR( "unhandled id %u\n", hash
->alg_id
);
478 return STATUS_NOT_IMPLEMENTED
;
481 if (pgnutls_hash_init( &hash
->u
.hash_handle
, alg
)) return STATUS_INTERNAL_ERROR
;
482 return STATUS_SUCCESS
;
485 static NTSTATUS
hmac_init( struct hash
*hash
, UCHAR
*key
, ULONG key_size
)
487 gnutls_mac_algorithm_t alg
;
489 if (!libgnutls_handle
) return STATUS_INTERNAL_ERROR
;
491 switch (hash
->alg_id
)
494 alg
= GNUTLS_MAC_MD5
;
497 alg
= GNUTLS_MAC_SHA1
;
501 alg
= GNUTLS_MAC_SHA256
;
505 alg
= GNUTLS_MAC_SHA384
;
509 alg
= GNUTLS_MAC_SHA512
;
513 ERR( "unhandled id %u\n", hash
->alg_id
);
514 return STATUS_NOT_IMPLEMENTED
;
517 if (pgnutls_hmac_init( &hash
->u
.hmac_handle
, alg
, key
, key_size
)) return STATUS_INTERNAL_ERROR
;
518 return STATUS_SUCCESS
;
521 static NTSTATUS
hash_update( struct hash
*hash
, UCHAR
*input
, ULONG size
)
523 if (pgnutls_hash( hash
->u
.hash_handle
, input
, size
)) return STATUS_INTERNAL_ERROR
;
524 return STATUS_SUCCESS
;
527 static NTSTATUS
hmac_update( struct hash
*hash
, UCHAR
*input
, ULONG size
)
529 if (pgnutls_hmac( hash
->u
.hmac_handle
, input
, size
)) return STATUS_INTERNAL_ERROR
;
530 return STATUS_SUCCESS
;
533 static NTSTATUS
hash_finish( struct hash
*hash
, UCHAR
*output
, ULONG size
)
535 pgnutls_hash_deinit( hash
->u
.hash_handle
, output
);
536 return STATUS_SUCCESS
;
539 static NTSTATUS
hmac_finish( struct hash
*hash
, UCHAR
*output
, ULONG size
)
541 pgnutls_hmac_deinit( hash
->u
.hmac_handle
, output
);
542 return STATUS_SUCCESS
;
552 static NTSTATUS
hash_init( struct hash
*hash
)
554 ERR( "support for hashes not available at build time\n" );
555 return STATUS_NOT_IMPLEMENTED
;
558 static NTSTATUS
hmac_init( struct hash
*hash
, UCHAR
*key
, ULONG key_size
)
560 ERR( "support for hashes not available at build time\n" );
561 return STATUS_NOT_IMPLEMENTED
;
564 static NTSTATUS
hash_update( struct hash
*hash
, UCHAR
*input
, ULONG size
)
566 ERR( "support for hashes not available at build time\n" );
567 return STATUS_NOT_IMPLEMENTED
;
570 static NTSTATUS
hmac_update( struct hash
*hash
, UCHAR
*input
, ULONG size
)
572 ERR( "support for hashes not available at build time\n" );
573 return STATUS_NOT_IMPLEMENTED
;
576 static NTSTATUS
hash_finish( struct hash
*hash
, UCHAR
*output
, ULONG size
)
578 ERR( "support for hashes not available at build time\n" );
579 return STATUS_NOT_IMPLEMENTED
;
582 static NTSTATUS
hmac_finish( struct hash
*hash
, UCHAR
*output
, ULONG size
)
584 ERR( "support for hashes not available at build time\n" );
585 return STATUS_NOT_IMPLEMENTED
;
589 #define OBJECT_LENGTH_MD5 274
590 #define OBJECT_LENGTH_SHA1 278
591 #define OBJECT_LENGTH_SHA256 286
592 #define OBJECT_LENGTH_SHA384 382
593 #define OBJECT_LENGTH_SHA512 382
595 static NTSTATUS
generic_alg_property( enum alg_id id
, const WCHAR
*prop
, UCHAR
*buf
, ULONG size
, ULONG
*ret_size
)
597 if (!strcmpW( prop
, BCRYPT_HASH_LENGTH
))
599 *ret_size
= sizeof(ULONG
);
600 if (size
< sizeof(ULONG
))
601 return STATUS_BUFFER_TOO_SMALL
;
603 *(ULONG
*)buf
= alg_props
[id
].hash_length
;
604 return STATUS_SUCCESS
;
607 if (!strcmpW( prop
, BCRYPT_ALGORITHM_NAME
))
609 *ret_size
= (strlenW(alg_props
[id
].alg_name
)+1)*sizeof(WCHAR
);
610 if (size
< *ret_size
)
611 return STATUS_BUFFER_TOO_SMALL
;
613 memcpy(buf
, alg_props
[id
].alg_name
, *ret_size
);
614 return STATUS_SUCCESS
;
617 return STATUS_NOT_IMPLEMENTED
;
620 static NTSTATUS
get_alg_property( enum alg_id id
, const WCHAR
*prop
, UCHAR
*buf
, ULONG size
, ULONG
*ret_size
)
625 status
= generic_alg_property( id
, prop
, buf
, size
, ret_size
);
626 if (status
!= STATUS_NOT_IMPLEMENTED
)
632 if (!strcmpW( prop
, BCRYPT_OBJECT_LENGTH
))
634 value
= OBJECT_LENGTH_MD5
;
637 FIXME( "unsupported md5 algorithm property %s\n", debugstr_w(prop
) );
638 return STATUS_NOT_IMPLEMENTED
;
641 if (!strcmpW( prop
, BCRYPT_OBJECT_LENGTH
)) return STATUS_NOT_SUPPORTED
;
642 FIXME( "unsupported rng algorithm property %s\n", debugstr_w(prop
) );
643 return STATUS_NOT_IMPLEMENTED
;
646 if (!strcmpW( prop
, BCRYPT_OBJECT_LENGTH
))
648 value
= OBJECT_LENGTH_SHA1
;
651 FIXME( "unsupported sha1 algorithm property %s\n", debugstr_w(prop
) );
652 return STATUS_NOT_IMPLEMENTED
;
655 if (!strcmpW( prop
, BCRYPT_OBJECT_LENGTH
))
657 value
= OBJECT_LENGTH_SHA256
;
660 FIXME( "unsupported sha256 algorithm property %s\n", debugstr_w(prop
) );
661 return STATUS_NOT_IMPLEMENTED
;
664 if (!strcmpW( prop
, BCRYPT_OBJECT_LENGTH
))
666 value
= OBJECT_LENGTH_SHA384
;
669 FIXME( "unsupported sha384 algorithm property %s\n", debugstr_w(prop
) );
670 return STATUS_NOT_IMPLEMENTED
;
673 if (!strcmpW( prop
, BCRYPT_OBJECT_LENGTH
))
675 value
= OBJECT_LENGTH_SHA512
;
678 FIXME( "unsupported sha512 algorithm property %s\n", debugstr_w(prop
) );
679 return STATUS_NOT_IMPLEMENTED
;
682 FIXME( "unsupported algorithm %u\n", id
);
683 return STATUS_NOT_IMPLEMENTED
;
686 if (size
< sizeof(ULONG
))
688 *ret_size
= sizeof(ULONG
);
689 return STATUS_BUFFER_TOO_SMALL
;
691 if (buf
) *(ULONG
*)buf
= value
;
692 *ret_size
= sizeof(ULONG
);
694 return STATUS_SUCCESS
;
697 static NTSTATUS
get_hash_property( enum alg_id id
, const WCHAR
*prop
, UCHAR
*buf
, ULONG size
, ULONG
*ret_size
)
701 status
= generic_alg_property( id
, prop
, buf
, size
, ret_size
);
702 if (status
== STATUS_NOT_IMPLEMENTED
)
703 FIXME( "unsupported property %s\n", debugstr_w(prop
) );
707 NTSTATUS WINAPI
BCryptGetProperty( BCRYPT_HANDLE handle
, LPCWSTR prop
, UCHAR
*buffer
, ULONG count
, ULONG
*res
, ULONG flags
)
709 struct object
*object
= handle
;
711 TRACE( "%p, %s, %p, %u, %p, %08x\n", handle
, wine_dbgstr_w(prop
), buffer
, count
, res
, flags
);
713 if (!object
) return STATUS_INVALID_HANDLE
;
714 if (!prop
|| !res
) return STATUS_INVALID_PARAMETER
;
716 switch (object
->magic
)
720 const struct algorithm
*alg
= (const struct algorithm
*)object
;
721 return get_alg_property( alg
->id
, prop
, buffer
, count
, res
);
725 const struct hash
*hash
= (const struct hash
*)object
;
726 return get_hash_property( hash
->alg_id
, prop
, buffer
, count
, res
);
729 WARN( "unknown magic %08x\n", object
->magic
);
730 return STATUS_INVALID_HANDLE
;
734 NTSTATUS WINAPI
BCryptCreateHash( BCRYPT_ALG_HANDLE algorithm
, BCRYPT_HASH_HANDLE
*handle
, UCHAR
*object
, ULONG objectlen
,
735 UCHAR
*secret
, ULONG secretlen
, ULONG flags
)
737 struct algorithm
*alg
= algorithm
;
741 TRACE( "%p, %p, %p, %u, %p, %u, %08x - stub\n", algorithm
, handle
, object
, objectlen
,
742 secret
, secretlen
, flags
);
745 FIXME( "unimplemented flags %08x\n", flags
);
746 return STATUS_NOT_IMPLEMENTED
;
749 if (!alg
|| alg
->hdr
.magic
!= MAGIC_ALG
) return STATUS_INVALID_HANDLE
;
750 if (object
) FIXME( "ignoring object buffer\n" );
752 if (!(hash
= HeapAlloc( GetProcessHeap(), 0, sizeof(*hash
) ))) return STATUS_NO_MEMORY
;
753 hash
->hdr
.magic
= MAGIC_HASH
;
754 hash
->alg_id
= alg
->id
;
755 hash
->hmac
= alg
->hmac
;
759 status
= hmac_init( hash
, secret
, secretlen
);
763 status
= hash_init( hash
);
766 if (status
!= STATUS_SUCCESS
)
768 HeapFree( GetProcessHeap(), 0, hash
);
773 return STATUS_SUCCESS
;
776 NTSTATUS WINAPI
BCryptDestroyHash( BCRYPT_HASH_HANDLE handle
)
778 struct hash
*hash
= handle
;
780 TRACE( "%p\n", handle
);
782 if (!hash
|| hash
->hdr
.magic
!= MAGIC_HASH
) return STATUS_INVALID_HANDLE
;
783 HeapFree( GetProcessHeap(), 0, hash
);
784 return STATUS_SUCCESS
;
787 NTSTATUS WINAPI
BCryptHashData( BCRYPT_HASH_HANDLE handle
, UCHAR
*input
, ULONG size
, ULONG flags
)
789 struct hash
*hash
= handle
;
791 TRACE( "%p, %p, %u, %08x\n", handle
, input
, size
, flags
);
793 if (!hash
|| hash
->hdr
.magic
!= MAGIC_HASH
) return STATUS_INVALID_HANDLE
;
794 if (!input
) return STATUS_SUCCESS
;
798 return hmac_update( hash
, input
, size
);
802 return hash_update( hash
, input
, size
);
806 NTSTATUS WINAPI
BCryptFinishHash( BCRYPT_HASH_HANDLE handle
, UCHAR
*output
, ULONG size
, ULONG flags
)
808 struct hash
*hash
= handle
;
810 TRACE( "%p, %p, %u, %08x\n", handle
, output
, size
, flags
);
812 if (!hash
|| hash
->hdr
.magic
!= MAGIC_HASH
) return STATUS_INVALID_HANDLE
;
813 if (!output
) return STATUS_INVALID_PARAMETER
;
817 return hmac_finish( hash
, output
, size
);
821 return hash_finish( hash
, output
, size
);
825 NTSTATUS WINAPI
BCryptHash( BCRYPT_ALG_HANDLE algorithm
, UCHAR
*secret
, ULONG secretlen
,
826 UCHAR
*input
, ULONG inputlen
, UCHAR
*output
, ULONG outputlen
)
829 BCRYPT_HASH_HANDLE handle
;
831 TRACE( "%p, %p, %u, %p, %u, %p, %u\n", algorithm
, secret
, secretlen
,
832 input
, inputlen
, output
, outputlen
);
834 status
= BCryptCreateHash( algorithm
, &handle
, NULL
, 0, secret
, secretlen
, 0);
835 if (status
!= STATUS_SUCCESS
)
840 status
= BCryptHashData( handle
, input
, inputlen
, 0 );
841 if (status
!= STATUS_SUCCESS
)
843 BCryptDestroyHash( handle
);
847 status
= BCryptFinishHash( handle
, output
, outputlen
, 0 );
848 if (status
!= STATUS_SUCCESS
)
850 BCryptDestroyHash( handle
);
854 return BCryptDestroyHash( handle
);
857 BOOL WINAPI
DllMain( HINSTANCE hinst
, DWORD reason
, LPVOID reserved
)
861 case DLL_PROCESS_ATTACH
:
863 DisableThreadLibraryCalls( hinst
);
864 #if defined(HAVE_GNUTLS_HASH) && !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H)
869 case DLL_PROCESS_DETACH
:
871 #if defined(HAVE_GNUTLS_HASH) && !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H)
872 gnutls_uninitialize();