Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:54:54

0001 // chachapoly.h - written and placed in the public domain by Jeffrey Walton

0002 //                RFC 8439, Section 2.8, AEAD Construction, http://tools.ietf.org/html/rfc8439

0003 
0004 /// \file chachapoly.h

0005 /// \brief IETF ChaCha20/Poly1305 AEAD scheme

0006 /// \details ChaCha20Poly1305 is an authenticated encryption scheme that combines

0007 ///  ChaCha20TLS and Poly1305TLS. The scheme is defined in RFC 8439, section 2.8,

0008 ///  AEAD_CHACHA20_POLY1305 construction, and uses the IETF versions of ChaCha20

0009 ///  and Poly1305.

0010 /// \sa <A HREF="http://tools.ietf.org/html/rfc8439">RFC 8439, ChaCha20 and Poly1305

0011 ///  for IETF Protocols</A>.

0012 /// \since Crypto++ 8.1

0013 
0014 #ifndef CRYPTOPP_CHACHA_POLY1305_H
0015 #define CRYPTOPP_CHACHA_POLY1305_H
0016 
0017 #include "cryptlib.h"
0018 #include "authenc.h"
0019 #include "chacha.h"
0020 #include "poly1305.h"
0021 
0022 NAMESPACE_BEGIN(CryptoPP)
0023 
0024 ////////////////////////////// IETF ChaChaTLS //////////////////////////////

0025 
0026 /// \brief IETF ChaCha20Poly1305 cipher base implementation

0027 /// \details Base implementation of the AuthenticatedSymmetricCipher interface

0028 /// \since Crypto++ 8.1

0029 class ChaCha20Poly1305_Base : public AuthenticatedSymmetricCipherBase
0030 {
0031 public:
0032     CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName()
0033         {return "ChaCha20/Poly1305";}
0034 
0035     virtual ~ChaCha20Poly1305_Base() {}
0036 
0037     // AuthenticatedSymmetricCipher

0038     std::string AlgorithmName() const
0039         {return std::string("ChaCha20/Poly1305");}
0040     std::string AlgorithmProvider() const
0041         {return GetSymmetricCipher().AlgorithmProvider();}
0042     size_t MinKeyLength() const
0043         {return 32;}
0044     size_t MaxKeyLength() const
0045         {return 32;}
0046     size_t DefaultKeyLength() const
0047         {return 32;}
0048     size_t GetValidKeyLength(size_t n) const
0049         {CRYPTOPP_UNUSED(n); return 32;}
0050     bool IsValidKeyLength(size_t n) const
0051         {return n==32;}
0052     unsigned int OptimalDataAlignment() const
0053         {return GetSymmetricCipher().OptimalDataAlignment();}
0054     IV_Requirement IVRequirement() const
0055         {return UNIQUE_IV;}
0056     unsigned int IVSize() const
0057         {return 12;}
0058     unsigned int MinIVLength() const
0059         {return 12;}
0060     unsigned int MaxIVLength() const
0061         {return 12;}
0062     unsigned int DigestSize() const
0063         {return 16;}
0064     lword MaxHeaderLength() const
0065         {return LWORD_MAX;}  // 2^64-1 bytes

0066     lword MaxMessageLength() const
0067         {return W64LIT(274877906880);}  // 2^38-1 blocks

0068     lword MaxFooterLength() const
0069         {return 0;}
0070 
0071     /// \brief Encrypts and calculates a MAC in one call

0072     /// \param ciphertext the encryption buffer

0073     /// \param mac the mac buffer

0074     /// \param macSize the size of the MAC buffer, in bytes

0075     /// \param iv the iv buffer

0076     /// \param ivLength the size of the IV buffer, in bytes

0077     /// \param aad the AAD buffer

0078     /// \param aadLength the size of the AAD buffer, in bytes

0079     /// \param message the message buffer

0080     /// \param messageLength the size of the messagetext buffer, in bytes

0081     /// \details EncryptAndAuthenticate() encrypts and generates the MAC in one call. The function

0082     ///   truncates the MAC if <tt>macSize < TagSize()</tt>.

0083     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);
0084 
0085     /// \brief Decrypts and verifies a MAC in one call

