summaryrefslogtreecommitdiff
path: root/src/SimpleRandomizer.cc
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2022-04-09 15:48:16 +0900
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2022-04-09 17:23:00 +0900
commitba3396f7bb210b53fb940f274a0622ad9799545c (patch)
treee186e0c5b27cc146810a0ddcba95866f6a67bce9 /src/SimpleRandomizer.cc
parent851a74f53e6128019dbfff7d410e91c9d4d03799 (diff)
Better entropy for getRandomBytes
Diffstat (limited to 'src/SimpleRandomizer.cc')
-rw-r--r--src/SimpleRandomizer.cc48
1 files changed, 38 insertions, 10 deletions
diff --git a/src/SimpleRandomizer.cc b/src/SimpleRandomizer.cc
index 8a055d66..8dbef82f 100644
--- a/src/SimpleRandomizer.cc
+++ b/src/SimpleRandomizer.cc
@@ -39,6 +39,11 @@
#include <cstdlib>
#include <cassert>
#include <cstring>
+#include <iostream>
+
+#ifdef __APPLE__
+# include <Security/SecRandom.h>
+#endif // __APPLE__
#include "a2time.h"
#include "a2functional.h"
@@ -89,17 +94,40 @@ void SimpleRandomizer::getRandomBytes(unsigned char* buf, size_t len)
{
#ifdef __MINGW32__
BOOL r = CryptGenRandom(provider_, len, reinterpret_cast<BYTE*>(buf));
- assert(r);
-#else // ! __MINGW32__
- auto ubuf = reinterpret_cast<result_type*>(buf);
- size_t q = len / sizeof(result_type);
- auto dis = std::uniform_int_distribution<result_type>();
- for (; q > 0; --q, ++ubuf) {
- *ubuf = dis(gen_);
+ if (!r) {
+ assert(r);
+ abort();
+ }
+#elif defined(__APPLE__)
+ auto rv = SecRandomCopyBytes(kSecRandomDefault, len, buf);
+ assert(errSecSuccess == rv);
+#else // !__MINGW32__ && !__APPLE__
+ constexpr static size_t blocklen = 256;
+ auto iter = len / blocklen;
+ auto p = buf;
+
+ for (size_t i = 0; i < iter; ++i) {
+ auto rv = getentropy(p, blocklen);
+ if (rv != 0) {
+ std::cerr << "getentropy: " << strerror(errno) << std::endl;
+ assert(0);
+ abort();
+ }
+
+ p += blocklen;
+ }
+
+ auto rem = len - iter * blocklen;
+ if (rem == 0) {
+ return;
+ }
+
+ auto rv = getentropy(p, rem);
+ if (rv != 0) {
+ std::cerr << "getentropy: " << strerror(errno) << std::endl;
+ assert(0);
+ abort();
}
- const size_t r = len % sizeof(result_type);
- auto last = dis(gen_);
- memcpy(ubuf, &last, r);
#endif // ! __MINGW32__
}