/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef RTC_BASE_MESSAGE_DIGEST_H_
#define RTC_BASE_MESSAGE_DIGEST_H_

#include <stddef.h>

#include <string>

namespace rtc {

// Definitions for the digest algorithms.
extern const char DIGEST_MD5[];
extern const char DIGEST_SHA_1[];
extern const char DIGEST_SHA_224[];
extern const char DIGEST_SHA_256[];
extern const char DIGEST_SHA_384[];
extern const char DIGEST_SHA_512[];

// A general class for computing hashes.
class MessageDigest {
 public:
  enum { kMaxSize = 64 };  // Maximum known size (SHA-512)
  virtual ~MessageDigest() {}
  // Returns the digest output size (e.g. 16 bytes for MD5).
  virtual size_t Size() const = 0;
  // Updates the digest with `len` bytes from `buf`.
  virtual void Update(const void* buf, size_t len) = 0;
  // Outputs the digest value to `buf` with length `len`.
  // Returns the number of bytes written, i.e., Size().
  virtual size_t Finish(void* buf, size_t len) = 0;
};

// A factory class for creating digest objects.
class MessageDigestFactory {
 public:
  static MessageDigest* Create(const std::string& alg);
};

// A check that an algorithm is in a list of approved digest algorithms
// from RFC 4572 (FIPS 180).
bool IsFips180DigestAlgorithm(const std::string& alg);

// Functions to create hashes.

// Computes the hash of `in_len` bytes of `input`, using the `digest` hash
// implementation, and outputs the hash to the buffer `output`, which is
// `out_len` bytes long. Returns the number of bytes written to `output` if
// successful, or 0 if `out_len` was too small.
size_t ComputeDigest(MessageDigest* digest,
                     const void* input,
                     size_t in_len,
                     void* output,
                     size_t out_len);
// Like the previous function, but creates a digest implementation based on
// the desired digest name `alg`, e.g. DIGEST_SHA_1. Returns 0 if there is no
// digest with the given name.
size_t ComputeDigest(const std::string& alg,
                     const void* input,
                     size_t in_len,
                     void* output,
                     size_t out_len);
// Computes the hash of `input` using the `digest` hash implementation, and
// returns it as a hex-encoded string.
std::string ComputeDigest(MessageDigest* digest, const std::string& input);
// Like the previous function, but creates a digest implementation based on
// the desired digest name `alg`, e.g. DIGEST_SHA_1. Returns empty string if
// there is no digest with the given name.
std::string ComputeDigest(const std::string& alg, const std::string& input);
// Like the previous function, but returns an explicit result code.
bool ComputeDigest(const std::string& alg,
                   const std::string& input,
                   std::string* output);

// Shorthand way to compute a hex-encoded hash using MD5.
inline std::string MD5(const std::string& input) {
  return ComputeDigest(DIGEST_MD5, input);
}

// Functions to compute RFC 2104 HMACs.

// Computes the HMAC of `in_len` bytes of `input`, using the `digest` hash
// implementation and `key_len` bytes of `key` to key the HMAC, and outputs
// the HMAC to the buffer `output`, which is `out_len` bytes long. Returns the
// number of bytes written to `output` if successful, or 0 if `out_len` was too
// small.
size_t ComputeHmac(MessageDigest* digest,
                   const void* key,
                   size_t key_len,
                   const void* input,
                   size_t in_len,
                   void* output,
                   size_t out_len);
// Like the previous function, but creates a digest implementation based on
// the desired digest name `alg`, e.g. DIGEST_SHA_1. Returns 0 if there is no
// digest with the given name.
size_t ComputeHmac(const std::string& alg,
                   const void* key,
                   size_t key_len,
                   const void* input,
                   size_t in_len,
                   void* output,
                   size_t out_len);
// Computes the HMAC of `input` using the `digest` hash implementation and `key`
// to key the HMAC, and returns it as a hex-encoded string.
std::string ComputeHmac(MessageDigest* digest,
                        const std::string& key,
                        const std::string& input);
// Like the previous function, but creates a digest implementation based on
// the desired digest name `alg`, e.g. DIGEST_SHA_1. Returns empty string if
// there is no digest with the given name.
std::string ComputeHmac(const std::string& alg,
                        const std::string& key,
                        const std::string& input);
// Like the previous function, but returns an explicit result code.
bool ComputeHmac(const std::string& alg,
                 const std::string& key,
                 const std::string& input,
                 std::string* output);

}  // namespace rtc

#endif  // RTC_BASE_MESSAGE_DIGEST_H_
