diff options
Diffstat (limited to 'chromium/sync/util/nigori.cc')
-rw-r--r-- | chromium/sync/util/nigori.cc | 250 |
1 files changed, 0 insertions, 250 deletions
diff --git a/chromium/sync/util/nigori.cc b/chromium/sync/util/nigori.cc deleted file mode 100644 index e74d81a9185..00000000000 --- a/chromium/sync/util/nigori.cc +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "sync/util/nigori.h" - -#include <sstream> -#include <vector> - -#include "base/base64.h" -#include "base/logging.h" -#include "base/strings/string_util.h" -#include "base/sys_byteorder.h" -#include "crypto/encryptor.h" -#include "crypto/hmac.h" -#include "crypto/random.h" -#include "crypto/symmetric_key.h" - -using base::Base64Encode; -using base::Base64Decode; -using crypto::Encryptor; -using crypto::HMAC; -using crypto::SymmetricKey; - -namespace syncer { - -// NigoriStream simplifies the concatenation operation of the Nigori protocol. -class NigoriStream { - public: - // Append the big-endian representation of the length of |value| with 32 bits, - // followed by |value| itself to the stream. - NigoriStream& operator<<(const std::string& value) { - uint32 size = base::HostToNet32(value.size()); - stream_.write((char *) &size, sizeof(uint32)); - stream_ << value; - return *this; - } - - // Append the big-endian representation of the length of |type| with 32 bits, - // followed by the big-endian representation of the value of |type|, with 32 - // bits, to the stream. - NigoriStream& operator<<(const Nigori::Type type) { - uint32 size = base::HostToNet32(sizeof(uint32)); - stream_.write((char *) &size, sizeof(uint32)); - uint32 value = base::HostToNet32(type); - stream_.write((char *) &value, sizeof(uint32)); - return *this; - } - - std::string str() { - return stream_.str(); - } - - private: - std::ostringstream stream_; -}; - -// static -const char Nigori::kSaltSalt[] = "saltsalt"; - -Nigori::Nigori() { -} - -Nigori::~Nigori() { -} - -bool Nigori::InitByDerivation(const std::string& hostname, - const std::string& username, - const std::string& password) { - NigoriStream salt_password; - salt_password << username << hostname; - - // Suser = PBKDF2(Username || Servername, "saltsalt", Nsalt, 8) - scoped_ptr<SymmetricKey> user_salt(SymmetricKey::DeriveKeyFromPassword( - SymmetricKey::HMAC_SHA1, salt_password.str(), - kSaltSalt, - kSaltIterations, - kSaltKeySizeInBits)); - DCHECK(user_salt.get()); - - std::string raw_user_salt; - if (!user_salt->GetRawKey(&raw_user_salt)) - return false; - - // Kuser = PBKDF2(P, Suser, Nuser, 16) - user_key_.reset(SymmetricKey::DeriveKeyFromPassword(SymmetricKey::AES, - password, raw_user_salt, kUserIterations, kDerivedKeySizeInBits)); - DCHECK(user_key_.get()); - - // Kenc = PBKDF2(P, Suser, Nenc, 16) - encryption_key_.reset(SymmetricKey::DeriveKeyFromPassword(SymmetricKey::AES, - password, raw_user_salt, kEncryptionIterations, kDerivedKeySizeInBits)); - DCHECK(encryption_key_.get()); - - // Kmac = PBKDF2(P, Suser, Nmac, 16) - mac_key_.reset(SymmetricKey::DeriveKeyFromPassword( - SymmetricKey::HMAC_SHA1, password, raw_user_salt, kSigningIterations, - kDerivedKeySizeInBits)); - DCHECK(mac_key_.get()); - - return user_key_.get() && encryption_key_.get() && mac_key_.get(); -} - -bool Nigori::InitByImport(const std::string& user_key, - const std::string& encryption_key, - const std::string& mac_key) { - user_key_.reset(SymmetricKey::Import(SymmetricKey::AES, user_key)); - DCHECK(user_key_.get()); - - encryption_key_.reset(SymmetricKey::Import(SymmetricKey::AES, - encryption_key)); - DCHECK(encryption_key_.get()); - - mac_key_.reset(SymmetricKey::Import(SymmetricKey::HMAC_SHA1, mac_key)); - DCHECK(mac_key_.get()); - - return user_key_.get() && encryption_key_.get() && mac_key_.get(); -} - -// Permute[Kenc,Kmac](type || name) -bool Nigori::Permute(Type type, const std::string& name, - std::string* permuted) const { - DCHECK_LT(0U, name.size()); - - NigoriStream plaintext; - plaintext << type << name; - - Encryptor encryptor; - if (!encryptor.Init(encryption_key_.get(), Encryptor::CBC, - std::string(kIvSize, 0))) - return false; - - std::string ciphertext; - if (!encryptor.Encrypt(plaintext.str(), &ciphertext)) - return false; - - std::string raw_mac_key; - if (!mac_key_->GetRawKey(&raw_mac_key)) - return false; - - HMAC hmac(HMAC::SHA256); - if (!hmac.Init(raw_mac_key)) - return false; - - std::vector<unsigned char> hash(kHashSize); - if (!hmac.Sign(ciphertext, &hash[0], hash.size())) - return false; - - std::string output; - output.assign(ciphertext); - output.append(hash.begin(), hash.end()); - - Base64Encode(output, permuted); - return true; -} - -// Enc[Kenc,Kmac](value) -bool Nigori::Encrypt(const std::string& value, std::string* encrypted) const { - if (0U >= value.size()) - return false; - - std::string iv; - crypto::RandBytes(WriteInto(&iv, kIvSize + 1), kIvSize); - - Encryptor encryptor; - if (!encryptor.Init(encryption_key_.get(), Encryptor::CBC, iv)) - return false; - - std::string ciphertext; - if (!encryptor.Encrypt(value, &ciphertext)) - return false; - - std::string raw_mac_key; - if (!mac_key_->GetRawKey(&raw_mac_key)) - return false; - - HMAC hmac(HMAC::SHA256); - if (!hmac.Init(raw_mac_key)) - return false; - - std::vector<unsigned char> hash(kHashSize); - if (!hmac.Sign(ciphertext, &hash[0], hash.size())) - return false; - - std::string output; - output.assign(iv); - output.append(ciphertext); - output.append(hash.begin(), hash.end()); - - Base64Encode(output, encrypted); - return true; -} - -bool Nigori::Decrypt(const std::string& encrypted, std::string* value) const { - std::string input; - if (!Base64Decode(encrypted, &input)) - return false; - - if (input.size() < kIvSize * 2 + kHashSize) - return false; - - // The input is: - // * iv (16 bytes) - // * ciphertext (multiple of 16 bytes) - // * hash (32 bytes) - std::string iv(input.substr(0, kIvSize)); - std::string ciphertext(input.substr(kIvSize, - input.size() - (kIvSize + kHashSize))); - std::string hash(input.substr(input.size() - kHashSize, kHashSize)); - - std::string raw_mac_key; - if (!mac_key_->GetRawKey(&raw_mac_key)) - return false; - - HMAC hmac(HMAC::SHA256); - if (!hmac.Init(raw_mac_key)) - return false; - - std::vector<unsigned char> expected(kHashSize); - if (!hmac.Sign(ciphertext, &expected[0], expected.size())) - return false; - - if (hash.compare(0, hash.size(), - reinterpret_cast<char *>(&expected[0]), - expected.size())) - return false; - - Encryptor encryptor; - if (!encryptor.Init(encryption_key_.get(), Encryptor::CBC, iv)) - return false; - - if (!encryptor.Decrypt(ciphertext, value)) - return false; - - return true; -} - -bool Nigori::ExportKeys(std::string* user_key, - std::string* encryption_key, - std::string* mac_key) const { - DCHECK(user_key); - DCHECK(encryption_key); - DCHECK(mac_key); - - return user_key_->GetRawKey(user_key) && - encryption_key_->GetRawKey(encryption_key) && - mac_key_->GetRawKey(mac_key); -} - -} // namespace syncer |