diff --git a/filters.cpp b/filters.cpp index 7b0017a6..e4ffe2ca 100644 --- a/filters.cpp +++ b/filters.cpp @@ -579,13 +579,30 @@ size_t ArrayXorSink::Put2(const byte *begin, size_t length, int messageEnd, bool // ************************************************************* -StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding, bool allowAuthenticatedSymmetricCipher) +StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding) : FilterWithBufferedInput(attachment) - , m_cipher(c), m_padding(DEFAULT_PADDING), m_optimalBufferSize(0) + , m_cipher(c), m_padding(DEFAULT_PADDING), m_optimalBufferSize(0), m_authenticated(false) { CRYPTOPP_ASSERT(c.MinLastBlockSize() == 0 || c.MinLastBlockSize() > c.MandatoryBlockSize()); - if (!allowAuthenticatedSymmetricCipher && dynamic_cast(&c) != NULLPTR) + const bool authenticatedFilter = dynamic_cast(&c) != NULLPTR; + if (authenticatedFilter && !m_authenticated) + throw InvalidArgument("StreamTransformationFilter: please use AuthenticatedEncryptionFilter and AuthenticatedDecryptionFilter for AuthenticatedSymmetricCipher"); + + IsolatedInitialize(MakeParameters(Name::BlockPaddingScheme(), padding)); +} + +StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding, bool authenticated) + : FilterWithBufferedInput(attachment) + , m_cipher(c), m_padding(DEFAULT_PADDING), m_optimalBufferSize(0), m_authenticated(authenticated) +{ + const bool authenticatedFilter = dynamic_cast(&c) != NULLPTR; + if (!authenticatedFilter) + { + CRYPTOPP_ASSERT(c.MinLastBlockSize() == 0 || c.MinLastBlockSize() > c.MandatoryBlockSize()); + } + + if (authenticatedFilter && !m_authenticated) throw InvalidArgument("StreamTransformationFilter: please use AuthenticatedEncryptionFilter and AuthenticatedDecryptionFilter for AuthenticatedSymmetricCipher"); IsolatedInitialize(MakeParameters(Name::BlockPaddingScheme(), padding)); diff --git a/filters.h b/filters.h index 2e56f122..5fda823d 100644 --- a/filters.h +++ b/filters.h @@ -336,6 +336,7 @@ public: { return PutMaybeModifiable(const_cast(inString), length, messageEnd, blocking, false); } + size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking) { return PutMaybeModifiable(inString, length, messageEnd, blocking, true); @@ -499,7 +500,10 @@ struct BlockPaddingSchemeDef //! \class StreamTransformationFilter //! \brief Filter wrapper for StreamTransformation -//! \details StreamTransformationFilter is a filter wrapper for StreamTransformation. The filter will optionally handle padding/unpadding when needed +//! \details StreamTransformationFilter() is a filter wrapper for StreamTransformation(). It is used when +//! pipelining data for stream ciphers and confidentiality-only block ciphers. The filter will optionally +//! handle padding and unpadding when needed. If you are using an authenticated encryption mode of operation, +//! then use AuthenticatedEncryptionFilter() and AuthenticatedDecryptionFilter() //! \since Crypto++ 5.0 class CRYPTOPP_DLL StreamTransformationFilter : public FilterWithBufferedInput, public BlockPaddingSchemeDef, private FilterPutSpaceHelper { @@ -510,12 +514,29 @@ public: //! \param c reference to a StreamTransformation //! \param attachment an optional attached transformation //! \param padding the \ref BlockPaddingSchemeDef "padding scheme" - //! \param allowAuthenticatedSymmetricCipher flag indicating whether the filter should allow authenticated encryption schemes - StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment = NULLPTR, BlockPaddingScheme padding = DEFAULT_PADDING, bool allowAuthenticatedSymmetricCipher = false); + //! \details This contructor creates a StreamTransformationFilter() for stream ciphers and + //! confidentiality-only block cipher modes of operation. If you are using an authenticated + //! encryption mode of operation, then use either AuthenticatedEncryptionFilter() or + //! AuthenticatedDecryptionFilter(). + //! \sa AuthenticatedEncryptionFilter() and AuthenticatedDecryptionFilter() + StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment = NULLPTR, BlockPaddingScheme padding = DEFAULT_PADDING); std::string AlgorithmName() const {return m_cipher.AlgorithmName();} protected: + + friend class AuthenticatedEncryptionFilter; + friend class AuthenticatedDecryptionFilter; + + //! \brief Construct a StreamTransformationFilter + //! \param c reference to a StreamTransformation + //! \param attachment an optional attached transformation + //! \param padding the \ref BlockPaddingSchemeDef "padding scheme" + //! \param authenticated flag indicating whether the filter should allow authenticated encryption schemes + //! \details This constructor is used for authenticated encryption mode of operation and by + //! AuthenticatedEncryptionFilter() and AuthenticatedDecryptionFilter(). + StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding, bool authenticated); + void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize); void FirstPut(const byte *inString); void NextPutMultiple(const byte *inString, size_t length); @@ -527,6 +548,8 @@ protected: StreamTransformation &m_cipher; BlockPaddingScheme m_padding; unsigned int m_optimalBufferSize; + // TODO: do we need this? + bool m_authenticated; }; //! \class HashFilter