// Copyright (c) 2011 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 "crypto/symmetric_key.h"

#include <winsock2.h>  // For htonl.

#include <vector>

// TODO(wtc): replace scoped_array by std::vector.
#include "base/memory/scoped_ptr.h"

namespace crypto {

namespace {

// The following is a non-public Microsoft header documented in MSDN under
// CryptImportKey / CryptExportKey. Following the header is the byte array of
// the actual plaintext key.
struct PlaintextBlobHeader {
  BLOBHEADER hdr;
  DWORD cbKeySize;
};

// CryptoAPI makes use of three distinct ALG_IDs for AES, rather than just
// CALG_AES (which exists, but depending on the functions you are calling, may
// result in function failure, whereas the subtype would succeed).
ALG_ID GetAESAlgIDForKeySize(size_t key_size_in_bits) {
  // Only AES-128/-192/-256 is supported in CryptoAPI.
  switch (key_size_in_bits) {
    case 128:
      return CALG_AES_128;
    case 192:
      return CALG_AES_192;
    case 256:
      return CALG_AES_256;
    default:
      NOTREACHED();
      return 0;
  }
};

// Imports a raw/plaintext key of |key_size| stored in |*key_data| into a new
// key created for the specified |provider|. |alg| contains the algorithm of
// the key being imported.
// If |key_data| is intended to be used as an HMAC key, then |alg| should be
// CALG_HMAC.
// If successful, returns true and stores the imported key in |*key|.
// TODO(wtc): use this function in hmac_win.cc.
bool ImportRawKey(HCRYPTPROV provider,
                  ALG_ID alg,
                  const void* key_data, DWORD key_size,
                  ScopedHCRYPTKEY* key) {
  DCHECK_GT(key_size, 0);

  DWORD actual_size = sizeof(PlaintextBlobHeader) + key_size;
  std::vector<BYTE> tmp_data(actual_size);
  BYTE* actual_key = &tmp_data[0];
  memcpy(actual_key + sizeof(PlaintextBlobHeader), key_data, key_size);
  PlaintextBlobHeader* key_header =
      reinterpret_cast<PlaintextBlobHeader*>(actual_key);
  memset(key_header, 0, sizeof(PlaintextBlobHeader));

  key_header->hdr.bType = PLAINTEXTKEYBLOB;
  key_header->hdr.bVersion = CUR_BLOB_VERSION;
  key_header->hdr.aiKeyAlg = alg;

  key_header->cbKeySize = key_size;

  HCRYPTKEY unsafe_key = NULL;
  DWORD flags = CRYPT_EXPORTABLE;
  if (alg == CALG_HMAC) {
    // Though it may appear odd that IPSEC and RC2 are being used, this is
    // done in accordance with Microsoft's FIPS 140-2 Security Policy for the
    // RSA Enhanced Provider, as the approved means of using arbitrary HMAC
    // key material.
    key_header->hdr.aiKeyAlg = CALG_RC2;
    flags |= CRYPT_IPSEC_HMAC_KEY;
  }

  BOOL ok =
      CryptImportKey(provider, actual_key, actual_size, 0, flags, &unsafe_key);

  // Clean up the temporary copy of key, regardless of whether it was imported
  // sucessfully or not.
  SecureZeroMemory(actual_key, actual_size);

  if (!ok)
    return false;

  key->reset(unsafe_key);
  return true;
}

// Attempts to generate a random AES key of |key_size_in_bits|. Returns true
// if generation is successful, storing the generated key in |*key| and the
// key provider (CSP) in |*provider|.
bool GenerateAESKey(size_t key_size_in_bits,
                    ScopedHCRYPTPROV* provider,
                    ScopedHCRYPTKEY* key) {
  DCHECK(provider);
  DCHECK(key);

  ALG_ID alg = GetAESAlgIDForKeySize(key_size_in_bits);
  if (alg == 0)
    return false;

  ScopedHCRYPTPROV safe_provider;
  // Note: The only time NULL is safe to be passed as pszContainer is when
  // dwFlags contains CRYPT_VERIFYCONTEXT, as all keys generated and/or used
  // will be treated as ephemeral keys and not persisted.
  BOOL ok = CryptAcquireContext(safe_provider.receive(), NULL, NULL,
                                PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
  if (!ok)
    return false;

  ScopedHCRYPTKEY safe_key;
  // In the FIPS 140-2 Security Policy for CAPI on XP/Vista+, Microsoft notes
  // that CryptGenKey makes use of the same functionality exposed via
  // CryptGenRandom. The reason this is being used, as opposed to
  // CryptGenRandom and CryptImportKey is for compliance with the security
  // policy
  ok = CryptGenKey(safe_provider.get(), alg, CRYPT_EXPORTABLE,
                   safe_key.receive());
  if (!ok)
    return false;

  key->swap(safe_key);
  provider->swap(safe_provider);

  return true;
}

// Returns true if the HMAC key size meets the requirement of FIPS 198
// Section 3.  |alg| is the hash function used in the HMAC.
bool CheckHMACKeySize(size_t key_size_in_bits, ALG_ID alg) {
  DWORD hash_size = 0;
  switch (alg) {
    case CALG_SHA1:
      hash_size = 20;
      break;
    case CALG_SHA_256:
      hash_size = 32;
      break;
    case CALG_SHA_384:
      hash_size = 48;
      break;
    case CALG_SHA_512:
      hash_size = 64;
      break;
  }
  if (hash_size == 0)
    return false;

  // An HMAC key must be >= L/2, where L is the output size of the hash
  // function being used.
  return (key_size_in_bits >= (hash_size / 2 * 8) &&
         (key_size_in_bits % 8) == 0);
}

// Attempts to generate a random, |key_size_in_bits|-long HMAC key, for use
// with the hash function |alg|.
// |key_size_in_bits| must be >= 1/2 the hash size of |alg| for security.
// Returns true if generation is successful, storing the generated key in
// |*key| and the key provider (CSP) in |*provider|.
bool GenerateHMACKey(size_t key_size_in_bits,
                     ALG_ID alg,
                     ScopedHCRYPTPROV* provider,
                     ScopedHCRYPTKEY* key,
                     scoped_array<BYTE>* raw_key) {
  DCHECK(provider);
  DCHECK(key);
  DCHECK(raw_key);

  if (!CheckHMACKeySize(key_size_in_bits, alg))
    return false;

  ScopedHCRYPTPROV safe_provider;
  // See comment in GenerateAESKey as to why NULL is acceptable for the
  // container name.
  BOOL ok = CryptAcquireContext(safe_provider.receive(), NULL, NULL,
                                PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
  if (!ok)
    return false;

  DWORD key_size_in_bytes = key_size_in_bits / 8;
  scoped_array<BYTE> random(new BYTE[key_size_in_bytes]);
  ok = CryptGenRandom(safe_provider, key_size_in_bytes, random.get());
  if (!ok)
    return false;

  ScopedHCRYPTKEY safe_key;
  bool rv = ImportRawKey(safe_provider, CALG_HMAC, random.get(),
                         key_size_in_bytes, &safe_key);
  if (rv) {
    key->swap(safe_key);
    provider->swap(safe_provider);
    raw_key->swap(random);
  }

  SecureZeroMemory(random.get(), key_size_in_bytes);
  return rv;
}

// Attempts to create an HMAC hash instance using the specified |provider|
// and |key|. The inner hash function will be |hash_alg|. If successful,
// returns true and stores the hash in |*hash|.
// TODO(wtc): use this function in hmac_win.cc.
bool CreateHMACHash(HCRYPTPROV provider,
                    HCRYPTKEY key,
                    ALG_ID hash_alg,
                    ScopedHCRYPTHASH* hash) {
  ScopedHCRYPTHASH safe_hash;
  BOOL ok = CryptCreateHash(provider, CALG_HMAC, key, 0, safe_hash.receive());
  if (!ok)
    return false;

  HMAC_INFO hmac_info;
  memset(&hmac_info, 0, sizeof(hmac_info));
  hmac_info.HashAlgid = hash_alg;

  ok = CryptSetHashParam(safe_hash, HP_HMAC_INFO,
                         reinterpret_cast<const BYTE*>(&hmac_info), 0);
  if (!ok)
    return false;

  hash->swap(safe_hash);
  return true;
}

// Computes a block of the derived key using the PBKDF2 function F for the
// specified |block_index| using the PRF |hash|, writing the output to
// |output_buf|.
// |output_buf| must have enough space to accomodate the output of the PRF
// specified by |hash|.
// Returns true if the block was successfully computed.
bool ComputePBKDF2Block(HCRYPTHASH hash,
                        DWORD hash_size,
                        const std::string& salt,
                        size_t iterations,
                        uint32 block_index,
                        BYTE* output_buf) {
  // From RFC 2898:
  // 3. <snip> The function F is defined as the exclusive-or sum of the first
  //    c iterates of the underlying pseudorandom function PRF applied to the
  //    password P and the concatenation of the salt S and the block index i:
  //      F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c
  //    where
  //      U_1 = PRF(P, S || INT (i))
  //      U_2 = PRF(P, U_1)
  //      ...
  //      U_c = PRF(P, U_{c-1})
  ScopedHCRYPTHASH safe_hash;
  BOOL ok = CryptDuplicateHash(hash, NULL, 0, safe_hash.receive());
  if (!ok)
    return false;

  // Iteration U_1: Compute PRF for S.
  ok = CryptHashData(safe_hash, reinterpret_cast<const BYTE*>(salt.data()),
                     salt.size(), 0);
  if (!ok)
    return false;

  // Iteration U_1: and append (big-endian) INT (i).
  uint32 big_endian_block_index = htonl(block_index);
  ok = CryptHashData(safe_hash,
                     reinterpret_cast<BYTE*>(&big_endian_block_index),
                     sizeof(big_endian_block_index), 0);

  std::vector<BYTE> hash_value(hash_size);

  DWORD size = hash_size;
  ok = CryptGetHashParam(safe_hash, HP_HASHVAL, &hash_value[0], &size, 0);
  if (!ok  || size != hash_size)
    return false;

  memcpy(output_buf, &hash_value[0], hash_size);

  // Iteration 2 - c: Compute U_{iteration} by applying the PRF to
  // U_{iteration - 1}, then xor the resultant hash with |output|, which
  // contains U_1 ^ U_2 ^ ... ^ U_{iteration - 1}.
  for (size_t iteration = 2; iteration <= iterations; ++iteration) {
    safe_hash.reset();
    ok = CryptDuplicateHash(hash, NULL, 0, safe_hash.receive());
    if (!ok)
      return false;

    ok = CryptHashData(safe_hash, &hash_value[0], hash_size, 0);
    if (!ok)
      return false;

    size = hash_size;
    ok = CryptGetHashParam(safe_hash, HP_HASHVAL, &hash_value[0], &size, 0);
    if (!ok || size != hash_size)
      return false;

    for (int i = 0; i < hash_size; ++i)
      output_buf[i] ^= hash_value[i];
  }

  return true;
}

}  // namespace

SymmetricKey::~SymmetricKey() {
  // TODO(wtc): create a "secure" string type that zeroes itself in the
  // destructor.
  if (!raw_key_.empty())
    SecureZeroMemory(const_cast<char *>(raw_key_.data()), raw_key_.size());
}

// static
SymmetricKey* SymmetricKey::GenerateRandomKey(Algorithm algorithm,
                                              size_t key_size_in_bits) {
  DCHECK_GE(key_size_in_bits, 8);

  ScopedHCRYPTPROV provider;
  ScopedHCRYPTKEY key;

  bool ok = false;
  scoped_array<BYTE> raw_key;

  switch (algorithm) {
    case AES:
      ok = GenerateAESKey(key_size_in_bits, &provider, &key);
      break;
    case HMAC_SHA1:
      ok = GenerateHMACKey(key_size_in_bits, CALG_SHA1, &provider,
                           &key, &raw_key);
      break;
  }

  if (!ok) {
    NOTREACHED();
    return NULL;
  }

  size_t key_size_in_bytes = key_size_in_bits / 8;
  if (raw_key == NULL)
    key_size_in_bytes = 0;

  SymmetricKey* result = new SymmetricKey(provider.release(),
                                          key.release(),
                                          raw_key.get(),
                                          key_size_in_bytes);
  if (raw_key != NULL)
    SecureZeroMemory(raw_key.get(), key_size_in_bytes);

  return result;
}

// static
SymmetricKey* SymmetricKey::DeriveKeyFromPassword(Algorithm algorithm,
                                                  const std::string& password,
                                                  const std::string& salt,
                                                  size_t iterations,
                                                  size_t key_size_in_bits) {
  // CryptoAPI lacks routines to perform PBKDF2 derivation as specified
  // in RFC 2898, so it must be manually implemented. Only HMAC-SHA1 is
  // supported as the PRF.

  // While not used until the end, sanity-check the input before proceeding
  // with the expensive computation.
  DWORD provider_type = 0;
  ALG_ID alg = 0;
  switch (algorithm) {
    case AES:
      provider_type = PROV_RSA_AES;
      alg = GetAESAlgIDForKeySize(key_size_in_bits);
      break;
    case HMAC_SHA1:
      provider_type = PROV_RSA_FULL;
      alg = CALG_HMAC;
      break;
    default:
      NOTREACHED();
      break;
  }
  if (provider_type == 0 || alg == 0)
    return NULL;

  ScopedHCRYPTPROV provider;
  BOOL ok = CryptAcquireContext(provider.receive(), NULL, NULL, provider_type,
                                CRYPT_VERIFYCONTEXT);
  if (!ok)
    return NULL;

  // Convert the user password into a key suitable to be fed into the PRF
  // function.
  ScopedHCRYPTKEY password_as_key;
  BYTE* password_as_bytes =
      const_cast<BYTE*>(reinterpret_cast<const BYTE*>(password.data()));
  if (!ImportRawKey(provider, CALG_HMAC, password_as_bytes,
                    password.size(), &password_as_key))
    return NULL;

  // Configure the PRF function. Only HMAC variants are supported, with the
  // only hash function supported being SHA1.
  // TODO(rsleevi): Support SHA-256 on XP SP3+.
  ScopedHCRYPTHASH prf;
  if (!CreateHMACHash(provider, password_as_key, CALG_SHA1, &prf))
    return NULL;

  DWORD hLen = 0;
  DWORD param_size = sizeof(hLen);
  ok = CryptGetHashParam(prf, HP_HASHSIZE,
                         reinterpret_cast<BYTE*>(&hLen), &param_size, 0);
  if (!ok || hLen == 0)
    return NULL;

  // 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and stop.
  size_t dkLen = key_size_in_bits / 8;
  DCHECK_GT(dkLen, 0);

  if ((dkLen / hLen) > 0xFFFFFFFF) {
    DLOG(ERROR) << "Derived key too long.";
    return NULL;
  }

  // 2. Let l be the number of hLen-octet blocks in the derived key,
  //    rounding up, and let r be the number of octets in the last
  //    block:
  size_t L = (dkLen + hLen - 1) / hLen;
  DCHECK_GT(L, 0);

  size_t total_generated_size = L * hLen;
  std::vector<BYTE> generated_key(total_generated_size);
  BYTE* block_offset = &generated_key[0];

  // 3. For each block of the derived key apply the function F defined below
  //    to the password P, the salt S, the iteration count c, and the block
  //    index to compute the block:
  //    T_1 = F (P, S, c, 1)
  //    T_2 = F (P, S, c, 2)
  //    ...
  //    T_l = F (P, S, c, l)
  // <snip>
  // 4. Concatenate the blocks and extract the first dkLen octets to produce
  //    a derived key DK:
  //    DK = T_1 || T_2 || ... || T_l<0..r-1>
  for (uint32 block_index = 1; block_index <= L; ++block_index) {
    if (!ComputePBKDF2Block(prf, hLen, salt, iterations, block_index,
                            block_offset))
        return NULL;
    block_offset += hLen;
  }

  // Convert the derived key bytes into a key handle for the desired algorithm.
  ScopedHCRYPTKEY key;
  if (!ImportRawKey(provider, alg, &generated_key[0], dkLen, &key))
    return NULL;

  SymmetricKey* result = new SymmetricKey(provider.release(), key.release(),
                                          &generated_key[0], dkLen);

  SecureZeroMemory(&generated_key[0], total_generated_size);

  return result;
}

// static
SymmetricKey* SymmetricKey::Import(Algorithm algorithm,
                                   const std::string& raw_key) {
  DWORD provider_type = 0;
  ALG_ID alg = 0;
  switch (algorithm) {
    case AES:
      provider_type = PROV_RSA_AES;
      alg = GetAESAlgIDForKeySize(raw_key.size() * 8);
      break;
    case HMAC_SHA1:
      provider_type = PROV_RSA_FULL;
      alg = CALG_HMAC;
      break;
    default:
      NOTREACHED();
      break;
  }
  if (provider_type == 0 || alg == 0)
    return NULL;

  ScopedHCRYPTPROV provider;
  BOOL ok = CryptAcquireContext(provider.receive(), NULL, NULL, provider_type,
                                CRYPT_VERIFYCONTEXT);
  if (!ok)
    return NULL;

  ScopedHCRYPTKEY key;
  if (!ImportRawKey(provider, alg, raw_key.data(), raw_key.size(), &key))
    return NULL;

  return new SymmetricKey(provider.release(), key.release(),
                          raw_key.data(), raw_key.size());
}

bool SymmetricKey::GetRawKey(std::string* raw_key) {
  // Short circuit for when the key was supplied to the constructor.
  if (!raw_key_.empty()) {
    *raw_key = raw_key_;
    return true;
  }

  DWORD size = 0;
  BOOL ok = CryptExportKey(key_, 0, PLAINTEXTKEYBLOB, 0, NULL, &size);
  if (!ok)
    return false;

  std::vector<BYTE> result(size);

  ok = CryptExportKey(key_, 0, PLAINTEXTKEYBLOB, 0, &result[0], &size);
  if (!ok)
    return false;

  PlaintextBlobHeader* header =
      reinterpret_cast<PlaintextBlobHeader*>(&result[0]);
  raw_key->assign(reinterpret_cast<char*>(&result[sizeof(*header)]),
                  header->cbKeySize);

  SecureZeroMemory(&result[0], size);

  return true;
}

SymmetricKey::SymmetricKey(HCRYPTPROV provider,
                           HCRYPTKEY key,
                           const void* key_data, size_t key_size_in_bytes)
    : provider_(provider), key_(key) {
  if (key_data) {
    raw_key_.assign(reinterpret_cast<const char*>(key_data),
                    key_size_in_bytes);
  }
}

}  // namespace crypto
