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

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: 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 {
46 // Don't care about token encryption while debugging.
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 }
73
74 private: 40 private:
75 void LoadSystemSalt() { 41 void LoadSystemSalt() {
76 if (!system_salt_.empty()) 42 if (!system_salt_.empty())
77 return; 43 return;
78 std::vector<uint8> salt; 44 std::vector<uint8> salt;
79 DBusThreadManager::Get()->GetCryptohomeClient()->GetSystemSalt(&salt); 45 DBusThreadManager::Get()->GetCryptohomeClient()->GetSystemSalt(&salt);
80 if (salt.empty() || salt.size() % 2 != 0U) { 46 if (salt.empty() || salt.size() % 2 != 0U) {
81 LOG(WARNING) << "System salt not available"; 47 LOG(WARNING) << "System salt not available";
82 return; 48 return;
83 } 49 }
84 system_salt_ = StringToLowerASCII(base::HexEncode( 50 system_salt_ = StringToLowerASCII(base::HexEncode(
85 reinterpret_cast<const void*>(salt.data()), salt.size())); 51 reinterpret_cast<const void*>(salt.data()), salt.size()));
86 } 52 }
87 53
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_; 54 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 55
161 DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryImpl); 56 DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryImpl);
162 }; 57 };
163 58
164 class CryptohomeLibraryStubImpl : public CryptohomeLibrary { 59 class CryptohomeLibraryStubImpl : public CryptohomeLibrary {
165 public: 60 public:
166 CryptohomeLibraryStubImpl() 61 CryptohomeLibraryStubImpl()
167 : locked_(false) {} 62 : locked_(false) {}
168 virtual ~CryptohomeLibraryStubImpl() {} 63 virtual ~CryptohomeLibraryStubImpl() {}
169 64
170 virtual std::string GetSystemSalt() OVERRIDE { 65 virtual std::string GetSystemSalt() OVERRIDE {
171 return kStubSystemSalt; 66 return kStubSystemSalt;
172 } 67 }
173 68
174 virtual std::string EncryptWithSystemSalt(const std::string& token) OVERRIDE {
175 return token;
176 }
177
178 virtual std::string DecryptWithSystemSalt(
179 const std::string& encrypted_token_hex) OVERRIDE {
180 return encrypted_token_hex;
181 }
182
183 private: 69 private:
184 std::map<std::string, std::string> install_attrs_; 70 std::map<std::string, std::string> install_attrs_;
185 bool locked_; 71 bool locked_;
186 DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryStubImpl); 72 DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryStubImpl);
187 }; 73 };
188 74
189 CryptohomeLibrary::CryptohomeLibrary() {} 75 CryptohomeLibrary::CryptohomeLibrary() {}
190 CryptohomeLibrary::~CryptohomeLibrary() {} 76 CryptohomeLibrary::~CryptohomeLibrary() {}
191 77
192 static CryptohomeLibrary* g_cryptohome_library = NULL; 78 static CryptohomeLibrary* g_cryptohome_library = NULL;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 CHECK(!g_test_cryptohome_library || !impl); 113 CHECK(!g_test_cryptohome_library || !impl);
228 g_test_cryptohome_library = impl; 114 g_test_cryptohome_library = impl;
229 } 115 }
230 116
231 // static 117 // static
232 CryptohomeLibrary* CryptohomeLibrary::GetTestImpl() { 118 CryptohomeLibrary* CryptohomeLibrary::GetTestImpl() {
233 return new CryptohomeLibraryStubImpl(); 119 return new CryptohomeLibraryStubImpl();
234 } 120 }
235 121
236 } // namespace chromeos 122 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698