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