commit b4ac402fd00535456ade2f90a3119d5657e80bdb
parent 516314b7eca2efdfbdb276e907c1bd245f2bfe3a
Author: Michael Savage <mikejsavage@gmail.com>
Date: Sun, 18 Feb 2018 20:41:09 +0200
Add ggentropy
Diffstat:
2 files changed, 78 insertions(+), 0 deletions(-)
diff --git a/ggentropy.cc b/ggentropy.cc
@@ -0,0 +1,73 @@
+#include "intrinsics.h"
+#include "log.h"
+#include "platform.h"
+
+#if PLATFORM_LINUX || PLATFORM_OSX
+
+static bool try_urandom( void * buf, size_t n ) {
+ ASSERT( n <= 256 );
+
+ FILE * f = fopen( "/dev/urandom", "r" );
+ if( f == NULL )
+ return false;
+
+ size_t ok = fread( buf, 1, n, f );
+ fclose( f );
+
+ return ok == n;
+}
+
+#endif
+
+#if PLATFORM_WINDOWS
+
+#include <wincrypt.h>
+
+bool ggentropy( void * buf, size_t n ) {
+ ASSERT( n <= 256 );
+ HCRYPTPROV provider;
+
+ if( CryptAcquireContext( &provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == 0 )
+ return false;
+
+ int ok = CryptGenRandom( provider, n, buf );
+ CryptReleaseContext(provider, 0);
+
+ return ok != 0;
+}
+
+#elif PLATFORM_LINUX
+
+#include <sys/random.h>
+
+bool ggentropy( void * buf, size_t n ) {
+ ASSERT( n <= 256 );
+
+ int ok = getrandom( buf, n, 0 );
+ if( ok == 0 )
+ return true;
+
+ if( errno != ENOSYS )
+ FATAL( "getrandom" );
+
+ return try_urandom( buf, n );
+}
+
+#elif PLATFORM_OSX
+
+bool ggentropy( void * buf, size_t n ) {
+ ASSERT( n <= 256 );
+ return try_urandom( buf, n );
+}
+
+#elif PLATFORM_OPENBSD
+
+bool ggentropy( void * buf, size_t n ) {
+ ASSERT( n <= 256 );
+ arc4random_buf( buf, n );
+ return true;
+}
+
+#else
+#error new platform
+#endif
diff --git a/ggentropy.h b/ggentropy.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#include <stddef.h>
+
+bool ggentropy( void * buf, size_t n );