blob: 86dd1ee1d768c9919871c163d33e689ba37ae8ea [file] [log] [blame]
/***************** See RFC 6234 for details. *******************/
/*
Copyright (c) 2011 IETF Trust and the persons identified as
authors of the code. All rights reserved.
Redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following
conditions are met:
- Redistributions of source code must retain the above
copyright notice, this list of conditions and
the following disclaimer.
- Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
- Neither the name of Internet Society, IETF or IETF Trust, nor
the names of specific contributors, may be used to endorse or
promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Implementation of the SHA256 Secure Hash Algorithm as defined in the U.S.
National Institute of Standards and Technology Federal Information Processing
Standards Publication (FIPS PUB) 180-3 published in October 2008 and formerly
defined in its predecessors, FIPS PUB 180-1 and FIP PUB 180-2. See:
The algorithm description is available at
http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf
The code is derived from: https://www.rfc-editor.org/rfc/rfc6234.txt
*/
#ifndef VERIBLE_COMMON_UTIL_SHA_H_
#define VERIBLE_COMMON_UTIL_SHA_H_
#include <array>
#include <cstdint>
#include <string>
#include "absl/strings/string_view.h"
namespace verible {
// The size of SHA256 hash in bytes.
inline constexpr int32_t kSha256HashSize = 32;
// The size of a single message block, in bytes.
inline constexpr int32_t kSha256MessageBlockSize = 64;
// The context information for the SHA-256 hashing operation.
class Sha256Context {
public:
Sha256Context() { Reset(); }
// Finishes off the digest calculations and returns the 256-bit message
// digest. Resets the context in preparation for computing a new SHA-256.
// NOTE: The first octet of hash is stored in the element with index 0, the
// last octet of hash in the element with index 27/31.
std::array<uint8_t, kSha256HashSize> BuildAndReset();
// Adds an array of octets as the next portion of the message. Returns false
// if the accumulated message is too large (>2 Exabytes). Can be called
// multiple times to incrementally build the digest.
bool AddInput(absl::string_view message);
// Returns true if the accumulated message is too large (>2 Exabytes).
bool IsOverflowed() const { return overflowed_; }
private:
// Initialize the Sha256Context in preparation for computing a new SHA-256
// message digest.
void Reset();
// Adds "length" to the length. Returns false if the accumulated message is
// too large (>2 Exabytes).
bool AddLength(unsigned int length);
// Process the next 512 bits of the message stored in the message_block_
// array.
//
// Many of the variable names in this code, especially the
// single character names, were used because those were the
// names used in the Secure Hash Standard.
void ProcessMessageBlock();
// Padds the message to the next even multiple of 512 bits. The first padding
// bit must be a '1'. The last 64 bits represent the length of the original
// message. All bits in between should be 0. This helper function will pad
// the message according to those rules by filling the message_block_ array
// accordingly. When it returns, it can be assumed that the message digest
// has been computed.
//
// Pad_Byte is the last byte to add to the message block before the 0-padding
// and length. This will contain the last bits of the message followed by
// another single bit. If the message was an exact multiple of 8-bits long,
// Pad_Byte will be 0x80.
void PadMessage(uint8_t Pad_Byte);
// Message Digest
std::array<uint32_t, kSha256HashSize / 4> intermediate_hash_;
// Message length in bits.
uint32_t length_high_;
uint32_t length_low_;
// The last set index in the message_block_ array.
int_least16_t message_block_index_;
std::array<uint8_t, kSha256MessageBlockSize> message_block_;
// True if the accumulated message is too large (>2 Exabytes).
bool overflowed_;
};
// Returns the SHA256 hash of the given content.
std::array<uint8_t, kSha256HashSize> Sha256(absl::string_view content);
// Returns the HEX string representation of SHA256 hash of the given content.
std::string Sha256Hex(absl::string_view content);
} // namespace verible
#endif // VERIBLE_COMMON_UTIL_SHA_H_