// Copyright (c) 2009-2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Crypto - class for handling the keyset key management functions relating to
// cryptohome.  This includes wrapping/unwrapping the vault keyset (and
// supporting functions) and setting/clearing the user keyring for use with
// ecryptfs.

#ifndef CRYPTOHOME_CRYPTO_H_
#define CRYPTOHOME_CRYPTO_H_

#include <base/basictypes.h>
#include <base/file_path.h>

#include "secure_blob.h"
#include "tpm.h"
#include "vault_keyset.h"
#include "vault_keyset.pb.h"

namespace cryptohome {

// Default number of hash rounds to use when generating  key from a password
extern const unsigned int kDefaultPasswordRounds;

class Crypto : public EntropySource {
 public:

  // PaddingScheme dictates the padding at the end of the ciphertext:
  //   kPaddingNone - Do not use padding.  The input plaintext must be a
  //     multiple of the crypto algorithm's block size.  This is used in the
  //     encryption of the vault keyset as described in the Protection
  //     Mechanisms section of the README file.
  //   kPaddingLibraryDefault - Use OpenSSL default padding (PKCS#5), which
  //     allows the plaintext to be marginally verified on decrypt, and
  //     automatically handles plaintext that is not a multiple of the block
  //     size.
  //   kPaddingCryptohomeDefault - The default padding, which adds a SHA1 hash
  //     to the end of the plaintext before encryption so that the contents can
  //     be verified.
  enum PaddingScheme {
    kPaddingNone = 0,
    kPaddingLibraryDefault = 1,
    kPaddingCryptohomeDefault = 2,
  };

  enum BlockMode {
    kEcb = 1,
    kCbc = 2,
  };

  enum CryptoError {
    CE_NONE = 0,
    CE_TPM_FATAL,
    CE_TPM_COMM_ERROR,
    CE_TPM_DEFEND_LOCK,
    CE_TPM_CRYPTO,
    CE_SCRYPT_CRYPTO,
    CE_OTHER_FATAL,
    CE_OTHER_CRYPTO,
    CE_NO_PUBLIC_KEY_HASH,
  };

  // Default constructor
  Crypto();

  virtual ~Crypto();

  // Initializes Crypto
  bool Init();

  // Returns random bytes of the given length using OpenSSL's random number
  // generator.  The random number generator is automatically seeded from
  // /dev/urandom by OpenSSL.
  //
  // Parameters
  //   rand (OUT) - Where to store the random bytes
  //   length - The number of random bytes to store in rand
  void GetSecureRandom(unsigned char* rand, unsigned int length) const;

  // Gets the AES block size
  unsigned int GetAesBlockSize() const;

  // AES decrypts the wrapped blob
  //
  // Parameters
  //   wrapped - The blob containing the encrypted data
  //   start - The position in the blob to start with
  //   count - The count of bytes to decrypt
  //   key - The AES key to use in decryption
  //   iv - The initialization vector to use
  //   padding - The padding method to use
  //   unwrapped (OUT) - The unwrapped (decrypted) data
  bool AesDecrypt(const chromeos::Blob& wrapped, unsigned int start,
                  unsigned int count, const SecureBlob& key,
                  const SecureBlob& iv, PaddingScheme padding,
                  SecureBlob* unwrapped) const;

  // AES encrypts the plain text data using the specified key
  //
  // Parameters
  //   unwrapped - The plain text data to encrypt
  //   start - The position in the blob to start with
  //   count - The count of bytes to encrypt
  //   key - The AES key to use
  //   iv - The initialization vector to use
  //   padding - The padding method to use
  //   wrapped - On success, the encrypted data
  bool AesEncrypt(const chromeos::Blob& unwrapped, unsigned int start,
                  unsigned int count, const SecureBlob& key,
                  const SecureBlob& iv, PaddingScheme padding,
                  SecureBlob* wrapped) const;

  // Same as AesDecrypt, but allows using either CBC or ECB
  bool AesDecryptSpecifyBlockMode(const chromeos::Blob& wrapped,
                                  unsigned int start, unsigned int count,
                                  const SecureBlob& key, const SecureBlob& iv,
                                  PaddingScheme padding, BlockMode block_mode,
                                  SecureBlob* unwrapped) const;

