X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/b80e619319b1def83d1e8b4f84042b661be1be7f..14957cd040308e3eeec43d26bae5d76da13fcd85:/wtf/RandomNumber.cpp?ds=sidebyside diff --git a/wtf/RandomNumber.cpp b/wtf/RandomNumber.cpp index fc48263..490c591 100644 --- a/wtf/RandomNumber.cpp +++ b/wtf/RandomNumber.cpp @@ -27,6 +27,7 @@ #include "config.h" #include "RandomNumber.h" +#include "CryptographicallyRandomNumber.h" #include "RandomNumberSeed.h" #include @@ -34,9 +35,9 @@ #include #include -#if OS(WINCE) +#if USE(MERSENNE_TWISTER_19937) extern "C" { -#include "wince/mt19937ar.c" +#include "mt19937ar.c" } #endif @@ -44,79 +45,41 @@ extern "C" { #include #include #include +#include +#include #endif namespace WTF { -double weakRandomNumber() +double randomNumber() { -#if COMPILER(MSVC) && defined(_CRT_RAND_S) - // rand_s is incredibly slow on windows so we fall back on rand for Math.random - return (rand() + (rand() / (RAND_MAX + 1.0))) / (RAND_MAX + 1.0); -#elif PLATFORM(BREWMP) - uint32_t bits; - GETRAND(reinterpret_cast(&bits), sizeof(uint32_t)); +#if USE(OS_RANDOMNESS) + uint32_t bits = cryptographicallyRandomNumber(); return static_cast(bits) / (static_cast(std::numeric_limits::max()) + 1.0); #else - return randomNumber(); -#endif -} + // Without OS_RANDOMNESS, we fall back to other random number generators + // that might not be cryptographically secure. Ideally, most ports would + // define USE(OS_RANDOMNESS). -double randomNumber() -{ -#if !ENABLE(JSC_MULTIPLE_THREADS) +#if !ENABLE(WTF_MULTIPLE_THREADS) static bool s_initialized = false; if (!s_initialized) { initializeRandomNumberGenerator(); s_initialized = true; } #endif - -#if COMPILER(MSVC) && defined(_CRT_RAND_S) - uint32_t bits; - rand_s(&bits); - return static_cast(bits) / (static_cast(std::numeric_limits::max()) + 1.0); -#elif OS(DARWIN) - uint32_t bits = arc4random(); - return static_cast(bits) / (static_cast(std::numeric_limits::max()) + 1.0); -#elif OS(UNIX) - uint32_t part1 = random() & (RAND_MAX - 1); - uint32_t part2 = random() & (RAND_MAX - 1); - // random only provides 31 bits - uint64_t fullRandom = part1; - fullRandom <<= 31; - fullRandom |= part2; - // Mask off the low 53bits - fullRandom &= (1LL << 53) - 1; - return static_cast(fullRandom)/static_cast(1LL << 53); -#elif OS(WINCE) +#if USE(MERSENNE_TWISTER_19937) return genrand_res53(); -#elif OS(WINDOWS) - uint32_t part1 = rand() & (RAND_MAX - 1); - uint32_t part2 = rand() & (RAND_MAX - 1); - uint32_t part3 = rand() & (RAND_MAX - 1); - uint32_t part4 = rand() & (RAND_MAX - 1); - // rand only provides 15 bits on Win32 - uint64_t fullRandom = part1; - fullRandom <<= 15; - fullRandom |= part2; - fullRandom <<= 15; - fullRandom |= part3; - fullRandom <<= 15; - fullRandom |= part4; - - // Mask off the low 53bits - fullRandom &= (1LL << 53) - 1; - return static_cast(fullRandom)/static_cast(1LL << 53); #elif PLATFORM(BREWMP) uint32_t bits; - ISource* randomSource; - - IShell* shell = reinterpret_cast(GETAPPINSTANCE())->m_pIShell; - ISHELL_CreateInstance(shell, AEECLSID_RANDOM, reinterpret_cast(&randomSource)); - ISOURCE_Read(randomSource, reinterpret_cast(&bits), 4); - ISOURCE_Release(randomSource); + // Is this a cryptographically strong source of random numbers? If so, we + // should move this into OSRandomSource. + // http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/140sp/140sp851.pdf + // is slightly unclear on this point, although it seems to imply that it is + // secure. + RefPtr randomSource = createRefPtrInstance(AEECLSID_RANDOM); + ISOURCE_Read(randomSource.get(), reinterpret_cast(&bits), 4); return static_cast(bits) / (static_cast(std::numeric_limits::max()) + 1.0); #else @@ -134,6 +97,7 @@ double randomNumber() fullRandom &= (1LL << 53) - 1; return static_cast(fullRandom)/static_cast(1LL << 53); #endif +#endif } }