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
20 #include <wine/config.h>
21 #include <wine/port.h>
24 #define WIN32_NO_STATUS
30 #include <wine/debug.h>
31 #include <wine/unicode.h>
32 #include <wine/library.h>
34 #ifdef SONAME_LIBMBEDTLS
35 #include <mbedtls/sha1.h>
36 #include <mbedtls/sha256.h>
37 #include <mbedtls/sha512.h>
40 WINE_DEFAULT_DEBUG_CHANNEL(bcrypt
);
42 static HINSTANCE instance
;
44 #if defined(HAVE_GNUTLS_HASH) && !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H)
45 WINE_DECLARE_DEBUG_CHANNEL(winediag
);
47 static void *libgnutls_handle
;
48 #define MAKE_FUNCPTR(f) static typeof(f) * p##f
49 MAKE_FUNCPTR(gnutls_global_deinit
);
50 MAKE_FUNCPTR(gnutls_global_init
);
51 MAKE_FUNCPTR(gnutls_global_set_log_function
);
52 MAKE_FUNCPTR(gnutls_global_set_log_level
);
53 MAKE_FUNCPTR(gnutls_hash
);
54 MAKE_FUNCPTR(gnutls_hash_deinit
);
55 MAKE_FUNCPTR(gnutls_hash_init
);
56 MAKE_FUNCPTR(gnutls_perror
);
59 static void gnutls_log( int level
, const char *msg
)
61 TRACE( "<%d> %s", level
, msg
);
64 static BOOL
gnutls_initialize(void)
68 if (!(libgnutls_handle
= wine_dlopen( SONAME_LIBGNUTLS
, RTLD_NOW
, NULL
, 0 )))
70 ERR_(winediag
)( "failed to load libgnutls, no support for crypto hashes\n" );
74 #define LOAD_FUNCPTR(f) \
75 if (!(p##f = wine_dlsym( libgnutls_handle, #f, NULL, 0 ))) \
77 ERR( "failed to load %s\n", #f ); \
81 LOAD_FUNCPTR(gnutls_global_deinit
)
82 LOAD_FUNCPTR(gnutls_global_init
)
83 LOAD_FUNCPTR(gnutls_global_set_log_function
)
84 LOAD_FUNCPTR(gnutls_global_set_log_level
)
85 LOAD_FUNCPTR(gnutls_hash
);
86 LOAD_FUNCPTR(gnutls_hash_deinit
);
87 LOAD_FUNCPTR(gnutls_hash_init
);
88 LOAD_FUNCPTR(gnutls_perror
)
91 if ((ret
= pgnutls_global_init()) != GNUTLS_E_SUCCESS
)
93 pgnutls_perror( ret
);
97 if (TRACE_ON( bcrypt
))
99 pgnutls_global_set_log_level( 4 );
100 pgnutls_global_set_log_function( gnutls_log
);
106 wine_dlclose( libgnutls_handle
, NULL
, 0 );
107 libgnutls_handle
= NULL
;
111 static void gnutls_uninitialize(void)
113 pgnutls_global_deinit();
114 wine_dlclose( libgnutls_handle
, NULL
, 0 );
115 libgnutls_handle
= NULL
;
117 #elif defined(SONAME_LIBMBEDTLS) && !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H) && !defined(__REACTOS__)
118 WINE_DECLARE_DEBUG_CHANNEL(winediag
);
120 void *libmbedtls_handle
;
122 #define MAKE_FUNCPTR(f) static typeof(f) * p##f
123 MAKE_FUNCPTR(mbedtls_sha1_init
);
124 MAKE_FUNCPTR(mbedtls_sha1_starts
);
125 MAKE_FUNCPTR(mbedtls_sha1_update
);
126 MAKE_FUNCPTR(mbedtls_sha1_finish
);
127 MAKE_FUNCPTR(mbedtls_sha1_free
);
128 MAKE_FUNCPTR(mbedtls_sha256_init
);
129 MAKE_FUNCPTR(mbedtls_sha256_starts
);
130 MAKE_FUNCPTR(mbedtls_sha256_update
);
131 MAKE_FUNCPTR(mbedtls_sha256_finish
);
132 MAKE_FUNCPTR(mbedtls_sha256_free
);
133 MAKE_FUNCPTR(mbedtls_sha512_init
);
134 MAKE_FUNCPTR(mbedtls_sha512_starts
);
135 MAKE_FUNCPTR(mbedtls_sha512_update
);
136 MAKE_FUNCPTR(mbedtls_sha512_finish
);
137 MAKE_FUNCPTR(mbedtls_sha512_free
);
140 #define mbedtls_sha1_init pmbedtls_sha1_init
141 #define mbedtls_sha1_starts pmbedtls_sha1_starts
142 #define mbedtls_sha1_update pmbedtls_sha1_update
143 #define mbedtls_sha1_finish pmbedtls_sha1_finish
144 #define mbedtls_sha1_free pmbedtls_sha1_free
145 #define mbedtls_sha256_init pmbedtls_sha256_init
146 #define mbedtls_sha256_starts pmbedtls_sha256_starts
147 #define mbedtls_sha256_update pmbedtls_sha256_update
148 #define mbedtls_sha256_finish pmbedtls_sha256_finish
149 #define mbedtls_sha256_free pmbedtls_sha256_free
150 #define mbedtls_sha512_init pmbedtls_sha512_init
151 #define mbedtls_sha512_starts pmbedtls_sha512_starts
152 #define mbedtls_sha512_update pmbedtls_sha512_update
153 #define mbedtls_sha512_finish pmbedtls_sha512_finish
154 #define mbedtls_sha512_free pmbedtls_sha512_free
156 static BOOL
mbedtls_initialize(void)
158 if (!(libmbedtls_handle
= wine_dlopen( SONAME_LIBMBEDTLS
, RTLD_NOW
, NULL
, 0 )))
160 ERR_(winediag
)( "failed to load libmbedtls, no support for crypto hashes\n" );
164 #define LOAD_FUNCPTR(f) \
165 if (!(p##f = wine_dlsym( libmbedtls_handle, #f, NULL, 0 ))) \
167 ERR( "failed to load %s\n", #f ); \
171 LOAD_FUNCPTR(mbedtls_sha1_init
)
172 LOAD_FUNCPTR(mbedtls_sha1_starts
)
173 LOAD_FUNCPTR(mbedtls_sha1_update
)
174 LOAD_FUNCPTR(mbedtls_sha1_finish
)
175 LOAD_FUNCPTR(mbedtls_sha1_free
);
176 LOAD_FUNCPTR(mbedtls_sha256_init
)
177 LOAD_FUNCPTR(mbedtls_sha256_starts
)
178 LOAD_FUNCPTR(mbedtls_sha256_update
)
179 LOAD_FUNCPTR(mbedtls_sha256_finish
)
180 LOAD_FUNCPTR(mbedtls_sha256_free
);
181 LOAD_FUNCPTR(mbedtls_sha512_init
)
182 LOAD_FUNCPTR(mbedtls_sha512_starts
)
183 LOAD_FUNCPTR(mbedtls_sha512_update
)
184 LOAD_FUNCPTR(mbedtls_sha512_finish
)
185 LOAD_FUNCPTR(mbedtls_sha512_free
);
191 wine_dlclose( libmbedtls_handle
, NULL
, 0 );
192 libmbedtls_handle
= NULL
;
196 static void mbedtls_uninitialize(void)
198 wine_dlclose( libmbedtls_handle
, NULL
, 0 );
199 libmbedtls_handle
= NULL
;
201 #endif /* SONAME_LIBMBEDTLS && !HAVE_COMMONCRYPTO_COMMONDIGEST_H && !__REACTOS__ */
203 NTSTATUS WINAPI
BCryptEnumAlgorithms(ULONG dwAlgOperations
, ULONG
*pAlgCount
,
204 BCRYPT_ALGORITHM_IDENTIFIER
**ppAlgList
, ULONG dwFlags
)
206 FIXME("%08x, %p, %p, %08x - stub\n", dwAlgOperations
, pAlgCount
, ppAlgList
, dwFlags
);
211 return STATUS_NOT_IMPLEMENTED
;
214 NTSTATUS WINAPI
BCryptGenRandom(BCRYPT_ALG_HANDLE algorithm
, UCHAR
*buffer
, ULONG count
, ULONG flags
)
216 const DWORD supported_flags
= BCRYPT_USE_SYSTEM_PREFERRED_RNG
;
217 TRACE("%p, %p, %u, %08x - semi-stub\n", algorithm
, buffer
, count
, flags
);
221 /* It's valid to call without an algorithm if BCRYPT_USE_SYSTEM_PREFERRED_RNG
222 * is set. In this case the preferred system RNG is used.
224 if (!(flags
& BCRYPT_USE_SYSTEM_PREFERRED_RNG
))
225 return STATUS_INVALID_HANDLE
;
228 return STATUS_INVALID_PARAMETER
;
230 if (flags
& ~supported_flags
)
231 FIXME("unsupported flags %08x\n", flags
& ~supported_flags
);
234 FIXME("ignoring selected algorithm\n");
236 /* When zero bytes are requested the function returns success too. */
238 return STATUS_SUCCESS
;
240 if (flags
& BCRYPT_USE_SYSTEM_PREFERRED_RNG
)
242 if (RtlGenRandom(buffer
, count
))
243 return STATUS_SUCCESS
;
246 FIXME("called with unsupported parameters, returning error\n");
247 return STATUS_NOT_IMPLEMENTED
;
250 #define MAGIC_ALG (('A' << 24) | ('L' << 16) | ('G' << 8) | '0')
251 #define MAGIC_HASH (('H' << 24) | ('A' << 16) | ('S' << 8) | 'H')
265 static const struct {
267 const WCHAR
*alg_name
;
269 /* ALG_ID_SHA1 */ { 20, BCRYPT_SHA1_ALGORITHM
},
270 /* ALG_ID_SHA256 */ { 32, BCRYPT_SHA256_ALGORITHM
},
271 /* ALG_ID_SHA384 */ { 48, BCRYPT_SHA384_ALGORITHM
},
272 /* ALG_ID_SHA512 */ { 64, BCRYPT_SHA512_ALGORITHM
}
281 NTSTATUS WINAPI
BCryptOpenAlgorithmProvider( BCRYPT_ALG_HANDLE
*handle
, LPCWSTR id
, LPCWSTR implementation
, DWORD flags
)
283 struct algorithm
*alg
;
286 TRACE( "%p, %s, %s, %08x\n", handle
, wine_dbgstr_w(id
), wine_dbgstr_w(implementation
), flags
);
288 if (!handle
|| !id
) return STATUS_INVALID_PARAMETER
;
291 FIXME( "unimplemented flags %08x\n", flags
);
292 return STATUS_NOT_IMPLEMENTED
;
295 if (!strcmpW( id
, BCRYPT_SHA1_ALGORITHM
)) alg_id
= ALG_ID_SHA1
;
296 else if (!strcmpW( id
, BCRYPT_SHA256_ALGORITHM
)) alg_id
= ALG_ID_SHA256
;
297 else if (!strcmpW( id
, BCRYPT_SHA384_ALGORITHM
)) alg_id
= ALG_ID_SHA384
;
298 else if (!strcmpW( id
, BCRYPT_SHA512_ALGORITHM
)) alg_id
= ALG_ID_SHA512
;
301 FIXME( "algorithm %s not supported\n", debugstr_w(id
) );
302 return STATUS_NOT_IMPLEMENTED
;
304 if (implementation
&& strcmpW( implementation
, MS_PRIMITIVE_PROVIDER
))
306 FIXME( "implementation %s not supported\n", debugstr_w(implementation
) );
307 return STATUS_NOT_IMPLEMENTED
;
310 if (!(alg
= HeapAlloc( GetProcessHeap(), 0, sizeof(*alg
) ))) return STATUS_NO_MEMORY
;
311 alg
->hdr
.magic
= MAGIC_ALG
;
315 return STATUS_SUCCESS
;
318 NTSTATUS WINAPI
BCryptCloseAlgorithmProvider( BCRYPT_ALG_HANDLE handle
, DWORD flags
)
320 struct algorithm
*alg
= handle
;
322 TRACE( "%p, %08x\n", handle
, flags
);
324 if (!alg
|| alg
->hdr
.magic
!= MAGIC_ALG
) return STATUS_INVALID_HANDLE
;
325 HeapFree( GetProcessHeap(), 0, alg
);
326 return STATUS_SUCCESS
;
329 NTSTATUS WINAPI
BCryptGetFipsAlgorithmMode(BOOLEAN
*enabled
)
331 FIXME("%p - semi-stub\n", enabled
);
334 return STATUS_INVALID_PARAMETER
;
337 return STATUS_SUCCESS
;
340 #ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
347 CC_SHA1_CTX sha1_ctx
;
348 CC_SHA256_CTX sha256_ctx
;
349 CC_SHA512_CTX sha512_ctx
;
353 static NTSTATUS
hash_init( struct hash
*hash
)
355 switch (hash
->alg_id
)
358 CC_SHA1_Init( &hash
->u
.sha1_ctx
);
362 CC_SHA256_Init( &hash
->u
.sha256_ctx
);
366 CC_SHA384_Init( &hash
->u
.sha512_ctx
);
370 CC_SHA512_Init( &hash
->u
.sha512_ctx
);
374 ERR( "unhandled id %u\n", hash
->alg_id
);
375 return STATUS_NOT_IMPLEMENTED
;
377 return STATUS_SUCCESS
;
380 static NTSTATUS
hash_update( struct hash
*hash
, UCHAR
*input
, ULONG size
)
382 switch (hash
->alg_id
)
385 CC_SHA1_Update( &hash
->u
.sha1_ctx
, input
, size
);
389 CC_SHA256_Update( &hash
->u
.sha256_ctx
, input
, size
);
393 CC_SHA384_Update( &hash
->u
.sha512_ctx
, input
, size
);
397 CC_SHA512_Update( &hash
->u
.sha512_ctx
, input
, size
);
401 ERR( "unhandled id %u\n", hash
->alg_id
);
402 return STATUS_NOT_IMPLEMENTED
;
404 return STATUS_SUCCESS
;
407 static NTSTATUS
hash_finish( struct hash
*hash
, UCHAR
*output
, ULONG size
)
409 switch (hash
->alg_id
)
412 CC_SHA1_Final( output
, &hash
->u
.sha1_ctx
);
416 CC_SHA256_Final( output
, &hash
->u
.sha256_ctx
);
420 CC_SHA384_Final( output
, &hash
->u
.sha512_ctx
);
424 CC_SHA512_Final( output
, &hash
->u
.sha512_ctx
);
428 ERR( "unhandled id %u\n", hash
->alg_id
);
431 return STATUS_SUCCESS
;
433 #elif defined(HAVE_GNUTLS_HASH)
438 gnutls_hash_hd_t 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_SHA1
;
454 alg
= GNUTLS_DIG_SHA256
;
458 alg
= GNUTLS_DIG_SHA384
;
462 alg
= GNUTLS_DIG_SHA512
;
466 ERR( "unhandled id %u\n", hash
->alg_id
);
467 return STATUS_NOT_IMPLEMENTED
;
470 if (pgnutls_hash_init( &hash
->handle
, alg
)) return STATUS_INTERNAL_ERROR
;
471 return STATUS_SUCCESS
;
474 static NTSTATUS
hash_update( struct hash
*hash
, UCHAR
*input
, ULONG size
)
476 if (pgnutls_hash( hash
->handle
, input
, size
)) return STATUS_INTERNAL_ERROR
;
477 return STATUS_SUCCESS
;
480 static NTSTATUS
hash_finish( struct hash
*hash
, UCHAR
*output
, ULONG size
)
482 pgnutls_hash_deinit( hash
->handle
, output
);
483 return STATUS_SUCCESS
;
485 #elif defined(SONAME_LIBMBEDTLS)
492 mbedtls_sha1_context sha1_ctx
;
493 mbedtls_sha256_context sha256_ctx
;
494 mbedtls_sha512_context sha512_ctx
;
498 static NTSTATUS
hash_init( struct hash
*hash
)
501 if (!libmbedtls_handle
) return STATUS_INTERNAL_ERROR
;
503 switch (hash
->alg_id
)
506 mbedtls_sha1_init(&hash
->u
.sha1_ctx
);
507 mbedtls_sha1_starts(&hash
->u
.sha1_ctx
);
511 mbedtls_sha256_init(&hash
->u
.sha256_ctx
);
512 mbedtls_sha256_starts(&hash
->u
.sha256_ctx
, FALSE
);
517 mbedtls_sha512_init(&hash
->u
.sha512_ctx
);
518 mbedtls_sha512_starts(&hash
->u
.sha512_ctx
, hash
->alg_id
==ALG_ID_SHA384
);
522 ERR( "unhandled id %u\n", hash
->alg_id
);
523 return STATUS_NOT_IMPLEMENTED
;
526 return STATUS_SUCCESS
;
529 static NTSTATUS
hash_update( struct hash
*hash
, UCHAR
*input
, ULONG size
)
532 if (!libmbedtls_handle
) return STATUS_INTERNAL_ERROR
;
534 switch (hash
->alg_id
)
537 mbedtls_sha1_update(&hash
->u
.sha1_ctx
, input
, size
);
541 mbedtls_sha256_update(&hash
->u
.sha256_ctx
, input
, size
);
546 mbedtls_sha512_update(&hash
->u
.sha512_ctx
, input
, size
);
550 ERR( "unhandled id %u\n", hash
->alg_id
);
551 return STATUS_NOT_IMPLEMENTED
;
554 return STATUS_SUCCESS
;
557 static NTSTATUS
hash_finish( struct hash
*hash
, UCHAR
*output
, ULONG size
)
560 if (!libmbedtls_handle
) return STATUS_INTERNAL_ERROR
;
562 switch (hash
->alg_id
)
565 mbedtls_sha1_finish(&hash
->u
.sha1_ctx
, output
);
566 mbedtls_sha1_free(&hash
->u
.sha1_ctx
);
570 mbedtls_sha256_finish(&hash
->u
.sha256_ctx
, output
);
571 mbedtls_sha256_free(&hash
->u
.sha256_ctx
);
576 mbedtls_sha512_finish(&hash
->u
.sha512_ctx
, output
);
577 mbedtls_sha512_free(&hash
->u
.sha512_ctx
);
581 ERR( "unhandled id %u\n", hash
->alg_id
);
582 return STATUS_NOT_IMPLEMENTED
;
585 return STATUS_SUCCESS
;
594 static NTSTATUS
hash_init( struct hash
*hash
)
596 ERR( "support for hashes not available at build time\n" );
597 return STATUS_NOT_IMPLEMENTED
;
600 static NTSTATUS
hash_update( struct hash
*hash
, UCHAR
*input
, ULONG size
)
602 ERR( "support for hashes not available at build time\n" );
603 return STATUS_NOT_IMPLEMENTED
;
606 static NTSTATUS
hash_finish( struct hash
*hash
, UCHAR
*output
, ULONG size
)
608 ERR( "support for hashes not available at build time\n" );
609 return STATUS_NOT_IMPLEMENTED
;
613 #define OBJECT_LENGTH_SHA1 278
614 #define OBJECT_LENGTH_SHA256 286
615 #define OBJECT_LENGTH_SHA384 382
616 #define OBJECT_LENGTH_SHA512 382
618 static NTSTATUS
generic_alg_property( enum alg_id id
, const WCHAR
*prop
, UCHAR
*buf
, ULONG size
, ULONG
*ret_size
)
620 if (!strcmpW( prop
, BCRYPT_HASH_LENGTH
))
622 *ret_size
= sizeof(ULONG
);
623 if (size
< sizeof(ULONG
))
624 return STATUS_BUFFER_TOO_SMALL
;
626 *(ULONG
*)buf
= alg_props
[id
].hash_length
;
627 return STATUS_SUCCESS
;
630 if (!strcmpW( prop
, BCRYPT_ALGORITHM_NAME
))
632 *ret_size
= (strlenW(alg_props
[id
].alg_name
)+1)*sizeof(WCHAR
);
633 if (size
< *ret_size
)
634 return STATUS_BUFFER_TOO_SMALL
;
636 memcpy(buf
, alg_props
[id
].alg_name
, *ret_size
);
637 return STATUS_SUCCESS
;
640 return STATUS_NOT_IMPLEMENTED
;
643 static NTSTATUS
get_alg_property( enum alg_id id
, const WCHAR
*prop
, UCHAR
*buf
, ULONG size
, ULONG
*ret_size
)
648 status
= generic_alg_property( id
, prop
, buf
, size
, ret_size
);
649 if (status
!= STATUS_NOT_IMPLEMENTED
)
655 if (!strcmpW( prop
, BCRYPT_OBJECT_LENGTH
))
657 value
= OBJECT_LENGTH_SHA1
;
660 FIXME( "unsupported sha1 algorithm property %s\n", debugstr_w(prop
) );
661 return STATUS_NOT_IMPLEMENTED
;
664 if (!strcmpW( prop
, BCRYPT_OBJECT_LENGTH
))
666 value
= OBJECT_LENGTH_SHA256
;
669 FIXME( "unsupported sha256 algorithm property %s\n", debugstr_w(prop
) );
670 return STATUS_NOT_IMPLEMENTED
;
673 if (!strcmpW( prop
, BCRYPT_OBJECT_LENGTH
))
675 value
= OBJECT_LENGTH_SHA384
;
678 FIXME( "unsupported sha384 algorithm property %s\n", debugstr_w(prop
) );
679 return STATUS_NOT_IMPLEMENTED
;
682 if (!strcmpW( prop
, BCRYPT_OBJECT_LENGTH
))
684 value
= OBJECT_LENGTH_SHA512
;
687 FIXME( "unsupported sha512 algorithm property %s\n", debugstr_w(prop
) );
688 return STATUS_NOT_IMPLEMENTED
;
691 FIXME( "unsupported algorithm %u\n", id
);
692 return STATUS_NOT_IMPLEMENTED
;
695 if (size
< sizeof(ULONG
))
697 *ret_size
= sizeof(ULONG
);
698 return STATUS_BUFFER_TOO_SMALL
;
700 if (buf
) *(ULONG
*)buf
= value
;
701 *ret_size
= sizeof(ULONG
);
703 return STATUS_SUCCESS
;
706 static NTSTATUS
get_hash_property( enum alg_id id
, const WCHAR
*prop
, UCHAR
*buf
, ULONG size
, ULONG
*ret_size
)
710 status
= generic_alg_property( id
, prop
, buf
, size
, ret_size
);
711 if (status
== STATUS_NOT_IMPLEMENTED
)
712 FIXME( "unsupported property %s\n", debugstr_w(prop
) );
716 NTSTATUS WINAPI
BCryptGetProperty( BCRYPT_HANDLE handle
, LPCWSTR prop
, UCHAR
*buffer
, ULONG count
, ULONG
*res
, ULONG flags
)
718 struct object
*object
= handle
;
720 TRACE( "%p, %s, %p, %u, %p, %08x\n", handle
, wine_dbgstr_w(prop
), buffer
, count
, res
, flags
);
722 if (!object
) return STATUS_INVALID_HANDLE
;
723 if (!prop
|| !res
) return STATUS_INVALID_PARAMETER
;
725 switch (object
->magic
)
729 const struct algorithm
*alg
= (const struct algorithm
*)object
;
730 return get_alg_property( alg
->id
, prop
, buffer
, count
, res
);
734 const struct hash
*hash
= (const struct hash
*)object
;
735 return get_hash_property( hash
->alg_id
, prop
, buffer
, count
, res
);
738 WARN( "unknown magic %08x\n", object
->magic
);
739 return STATUS_INVALID_HANDLE
;
743 NTSTATUS WINAPI
BCryptCreateHash( BCRYPT_ALG_HANDLE algorithm
, BCRYPT_HASH_HANDLE
*handle
, UCHAR
*object
, ULONG objectlen
,
744 UCHAR
*secret
, ULONG secretlen
, ULONG flags
)
746 struct algorithm
*alg
= algorithm
;
750 TRACE( "%p, %p, %p, %u, %p, %u, %08x - stub\n", algorithm
, handle
, object
, objectlen
,
751 secret
, secretlen
, flags
);
754 FIXME( "unimplemented flags %08x\n", flags
);
755 return STATUS_NOT_IMPLEMENTED
;
758 if (!alg
|| alg
->hdr
.magic
!= MAGIC_ALG
) return STATUS_INVALID_HANDLE
;
759 if (object
) FIXME( "ignoring object buffer\n" );
761 if (!(hash
= HeapAlloc( GetProcessHeap(), 0, sizeof(*hash
) ))) return STATUS_NO_MEMORY
;
762 hash
->hdr
.magic
= MAGIC_HASH
;
763 hash
->alg_id
= alg
->id
;
764 if ((status
= hash_init( hash
)) != STATUS_SUCCESS
)
766 HeapFree( GetProcessHeap(), 0, hash
);
771 return STATUS_SUCCESS
;
774 NTSTATUS WINAPI
BCryptDestroyHash( BCRYPT_HASH_HANDLE handle
)
776 struct hash
*hash
= handle
;
778 TRACE( "%p\n", handle
);
780 if (!hash
|| hash
->hdr
.magic
!= MAGIC_HASH
) return STATUS_INVALID_HANDLE
;
781 HeapFree( GetProcessHeap(), 0, hash
);
782 return STATUS_SUCCESS
;
785 NTSTATUS WINAPI
BCryptHashData( BCRYPT_HASH_HANDLE handle
, UCHAR
*input
, ULONG size
, ULONG flags
)
787 struct hash
*hash
= handle
;
789 TRACE( "%p, %p, %u, %08x\n", handle
, input
, size
, flags
);
791 if (!hash
|| hash
->hdr
.magic
!= MAGIC_HASH
) return STATUS_INVALID_HANDLE
;
792 if (!input
) return STATUS_INVALID_PARAMETER
;
794 return hash_update( hash
, input
, size
);
797 NTSTATUS WINAPI
BCryptFinishHash( BCRYPT_HASH_HANDLE handle
, UCHAR
*output
, ULONG size
, ULONG flags
)
799 struct hash
*hash
= handle
;
801 TRACE( "%p, %p, %u, %08x\n", handle
, output
, size
, flags
);
803 if (!hash
|| hash
->hdr
.magic
!= MAGIC_HASH
) return STATUS_INVALID_HANDLE
;
804 if (!output
) return STATUS_INVALID_PARAMETER
;
806 return hash_finish( hash
, output
, size
);
809 BOOL WINAPI
DllMain( HINSTANCE hinst
, DWORD reason
, LPVOID reserved
)
813 case DLL_PROCESS_ATTACH
:
815 DisableThreadLibraryCalls( hinst
);
816 #if defined(HAVE_GNUTLS_HASH) && !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H)
818 #elif defined(SONAME_LIBMBEDTLS) && !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H) && !defined(__REACTOS__)
819 mbedtls_initialize();
823 case DLL_PROCESS_DETACH
:
825 #if defined(HAVE_GNUTLS_HASH) && !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H)
826 gnutls_uninitialize();
827 #elif defined(SONAME_LIBMBEDTLS) && !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H) && !defined(__REACTOS__)
828 mbedtls_uninitialize();