// Copyright 2010-2014, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "base/encryptor.h"

#if defined(OS_WIN)
#include <windows.h>
#include <wincrypt.h>
#elif defined(OS_MACOSX)
#include <unistd.h>
#include <sys/types.h>
#else
#include <string.h>
#endif  // platforms (OS_WIN, OS_MACOSX, ...)

#include "base/logging.h"
#include "base/password_manager.h"
#include "base/unverified_aes256.h"
#include "base/unverified_sha1.h"
#include "base/util.h"

#ifdef OS_MACOSX
#include "base/mac_util.h"
#endif  // OS_MACOSX

using ::mozc::internal::UnverifiedSHA1;

namespace mozc {
namespace {

// By using SHA1, emulate Microsoft's CryptDerivePassword API
// http://msdn.microsoft.com/en-us/library/aa379916.aspx
// says:
// Let n be the required derived key length, in bytes.
// The derived key is the first n bytes of the hash value after
// the hash computation has been completed by CryptDeriveKey.
// If the hash is not a member of the SHA-2 family and the required key
// is for either 3DES or AES, the key is derived as follows:
//
// 1. Form a 64-byte buffer by repeating the constant 0x36 64 times.
//    Let k be the length of the hash value that is represented by
//    the input parameter hBaseData. Set the first k bytes of the
//    buffer to the result of an XOR operation of the first k bytes
//    of the buffer with the hash value that is represented by the
//    input parameter hBaseData.
// 2. Form a 64-byte buffer by repeating the constant 0x5C 64 times.
//    Set the first k bytes of the buffer to the result of an XOR
//    operation of the first k bytes of the buffer with the hash
//    value that is represented by the input parameter hBaseData.
// 3. Hash the result of step 1 by using the same hash algorithm
//    as that used to compute the hash value that is represented
//     by the hBaseData parameter.
// 4. Hash the result of step 2 by using the same hash algorithm as
//    that used to compute the hash value that is represented by the
//    hBaseData parameter.
// 5. Concatenate the result of step 3 with the result of step 4.
// 6. Use the first n bytes of the result of step 5 as the derived key.
string GetMSCryptDeriveKeyWithSHA1(const string &password,
                                   const string &salt) {
  uint8 buf1[64];
  uint8 buf2[64];

  // Step1.
  memset(buf1, 0x36, sizeof(buf1));

  // Step2.
  memset(buf2, 0x5c, sizeof(buf2));

  // Step 3 & 4
  const string hash = UnverifiedSHA1::MakeDigest(password + salt);
  for (size_t i = 0; i < hash.size(); ++i) {
    buf1[i] ^= static_cast<uint8>(hash[i]);
    buf2[i] ^= static_cast<uint8>(hash[i]);
  }

  // Step 5 & 6
  const string result1(reinterpret_cast<const char *>(buf1), sizeof(buf1));
  const string result2(reinterpret_cast<const char *>(buf2), sizeof(buf2));

  return (UnverifiedSHA1::MakeDigest(result1) +
          UnverifiedSHA1::MakeDigest(result2));
}

const size_t kBlockSize = 16;  // 128 bit
const size_t kKeySize = 32;   // 256 bit key length

}  // namespace

// TODO(yukawa): Consider to maintain these data directly in Encryptor::Key or
// completely rewrite Encryptor::Key once encryptor_legacy.cc is deprecated.
struct Encryptor::Key::InternalData {
  uint8 key[kKeySize];
  uint8 iv[kBlockSize];
  bool is_available;

