blob: 73caa04434492194f98eca5b6173b4bee96938e8 [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>
Gilad Arnold570ecb12014-01-29 10:52:29 -080010#include <base/stringprintf.h>
Alex Deymoca0aaa62014-01-06 10:39:58 -080011
12#include "policy_manager/random_provider.h"
Alex Deymoca0aaa62014-01-06 10:39:58 -080013
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.
Gilad Arnold570ecb12014-01-29 10:52:29 -080026class RandomVariable : public Variable<uint64_t> {
Alex Deymoca0aaa62014-01-06 10:39:58 -080027 public:
28 RandomVariable(FILE* fp) : fp_(fp) {}
29 virtual ~RandomVariable() {}
30
31 protected:
Gilad Arnold570ecb12014-01-29 10:52:29 -080032 virtual const uint64_t* GetValue(base::TimeDelta /* timeout */,
33 string* errmsg) {
34 uint64_t result;
35 // Aliasing via char pointer abides by the C/C++ strict-aliasing rules.
36 char* const buf = reinterpret_cast<char*>(&result);
Alex Deymoca0aaa62014-01-06 10:39:58 -080037 unsigned int buf_rd = 0;
38
Gilad Arnold570ecb12014-01-29 10:52:29 -080039 while (buf_rd < sizeof(result)) {
40 int rd = fread(buf + buf_rd, 1, sizeof(result) - buf_rd, fp_.get());
Alex Deymoca0aaa62014-01-06 10:39:58 -080041 if (rd == 0 || ferror(fp_.get())) {
42 // Either EOF on fp or read failed.
Gilad Arnold570ecb12014-01-29 10:52:29 -080043 if (errmsg) {
44 *errmsg = StringPrintf("Error reading from the random device: %s",
45 kRandomDevice);
46 }
Alex Deymoca0aaa62014-01-06 10:39:58 -080047 return NULL;
48 }
49 buf_rd += rd;
50 }
Alex Deymoca0aaa62014-01-06 10:39:58 -080051
Gilad Arnold570ecb12014-01-29 10:52:29 -080052 return new uint64_t(result);
Alex Deymoca0aaa62014-01-06 10:39:58 -080053 }
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