Coverage Report

Created: 2024-11-21 07:03

/src/cryptopp/blake2.h
Line
Count
Source (jump to first uncovered line)
1
// blake2.h - written and placed in the public domain by Jeffrey Walton
2
//            and Zooko Wilcox-O'Hearn. Based on Aumasson, Neves,
3
//            Wilcox-O'Hearn and Winnerlein's reference BLAKE2
4
//            implementation at http://github.com/BLAKE2/BLAKE2.
5
6
/// \file blake2.h
7
/// \brief Classes for BLAKE2b and BLAKE2s message digests and keyed message digests
8
/// \details This implementation follows Aumasson, Neves, Wilcox-O'Hearn and Winnerlein's
9
///   <A HREF="http://blake2.net/blake2.pdf">BLAKE2: simpler, smaller, fast as MD5</A> (2013.01.29).
10
///   Static algorithm name return either "BLAKE2b" or "BLAKE2s". An object algorithm name follows
11
///   the naming described in <A HREF="http://tools.ietf.org/html/rfc7693#section-4">RFC 7693, The
12
///   BLAKE2 Cryptographic Hash and Message Authentication Code (MAC)</A>.
13
/// \since C++ since Crypto++ 5.6.4, SSE since Crypto++ 5.6.4, NEON since Crypto++ 6.0,
14
///   Power8 since Crypto++ 8.0
15
16
#ifndef CRYPTOPP_BLAKE2_H
17
#define CRYPTOPP_BLAKE2_H
18
19
#include "cryptlib.h"
20
#include "secblock.h"
21
#include "seckey.h"
22
23
NAMESPACE_BEGIN(CryptoPP)
24
25
/// \brief BLAKE2s hash information
26
/// \since Crypto++ 5.6.4
27
struct BLAKE2s_Info : public VariableKeyLength<32,0,32,1,SimpleKeyingInterface::NOT_RESYNCHRONIZABLE>
28
{
29
    typedef VariableKeyLength<32,0,32,1,SimpleKeyingInterface::NOT_RESYNCHRONIZABLE> KeyBase;
30
    CRYPTOPP_CONSTANT(MIN_KEYLENGTH = KeyBase::MIN_KEYLENGTH);
31
    CRYPTOPP_CONSTANT(MAX_KEYLENGTH = KeyBase::MAX_KEYLENGTH);
32
    CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH = KeyBase::DEFAULT_KEYLENGTH);
33
34
    CRYPTOPP_CONSTANT(BLOCKSIZE = 64);
35
    CRYPTOPP_CONSTANT(DIGESTSIZE = 32);
36
    CRYPTOPP_CONSTANT(SALTSIZE = 8);
37
    CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = 8);
38
39
0
    CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "BLAKE2s";}
40
};
41
42
/// \brief BLAKE2b hash information
43
/// \since Crypto++ 5.6.4
44
struct BLAKE2b_Info : public VariableKeyLength<64,0,64,1,SimpleKeyingInterface::NOT_RESYNCHRONIZABLE>
45
{
46
    typedef VariableKeyLength<64,0,64,1,SimpleKeyingInterface::NOT_RESYNCHRONIZABLE> KeyBase;
47
    CRYPTOPP_CONSTANT(MIN_KEYLENGTH = KeyBase::MIN_KEYLENGTH);
48
    CRYPTOPP_CONSTANT(MAX_KEYLENGTH = KeyBase::MAX_KEYLENGTH);
49
    CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH = KeyBase::DEFAULT_KEYLENGTH);
50
51
    CRYPTOPP_CONSTANT(BLOCKSIZE = 128);
52
    CRYPTOPP_CONSTANT(DIGESTSIZE = 64);
53
    CRYPTOPP_CONSTANT(SALTSIZE = 16);
54
    CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = 16);
55
56
0
    CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "BLAKE2b";}
57
};
58
59
/// \brief BLAKE2s parameter block
60
struct CRYPTOPP_NO_VTABLE BLAKE2s_ParameterBlock
61
{
62
    CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2s_Info::SALTSIZE);
63
    CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2s_Info::DIGESTSIZE);
64
    CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2s_Info::PERSONALIZATIONSIZE);
65
66
    BLAKE2s_ParameterBlock()
67
355
    {
68
355
        Reset();
69
355
    }
70
71
    BLAKE2s_ParameterBlock(size_t digestSize)