  InternalData()
      : is_available(false) {
    memset(key, '\0', arraysize(key));
    memset(iv, '\0', arraysize(iv));
  }
};

size_t Encryptor::Key::block_size() const {
  return kBlockSize;
}

const uint8 *Encryptor::Key::iv() const {
  return data_->iv;
}

size_t Encryptor::Key::iv_size() const {
  return kBlockSize;   // the same as block size
}

size_t Encryptor::Key::key_size() const {
  return kKeySize * 8;
}

bool Encryptor::Key::IsAvailable() const {
  return data_->is_available;
}

size_t Encryptor::Key::GetEncryptedSize(size_t size) const {
  // Even when given size is already multples of 16, we add
  // an extra block_size as a padding.
  // The extra padding can allow us to know that the message decrypted
  // is invalid or broken.
  return (size / block_size() + 1) * block_size();
}

bool Encryptor::Key::DeriveFromPassword(const string &password,
                                        const string &salt,
                                        const uint8 *iv) {
  if (IsAvailable()) {
    LOG(WARNING) << "key is already set";
    return false;
  }

  if (password.empty()) {
    LOG(WARNING) << "password is empty";
    return false;
  }

  if (iv != NULL) {
    memcpy(data_->iv, iv, iv_size());
  } else {
    memset(data_->iv, '\0', iv_size());
  }

  const string key = GetMSCryptDeriveKeyWithSHA1(password, salt);
  DCHECK_EQ(40, key.size());   // SHA1 is 160bit hash, so 160*2/8 = 40byte

  // Store the session key.
  // NOTE: key_size() returns size in bit for historical reasons.
  memcpy(data_->key, key.data(), key_size() / 8);

  data_->is_available = true;

  return true;
}

Encryptor::Key::Key()
    : data_(new Encryptor::Key::InternalData) {
}

Encryptor::Key::~Key() {
}

bool Encryptor::EncryptString(const Encryptor::Key &key, string *data) {
  if (data == NULL || data->empty()) {
    LOG(ERROR) << "data is NULL or empty";
    return false;
  }
  size_t size = data->size();
  scoped_ptr<char[]> buf(new char[key.GetEncryptedSize(data->size())]);
  memcpy(buf.get(), data->data(), data->size());
  if (!Encryptor::EncryptArray(key, buf.get(), &size)) {
    LOG(ERROR) << "EncryptArray() failed";
    return false;
  }
  data->assign(buf.get(), size);
  return true;
}

bool Encryptor::DecryptString(const Encryptor::Key &key, string *data) {
  if (data == NULL || data->empty()) {
    LOG(ERROR) << "data is NULL or empty";
    return false;
  }
  size_t size = data->size();
  scoped_ptr<char[]> buf(new char[data->size()]);
  memcpy(buf.get(), data->data(), data->size());
  if (!Encryptor::DecryptArray(key, buf.get(), &size)) {
    LOG(ERROR) << "DecryptArray() failed";
    return false;
  }
  data->assign(buf.get(), size);
  return true;
}

bool Encryptor::EncryptArray(const Encryptor::Key &key,
                             char *buf, size_t *buf_size) {
  if (!key.IsAvailable()) {
    LOG(ERROR) << "key is not available";
    return false;
  }

  if (buf == NULL || buf_size == NULL || *buf_size == 0) {
    LOG(ERROR) << "invalid buffer given";
    return false;
  }

  const size_t enc_size = key.GetEncryptedSize(*buf_size);

  // perform PKCS#5 padding
  const size_t padding_size = enc_size - *buf_size;
  const uint8 padding_value = static_cast<uint8>(padding_size);
  for (size_t i = *buf_size; i < enc_size; ++i) {
    buf[i] = static_cast<char>(padding_value);
  }

  // For historical reasons, we are using AES256/CBC for obfuscation.
  internal::UnverifiedAES256::TransformCBC(key.data_->key,
                                           key.data_->iv,
                                           reinterpret_cast<uint8 *>(buf),
                                           enc_size / kBlockSize);
  *buf_size = enc_size;
  return true;
}

bool Encryptor::DecryptArray(const Encryptor::Key &key,
                             char *buf, size_t *buf_size) {
  if (!key.IsAvailable()) {
    LOG(ERROR) << "key is not available";
    return false;
  }

  if (buf == NULL || buf_size == NULL || *buf_size == 0) {
    LOG(ERROR) << "invalid buffer given";
    return false;
  }

  if (*buf_size < key.block_size() || *buf_size % key.block_size() != 0) {
    LOG(ERROR) << "buf size is not multiples of " << key.block_size();
    return false;
  }

  size_t size = *buf_size;

  // For historical reasons, we are using AES256/CBC for obfuscation.
  internal::UnverifiedAES256::InverseTransformCBC(
      key.data_->key,
      key.data_->iv,
      reinterpret_cast<uint8 *>(buf),
      size / kBlockSize);

  // perform PKCS#5 un-padding
  // see. http://www.chilkatsoft.com/faq/PKCS5_Padding.html
  const uint8 padding_value = static_cast<uint8>(buf[size - 1]);
  const size_t padding_size = static_cast<size_t>(padding_value);
  if (padding_value == 0x00 || padding_value > kBlockSize) {
    LOG(ERROR) << "Cannot find PKCS#5 padding values: ";
    return false;
  }

  if (size <= padding_size) {
    LOG(ERROR) << "padding size is no smaller than original message";
    return false;
  }

  for (size_t i = size - padding_size; i < size; ++i) {
    if (static_cast<uint8>(buf[i]) != padding_value) {
      LOG(ERROR) << "invalid padding value. message is broken";
      return false;
    }
  }
  *buf_size -= padding_size;   // remove padding part
  return true;
}

// Protect|Unprotect Data
#ifdef OS_WIN
// See. http://msdn.microsoft.com/en-us/library/aa380261.aspx
bool Encryptor::ProtectData(const string &plain_text,
                            string *cipher_text) {
  DCHECK(cipher_text);
  DATA_BLOB input;
  input.pbData = const_cast<BYTE *>(
      reinterpret_cast<const BYTE *>(plain_text.data()));
  input.cbData = static_cast<DWORD>(plain_text.size());

  DATA_BLOB output;
  const BOOL result = ::CryptProtectData(&input, L"",
                                         NULL, NULL, NULL,
                                         CRYPTPROTECT_UI_FORBIDDEN,
                                         &output);
  if (!result) {
    LOG(ERROR) << "CryptProtectData failed: " << ::GetLastError();
    return false;
  }

  cipher_text->assign(reinterpret_cast<char *>(output.pbData),
                      output.cbData);

  ::LocalFree(output.pbData);

  return true;
}

// See. http://msdn.microsoft.com/en-us/library/aa380882(VS.85).aspx
bool Encryptor::UnprotectData(const string &cipher_text,
                              string *plain_text) {
  DCHECK(plain_text);
  DATA_BLOB input;
  input.pbData = const_cast<BYTE *>(
      reinterpret_cast<const BYTE*>(cipher_text.data()));
  input.cbData = static_cast<DWORD>(cipher_text.length());

  DATA_BLOB output;
  const BOOL result = ::CryptUnprotectData(&input,
                                           NULL, NULL, NULL, NULL,
                                           CRYPTPROTECT_UI_FORBIDDEN,
                                           &output);
  if (!result) {
    LOG(ERROR) << "CryptUnprotectData failed: " << ::GetLastError();
    return false;
  }

  plain_text->assign(reinterpret_cast<char *>(output.pbData), output.cbData);

  ::LocalFree(output.pbData);

  return true;
}

#elif defined(OS_MACOSX)

// ProtectData for Mac uses the serial number and the current pid as the key.
bool Encryptor::ProtectData(const string &plain_text,
                            string *cipher_text) {
  DCHECK(cipher_text);
  Encryptor::Key key;
  const string serial_number = MacUtil::GetSerialNumber();
  const string salt = Util::StringPrintf("%x", ::getuid());
  if (serial_number.empty()) {
    LOG(ERROR) << "Cannot get the serial number";
    return false;
  }
  if (!key.DeriveFromPassword(serial_number, salt)) {
    LOG(ERROR) << "Cannot prepare the internal key";
    return false;
  }

  cipher_text->assign(plain_text);
  if (!EncryptString(key, cipher_text)) {
    cipher_text->clear();
    LOG(ERROR) << "Cannot encrypt the text";
    return false;
  }
  return true;
}

// Same as ProtectData.
bool Encryptor::UnprotectData(const string &cipher_text,
                              string *plain_text) {
  DCHECK(plain_text);
  Encryptor::Key key;
  const string serial_number = MacUtil::GetSerialNumber();
  const string salt = Util::StringPrintf("%x", ::getuid());
  if (serial_number.empty()) {
    LOG(ERROR) << "Cannot get the serial number";
    return false;
  }
  if (!key.DeriveFromPassword(serial_number, salt)) {
    LOG(ERROR) << "Cannot prepare the internal key";
    return false;
  }

  plain_text->assign(cipher_text);
  if (!DecryptString(key, plain_text)) {
    plain_text->clear();
    LOG(ERROR) << "Cannot encrypt the text";
    return false;
  }
  return true;
}

#else  // OS_WIN | OS_MACOSX

namespace {

const size_t kSaltSize = 32;

}  // namespace

// Use AES to emulate ProtectData
bool Encryptor::ProtectData(const string &plain_text, string *cipher_text) {
  string password;
  if (!PasswordManager::GetPassword(&password)) {
    LOG(ERROR) << "Cannot get password";
    return false;
  }

  char salt_buf[kSaltSize];
  Util::GetRandomSequence(salt_buf, sizeof(salt_buf));

  string salt(salt_buf, kSaltSize);

  Encryptor::Key key;
  if (!key.DeriveFromPassword(password, salt)) {
    LOG(ERROR) << "DeriveFromPassword failed";
    return false;
  }

  string buf = plain_text;
  if (!Encryptor::EncryptString(key, &buf)) {
    LOG(ERROR) << "Encryptor::EncryptString failed";
    return false;
  }

  cipher_text->clear();
  *cipher_text += salt;
  *cipher_text += buf;

  return true;
}

// Use AES to emulate UnprotectData
bool Encryptor::UnprotectData(const string &cipher_text, string *plain_text) {
  if (cipher_text.size() < kSaltSize) {
    LOG(ERROR) << "encrypted message is too short";
    return false;
  }

  string password;
  if (!PasswordManager::GetPassword(&password)) {
    LOG(ERROR) << "Cannot get password";
    return false;
  }

  const string salt(cipher_text.data(), kSaltSize);

  Encryptor::Key key;
  if (!key.DeriveFromPassword(password, salt)) {
    LOG(ERROR) << "DeriveFromPassword failed";
    return false;
  }

  string buf(cipher_text.data() + kSaltSize,
             cipher_text.size() - kSaltSize);

  if (!Encryptor::DecryptString(key, &buf)) {
    LOG(ERROR) << "Encryptor::DecryptString failed";
    return false;
  }

  plain_text->clear();
  *plain_text += buf;

  return true;
}
#endif  // OS_WIN

}  // namespace mozc
