chachapoly.h 13 KB

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