diff options
-rw-r--r-- | base/rand_util.h | 15 | ||||
-rw-r--r-- | base/rand_util_posix.cc | 1 | ||||
-rw-r--r-- | base/rand_util_win.cc | 3 | ||||
-rw-r--r-- | crypto/crypto.gyp | 3 | ||||
-rw-r--r-- | crypto/openpgp_symmetric_encryption.cc | 9 | ||||
-rw-r--r-- | crypto/p224_spake.cc | 6 | ||||
-rw-r--r-- | crypto/random.cc | 19 | ||||
-rw-r--r-- | crypto/random.h | 21 | ||||
-rw-r--r-- | crypto/random_unittest.cc | 27 | ||||
-rw-r--r-- | sync/util/nigori.cc | 14 |
10 files changed, 95 insertions, 23 deletions
diff --git a/base/rand_util.h b/base/rand_util.h index c5c4ef8..4f4765b 100644 --- a/base/rand_util.h +++ b/base/rand_util.h @@ -32,14 +32,21 @@ BASE_EXPORT double RandDouble(); // the range [0, 1). Thread-safe. BASE_EXPORT double BitsToOpenEndedUnitInterval(uint64 bits); -// Fills |output_length| bytes of |output| with cryptographically strong random -// data. +// Fills |output_length| bytes of |output| with random data. +// +// WARNING: +// Do not use for security-sensitive purposes. +// See crypto/ for cryptographically secure random number generation APIs. BASE_EXPORT void RandBytes(void* output, size_t output_length); -// Fills a string of length |length| with with cryptographically strong random -// data and returns it. |length| should be nonzero. +// Fills a string of length |length| with with random data and returns it. +// |length| should be nonzero. // // Note that this is a variation of |RandBytes| with a different return type. +// +// WARNING: +// Do not use for security-sensitive purposes. +// See crypto/ for cryptographically secure random number generation APIs. BASE_EXPORT std::string RandBytesAsString(size_t length); #ifdef OS_POSIX diff --git a/base/rand_util_posix.cc b/base/rand_util_posix.cc index abb404a..d65ddae 100644 --- a/base/rand_util_posix.cc +++ b/base/rand_util_posix.cc @@ -41,6 +41,7 @@ base::LazyInstance<URandomFd> g_urandom_fd = LAZY_INSTANCE_INITIALIZER; namespace base { +// NOTE: This function must be cryptographically secure. http://crbug.com/140076 uint64 RandUint64() { uint64 number; diff --git a/base/rand_util_win.cc b/base/rand_util_win.cc index ec0411e..391fe5b 100644 --- a/base/rand_util_win.cc +++ b/base/rand_util_win.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -21,6 +21,7 @@ uint32 RandUint32() { namespace base { +// NOTE: This function must be cryptographically secure. http://crbug.com/140076 uint64 RandUint64() { uint32 first_half = RandUint32(); uint32 second_half = RandUint32(); diff --git a/crypto/crypto.gyp b/crypto/crypto.gyp index 287b53c..e124423 100644 --- a/crypto/crypto.gyp +++ b/crypto/crypto.gyp @@ -197,6 +197,8 @@ 'openssl_util.h', 'p224.cc', 'p224.h', + 'random.h', + 'random.cc', 'rsa_private_key.cc', 'rsa_private_key.h', 'rsa_private_key_mac.cc', @@ -242,6 +244,7 @@ 'nss_util_unittest.cc', 'p224_unittest.cc', 'p224_spake_unittest.cc', + 'random_unittest.cc', 'rsa_private_key_unittest.cc', 'rsa_private_key_nss_unittest.cc', 'secure_hash_unittest.cc', diff --git a/crypto/openpgp_symmetric_encryption.cc b/crypto/openpgp_symmetric_encryption.cc index 3f37d4c..7eb6737 100644 --- a/crypto/openpgp_symmetric_encryption.cc +++ b/crypto/openpgp_symmetric_encryption.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -12,7 +12,7 @@ #include <vector> #include "base/logging.h" -#include "base/rand_util.h" +#include "crypto/random.h" #include "crypto/scoped_nss_types.h" #include "crypto/nss_util.h" @@ -680,7 +680,8 @@ class Encrypter { ske.push_back(3); // iterated and salted S2K ske.push_back(2); // SHA-1 - uint64 salt64 = base::RandUint64(); + uint64 salt64; + crypto::RandBytes(&salt64, sizeof(salt64)); ByteString salt(sizeof(salt64), 0); // It's a random value, so endianness doesn't matter. @@ -710,7 +711,7 @@ class Encrypter { static const unsigned kBlockSize = 16; // AES block size uint8 prefix[kBlockSize + 2], fre[kBlockSize], iv[kBlockSize]; - base::RandBytes(iv, kBlockSize); + crypto::RandBytes(iv, kBlockSize); memset(fre, 0, sizeof(fre)); ScopedPK11Context aes_context; diff --git a/crypto/p224_spake.cc b/crypto/p224_spake.cc index af3c2b8..31109a4 100644 --- a/crypto/p224_spake.cc +++ b/crypto/p224_spake.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,8 +8,8 @@ #include <crypto/p224_spake.h> #include <base/logging.h> -#include <base/rand_util.h> #include <crypto/p224.h> +#include <crypto/random.h> #include <crypto/secure_util.h> namespace { @@ -103,7 +103,7 @@ P224EncryptedKeyExchange::P224EncryptedKeyExchange( memset(&expected_authenticator_, 0, sizeof(expected_authenticator_)); // x_ is a random scalar. - base::RandBytes(x_, sizeof(x_)); + RandBytes(x_, sizeof(x_)); // X = g**x_ p224::Point X; diff --git a/crypto/random.cc b/crypto/random.cc new file mode 100644 index 0000000..a19bb1a --- /dev/null +++ b/crypto/random.cc @@ -0,0 +1,19 @@ +// Copyright (c) 2012 The Chromium 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 "crypto/random.h" + +#include "base/rand_util.h" + +namespace crypto { + +void RandBytes(void *bytes, size_t length) { + // It's OK to call base::RandBytes(), because it's already strongly random. + // But _other_ code should go through this function to ensure that code which + // needs secure randomness is easily discoverable. + base::RandBytes(bytes, length); +} + +} // namespace crypto + diff --git a/crypto/random.h b/crypto/random.h new file mode 100644 index 0000000..cdbe8a9 --- /dev/null +++ b/crypto/random.h @@ -0,0 +1,21 @@ +// Copyright (c) 2012 The Chromium 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 CRYPTO_RANDOM_H_ +#define CRYPTO_RANDOM_H_ + +#include <stdlib.h> + +#include "crypto/crypto_export.h" + +namespace crypto { + +// Fills the given buffer with |length| random bytes of cryptographically +// secure random numbers. +// |length| must be positive. +CRYPTO_EXPORT void RandBytes(void *bytes, size_t length); + +} + +#endif diff --git a/crypto/random_unittest.cc b/crypto/random_unittest.cc new file mode 100644 index 0000000..297f3cc --- /dev/null +++ b/crypto/random_unittest.cc @@ -0,0 +1,27 @@ +// Copyright (c) 2012 The Chromium 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 "crypto/random.h" + +#include "base/string_util.h" +#include "testing/gtest/include/gtest/gtest.h" + +// Basic functionality tests. Does NOT test the security of the random data. + +// Ensures we don't have all trivial data, i.e. that the data is indeed random. +// Currently, that means the bytes cannot be all the same (e.g. all zeros). +bool IsTrivial(const std::string& bytes) { + for (size_t i = 0; i < bytes.size(); i++) { + if (bytes[i] != bytes[0]) { + return false; + } + } + return true; +} + +TEST(RandBytes, RandBytes) { + std::string bytes(16, '\0'); + crypto::RandBytes(WriteInto(&bytes, bytes.size()), bytes.size()); + EXPECT_TRUE(!IsTrivial(bytes)); +} diff --git a/sync/util/nigori.cc b/sync/util/nigori.cc index f2ee83d..60fc895 100644 --- a/sync/util/nigori.cc +++ b/sync/util/nigori.cc @@ -9,16 +9,15 @@ #include "base/base64.h" #include "base/logging.h" -#include "base/rand_util.h" #include "base/string_util.h" #include "base/sys_byteorder.h" #include "crypto/encryptor.h" #include "crypto/hmac.h" +#include "crypto/random.h" #include "crypto/symmetric_key.h" using base::Base64Encode; using base::Base64Decode; -using base::RandInt; using crypto::Encryptor; using crypto::HMAC; using crypto::SymmetricKey; @@ -154,20 +153,13 @@ bool Nigori::Permute(Type type, const std::string& name, return Base64Encode(output, permuted); } -std::string GenerateRandomString(size_t size) { - // TODO(albertb): Use a secure random function. - std::string random(size, 0); - for (size_t i = 0; i < size; ++i) - random[i] = RandInt(0, 0xff); - return random; -} - // Enc[Kenc,Kmac](value) bool Nigori::Encrypt(const std::string& value, std::string* encrypted) const { if (0U >= value.size()) return false; - std::string iv = GenerateRandomString(kIvSize); + std::string iv; + crypto::RandBytes(WriteInto(&iv, kIvSize + 1), kIvSize); Encryptor encryptor; if (!encryptor.Init(encryption_key_.get(), Encryptor::CBC, iv)) |