Home | History | Annotate | Download | only in base
      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