Coverage Report

Created: 2024-11-21 07:03

/src/cryptopp/chacha.h
Line
Count
Source (jump to first uncovered line)
1
// chacha.h - written and placed in the public domain by Jeffrey Walton.
2
//            Based on Wei Dai's Salsa20, Botan's SSE2 implementation,
3
//            and Bernstein's reference ChaCha family implementation at
4
//            http://cr.yp.to/chacha.html.
5
6
// The library added Bernstein's ChaCha classes at Crypto++ 5.6.4. The IETF
7
// uses a slightly different implementation than Bernstein, and the IETF
8
// ChaCha and XChaCha classes were added at Crypto++ 8.1. We wanted to maintain
9
// ABI compatibility at the 8.1 release so the original ChaCha classes were not
10
// disturbed. Instead new classes were added for IETF ChaCha. The back-end
11
// implementation shares code as expected, however.
12
13
/// \file chacha.h
14
/// \brief Classes for ChaCha8, ChaCha12 and ChaCha20 stream ciphers
15
/// \details Crypto++ provides Bernstein and ECRYPT's ChaCha from <a
16
///  href="http://cr.yp.to/chacha/chacha-20080128.pdf">ChaCha, a
17
///  variant of Salsa20</a> (2008.01.28). Crypto++ also provides the
18
///  IETF implementation of ChaCha using the ChaChaTLS name. Bernstein's
19
///  implementation is _slightly_ different from the TLS working group's
20
///  implementation for cipher suites
21
///  <tt>TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256</tt>,
22
///  <tt>TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256</tt>,
23
///  and <tt>TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256</tt>. Finally,
24
///  the library provides <a
25
///  href="https://tools.ietf.org/html/draft-arciszewski-xchacha">XChaCha:
26
///  eXtended-nonce ChaCha and AEAD_XChaCha20_Poly1305 (rev. 03)</a>.
27
/// \since ChaCha since Crypto++ 5.6.4, ChaChaTLS and XChaCha20 since Crypto++ 8.1
28
29
#ifndef CRYPTOPP_CHACHA_H
30
#define CRYPTOPP_CHACHA_H
31
32
#include "strciphr.h"
33
#include "secblock.h"
34
35
NAMESPACE_BEGIN(CryptoPP)
36
37
////////////////////////////// Bernstein ChaCha //////////////////////////////
38
39
/// \brief ChaCha stream cipher information
40
/// \since Crypto++ 5.6.4
41
struct ChaCha_Info : public VariableKeyLength<32, 16, 32, 16, SimpleKeyingInterface::UNIQUE_IV, 8>
42
{
43
    /// \brief The algorithm name
44
    /// \return the algorithm name
45
    /// \details StaticAlgorithmName returns the algorithm's name as a static
46
    ///  member function.
47
    /// \details Bernstein named the cipher variants ChaCha8, ChaCha12 and
48
    ///  ChaCha20. More generally, Bernstein called the family ChaCha{r}.
49
    ///  AlgorithmName() provides the exact name once rounds are set.
50
0
    static const char* StaticAlgorithmName() {
51
0
        return "ChaCha";
52
0
    }
53
};
54
55
/// \brief ChaCha stream cipher implementation
56
/// \since Crypto++ 5.6.4
57
class CRYPTOPP_NO_VTABLE ChaCha_Policy : public AdditiveCipherConcretePolicy<word32, 16>
58
{
59
public:
60
0
    virtual ~ChaCha_Policy() {}
61
0
    ChaCha_Policy() : m_rounds(ROUNDS) {}
62
63
protected:
64
    void CipherSetKey(const NameValuePairs &params, const byte *key, size_t length);
65
    void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount);
66
    void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length);
67
0
    bool CipherIsRandomAccess() const {return true;}
68
    void SeekToIteration(lword iterationCount);
69
    unsigned int GetAlignment() const;
70
    unsigned int GetOptimalBlockSize() const;
