blob: ea10de60753924341b99de161143907429aed99b [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 Vakulenko072359c2014-07-18 11:41:07 -07008#include <string>
9
Alex Vakulenko75039d72014-03-25 12:36:28 -070010#include <base/files/file_path.h>
Ben Chan736fcb52014-05-21 18:28:22 -070011#include <base/files/scoped_file.h>
Alex Vakulenko75039d72014-03-25 12:36:28 -070012#include <base/strings/stringprintf.h>
Alex Deymoca0aaa62014-01-06 10:39:58 -080013
Alex Deymo63784a52014-05-28 10:46:14 -070014#include "update_engine/update_manager/real_random_provider.h"
15#include "update_engine/update_manager/variable.h"
Alex Deymoca0aaa62014-01-06 10:39:58 -080016
17using std::string;
18
19namespace {
20
21// The device providing randomness.
22const char* kRandomDevice = "/dev/urandom";
23
24} // namespace
25
Alex Deymo63784a52014-05-28 10:46:14 -070026namespace chromeos_update_manager {
Alex Deymoca0aaa62014-01-06 10:39:58 -080027
Gilad Arnold12db7012014-01-29 16:45:30 -080028// A random seed variable.
29class RandomSeedVariable : public Variable<uint64_t> {
Alex Deymoca0aaa62014-01-06 10:39:58 -080030 public:
Alex Deymo0e433692014-02-20 07:23:03 -080031 // RandomSeedVariable is initialized as kVariableModeConst to let the
32 // EvaluationContext cache the value between different evaluations of the same
33 // policy request.
Gilad Arnold12db7012014-01-29 16:45:30 -080034 RandomSeedVariable(const string& name, FILE* fp)
Alex Deymo0e433692014-02-20 07:23:03 -080035 : Variable<uint64_t>(name, kVariableModeConst), fp_(fp) {}
Gilad Arnold12db7012014-01-29 16:45:30 -080036 virtual ~RandomSeedVariable() {}
Alex Deymoca0aaa62014-01-06 10:39:58 -080037
38 protected:
Gilad Arnold570ecb12014-01-29 10:52:29 -080039 virtual const uint64_t* GetValue(base::TimeDelta /* timeout */,
40 string* errmsg) {
41 uint64_t result;
42 // Aliasing via char pointer abides by the C/C++ strict-aliasing rules.
43 char* const buf = reinterpret_cast<char*>(&result);
Alex Deymoca0aaa62014-01-06 10:39:58 -080044 unsigned int buf_rd = 0;
45
Gilad Arnold570ecb12014-01-29 10:52:29 -080046 while (buf_rd < sizeof(result)) {
47 int rd = fread(buf + buf_rd, 1, sizeof(result) - buf_rd, fp_.get());
Alex Deymoca0aaa62014-01-06 10:39:58 -080048 if (rd == 0 || ferror(fp_.get())) {
49 // Either EOF on fp or read failed.
Gilad Arnold570ecb12014-01-29 10:52:29 -080050 if (errmsg) {
Alex Vakulenko75039d72014-03-25 12:36:28 -070051 *errmsg = base::StringPrintf(
52 "Error reading from the random device: %s", kRandomDevice);
Gilad Arnold570ecb12014-01-29 10:52:29 -080053 }
Alex Vakulenko88b591f2014-08-28 16:48:57 -070054 return nullptr;
Alex Deymoca0aaa62014-01-06 10:39:58 -080055 }
56 buf_rd += rd;
57 }
Alex Deymoca0aaa62014-01-06 10:39:58 -080058
Gilad Arnold570ecb12014-01-29 10:52:29 -080059 return new uint64_t(result);
Alex Deymoca0aaa62014-01-06 10:39:58 -080060 }
61
62 private:
Ben Chan736fcb52014-05-21 18:28:22 -070063 base::ScopedFILE fp_;
Gilad Arnolda87340b2014-01-30 11:10:18 -080064
65 DISALLOW_COPY_AND_ASSIGN(RandomSeedVariable);
Alex Deymoca0aaa62014-01-06 10:39:58 -080066};
67
Alex Deymo42c30c32014-04-24 18:41:18 -070068bool RealRandomProvider::Init(void) {
Alex Deymoca0aaa62014-01-06 10:39:58 -080069 FILE* fp = fopen(kRandomDevice, "r");
70 if (!fp)
71 return false;
David Zeuthen21716e22014-04-23 15:42:05 -070072 var_seed_.reset(new RandomSeedVariable("seed", fp));
Alex Deymoca0aaa62014-01-06 10:39:58 -080073 return true;
74}
75
Alex Deymo63784a52014-05-28 10:46:14 -070076} // namespace chromeos_update_manager