blob: 34e82c12ce56a950c0648979293d179733ae210f [file] [log] [blame]
Alex Deymoca0aaa62014-01-06 10:39:58 -08001// Copyright (c) 2014 The Chromium OS 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 <stdio.h>
6#include <unistd.h>
7
8#include <base/file_path.h>
9#include <base/file_util.h>
10
11#include "policy_manager/random_provider.h"
Alex Deymoca0aaa62014-01-06 10:39:58 -080012
13using std::string;
14
15namespace {
16
17// The device providing randomness.
18const char* kRandomDevice = "/dev/urandom";
19
20} // namespace
21
22namespace chromeos_policy_manager {
23
24// The random variable class implementation.
25class RandomVariable : public Variable<uint64> {
26 public:
27 RandomVariable(FILE* fp) : fp_(fp) {}
28 virtual ~RandomVariable() {}
29
30 protected:
31 virtual const uint64* GetValue(base::TimeDelta /* timeout */,
32 string* errmsg) {
33 uint8 buf[sizeof(uint64)];
34 unsigned int buf_rd = 0;
35
36 while (buf_rd < sizeof(uint64)) {
37 int rd = fread(buf + buf_rd, 1, sizeof(uint64) - buf_rd, fp_.get());
38 if (rd == 0 || ferror(fp_.get())) {
39 // Either EOF on fp or read failed.
40 if (errmsg)
41 *errmsg = string("Error reading from the random device: ")
42 + kRandomDevice;
43 return NULL;
44 }
45 buf_rd += rd;
46 }
47 // Convert the result to a uint64.
48 uint64 result = 0;
49 for (unsigned int i = 0; i < sizeof(uint64); ++i)
50 result = (result << 8) | buf[i];
51
52 return new uint64(result);
53 }
54
55 private:
56 DISALLOW_COPY_AND_ASSIGN(RandomVariable);
57
58 file_util::ScopedFILE fp_;
59};
60
61
62// RandomProvider implementation.
63
Gilad Arnoldb33e1982014-01-27 14:46:27 -080064bool RandomProvider::DoInit(void) {
Alex Deymoca0aaa62014-01-06 10:39:58 -080065 FILE* fp = fopen(kRandomDevice, "r");
66 if (!fp)
67 return false;
68 var_random_seed = new RandomVariable(fp);
69 return true;
70}
71
Alex Deymoca0aaa62014-01-06 10:39:58 -080072} // namespace chromeos_policy_manager