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 "components/sync/base/nigori.h" | 5 #include "components/sync/base/nigori.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <sstream> | 9 #include <sstream> |
10 #include <vector> | 10 #include <vector> |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 const std::string& password) { | 68 const std::string& password) { |
69 NigoriStream salt_password; | 69 NigoriStream salt_password; |
70 salt_password << username << hostname; | 70 salt_password << username << hostname; |
71 | 71 |
72 // Suser = PBKDF2(Username || Servername, "saltsalt", Nsalt, 8) | 72 // Suser = PBKDF2(Username || Servername, "saltsalt", Nsalt, 8) |
73 std::unique_ptr<SymmetricKey> user_salt(SymmetricKey::DeriveKeyFromPassword( | 73 std::unique_ptr<SymmetricKey> user_salt(SymmetricKey::DeriveKeyFromPassword( |
74 SymmetricKey::HMAC_SHA1, salt_password.str(), kSaltSalt, kSaltIterations, | 74 SymmetricKey::HMAC_SHA1, salt_password.str(), kSaltSalt, kSaltIterations, |
75 kSaltKeySizeInBits)); | 75 kSaltKeySizeInBits)); |
76 DCHECK(user_salt); | 76 DCHECK(user_salt); |
77 | 77 |
78 std::string raw_user_salt; | |
79 if (!user_salt->GetRawKey(&raw_user_salt)) | |
80 return false; | |
81 | |
82 // Kuser = PBKDF2(P, Suser, Nuser, 16) | 78 // Kuser = PBKDF2(P, Suser, Nuser, 16) |
83 user_key_ = SymmetricKey::DeriveKeyFromPassword( | 79 user_key_ = SymmetricKey::DeriveKeyFromPassword( |
84 SymmetricKey::AES, password, raw_user_salt, kUserIterations, | 80 SymmetricKey::AES, password, user_salt->key(), kUserIterations, |
85 kDerivedKeySizeInBits); | 81 kDerivedKeySizeInBits); |
86 DCHECK(user_key_); | 82 DCHECK(user_key_); |
87 | 83 |
88 // Kenc = PBKDF2(P, Suser, Nenc, 16) | 84 // Kenc = PBKDF2(P, Suser, Nenc, 16) |
89 encryption_key_ = SymmetricKey::DeriveKeyFromPassword( | 85 encryption_key_ = SymmetricKey::DeriveKeyFromPassword( |
90 SymmetricKey::AES, password, raw_user_salt, kEncryptionIterations, | 86 SymmetricKey::AES, password, user_salt->key(), kEncryptionIterations, |
91 kDerivedKeySizeInBits); | 87 kDerivedKeySizeInBits); |
92 DCHECK(encryption_key_); | 88 DCHECK(encryption_key_); |
93 | 89 |
94 // Kmac = PBKDF2(P, Suser, Nmac, 16) | 90 // Kmac = PBKDF2(P, Suser, Nmac, 16) |
95 mac_key_ = SymmetricKey::DeriveKeyFromPassword( | 91 mac_key_ = SymmetricKey::DeriveKeyFromPassword( |
96 SymmetricKey::HMAC_SHA1, password, raw_user_salt, kSigningIterations, | 92 SymmetricKey::HMAC_SHA1, password, user_salt->key(), kSigningIterations, |
97 kDerivedKeySizeInBits); | 93 kDerivedKeySizeInBits); |
98 DCHECK(mac_key_); | 94 DCHECK(mac_key_); |
99 | 95 |
100 return user_key_ && encryption_key_ && mac_key_; | 96 return user_key_ && encryption_key_ && mac_key_; |
101 } | 97 } |
102 | 98 |
103 bool Nigori::InitByImport(const std::string& user_key, | 99 bool Nigori::InitByImport(const std::string& user_key, |
104 const std::string& encryption_key, | 100 const std::string& encryption_key, |
105 const std::string& mac_key) { | 101 const std::string& mac_key) { |
106 user_key_ = SymmetricKey::Import(SymmetricKey::AES, user_key); | 102 user_key_ = SymmetricKey::Import(SymmetricKey::AES, user_key); |
(...skipping 18 matching lines...) Expand all Loading... |
125 | 121 |
126 Encryptor encryptor; | 122 Encryptor encryptor; |
127 if (!encryptor.Init(encryption_key_.get(), Encryptor::CBC, | 123 if (!encryptor.Init(encryption_key_.get(), Encryptor::CBC, |
128 std::string(kIvSize, 0))) | 124 std::string(kIvSize, 0))) |
129 return false; | 125 return false; |
130 | 126 |
131 std::string ciphertext; | 127 std::string ciphertext; |
132 if (!encryptor.Encrypt(plaintext.str(), &ciphertext)) | 128 if (!encryptor.Encrypt(plaintext.str(), &ciphertext)) |
133 return false; | 129 return false; |
134 | 130 |
135 std::string raw_mac_key; | |
136 if (!mac_key_->GetRawKey(&raw_mac_key)) | |
137 return false; | |
138 | |
139 HMAC hmac(HMAC::SHA256); | 131 HMAC hmac(HMAC::SHA256); |
140 if (!hmac.Init(raw_mac_key)) | 132 if (!hmac.Init(mac_key_->key())) |
141 return false; | 133 return false; |
142 | 134 |
143 std::vector<unsigned char> hash(kHashSize); | 135 std::vector<unsigned char> hash(kHashSize); |
144 if (!hmac.Sign(ciphertext, &hash[0], hash.size())) | 136 if (!hmac.Sign(ciphertext, &hash[0], hash.size())) |
145 return false; | 137 return false; |
146 | 138 |
147 std::string output; | 139 std::string output; |
148 output.assign(ciphertext); | 140 output.assign(ciphertext); |
149 output.append(hash.begin(), hash.end()); | 141 output.append(hash.begin(), hash.end()); |
150 | 142 |
(...skipping 10 matching lines...) Expand all Loading... |
161 crypto::RandBytes(base::WriteInto(&iv, kIvSize + 1), kIvSize); | 153 crypto::RandBytes(base::WriteInto(&iv, kIvSize + 1), kIvSize); |
162 | 154 |
163 Encryptor encryptor; | 155 Encryptor encryptor; |
164 if (!encryptor.Init(encryption_key_.get(), Encryptor::CBC, iv)) | 156 if (!encryptor.Init(encryption_key_.get(), Encryptor::CBC, iv)) |
165 return false; | 157 return false; |
166 | 158 |
167 std::string ciphertext; | 159 std::string ciphertext; |
168 if (!encryptor.Encrypt(value, &ciphertext)) | 160 if (!encryptor.Encrypt(value, &ciphertext)) |
169 return false; | 161 return false; |
170 | 162 |
171 std::string raw_mac_key; | |
172 if (!mac_key_->GetRawKey(&raw_mac_key)) | |
173 return false; | |
174 | |
175 HMAC hmac(HMAC::SHA256); | 163 HMAC hmac(HMAC::SHA256); |
176 if (!hmac.Init(raw_mac_key)) | 164 if (!hmac.Init(mac_key_->key())) |
177 return false; | 165 return false; |
178 | 166 |
179 std::vector<unsigned char> hash(kHashSize); | 167 std::vector<unsigned char> hash(kHashSize); |
180 if (!hmac.Sign(ciphertext, &hash[0], hash.size())) | 168 if (!hmac.Sign(ciphertext, &hash[0], hash.size())) |
181 return false; | 169 return false; |
182 | 170 |
183 std::string output; | 171 std::string output; |
184 output.assign(iv); | 172 output.assign(iv); |
185 output.append(ciphertext); | 173 output.append(ciphertext); |
186 output.append(hash.begin(), hash.end()); | 174 output.append(hash.begin(), hash.end()); |
(...skipping 12 matching lines...) Expand all Loading... |
199 | 187 |
200 // The input is: | 188 // The input is: |
201 // * iv (16 bytes) | 189 // * iv (16 bytes) |
202 // * ciphertext (multiple of 16 bytes) | 190 // * ciphertext (multiple of 16 bytes) |
203 // * hash (32 bytes) | 191 // * hash (32 bytes) |
204 std::string iv(input.substr(0, kIvSize)); | 192 std::string iv(input.substr(0, kIvSize)); |
205 std::string ciphertext( | 193 std::string ciphertext( |
206 input.substr(kIvSize, input.size() - (kIvSize + kHashSize))); | 194 input.substr(kIvSize, input.size() - (kIvSize + kHashSize))); |
207 std::string hash(input.substr(input.size() - kHashSize, kHashSize)); | 195 std::string hash(input.substr(input.size() - kHashSize, kHashSize)); |
208 | 196 |
209 std::string raw_mac_key; | |
210 if (!mac_key_->GetRawKey(&raw_mac_key)) | |
211 return false; | |
212 | |
213 HMAC hmac(HMAC::SHA256); | 197 HMAC hmac(HMAC::SHA256); |
214 if (!hmac.Init(raw_mac_key)) | 198 if (!hmac.Init(mac_key_->key())) |
215 return false; | 199 return false; |
216 | 200 |
217 std::vector<unsigned char> expected(kHashSize); | 201 std::vector<unsigned char> expected(kHashSize); |
218 if (!hmac.Sign(ciphertext, &expected[0], expected.size())) | 202 if (!hmac.Sign(ciphertext, &expected[0], expected.size())) |
219 return false; | 203 return false; |
220 | 204 |
221 if (hash.compare(0, hash.size(), reinterpret_cast<char*>(&expected[0]), | 205 if (hash.compare(0, hash.size(), reinterpret_cast<char*>(&expected[0]), |
222 expected.size())) | 206 expected.size())) |
223 return false; | 207 return false; |
224 | 208 |
225 Encryptor encryptor; | 209 Encryptor encryptor; |
226 if (!encryptor.Init(encryption_key_.get(), Encryptor::CBC, iv)) | 210 if (!encryptor.Init(encryption_key_.get(), Encryptor::CBC, iv)) |
227 return false; | 211 return false; |
228 | 212 |
229 if (!encryptor.Decrypt(ciphertext, value)) | 213 if (!encryptor.Decrypt(ciphertext, value)) |
230 return false; | 214 return false; |
231 | 215 |
232 return true; | 216 return true; |
233 } | 217 } |
234 | 218 |
235 bool Nigori::ExportKeys(std::string* user_key, | 219 void Nigori::ExportKeys(std::string* user_key, |
236 std::string* encryption_key, | 220 std::string* encryption_key, |
237 std::string* mac_key) const { | 221 std::string* mac_key) const { |
238 DCHECK(encryption_key); | 222 DCHECK(encryption_key); |
239 DCHECK(mac_key); | 223 DCHECK(mac_key); |
240 DCHECK(user_key); | 224 DCHECK(user_key); |
241 | 225 |
242 if (user_key_) | 226 if (user_key_) |
243 user_key_->GetRawKey(user_key); | 227 *user_key = user_key_->key(); |
244 else | 228 else |
245 user_key->clear(); | 229 user_key->clear(); |
246 | 230 |
247 return encryption_key_->GetRawKey(encryption_key) && | 231 *encryption_key = encryption_key_->key(); |
248 mac_key_->GetRawKey(mac_key); | 232 *mac_key = mac_key_->key(); |
249 } | 233 } |
250 | 234 |
251 } // namespace syncer | 235 } // namespace syncer |
OLD | NEW |