Coverage Report

Created: 2021-02-21 07:20

/src/botan/src/lib/hash/comb4p/comb4p.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* Comb4P hash combiner
3
* (C) 2010 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#include <botan/internal/comb4p.h>
9
#include <botan/exceptn.h>
10
11
namespace Botan {
12
13
namespace {
14
15
void comb4p_round(secure_vector<uint8_t>& out,
16
                  const secure_vector<uint8_t>& in,
17
                  uint8_t round_no,
18
                  HashFunction& h1,
19
                  HashFunction& h2)
20
0
   {
21
0
   h1.update(round_no);
22
0
   h2.update(round_no);
23
24
0
   h1.update(in.data(), in.size());
25
0
   h2.update(in.data(), in.size());
26
27
0
   secure_vector<uint8_t> h_buf = h1.final();
28
0
   xor_buf(out.data(), h_buf.data(), std::min(out.size(), h_buf.size()));
29
30
0
   h_buf = h2.final();
31
0
   xor_buf(out.data(), h_buf.data(), std::min(out.size(), h_buf.size()));
32
0
   }
33
34
}
35
36
Comb4P::Comb4P(HashFunction* h1, HashFunction* h2) :
37
   m_hash1(h1), m_hash2(h2)
38
0
   {
39
0
   if(m_hash1->name() == m_hash2->name())
40
0
      throw Invalid_Argument("Comb4P: Must use two distinct hashes");
41
42
0
   if(m_hash1->output_length() != m_hash2->output_length())
43
0
      throw Invalid_Argument("Comb4P: Incompatible hashes " +
44
0
                                  m_hash1->name() + " and " +
45
0
                                  m_hash2->name());
46
47
0
   clear();
48
0
   }
49
50
size_t Comb4P::hash_block_size() const
51
0
   {
52
0
   if(m_hash1->hash_block_size() == m_hash2->hash_block_size())
53
0
      return m_hash1->hash_block_size();
54
55
   /*
56
   * Return LCM of the block sizes? This would probably be OK for
57
   * HMAC, which is the main thing relying on knowing the block size.
58
   */
59
0
   return 0;
60
0
   }
61
62
void Comb4P::clear()
63
0
   {
64
0
   m_hash1->clear();
65
0
   m_hash2->clear();
66
67
   // Prep for processing next message, if any
68
0
   m_hash1->update(0);
69
0
   m_hash2->update(0);
70
0
   }
71
72
std::unique_ptr<HashFunction> Comb4P::copy_state() const
73
0
   {
74
0
   std::unique_ptr<Comb4P> copy(new Comb4P);
75
0
   copy->m_hash1 = m_hash1->copy_state();
76
0
   copy->m_hash2 = m_hash2->copy_state();
77
   // work around GCC 4.8 bug
78
0
   return std::unique_ptr<HashFunction>(copy.release());
79
0
   }
80
81
void Comb4P::add_data(const uint8_t input[], size_t length)
82
0
   {
83
0
   m_hash1->update(input, length);
84
0
   m_hash2->update(input, length);
85
0
   }
86
87
void Comb4P::final_result(uint8_t out[])
88
0
   {
89
0
   secure_vector<uint8_t> h1 = m_hash1->final();
90
0
   secure_vector<uint8_t> h2 = m_hash2->final();
91
92
   // First round
93
0
   xor_buf(h1.data(), h2.data(), std::min(h1.size(), h2.size()));
94
95
   // Second round
96
0
   comb4p_round(h2, h1, 1, *m_hash1, *m_hash2);
97
98
   // Third round
99
0
   comb4p_round(h1, h2, 2, *m_hash1, *m_hash2);
100
101
0
   copy_mem(out            , h1.data(), h1.size());
102
0
   copy_mem(out + h1.size(), h2.data(), h2.size());
103
104
   // Prep for processing next message, if any
105
0
   m_hash1->update(0);
106
0
   m_hash2->update(0);
107
0
   }
108
109
}
110