// Copyright 2012 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Lockbox - class for storing tamper-evident data blobs.
#ifndef CRYPTOHOME_LOCKBOX_H_
#define CRYPTOHOME_LOCKBOX_H_

#include <memory>

#include <base/strings/string_util.h>
#include <brillo/secure_blob.h>
#include <libhwsec/frontend/cryptohome/frontend.h>
#include <libstorage/platform/platform.h>
#include <openssl/sha.h>

namespace cryptohome {

class LockboxContents;

enum class LockboxError {
  kNvramInvalid,
  kTpmUnavailable,
  kTpmError,  // Transient or unknown TPM error.
};

// Enable LockboxError to be used in LOG output.
std::ostream& operator<<(std::ostream& out, LockboxError error);

// Lockbox stores a blob of data in a tamper-evident manner.
//
// This class provides system integration for supporting tamper-evident
// storage using the TPM NVRAM locking and restricted TPM ownership to
// ensure that a data blob stored on disk has not been tampered with to
// the degree that can be cryptographically assured.
//
// Lockbox is not thread-safe and should not be accessed in parallel.
//
// A normal usage flow for Lockbox would be something as follows:
//
// Initializing new data against a lockbox (except with error checking :)
//   Lockbox lockbox(hwsec, hwsec::Space::kInstallAttributes);
//   LockboxError error;
//   lockbox->Create(&error);
//   lockbox->Store(mah_locked_data, &error);
//
// Verifying data is performed via class |LockboxContents|.
class Lockbox {
 public:
  // Populates the basic internal state of the Lockbox.
  //
  // Parameters
  // - hwsec: a required pointer to hwsec object.
  // - space: the space for lockbox.
  Lockbox(const hwsec::CryptohomeFrontend* hwsec, hwsec::Space space);

  Lockbox(const Lockbox&) = delete;
  Lockbox& operator=(const Lockbox&) = delete;

  virtual ~Lockbox() = default;

  // Sets up the backend state needed for this lockbox.
  //
  // Instantiates a new TPM NVRAM index lockable bWriteDefine to store
  // the hash and blob size of the data to lock away.
  //
  // Parameters
  // - error: will contain the LockboxError if false.
  // Returns
  // - true if a new space was instantiated or an old one could be used.
  // - false if the space cannot be created or claimed.
  [[nodiscard]] virtual bool Reset(LockboxError* error);

  // Hashes, salts, sizes, and stores metadata required for verifying |data|
  // in TPM NVRAM for later verification.
  //
  // Parameters
  // - data: blob to store.
  // - error: LockboxError populated only on failure
  // Returns
  // - true if written to disk and NVRAM (if there is a tpm).
  // - false if the data could not be persisted.
  [[nodiscard]] virtual bool Store(const brillo::Blob& data,
                                   LockboxError* error);

 protected:
  // constructor for mock testing purpose.
  Lockbox() = default;

 private:
  const hwsec::CryptohomeFrontend* hwsec_;
  hwsec::Space space_;
};

// Represents decoded lockbox NVRAM space contents and provides operations to
// encode/decode, as well as setting up and verifying integrity of a specific
// data blob.
class LockboxContents {
 public:
  enum class VerificationResult {
    kValid,
    kSizeMismatch,
    kHashMismatch,
  };

  static inline constexpr size_t kFixedPartSize =
      sizeof(uint32_t) + sizeof(uint8_t) + SHA256_DIGEST_LENGTH;
  static inline constexpr size_t kKeyMaterialSize = 32;
  static inline constexpr size_t kNvramSize = kKeyMaterialSize + kFixedPartSize;

  // Creates a LockboxContents instance that'll handle encoded lockbox contents
  // corresponding to an NVRAM space of size |nvram_size|. Returns nullptr in
  // case the passed |nvram_size| isn't supported.
  static std::unique_ptr<LockboxContents> New();

  size_t key_material_size() const { return key_material_.size(); }

  // Serialize to |nvram_data|.
  [[nodiscard]] bool Encode(brillo::SecureBlob* nvram_data);

  // Deserialize from |nvram_data|.
  [[nodiscard]] bool Decode(const brillo::SecureBlob& nvram_data);

  // Sets key material, which must be of key_material_size().
  [[nodiscard]] bool SetKeyMaterial(const brillo::SecureBlob& key_material);

  // Protect |blob|, i.e. compute the digest that will later make Verify() to
  // succeed if and only if a copy of |blob| is being passed.
  [[nodiscard]] bool Protect(const brillo::Blob& blob);

  // Verify |blob| against the lockbox contents.
  [[nodiscard]] VerificationResult Verify(const brillo::Blob& blob);

 private:
  LockboxContents() = default;

  uint32_t size_ = 0;
  uint8_t flags_ = 0;
  brillo::SecureBlob key_material_ = {0};
  uint8_t hash_[SHA256_DIGEST_LENGTH] = {0};
};

}  // namespace cryptohome

#endif  // CRYPTOHOME_LOCKBOX_H_