  // Same as AesEncrypt, but allows using either CBC or ECB
  bool AesEncryptSpecifyBlockMode(const chromeos::Blob& unwrapped,
                                  unsigned int start, unsigned int count,
                                  const SecureBlob& key, const SecureBlob& iv,
                                  PaddingScheme padding, BlockMode block_mode,
                                  SecureBlob* wrapped) const;

  // Creates a new RSA key
  //
  // Parameters
  //   key_bits - The key size to generate
  //   n (OUT) - the modulus
  //   p (OUT) - the private key
  bool CreateRsaKey(unsigned int key_bits, SecureBlob* n, SecureBlob* p) const;

  // Decrypts an encrypted vault keyset.  The vault keyset should be the output
  // of EncryptVaultKeyset().
  //
  // Parameters
  //   encrypted_keyset - The blob containing the encrypted keyset
  //   vault_key - The passkey used to decrypt the keyset
  //   crypt_flags (OUT) - Whether the keyset was wrapped by the TPM or scrypt
  //   error (OUT) - The specific error code on failure
  //   vault_keyset (OUT) - The decrypted vault keyset on success
  bool DecryptVaultKeyset(const SerializedVaultKeyset& serialized,
                          const chromeos::Blob& vault_key,
                          unsigned int* crypt_flags, CryptoError* error,
                          VaultKeyset* vault_keyset) const;

  // Encrypts the vault keyset with the given passkey
  //
  // Parameters
  //   vault_keyset - The VaultKeyset to encrypt
  //   vault_key - The passkey used to encrypt the keyset
  //   vault_key_salt - The salt to use for the vault passkey to key conversion
  //                    when encrypting the keyset
  //   encrypted_keyset - On success, the encrypted vault keyset
  bool EncryptVaultKeyset(const VaultKeyset& vault_keyset,
                          const SecureBlob& vault_key,
                          const SecureBlob& vault_key_salt,
                          SerializedVaultKeyset* serialized) const;

  // Decrypts an encrypted vault keyset in the old method
  //
  // Parameters
  //   encrypted_keyset - The blob containing the encrypted keyset
  //   vault_key - The passkey used to decrypt the keyset
  //   vault_keyset (OUT) - The decrypted vault keyset on success
  bool DecryptVaultKeysetOld(const chromeos::Blob& encrypted_keyset,
                             const chromeos::Blob& vault_key,
                             VaultKeyset* vault_keyset) const;

  // Encrypts the vault keyset with the given passkey in the old method
  //
  // Parameters
  //   vault_keyset - The VaultKeyset to encrypt
  //   vault_key - The passkey used to wrap the keyset
  //   vault_key_salt - The salt to use for the vault passke to key conversion
  //                    when encrypting the keyset
  //   encrypted_keyset - On success, the encrypted vault keyset
  bool EncryptVaultKeysetOld(const VaultKeyset& vault_keyset,
                             const SecureBlob& vault_key,
                             const SecureBlob& vault_key_salt,
                             SecureBlob* encrypted_keyset) const;

  // Converts the passkey directly to an AES key.  This method derives the key
  // using the default OpenSSL conversion method.
  //
  // Parameters
  //   passkey - The passkey (hash, currently) to create the key from
  //   salt - The salt used in creating the key
  //   rounds - The number of SHA rounds to perform
  //   key (OUT) - The AES key
  //   iv (OUT) - The initialization vector
  bool PasskeyToAesKey(const chromeos::Blob& passkey,
                       const chromeos::Blob& salt, unsigned int rounds,
                       SecureBlob* key, SecureBlob* iv) const;

  // Converts the passkey to a symmetric key used to decrypt the user's
  // cryptohome key.  This method calculates a SHA1 hash of the salt and the
  // specified number of iterations on the passkey.
  //
  // Parameters
  //   passkey - The passkey (hash, currently) to create the key from
  //   salt - The salt used in creating the key
  //   iters - The hash iterations to use in generating the key
  //   wrapper (OUT) - The wrapper
  void PasskeyToKeysetKey(const chromeos::Blob& passkey,
                          const chromeos::Blob& salt, unsigned int iters,
                          SecureBlob* key) const;