72
0
    {
73
0
        Reset(digestSize);
74
0
    }
75
76
    BLAKE2s_ParameterBlock(size_t digestSize, size_t keyLength, const byte* salt, size_t saltLength,
77
        const byte* personalization, size_t personalizationLength);
78
79
    void Reset(size_t digestLength=DIGESTSIZE, size_t keyLength=0);
80
81
40.4k
    byte* data() {
82
40.4k
        return m_data.data();
83
40.4k
    }
84
85
20.2k
    const byte* data() const {
86
20.2k
        return m_data.data();
87
20.2k
    }
88
89
0
    size_t size() const {
90
0
        return m_data.size();
91
0
    }
92
93
0
    byte* salt() {
94
0
        return m_data + SaltOff;
95
0
    }
96
97
0
    byte* personalization() {
98
0
        return m_data + PersonalizationOff;
99
0
    }
100
101
    // Offsets into the byte array
102
    enum {
103
        DigestOff = 0, KeyOff = 1, FanoutOff = 2, DepthOff = 3, LeafOff = 4, NodeOff = 8,
104
        NodeDepthOff = 14, InnerOff = 15, SaltOff = 16, PersonalizationOff = 24
105
    };
106
107
    FixedSizeAlignedSecBlock<byte, 32, true> m_data;
108
};
109
110
/// \brief BLAKE2b parameter block
111
struct CRYPTOPP_NO_VTABLE BLAKE2b_ParameterBlock
112
{
113
    CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2b_Info::SALTSIZE);
114
    CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2b_Info::DIGESTSIZE);
115
    CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2b_Info::PERSONALIZATIONSIZE);
116
117
    BLAKE2b_ParameterBlock()
118
369
    {
119
369
        Reset();
120
369
    }
121
122
    BLAKE2b_ParameterBlock(size_t digestSize)
123
0
    {
124
0
        Reset(digestSize);
125
0
    }
126
127
    BLAKE2b_ParameterBlock(size_t digestSize, size_t keyLength, const byte* salt, size_t saltLength,
128
        const byte* personalization, size_t personalizationLength);
129
130
    void Reset(size_t digestLength=DIGESTSIZE, size_t keyLength=0);
131
132
21.5k
    byte* data() {
133
21.5k
        return m_data.data();
134
21.5k
    }
135
136
10.7k
    const byte* data() const {
137
10.7k
        return m_data.data();
138
10.7k
    }
139
140
0
    size_t size() const {
141
0
        return m_data.size();
142
0
    }
143
144
0
    byte* salt() {
145
0
        return m_data + SaltOff;
146
0
    }
147
148
0
    byte* personalization() {
149
0
        return m_data + PersonalizationOff;
150
0
    }
151
152
    // Offsets into the byte array
153
    enum {
154
        DigestOff = 0, KeyOff = 1, FanoutOff = 2, DepthOff = 3, LeafOff = 4, NodeOff = 8,
155
        NodeDepthOff = 16, InnerOff = 17, RfuOff = 18, SaltOff = 32, PersonalizationOff = 48
156
    };
157
158
    FixedSizeAlignedSecBlock<byte, 64, true> m_data;
