| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chromeos/cryptohome/cryptohome_library.h" | 5 #include "chromeos/cryptohome/cryptohome_library.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/chromeos/chromeos_version.h" | 10 #include "base/chromeos/chromeos_version.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 const size_t kNonceSize = 16; | 26 const size_t kNonceSize = 16; |
| 27 | 27 |
| 28 // Does nothing. Used as a Cryptohome::VoidMethodCallback. | 28 // Does nothing. Used as a Cryptohome::VoidMethodCallback. |
| 29 void DoNothing(DBusMethodCallStatus call_status) {} | 29 void DoNothing(DBusMethodCallStatus call_status) {} |
| 30 | 30 |
| 31 } // namespace | 31 } // namespace |
| 32 | 32 |
| 33 // This class handles the interaction with the ChromeOS cryptohome library APIs. | 33 // This class handles the interaction with the ChromeOS cryptohome library APIs. |
| 34 class CryptohomeLibraryImpl : public CryptohomeLibrary { | 34 class CryptohomeLibraryImpl : public CryptohomeLibrary { |
| 35 public: | 35 public: |
| 36 CryptohomeLibraryImpl() : weak_ptr_factory_(this) { | 36 CryptohomeLibraryImpl() { |
| 37 } | 37 } |
| 38 | 38 |
| 39 virtual ~CryptohomeLibraryImpl() { | 39 virtual ~CryptohomeLibraryImpl() { |
| 40 } | 40 } |
| 41 | 41 |
| 42 virtual bool TpmIsEnabled() OVERRIDE { | 42 virtual bool TpmIsEnabled() OVERRIDE { |
| 43 bool result = false; | 43 bool result = false; |
| 44 DBusThreadManager::Get()->GetCryptohomeClient()->CallTpmIsEnabledAndBlock( | 44 DBusThreadManager::Get()->GetCryptohomeClient()->CallTpmIsEnabledAndBlock( |
| 45 &result); | 45 &result); |
| 46 return result; | 46 return result; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 | 110 |
| 111 virtual bool InstallAttributesIsFirstInstall() OVERRIDE { | 111 virtual bool InstallAttributesIsFirstInstall() OVERRIDE { |
| 112 bool result = false; | 112 bool result = false; |
| 113 DBusThreadManager::Get()->GetCryptohomeClient()-> | 113 DBusThreadManager::Get()->GetCryptohomeClient()-> |
| 114 InstallAttributesIsFirstInstall(&result); | 114 InstallAttributesIsFirstInstall(&result); |
| 115 return result; | 115 return result; |
| 116 } | 116 } |
| 117 | 117 |
| 118 virtual std::string GetSystemSalt() OVERRIDE { | 118 virtual std::string GetSystemSalt() OVERRIDE { |
| 119 LoadSystemSalt(); // no-op if it's already loaded. | 119 LoadSystemSalt(); // no-op if it's already loaded. |
| 120 return StringToLowerASCII(base::HexEncode( | 120 return system_salt_; |
| 121 reinterpret_cast<const void*>(system_salt_.data()), | |
| 122 system_salt_.size())); | |
| 123 } | 121 } |
| 124 | 122 |
| 125 virtual std::string EncryptWithSystemSalt(const std::string& token) OVERRIDE { | 123 virtual std::string EncryptWithSystemSalt(const std::string& token) OVERRIDE { |
| 126 // Don't care about token encryption while debugging. | 124 // Don't care about token encryption while debugging. |
| 127 if (!base::chromeos::IsRunningOnChromeOS()) | 125 if (!base::chromeos::IsRunningOnChromeOS()) |
| 128 return token; | 126 return token; |
| 129 | 127 |
| 130 if (!LoadSystemSaltKey()) { | 128 if (!LoadSystemSaltKey()) { |
| 131 LOG(WARNING) << "System salt key is not available for encrypt."; | 129 LOG(WARNING) << "System salt key is not available for encrypt."; |
| 132 return std::string(); | 130 return std::string(); |
| 133 } | 131 } |
| 134 return EncryptTokenWithKey(system_salt_key_.get(), | 132 return EncryptTokenWithKey(system_salt_key_.get(), |
| 135 GetSystemSalt(), | 133 system_salt_, |
| 136 token); | 134 token); |
| 137 } | 135 } |
| 138 | 136 |
| 139 virtual std::string DecryptWithSystemSalt( | 137 virtual std::string DecryptWithSystemSalt( |
| 140 const std::string& encrypted_token_hex) OVERRIDE { | 138 const std::string& encrypted_token_hex) OVERRIDE { |
| 141 // Don't care about token encryption while debugging. | 139 // Don't care about token encryption while debugging. |
| 142 if (!base::chromeos::IsRunningOnChromeOS()) | 140 if (!base::chromeos::IsRunningOnChromeOS()) |
| 143 return encrypted_token_hex; | 141 return encrypted_token_hex; |
| 144 | 142 |
| 145 if (!LoadSystemSaltKey()) { | 143 if (!LoadSystemSaltKey()) { |
| 146 LOG(WARNING) << "System salt key is not available for decrypt."; | 144 LOG(WARNING) << "System salt key is not available for decrypt."; |
| 147 return std::string(); | 145 return std::string(); |
| 148 } | 146 } |
| 149 return DecryptTokenWithKey(system_salt_key_.get(), | 147 return DecryptTokenWithKey(system_salt_key_.get(), |
| 150 GetSystemSalt(), | 148 system_salt_, |
| 151 encrypted_token_hex); | 149 encrypted_token_hex); |
| 152 } | 150 } |
| 153 | 151 |
| 154 private: | 152 private: |
| 155 void LoadSystemSalt() { | 153 void LoadSystemSalt() { |
| 156 if (!system_salt_.empty()) | 154 if (!system_salt_.empty()) |
| 157 return; | 155 return; |
| 158 DBusThreadManager::Get()->GetCryptohomeClient()-> | 156 std::vector<uint8> salt; |
| 159 GetSystemSalt(&system_salt_); | 157 DBusThreadManager::Get()->GetCryptohomeClient()->GetSystemSalt(&salt); |
| 160 CHECK(!system_salt_.empty()); | 158 if (salt.empty() || salt.size() % 2 != 0U) { |
| 161 CHECK_EQ(system_salt_.size() % 2, 0U); | 159 LOG(WARNING) << "System salt not available"; |
| 160 return; |
| 161 } |
| 162 system_salt_ = StringToLowerASCII(base::HexEncode( |
| 163 reinterpret_cast<const void*>(salt.data()), salt.size())); |
| 162 } | 164 } |
| 163 | 165 |
| 164 // TODO: should this use the system salt for both the password and the salt | 166 // TODO: should this use the system salt for both the password and the salt |
| 165 // value, or should this use a separate salt value? | 167 // value, or should this use a separate salt value? |
| 166 bool LoadSystemSaltKey() { | 168 bool LoadSystemSaltKey() { |
| 169 if (system_salt_.empty()) |
| 170 return false; |
| 167 if (!system_salt_key_.get()) | 171 if (!system_salt_key_.get()) |
| 168 system_salt_key_.reset(PassphraseToKey(GetSystemSalt(), GetSystemSalt())); | 172 system_salt_key_.reset(PassphraseToKey(system_salt_, system_salt_)); |
| 169 return system_salt_key_.get(); | 173 return system_salt_key_.get(); |
| 170 } | 174 } |
| 171 | 175 |
| 172 crypto::SymmetricKey* PassphraseToKey(const std::string& passphrase, | 176 crypto::SymmetricKey* PassphraseToKey(const std::string& passphrase, |
| 173 const std::string& salt) { | 177 const std::string& salt) { |
| 174 return crypto::SymmetricKey::DeriveKeyFromPassword( | 178 return crypto::SymmetricKey::DeriveKeyFromPassword( |
| 175 crypto::SymmetricKey::AES, passphrase, salt, 1000, 256); | 179 crypto::SymmetricKey::AES, passphrase, salt, 1000, 256); |
| 176 } | 180 } |
| 177 | 181 |
| 178 | 182 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 std::string nonce = salt.substr(0, kNonceSize); | 224 std::string nonce = salt.substr(0, kNonceSize); |
| 221 std::string token; | 225 std::string token; |
| 222 CHECK(encryptor.SetCounter(nonce)); | 226 CHECK(encryptor.SetCounter(nonce)); |
| 223 if (!encryptor.Decrypt(encrypted_token, &token)) { | 227 if (!encryptor.Decrypt(encrypted_token, &token)) { |
| 224 LOG(WARNING) << "Failed to decrypt token."; | 228 LOG(WARNING) << "Failed to decrypt token."; |
| 225 return std::string(); | 229 return std::string(); |
| 226 } | 230 } |
| 227 return token; | 231 return token; |
| 228 } | 232 } |
| 229 | 233 |
| 230 base::WeakPtrFactory<CryptohomeLibraryImpl> weak_ptr_factory_; | 234 std::string system_salt_; |
| 231 std::vector<uint8> system_salt_; | |
| 232 // A key based on the system salt. Useful for encrypting device-level | 235 // A key based on the system salt. Useful for encrypting device-level |
| 233 // data for which we have no additional credentials. | 236 // data for which we have no additional credentials. |
| 234 scoped_ptr<crypto::SymmetricKey> system_salt_key_; | 237 scoped_ptr<crypto::SymmetricKey> system_salt_key_; |
| 235 | 238 |
| 236 DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryImpl); | 239 DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryImpl); |
| 237 }; | 240 }; |
| 238 | 241 |
| 239 class CryptohomeLibraryStubImpl : public CryptohomeLibrary { | 242 class CryptohomeLibraryStubImpl : public CryptohomeLibrary { |
| 240 public: | 243 public: |
| 241 CryptohomeLibraryStubImpl() | 244 CryptohomeLibraryStubImpl() |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 CHECK(!g_test_cryptohome_library || !impl); | 349 CHECK(!g_test_cryptohome_library || !impl); |
| 347 g_test_cryptohome_library = impl; | 350 g_test_cryptohome_library = impl; |
| 348 } | 351 } |
| 349 | 352 |
| 350 // static | 353 // static |
| 351 CryptohomeLibrary* CryptohomeLibrary::GetTestImpl() { | 354 CryptohomeLibrary* CryptohomeLibrary::GetTestImpl() { |
| 352 return new CryptohomeLibraryStubImpl(); | 355 return new CryptohomeLibraryStubImpl(); |
| 353 } | 356 } |
| 354 | 357 |
| 355 } // namespace chromeos | 358 } // namespace chromeos |
| OLD | NEW |