// 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 "crypto/symmetric_key.h"

#include <stddef.h>
#include <stdint.h>

#include <vector>

// TODO(wtc): replace scoped_array by std::vector.
#include "base/memory/scoped_ptr.h"
#include "base/sys_byteorder.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, size_t key_size,
                  ScopedHCRYPTKEY* key) {
  DCHECK_GT(key_size, 0u);

  DWORD actual_size =
      static_cast<DWORD>(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 = static_cast<DWORD>(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
  // successfully 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_ptr<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 = static_cast<DWORD>(key_size_in_bits / 8);
  scoped_ptr<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_t 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()),
                     static_cast<DWORD>(salt.size()), 0);
  if (!ok)
    return false;

  // Iteration U_1: and append (big-endian) INT (i).
  uint32_t big_endian_block_index = base::HostToNet32(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 (DWORD 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, 8u);

  ScopedHCRYPTPROV provider;
  ScopedHCRYPTKEY key;

  bool ok = false;
  scoped_ptr<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, 0u);

  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, 0u);

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