@@ -23,6 +23,48 @@ static void *libmbedtls_handle;
2323static mbedtls_entropy_context entropy ;
2424static mbedtls_ctr_drbg_context ctr_drbg ;
2525
26+ #ifdef __REACTOS__
27+ static volatile LONG ctr_drbg_seed_state ; /* 0=not seeded, 1=seeding, 2=seeded, -1=failed */
28+
29+ static int ensure_ctr_drbg_seeded (void )
30+ {
31+ LONG state = InterlockedCompareExchange (& ctr_drbg_seed_state , 1 , 0 );
32+ int ret ;
33+
34+ if (state == 2 ) return 0 ;
35+ if (state == -1 ) return -1 ;
36+ if (state == 1 )
37+ {
38+ while ((state = InterlockedCompareExchange (& ctr_drbg_seed_state , 0 , 0 )) == 1 )
39+ SwitchToThread ();
40+ return state == 2 ? 0 : -1 ;
41+ }
42+
43+ ret = mbedtls_ctr_drbg_seed (& ctr_drbg , mbedtls_entropy_func , & entropy , NULL , 0 );
44+ if (ret )
45+ {
46+ ERR ("mbedtls_ctr_drbg_seed failed: %d\n" , ret );
47+ InterlockedExchange (& ctr_drbg_seed_state , -1 );
48+ return -1 ;
49+ }
50+
51+ InterlockedExchange (& ctr_drbg_seed_state , 2 );
52+ return 0 ;
53+ }
54+
55+ static int bcrypt_mbedtls_rng (void * rng_ctx , unsigned char * output , size_t len )
56+ {
57+ if (ensure_ctr_drbg_seeded ())
58+ return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED ;
59+ return mbedtls_ctr_drbg_random (rng_ctx , output , len );
60+ }
61+ #else
62+ static int bcrypt_mbedtls_rng (void * rng_ctx , unsigned char * output , size_t len )
63+ {
64+ return mbedtls_ctr_drbg_random (rng_ctx , output , len );
65+ }
66+ #endif
67+
2668union key_data
2769{
2870 union
@@ -272,7 +314,12 @@ NTSTATUS process_attach(void *args)
272314#endif
273315 mbedtls_ctr_drbg_init (& ctr_drbg );
274316 mbedtls_entropy_init (& entropy );
317+
318+ #ifdef __REACTOS__
319+ InterlockedExchange (& ctr_drbg_seed_state , 0 );
320+ #else
275321 mbedtls_ctr_drbg_seed (& ctr_drbg , mbedtls_entropy_func , & entropy , NULL , 0 );
322+ #endif
276323
277324 return STATUS_SUCCESS ;
278325#ifndef __REACTOS__
@@ -389,6 +436,9 @@ NTSTATUS process_detach(void *args)
389436#endif
390437 mbedtls_entropy_free (& entropy );
391438 mbedtls_ctr_drbg_free (& ctr_drbg );
439+ #ifdef __REACTOS__
440+ InterlockedExchange (& ctr_drbg_seed_state , 0 );
441+ #endif
392442#ifndef __REACTOS__
393443 wine_dlclose (libmbedtls_handle , NULL , 0 );
394444 libmbedtls_handle = NULL ;
0 commit comments