Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/cryptopp/iterhash.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // iterhash.h - originally written and placed in the public domain by Wei Dai

0002 
0003 /// \file iterhash.h

0004 /// \brief Base classes for iterated hashes

0005 
0006 #ifndef CRYPTOPP_ITERHASH_H
0007 #define CRYPTOPP_ITERHASH_H
0008 
0009 #include "cryptlib.h"
0010 #include "secblock.h"
0011 #include "misc.h"
0012 #include "simple.h"
0013 
0014 #if CRYPTOPP_MSC_VERSION
0015 # pragma warning(push)
0016 # pragma warning(disable: 4231 4275)
0017 # if (CRYPTOPP_MSC_VERSION >= 1400)
0018 #  pragma warning(disable: 6011 6386 28193)
0019 # endif
0020 #endif
0021 
0022 NAMESPACE_BEGIN(CryptoPP)
0023 
0024 /// \brief Exception thrown when trying to hash more data than is allowed by a hash function

0025 class CRYPTOPP_DLL HashInputTooLong : public InvalidDataFormat
0026 {
0027 public:
0028     explicit HashInputTooLong(const std::string &alg)
0029         : InvalidDataFormat("IteratedHashBase: input data exceeds maximum allowed by hash function " + alg) {}
0030 };
0031 
0032 /// \brief Iterated hash base class

0033 /// \tparam T Hash word type

0034 /// \tparam BASE HashTransformation derived class

0035 /// \details IteratedHashBase provides an interface for block-based iterated hashes

0036 /// \sa HashTransformation, MessageAuthenticationCode

0037 template <class T, class BASE>
0038 class CRYPTOPP_NO_VTABLE IteratedHashBase : public BASE
0039 {
0040 public:
0041     typedef T HashWordType;
0042 
0043     virtual ~IteratedHashBase() {}
0044 
0045     /// \brief Construct an IteratedHashBase

0046     IteratedHashBase() : m_countLo(0), m_countHi(0) {}
0047 
0048     /// \brief Provides the input block size most efficient for this cipher.

0049     /// \return The input block size that is most efficient for the cipher

0050     /// \details The base class implementation returns MandatoryBlockSize().

0051     /// \note Optimal input length is

0052     ///   <tt>n * OptimalBlockSize() - GetOptimalBlockSizeUsed()</tt> for any <tt>n \> 0</tt>.

0053     unsigned int OptimalBlockSize() const {return this->BlockSize();}
0054 
0055     /// \brief Provides input and output data alignment for optimal performance.

0056     /// \return the input data alignment that provides optimal performance

0057     /// \details OptimalDataAlignment returns the natural alignment of the hash word.

0058     unsigned int OptimalDataAlignment() const {return GetAlignmentOf<T>();}
0059 
0060     /// \brief Updates a hash with additional input

0061     /// \param input the additional input as a buffer

0062     /// \param length the size of the buffer, in bytes

0063     void Update(const byte *input, size_t length);
0064 
0065     /// \brief Requests space which can be written into by the caller

0066     /// \param size the requested size of the buffer

0067     /// \details The purpose of this method is to help avoid extra memory allocations.

0068     /// \details size is an \a IN and \a OUT parameter and used as a hint. When the call is made,

0069     ///   size is the requested size of the buffer. When the call returns, size is the size of

0070     ///   the array returned to the caller.

0071     /// \details The base class implementation sets  size to 0 and returns  NULL.

0072     /// \note Some objects, like ArraySink, cannot create a space because its fixed.

0073     byte * CreateUpdateSpace(size_t &size);
0074 
0075     /// \brief Restart the hash

0076     /// \details Discards the current state, and restart for a new message

0077     void Restart();
0078 
0079     /// \brief Computes the hash of the current message

0080     /// \param digest a pointer to the buffer to receive the hash

0081     /// \param digestSize the size of the truncated digest, in bytes

0082     /// \details TruncatedFinal() calls Final() and then copies digestSize bytes to digest.

0083     ///   The hash is restarted the hash for the next message.

0084     void TruncatedFinal(byte *digest, size_t digestSize);
0085 
0086     /// \brief Retrieve the provider of this algorithm

0087     /// \return the algorithm provider

0088     /// \details The algorithm provider can be a name like "C++", "SSE", "NEON", "AESNI",

0089     ///    "ARMv8" and "Power8". C++ is standard C++ code. Other labels, like SSE,

0090     ///    usually indicate a specialized implementation using instructions from a higher

0091     ///    instruction set architecture (ISA). Future labels may include external hardware

0092     ///    like a hardware security module (HSM).

0093     /// \note  Provider is not universally implemented yet.

0094     virtual std::string AlgorithmProvider() const { return "C++"; }
0095 
0096 protected:
0097     inline T GetBitCountHi() const
0098         {return (m_countLo >> (8*sizeof(T)-3)) + (m_countHi << 3);}
0099     inline T GetBitCountLo() const
0100         {return m_countLo << 3;}
0101 
0102     void PadLastBlock(unsigned int lastBlockSize, byte padFirst=0x80);
0103     virtual void Init() =0;
0104 
0105     virtual ByteOrder GetByteOrder() const =0;
0106     virtual void HashEndianCorrectedBlock(const HashWordType *data) =0;
0107     virtual size_t HashMultipleBlocks(const T *input, size_t length);
0108     void HashBlock(const HashWordType *input)
0109         {HashMultipleBlocks(input, this->BlockSize());}
0110 
0111     virtual T* DataBuf() =0;
0112     virtual T* StateBuf() =0;
0113 
0114 private:
0115     T m_countLo, m_countHi;
0116 };
0117 
0118 /// \brief Iterated hash base class

