// Copyright 2014 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.

#ifndef TRUNKS_TPM_UTILITY_IMPL_H_
#define TRUNKS_TPM_UTILITY_IMPL_H_

#include "trunks/tpm_utility.h"

#include <functional>
#include <map>
#include <memory>
#include <string>
#include <vector>

#include <base/macros.h>
#include <brillo/secure_blob.h>
#include <gtest/gtest_prod.h>

#include "trunks/scoped_key_handle.h"
#include "trunks/trunks_export.h"

namespace trunks {

const char kWellKnownPassword[] = "cros-password";

class AuthorizationDelegate;
class TrunksFactory;

// A default implementation of TpmUtility.
class TRUNKS_EXPORT TpmUtilityImpl : public TpmUtility {
 public:
  explicit TpmUtilityImpl(const TrunksFactory& factory);
  TpmUtilityImpl(const TpmUtilityImpl&) = delete;
  TpmUtilityImpl& operator=(const TpmUtilityImpl&) = delete;

  ~TpmUtilityImpl() override;

  // TpmUtility methods.
  TPM_RC Startup() override;
  TPM_RC Clear() override;
  void Shutdown() override;
  TPM_RC CheckState() override;
  TPM_RC InitializeTpm() override;
  TPM_RC AllocatePCR(const std::string& platform_password) override;
  TPM_RC PrepareForPinWeaver() override;
  TPM_RC PrepareForOwnership() override;
  TPM_RC TakeOwnership(const std::string& owner_password,
                       const std::string& endorsement_password,
                       const std::string& lockout_password) override;
  TPM_RC StirRandom(const std::string& entropy_data,
                    AuthorizationDelegate* delegate) override;
  TPM_RC GenerateRandom(size_t num_bytes,
                        AuthorizationDelegate* delegate,
                        std::string* random_data) override;
  TPM_RC ExtendPCR(int pcr_index,
                   const std::string& extend_data,
                   AuthorizationDelegate* delegate) override;
  TPM_RC ExtendPCRForCSME(int pcr_index,
                          const std::string& extend_data) override;
  TPM_RC ReadPCR(int pcr_index, std::string* pcr_value) override;
  TPM_RC ReadPCRFromCSME(int pcr_index, std::string* pcr_value) override;
  TPM_RC AsymmetricEncrypt(TPM_HANDLE key_handle,
                           TPM_ALG_ID scheme,
                           TPM_ALG_ID hash_alg,
                           const std::string& plaintext,
                           AuthorizationDelegate* delegate,
                           std::string* ciphertext) override;
  TPM_RC AsymmetricDecrypt(TPM_HANDLE key_handle,
                           TPM_ALG_ID scheme,
                           TPM_ALG_ID hash_alg,
                           const std::string& ciphertext,
                           AuthorizationDelegate* delegate,
                           std::string* plaintext) override;
  TPM_RC RawSign(TPM_HANDLE key_handle,
                 TPM_ALG_ID scheme,
                 TPM_ALG_ID hash_alg,
                 const std::string& plaintext,
                 bool generate_hash,
                 AuthorizationDelegate* delegate,
                 TPMT_SIGNATURE* auth) override;
  TPM_RC Sign(TPM_HANDLE key_handle,
              TPM_ALG_ID scheme,
              TPM_ALG_ID hash_alg,
              const std::string& plaintext,
              bool generate_hash,
              AuthorizationDelegate* delegate,
              std::string* signature) override;
  TPM_RC CertifyCreation(TPM_HANDLE key_handle,
                         const std::string& creation_blob) override;
  TPM_RC ChangeKeyAuthorizationData(TPM_HANDLE key_handle,
                                    const std::string& new_password,
                                    AuthorizationDelegate* delegate,
                                    std::string* key_blob) override;
  TPM_RC ImportRSAKey(AsymmetricKeyUsage key_type,
                      const std::string& modulus,
                      uint32_t public_exponent,
                      const std::string& prime_factor,
                      const std::string& password,
                      AuthorizationDelegate* delegate,
                      std::string* key_blob) override;
  TPM_RC ImportECCKey(AsymmetricKeyUsage key_type,
                      TPMI_ECC_CURVE curve_id,
                      const std::string& public_point_x,
                      const std::string& public_point_y,
                      const std::string& private_value,
                      const std::string& password,
                      AuthorizationDelegate* delegate,
                      std::string* key_blob) override;
  TPM_RC CreateRSAKeyPair(AsymmetricKeyUsage key_type,
                          int modulus_bits,
                          uint32_t public_exponent,
                          const std::string& password,
                          const std::string& policy_digest,
                          bool use_only_policy_authorization,
                          const std::vector<uint32_t>& creation_pcr_indexes,
                          AuthorizationDelegate* delegate,
                          std::string* key_blob,
                          std::string* creation_blob) override;
  TPM_RC CreateECCKeyPair(AsymmetricKeyUsage key_type,
                          TPMI_ECC_CURVE curve_id,
                          const std::string& password,
                          const std::string& policy_digest,
                          bool use_only_policy_authorization,
                          const std::vector<uint32_t>& creation_pcr_indexes,
                          AuthorizationDelegate* delegate,
                          std::string* key_blob,
                          std::string* creation_blob) override;
  TPM_RC LoadKey(const std::string& key_blob,
                 AuthorizationDelegate* delegate,
                 TPM_HANDLE* key_handle) override;
  TPM_RC LoadRSAPublicKey(AsymmetricKeyUsage key_type,
                          TPM_ALG_ID scheme,
                          TPM_ALG_ID hash_alg,
                          const std::string& modulus,
                          uint32_t public_exponent,
                          AuthorizationDelegate* delegate,
                          TPM_HANDLE* key_handle) override;
  TPM_RC LoadECPublicKey(AsymmetricKeyUsage key_type,
                         TPM_ECC_CURVE curve_id,
                         TPM_ALG_ID scheme,
                         TPM_ALG_ID hash_alg,
                         const std::string& x,
                         const std::string& y,
                         AuthorizationDelegate* delegate,
                         TPM_HANDLE* key_handle) override;
  TPM_RC GetKeyName(TPM_HANDLE handle, std::string* name) override;
  TPM_RC GetKeyPublicArea(TPM_HANDLE handle, TPMT_PUBLIC* public_data) override;
  TPM_RC SealData(const std::string& data_to_seal,
                  const std::string& policy_digest,
                  const std::string& auth_value,
                  AuthorizationDelegate* delegate,
                  std::string* sealed_data) override;
  TPM_RC UnsealData(const std::string& sealed_data,
                    AuthorizationDelegate* delegate,
                    std::string* unsealed_data) override;
  TPM_RC UnsealDataWithHandle(TPM_HANDLE object_handle,
                              AuthorizationDelegate* delegate,
                              std::string* unsealed_data) override;
  TPM_RC StartSession(HmacSession* session) override;
  TPM_RC GetPolicyDigestForPcrValues(
      const std::map<uint32_t, std::string>& pcr_map,
      bool use_auth_value,
      std::string* policy_digest) override;
  TPM_RC DefineNVSpace(uint32_t index,
                       size_t num_bytes,
                       TPMA_NV attributes,
                       const std::string& authorization_value,
                       const std::string& policy_digest,
                       AuthorizationDelegate* delegate) override;
  TPM_RC DestroyNVSpace(uint32_t index,
                        AuthorizationDelegate* delegate) override;
  TPM_RC LockNVSpace(uint32_t index,
                     bool lock_read,
                     bool lock_write,
                     bool using_owner_authorization,
                     AuthorizationDelegate* delegate) override;
  TPM_RC WriteNVSpace(uint32_t index,
                      uint32_t offset,
                      const std::string& nvram_data,
                      bool using_owner_authorization,
                      bool extend,
                      AuthorizationDelegate* delegate) override;
  TPM_RC ReadNVSpace(uint32_t index,
                     uint32_t offset,
                     size_t num_bytes,
                     bool using_owner_authorization,
                     std::string* nvram_data,
                     AuthorizationDelegate* delegate) override;
  TPM_RC GetNVSpaceName(uint32_t index, std::string* name) override;
  TPM_RC GetNVSpacePublicArea(uint32_t index,
                              TPMS_NV_PUBLIC* public_data) override;
  TPM_RC ListNVSpaces(std::vector<uint32_t>* index_list) override;
  TPM_RC SetDictionaryAttackParameters(
      uint32_t max_tries,
      uint32_t recovery_time,
      uint32_t lockout_recovery,
      AuthorizationDelegate* delegate) override;
  TPM_RC ResetDictionaryAttackLock(AuthorizationDelegate* delegate) override;
  TPM_RC GetEndorsementKey(TPM_ALG_ID key_type,
                           AuthorizationDelegate* endorsement_delegate,
                           AuthorizationDelegate* owner_delegate,
                           TPM_HANDLE* key_handle) override;
  TPM_RC CreateIdentityKey(TPM_ALG_ID key_type,
                           AuthorizationDelegate* delegate,
                           std::string* key_blob) override;
  TPM_RC DeclareTpmFirmwareStable() override;
  TPM_RC GetPublicRSAEndorsementKeyModulus(std::string* ekm) override;
  TPM_RC ManageCCDPwd(bool allow_pwd) override;
  TPM_RC GetAlertsData(TpmAlertsData* alerts) override;
  TPM_RC PinWeaverIsSupported(uint8_t request_version,
                              uint8_t* protocol_version) override;
  TPM_RC PinWeaverResetTree(uint8_t protocol_version,
                            uint8_t bits_per_level,
                            uint8_t height,
                            uint32_t* result_code,
                            std::string* root_hash) override;
  TPM_RC PinWeaverInsertLeaf(uint8_t protocol_version,
                             uint64_t label,
                             const std::string& h_aux,
                             const brillo::SecureBlob& le_secret,
                             const brillo::SecureBlob& he_secret,
                             const brillo::SecureBlob& reset_secret,
                             const std::map<uint32_t, uint32_t>& delay_schedule,
                             const ValidPcrCriteria& valid_pcr_criteria,
                             uint32_t* result_code,
                             std::string* root_hash,
                             std::string* cred_metadata,
                             std::string* mac) override;
  TPM_RC PinWeaverRemoveLeaf(uint8_t protocol_version,
                             uint64_t label,
                             const std::string& h_aux,
                             const std::string& mac,
                             uint32_t* result_code,
                             std::string* root_hash) override;
  TPM_RC PinWeaverTryAuth(uint8_t protocol_version,
                          const brillo::SecureBlob& le_secret,
                          const std::string& h_aux,
                          const std::string& cred_metadata,
                          uint32_t* result_code,
                          std::string* root_hash,
                          uint32_t* seconds_to_wait,
                          brillo::SecureBlob* he_secret,
                          brillo::SecureBlob* reset_secret,
                          std::string* cred_metadata_out,
                          std::string* mac_out) override;
  TPM_RC PinWeaverResetAuth(uint8_t protocol_version,
                            const brillo::SecureBlob& reset_secret,
                            const std::string& h_aux,
                            const std::string& cred_metadata,
                            uint32_t* result_code,
                            std::string* root_hash,
                            brillo::SecureBlob* he_secret,
                            std::string* cred_metadata_out,
                            std::string* mac_out) override;
  TPM_RC PinWeaverGetLog(uint8_t protocol_version,
                         const std::string& root,
                         uint32_t* result_code,
                         std::string* root_hash,
                         std::vector<trunks::PinWeaverLogEntry>* log) override;
  TPM_RC PinWeaverLogReplay(uint8_t protocol_version,
                            const std::string& log_root,
                            const std::string& h_aux,
                            const std::string& cred_metadata,
                            uint32_t* result_code,
                            std::string* root_hash,
                            std::string* cred_metadata_out,
                            std::string* mac_out) override;
  TPM_RC GetRsuDeviceId(std::string* device_id) override;
  TPM_RC GetRoVerificationStatus(ApRoStatus* status) override;

