summaryrefslogtreecommitdiff
path: root/source/kit/secure_random.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/kit/secure_random.c')
-rw-r--r--source/kit/secure_random.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/source/kit/secure_random.c b/source/kit/secure_random.c
new file mode 100644
index 0000000..8f7a302
--- /dev/null
+++ b/source/kit/secure_random.c
@@ -0,0 +1,43 @@
+#include "secure_random.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN 1
+# endif
+# include <windows.h>
+# include <wincrypt.h>
+#else
+# include <unistd.h>
+#endif
+
+void kit_secure_random(i64 size, void *data) {
+ assert(size >= 0);
+ assert(data != NULL);
+
+ if (size <= 0 || data == NULL)
+ return;
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ HCRYPTPROV prov = 0;
+ if (!CryptAcquireContextW(&prov, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT | CRYPT_SILENT) ||
+ !CryptGenRandom(prov, (DWORD) size, (BYTE *) data) ||
+ !CryptReleaseContext(prov, 0))
+ abort();
+#else
+ FILE *f = fopen("/dev/urandom", "rb");
+
+ if (f == NULL)
+ abort();
+
+ i64 n = (i64) fread(data, 1, size, f);
+ fclose(f);
+
+ if (n != size)
+ abort();
+#endif
+}