0119 /// \tparam T_HashWordType Hash word type

0120 /// \tparam T_Endianness Endianness type of hash

0121 /// \tparam T_BlockSize Block size of the hash

0122 /// \tparam T_Base HashTransformation derived class

0123 /// \details IteratedHash provides a default implementation for block-based iterated hashes

0124 /// \sa HashTransformation, MessageAuthenticationCode

0125 template <class T_HashWordType, class T_Endianness, unsigned int T_BlockSize, class T_Base = HashTransformation>
0126 class CRYPTOPP_NO_VTABLE IteratedHash : public IteratedHashBase<T_HashWordType, T_Base>
0127 {
0128 public:
0129     typedef T_Endianness ByteOrderClass;
0130     typedef T_HashWordType HashWordType;
0131 
0132     CRYPTOPP_CONSTANT(BLOCKSIZE = T_BlockSize);
0133     // BCB2006 workaround: can't use BLOCKSIZE here

0134     CRYPTOPP_COMPILE_ASSERT((T_BlockSize & (T_BlockSize - 1)) == 0);    // blockSize is a power of 2

0135 
0136     virtual ~IteratedHash() {}
0137 
0138     /// \brief Provides the block size of the hash

0139     /// \return the block size of the hash, in bytes

0140     /// \details BlockSize() returns <tt>T_BlockSize</tt>.

0141     unsigned int BlockSize() const {return T_BlockSize;}
0142 
0143     /// \brief Provides the byte order of the hash

0144     /// \return the byte order of the hash as an enumeration

0145     /// \details GetByteOrder() returns <tt>T_Endianness::ToEnum()</tt>.

0146     /// \sa ByteOrder()

0147     ByteOrder GetByteOrder() const {return T_Endianness::ToEnum();}
0148 
0149     /// \brief Adjusts the byte ordering of the hash

0150     /// \param out the output buffer

0151     /// \param in the input buffer

0152     /// \param byteCount the size of the buffers, in bytes

0153     /// \details CorrectEndianess() calls ConditionalByteReverse() using <tt>T_Endianness</tt>.

0154     inline void CorrectEndianess(HashWordType *out, const HashWordType *in, size_t byteCount)
0155     {
0156         CRYPTOPP_ASSERT(in != NULLPTR);
0157         CRYPTOPP_ASSERT(out != NULLPTR);
0158         CRYPTOPP_ASSERT(IsAligned<T_HashWordType>(in));
0159         CRYPTOPP_ASSERT(IsAligned<T_HashWordType>(out));
0160 
0161         ConditionalByteReverse(T_Endianness::ToEnum(), out, in, byteCount);
0162     }
0163 
0164 protected:
0165     enum { Blocks = T_BlockSize/sizeof(T_HashWordType) };
0166     T_HashWordType* DataBuf() {return this->m_data;}
0167     FixedSizeSecBlock<T_HashWordType, Blocks> m_data;
0168 };
0169 
0170 /// \brief Iterated hash with a static transformation function