  bool IsCr50() override;

 private:
  friend class TpmUtilityTest;
  friend class NVTpmUtilityTest;

  const TrunksFactory& factory_;
  std::map<uint32_t, TPMS_NV_PUBLIC> nvram_public_area_map_;
  uint32_t vendor_id_;
  std::string cached_rsu_device_id_;
  size_t max_nv_chunk_size_ = 0;

  enum class PinWeaverBackendType {
    kUnknown,
    kNotSupported,
    kCr50,
    kCsme,
  };
  PinWeaverBackendType pinweaver_backend_type_ = PinWeaverBackendType::kUnknown;

  // Creates the CSME salting key and calls `InitOwner()` API of CSME to
  // initialize the necessary TPM resources for pinweaver-csme. Returns
  // `TPM_RC_SUCCESS` if the operations succeed; otherwise, return
  // `TPM_RC_FAILURE`. If the pinweaver is supported natively by GCS (e.g.,
  // cr50), performs no-ops and return `TPM_RC_SUCCESS`.
  TPM_RC InitializeOwnerForCsme();

  // This methods sets the well-known owner authorization and creates SRK and
  // the salting key with it. Only succeeds if owner authorization was not set
  // yet. These are the common operations done (1) by pre-initialization when
  // the owner authorization is not set yet, and (2) when taking ownership,
  // which repeats them in case (pre-)initialization was interrupted earlier.
  TPM_RC CreateStorageAndSaltingKeys();

