Coverage Report

Created: 2024-06-28 06:39

/src/botan/src/lib/hash/blake2/blake2b.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* BLAKE2b
3
* (C) 2016 cynecx
4
* (C) 2017 Jack Lloyd
5
*
6
* Botan is released under the Simplified BSD License (see license.txt)
7
*/
8
9
#include <botan/internal/blake2b.h>
10
11
#include <botan/exceptn.h>
12
#include <botan/mem_ops.h>
13
#include <botan/internal/fmt.h>
14
#include <botan/internal/loadstor.h>
15
#include <botan/internal/rotate.h>
16
#include <botan/internal/stl_util.h>
17
18
#include <algorithm>
19
#include <array>
20
21
namespace Botan {
22
23
namespace {
24
25
constexpr std::array<uint64_t, 8> blake2b_IV{0x6a09e667f3bcc908,
26
                                             0xbb67ae8584caa73b,
27
                                             0x3c6ef372fe94f82b,
28
                                             0xa54ff53a5f1d36f1,
29
                                             0x510e527fade682d1,
30
                                             0x9b05688c2b3e6c1f,
31
                                             0x1f83d9abfb41bd6b,
32
                                             0x5be0cd19137e2179};
33
34
}  // namespace
35
36
1.29k
BLAKE2b::BLAKE2b(size_t output_bits) : m_output_bits(output_bits), m_H(blake2b_IV.size()), m_T(), m_F(), m_key_size(0) {
37
1.29k
   if(output_bits == 0 || output_bits > 512 || output_bits % 8 != 0) {
38
0
      throw Invalid_Argument("Bad output bits size for BLAKE2b");
39
0
   }
40
41
1.29k
   state_init();
42
1.29k
}
43
44
1.74M
void BLAKE2b::state_init() {
45
1.74M
   copy_mem(m_H.data(), blake2b_IV.data(), blake2b_IV.size());
46
1.74M
   m_H[0] ^= (0x01010000 | (static_cast<uint8_t>(m_key_size) << 8) | static_cast<uint8_t>(output_length()));
47
1.74M
   m_T[0] = m_T[1] = 0;
48
1.74M
   m_F = 0;
49
50
1.74M
   m_buffer.clear();
51
1.74M
   if(m_key_size > 0) {
52
164
      m_buffer.append(m_padded_key_buffer);
53
164
   }
54
1.74M
}
55
56
namespace {
57
58
175M
BOTAN_FORCE_INLINE void G(uint64_t& a, uint64_t& b, uint64_t& c, uint64_t& d, uint64_t M0, uint64_t M1) {
59
175M
   a = a + b + M0;
60
175M
   d = rotr<32>(d ^ a);
61
175M
   c = c + d;
62
175M
   b = rotr<24>(b ^ c);
63
175M
   a = a + b + M1;
64
175M
   d = rotr<16>(d ^ a);
65
175M
   c = c + d;
66
175M
   b = rotr<63>(b ^ c);
67
175M
}
68
69
template <size_t i0,
70
          size_t i1,
71
          size_t i2,
72
          size_t i3,
73
          size_t i4,
74
          size_t i5,
75
          size_t i6,
76
          size_t i7,
77
          size_t i8,
78
          size_t i9,
79
          size_t iA,
80
          size_t iB,
81
          size_t iC,
82
          size_t iD,
83
          size_t iE,
84
          size_t iF>
85
21.9M
BOTAN_FORCE_INLINE void ROUND(uint64_t* v, const uint64_t* M) {
86
21.9M
   G(v[0], v[4], v[8], v[12], M[i0], M[i1]);
87
21.9M
   G(v[1], v[5], v[9], v[13], M[i2], M[i3]);
88
21.9M
   G(v[2], v[6], v[10], v[14], M[i4], M[i5]);
89
21.9M
   G(v[3], v[7], v[11], v[15], M[i6], M[i7]);
90
21.9M
   G(v[0], v[5], v[10], v[15], M[i8], M[i9]);
91
21.9M
   G(v[1], v[6], v[11], v[12], M[iA], M[iB]);
92
21.9M
   G(v[2], v[7], v[8], v[13], M[iC], M[iD]);
93
21.9M
   G(v[3], v[4], v[9], v[14], M[iE], M[iF]);
94
21.9M
}
blake2b.cpp:void Botan::(anonymous namespace)::ROUND<0ul, 1ul, 2ul, 3ul, 4ul, 5ul, 6ul, 7ul, 8ul, 9ul, 10ul, 11ul, 12ul, 13ul, 14ul, 15ul>(unsigned long*, unsigned long const*)
Line
Count
Source
85
3.65M
BOTAN_FORCE_INLINE void ROUND(uint64_t* v, const uint64_t* M) {
86
3.65M
   G(v[0], v[4], v[8], v[12], M[i0], M[i1]);
87
3.65M
   G(v[1], v[5], v[9], v[13], M[i2], M[i3]);
88
3.65M
   G(v[2], v[6], v[10], v[14], M[i4], M[i5]);
89
3.65M
   G(v[3], v[7], v[11], v[15], M[i6], M[i7]);
90
3.65M
   G(v[0], v[5], v[10], v[15], M[i8], M[i9]);
91
3.65M
   G(v[1], v[6], v[11], v[12], M[iA], M[iB]);
92
3.65M
   G(v[2], v[7], v[8], v[13], M[iC], M[iD]);
93
3.65M
   G(v[3], v[4], v[9], v[14], M[iE], M[iF]);
94
3.65M
}
blake2b.cpp:void Botan::(anonymous namespace)::ROUND<14ul, 10ul, 4ul, 8ul, 9ul, 15ul, 13ul, 6ul, 1ul, 12ul, 0ul, 2ul, 11ul, 7ul, 5ul, 3ul>(unsigned long*, unsigned long const*)
Line
Count
Source
85
3.65M
BOTAN_FORCE_INLINE void ROUND(uint64_t* v, const uint64_t* M) {
86
3.65M
   G(v[0], v[4], v[8], v[12], M[i0], M[i1]);
87
3.65M
   G(v[1], v[5], v[9], v[13], M[i2], M[i3]);
88
3.65M
   G(v[2], v[6], v[10], v[14], M[i4], M[i5]);
89
3.65M
   G(v[3], v[7], v[11], v[15], M[i6], M[i7]);
90
3.65M
   G(v[0], v[5], v[10], v[15], M[i8], M[i9]);
91
3.65M
   G(v[1], v[6], v[11], v[12], M[iA], M[iB]);
92
3.65M
   G(v[2], v[7], v[8], v[13], M[iC], M[iD]);
93
3.65M
   G(v[3], v[4], v[9], v[14], M[iE], M[iF]);
94
3.65M
}
blake2b.cpp:void Botan::(anonymous namespace)::ROUND<11ul, 8ul, 12ul, 0ul, 5ul, 2ul, 15ul, 13ul, 10ul, 14ul, 3ul, 6ul, 7ul, 1ul, 9ul, 4ul>(unsigned long*, unsigned long const*)
Line
Count
Source
85
1.82M
BOTAN_FORCE_INLINE void ROUND(uint64_t* v, const uint64_t* M) {
86
1.82M
   G(v[0], v[4], v[8], v[12], M[i0], M[i1]);
87
1.82M
   G(v[1], v[5], v[9], v[13], M[i2], M[i3]);
88
1.82M
   G(v[2], v[6], v[10], v[14], M[i4], M[i5]);
89
1.82M
   G(v[3], v[7], v[11], v[15], M[i6], M[i7]);
90
1.82M
   G(v[0], v[5], v[10], v[15], M[i8], M[i9]);
91
1.82M
   G(v[1], v[6], v[11], v[12], M[iA], M[iB]);
92
1.82M
   G(v[2], v[7], v[8], v[13], M[iC], M[iD]);
93
1.82M
   G(v[3], v[4], v[9], v[14], M[iE], M[iF]);
94
1.82M
}
blake2b.cpp:void Botan::(anonymous namespace)::ROUND<7ul, 9ul, 3ul, 1ul, 13ul, 12ul, 11ul, 14ul, 2ul, 6ul, 5ul, 10ul, 4ul, 0ul, 15ul, 8ul>(unsigned long*, unsigned long const*)
Line
Count
Source
85
1.82M
BOTAN_FORCE_INLINE void ROUND(uint64_t* v, const uint64_t* M) {
86
1.82M
   G(v[0], v[4], v[8], v[12], M[i0], M[i1]);
87
1.82M
   G(v[1], v[5], v[9], v[13], M[i2], M[i3]);
88
1.82M
   G(v[2], v[6], v[10], v[14], M[i4], M[i5]);
89
1.82M
   G(v[3], v[7], v[11], v[15], M[i6], M[i7]);
90
1.82M
   G(v[0], v[5], v[10], v[15], M[i8], M[i9]);
91
1.82M
   G(v[1], v[6], v[11], v[12], M[iA], M[iB]);
92
1.82M
   G(v[2], v[7], v[8], v[13], M[iC], M[iD]);
93
1.82M
   G(v[3], v[4], v[9], v[14], M[iE], M[iF]);
94
1.82M
}
blake2b.cpp:void Botan::(anonymous namespace)::ROUND<9ul, 0ul, 5ul, 7ul, 2ul, 4ul, 10ul, 15ul, 14ul, 1ul, 11ul, 12ul, 6ul, 8ul, 3ul, 13ul>(unsigned long*, unsigned long const*)
Line
Count
Source
85
1.82M
BOTAN_FORCE_INLINE void ROUND(uint64_t* v, const uint64_t* M) {
86
1.82M
   G(v[0], v[4], v[8], v[12], M[i0], M[i1]);
87
1.82M
   G(v[1], v[5], v[9], v[13], M[i2], M[i3]);
88
1.82M
   G(v[2], v[6], v[10], v[14], M[i4], M[i5]);
89
1.82M
   G(v[3], v[7], v[11], v[15], M[i6], M[i7]);
90
1.82M
   G(v[0], v[5], v[10], v[15], M[i8], M[i9]);
91
1.82M
   G(v[1], v[6], v[11], v[12], M[iA], M[iB]);
92
1.82M
   G(v[2], v[7], v[8], v[13], M[iC], M[iD]);
93
1.82M
   G(v[3], v[4], v[9], v[14], M[iE], M[iF]);
94
1.82M
}
blake2b.cpp:void Botan::(anonymous namespace)::ROUND<2ul, 12ul, 6ul, 10ul, 0ul, 11ul, 8ul, 3ul, 4ul, 13ul, 7ul, 5ul, 15ul, 14ul, 1ul, 9ul>(unsigned long*, unsigned long const*)
Line
Count
Source
85
1.82M
BOTAN_FORCE_INLINE void ROUND(uint64_t* v, const uint64_t* M) {
86
1.82M
   G(v[0], v[4], v[8], v[12], M[i0], M[i1]);
87
1.82M
   G(v[1], v[5], v[9], v[13], M[i2], M[i3]);
88
1.82M
   G(v[2], v[6], v[10], v[14], M[i4], M[i5]);
89
1.82M
   G(v[3], v[7], v[11], v[15], M[i6], M[i7]);
90
1.82M
   G(v[0], v[5], v[10], v[15], M[i8], M[i9]);
91
1.82M
   G(v[1], v[6], v[11], v[12], M[iA], M[iB]);
92
1.82M
   G(v[2], v[7], v[8], v[13], M[iC], M[iD]);
93
1.82M
   G(v[3], v[4], v[9], v[14], M[iE], M[iF]);
94
1.82M
}
blake2b.cpp:void Botan::(anonymous namespace)::ROUND<12ul, 5ul, 1ul, 15ul, 14ul, 13ul, 4ul, 10ul, 0ul, 7ul, 6ul, 3ul, 9ul, 2ul, 8ul, 11ul>(unsigned long*, unsigned long const*)
Line
Count
Source
85
1.82M
BOTAN_FORCE_INLINE void ROUND(uint64_t* v, const uint64_t* M) {
86
1.82M
   G(v[0], v[4], v[8], v[12], M[i0], M[i1]);
87
1.82M
   G(v[1], v[5], v[9], v[13], M[i2], M[i3]);
88
1.82M
   G(v[2], v[6], v[10], v[14], M[i4], M[i5]);
89
1.82M
   G(v[3], v[7], v[11], v[15], M[i6], M[i7]);
90
1.82M
   G(v[0], v[5], v[10], v[15], M[i8], M[i9]);
91
1.82M
   G(v[1], v[6], v[11], v[12], M[iA], M[iB]);
92
1.82M
   G(v[2], v[7], v[8], v[13], M[iC], M[iD]);
93
1.82M
   G(v[3], v[4], v[9], v[14], M[iE], M[iF]);
94
1.82M
}
blake2b.cpp:void Botan::(anonymous namespace)::ROUND<13ul, 11ul, 7ul, 14ul, 12ul, 1ul, 3ul, 9ul, 5ul, 0ul, 15ul, 4ul, 8ul, 6ul, 2ul, 10ul>(unsigned long*, unsigned long const*)
Line
Count
Source
85
1.82M
BOTAN_FORCE_INLINE void ROUND(uint64_t* v, const uint64_t* M) {
86
1.82M
   G(v[0], v[4], v[8], v[12], M[i0], M[i1]);
87
1.82M
   G(v[1], v[5], v[9], v[13], M[i2], M[i3]);
88
1.82M
   G(v[2], v[6], v[10], v[14], M[i4], M[i5]);
89
1.82M
   G(v[3], v[7], v[11], v[15], M[i6], M[i7]);
90
1.82M
   G(v[0], v[5], v[10], v[15], M[i8], M[i9]);
91
1.82M
   G(v[1], v[6], v[11], v[12], M[iA], M[iB]);
92
1.82M
   G(v[2], v[7], v[8], v[13], M[iC], M[iD]);
93
1.82M
   G(v[3], v[4], v[9], v[14], M[iE], M[iF]);
94
1.82M
}
blake2b.cpp:void Botan::(anonymous namespace)::ROUND<6ul, 15ul, 14ul, 9ul, 11ul, 3ul, 0ul, 8ul, 12ul, 2ul, 13ul, 7ul, 1ul, 4ul, 10ul, 5ul>(unsigned long*, unsigned long const*)
Line
Count
Source
85
1.82M
BOTAN_FORCE_INLINE void ROUND(uint64_t* v, const uint64_t* M) {
86
1.82M
   G(v[0], v[4], v[8], v[12], M[i0], M[i1]);
87
1.82M
   G(v[1], v[5], v[9], v[13], M[i2], M[i3]);
88
1.82M
   G(v[2], v[6], v[10], v[14], M[i4], M[i5]);
89
1.82M
   G(v[3], v[7], v[11], v[15], M[i6], M[i7]);
90
1.82M
   G(v[0], v[5], v[10], v[15], M[i8], M[i9]);
91
1.82M
   G(v[1], v[6], v[11], v[12], M[iA], M[iB]);
92
1.82M
   G(v[2], v[7], v[8], v[13], M[iC], M[iD]);
93
1.82M
   G(v[3], v[4], v[9], v[14], M[iE], M[iF]);
94
1.82M
}
blake2b.cpp:void Botan::(anonymous namespace)::ROUND<10ul, 2ul, 8ul, 4ul, 7ul, 6ul, 1ul, 5ul, 15ul, 11ul, 9ul, 14ul, 3ul, 12ul, 13ul, 0ul>(unsigned long*, unsigned long const*)
Line
Count
Source
85
1.82M
BOTAN_FORCE_INLINE void ROUND(uint64_t* v, const uint64_t* M) {
86
1.82M
   G(v[0], v[4], v[8], v[12], M[i0], M[i1]);
87
1.82M
   G(v[1], v[5], v[9], v[13], M[i2], M[i3]);
88
1.82M
   G(v[2], v[6], v[10], v[14], M[i4], M[i5]);
89
1.82M
   G(v[3], v[7], v[11], v[15], M[i6], M[i7]);
90
1.82M
   G(v[0], v[5], v[10], v[15], M[i8], M[i9]);
91
1.82M
   G(v[1], v[6], v[11], v[12], M[iA], M[iB]);
92
1.82M
   G(v[2], v[7], v[8], v[13], M[iC], M[iD]);
93
1.82M
   G(v[3], v[4], v[9], v[14], M[iE], M[iF]);
94
1.82M
}
95
96
}  // namespace
97
98
1.76M
void BLAKE2b::compress(const uint8_t* input, size_t blocks, uint64_t increment) {
99
3.59M
   for(size_t b = 0; b != blocks; ++b) {
100
1.82M
      m_T[0] += increment;
101
1.82M
      if(m_T[0] < increment) {
102
0
         m_T[1]++;
103
0
      }
104
105
1.82M
      uint64_t M[16];
106
1.82M
      uint64_t v[16];
107
1.82M
      load_le(M, input, 16);
108
109
1.82M
      input += BLAKE2B_BLOCKBYTES;
110
111
16.4M
      for(size_t i = 0; i < 8; i++) {
112
14.6M
         v[i] = m_H[i];
113
14.6M
      }
114
16.4M
      for(size_t i = 0; i != 8; ++i) {
115
14.6M
         v[i + 8] = blake2b_IV[i];
116
14.6M
      }
117
118
1.82M
      v[12] ^= m_T[0];
119
1.82M
      v[13] ^= m_T[1];
120
1.82M
      v[14] ^= m_F;
121
122
1.82M
      ROUND<0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15>(v, M);
123
1.82M
      ROUND<14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3>(v, M);
124
1.82M
      ROUND<11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4>(v, M);
125
1.82M
      ROUND<7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8>(v, M);
126
1.82M
      ROUND<9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13>(v, M);
127
1.82M
      ROUND<2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9>(v, M);
128
1.82M
      ROUND<12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11>(v, M);
129
1.82M
      ROUND<13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10>(v, M);
130
1.82M
      ROUND<6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5>(v, M);
131
1.82M
      ROUND<10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0>(v, M);
132
1.82M
      ROUND<0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15>(v, M);
133
1.82M
      ROUND<14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3>(v, M);
134
135
16.4M
      for(size_t i = 0; i < 8; i++) {
136
14.6M
         m_H[i] ^= v[i] ^ v[i + 8];
137
14.6M
      }
138
1.82M
   }
139
1.76M
}
140
141
2.01M
void BLAKE2b::add_data(std::span<const uint8_t> input) {
142
2.01M
   BufferSlicer in(input);
143
144
4.01M
   while(!in.empty()) {
145
2.00M
      if(const auto one_block = m_buffer.handle_unaligned_data(in)) {
146
23.6k
         compress(one_block->data(), 1, BLAKE2B_BLOCKBYTES);
147
23.6k
      }
148
149
2.00M
      if(m_buffer.in_alignment()) {
150
23.6k
         const auto [aligned_data, full_blocks] = m_buffer.aligned_data_to_process(in);
151
23.6k
         if(full_blocks > 0) {
152
1.48k
            compress(aligned_data.data(), full_blocks, BLAKE2B_BLOCKBYTES);
153
1.48k
         }
154
23.6k
      }
155
2.00M
   }
156
2.01M
}
157
158
1.74M
void BLAKE2b::final_result(std::span<uint8_t> output) {
159
1.74M
   const auto pos = m_buffer.elements_in_buffer();
160
1.74M
   m_buffer.fill_up_with_zeros();
161
162
1.74M
   m_F = 0xFFFFFFFFFFFFFFFF;
163
1.74M
   compress(m_buffer.consume().data(), 1, pos);
164
1.74M
   copy_out_le(output.first(output_length()), m_H);
165
1.74M
   state_init();
166
1.74M
}
167
168
210
Key_Length_Specification BLAKE2b::key_spec() const {
169
210
   return Key_Length_Specification(1, 64);
170
210
}
171
172
46
std::string BLAKE2b::name() const {
173
46
   return fmt("BLAKE2b({})", m_output_bits);
174
46
}
175
176
189
std::unique_ptr<HashFunction> BLAKE2b::new_object() const {
177
189
   return std::make_unique<BLAKE2b>(m_output_bits);
178
189
}
179
180
0
std::unique_ptr<HashFunction> BLAKE2b::copy_state() const {
181
0
   return std::make_unique<BLAKE2b>(*this);
182
0
}
183
184
4.41k
bool BLAKE2b::has_keying_material() const {
185
4.41k
   return m_key_size > 0;
186
4.41k
}
187
188
82
void BLAKE2b::key_schedule(std::span<const uint8_t> key) {
189
82
   BOTAN_ASSERT_NOMSG(key.size() <= m_buffer.size());
190
191
82
   m_key_size = key.size();
192
82
   m_padded_key_buffer.resize(m_buffer.size());
193
194
82
   if(m_padded_key_buffer.size() > m_key_size) {
195
82
      size_t padding = m_padded_key_buffer.size() - m_key_size;
196
82
      clear_mem(m_padded_key_buffer.data() + m_key_size, padding);
197
82
   }
198
199
82
   copy_mem(m_padded_key_buffer.data(), key.data(), key.size());
200
82
   state_init();
201
82
}
202
203
164
void BLAKE2b::clear() {
204
164
   zeroise(m_H);
205
164
   m_buffer.clear();
206
164
   zeroise(m_padded_key_buffer);
207
164
   m_key_size = 0;
208
164
   state_init();
209
164
}
210
211
}  // namespace Botan