  // Gets an existing salt, or creates one if it doesn't exist
  //
  // Parameters
  //   path - The path to the salt file
  //   length - The length of the new salt if it needs to be created
  //   force - If true, forces creation of a new salt even if the file exists
  //   salt (OUT) - The salt
  bool GetOrCreateSalt(const FilePath& path, unsigned int length, bool force,
                       SecureBlob* salt) const;

  // Adds the specified key to the ecryptfs keyring so that the cryptohome can
  // be mounted.  Clears the user keyring first.
  //
  // Parameters
  //   vault_keyset - The keyset to add
  //   key_signature (OUT) - The signature of the cryptohome key that should be
  //     used in subsequent calls to mount(2)
  //   filename_key_signature (OUT) - The signature of the cryptohome filename
  //     encryption key that should be used in subsequent calls to mount(2)
  bool AddKeyset(const VaultKeyset& vault_keyset,
                 std::string* key_signature,
                 std::string* filename_key_signature) const;

  // Clears the user's kernel keyring
  void ClearKeyset() const;

  // Gets the SHA1 hash of the data provided
  void GetSha1(const chromeos::Blob& data, unsigned int start,
               unsigned int count, SecureBlob* hash) const;

  // Gets the SHA256 hash of the data provided
  void GetSha256(const chromeos::Blob& data, unsigned int start,
                 unsigned int count, SecureBlob* hash) const;

  // Encodes a binary blob to hex-ascii
  //
  // Parameters
  //   blob - The binary blob to convert
  //   buffer (IN/OUT) - Where to store the converted blob
  //   buffer_length - The size of the buffer
  static void AsciiEncodeToBuffer(const chromeos::Blob& blob, char* buffer,
                                  unsigned int buffer_length);

  // Converts a null-terminated password to a passkey (ascii-encoded first half
  // of the salted SHA1 hash of the password).
  //
  // Parameters
  //   password - The password to convert
  //   salt - The salt used during hashing
  //   passkey (OUT) - The passkey
  static void PasswordToPasskey(const char* password,
                                const chromeos::Blob& salt,
                                SecureBlob* passkey);

  // Ensures that the TPM is connected
  CryptoError EnsureTpm(bool disconnect_first) const;

  // Sets whether or not to use scrypt to add a layer of protection to the vault
  // keyset when the TPM is not used
  void set_fallback_to_scrypt(bool value) {
    fallback_to_scrypt_ = value;
  }

  // Sets whether or not to use the TPM (must be called before init, depends
  // on the presence of a functioning, initialized TPM).  The TPM is merely used
  // to add a layer of difficulty in a brute-force attack against the user's
  // credentials.
  void set_use_tpm(bool value) {
    use_tpm_ = value;
  }

  // Sets whether to always load the TPM, even if it isn't used
  void set_load_tpm(bool value) {
    load_tpm_ = value;
  }

  // Sets the TPM implementation
  void set_tpm(Tpm* value) {
    tpm_ = value;
  }

  // Gets whether the TPM is set
  bool has_tpm() {
    return (tpm_ != NULL);
  }

  // Gets the TPM implementation
  const Tpm* get_tpm() {
    return tpm_;
  }

  // Checks if the TPM is connected
  bool is_tpm_connected() {
    if (tpm_ == NULL) {
      return false;
    }
    return tpm_->IsConnected();
  }

 private:
  // Converts a TPM error to a Crypto error
  CryptoError TpmErrorToCrypto(Tpm::TpmRetryAction retry_action) const;

  // Adds the specified key to the user keyring
  //
  // Parameters
  //   key - The key to add
  //   key_sig - The key's (ascii) signature
  //   salt - The salt
  bool PushVaultKey(const SecureBlob& key, const std::string& key_sig,
                           const SecureBlob& salt) const;

  // If set, the TPM will be used during the encryption of the vault keyset
  bool use_tpm_;

  // TODO(fes): Remove this when TPM becomes default or not, it is only used in
  // keyset migration.
  // If set, Crypto can process TPM-encrypted keysets, but won't default to save
  // keysets as TPM-encrypted.
  bool load_tpm_;

  // The TPM implementation
  Tpm* tpm_;

  // If set, Crypto will use scrypt to protect the vault keyset when the TPM is
  // not available for use (or turned off)
  bool fallback_to_scrypt_;

  DISALLOW_COPY_AND_ASSIGN(Crypto);
};

}  // namespace cryptohome

#endif  // CRYPTOHOME_CRYPTO_H_