0086     /// \param message the decryption buffer

0087     /// \param mac the mac buffer

0088     /// \param macSize the size of the MAC buffer, in bytes

0089     /// \param iv the iv buffer

0090     /// \param ivLength the size of the IV buffer, in bytes

0091     /// \param aad the AAD buffer

0092     /// \param aadLength the size of the AAD buffer, in bytes

0093     /// \param ciphertext the cipher buffer

0094     /// \param ciphertextLength the size of the ciphertext buffer, in bytes

0095     /// \return true if the MAC is valid and the decoding succeeded, false otherwise

0096     /// \details DecryptAndVerify() decrypts and verifies the MAC in one call.

0097     /// <tt>message</tt> is a decryption buffer and should be at least as large as the ciphertext buffer.

0098     /// \details The function returns true iff MAC is valid. DecryptAndVerify() assumes the MAC

0099     ///  is truncated if <tt>macLength < TagSize()</tt>.

0100     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);
0101 
0102 protected:
0103     // AuthenticatedSymmetricCipherBase

0104     bool AuthenticationIsOnPlaintext() const {return false;}
0105     unsigned int AuthenticationBlockSize() const {return 1;}
0106     void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs &params);
0107     void Resync(const byte *iv, size_t len);
0108     size_t AuthenticateBlocks(const byte *data, size_t len);
0109     void AuthenticateLastHeaderBlock();
0110     void AuthenticateLastConfidentialBlock();
0111     void AuthenticateLastFooterBlock(byte *mac, size_t macSize);
0112 
0113     // See comments in chachapoly.cpp

0114     void RekeyCipherAndMac(const byte *userKey, size_t userKeyLength, const NameValuePairs &params);
0115 
0116     virtual const MessageAuthenticationCode & GetMAC() const = 0;
0117     virtual MessageAuthenticationCode & AccessMAC() = 0;
0118 
0119 private:
0120     SecByteBlock m_userKey;
0121 };
0122 
0123 /// \brief IETF ChaCha20Poly1305 cipher final implementation

0124 /// \tparam T_IsEncryption flag indicating cipher direction

0125 /// \details ChaCha20Poly1305 is an authenticated encryption scheme that combines

0126 ///  ChaCha20TLS and Poly1305TLS. The scheme is defined in RFC 8439, section 2.8,

0127 ///  AEAD_CHACHA20_POLY1305 construction, and uses the IETF versions of ChaCha20

0128 ///  and Poly1305.

0129 /// \sa <A HREF="http://tools.ietf.org/html/rfc8439">RFC 8439, ChaCha20 and Poly1305

0130 ///  for IETF Protocols</A>.

0131 /// \since Crypto++ 8.1

0132 template <bool T_IsEncryption>
0133 class ChaCha20Poly1305_Final : public ChaCha20Poly1305_Base
0134 {
0135 public:
0136     virtual ~ChaCha20Poly1305_Final() {}
0137 
0138 protected:
0139     const SymmetricCipher & GetSymmetricCipher()
0140         {return const_cast<ChaCha20Poly1305_Final *>(this)->AccessSymmetricCipher();}
0141     SymmetricCipher & AccessSymmetricCipher()
0142         {return m_cipher;}
0143     bool IsForwardTransformation() const
0144         {return T_IsEncryption;}
0145 
0146     const MessageAuthenticationCode & GetMAC() const
0147         {return const_cast<ChaCha20Poly1305_Final *>(this)->AccessMAC();}
0148     MessageAuthenticationCode & AccessMAC()
0149         {return m_mac;}
0150 
0151 private:
0152     ChaChaTLS::Encryption m_cipher;
0153     Poly1305TLS m_mac;
0154 };
0155 
0156 /// \brief IETF ChaCha20/Poly1305 AEAD scheme

0157 /// \details ChaCha20Poly1305 is an authenticated encryption scheme that combines

0158 ///  ChaCha20TLS and Poly1305TLS. The scheme is defined in RFC 8439, section 2.8,

0159 ///  AEAD_CHACHA20_POLY1305 construction, and uses the IETF versions of ChaCha20

0160 ///  and Poly1305.

