| 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 |