medfall

A super great game engine
Log | Files | Refs

ggentropy.cc (1235B)


      1 #include "intrinsics.h"
      2 #include "log.h"
      3 #include "platform.h"
      4 
      5 #if PLATFORM_LINUX || PLATFORM_OSX
      6 
      7 static bool try_urandom( void * buf, size_t n ) {
      8 	ASSERT( n <= 256 );
      9 
     10 	FILE * f = fopen( "/dev/urandom", "r" );
     11 	if( f == NULL )
     12 		return false;
     13 
     14 	size_t ok = fread( buf, 1, n, f );
     15 	fclose( f );
     16 
     17 	return ok == n;
     18 }
     19 
     20 #endif
     21 
     22 #if PLATFORM_WINDOWS
     23 
     24 #include <wincrypt.h>
     25 
     26 bool ggentropy( void * buf, size_t n ) {
     27 	ASSERT( n <= 256 );
     28 
     29 	HCRYPTPROV provider;
     30 	if( CryptAcquireContext( &provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == 0 )
     31 		return false;
     32 
     33 	int ok = CryptGenRandom( provider, n, ( BYTE * ) buf );
     34 	CryptReleaseContext( provider, 0 );
     35 
     36 	return ok != 0;
     37 }
     38 
     39 #elif PLATFORM_LINUX
     40 
     41 #include <sys/random.h>
     42 
     43 bool ggentropy( void * buf, size_t n ) {
     44 	ASSERT( n <= 256 );
     45 
     46 	ssize_t ok = getrandom( buf, n, 0 );
     47 	if( ok >= 0 && size_t( ok ) == n )
     48 		return true;
     49 
     50 	if( errno != ENOSYS )
     51 		return false;
     52 
     53 	return try_urandom( buf, n );
     54 }
     55 
     56 #elif PLATFORM_OSX
     57 
     58 bool ggentropy( void * buf, size_t n ) {
     59 	ASSERT( n <= 256 );
     60 	return try_urandom( buf, n );
     61 }
     62 
     63 #elif PLATFORM_OPENBSD
     64 
     65 bool ggentropy( void * buf, size_t n ) {
     66 	ASSERT( n <= 256 );
     67 	arc4random_buf( buf, n );
     68 	return true;
     69 }
     70 
     71 #else
     72 #error new platform
     73 #endif