1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Copyright (c) 2008 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/rand_util.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/rand_util_c.h" 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <errno.h> 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <fcntl.h> 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <unistd.h> 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_util.h" 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/lazy_instance.h" 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace { 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// We keep the file descriptor for /dev/urandom around so we don't need to 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// reopen it (which is expensive), and since we may not even be able to reopen 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// it if we are later put in a sandbox. This class wraps the file descriptor so 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// we can use LazyInstance to handle opening it on the first access. 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass URandomFd { 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott URandomFd() { 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fd_ = open("/dev/urandom", O_RDONLY); 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHECK_GE(fd_, 0) << "Cannot open /dev/urandom: " << errno; 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~URandomFd() { 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott close(fd_); 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int fd() const { return fd_; } 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int fd_; 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbase::LazyInstance<URandomFd> g_urandom_fd(base::LINKER_INITIALIZED); 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace base { 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottuint64 RandUint64() { 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott uint64 number; 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int urandom_fd = g_urandom_fd.Pointer()->fd(); 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool success = file_util::ReadFromFD(urandom_fd, 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott reinterpret_cast<char*>(&number), 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sizeof(number)); 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CHECK(success); 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return number; 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace base 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint GetUrandomFD(void) { 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return g_urandom_fd.Pointer()->fd(); 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 62