// Copyright 2017 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_LIB_DIGEST_DIGEST_H_
#define SRC_LIB_DIGEST_DIGEST_H_

#include <stddef.h>
#include <stdint.h>
#include <zircon/compiler.h>
#include <zircon/types.h>

#include <memory>
#include <ostream>

#include <fbl/string.h>

namespace digest {

// The length (in bytes) of a SHA256 hash.
constexpr size_t kSha256Length = 32;

// The length (in characters) of a stringified SHA256 hash. Does not include room for a
// null-terminator character.
constexpr size_t kSha256HexLength = (kSha256Length * 2);

// This class represents a digest produced by a hash algorithm.
// This class is not thread safe.
class Digest final {
 public:
  Digest();
  explicit Digest(const uint8_t (&bytes)[kSha256Length]);
  Digest(Digest&& other);
  Digest& operator=(const uint8_t (&bytes)[kSha256Length]);
  Digest& operator=(Digest&& other);

  // Copying a digest copies the digest bytes but can not be used for incrementally adding to
  // the digest. The copy constructor/assignment code will assert if the source object is not
  // finalized.
  Digest(const Digest& other);
  Digest& operator=(const Digest& other);

  ~Digest();

  const uint8_t* get() const { return bytes_; }
  constexpr size_t len() const { return sizeof(bytes_); }

  // Initializes the hash algorithm context.  It must be called before Update,
  // and after Final when reusing the Digest object.
  void Init();

  // Adds data to be hashed.  This may be called multiple times between calls
  // to |Init| and |Final|.  If A and B are byte sequences of length A_len and
  // B_len, respectively, and AB is the concatenation of A and B, then
  // "Update(A, A_len); Update(B, B_len);" and "Update(AB, A_len + B_len)"
  // yield the same internal state and will produce the same digest when
  // |Final| is called.
  void Update(const void* data, size_t len);

  // Completes the hash algorithm and returns the digest.  This must only be
  // called after a call to |Init|; intervening calls to |Update| are
  // optional.
  const uint8_t* Final();

  // This convenience method performs the hash algorithm in "one shot": It
  // calls |Init| and |Update(data, len)| before returning the result of
  // calling |Final|.
  const uint8_t* Hash(const void* data, size_t len);

  // Converts a null-terminated |hex| string to binary and stores it in this
  // object. |hex| must represent |kLength| bytes, that is, it must have
  // |kLength| * 2 characters.
  zx_status_t Parse(const char* hex, size_t len);
  zx_status_t Parse(const char* hex) { return Parse(hex, strlen(hex)); }
  zx_status_t Parse(const fbl::String& hex) { return Parse(hex.c_str(), hex.length()); }

  // Returns the current digest as a hex string.
  fbl::String ToString() const;

  // Writes digest to |out|.
  void CopyTo(uint8_t (&out)[kSha256Length]) const { CopyTo(out, kSha256Length); }

  // Write digest to |out|. |len| must be at least |kSha256Length|; if it is
  // greater, the remainder of |out| is filled with zeros.
  void CopyTo(uint8_t* out, size_t len) const;

  // Like |CopyTo(out, len)|, but only writes the first |len| bytes of the digest to |out| if |len|
  // is less than |kSha256Length|.
  void CopyTruncatedTo(uint8_t* out, size_t len) const;

  // Equality operators.  Those that take |const uint8_t *| arguments will
  // read |kLength| bytes; callers MUST ensure there are sufficient bytes
  // present.
  bool Equals(const uint8_t* rhs, size_t rhs_len) const;
  bool operator==(const Digest& rhs) const { return Equals(rhs.bytes_, kSha256Length); }
  bool operator!=(const Digest& rhs) const { return !Equals(rhs.bytes_, kSha256Length); }
  bool operator==(const uint8_t (&rhs)[kSha256Length]) const { return Equals(rhs, kSha256Length); }
  bool operator!=(const uint8_t (&rhs)[kSha256Length]) const { return !Equals(rhs, kSha256Length); }

  // Allow a digest to be used in a map.
  bool operator<(const Digest& rhs) const { return memcmp(bytes_, rhs.bytes_, kSha256Length) < 0; }

 private:
  // Opaque crypto implementation context.
  struct Context;

  friend std::ostream& operator<<(std::ostream&, const Digest&);

  // Opaque pointer to the crypto implementation context.
  std::unique_ptr<Context> ctx_;
  // The raw bytes of the current digest.  This is filled in either by the
  // assignment operators or the Parse and Final methods.
  uint8_t bytes_[kSha256Length];
};

std::ostream& operator<<(std::ostream&, const Digest&);

}  // namespace digest

#endif  // SRC_LIB_DIGEST_DIGEST_H_