159
};
160
161
/// \brief BLAKE2s state information
162
/// \since Crypto++ 5.6.4
163
struct CRYPTOPP_NO_VTABLE BLAKE2s_State
164
{
165
355
    BLAKE2s_State() {
166
355
        Reset();
167
355
    }
168
169
    void Reset();
170
171
1.96M
    inline word32* h() {
172
1.96M
        return m_hft.data();
173
1.96M
    }
174
175
981k
    inline word32* t() {
176
981k
        return m_hft.data() + 8;
177
981k
    }
178
179
19.8k
    inline word32* f() {
180
19.8k
        return m_hft.data() + 10;
181
19.8k
    }
182
183
0
    inline byte* data() {
184
0
        return m_buf.data();
185
0
    }
186
187
    // SSE4, Power7 and NEON depend upon t[] and f[] being side-by-side
188
    CRYPTOPP_CONSTANT(BLOCKSIZE = BLAKE2s_Info::BLOCKSIZE);
189
    FixedSizeAlignedSecBlock<word32, 8+2+2, true> m_hft;
190
    FixedSizeAlignedSecBlock<byte, BLOCKSIZE, true> m_buf;
191
    size_t m_len;
192
};
193
194
/// \brief BLAKE2b state information
195
/// \since Crypto++ 5.6.4
196
struct CRYPTOPP_NO_VTABLE BLAKE2b_State
197
{
198
369
    BLAKE2b_State() {
199
369
        Reset();
200
369
    }
201
202
    void Reset();
203
204
2.46M
    inline word64* h() {
205
2.46M
        return m_hft.data();
206
2.46M
    }
207
208
418k
    inline word64* t() {
209
418k
        return m_hft.data() + 8;
210
418k
    }
211
212
214k
    inline word64* f() {
213
214k
        return m_hft.data() + 10;
214
214k
    }
215
216
0
    inline byte* data() {
217
0
        return m_buf.data();
218
0
    }
219
220
    // SSE4, Power8 and NEON depend upon t[] and f[] being side-by-side
221
    CRYPTOPP_CONSTANT(BLOCKSIZE = BLAKE2b_Info::BLOCKSIZE);
222
    FixedSizeAlignedSecBlock<word64, 8+2+2, true> m_hft;
223
    FixedSizeAlignedSecBlock<byte, BLOCKSIZE, true> m_buf;
224
    size_t m_len;
225
};
226
227
/// \brief The BLAKE2s cryptographic hash function
228
/// \details BLAKE2s can function as both a hash and keyed hash. If you want only the hash,
229
///   then use the BLAKE2s constructor that accepts no parameters or digest size. If you
230
///   want a keyed hash, then use the constructor that accpts the key as a parameter.
231
///   Once a key and digest size are selected, its effectively immutable. The Restart()
232
///   method that accepts a ParameterBlock does not allow you to change it.
233
/// \sa Aumasson, Neves, Wilcox-O'Hearn and Winnerlein's
234
///   <A HREF="http://blake2.net/blake2.pdf">BLAKE2: simpler, smaller, fast as MD5</A> (2013.01.29).
235
/// \since C++ since Crypto++ 5.6.4, SSE since Crypto++ 5.6.4, NEON since Crypto++ 6.0,
236
///   Power8 since Crypto++ 8.0
237
class BLAKE2s : public SimpleKeyingInterfaceImpl<MessageAuthenticationCode, BLAKE2s_Info>
238
{
239
public:
240
    CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH = BLAKE2s_Info::DEFAULT_KEYLENGTH);
241
    CRYPTOPP_CONSTANT(MIN_KEYLENGTH = BLAKE2s_Info::MIN_KEYLENGTH);
242
    CRYPTOPP_CONSTANT(MAX_KEYLENGTH = BLAKE2s_Info::MAX_KEYLENGTH);
243
244
    CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2s_Info::DIGESTSIZE);
245
    CRYPTOPP_CONSTANT(BLOCKSIZE = BLAKE2s_Info::BLOCKSIZE);
246
    CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2s_Info::SALTSIZE);
247
    CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2s_Info::PERSONALIZATIONSIZE);
248
249
    typedef BLAKE2s_State State;
250
    typedef BLAKE2s_ParameterBlock ParameterBlock;
251
252
9
    CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "BLAKE2s";}
253
254
355
    virtual ~BLAKE2s() {}
255
256
    /// \brief Construct a BLAKE2s hash
257
    /// \param digestSize the digest size, in bytes
258
    /// \param treeMode flag indicating tree mode
259
    /// \since Crypto++ 5.6.4
260
    BLAKE2s(bool treeMode=false, unsigned int digestSize = DIGESTSIZE);
261
262
    /// \brief Construct a BLAKE2s hash
263
    /// \param digestSize the digest size, in bytes
264
    /// \details treeMode flag is set to false
265
    /// \since Crypto++ 8.2
266
    BLAKE2s(unsigned int digestSize);
267
268
    /// \brief Construct a BLAKE2s hash
269
    /// \param key a byte array used to key the cipher
270
    /// \param keyLength the size of the byte array
271
    /// \param salt a byte array used as salt
272
    /// \param saltLength the size of the byte array
273
    /// \param personalization a byte array used as personalization string
274
    /// \param personalizationLength the size of the byte array
275
    /// \param treeMode flag indicating tree mode
276
    /// \param digestSize the digest size, in bytes
277
    /// \since Crypto++ 5.6.4
278
    BLAKE2s(const byte *key, size_t keyLength, const byte* salt = NULLPTR, size_t saltLength = 0,
279
        const byte* personalization = NULLPTR, size_t personalizationLength = 0,
280
        bool treeMode=false, unsigned int digestSize = DIGESTSIZE);
