Coverage Report

Created: 2024-11-21 07:03

/src/cryptopp/chachapoly.h
Line
Count
Source (jump to first uncovered line)
1
// chachapoly.h - written and placed in the public domain by Jeffrey Walton
2
//                RFC 8439, Section 2.8, AEAD Construction, http://tools.ietf.org/html/rfc8439
3
4
/// \file chachapoly.h
5
/// \brief IETF ChaCha20/Poly1305 AEAD scheme
6
/// \details ChaCha20Poly1305 is an authenticated encryption scheme that combines
7
///  ChaCha20TLS and Poly1305TLS. The scheme is defined in RFC 8439, section 2.8,
8
///  AEAD_CHACHA20_POLY1305 construction, and uses the IETF versions of ChaCha20
9
///  and Poly1305.
10
/// \sa <A HREF="http://tools.ietf.org/html/rfc8439">RFC 8439, ChaCha20 and Poly1305
11
///  for IETF Protocols</A>.
12
/// \since Crypto++ 8.1
13
14
#ifndef CRYPTOPP_CHACHA_POLY1305_H
15
#define CRYPTOPP_CHACHA_POLY1305_H
16
17
#include "cryptlib.h"
18
#include "authenc.h"
19
#include "chacha.h"
20
#include "poly1305.h"
21
22
NAMESPACE_BEGIN(CryptoPP)
23
24
////////////////////////////// IETF ChaChaTLS //////////////////////////////
25
26
/// \brief IETF ChaCha20Poly1305 cipher base implementation
27
/// \details Base implementation of the AuthenticatedSymmetricCipher interface
28
/// \since Crypto++ 8.1
29
class ChaCha20Poly1305_Base : public AuthenticatedSymmetricCipherBase
30
{
31
public:
32
  CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName()
33
0
    {return "ChaCha20/Poly1305";}
34
35
27
  virtual ~ChaCha20Poly1305_Base() {}
36
37
  // AuthenticatedSymmetricCipher
38
  std::string AlgorithmName() const
39
8
    {return std::string("ChaCha20/Poly1305");}
40
  std::string AlgorithmProvider() const
41
0
    {return GetSymmetricCipher().AlgorithmProvider();}
42
  size_t MinKeyLength() const
43
0
    {return 32;}
44
  size_t MaxKeyLength() const
45
0
    {return 32;}
46
  size_t DefaultKeyLength() const
47
0
    {return 32;}
48
  size_t GetValidKeyLength(size_t n) const
49
0
    {CRYPTOPP_UNUSED(n); return 32;}
50
  bool IsValidKeyLength(size_t n) const
51
0
    {return n==32;}
52
  unsigned int OptimalDataAlignment() const
53
0
    {return GetSymmetricCipher().OptimalDataAlignment();}
54
  IV_Requirement IVRequirement() const
55
0
    {return UNIQUE_IV;}
56
  unsigned int IVSize() const
57
0
    {return 12;}
58
  unsigned int MinIVLength() const
59
68
    {return 12;}
60
  unsigned int MaxIVLength() const
61
64
    {return 12;}
62
  unsigned int DigestSize() const
63
36
    {return 16;}
64
  lword MaxHeaderLength() const
65
13
    {return LWORD_MAX;}  // 2^64-1 bytes
66
  lword MaxMessageLength() const
67
18
    {return W64LIT(274877906880);}  // 2^38-1 blocks
68
  lword MaxFooterLength() const
69
13
    {return 0;}
70
71
  /// \brief Encrypts and calculates a MAC in one call
72
  /// \param ciphertext the encryption buffer
73
  /// \param mac the mac buffer
74
  /// \param macSize the size of the MAC buffer, in bytes
75
  /// \param iv the iv buffer
76
  /// \param ivLength the size of the IV buffer, in bytes
77
  /// \param aad the AAD buffer
78
  /// \param aadLength the size of the AAD buffer, in bytes
79
  /// \param message the message buffer
80
  /// \param messageLength the size of the messagetext buffer, in bytes
81
  /// \details EncryptAndAuthenticate() encrypts and generates the MAC in one call. The function
82
  ///   truncates the MAC if <tt>macSize < TagSize()</tt>.
83
  virtual void EncryptAndAuthenticate(byte *ciphertext, byte *mac, size_t macSize, const byte *iv, int ivLength, const byte *aad, size_t aadLength, const byte *message, size_t messageLength);
84
85
  /// \brief Decrypts and verifies a MAC in one call
86
  /// \param message the decryption buffer
87
  /// \param mac the mac buffer
88
  /// \param macSize the size of the MAC buffer, in bytes
89
  /// \param iv the iv buffer
90
  /// \param ivLength the size of the IV buffer, in bytes
91
  /// \param aad the AAD buffer
92
  /// \param aadLength the size of the AAD buffer, in bytes
93
  /// \param ciphertext the cipher buffer
94
  /// \param ciphertextLength the size of the ciphertext buffer, in bytes
95
  /// \return true if the MAC is valid and the decoding succeeded, false otherwise
96
  /// \details DecryptAndVerify() decrypts and verifies the MAC in one call.
97
  /// <tt>message</tt> is a decryption buffer and should be at least as large as the ciphertext buffer.
98
  /// \details The function returns true iff MAC is valid. DecryptAndVerify() assumes the MAC
99
  ///  is truncated if <tt>macLength < TagSize()</tt>.
100
  virtual bool DecryptAndVerify(byte *message, const byte *mac, size_t macSize, const byte *iv, int ivLength, const byte *aad, size_t aadLength, const byte *ciphertext, size_t ciphertextLength);
101
102
protected:
103
  // AuthenticatedSymmetricCipherBase
104
18
  bool AuthenticationIsOnPlaintext() const {return false;}
105
24
  unsigned int AuthenticationBlockSize() const {return 1;}
106
  void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs &params);
