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