1 | #ifndef CRYPTOPP_ITERHASH_H |
---|
2 | #define CRYPTOPP_ITERHASH_H |
---|
3 | |
---|
4 | #include "cryptlib.h" |
---|
5 | #include "secblock.h" |
---|
6 | #include "misc.h" |
---|
7 | #include "simple.h" |
---|
8 | |
---|
9 | NAMESPACE_BEGIN(CryptoPP) |
---|
10 | |
---|
11 | //! \class HashInputTooLong |
---|
12 | //! \brief Exception thrown when trying to hash more data than is allowed by a hash function |
---|
13 | class CRYPTOPP_DLL HashInputTooLong : public InvalidDataFormat |
---|
14 | { |
---|
15 | public: |
---|
16 | explicit HashInputTooLong(const std::string &alg) |
---|
17 | : InvalidDataFormat("IteratedHashBase: input data exceeds maximum allowed by hash function " + alg) {} |
---|
18 | }; |
---|
19 | |
---|
20 | //! \class IteratedHashBase |
---|
21 | //! \brief Iterated hash base class |
---|
22 | //! \tparam T Hash word type |
---|
23 | //! \tparam BASE HashTransformation derived class |
---|
24 | //! \details IteratedHashBase provides an interface for block-based iterated hashes |
---|
25 | //! \sa HashTransformation, MessageAuthenticationCode |
---|
26 | template <class T, class BASE> |
---|
27 | class CRYPTOPP_NO_VTABLE IteratedHashBase : public BASE |
---|
28 | { |
---|
29 | public: |
---|
30 | typedef T HashWordType; |
---|
31 | |
---|
32 | //! \brief Construct an IteratedHashBase |
---|
33 | IteratedHashBase() : m_countLo(0), m_countHi(0) {} |
---|
34 | |
---|
35 | //! \brief Provides the input block size most efficient for this cipher. |
---|
36 | //! \return The input block size that is most efficient for the cipher |
---|
37 | //! \details The base class implementation returns MandatoryBlockSize(). |
---|
38 | //! \note Optimal input length is |
---|
39 | //! <tt>n * OptimalBlockSize() - GetOptimalBlockSizeUsed()</tt> for any <tt>n \> 0</tt>. |
---|
40 | unsigned int OptimalBlockSize() const {return this->BlockSize();} |
---|
41 | |
---|
42 | //! \brief Provides input and output data alignment for optimal performance. |
---|
43 | //! \return the input data alignment that provides optimal performance |
---|
44 | //! \details OptimalDataAlignment returnes the natural alignment of the hash word. |
---|
45 | unsigned int OptimalDataAlignment() const {return GetAlignmentOf<T>();} |
---|
46 | |
---|
47 | //! \brief Updates a hash with additional input |
---|
48 | //! \param input the additional input as a buffer |
---|
49 | //! \param length the size of the buffer, in bytes |
---|
50 | void Update(const byte *input, size_t length); |
---|
51 | |
---|
52 | //! \brief Requests space which can be written into by the caller |
---|
53 | //! \param size the requested size of the buffer |
---|
54 | //! \details The purpose of this method is to help avoid extra memory allocations. |
---|
55 | //! \details size is an \a IN and \a OUT parameter and used as a hint. When the call is made, |
---|
56 | //! size is the requested size of the buffer. When the call returns, size is the size of |
---|
57 | //! the array returned to the caller. |
---|
58 | //! \details The base class implementation sets size to 0 and returns NULL. |
---|
59 | //! \note Some objects, like ArraySink, cannot create a space because its fixed. |
---|
60 | byte * CreateUpdateSpace(size_t &size); |
---|
61 | |
---|
62 | //! \brief Restart the hash |
---|
63 | //! \details Discards the current state, and restart for a new message |
---|
64 | void Restart(); |
---|
65 | |
---|
66 | //! \brief Computes the hash of the current message |
---|
67 | //! \param digest a pointer to the buffer to receive the hash |
---|
68 | //! \param digestSize the size of the truncated digest, in bytes |
---|
69 | //! \details TruncatedFinal() call Final() and then copies digestSize bytes to digest. |
---|
70 | //! The hash is restarted the hash for the next message. |
---|
71 | void TruncatedFinal(byte *digest, size_t digestSize); |
---|
72 | |
---|
73 | protected: |
---|
74 | inline T GetBitCountHi() const {return (m_countLo >> (8*sizeof(T)-3)) + (m_countHi << 3);} |
---|
75 | inline T GetBitCountLo() const {return m_countLo << 3;} |
---|
76 | |
---|
77 | void PadLastBlock(unsigned int lastBlockSize, byte padFirst=0x80); |
---|
78 | virtual void Init() =0; |
---|
79 | |
---|
80 | virtual ByteOrder GetByteOrder() const =0; |
---|
81 | virtual void HashEndianCorrectedBlock(const HashWordType *data) =0; |
---|
82 | virtual size_t HashMultipleBlocks(const T *input, size_t length); |
---|
83 | void HashBlock(const HashWordType *input) {HashMultipleBlocks(input, this->BlockSize());} |
---|
84 | |
---|
85 | virtual T* DataBuf() =0; |
---|
86 | virtual T* StateBuf() =0; |
---|
87 | |
---|
88 | private: |
---|
89 | T m_countLo, m_countHi; |
---|
90 | }; |
---|
91 | |
---|
92 | //! \class IteratedHash |
---|
93 | //! \brief Iterated hash base class |
---|
94 | //! \tparam T_HashWordType Hash word type |
---|
95 | //! \tparam T_Endianness Endianness type of hash |
---|
96 | //! \tparam T_BlockSize Block size of the hash |
---|
97 | //! \tparam T_Base HashTransformation derived class |
---|
98 | //! \details IteratedHash provides a default implementation for block-based iterated hashes |
---|
99 | //! \sa HashTransformation, MessageAuthenticationCode |
---|
100 | template <class T_HashWordType, class T_Endianness, unsigned int T_BlockSize, class T_Base = HashTransformation> |
---|
101 | class CRYPTOPP_NO_VTABLE IteratedHash : public IteratedHashBase<T_HashWordType, T_Base> |
---|
102 | { |
---|
103 | public: |
---|
104 | typedef T_Endianness ByteOrderClass; |
---|
105 | typedef T_HashWordType HashWordType; |
---|
106 | |
---|
107 | #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 |
---|
108 | virtual ~IteratedHash() { } |
---|
109 | #endif |
---|
110 | |
---|
111 | CRYPTOPP_CONSTANT(BLOCKSIZE = T_BlockSize) |
---|
112 | // BCB2006 workaround: can't use BLOCKSIZE here |
---|
113 | CRYPTOPP_COMPILE_ASSERT((T_BlockSize & (T_BlockSize - 1)) == 0); // blockSize is a power of 2 |
---|
114 | |
---|
115 | //! \brief Provides the block size of the hash |
---|
116 | //! \return the block size of the hash, in bytes |
---|
117 | //! \details BlockSize() returns <tt>T_BlockSize</tt>. |
---|
118 | unsigned int BlockSize() const {return T_BlockSize;} |
---|
119 | |
---|
120 | //! \brief Provides the byte order of the hash |
---|
121 | //! \returns the byte order of the hash as an enumeration |
---|
122 | //! \details GetByteOrder() returns <tt>T_Endianness::ToEnum()</tt>. |
---|
123 | //! \sa ByteOrder() |
---|
124 | ByteOrder GetByteOrder() const {return T_Endianness::ToEnum();} |
---|
125 | |
---|
126 | //! \brief Adjusts the byte ordering of the hash |
---|
127 | //! \param out the output buffer |
---|
128 | //! \param in the input buffer |
---|
129 | //! \param byteCount the size of the buffers, in bytes |
---|
130 | //! \details CorrectEndianess() calls ConditionalByteReverse() using <tt>T_Endianness</tt>. |
---|
131 | inline void CorrectEndianess(HashWordType *out, const HashWordType *in, size_t byteCount) |
---|
132 | { |
---|
133 | ConditionalByteReverse(T_Endianness::ToEnum(), out, in, byteCount); |
---|
134 | } |
---|
135 | |
---|
136 | protected: |
---|
137 | T_HashWordType* DataBuf() {return this->m_data;} |
---|
138 | FixedSizeSecBlock<T_HashWordType, T_BlockSize/sizeof(T_HashWordType)> m_data; |
---|
139 | }; |
---|
140 | |
---|
141 | //! \class IteratedHashWithStaticTransform |
---|
142 | //! \brief Iterated hash with a static transformation function |
---|
143 | //! \tparam T_HashWordType Hash word type |
---|
144 | //! \tparam T_Endianness Endianness type of hash |
---|
145 | //! \tparam T_BlockSize Block size of the hash |
---|
146 | //! \tparam T_StateSize Internal state size of the hash |
---|
147 | //! \tparam T_Transform HashTransformation derived class |
---|
148 | //! \tparam T_DigestSize Digest size of the hash |
---|
149 | //! \tparam T_StateAligned Flag indicating if state is 16-byte aligned |
---|
150 | //! \sa HashTransformation, MessageAuthenticationCode |
---|
151 | 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> |
---|
152 | class CRYPTOPP_NO_VTABLE IteratedHashWithStaticTransform |
---|
153 | : public ClonableImpl<T_Transform, AlgorithmImpl<IteratedHash<T_HashWordType, T_Endianness, T_BlockSize>, T_Transform> > |
---|
154 | { |
---|
155 | public: |
---|
156 | |
---|
157 | #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 |
---|
158 | virtual ~IteratedHashWithStaticTransform() { } |
---|
159 | #endif |
---|
160 | |
---|
161 | CRYPTOPP_CONSTANT(DIGESTSIZE = T_DigestSize ? T_DigestSize : T_StateSize) |
---|
162 | |
---|
163 | //! \brief Provides the digest size of the hash |
---|
164 | //! \return the digest size of the hash, in bytes |
---|
165 | //! \details DigestSize() returns <tt>DIGESTSIZE</tt>. |
---|
166 | unsigned int DigestSize() const {return DIGESTSIZE;}; |
---|
167 | |
---|
168 | protected: |
---|
169 | IteratedHashWithStaticTransform() {this->Init();} |
---|
170 | void HashEndianCorrectedBlock(const T_HashWordType *data) {T_Transform::Transform(this->m_state, data);} |
---|
171 | void Init() {T_Transform::InitState(this->m_state);} |
---|
172 | |
---|
173 | T_HashWordType* StateBuf() {return this->m_state;} |
---|
174 | FixedSizeAlignedSecBlock<T_HashWordType, T_BlockSize/sizeof(T_HashWordType), T_StateAligned> m_state; |
---|
175 | }; |
---|
176 | |
---|
177 | #ifndef __GNUC__ |
---|
178 | CRYPTOPP_DLL_TEMPLATE_CLASS IteratedHashBase<word64, HashTransformation>; |
---|
179 | CRYPTOPP_STATIC_TEMPLATE_CLASS IteratedHashBase<word64, MessageAuthenticationCode>; |
---|
180 | |
---|
181 | CRYPTOPP_DLL_TEMPLATE_CLASS IteratedHashBase<word32, HashTransformation>; |
---|
182 | CRYPTOPP_STATIC_TEMPLATE_CLASS IteratedHashBase<word32, MessageAuthenticationCode>; |
---|
183 | #endif |
---|
184 | |
---|
185 | NAMESPACE_END |
---|
186 | |
---|
187 | #endif |
---|