Botan  2.7.0
Crypto and TLS for C++11
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  m_count(0),
23  m_position(0),
24  BIG_BYTE_ENDIAN(byte_end),
25  BIG_BIT_ENDIAN(bit_end),
26  COUNT_SIZE(cnt_size)
27  {
28  }
29 
30 /*
31 * Clear memory of sensitive data
32 */
34  {
35  zeroise(m_buffer);
36  m_count = m_position = 0;
37  }
38 
39 /*
40 * Update the hash
41 */
42 void MDx_HashFunction::add_data(const uint8_t input[], size_t length)
43  {
44  m_count += length;
45 
46  if(m_position)
47  {
48  buffer_insert(m_buffer, m_position, input, length);
49 
50  if(m_position + length >= m_buffer.size())
51  {
52  compress_n(m_buffer.data(), 1);
53  input += (m_buffer.size() - m_position);
54  length -= (m_buffer.size() - m_position);
55  m_position = 0;
56  }
57  }
58 
59  const size_t full_blocks = length / m_buffer.size();
60  const size_t remaining = length % m_buffer.size();
61 
62  if(full_blocks)
63  compress_n(input, full_blocks);
64 
65  buffer_insert(m_buffer, m_position, input + full_blocks * m_buffer.size(), remaining);
66  m_position += remaining;
67  }
68 
69 /*
70 * Finalize a hash
71 */
72 void MDx_HashFunction::final_result(uint8_t output[])
73  {
74  clear_mem(&m_buffer[m_position], m_buffer.size() - m_position);
75  m_buffer[m_position] = (BIG_BIT_ENDIAN ? 0x80 : 0x01);
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 */
93 void MDx_HashFunction::write_count(uint8_t out[])
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 uint64_t 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 clear() override
Definition: mdx_hash.cpp:33
void store_be(uint16_t in, uint8_t out[2])
Definition: loadstor.h:434
void clear_mem(T *ptr, size_t n)
Definition: mem_ops.h:97
size_t hash_block_size() const override final
Definition: mdx_hash.h:32
virtual void compress_n(const uint8_t blocks[], size_t block_n)=0
void add_data(const uint8_t input[], size_t length) override final
Definition: mdx_hash.cpp:42
virtual void copy_out(uint8_t buffer[])=0
Definition: alg_id.cpp:13
virtual void write_count(uint8_t out[])
Definition: mdx_hash.cpp:93
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
Definition: secmem.h:103
virtual size_t output_length() const =0
void final_result(uint8_t output[]) override final
Definition: mdx_hash.cpp:72
MDx_HashFunction(size_t block_length, bool big_byte_endian, bool big_bit_endian, size_t counter_size=8)
Definition: mdx_hash.cpp:17
void store_le(uint16_t in, uint8_t out[2])
Definition: loadstor.h:450
void zeroise(std::vector< T, Alloc > &vec)
Definition: secmem.h:183