0161 /// \sa <A HREF="http://tools.ietf.org/html/rfc8439">RFC 8439, ChaCha20 and Poly1305

0162 ///  for IETF Protocols</A>.

0163 /// \since Crypto++ 8.1

0164 struct ChaCha20Poly1305 : public AuthenticatedSymmetricCipherDocumentation
0165 {
0166     /// \brief ChaCha20Poly1305 encryption

0167     typedef ChaCha20Poly1305_Final<true> Encryption;
0168     /// \brief ChaCha20Poly1305 decryption

0169     typedef ChaCha20Poly1305_Final<false> Decryption;
0170 };
0171 
0172 ////////////////////////////// IETF XChaCha20 draft //////////////////////////////

0173 
0174 /// \brief IETF XChaCha20Poly1305 cipher base implementation

0175 /// \details Base implementation of the AuthenticatedSymmetricCipher interface

0176 /// \since Crypto++ 8.1

0177 class XChaCha20Poly1305_Base : public AuthenticatedSymmetricCipherBase
0178 {
0179 public:
0180     CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName()
0181         {return "XChaCha20/Poly1305";}
0182 
0183     virtual ~XChaCha20Poly1305_Base() {}
0184 
0185     // AuthenticatedSymmetricCipher

0186     std::string AlgorithmName() const
0187         {return std::string("XChaCha20/Poly1305");}
0188     std::string AlgorithmProvider() const
0189         {return GetSymmetricCipher().AlgorithmProvider();}
0190     size_t MinKeyLength() const
0191         {return 32;}
0192     size_t MaxKeyLength() const
0193         {return 32;}
0194     size_t DefaultKeyLength() const
0195         {return 32;}
0196     size_t GetValidKeyLength(size_t n) const
0197         {CRYPTOPP_UNUSED(n); return 32;}
0198     bool IsValidKeyLength(size_t n) const
0199         {return n==32;}
0200     unsigned int OptimalDataAlignment() const
0201         {return GetSymmetricCipher().OptimalDataAlignment();}
0202     IV_Requirement IVRequirement() const
0203         {return UNIQUE_IV;}
0204     unsigned int IVSize() const
0205         {return 24;}
0206     unsigned int MinIVLength() const
0207         {return 24;}
0208     unsigned int MaxIVLength() const
0209         {return 24;}
0210     unsigned int DigestSize() const
0211         {return 16;}
0212     lword MaxHeaderLength() const
0213         {return LWORD_MAX;}  // 2^64-1 bytes

0214     lword MaxMessageLength() const
0215         {return W64LIT(274877906880);}  // 2^38-1 blocks

0216     lword MaxFooterLength() const
0217         {return 0;}
0218 
0219     /// \brief Encrypts and calculates a MAC in one call

0220     /// \param ciphertext the encryption buffer

0221     /// \param mac the mac buffer

0222     /// \param macSize the size of the MAC buffer, in bytes

0223     /// \param iv the iv buffer

0224     /// \param ivLength the size of the IV buffer, in bytes

0225     /// \param aad the AAD buffer

0226     /// \param aadLength the size of the AAD buffer, in bytes

0227     /// \param message the message buffer

0228     /// \param messageLength the size of the messagetext buffer, in bytes

0229     /// \details EncryptAndAuthenticate() encrypts and generates the MAC in one call. The function

0230     ///   truncates the MAC if <tt>macSize < TagSize()</tt>.

0231     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);
0232 
0233     /// \brief Decrypts and verifies a MAC in one call

0234     /// \param message the decryption buffer

0235     /// \param mac the mac buffer

0236     /// \param macSize the size of the MAC buffer, in bytes

0237     /// \param iv the iv buffer

0238     /// \param ivLength the size of the IV buffer, in bytes

0239     /// \param aad the AAD buffer

0240     /// \param aadLength the size of the AAD buffer, in bytes

0241     /// \param ciphertext the cipher buffer

0242     /// \param ciphertextLength the size of the ciphertext buffer, in bytes

0243     /// \return true if the MAC is valid and the decoding succeeded, false otherwise

0244     /// \details DecryptAndVerify() decrypts and verifies the MAC in one call.

