1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/rand_util.h" 6 7 #include <errno.h> 8 #include <fcntl.h> 9 #include <stddef.h> 10 #include <stdint.h> 11 #include <unistd.h> 12 13 #include "base/logging.h" 14 #include "base/posix/eintr_wrapper.h" 15 16 namespace { 17 18 class URandomFd { 19 public: 20 URandomFd() : fd_(open("/dev/urandom", O_RDONLY)) { 21 DCHECK_GE(fd_, 0) << "Cannot open /dev/urandom: " << errno; 22 } 23 24 ~URandomFd() { close(fd_); } 25 26 int fd() const { return fd_; } 27 28 private: 29 const int fd_; 30 }; 31 32 bool ReadFromFD(int fd, char* buffer, size_t bytes) { 33 size_t total_read = 0; 34 while (total_read < bytes) { 35 ssize_t bytes_read = 36 HANDLE_EINTR(read(fd, buffer + total_read, bytes - total_read)); 37 if (bytes_read <= 0) 38 break; 39 total_read += bytes_read; 40 } 41 return total_read == bytes; 42 } 43 44 } // namespace 45 46 namespace base { 47 48 // NOTE: This function must be cryptographically secure. http://crbug.com/140076 49 uint64_t RandUint64() { 50 uint64_t number; 51 RandBytes(&number, sizeof(number)); 52 return number; 53 } 54 55 void RandBytes(void* output, size_t output_length) { 56 URandomFd urandom_fd; 57 const bool success = 58 ReadFromFD(urandom_fd.fd(), static_cast<char*>(output), output_length); 59 CHECK(success); 60 } 61 62 } // namespace base 63