blob: 431e77b3e7c3e847d7a7098a82a57f87f930d68c [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"
Gilad Arnolda87340b2014-01-30 11:10:18 -080013#include "policy_manager/variable.h"
Alex Deymoca0aaa62014-01-06 10:39:58 -080014
15using std::string;
16
17namespace {
18
19// The device providing randomness.
20const char* kRandomDevice = "/dev/urandom";
21
22} // namespace
23
24namespace chromeos_policy_manager {
25
Gilad Arnold12db7012014-01-29 16:45:30 -080026// A random seed variable.
27class RandomSeedVariable : public Variable<uint64_t> {
Alex Deymoca0aaa62014-01-06 10:39:58 -080028 public:
Gilad Arnold12db7012014-01-29 16:45:30 -080029 RandomSeedVariable(const string& name, FILE* fp)
Alex Deymo391ad9f2014-01-29 14:36:20 -080030 : Variable<uint64_t>(name), fp_(fp) {}
Gilad Arnold12db7012014-01-29 16:45:30 -080031 virtual ~RandomSeedVariable() {}
Alex Deymoca0aaa62014-01-06 10:39:58 -080032
33 protected:
Gilad Arnold570ecb12014-01-29 10:52:29 -080034 virtual const uint64_t* GetValue(base::TimeDelta /* timeout */,
35 string* errmsg) {
36 uint64_t result;
37 // Aliasing via char pointer abides by the C/C++ strict-aliasing rules.
38 char* const buf = reinterpret_cast<char*>(&result);
Alex Deymoca0aaa62014-01-06 10:39:58 -080039 unsigned int buf_rd = 0;
40
Gilad Arnold570ecb12014-01-29 10:52:29 -080041 while (buf_rd < sizeof(result)) {
42 int rd = fread(buf + buf_rd, 1, sizeof(result) - buf_rd, fp_.get());
Alex Deymoca0aaa62014-01-06 10:39:58 -080043 if (rd == 0 || ferror(fp_.get())) {
44 // Either EOF on fp or read failed.
Gilad Arnold570ecb12014-01-29 10:52:29 -080045 if (errmsg) {
46 *errmsg = StringPrintf("Error reading from the random device: %s",
47 kRandomDevice);
48 }
Alex Deymoca0aaa62014-01-06 10:39:58 -080049 return NULL;
50 }
51 buf_rd += rd;
52 }
Alex Deymoca0aaa62014-01-06 10:39:58 -080053
Gilad Arnold570ecb12014-01-29 10:52:29 -080054 return new uint64_t(result);
Alex Deymoca0aaa62014-01-06 10:39:58 -080055 }
56
57 private:
Alex Deymoca0aaa62014-01-06 10:39:58 -080058 file_util::ScopedFILE fp_;
Gilad Arnolda87340b2014-01-30 11:10:18 -080059
60 DISALLOW_COPY_AND_ASSIGN(RandomSeedVariable);
Alex Deymoca0aaa62014-01-06 10:39:58 -080061};
62
63
64// RandomProvider implementation.
65
Gilad Arnoldb33e1982014-01-27 14:46:27 -080066bool RandomProvider::DoInit(void) {
Alex Deymoca0aaa62014-01-06 10:39:58 -080067 FILE* fp = fopen(kRandomDevice, "r");
68 if (!fp)
69 return false;
Gilad Arnold12db7012014-01-29 16:45:30 -080070 var_random_seed = new RandomSeedVariable("random_seed", fp);
Alex Deymoca0aaa62014-01-06 10:39:58 -080071 return true;
72}
73
Alex Deymoca0aaa62014-01-06 10:39:58 -080074} // namespace chromeos_policy_manager