2019-01-28 13:52:56 +00:00
|
|
|
// chachapoly.h - written and placed in the public domain by Jeffrey Walton
|
|
|
|
// RFC 8439, Section 2.8, AEAD Construction, http://tools.ietf.org/html/rfc8439
|
|
|
|
|
|
|
|
/// \file chachapoly.h
|
|
|
|
/// \brief ChaCha20/Poly1305-TLS AEAD cipher
|
2019-01-29 03:42:34 +00:00
|
|
|
/// \details ChaCha20Poly1305 is an authenticated encryption scheme that combines
|
|
|
|
/// ChaCha20TLS and Poly1305TLS. The scheme is defined in RFC 8439, section 2.8,
|
|
|
|
/// AEAD_CHACHA20_POLY1305 construction, and uses the IETF versions of ChaCha
|
|
|
|
/// and Poly1305.
|
2019-01-28 13:52:56 +00:00
|
|
|
/// \sa <A HREF="http://tools.ietf.org/html/rfc8439">RFC 8439, ChaCha20 and Poly1305
|
|
|
|
/// for IETF Protocols</A>.
|
2019-01-29 03:42:34 +00:00
|
|
|
/// \since Crypto++ 8.1
|
2019-01-28 13:52:56 +00:00
|
|
|
|
|
|
|
#ifndef CRYPTOPP_CHACHA_POLY1305_H
|
|
|
|
#define CRYPTOPP_CHACHA_POLY1305_H
|
|
|
|
|
|
|
|
#include "cryptlib.h"
|
|
|
|
#include "authenc.h"
|
|
|
|
#include "chacha.h"
|
|
|
|
#include "poly1305.h"
|
|
|
|
|
|
|
|
NAMESPACE_BEGIN(CryptoPP)
|
|
|
|
|
|
|
|
/// \brief ChaCha20Poly1305 cipher base implementation
|
|
|
|
/// \details Base implementation of the AuthenticatedSymmetricCipher interface
|
|
|
|
/// \since Crypto++ 8.1
|
2019-01-31 12:24:43 +00:00
|
|
|
class ChaCha20Poly1305_Base : public AuthenticatedSymmetricCipherBase
|
2019-01-28 13:52:56 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
virtual ~ChaCha20Poly1305_Base() {}
|
|
|
|
|
|
|
|
virtual const MessageAuthenticationCode & GetMAC() const = 0;
|
|
|
|
virtual MessageAuthenticationCode & AccessMAC() = 0;
|
|
|
|
|
|
|
|
public:
|
|
|
|
// AuthenticatedSymmetricCipher
|
|
|
|
std::string AlgorithmName() const
|
|
|
|
{return std::string("ChaCha20/Poly1305");}
|
|
|
|
std::string AlgorithmProvider() const
|
2019-01-31 04:04:37 +00:00
|
|
|
{return GetSymmetricCipher().AlgorithmProvider();}
|
2019-01-28 13:52:56 +00:00
|
|
|
size_t MinKeyLength() const
|
|
|
|
{return 32;}
|
|
|
|
size_t MaxKeyLength() const
|
|
|
|
{return 32;}
|
|
|
|
size_t DefaultKeyLength() const
|
|
|
|
{return 32;}
|
|
|
|
size_t GetValidKeyLength(size_t n) const
|
|
|
|
{CRYPTOPP_UNUSED(n); return 32;}
|
|
|
|
bool IsValidKeyLength(size_t n) const
|
|
|
|
{return n==32;}
|
|
|
|
unsigned int OptimalDataAlignment() const
|
|
|
|
{return GetSymmetricCipher().OptimalDataAlignment();}
|
|
|
|
IV_Requirement IVRequirement() const
|
|
|
|
{return UNIQUE_IV;}
|
|
|
|
unsigned int IVSize() const
|
2019-01-28 15:01:19 +00:00
|
|
|
{return 12;}
|
2019-01-28 13:52:56 +00:00
|
|
|
unsigned int MinIVLength() const
|
|
|
|
{return 12;}
|
|
|
|
unsigned int MaxIVLength() const
|
|
|
|
{return 12;}
|
|
|
|
unsigned int DigestSize() const
|
|
|
|
{return 16;}
|
|
|
|
lword MaxHeaderLength() const
|
2019-01-30 08:31:59 +00:00
|
|
|
{return LWORD_MAX;} // 2^64-1 bytes
|
2019-01-28 13:52:56 +00:00
|
|
|
lword MaxMessageLength() const
|
2019-01-30 07:51:14 +00:00
|
|
|
{return W64LIT(274877906880);} // 2^38-1 blocks
|
2019-01-28 13:52:56 +00:00
|
|
|
lword MaxFooterLength() const
|
2019-01-30 05:55:27 +00:00
|
|
|
{return 0;}
|
2019-01-28 13:52:56 +00:00
|
|
|
|
|
|
|
/// \brief Encrypts and calculates a MAC in one call
|
|
|
|
/// \param ciphertext the encryption buffer
|
|
|
|
/// \param mac the mac buffer
|
2019-01-28 14:09:41 +00:00
|
|
|
/// \param macSize the size of the MAC buffer, in bytes
|
2019-01-28 13:52:56 +00:00
|
|
|
/// \param iv the iv buffer
|
|
|
|
/// \param ivLength the size of the IV buffer, in bytes
|
|
|
|
/// \param aad the AAD buffer
|
|
|
|
/// \param aadLength the size of the AAD buffer, in bytes
|
|
|
|
/// \param message the message buffer
|
|
|
|
/// \param messageLength the size of the messagetext buffer, in bytes
|
|
|
|
/// \details EncryptAndAuthenticate() encrypts and generates the MAC in one call. The function
|
|
|
|
/// truncates the MAC if <tt>macSize < TagSize()</tt>.
|
|
|
|
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);
|
|
|
|
|
|
|
|
/// \brief Decrypts and verifies a MAC in one call
|
|
|
|
/// \param message the decryption buffer
|
|
|
|
/// \param mac the mac buffer
|
2019-01-28 14:09:41 +00:00
|
|
|
/// \param macSize the size of the MAC buffer, in bytes
|
2019-01-28 13:52:56 +00:00
|
|
|
/// \param iv the iv buffer
|
|
|
|
/// \param ivLength the size of the IV buffer, in bytes
|
|
|
|
/// \param aad the AAD buffer
|
|
|
|
/// \param aadLength the size of the AAD buffer, in bytes
|
2019-01-28 14:09:41 +00:00
|
|
|
/// \param ciphertext the cipher buffer
|
|
|
|
/// \param ciphertextLength the size of the ciphertext buffer, in bytes
|
2019-01-28 13:52:56 +00:00
|
|
|
/// \return true if the MAC is valid and the decoding succeeded, false otherwise
|
|
|
|
/// \details DecryptAndVerify() decrypts and verifies the MAC in one call.
|
|
|
|
/// <tt>message</tt> is a decryption buffer and should be at least as large as the ciphertext buffer.
|
|
|
|
/// \details The function returns true iff MAC is valid. DecryptAndVerify() assumes the MAC
|
|
|
|
/// is truncated if <tt>macLength < TagSize()</tt>.
|
2019-01-28 14:09:41 +00:00
|
|
|
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);
|
2019-01-28 13:52:56 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
// AuthenticatedSymmetricCipherBase
|
|
|
|
bool AuthenticationIsOnPlaintext() const {return false;}
|
|
|
|
unsigned int AuthenticationBlockSize() const {return 1;}
|
|
|
|
void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms);
|
|
|
|
void Resync(const byte *iv, size_t len);
|
|
|
|
size_t AuthenticateBlocks(const byte *data, size_t len);
|
|
|
|
void AuthenticateLastHeaderBlock();
|
|
|
|
void AuthenticateLastConfidentialBlock();
|
|
|
|
void AuthenticateLastFooterBlock(byte *mac, size_t macSize);
|
|
|
|
|
|
|
|
protected:
|
2019-01-30 06:54:08 +00:00
|
|
|
// See comments in chachapoly.cpp
|
2019-01-28 13:52:56 +00:00
|
|
|
void RekeyCipherAndMac(const byte *userKey, size_t userKeyLength, const NameValuePairs ¶ms);
|
|
|
|
|
|
|
|
SecByteBlock m_userKey;
|
|
|
|
};
|
|
|
|
|
|
|
|
/// \brief ChaCha20Poly1305 cipher final implementation
|
2019-01-30 08:31:59 +00:00
|
|
|
/// \tparam T_IsEncryption flag indicating cipher direction
|
2019-01-29 03:42:34 +00:00
|
|
|
/// \details ChaCha20Poly1305 is an authenticated encryption scheme that combines
|
|
|
|
/// ChaCha20TLS and Poly1305TLS. The scheme is defined in RFC 8439, section 2.8,
|
|
|
|
/// AEAD_CHACHA20_POLY1305 construction, and uses the IETF versions of ChaCha
|
|
|
|
/// and Poly1305.
|
2019-01-28 13:52:56 +00:00
|
|
|
/// \sa <A HREF="http://tools.ietf.org/html/rfc8439">RFC 8439, ChaCha20 and Poly1305
|
|
|
|
/// for IETF Protocols</A>.
|
|
|
|
/// \since Crypto++ 8.1
|
2019-01-30 08:31:59 +00:00
|
|
|
template <bool T_IsEncryption>
|
2019-01-28 13:52:56 +00:00
|
|
|
class ChaCha20Poly1305_Final : public ChaCha20Poly1305_Base
|
|
|
|
{
|
2019-01-28 15:01:19 +00:00
|
|
|
public:
|
|
|
|
static std::string StaticAlgorithmName()
|
|
|
|
{return std::string("ChaCha20/Poly1305");}
|
|
|
|
|
2019-01-28 13:52:56 +00:00
|
|
|
protected:
|
|
|
|
const SymmetricCipher & GetSymmetricCipher()
|
|
|
|
{return const_cast<ChaCha20Poly1305_Final *>(this)->AccessSymmetricCipher();}
|
|
|
|
SymmetricCipher & AccessSymmetricCipher()
|
|
|
|
{return m_cipher;}
|
|
|
|
bool IsForwardTransformation() const
|
2019-01-30 08:31:59 +00:00
|
|
|
{return T_IsEncryption;}
|
2019-01-28 13:52:56 +00:00
|
|
|
|
|
|
|
const MessageAuthenticationCode & GetMAC() const
|
|
|
|
{return const_cast<ChaCha20Poly1305_Final *>(this)->AccessMAC();}
|
|
|
|
MessageAuthenticationCode & AccessMAC()
|
|
|
|
{return m_mac;}
|
|
|
|
|
|
|
|
private:
|
|
|
|
ChaChaTLS::Encryption m_cipher;
|
|
|
|
Poly1305TLS m_mac;
|
|
|
|
};
|
|
|
|
|
|
|
|
/// \brief ChaCha20Poly1305-TLS cipher mode of operation
|
2019-01-29 03:42:34 +00:00
|
|
|
/// \details ChaCha20Poly1305 is an authenticated encryption scheme that combines
|
|
|
|
/// ChaCha20TLS and Poly1305TLS. The scheme is defined in RFC 8439, section 2.8,
|
|
|
|
/// AEAD_CHACHA20_POLY1305 construction, and uses the IETF versions of ChaCha
|
|
|
|
/// and Poly1305.
|
2019-01-28 13:52:56 +00:00
|
|
|
/// \sa <A HREF="http://tools.ietf.org/html/rfc8439">RFC 8439, ChaCha20 and Poly1305
|
|
|
|
/// for IETF Protocols</A>.
|
|
|
|
/// \since Crypto++ 8.1
|
|
|
|
struct ChaCha20Poly1305 : public AuthenticatedSymmetricCipherDocumentation
|
|
|
|
{
|
2019-01-30 05:55:27 +00:00
|
|
|
typedef ChaCha20Poly1305_Final<true> Encryption;
|
|
|
|
typedef ChaCha20Poly1305_Final<false> Decryption;
|
2019-01-28 13:52:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
NAMESPACE_END
|
|
|
|
|
|
|
|
#endif // CRYPTOPP_CHACHA_POLY1305_H
|