0245     /// <tt>message</tt> is a decryption buffer and should be at least as large as the ciphertext buffer.

0246     /// \details The function returns true iff MAC is valid. DecryptAndVerify() assumes the MAC

0247     ///  is truncated if <tt>macLength < TagSize()</tt>.

0248     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);
0249 
0250 protected:
0251     // AuthenticatedSymmetricCipherBase

0252     bool AuthenticationIsOnPlaintext() const {return false;}
0253     unsigned int AuthenticationBlockSize() const {return 1;}
0254     void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs &params);
0255     void Resync(const byte *iv, size_t len);
0256     size_t AuthenticateBlocks(const byte *data, size_t len);
0257     void AuthenticateLastHeaderBlock();
0258     void AuthenticateLastConfidentialBlock();
0259     void AuthenticateLastFooterBlock(byte *mac, size_t macSize);
0260 
0261     // See comments in chachapoly.cpp

0262     void RekeyCipherAndMac(const byte *userKey, size_t userKeyLength, const NameValuePairs &params);
0263 
0264     virtual const MessageAuthenticationCode & GetMAC() const = 0;
0265     virtual MessageAuthenticationCode & AccessMAC() = 0;
0266 
0267 private:
0268     SecByteBlock m_userKey;
0269 };
0270 
0271 /// \brief IETF XChaCha20Poly1305 cipher final implementation

0272 /// \tparam T_IsEncryption flag indicating cipher direction

0273 /// \details XChaCha20Poly1305 is an authenticated encryption scheme that combines

0274 ///  XChaCha20 and Poly1305-TLS. The scheme is defined in RFC 8439, section 2.8,

0275 ///  AEAD_CHACHA20_POLY1305 construction, and uses the IETF versions of ChaCha20

0276 ///  and Poly1305.

0277 /// \sa <A HREF="http://tools.ietf.org/html/rfc8439">RFC 8439, ChaCha20 and Poly1305

0278 ///  for IETF Protocols</A>.

0279 /// \since Crypto++ 8.1

0280 template <bool T_IsEncryption>
0281 class XChaCha20Poly1305_Final : public XChaCha20Poly1305_Base
0282 {
0283 public:
0284     virtual ~XChaCha20Poly1305_Final() {}
0285 
0286 protected:
0287     const SymmetricCipher & GetSymmetricCipher()
0288         {return const_cast<XChaCha20Poly1305_Final *>(this)->AccessSymmetricCipher();}
0289     SymmetricCipher & AccessSymmetricCipher()
0290         {return m_cipher;}
0291     bool IsForwardTransformation() const
0292         {return T_IsEncryption;}
0293 
0294     const MessageAuthenticationCode & GetMAC() const
0295         {return const_cast<XChaCha20Poly1305_Final *>(this)->AccessMAC();}
0296     MessageAuthenticationCode & AccessMAC()
0297         {return m_mac;}
0298 
0299 private:
0300     XChaCha20::Encryption m_cipher;
0301     Poly1305TLS m_mac;
0302 };
0303 
0304 /// \brief IETF XChaCha20/Poly1305 AEAD scheme

0305 /// \details XChaCha20Poly1305 is an authenticated encryption scheme that combines

0306 ///  XChaCha20 and Poly1305-TLS. The scheme is defined in RFC 8439, section 2.8,

0307 ///  AEAD_XCHACHA20_POLY1305 construction, and uses the IETF versions of ChaCha20

0308 ///  and Poly1305.

0309 /// \sa <A HREF="http://tools.ietf.org/html/rfc8439">RFC 8439, ChaCha20 and Poly1305

0310 ///  for IETF Protocols</A>.

0311 /// \since Crypto++ 8.1

0312 struct XChaCha20Poly1305 : public AuthenticatedSymmetricCipherDocumentation
0313 {
0314     /// \brief XChaCha20Poly1305 encryption

0315     typedef XChaCha20Poly1305_Final<true> Encryption;
0316     /// \brief XChaCha20Poly1305 decryption

0317     typedef XChaCha20Poly1305_Final<false> Decryption;
0318 };
0319 
0320 NAMESPACE_END
0321 
0322 #endif  // CRYPTOPP_CHACHA_POLY1305_H