  // This method sets a known owner password in the TPM_RH_OWNER hierarchy.
  TPM_RC SetKnownOwnerPassword(const std::string& known_owner_password);

  // Synchronously derives storage root keys for RSA and ECC and persists the
  // keys in the TPM. This operation must be authorized by the |owner_password|
  // and, on success, KRSAStorageRootKey and kECCStorageRootKey can be used
  // with an empty authorization value until the TPM is cleared.
  TPM_RC CreateStorageRootKeys(const std::string& owner_password);

  // This method creates an RSA decryption key to be used for salting sessions.
  // This method also makes the salting key permanent under the storage
  // hierarchy.
  TPM_RC CreateSaltingKey(const std::string& owner_password);

  // Creates and persists the salting key for CSME. If the key is already
  // persisted, performs no-ops.
  TPM_RC CreateCsmeSaltingKey();

  // This method returns a partially filled TPMT_PUBLIC structure,
  // which can then be modified by other methods to create the public
  // template for a key. It takes a valid |key_type| tp construct the
  // parameters.
  TPMT_PUBLIC CreateDefaultPublicArea(TPM_ALG_ID key_alg);

  // Shared inner logic regardless of the key algorithm.
  // |key_type| is type of key usage. Eg. signing key, decrption key, etc
  // |public_area| contains algorithm-specific public-area metadata.
  // It will be copy and filled the rest information according the other
  // parameters. Then, it will be used by the TPM_Create command.
  // |password| is the authorization value to use to authorize the generating
  // key.
  // |policy_digest| specifies an optional policy to use to authorize the
  // generating key.
  // |use_only_policy_authorization| specifies if we can use
  // HmacSession in addition to PolicySession to authorize use of this key.
  // |creation_pcr_indexes| allows the caller to specify a list of pcr indexes
  // in the creation data.
  // |delegate| is an AuthorizationDelegate used to authorize the SRK which is
  // the parent of created key.
  // |key_blob| contains the key blob of created key that can be loaded into the
  // TPM.
  // If the |creation_blob| out param is defined, it will contain the serialized
  // creation structures generated by the TPM. This can be used to verify the
  // state of the TPM during key creation.
  // NOTE: if |use_only_policy_authorization| is set to true,
  // parameter_encryption must be disabled when the key is used.
  TPM_RC CreateKeyPairInner(AsymmetricKeyUsage key_type,
                            TPMT_PUBLIC public_area,
                            const std::string& password,
                            const std::string& policy_digest,
                            bool use_only_policy_authorization,
                            const std::vector<uint32_t>& creation_pcr_indexes,
                            AuthorizationDelegate* delegate,
                            std::string* key_blob,
                            std::string* creation_blob);