71
72
    std::string AlgorithmName() const;
73
    std::string AlgorithmProvider() const;
74
75
    CRYPTOPP_CONSTANT(ROUNDS = 20);  // Default rounds
76
    FixedSizeAlignedSecBlock<word32, 16> m_state;
77
    unsigned int m_rounds;
78
};
79
80
/// \brief ChaCha stream cipher
81
/// \details This is Bernstein and ECRYPT's ChaCha. It is _slightly_ different
82
///  from the IETF's version of ChaCha called ChaChaTLS.
83
/// \sa <a href="http://cr.yp.to/chacha/chacha-20080208.pdf">ChaCha, a variant
84
///  of Salsa20</a> (2008.01.28).
85
/// \since Crypto++ 5.6.4
86
struct ChaCha : public ChaCha_Info, public SymmetricCipherDocumentation
87
{
88
    /// \brief ChaCha Encryption
89
    typedef SymmetricCipherFinal<ConcretePolicyHolder<ChaCha_Policy, AdditiveCipherTemplate<> >, ChaCha_Info > Encryption;
90
    /// \brief ChaCha Decryption
91
    typedef Encryption Decryption;
92
};
93
94
////////////////////////////// IETF ChaChaTLS //////////////////////////////
95
96
/// \brief IETF ChaCha20 stream cipher information
97
/// \since Crypto++ 8.1
98
struct ChaChaTLS_Info : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 12>, FixedRounds<20>
99
{
100
    /// \brief The algorithm name
101
    /// \return the algorithm name
102
    /// \details StaticAlgorithmName returns the algorithm's name as a static
103
    ///  member function.
104
    /// \details This is the IETF's variant of Bernstein's ChaCha from RFC
105
    ///  8439. IETF ChaCha is called ChaChaTLS in the Crypto++ library. It
106
    ///  is _slightly_ different from Bernstein's implementation.
107
1
    static const char* StaticAlgorithmName() {
108
1
        return "ChaChaTLS";
109
1
    }
110
};
111
112
/// \brief IETF ChaCha20 stream cipher implementation
113
/// \since Crypto++ 8.1
114
class CRYPTOPP_NO_VTABLE ChaChaTLS_Policy : public AdditiveCipherConcretePolicy<word32, 16>
115
{
116
public:
117
27
    virtual ~ChaChaTLS_Policy() {}
118
27
    ChaChaTLS_Policy() : m_counter(0) {}
119
120
protected:
121
    void CipherSetKey(const NameValuePairs &params, const byte *key, size_t length);
122
    void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount);
123
    void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length);
124
0
    bool CipherIsRandomAccess() const {return true;}
125
    void SeekToIteration(lword iterationCount);
126
    unsigned int GetAlignment() const;
127
    unsigned int GetOptimalBlockSize() const;
128
129
    std::string AlgorithmName() const;
130
    std::string AlgorithmProvider() const;
131
132
    FixedSizeAlignedSecBlock<word32, 16+8> m_state;
133
    unsigned int m_counter;
134
    CRYPTOPP_CONSTANT(ROUNDS = ChaChaTLS_Info::ROUNDS);
135
    CRYPTOPP_CONSTANT(KEY = 16);  // Index into m_state
136
    CRYPTOPP_CONSTANT(CTR = 24);  // Index into m_state