107
  void Resync(const byte *iv, size_t len);
108
  size_t AuthenticateBlocks(const byte *data, size_t len);
109
  void AuthenticateLastHeaderBlock();
110
  void AuthenticateLastConfidentialBlock();
111
  void AuthenticateLastFooterBlock(byte *mac, size_t macSize);
112
113
  // See comments in chachapoly.cpp
114
  void RekeyCipherAndMac(const byte *userKey, size_t userKeyLength, const NameValuePairs &params);
115
116
  virtual const MessageAuthenticationCode & GetMAC() const = 0;
117
  virtual MessageAuthenticationCode & AccessMAC() = 0;
118
119
private:
120
  SecByteBlock m_userKey;
121
};
122
123
/// \brief IETF ChaCha20Poly1305 cipher final implementation
124
/// \tparam T_IsEncryption flag indicating cipher direction
125
/// \details ChaCha20Poly1305 is an authenticated encryption scheme that combines
126
///  ChaCha20TLS and Poly1305TLS. The scheme is defined in RFC 8439, section 2.8,
127
///  AEAD_CHACHA20_POLY1305 construction, and uses the IETF versions of ChaCha20
128
///  and Poly1305.
129
/// \sa <A HREF="http://tools.ietf.org/html/rfc8439">RFC 8439, ChaCha20 and Poly1305
130
///  for IETF Protocols</A>.
131
/// \since Crypto++ 8.1
132
template <bool T_IsEncryption>
133
class ChaCha20Poly1305_Final : public ChaCha20Poly1305_Base
134
{
135
public:
136
27
  virtual ~ChaCha20Poly1305_Final() {}
CryptoPP::ChaCha20Poly1305_Final<true>::~ChaCha20Poly1305_Final()
Line
Count
Source
136
8
  virtual ~ChaCha20Poly1305_Final() {}
CryptoPP::ChaCha20Poly1305_Final<false>::~ChaCha20Poly1305_Final()
Line
Count
Source
136
19
  virtual ~ChaCha20Poly1305_Final() {}
137
138
protected:
139
  const SymmetricCipher & GetSymmetricCipher()
140
    {return const_cast<ChaCha20Poly1305_Final *>(this)->AccessSymmetricCipher();}
141
  SymmetricCipher & AccessSymmetricCipher()
142
127
    {return m_cipher;}
CryptoPP::ChaCha20Poly1305_Final<true>::AccessSymmetricCipher()
Line
Count
Source
142
35
    {return m_cipher;}
CryptoPP::ChaCha20Poly1305_Final<false>::AccessSymmetricCipher()
Line
Count
Source
142
92
    {return m_cipher;}
143
  bool IsForwardTransformation() const
144
18
    {return T_IsEncryption;}
CryptoPP::ChaCha20Poly1305_Final<true>::IsForwardTransformation() const
Line
Count
Source
144
5
    {return T_IsEncryption;}
CryptoPP::ChaCha20Poly1305_Final<false>::IsForwardTransformation() const
Line
Count
Source
144
13
    {return T_IsEncryption;}
145
146
  const MessageAuthenticationCode & GetMAC() const
147
0
    {return const_cast<ChaCha20Poly1305_Final *>(this)->AccessMAC();}
Unexecuted instantiation: CryptoPP::ChaCha20Poly1305_Final<true>::GetMAC() const
Unexecuted instantiation: CryptoPP::ChaCha20Poly1305_Final<false>::GetMAC() const
148
  MessageAuthenticationCode & AccessMAC()
149
117
    {return m_mac;}
CryptoPP::ChaCha20Poly1305_Final<true>::AccessMAC()
Line
Count
Source
149
20
    {return m_mac;}
CryptoPP::ChaCha20Poly1305_Final<false>::AccessMAC()
Line
Count
Source
149
97
    {return m_mac;}
150
151
private:
152
  ChaChaTLS::Encryption m_cipher;
153
  Poly1305TLS m_mac;
154
};
155
156
/// \brief IETF ChaCha20/Poly1305 AEAD scheme
157
/// \details ChaCha20Poly1305 is an authenticated encryption scheme that combines
158
///  ChaCha20TLS and Poly1305TLS. The scheme is defined in RFC 8439, section 2.8,
159
///  AEAD_CHACHA20_POLY1305 construction, and uses the IETF versions of ChaCha20
160
///  and Poly1305.
161
/// \sa <A HREF="http://tools.ietf.org/html/rfc8439">RFC 8439, ChaCha20 and Poly1305
162
///  for IETF Protocols</A>.
163
/// \since Crypto++ 8.1
164
struct ChaCha20Poly1305 : public AuthenticatedSymmetricCipherDocumentation
165
{
166
  /// \brief ChaCha20Poly1305 encryption
167
  typedef ChaCha20Poly1305_Final<true> Encryption;
168
  /// \brief ChaCha20Poly1305 decryption
169
  typedef ChaCha20Poly1305_Final<false> Decryption;
170
};
171
172
////////////////////////////// IETF XChaCha20 draft //////////////////////////////
173
174
/// \brief IETF XChaCha20Poly1305 cipher base implementation
175
/// \details Base implementation of the AuthenticatedSymmetricCipher interface
176
/// \since Crypto++ 8.1
177
class XChaCha20Poly1305_Base : public AuthenticatedSymmetricCipherBase
178
{
179
public:
180
  CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName()
181
0
    {return "XChaCha20/Poly1305";}
182
183
13
  virtual ~XChaCha20Poly1305_Base() {}
184
185
  // AuthenticatedSymmetricCipher
186
  std::string AlgorithmName() const
187
11
    {return std::string("XChaCha20/Poly1305");}
188
  std::string AlgorithmProvider() const
189
0
    {return GetSymmetricCipher().AlgorithmProvider();}
190
  size_t MinKeyLength() const
191
0
    {return 32;}
192
  size_t MaxKeyLength() const
193
0
    {return 32;}
194
  size_t DefaultKeyLength() const
195
0
    {return 32;}
196
  size_t GetValidKeyLength(size_t n) const
197
0
    {CRYPTOPP_UNUSED(n); return 32;}
198
  bool IsValidKeyLength(size_t n) const
199
0
    {return n==32;}
200
  unsigned int OptimalDataAlignment() const
201
0
    {return GetSymmetricCipher().OptimalDataAlignment();}
202
  IV_Requirement IVRequirement() const
203
2
    {return UNIQUE_IV;}
204
  unsigned int IVSize() const
205
0
    {return 24;}
206
  unsigned int MinIVLength() const
207
22
    {return 24;}
208
  unsigned int MaxIVLength() const
209
12
    {return 24;}
210
  unsigned int DigestSize() const
211
0
    {return 16;}
212
  lword MaxHeaderLength() const
213
0
    {return LWORD_MAX;}  // 2^64-1 bytes
214
  lword MaxMessageLength() const
215
0
    {return W64LIT(274877906880);}  // 2^38-1 blocks
216
  lword MaxFooterLength() const
217
0
    {return 0;}
218
219
  /// \brief Encrypts and calculates a MAC in one call
220
  /// \param ciphertext the encryption buffer
221
  /// \param mac the mac buffer
222
  /// \param macSize the size of the MAC buffer, in bytes
223
  /// \param iv the iv buffer
224
  /// \param ivLength the size of the IV buffer, in bytes
225
  /// \param aad the AAD buffer
226
  /// \param aadLength the size of the AAD buffer, in bytes
227
  /// \param message the message buffer
228
  /// \param messageLength the size of the messagetext buffer, in bytes
229
  /// \details EncryptAndAuthenticate() encrypts and generates the MAC in one call. The function
230
  ///   truncates the MAC if <tt>macSize < TagSize()</tt>.
231
  virtual void EncryptAndAuthenticate(byte *ciphertext, byte *mac, size_t macSize, const byte *iv, int ivLength, const byte *aad, size_t aadLength, const byte *message, size_t messageLength);
232
233
  /// \brief Decrypts and verifies a MAC in one call
234
  /// \param message the decryption buffer
235
  /// \param mac the mac buffer
236
  /// \param macSize the size of the MAC buffer, in bytes
237
  /// \param iv the iv buffer
238
  /// \param ivLength the size of the IV buffer, in bytes
239
  /// \param aad the AAD buffer
240
  /// \param aadLength the size of the AAD buffer, in bytes
241
  /// \param ciphertext the cipher buffer
242
  /// \param ciphertextLength the size of the ciphertext buffer, in bytes
243
  /// \return true if the MAC is valid and the decoding succeeded, false otherwise
244
  /// \details DecryptAndVerify() decrypts and verifies the MAC in one call.
245
  /// <tt>message</tt> is a decryption buffer and should be at least as large as the ciphertext buffer.
246
  /// \details The function returns true iff MAC is valid. DecryptAndVerify() assumes the MAC
247
  ///  is truncated if <tt>macLength < TagSize()</tt>.
248
  virtual bool DecryptAndVerify(byte *message, const byte *mac, size_t macSize, const byte *iv, int ivLength, const byte *aad, size_t aadLength, const byte *ciphertext, size_t ciphertextLength);
249
250
protected:
251
  // AuthenticatedSymmetricCipherBase
252
0
  bool AuthenticationIsOnPlaintext() const {return false;}
253
0
  unsigned int AuthenticationBlockSize() const {return 1;}
254
  void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs &params);