281
282
    /// \brief Retrieve the object's name
283
    /// \return the object's algorithm name following RFC 7693
284
    /// \details Object algorithm name follows the naming described in
285
    ///   <A HREF="http://tools.ietf.org/html/rfc7693#section-4">RFC 7693, The BLAKE2 Cryptographic Hash and
286
    /// Message Authentication Code (MAC)</A>. For example, "BLAKE2b-512" and "BLAKE2s-256".
287
0
    std::string AlgorithmName() const {return std::string(BLAKE2s_Info::StaticAlgorithmName()) + "-" + IntToString(DigestSize()*8);}
288
289
55.9k
    unsigned int BlockSize() const {return BLOCKSIZE;}
290
57.1k
    unsigned int DigestSize() const {return m_digestSize;}
291
    unsigned int OptimalDataAlignment() const;
292
293
    void Update(const byte *input, size_t length);
294
    void Restart();
295
296
    /// \brief Restart a hash with parameter block and counter
297
    /// \param block parameter block
298
    /// \param counter counter array
299
    /// \details Parameter block is persisted across calls to Restart().
300
    void Restart(const BLAKE2s_ParameterBlock& block, const word32 counter[2]);
301
302
    /// \brief Set tree mode
303
    /// \param mode the new tree mode
304
    /// \details BLAKE2 has two finalization flags, called State::f[0] and State::f[1].
305
    ///   If <tt>treeMode=false</tt> (default), then State::f[1] is never set. If
306
    ///   <tt>treeMode=true</tt>, then State::f[1] is set when State::f[0] is set.
307
    ///   Tree mode is persisted across calls to Restart().
308
0
    void SetTreeMode(bool mode) {m_treeMode=mode;}
309
310
    /// \brief Get tree mode
311
    /// \return the current tree mode
312
    /// \details Tree mode is persisted across calls to Restart().
313
0
    bool GetTreeMode() const {return m_treeMode;}
314
315
    void TruncatedFinal(byte *hash, size_t size);
316
317
    std::string AlgorithmProvider() const;
318
319
protected:
320
    // Operates on state buffer and/or input. Must be BLOCKSIZE, final block will pad with 0's.
321
    void Compress(const byte *input);
322
    inline void IncrementCounter(size_t count=BLOCKSIZE);
323
324
    void UncheckedSetKey(const byte* key, unsigned int length, const CryptoPP::NameValuePairs& params);
325
326
private:
327
    State m_state;
328
    ParameterBlock m_block;
329
    AlignedSecByteBlock m_key;
330
    word32 m_digestSize, m_keyLength;
331
    bool m_treeMode;
332
};
333
334
/// \brief The BLAKE2b cryptographic hash function
335
/// \details BLAKE2b can function as both a hash and keyed hash. If you want only the hash,
336
///   then use the BLAKE2b constructor that accepts no parameters or digest size. If you
337
///   want a keyed hash, then use the constructor that accpts the key as a parameter.
338
///   Once a key and digest size are selected, its effectively immutable. The Restart()
339
///   method that accepts a ParameterBlock does not allow you to change it.
340
/// \sa Aumasson, Neves, Wilcox-O'Hearn and Winnerlein's
341
///   <A HREF="http://blake2.net/blake2.pdf">BLAKE2: simpler, smaller, fast as MD5</A> (2013.01.29).
342
/// \since C++ since Crypto++ 5.6.4, SSE since Crypto++ 5.6.4, NEON since Crypto++ 6.0,
343
///   Power8 since Crypto++ 8.0
344
class BLAKE2b : public SimpleKeyingInterfaceImpl<MessageAuthenticationCode, BLAKE2b_Info>
345
{
346
public:
347
    CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH = BLAKE2b_Info::DEFAULT_KEYLENGTH);
348
    CRYPTOPP_CONSTANT(MIN_KEYLENGTH = BLAKE2b_Info::MIN_KEYLENGTH);
349
    CRYPTOPP_CONSTANT(MAX_KEYLENGTH = BLAKE2b_Info::MAX_KEYLENGTH);
350
351
    CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2b_Info::DIGESTSIZE);
352
    CRYPTOPP_CONSTANT(BLOCKSIZE = BLAKE2b_Info::BLOCKSIZE);
353
    CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2b_Info::SALTSIZE);
