/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 ¶ms); |
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 ¶ms); |
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 ¶ms); |
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 ¶ms); |
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 |