Remove blink's use of RC4 for random value generation.

This re-implements Blink's random number generator (wtf::cryptographicallyRandomValues) in terms of calling crypto::RandomBytes() directly, rather than using an ARC4 keystream that periodically stirs in system randomness.

Reason: RC4 (ARC4) has known weaknesses and has already been disabled as an accepted TLS cipher for Chrome M48. It should not be used internally for generating random numbers in Blink.

The way cryptographically random number generation worked in Blink prior to this patch is that wtf::cryptographicallyRandomValues() would generate random bytes using an ARC4 keystream. Every 1.6MB of generated data it would stir in randomness obtained via Platform::current()->cryptographicallyRandomValues().

The way it works after this patchset is that wtf::cryptographicallyRandomValues() directly calls Platform::current()->cryptographicallyRandomValues(), without layering on its own PRNG. The concrete implementation of Platform::cryptographicallyRandomValues() now calls crypto::RandBytes() [1], which provides good cryptographically secure random numbers by reading from hardware/system randomness sources.

The consequences of this change are:

 * The fixed sequence of random numbers seen by certain tests will have changed. I haven't observed this to be a problem with any of the tests though.

 * The performance characteristics of cryptographicallyRandomValues() have changed, for the worse. Measured using a microbenchmark, window.crypto.getRandomValues() is almost 5x slower now. This is not all that surprising since RC4 was pretty fast, and was only mixing in system randomness every 1.6MB (my test generated 256MB).

[1] Technically it is calling base::RandBytes(), but under the hood that calls crypto::RandBytes(). Will fix that dependency separately.

BUG=552749

Review URL: https://codereview.chromium.org/1431233002

Cr-Commit-Position: refs/heads/master@{#358803}
diff --git a/third_party/WebKit/Source/wtf/CryptographicallyRandomNumber.cpp b/third_party/WebKit/Source/wtf/CryptographicallyRandomNumber.cpp
index 227a806..a3b1551 100644
--- a/third_party/WebKit/Source/wtf/CryptographicallyRandomNumber.cpp
+++ b/third_party/WebKit/Source/wtf/CryptographicallyRandomNumber.cpp
@@ -15,25 +15,9 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/*
- * Arc4 random number generator for OpenBSD.
- *
- * This code is derived from section 17.1 of Applied Cryptography,
- * second edition, which describes a stream cipher allegedly
- * compatible with RSA Labs "RC4" cipher (the actual description of
- * which is a trade secret).  The same algorithm is used as a stream
- * cipher called "arcfour" in Tatu Ylonen's ssh package.
- *
- * RC4 is a registered trademark of RSA Laboratories.
- */
-
 #include "config.h"
 #include "wtf/CryptographicallyRandomNumber.h"
 
-#include "wtf/StdLibExtras.h"
-#include "wtf/Threading.h"
-#include "wtf/ThreadingPrimitives.h"
-
 namespace WTF {
 
 static RandomNumberSource sourceFunction;
@@ -43,143 +27,16 @@
     sourceFunction = source;
 }
 
-namespace {
-
-class ARC4Stream {
-public:
-    ARC4Stream();
-
-    uint8_t i;
-    uint8_t j;
-    uint8_t s[256];
-};
-
-class ARC4RandomNumberGenerator {
-    USING_FAST_MALLOC(ARC4RandomNumberGenerator);
-public:
-    ARC4RandomNumberGenerator();
-
-    uint32_t randomNumber();
-    void randomValues(void* buffer, size_t length);
-
-private:
-    inline void addRandomData(unsigned char *data, int length);
-    void stir();
-    void stirIfNeeded();
-    inline uint8_t getByte();
-    inline uint32_t getWord();
-
-    ARC4Stream m_stream;
-    int m_count;
-    Mutex m_mutex;
-};
-
-ARC4Stream::ARC4Stream()
-{
-    for (int n = 0; n < 256; n++)
-        s[n] = static_cast<uint8_t>(n);
-    i = 0;
-    j = 0;
-}
-
-ARC4RandomNumberGenerator::ARC4RandomNumberGenerator()
-    : m_count(0)
-{
-}
-
-void ARC4RandomNumberGenerator::addRandomData(unsigned char* data, int length)
-{
-    m_stream.i--;
-    for (int n = 0; n < 256; n++) {
-        m_stream.i++;
-        uint8_t si = m_stream.s[m_stream.i];
-        m_stream.j += si + data[n % length];
-        m_stream.s[m_stream.i] = m_stream.s[m_stream.j];
-        m_stream.s[m_stream.j] = si;
-    }
-    m_stream.j = m_stream.i;
-}
-
-void ARC4RandomNumberGenerator::stir()
-{
-    unsigned char randomness[128];
-    size_t length = sizeof(randomness);
-    (*sourceFunction)(randomness, length);
-    addRandomData(randomness, length);
-
-    // Discard early keystream, as per recommendations in:
-    // http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps
-    for (int i = 0; i < 256; i++)
-        getByte();
-    m_count = 1600000;
-}
-
-void ARC4RandomNumberGenerator::stirIfNeeded()
-{
-    if (m_count <= 0)
-        stir();
-}
-
-uint8_t ARC4RandomNumberGenerator::getByte()
-{
-    m_stream.i++;
-    uint8_t si = m_stream.s[m_stream.i];
-    m_stream.j += si;
-    uint8_t sj = m_stream.s[m_stream.j];
-    m_stream.s[m_stream.i] = sj;
-    m_stream.s[m_stream.j] = si;
-    return (m_stream.s[(si + sj) & 0xff]);
-}
-
-uint32_t ARC4RandomNumberGenerator::getWord()
-{
-    uint32_t val;
-    val = getByte() << 24;
-    val |= getByte() << 16;
-    val |= getByte() << 8;
-    val |= getByte();
-    return val;
-}
-
-uint32_t ARC4RandomNumberGenerator::randomNumber()
-{
-    MutexLocker locker(m_mutex);
-
-    m_count -= 4;
-    stirIfNeeded();
-    return getWord();
-}
-
-void ARC4RandomNumberGenerator::randomValues(void* buffer, size_t length)
-{
-    MutexLocker locker(m_mutex);
-
-    unsigned char* result = reinterpret_cast<unsigned char*>(buffer);
-    stirIfNeeded();
-    while (length--) {
-        m_count--;
-        stirIfNeeded();
-        result[length] = getByte();
-    }
-}
-
-ARC4RandomNumberGenerator& sharedRandomNumberGenerator()
-{
-    AtomicallyInitializedStaticReference(ARC4RandomNumberGenerator, randomNumberGenerator, new ARC4RandomNumberGenerator);
-    return randomNumberGenerator;
-}
-
-}
-
-
 uint32_t cryptographicallyRandomNumber()
 {
-    return sharedRandomNumberGenerator().randomNumber();
+    uint32_t result;
+    cryptographicallyRandomValues(&result, sizeof(result));
+    return result;
 }
 
 void cryptographicallyRandomValues(void* buffer, size_t length)
 {
-    sharedRandomNumberGenerator().randomValues(buffer, length);
+    (*sourceFunction)(reinterpret_cast<unsigned char*>(buffer), length);
 }
 
 }