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