Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Unified Diff: chromeos/cryptohome/cryptohome_library.cc

Issue 14179007: Move cryptohome_library to src/chromeos (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chromeos/cryptohome/cryptohome_library.cc
diff --git a/chrome/browser/chromeos/cros/cryptohome_library.cc b/chromeos/cryptohome/cryptohome_library.cc
similarity index 50%
rename from chrome/browser/chromeos/cros/cryptohome_library.cc
rename to chromeos/cryptohome/cryptohome_library.cc
index 20c92b3760dcbc128a2f7b7db40e9b418957b627..6aae891fa02ea2cc8bf5532f99a1eb338d393332 100644
--- a/chrome/browser/chromeos/cros/cryptohome_library.cc
+++ b/chromeos/cryptohome/cryptohome_library.cc
@@ -2,22 +2,28 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/chromeos/cros/cryptohome_library.h"
+#include "chromeos/cryptohome/cryptohome_library.h"
#include <map>
#include "base/bind.h"
+#include "base/chromeos/chromeos_version.h"
#include "base/memory/weak_ptr.h"
#include "base/string_util.h"
#include "base/strings/string_number_conversions.h"
#include "chromeos/dbus/cryptohome_client.h"
#include "chromeos/dbus/dbus_thread_manager.h"
+#include "crypto/encryptor.h"
+#include "crypto/nss_util.h"
+#include "crypto/sha2.h"
+#include "crypto/symmetric_key.h"
namespace chromeos {
namespace {
const char kStubSystemSalt[] = "stub_system_salt";
+const size_t kKeySize = 16;
// Does nothing. Used as a Cryptohome::VoidMethodCallback.
void DoNothing(DBusMethodCallStatus call_status) {}
@@ -116,6 +122,35 @@ class CryptohomeLibraryImpl : public CryptohomeLibrary {
system_salt_.size()));
}
+ virtual std::string EncryptWithSystemSalt(const std::string& token) OVERRIDE {
+ // Don't care about token encryption while debugging.
+ if (!base::chromeos::IsRunningOnChromeOS())
+ return token;
+
+ if (!LoadSystemSaltKey()) {
+ LOG(WARNING) << "System salt key is not available for encrypt.";
+ return std::string();
+ }
+ return EncryptTokenWithKey(system_salt_key_.get(),
+ GetSystemSalt(),
+ token);
+ }
+
+ virtual std::string DecryptWithSystemSalt(
+ const std::string& encrypted_token_hex) OVERRIDE {
+ // Don't care about token encryption while debugging.
+ if (!base::chromeos::IsRunningOnChromeOS())
+ return encrypted_token_hex;
+
+ if (!LoadSystemSaltKey()) {
+ LOG(WARNING) << "System salt key is not available for decrypt.";
+ return std::string();
+ }
+ return DecryptTokenWithKey(system_salt_key_.get(),
+ GetSystemSalt(),
+ encrypted_token_hex);
+ }
+
private:
void LoadSystemSalt() {
if (!system_salt_.empty())
@@ -126,8 +161,77 @@ class CryptohomeLibraryImpl : public CryptohomeLibrary {
CHECK_EQ(system_salt_.size() % 2, 0U);
}
+ // TODO: should this use the system salt for both the password and the salt
+ // value, or should this use a separate salt value?
+ bool LoadSystemSaltKey() {
+ if (!system_salt_key_.get())
+ system_salt_key_.reset(PassphraseToKey(GetSystemSalt(), GetSystemSalt()));
+ return system_salt_key_.get();
+ }
+
+ crypto::SymmetricKey* PassphraseToKey(const std::string& passprhase,
+ const std::string& salt) {
+ return crypto::SymmetricKey::DeriveKeyFromPassword(
+ crypto::SymmetricKey::AES, passprhase, salt, 1000, 256);
+ }
+
+
+ // Encrypts (AES) the token given |key| and |salt|.
+ std::string EncryptTokenWithKey(crypto::SymmetricKey* key,
+ const std::string& salt,
+ const std::string& token) {
+ crypto::Encryptor encryptor;
+ if (!encryptor.Init(key, crypto::Encryptor::CTR, std::string())) {
+ LOG(WARNING) << "Failed to initialize Encryptor.";
+ return std::string();
+ }
+ std::string nonce = salt.substr(0, kKeySize);
+ std::string encoded_token;
+ CHECK(encryptor.SetCounter(nonce));
+ if (!encryptor.Encrypt(token, &encoded_token)) {
+ LOG(WARNING) << "Failed to encrypt token.";
+ return std::string();
+ }
+
+ return StringToLowerASCII(base::HexEncode(
+ reinterpret_cast<const void*>(encoded_token.data()),
+ encoded_token.size()));
+ }
+
+ // Decrypts (AES) hex encoded encrypted token given |key| and |salt|.
+ std::string DecryptTokenWithKey(crypto::SymmetricKey* key,
+ const std::string& salt,
+ const std::string& encrypted_token_hex) {
+ std::vector<uint8> encrypted_token_bytes;
+ if (!base::HexStringToBytes(encrypted_token_hex, &encrypted_token_bytes)) {
+ LOG(WARNING) << "Corrupt encrypted token found.";
+ return std::string();
+ }
+
+ std::string encrypted_token(
+ reinterpret_cast<char*>(encrypted_token_bytes.data()),
+ encrypted_token_bytes.size());
+ crypto::Encryptor encryptor;
+ if (!encryptor.Init(key, crypto::Encryptor::CTR, std::string())) {
+ LOG(WARNING) << "Failed to initialize Encryptor.";
+ return std::string();
+ }
+
+ std::string nonce = salt.substr(0, kKeySize);
+ std::string token;
+ CHECK(encryptor.SetCounter(nonce));
+ if (!encryptor.Decrypt(encrypted_token, &token)) {
+ LOG(WARNING) << "Failed to decrypt token.";
+ return std::string();
+ }
+ return token;
+ }
+
base::WeakPtrFactory<CryptohomeLibraryImpl> weak_ptr_factory_;
std::vector<uint8> system_salt_;
+ // A key based on the system salt. Useful for encrypting device-level
+ // data for which we have no additional credentials.
+ scoped_ptr<crypto::SymmetricKey> system_salt_key_;
DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryImpl);
};
@@ -186,6 +290,15 @@ class CryptohomeLibraryStubImpl : public CryptohomeLibrary {
return kStubSystemSalt;
}
+ virtual std::string EncryptWithSystemSalt(const std::string& token) {
+ return token;
+ }
+
+ virtual std::string DecryptWithSystemSalt(
+ const std::string& encrypted_token_hex) {
+ return encrypted_token_hex;
+ }
+
private:
std::map<std::string, std::string> install_attrs_;
bool locked_;
@@ -195,14 +308,48 @@ class CryptohomeLibraryStubImpl : public CryptohomeLibrary {
CryptohomeLibrary::CryptohomeLibrary() {}
CryptohomeLibrary::~CryptohomeLibrary() {}
+static CryptohomeLibrary* g_cryptohome_library = NULL;
+static CryptohomeLibrary* g_test_cryptohome_library = NULL;
+
// static
-CryptohomeLibrary* CryptohomeLibrary::GetImpl(bool stub) {
- CryptohomeLibrary* impl;
- if (stub)
- impl = new CryptohomeLibraryStubImpl();
+void CryptohomeLibrary::Initialize() {
+ CHECK(!g_cryptohome_library);
+ if (base::chromeos::IsRunningOnChromeOS())
+ g_cryptohome_library = new CryptohomeLibraryStubImpl();
else
- impl = new CryptohomeLibraryImpl();
- return impl;
+ g_cryptohome_library = new CryptohomeLibraryImpl();
+}
+
+// static
+bool CryptohomeLibrary::IsInitialized() {
+ return g_cryptohome_library;
+}
+
+// static
+void CryptohomeLibrary::Shutdown() {
+ CHECK(g_cryptohome_library);
+ delete g_cryptohome_library;
+ g_cryptohome_library = NULL;
+}
+
+// static
+CryptohomeLibrary* CryptohomeLibrary::Get() {
+ CHECK(g_cryptohome_library || g_test_cryptohome_library)
+ << "CryptohomeLibrary::Get() called before Initialize()";
+ if (g_test_cryptohome_library)
+ return g_test_cryptohome_library;
+ return g_cryptohome_library;
+}
+
+// static
+void CryptohomeLibrary::SetForTest(CryptohomeLibrary* impl) {
+ CHECK(!g_test_cryptohome_library || !impl);
+ g_test_cryptohome_library = impl;
+}
+
+// static
+CryptohomeLibrary* CryptohomeLibrary::GetTestImpl() {
+ return new CryptohomeLibraryStubImpl();
}
} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698