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

Side by Side Diff: chromeos/cryptohome/cryptohome_library.cc

Issue 25975002: cryptohome: Move Encrypt/DecryptWithSystemSalt() out of CryptohomeLibrary (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add GetCachedSystemSalt Created 7 years, 2 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/memory/weak_ptr.h" 10 #include "base/memory/weak_ptr.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
13 #include "base/sys_info.h" 13 #include "base/sys_info.h"
14 #include "chromeos/dbus/cryptohome_client.h" 14 #include "chromeos/dbus/cryptohome_client.h"
15 #include "chromeos/dbus/dbus_method_call_status.h" 15 #include "chromeos/dbus/dbus_method_call_status.h"
16 #include "chromeos/dbus/dbus_thread_manager.h" 16 #include "chromeos/dbus/dbus_thread_manager.h"
17 #include "crypto/encryptor.h"
18 #include "crypto/nss_util.h"
19 #include "crypto/sha2.h"
20 #include "crypto/symmetric_key.h"
21 17
22 namespace chromeos { 18 namespace chromeos {
23 19
24 namespace { 20 namespace {
25 21
26 const char kStubSystemSalt[] = "stub_system_salt"; 22 const char kStubSystemSalt[] = "stub_system_salt";
27 const size_t kNonceSize = 16;
28 23
29 } // namespace 24 } // namespace
30 25
31 // This class handles the interaction with the ChromeOS cryptohome library APIs. 26 // This class handles the interaction with the ChromeOS cryptohome library APIs.
32 class CryptohomeLibraryImpl : public CryptohomeLibrary { 27 class CryptohomeLibraryImpl : public CryptohomeLibrary {
33 public: 28 public:
34 CryptohomeLibraryImpl() { 29 CryptohomeLibraryImpl() {
35 } 30 }
36 31
37 virtual ~CryptohomeLibraryImpl() { 32 virtual ~CryptohomeLibraryImpl() {
38 } 33 }
39 34
40 virtual std::string GetSystemSalt() OVERRIDE { 35 virtual std::string GetSystemSalt() OVERRIDE {
41 LoadSystemSalt(); // no-op if it's already loaded. 36 LoadSystemSalt(); // no-op if it's already loaded.
42 return system_salt_; 37 return system_salt_;
43 } 38 }
44 39
45 virtual std::string EncryptWithSystemSalt(const std::string& token) OVERRIDE { 40 virtual std::string GetCachedSystemSalt() OVERRIDE {
46 // Don't care about token encryption while debugging. 41 return system_salt_;
47 if (!base::SysInfo::IsRunningOnChromeOS())
48 return token;
49
50 if (!LoadSystemSaltKey()) {
51 LOG(WARNING) << "System salt key is not available for encrypt.";
52 return std::string();
53 }
54 return EncryptTokenWithKey(system_salt_key_.get(),
55 system_salt_,
56 token);
57 }
58
59 virtual std::string DecryptWithSystemSalt(
60 const std::string& encrypted_token_hex) OVERRIDE {
61 // Don't care about token encryption while debugging.
62 if (!base::SysInfo::IsRunningOnChromeOS())
63 return encrypted_token_hex;
64
65 if (!LoadSystemSaltKey()) {
66 LOG(WARNING) << "System salt key is not available for decrypt.";
67 return std::string();
68 }
69 return DecryptTokenWithKey(system_salt_key_.get(),
70 system_salt_,
71 encrypted_token_hex);
72 } 42 }
73 43
74 private: 44 private:
75 void LoadSystemSalt() { 45 void LoadSystemSalt() {
76 if (!system_salt_.empty()) 46 if (!system_salt_.empty())
77 return; 47 return;
78 std::vector<uint8> salt; 48 std::vector<uint8> salt;
79 DBusThreadManager::Get()->GetCryptohomeClient()->GetSystemSalt(&salt); 49 DBusThreadManager::Get()->GetCryptohomeClient()->GetSystemSalt(&salt);
80 if (salt.empty() || salt.size() % 2 != 0U) { 50 if (salt.empty() || salt.size() % 2 != 0U) {
81 LOG(WARNING) << "System salt not available"; 51 LOG(WARNING) << "System salt not available";
82 return; 52 return;
83 } 53 }
84 system_salt_ = StringToLowerASCII(base::HexEncode( 54 system_salt_ = StringToLowerASCII(base::HexEncode(
85 reinterpret_cast<const void*>(salt.data()), salt.size())); 55 reinterpret_cast<const void*>(salt.data()), salt.size()));
86 } 56 }
87 57
88 // TODO: should this use the system salt for both the password and the salt
89 // value, or should this use a separate salt value?
90 bool LoadSystemSaltKey() {
91 if (system_salt_.empty())
92 return false;
93 if (!system_salt_key_.get())
94 system_salt_key_.reset(PassphraseToKey(system_salt_, system_salt_));
95 return system_salt_key_.get();
96 }
97
98 crypto::SymmetricKey* PassphraseToKey(const std::string& passphrase,
99 const std::string& salt) {
100 return crypto::SymmetricKey::DeriveKeyFromPassword(
101 crypto::SymmetricKey::AES, passphrase, salt, 1000, 256);
102 }
103
104
105 // Encrypts (AES) the token given |key| and |salt|.
106 std::string EncryptTokenWithKey(crypto::SymmetricKey* key,
107 const std::string& salt,
108 const std::string& token) {
109 crypto::Encryptor encryptor;
110 if (!encryptor.Init(key, crypto::Encryptor::CTR, std::string())) {
111 LOG(WARNING) << "Failed to initialize Encryptor.";
112 return std::string();
113 }
114 std::string nonce = salt.substr(0, kNonceSize);
115 std::string encoded_token;
116 CHECK(encryptor.SetCounter(nonce));
117 if (!encryptor.Encrypt(token, &encoded_token)) {
118 LOG(WARNING) << "Failed to encrypt token.";
119 return std::string();
120 }
121
122 return StringToLowerASCII(base::HexEncode(
123 reinterpret_cast<const void*>(encoded_token.data()),
124 encoded_token.size()));
125 }
126
127 // Decrypts (AES) hex encoded encrypted token given |key| and |salt|.
128 std::string DecryptTokenWithKey(crypto::SymmetricKey* key,
129 const std::string& salt,
130 const std::string& encrypted_token_hex) {
131 std::vector<uint8> encrypted_token_bytes;
132 if (!base::HexStringToBytes(encrypted_token_hex, &encrypted_token_bytes)) {
133 LOG(WARNING) << "Corrupt encrypted token found.";
134 return std::string();
135 }
136
137 std::string encrypted_token(
138 reinterpret_cast<char*>(encrypted_token_bytes.data()),
139 encrypted_token_bytes.size());
140 crypto::Encryptor encryptor;
141 if (!encryptor.Init(key, crypto::Encryptor::CTR, std::string())) {
142 LOG(WARNING) << "Failed to initialize Encryptor.";
143 return std::string();
144 }
145
146 std::string nonce = salt.substr(0, kNonceSize);
147 std::string token;
148 CHECK(encryptor.SetCounter(nonce));
149 if (!encryptor.Decrypt(encrypted_token, &token)) {
150 LOG(WARNING) << "Failed to decrypt token.";
151 return std::string();
152 }
153 return token;
154 }
155
156 std::string system_salt_; 58 std::string system_salt_;
157 // A key based on the system salt. Useful for encrypting device-level
158 // data for which we have no additional credentials.
159 scoped_ptr<crypto::SymmetricKey> system_salt_key_;
160 59
161 DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryImpl); 60 DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryImpl);
162 }; 61 };
163 62
164 class CryptohomeLibraryStubImpl : public CryptohomeLibrary { 63 class CryptohomeLibraryStubImpl : public CryptohomeLibrary {
165 public: 64 public:
166 CryptohomeLibraryStubImpl() 65 CryptohomeLibraryStubImpl()
167 : locked_(false) {} 66 : locked_(false) {}
168 virtual ~CryptohomeLibraryStubImpl() {} 67 virtual ~CryptohomeLibraryStubImpl() {}
169 68
170 virtual std::string GetSystemSalt() OVERRIDE { 69 virtual std::string GetSystemSalt() OVERRIDE {
171 return kStubSystemSalt; 70 return kStubSystemSalt;
172 } 71 }
173 72
174 virtual std::string EncryptWithSystemSalt(const std::string& token) OVERRIDE { 73 virtual std::string GetCachedSystemSalt() OVERRIDE {
175 return token; 74 return kStubSystemSalt;
176 }
177
178 virtual std::string DecryptWithSystemSalt(
179 const std::string& encrypted_token_hex) OVERRIDE {
180 return encrypted_token_hex;
181 } 75 }
182 76
183 private: 77 private:
184 std::map<std::string, std::string> install_attrs_; 78 std::map<std::string, std::string> install_attrs_;
185 bool locked_; 79 bool locked_;
hashimoto 2013/10/04 08:38:56 nit: Can we remove these two members? It seems the
satorux1 2013/10/07 02:19:14 Good catch. Forgot to remove them earlier. Done!
186 DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryStubImpl); 80 DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryStubImpl);
187 }; 81 };
188 82
189 CryptohomeLibrary::CryptohomeLibrary() {} 83 CryptohomeLibrary::CryptohomeLibrary() {}
190 CryptohomeLibrary::~CryptohomeLibrary() {} 84 CryptohomeLibrary::~CryptohomeLibrary() {}
191 85
192 static CryptohomeLibrary* g_cryptohome_library = NULL; 86 static CryptohomeLibrary* g_cryptohome_library = NULL;
193 static CryptohomeLibrary* g_test_cryptohome_library = NULL; 87 static CryptohomeLibrary* g_test_cryptohome_library = NULL;
194 88
195 // static 89 // static
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 CHECK(!g_test_cryptohome_library || !impl); 121 CHECK(!g_test_cryptohome_library || !impl);
228 g_test_cryptohome_library = impl; 122 g_test_cryptohome_library = impl;
229 } 123 }
230 124
231 // static 125 // static
232 CryptohomeLibrary* CryptohomeLibrary::GetTestImpl() { 126 CryptohomeLibrary* CryptohomeLibrary::GetTestImpl() {
233 return new CryptohomeLibraryStubImpl(); 127 return new CryptohomeLibraryStubImpl();
234 } 128 }
235 129
236 } // namespace chromeos 130 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698