  // Shared inner logic of key importing regardless of key algorithm.
  // |key_type| is type of key usage. Eg. signing key, decrption key, etc
  // |public_area| contains algorithm-specific public-area metadata.
  // |in_sensitive| contains algorithm-specific private-area metadata.
  // |password| is the authorization value for the imported key.
  // |delegate| is an AuthorizationDelegate used to authorize the SRK which is
  // the parent of created key.
  // If the out argument |key_blob| is not null, it is populated with
  // the imported key, which can then be loaded into the TPM.
  TPM_RC ImportKeyInner(AsymmetricKeyUsage key_type,
                        TPMT_PUBLIC public_area,
                        TPMT_SENSITIVE in_sensitive,
                        const std::string& password,
                        AuthorizationDelegate* delegate,
                        std::string* key_blob);

  // Sets TPM |hierarchy| authorization to |password| using |authorization|.
  TPM_RC SetHierarchyAuthorization(TPMI_RH_HIERARCHY_AUTH hierarchy,
                                   const std::string& password,
                                   AuthorizationDelegate* authorization);

  // Disables the TPM platform hierarchy until the next startup. This requires
  // platform |authorization|.
  TPM_RC DisablePlatformHierarchy(AuthorizationDelegate* authorization);

  // Given a public area, this method computes the object name. Following
  // TPM2.0 Specification Part 1 section 16,
  // object_name = HashAlg || Hash(public_area);
  TPM_RC ComputeKeyName(const TPMT_PUBLIC& public_area,
                        std::string* object_name);

