PolicyManager: New PRNG to use together with the RandomProvider's seed.

The RandomProvider gives you a single random value that you can use
to generate more unsecure random numbers on policies in a
deterministic way.

BUG=chromium:358269
TEST=Unittest added.

Change-Id: Ie344014c55cc56e7dbdf3ce679eb3ca37be52678
Reviewed-on: https://chromium-review.googlesource.com/197441
Reviewed-by: Alex Deymo <deymo@chromium.org>
Tested-by: Alex Deymo <deymo@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
diff --git a/policy_manager/prng.h b/policy_manager/prng.h
new file mode 100644
index 0000000..2922e9f
--- /dev/null
+++ b/policy_manager/prng.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_PRNG_H_
+#define CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_PRNG_H_
+
+#include <cstdlib>
+
+#include <base/basictypes.h>
+
+namespace chromeos_policy_manager {
+
+// An unsecure Pseudo-Random Number Generator class based on rand_r(3), which
+// is thread safe and doesn't interfere with other calls to rand().
+class PRNG {
+ public:
+  // Creates the object using the passed |seed| value as the initial state.
+  explicit PRNG(unsigned int seed) : state_(seed) {}
+
+  // Returns a pseudo-random integer in the range [0, RAND_MAX].
+  int rand() { return rand_r(&state_); }
+
+ private:
+  // The internal state of the PRNG.
+  unsigned int state_;
+
+  DISALLOW_COPY_AND_ASSIGN(PRNG);
+};
+
+}  // namespace chromeos_policy_manager
+
+#endif  // CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_PRNG_H_
diff --git a/policy_manager/prng_unittest.cc b/policy_manager/prng_unittest.cc
new file mode 100644
index 0000000..4bdf836
--- /dev/null
+++ b/policy_manager/prng_unittest.cc
@@ -0,0 +1,52 @@
+// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "update_engine/policy_manager/prng.h"
+
+#include <vector>
+
+#include <gtest/gtest.h>
+
+using std::vector;
+
+namespace chromeos_policy_manager {
+
+TEST(PmPRNGTest, ShouldBeDeterministic) {
+  PRNG a(42);
+  PRNG b(42);
+
+  for (int i = 0; i < 1000; ++i) {
+    EXPECT_EQ(a.rand(), b.rand()) << "Iteration i=" << i;
+  }
+}
+
+TEST(PmPRNGTest, SeedChangesGeneratedSequence) {
+  PRNG a(42);
+  PRNG b(5);
+
+  vector<int> values_a;
+  vector<int> values_b;
+
+  for (int i = 0; i < 100; ++i) {
+    values_a.push_back(a.rand());
+    values_b.push_back(b.rand());
+  }
+  EXPECT_NE(values_a, values_b);
+}
+
+TEST(PmPRNGTest, IsNotConstant) {
+  PRNG prng(5);
+
+  int initial_value = prng.rand();
+  bool prng_is_constant = true;
+  for (int i = 0; i < 100; ++i) {
+    if (prng.rand() != initial_value) {
+      prng_is_constant = false;
+      break;
+    }
+  }
+  EXPECT_FALSE(prng_is_constant) << "After 100 iterations.";
+}
+
+}  // namespace chromeos_policy_manager