137
};
138
139
/// \brief IETF ChaCha20 stream cipher
140
/// \details This is the IETF's variant of Bernstein's ChaCha from RFC 8439.
141
///  IETF ChaCha is called ChaChaTLS in the Crypto++ library. It is
142
///  _slightly_ different from the Bernstein implementation. ChaCha-TLS
143
///  can be used for cipher suites
144
///  <tt>TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256</tt>,
145
///  <tt>TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256</tt>, and
146
///  <tt>TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256</tt>.
147
/// \sa <a href="https://tools.ietf.org/html/rfc8439">RFC 8439, ChaCha20 and
148
///  Poly1305 for IETF Protocols</a>, <A
149
///  HREF="https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU">How
150
///  to handle block counter wrap in IETF's ChaCha algorithm?</A> and
151
///  <A HREF="https://github.com/weidai11/cryptopp/issues/790">Issue
152
///  790, ChaChaTLS results when counter block wraps</A>.
153
/// \since Crypto++ 8.1
154
struct ChaChaTLS : public ChaChaTLS_Info, public SymmetricCipherDocumentation
155
{
156
    /// \brief ChaCha-TLS Encryption
157
    typedef SymmetricCipherFinal<ConcretePolicyHolder<ChaChaTLS_Policy, AdditiveCipherTemplate<> >, ChaChaTLS_Info > Encryption;
158
    /// \brief ChaCha-TLS Decryption
159
    typedef Encryption Decryption;
160
};
161
162
////////////////////////////// IETF XChaCha20 draft //////////////////////////////
163
164
/// \brief IETF XChaCha20 stream cipher information
165
/// \since Crypto++ 8.1
166
struct XChaCha20_Info : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 24>
167
{
168
    /// \brief The algorithm name
169
    /// \return the algorithm name
170
    /// \details StaticAlgorithmName returns the algorithm's name as a static
171
    ///  member function.
172
    /// \details This is the IETF's XChaCha from draft-arciszewski-xchacha.
173
2
    static const char* StaticAlgorithmName() {
174
2
        return "XChaCha20";
175
2
    }
176
};
177
178
/// \brief IETF XChaCha20 stream cipher implementation
179
/// \since Crypto++ 8.1
180
class CRYPTOPP_NO_VTABLE XChaCha20_Policy : public AdditiveCipherConcretePolicy<word32, 16>
181
{
182
public:
183
13
    virtual ~XChaCha20_Policy() {}
184
13
    XChaCha20_Policy() : m_counter(0), m_rounds(ROUNDS) {}
185
186
protected:
187
    void CipherSetKey(const NameValuePairs &params, const byte *key, size_t length);
188
    void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount);
189
    void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length);
190
0
    bool CipherIsRandomAccess() const {return false;}
191
    void SeekToIteration(lword iterationCount);
192
    unsigned int GetAlignment() const;
193
    unsigned int GetOptimalBlockSize() const;
194
195
    std::string AlgorithmName() const;
196
    std::string AlgorithmProvider() const;
197
198
    FixedSizeAlignedSecBlock<word32, 16+8> m_state;
199
    unsigned int m_counter, m_rounds;
200
    CRYPTOPP_CONSTANT(ROUNDS = 20);  // Default rounds
201
    CRYPTOPP_CONSTANT(KEY = 16);  // Index into m_state
202
};
203
204
/// \brief IETF XChaCha20 stream cipher
205
/// \details This is the IETF's XChaCha from draft-arciszewski-xchacha.
206
/// \sa <a href="https://tools.ietf.org/html/draft-arciszewski-xchacha">XChaCha:
207
///  eXtended-nonce ChaCha and AEAD_XChaCha20_Poly1305 (rev. 03)</a>, <A
208
///  HREF="https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU">How
209
///  to handle block counter wrap in IETF's ChaCha algorithm?</A> and
210
///  <A HREF="https://github.com/weidai11/cryptopp/issues/790">Issue
211
///  790, ChaCha20 results when counter block wraps</A>.
212
/// \since Crypto++ 8.1
213
struct XChaCha20 : public XChaCha20_Info, public SymmetricCipherDocumentation
214
{
215
    /// \brief XChaCha Encryption
216
    typedef SymmetricCipherFinal<ConcretePolicyHolder<XChaCha20_Policy, AdditiveCipherTemplate<> >, XChaCha20_Info > Encryption;
217
    /// \brief XChaCha Decryption
218
    typedef Encryption Decryption;
219
};
220
221
NAMESPACE_END
222
223
#endif  // CRYPTOPP_CHACHA_H