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 |