354
    CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2b_Info::PERSONALIZATIONSIZE);
355
356
    typedef BLAKE2b_State State;
357
    typedef BLAKE2b_ParameterBlock ParameterBlock;
358
359
2
    CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "BLAKE2b";}
360
361
369
    virtual ~BLAKE2b() {}
362
363
    /// \brief Construct a BLAKE2b hash
364
    /// \param digestSize the digest size, in bytes
365
    /// \param treeMode flag indicating tree mode
366
    /// \since Crypto++ 5.6.4
367
    BLAKE2b(bool treeMode=false, unsigned int digestSize = DIGESTSIZE);
368
369
    /// \brief Construct a BLAKE2s hash
370
    /// \param digestSize the digest size, in bytes
371
    /// \details treeMode flag is set to false
372
    /// \since Crypto++ 8.2
373
    BLAKE2b(unsigned int digestSize);
374
375
    /// \brief Construct a BLAKE2b hash
376
    /// \param key a byte array used to key the cipher
377
    /// \param keyLength the size of the byte array
378
    /// \param salt a byte array used as salt
379
    /// \param saltLength the size of the byte array
380
    /// \param personalization a byte array used as personalization string
381
    /// \param personalizationLength the size of the byte array
382
    /// \param treeMode flag indicating tree mode
383
    /// \param digestSize the digest size, in bytes
384
    /// \since Crypto++ 5.6.4
385
    BLAKE2b(const byte *key, size_t keyLength, const byte* salt = NULLPTR, size_t saltLength = 0,
386
        const byte* personalization = NULLPTR, size_t personalizationLength = 0,
387
        bool treeMode=false, unsigned int digestSize = DIGESTSIZE);
388
389
    /// \brief Retrieve the object's name
390
    /// \return the object's algorithm name following RFC 7693
391
    /// \details Object algorithm name follows the naming described in
392
    ///   <A HREF="http://tools.ietf.org/html/rfc7693#section-4">RFC 7693, The BLAKE2 Cryptographic Hash and
393
    /// Message Authentication Code (MAC)</A>. For example, "BLAKE2b-512" and "BLAKE2s-256".
394
0
    std::string AlgorithmName() const {return std::string(BLAKE2b_Info::StaticAlgorithmName()) + "-" + IntToString(DigestSize()*8);}
395
396
42.1k
    unsigned int BlockSize() const {return BLOCKSIZE;}
397
28.9k
    unsigned int DigestSize() const {return m_digestSize;}
398
    unsigned int OptimalDataAlignment() const;
399
400
    void Update(const byte *input, size_t length);
401
    void Restart();
402
403
    /// \brief Restart a hash with parameter block and counter
404
    /// \param block parameter block
405
    /// \param counter counter array
406
    /// \details Parameter block is persisted across calls to Restart().
407
    void Restart(const BLAKE2b_ParameterBlock& block, const word64 counter[2]);
408
409
    /// \brief Set tree mode
410
    /// \param mode the new tree mode
411
    /// \details BLAKE2 has two finalization flags, called State::f[0] and State::f[1].
412
    ///   If <tt>treeMode=false</tt> (default), then State::f[1] is never set. If
413
    ///   <tt>treeMode=true</tt>, then State::f[1] is set when State::f[0] is set.
414
    ///   Tree mode is persisted across calls to Restart().
415
0
    void SetTreeMode(bool mode) {m_treeMode=mode;}
416
417
    /// \brief Get tree mode
418
    /// \return the current tree mode
419
    /// \details Tree mode is persisted across calls to Restart().
420
0
    bool GetTreeMode() const {return m_treeMode;}
421
422
    void TruncatedFinal(byte *hash, size_t size);
423
424
    std::string AlgorithmProvider() const;
425
426
protected:
427
428
    // Operates on state buffer and/or input. Must be BLOCKSIZE, final block will pad with 0's.
429
    void Compress(const byte *input);
430
    inline void IncrementCounter(size_t count=BLOCKSIZE);
431
432
    void UncheckedSetKey(const byte* key, unsigned int length, const CryptoPP::NameValuePairs& params);
433
434
private:
435
    State m_state;
436
    ParameterBlock m_block;
437
    AlignedSecByteBlock m_key;
438
    word32 m_digestSize, m_keyLength;
439
    bool m_treeMode;
440
};
441
442
NAMESPACE_END
443
444
#endif