Botan  1.11.26
mdx_hash.cpp
Go to the documentation of this file.
1 /*
2 * Merkle-Damgard Hash Function
3 * (C) 1999-2008 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/mdx_hash.h>
9 #include <botan/exceptn.h>
10 #include <botan/loadstor.h>
11 
12 namespace Botan {
13 
14 /*
15 * MDx_HashFunction Constructor
16 */
18  bool byte_end,
19  bool bit_end,
20  size_t cnt_size) :
21  m_buffer(block_len),
22  BIG_BYTE_ENDIAN(byte_end),
23  BIG_BIT_ENDIAN(bit_end),
24  COUNT_SIZE(cnt_size)
25  {
26  m_count = m_position = 0;
27  }
28 
29 /*
30 * Clear memory of sensitive data
31 */
33  {
34  zeroise(m_buffer);
35  m_count = m_position = 0;
36  }
37 
38 /*
39 * Update the hash
40 */
41 void MDx_HashFunction::add_data(const byte input[], size_t length)
42  {
43  m_count += length;
44 
45  if(m_position)
46  {
47  buffer_insert(m_buffer, m_position, input, length);
48 
49  if(m_position + length >= m_buffer.size())
50  {
51  compress_n(m_buffer.data(), 1);
52  input += (m_buffer.size() - m_position);
53  length -= (m_buffer.size() - m_position);
54  m_position = 0;
55  }
56  }
57 
58  const size_t full_blocks = length / m_buffer.size();
59  const size_t remaining = length % m_buffer.size();
60 
61  if(full_blocks)
62  compress_n(input, full_blocks);
63 
64  buffer_insert(m_buffer, m_position, input + full_blocks * m_buffer.size(), remaining);
65  m_position += remaining;
66  }
67 
68 /*
69 * Finalize a hash
70 */
72  {
73  m_buffer[m_position] = (BIG_BIT_ENDIAN ? 0x80 : 0x01);
74  for(size_t i = m_position+1; i != m_buffer.size(); ++i)
75  m_buffer[i] = 0;
76 
77  if(m_position >= m_buffer.size() - COUNT_SIZE)
78  {
79  compress_n(m_buffer.data(), 1);
80  zeroise(m_buffer);
81  }
82 
83  write_count(&m_buffer[m_buffer.size() - COUNT_SIZE]);
84 
85  compress_n(m_buffer.data(), 1);
86  copy_out(output);
87  clear();
88  }
89 
90 /*
91 * Write the count bits to the buffer
92 */
94  {
95  if(COUNT_SIZE < 8)
96  throw Invalid_State("MDx_HashFunction::write_count: COUNT_SIZE < 8");
97  if(COUNT_SIZE >= output_length() || COUNT_SIZE >= hash_block_size())
98  throw Invalid_Argument("MDx_HashFunction: COUNT_SIZE is too big");
99 
100  const u64bit bit_count = m_count * 8;
101 
102  if(BIG_BYTE_ENDIAN)
103  store_be(bit_count, out + COUNT_SIZE - 8);
104  else
105  store_le(bit_count, out + COUNT_SIZE - 8);
106  }
107 
108 }
void final_result(byte output[]) override
Definition: mdx_hash.cpp:71
void clear() override
Definition: mdx_hash.cpp:32
virtual void compress_n(const byte blocks[], size_t block_n)=0
void store_le(u16bit in, byte out[2])
Definition: loadstor.h:461
size_t hash_block_size() const override
Definition: mdx_hash.h:32
virtual void write_count(byte out[])
Definition: mdx_hash.cpp:93
std::uint64_t u64bit
Definition: types.h:34
Definition: alg_id.cpp:13
void store_be(u16bit in, byte out[2])
Definition: loadstor.h:445
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
Definition: secmem.h:108
void add_data(const byte input[], size_t length) override
Definition: mdx_hash.cpp:41
virtual size_t output_length() const =0
MDx_HashFunction(size_t block_length, bool big_byte_endian, bool big_bit_endian, size_t counter_size=8)
Definition: mdx_hash.cpp:17
virtual void copy_out(byte buffer[])=0
void zeroise(std::vector< T, Alloc > &vec)
Definition: secmem.h:186
std::uint8_t byte
Definition: types.h:31