// Copyright 2020 The Fuchsia 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 SRC_STORAGE_BLOBFS_BLOB_VERIFIER_H_
#define SRC_STORAGE_BLOBFS_BLOB_VERIFIER_H_

#include <lib/fzl/owned-vmo-mapper.h>
#include <lib/stdcompat/span.h>
#include <lib/zx/status.h>
#include <zircon/status.h>
#include <zircon/types.h>

#include <fbl/macros.h>

#include "src/lib/digest/digest.h"
#include "src/lib/digest/merkle-tree.h"
#include "src/storage/blobfs/blob_corruption_notifier.h"
#include "src/storage/blobfs/blob_layout.h"
#include "src/storage/blobfs/blobfs_metrics.h"

namespace blobfs {

// BlobVerifier verifies the contents of a blob against a merkle tree. Thread-safe.
class BlobVerifier {
 public:
  // Creates an instance of BlobVerifier for blobs named |digest|, using the provided merkle tree
  // which is at most |merkle_size| bytes. The passed-in BlobfsMetrics will be updated when this
  // class runs.
  //
  // The passed-in mapped merkle_data_blocks contains the blocks loaded from disk.  The tree is
  // copied into the member `merkle_data_`.
  //
  // Returns an error if the merkle tree's root does not match |digest|, or if the required tree
  // size for |data_size| bytes is bigger than |merkle_size|.
  [[nodiscard]] static zx::status<std::unique_ptr<BlobVerifier>> Create(
      digest::Digest digest, std::shared_ptr<BlobfsMetrics> metrics,
      cpp20::span<const uint8_t> merkle_data_blocks, const BlobLayout& layout,
      const BlobCorruptionNotifier* notifier);

  // Creates an instance of BlobVerifier for blobs named |digest|, which are small enough to not
  // have a stored merkle tree (i.e. MerkleTreeBytes(data_size) == 0). The passed-in BlobfsMetrics
  // will be updated when this class runs.
  [[nodiscard]] static zx::status<std::unique_ptr<BlobVerifier>> CreateWithoutTree(
      digest::Digest digest, std::shared_ptr<BlobfsMetrics> metrics, size_t data_size,
      const BlobCorruptionNotifier* notifier);

  // Verifies the entire contents of a blob. |buffer_size| is the total size of the buffer and the
  // buffer must be zeroed from |data_size| to |buffer_size|.
  // TODO(fxbug.dev/45457): Make const if MerkleTreeVerifier::Verify becomes const
  [[nodiscard]] zx_status_t Verify(const void* data, size_t data_size, size_t buffer_size);

  // Verifies a range of the contents of a blob from [data_offset, data_offset + length).
  // IMPORTANT: |data| is expected to be a pointer to the blob's contents at |data_offset|, not the
  // absolute start of the blob's data. (This facilitates partial verification when the blob is only
  // partially mapped in.) |buffer_size| is the total size of the buffer (relative to |data|) and
  // the buffer must be zerored from |data_size| to |buffer_size|.
  // TODO(fxbug.dev/45457): Make const if MerkleTreeVerifier::Verify becomes const
  [[nodiscard]] zx_status_t VerifyPartial(const void* data, size_t length, size_t data_offset,
                                          size_t buffer_size);

  // Modifies |data_off| and |buf_len| to be aligned to the minimum number of merkle tree nodes that
  // covered their original range.
  [[nodiscard]] zx_status_t Align(size_t* data_off, size_t* buf_len) const {
    return tree_verifier_.Align(data_off, buf_len);
  }

  const Digest& digest() { return digest_; }
  cpp20::span<const uint8_t> merkle_data() const {
    return cpp20::span(merkle_data_.get(), tree_verifier_.GetTreeLength());
  }

 private:
  // Use |Create| or |CreateWithoutTree| to construct.
  explicit BlobVerifier(digest::Digest digest, std::shared_ptr<BlobfsMetrics> metrics);

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

  std::unique_ptr<uint8_t[]> merkle_data_;

  const BlobCorruptionNotifier* corruption_notifier_;
  const digest::Digest digest_;

  // The verification lock is to be used whenever calling Verify() on the |tree_verifier_| since
  // the call mutates internal state variables which makes the call not thread-safe. The member is
  // not guarded by the mutex because there are perfectly safe const calls within it that do not
  // require locking. Failing to take this lock when running Verify() will make this class no longer
  // thread-safe.
  std::mutex verification_lock_;
  digest::MerkleTreeVerifier tree_verifier_;
  std::shared_ptr<BlobfsMetrics> metrics_;
};

}  // namespace blobfs

#endif  // SRC_STORAGE_BLOBFS_BLOB_VERIFIER_H_
