blob: f2373b040ffbb252393c7050812d4b16b186477b [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
65bool RandomProvider::Init(void) {
66 // Check for double Init()
67 if (var_random_seed != NULL)
68 return false;
69
70 FILE* fp = fopen(kRandomDevice, "r");
71 if (!fp)
72 return false;
73 var_random_seed = new RandomVariable(fp);
74 return true;
75}
76
77void RandomProvider::Finalize(void) {
78 if (var_random_seed) {
79 delete var_random_seed;
80 var_random_seed = NULL;
81 }
82}
83
84} // namespace chromeos_policy_manager