aboutsummaryrefslogtreecommitdiff
path: root/src/crypto/random.c
diff options
context:
space:
mode:
authorAntonio Juarez <antonio.maria.juarez@live.com>2014-03-03 22:07:58 +0000
committerAntonio Juarez <antonio.maria.juarez@live.com>2014-03-03 22:07:58 +0000
commit296ae46ed8f8f6e5f986f978febad302e3df231a (patch)
tree1629164454a239308f33c9e12afb22e7f3cd8eeb /src/crypto/random.c
parentchanged name (diff)
downloadmonero-296ae46ed8f8f6e5f986f978febad302e3df231a.tar.xz
moved all stuff to github
Diffstat (limited to 'src/crypto/random.c')
-rw-r--r--src/crypto/random.c73
1 files changed, 64 insertions, 9 deletions
diff --git a/src/crypto/random.c b/src/crypto/random.c
index 582d0b8f6..a17cb47d2 100644
--- a/src/crypto/random.c
+++ b/src/crypto/random.c
@@ -1,17 +1,41 @@
+// Copyright (c) 2012-2013 The Cryptonote developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
#include <assert.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "hash-ops.h"
+#include "initializer.h"
+#include "random.h"
+
+static void generate_system_random_bytes(size_t n, void *result);
+
+#if defined(_WIN32)
+
+#include <windows.h>
+#include <wincrypt.h>
+
+static void generate_system_random_bytes(size_t n, void *result) {
+ HCRYPTPROV prov;
+#define must_succeed(x) do if (!(x)) assert(0); while (0)
+ must_succeed(CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT));
+ must_succeed(CryptGenRandom(prov, (DWORD)n, result));
+ must_succeed(CryptReleaseContext(prov, 0));
+#undef must_succeed
+}
+
+#else
+
#include <err.h>
#include <errno.h>
#include <fcntl.h>
-#include <stddef.h>
#include <stdlib.h>
-#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
-#include "hash.h"
-#include "random.h"
-
static void generate_system_random_bytes(size_t n, void *result) {
int fd;
if ((fd = open("/dev/urandom", O_RDONLY | O_NOCTTY | O_CLOEXEC)) < 0) {
@@ -38,20 +62,51 @@ static void generate_system_random_bytes(size_t n, void *result) {
}
}
-static struct keccak_state state;
+#endif
-void init_random(void) {
+static union hash_state state;
+
+#if !defined(NDEBUG)
+static volatile int curstate; /* To catch thread safety problems. */
+#endif
+
+FINALIZER(deinit_random) {
+#if !defined(NDEBUG)
+ assert(curstate == 1);
+ curstate = 0;
+#endif
+ memset(&state, 0, sizeof(union hash_state));
+}
+
+INITIALIZER(init_random) {
generate_system_random_bytes(32, &state);
+ REGISTER_FINALIZER(deinit_random);
+#if !defined(NDEBUG)
+ assert(curstate == 0);
+ curstate = 1;
+#endif
}
void generate_random_bytes(size_t n, void *result) {
+#if !defined(NDEBUG)
+ assert(curstate == 1);
+ curstate = 2;
+#endif
if (n == 0) {
+#if !defined(NDEBUG)
+ assert(curstate == 2);
+ curstate = 1;
+#endif
return;
}
for (;;) {
- keccak_permutation(&state);
+ hash_permutation(&state);
if (n <= HASH_DATA_AREA) {
memcpy(result, &state, n);
+#if !defined(NDEBUG)
+ assert(curstate == 2);
+ curstate = 1;
+#endif
return;
} else {
memcpy(result, &state, HASH_DATA_AREA);
@@ -59,4 +114,4 @@ void generate_random_bytes(size_t n, void *result) {
n -= HASH_DATA_AREA;
}
}
-} \ No newline at end of file
+}