  // Given a public area, this method computers the NVSpace's name.
  // It follows TPM2.0 Specification Part 1 section 16,
  // nv_name = HashAlg || Hash(nv_public_area);
  TPM_RC ComputeNVSpaceName(const TPMS_NV_PUBLIC& nv_public_area,
                            std::string* nv_name);

  // This encrypts the |sensitive_data| struct according to the specification
  // defined in TPM2.0 spec Part 1: Figure 19.
  TPM_RC EncryptPrivateData(const TPMT_SENSITIVE& sensitive_area,
                            const TPMT_PUBLIC& public_area,
                            TPM2B_PRIVATE* encrypted_private_data,
                            TPM2B_DATA* encryption_key);

  // Looks for a given persistent |key_handle| and outputs whether or not it
  // |exists|. Returns TPM_RC_SUCCESS on success.
  TPM_RC DoesPersistentKeyExist(TPMI_DH_PERSISTENT key_handle, bool* exists);

  // Connects to the TPM driver and runs a few basic operations/checks.
  // Returns an error in case it failed to conect to the tpm, genereates log
  // warnings for other conditions.
  //
  // Also returns tpm_state to the caller for further use.
  TPM_RC TpmBasicInit(std::unique_ptr<TpmState>* tpm_state);

  // Return true if the TPM supports padding-only scheme for Sign.
  bool SupportsPaddingOnlySigningScheme() { return IsCr50() || IsSimulator(); }

  // Returns Vendor ID as reported in TPM_PT_MANUFACTURER property, or 0
  // in case of error reading the property.
  // Caches a non-zero vendor ID.
  uint32_t VendorId();

  // Returns true for TPMs running on simulator.
  bool IsSimulator();

  // Send an arbitrary command to the TPM and wait for the response.
  // Returns the response packet.
  std::string SendCommandAndWait(const std::string& command);

  // Sends vendor command in cr50 format, built from subcommand and already
  // serialized |command_payload|.
  // Returns the result of the command. Fills the |response_payload|,
  // if successful.
  TPM_RC Cr50VendorCommand(uint16_t subcommand,
                           const std::string& command_payload,
                           std::string* response_payload);

  // Helper function for serializing cr50 vendor command called from
  // Cr50VendorCommand(). Builds the ready-to-send |serialized_command|
  // including the standard header, the |subcommand| code, and the
  // subcommand-specific |command_payload|.
  // Returns the result of serializing the command.
  TPM_RC SerializeCommand_Cr50Vendor(uint16_t subcommand,
                                     const std::string& command_payload,
                                     std::string* serialized_command);

  // Helper function for parsing the response to cr50 vendor command,
  // called from Cr50VendorCommand(). Takes the |response| received from
  // the TPM, parses and ensures the correctness of the header, and
  // extracts the subcommand-specific |response_payload| (kept serialized
  // as received from the TPM).
  // If deserialization failed, returns an error. If the header is correctly
  // parsed, returns the error code received from the TPM.
  TPM_RC ParseResponse_Cr50Vendor(const std::string& response,
                                  std::string* response_payload);

  // Helper function for PinWeaver vendor specific commands.
  template <typename S, typename P>
  TPM_RC PinWeaverCommand(const std::string& tag, S serialize, P parse);

  // Obrains RSU device id from Cr50.
  TPM_RC GetRsuDeviceIdInternal(std::string* device_id);

  // Sends pinweaver command to CSME instead of GSC.
  TPM_RC PinWeaverCsmeCommand(const std::string& in, std::string* out);

  PinWeaverBackendType GetPinwWeaverBackendType();

  // Obtains max supported size of NV_Read/Write buffer.
  TPM_RC GetMaxNVChunkSize(size_t* size);
};

}  // namespace trunks

#endif  // TRUNKS_TPM_UTILITY_IMPL_H_
