blob: 225b89676a042c9b8528bd74abffec5f9d5dd993 [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
Gilad Arnold12db7012014-01-29 16:45:30 -080025// A random seed variable.
26class RandomSeedVariable : public Variable<uint64_t> {
Alex Deymoca0aaa62014-01-06 10:39:58 -080027 public:
Gilad Arnold12db7012014-01-29 16:45:30 -080028 RandomSeedVariable(const string& name, FILE* fp)
Alex Deymo391ad9f2014-01-29 14:36:20 -080029 : Variable<uint64_t>(name), fp_(fp) {}
Gilad Arnold12db7012014-01-29 16:45:30 -080030 virtual ~RandomSeedVariable() {}
Alex Deymoca0aaa62014-01-06 10:39:58 -080031
32 protected:
Gilad Arnold570ecb12014-01-29 10:52:29 -080033 virtual const uint64_t* GetValue(base::TimeDelta /* timeout */,
34 string* errmsg) {
35 uint64_t result;
36 // Aliasing via char pointer abides by the C/C++ strict-aliasing rules.
37 char* const buf = reinterpret_cast<char*>(&result);
Alex Deymoca0aaa62014-01-06 10:39:58 -080038 unsigned int buf_rd = 0;
39
Gilad Arnold570ecb12014-01-29 10:52:29 -080040 while (buf_rd < sizeof(result)) {
41 int rd = fread(buf + buf_rd, 1, sizeof(result) - buf_rd, fp_.get());
Alex Deymoca0aaa62014-01-06 10:39:58 -080042 if (rd == 0 || ferror(fp_.get())) {
43 // Either EOF on fp or read failed.
Gilad Arnold570ecb12014-01-29 10:52:29 -080044 if (errmsg) {
45 *errmsg = StringPrintf("Error reading from the random device: %s",
46 kRandomDevice);
47 }
Alex Deymoca0aaa62014-01-06 10:39:58 -080048 return NULL;
49 }
50 buf_rd += rd;
51 }
Alex Deymoca0aaa62014-01-06 10:39:58 -080052
Gilad Arnold570ecb12014-01-29 10:52:29 -080053 return new uint64_t(result);
Alex Deymoca0aaa62014-01-06 10:39:58 -080054 }
55
56 private:
Gilad Arnold12db7012014-01-29 16:45:30 -080057 DISALLOW_COPY_AND_ASSIGN(RandomSeedVariable);
Alex Deymoca0aaa62014-01-06 10:39:58 -080058
59 file_util::ScopedFILE fp_;
60};
61
62
63// RandomProvider implementation.
64
Gilad Arnoldb33e1982014-01-27 14:46:27 -080065bool RandomProvider::DoInit(void) {
Alex Deymoca0aaa62014-01-06 10:39:58 -080066 FILE* fp = fopen(kRandomDevice, "r");
67 if (!fp)
68 return false;
Gilad Arnold12db7012014-01-29 16:45:30 -080069 var_random_seed = new RandomSeedVariable("random_seed", fp);
Alex Deymoca0aaa62014-01-06 10:39:58 -080070 return true;
71}
72
Alex Deymoca0aaa62014-01-06 10:39:58 -080073} // namespace chromeos_policy_manager