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:
URandomFd()20   URandomFd() : fd_(open("/dev/urandom", O_RDONLY)) {
21     DCHECK_GE(fd_, 0) << "Cannot open /dev/urandom: " << errno;
22   }
23 
~URandomFd()24   ~URandomFd() { close(fd_); }
25 
fd() const26   int fd() const { return fd_; }
27 
28  private:
29   const int fd_;
30 };
31 
ReadFromFD(int fd,char * buffer,size_t bytes)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
RandUint64()49 uint64_t RandUint64() {
50   uint64_t number;
51   RandBytes(&number, sizeof(number));
52   return number;
53 }
54 
RandBytes(void * output,size_t output_length)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