12fc2651226baac27029e38c9d6ef883fa32084dbSteve Block/*
22fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * Copyright (c) 1996, David Mazieres <dm@uun.org>
32fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
42fc2651226baac27029e38c9d6ef883fa32084dbSteve Block *
52fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * Permission to use, copy, modify, and distribute this software for any
62fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * purpose with or without fee is hereby granted, provided that the above
72fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * copyright notice and this permission notice appear in all copies.
82fc2651226baac27029e38c9d6ef883fa32084dbSteve Block *
92fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block */
172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block/*
192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * Arc4 random number generator for OpenBSD.
202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block *
212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * This code is derived from section 17.1 of Applied Cryptography,
222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * second edition, which describes a stream cipher allegedly
232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * compatible with RSA Labs "RC4" cipher (the actual description of
242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * which is a trade secret).  The same algorithm is used as a stream
252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * cipher called "arcfour" in Tatu Ylonen's ssh package.
262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block *
272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * RC4 is a registered trademark of RSA Laboratories.
282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block */
292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "config.h"
312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "CryptographicallyRandomNumber.h"
322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "MainThread.h"
342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "OSRandomSource.h"
352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "StdLibExtras.h"
362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "ThreadingPrimitives.h"
372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
382fc2651226baac27029e38c9d6ef883fa32084dbSteve Blocknamespace WTF {
392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#if USE(OS_RANDOMNESS)
412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
422fc2651226baac27029e38c9d6ef883fa32084dbSteve Blocknamespace {
432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
442fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockclass ARC4Stream {
452fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockpublic:
462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ARC4Stream();
472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    uint8_t i;
492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    uint8_t j;
502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    uint8_t s[256];
512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block};
522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
532fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockclass ARC4RandomNumberGenerator {
542fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockpublic:
552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ARC4RandomNumberGenerator();
562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    uint32_t randomNumber();
582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    void randomValues(void* buffer, size_t length);
592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
602fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockprivate:
612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    inline void addRandomData(unsigned char *data, int length);
622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    void stir();
632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    void stirIfNeeded();
642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    inline uint8_t getByte();
652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    inline uint32_t getWord();
662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ARC4Stream m_stream;
682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int m_count;
692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#if ENABLE(JSC_MULTIPLE_THREADS)
702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    Mutex m_mutex;
712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#endif
722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block};
732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
742fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockARC4Stream::ARC4Stream()
752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    for (int n = 0; n < 256; n++)
772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        s[n] = n;
782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    i = 0;
792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    j = 0;
802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
822fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockARC4RandomNumberGenerator::ARC4RandomNumberGenerator()
832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    : m_count(0)
842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
872fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid ARC4RandomNumberGenerator::addRandomData(unsigned char* data, int length)
882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_stream.i--;
902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    for (int n = 0; n < 256; n++) {
912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        m_stream.i++;
922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        uint8_t si = m_stream.s[m_stream.i];
932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        m_stream.j += si + data[n % length];
942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        m_stream.s[m_stream.i] = m_stream.s[m_stream.j];
952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        m_stream.s[m_stream.j] = si;
962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_stream.j = m_stream.i;
982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1002fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid ARC4RandomNumberGenerator::stir()
1012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
1022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    unsigned char randomness[128];
1032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    size_t length = sizeof(randomness);
1042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    cryptographicallyRandomValuesFromOS(randomness, length);
1052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    addRandomData(randomness, length);
1062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // Discard early keystream, as per recommendations in:
1082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps
1092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    for (int i = 0; i < 256; i++)
1102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        getByte();
1112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_count = 1600000;
1122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
1132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1142fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid ARC4RandomNumberGenerator::stirIfNeeded()
1152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
1162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (m_count <= 0)
1172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        stir();
1182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
1192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1202fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockuint8_t ARC4RandomNumberGenerator::getByte()
1212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
1222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_stream.i++;
1232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    uint8_t si = m_stream.s[m_stream.i];
1242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_stream.j += si;
1252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    uint8_t sj = m_stream.s[m_stream.j];
1262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_stream.s[m_stream.i] = sj;
1272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_stream.s[m_stream.j] = si;
1282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return (m_stream.s[(si + sj) & 0xff]);
1292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
1302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1312fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockuint32_t ARC4RandomNumberGenerator::getWord()
1322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
1332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    uint32_t val;
1342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    val = getByte() << 24;
1352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    val |= getByte() << 16;
1362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    val |= getByte() << 8;
1372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    val |= getByte();
1382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return val;
1392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
1402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1412fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockuint32_t ARC4RandomNumberGenerator::randomNumber()
1422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
1432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#if ENABLE(JSC_MULTIPLE_THREADS)
1442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    MutexLocker locker(m_mutex);
1452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#endif
1462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_count -= 4;
1482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    stirIfNeeded();
1492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return getWord();
1502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
1512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1522fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid ARC4RandomNumberGenerator::randomValues(void* buffer, size_t length)
1532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
1542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#if ENABLE(JSC_MULTIPLE_THREADS)
1552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    MutexLocker locker(m_mutex);
1562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#endif
1572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    unsigned char* result = reinterpret_cast<unsigned char*>(buffer);
1592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    stirIfNeeded();
1602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    while (length--) {
1612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        m_count--;
1622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        stirIfNeeded();
1632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        result[length] = getByte();
1642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
1652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
1662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1672fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockARC4RandomNumberGenerator& sharedRandomNumberGenerator()
1682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
1692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    DEFINE_STATIC_LOCAL(ARC4RandomNumberGenerator, randomNumberGenerator, ());
1702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return randomNumberGenerator;
1712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
1722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
1742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1752fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockuint32_t cryptographicallyRandomNumber()
1762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
1772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return sharedRandomNumberGenerator().randomNumber();
1782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
1792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1802fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid cryptographicallyRandomValues(void* buffer, size_t length)
1812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
1822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    sharedRandomNumberGenerator().randomValues(buffer, length);
1832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
1842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#endif
1862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
188