blob: 4c8ae8550da8f197341414e20a7d5aaa78c94791 [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
Alex Vakulenko75039d72014-03-25 12:36:28 -07008#include <base/files/file_path.h>
Alex Deymoca0aaa62014-01-06 10:39:58 -08009#include <base/file_util.h>
Alex Vakulenko75039d72014-03-25 12:36:28 -070010#include <base/strings/stringprintf.h>
Alex Deymoca0aaa62014-01-06 10:39:58 -080011
Alex Deymo6e97bb22014-02-05 16:46:16 -080012#include "update_engine/policy_manager/real_random_provider.h"
13#include "update_engine/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:
Alex Deymo0e433692014-02-20 07:23:03 -080029 // RandomSeedVariable is initialized as kVariableModeConst to let the
30 // EvaluationContext cache the value between different evaluations of the same
31 // policy request.
Gilad Arnold12db7012014-01-29 16:45:30 -080032 RandomSeedVariable(const string& name, FILE* fp)
Alex Deymo0e433692014-02-20 07:23:03 -080033 : Variable<uint64_t>(name, kVariableModeConst), fp_(fp) {}
Gilad Arnold12db7012014-01-29 16:45:30 -080034 virtual ~RandomSeedVariable() {}
Alex Deymoca0aaa62014-01-06 10:39:58 -080035
36 protected:
Gilad Arnold570ecb12014-01-29 10:52:29 -080037 virtual const uint64_t* GetValue(base::TimeDelta /* timeout */,
38 string* errmsg) {
39 uint64_t result;
40 // Aliasing via char pointer abides by the C/C++ strict-aliasing rules.
41 char* const buf = reinterpret_cast<char*>(&result);
Alex Deymoca0aaa62014-01-06 10:39:58 -080042 unsigned int buf_rd = 0;
43
Gilad Arnold570ecb12014-01-29 10:52:29 -080044 while (buf_rd < sizeof(result)) {
45 int rd = fread(buf + buf_rd, 1, sizeof(result) - buf_rd, fp_.get());
Alex Deymoca0aaa62014-01-06 10:39:58 -080046 if (rd == 0 || ferror(fp_.get())) {
47 // Either EOF on fp or read failed.
Gilad Arnold570ecb12014-01-29 10:52:29 -080048 if (errmsg) {
Alex Vakulenko75039d72014-03-25 12:36:28 -070049 *errmsg = base::StringPrintf(
50 "Error reading from the random device: %s", kRandomDevice);
Gilad Arnold570ecb12014-01-29 10:52:29 -080051 }
Alex Deymoca0aaa62014-01-06 10:39:58 -080052 return NULL;
53 }
54 buf_rd += rd;
55 }
Alex Deymoca0aaa62014-01-06 10:39:58 -080056
Gilad Arnold570ecb12014-01-29 10:52:29 -080057 return new uint64_t(result);
Alex Deymoca0aaa62014-01-06 10:39:58 -080058 }
59
60 private:
Alex Deymoca0aaa62014-01-06 10:39:58 -080061 file_util::ScopedFILE fp_;
Gilad Arnolda87340b2014-01-30 11:10:18 -080062
63 DISALLOW_COPY_AND_ASSIGN(RandomSeedVariable);
Alex Deymoca0aaa62014-01-06 10:39:58 -080064};
65
Alex Deymobb019fe2014-02-03 20:12:17 -080066bool RealRandomProvider::DoInit(void) {
Alex Deymoca0aaa62014-01-06 10:39:58 -080067 FILE* fp = fopen(kRandomDevice, "r");
68 if (!fp)
69 return false;
Alex Deymo540d9422014-02-27 11:17:31 -080070 set_var_seed(new RandomSeedVariable("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