255
  void Resync(const byte *iv, size_t len);
256
  size_t AuthenticateBlocks(const byte *data, size_t len);
257
  void AuthenticateLastHeaderBlock();
258
  void AuthenticateLastConfidentialBlock();
259
  void AuthenticateLastFooterBlock(byte *mac, size_t macSize);
260
261
  // See comments in chachapoly.cpp
262
  void RekeyCipherAndMac(const byte *userKey, size_t userKeyLength, const NameValuePairs &params);
263
264
  virtual const MessageAuthenticationCode & GetMAC() const = 0;
265
  virtual MessageAuthenticationCode & AccessMAC() = 0;
266
267
private:
268
  SecByteBlock m_userKey;
269
};
270
271
/// \brief IETF XChaCha20Poly1305 cipher final implementation
272
/// \tparam T_IsEncryption flag indicating cipher direction
273
/// \details XChaCha20Poly1305 is an authenticated encryption scheme that combines
274
///  XChaCha20 and Poly1305-TLS. The scheme is defined in RFC 8439, section 2.8,
275
///  AEAD_CHACHA20_POLY1305 construction, and uses the IETF versions of ChaCha20
276
///  and Poly1305.
277
/// \sa <A HREF="http://tools.ietf.org/html/rfc8439">RFC 8439, ChaCha20 and Poly1305
278
///  for IETF Protocols</A>.
279
/// \since Crypto++ 8.1
280
template <bool T_IsEncryption>
281
class XChaCha20Poly1305_Final : public XChaCha20Poly1305_Base
282
{
283
public:
284
13
  virtual ~XChaCha20Poly1305_Final() {}
CryptoPP::XChaCha20Poly1305_Final<true>::~XChaCha20Poly1305_Final()
Line
Count
Source
284
9
  virtual ~XChaCha20Poly1305_Final() {}
CryptoPP::XChaCha20Poly1305_Final<false>::~XChaCha20Poly1305_Final()
Line
Count
Source
284
4
  virtual ~XChaCha20Poly1305_Final() {}
285
286
protected:
287
  const SymmetricCipher & GetSymmetricCipher()
288
    {return const_cast<XChaCha20Poly1305_Final *>(this)->AccessSymmetricCipher();}
289
  SymmetricCipher & AccessSymmetricCipher()
290
2
    {return m_cipher;}
CryptoPP::XChaCha20Poly1305_Final<true>::AccessSymmetricCipher()
Line
Count
Source
290
2
    {return m_cipher;}
Unexecuted instantiation: CryptoPP::XChaCha20Poly1305_Final<false>::AccessSymmetricCipher()
291
  bool IsForwardTransformation() const
292
0
    {return T_IsEncryption;}
Unexecuted instantiation: CryptoPP::XChaCha20Poly1305_Final<true>::IsForwardTransformation() const
Unexecuted instantiation: CryptoPP::XChaCha20Poly1305_Final<false>::IsForwardTransformation() const
293
294
  const MessageAuthenticationCode & GetMAC() const
295
0
    {return const_cast<XChaCha20Poly1305_Final *>(this)->AccessMAC();}
Unexecuted instantiation: CryptoPP::XChaCha20Poly1305_Final<true>::GetMAC() const
Unexecuted instantiation: CryptoPP::XChaCha20Poly1305_Final<false>::GetMAC() const
296
  MessageAuthenticationCode & AccessMAC()
297
0
    {return m_mac;}
Unexecuted instantiation: CryptoPP::XChaCha20Poly1305_Final<true>::AccessMAC()
Unexecuted instantiation: CryptoPP::XChaCha20Poly1305_Final<false>::AccessMAC()
298
299
private:
300
  XChaCha20::Encryption m_cipher;
301
  Poly1305TLS m_mac;
302
};
303
304
/// \brief IETF XChaCha20/Poly1305 AEAD scheme
305
/// \details XChaCha20Poly1305 is an authenticated encryption scheme that combines
306
///  XChaCha20 and Poly1305-TLS. The scheme is defined in RFC 8439, section 2.8,
307
///  AEAD_XCHACHA20_POLY1305 construction, and uses the IETF versions of ChaCha20
308
///  and Poly1305.
309
/// \sa <A HREF="http://tools.ietf.org/html/rfc8439">RFC 8439, ChaCha20 and Poly1305
310
///  for IETF Protocols</A>.
311
/// \since Crypto++ 8.1
312
struct XChaCha20Poly1305 : public AuthenticatedSymmetricCipherDocumentation
313
{
314
  /// \brief XChaCha20Poly1305 encryption
315
  typedef XChaCha20Poly1305_Final<true> Encryption;
316
  /// \brief XChaCha20Poly1305 decryption
317
  typedef XChaCha20Poly1305_Final<false> Decryption;
318
};
319
320
NAMESPACE_END
321
322
#endif  // CRYPTOPP_CHACHA_POLY1305_H