0171 /// \tparam T_HashWordType Hash word type

0172 /// \tparam T_Endianness Endianness type of hash

0173 /// \tparam T_BlockSize Block size of the hash

0174 /// \tparam T_StateSize Internal state size of the hash

0175 /// \tparam T_Transform HashTransformation derived class

0176 /// \tparam T_DigestSize Digest size of the hash

0177 /// \tparam T_StateAligned Flag indicating if state is 16-byte aligned

0178 /// \sa HashTransformation, MessageAuthenticationCode

0179 template <class T_HashWordType, class T_Endianness, unsigned int T_BlockSize, unsigned int T_StateSize, class T_Transform, unsigned int T_DigestSize = 0, bool T_StateAligned = false>
0180 class CRYPTOPP_NO_VTABLE IteratedHashWithStaticTransform
0181     : public ClonableImpl<T_Transform, AlgorithmImpl<IteratedHash<T_HashWordType, T_Endianness, T_BlockSize>, T_Transform> >
0182 {
0183 public:
0184     CRYPTOPP_CONSTANT(DIGESTSIZE = T_DigestSize ? T_DigestSize : T_StateSize);
0185 
0186     virtual ~IteratedHashWithStaticTransform() {}
0187 
0188     /// \brief Provides the digest size of the hash

0189     /// \return the digest size of the hash, in bytes

0190     /// \details DigestSize() returns <tt>DIGESTSIZE</tt>.

0191     unsigned int DigestSize() const {return DIGESTSIZE;}
0192 
0193 protected:
0194     // https://github.com/weidai11/cryptopp/issues/147#issuecomment-766231864

0195     IteratedHashWithStaticTransform() {IteratedHashWithStaticTransform::Init();}
0196     void HashEndianCorrectedBlock(const T_HashWordType *data) {T_Transform::Transform(this->m_state, data);}
0197     void Init() {T_Transform::InitState(this->m_state);}
0198 
0199     enum { Blocks = T_BlockSize/sizeof(T_HashWordType) };
0200     T_HashWordType* StateBuf() {return this->m_state;}
0201     FixedSizeAlignedSecBlock<T_HashWordType, Blocks, T_StateAligned> m_state;
0202 };
0203 
0204 #if !defined(__GNUC__) && !defined(__clang__)
0205     CRYPTOPP_DLL_TEMPLATE_CLASS IteratedHashBase<word64, HashTransformation>;
0206     CRYPTOPP_STATIC_TEMPLATE_CLASS IteratedHashBase<word64, MessageAuthenticationCode>;
0207 
0208     CRYPTOPP_DLL_TEMPLATE_CLASS IteratedHashBase<word32, HashTransformation>;
0209     CRYPTOPP_STATIC_TEMPLATE_CLASS IteratedHashBase<word32, MessageAuthenticationCode>;
0210 #endif
0211 
0212 NAMESPACE_END
0213 
0214 #if CRYPTOPP_MSC_VERSION
0215 # pragma warning(pop)
0216 #endif
0217 
0218 #endif