Remove potential UB from CFB_CipherConcretePolicy

pull/748/head
Jeffrey Walton 2018-11-19 23:40:51 -05:00
parent 081d9110ee
commit 778f6f122d
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
1 changed files with 22 additions and 9 deletions

View File

@ -203,6 +203,8 @@ struct CRYPTOPP_NO_VTABLE AdditiveCipherConcretePolicy : public BASE
typedef WT WordType; typedef WT WordType;
CRYPTOPP_CONSTANT(BYTES_PER_ITERATION = sizeof(WordType) * W) CRYPTOPP_CONSTANT(BYTES_PER_ITERATION = sizeof(WordType) * W)
virtual ~AdditiveCipherConcretePolicy() {}
#if !(CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64) #if !(CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64)
/// \brief Provides data alignment requirements /// \brief Provides data alignment requirements
/// \returns data alignment requirements, in bytes /// \returns data alignment requirements, in bytes
@ -289,6 +291,7 @@ class CRYPTOPP_NO_VTABLE AdditiveCipherTemplate : public BASE, public RandomNumb
{ {
public: public:
virtual ~AdditiveCipherTemplate() {} virtual ~AdditiveCipherTemplate() {}
AdditiveCipherTemplate() : m_leftOver(0) {}
/// \brief Generate random array of bytes /// \brief Generate random array of bytes
/// \param output the byte buffer /// \param output the byte buffer
@ -366,7 +369,7 @@ public:
/// dominant one. For example on x86 <tt>AES/GCM</tt> returns "AESNI" rather than /// dominant one. For example on x86 <tt>AES/GCM</tt> returns "AESNI" rather than
/// "CLMUL" or "AES+SSE4.1" or "AES+CLMUL" or "AES+SSE4.1+CLMUL". /// "CLMUL" or "AES+SSE4.1" or "AES+CLMUL" or "AES+SSE4.1+CLMUL".
/// \note Provider is not universally implemented yet. /// \note Provider is not universally implemented yet.
virtual std::string AlgorithmProvider() const { return this->GetPolicy().AlgorithmProvider(); } std::string AlgorithmProvider() const { return this->GetPolicy().AlgorithmProvider(); }
typedef typename BASE::PolicyInterface PolicyInterface; typedef typename BASE::PolicyInterface PolicyInterface;
@ -378,7 +381,7 @@ protected:
inline byte * KeystreamBufferBegin() {return this->m_buffer.data();} inline byte * KeystreamBufferBegin() {return this->m_buffer.data();}
inline byte * KeystreamBufferEnd() {return (PtrAdd(this->m_buffer.data(), this->m_buffer.size()));} inline byte * KeystreamBufferEnd() {return (PtrAdd(this->m_buffer.data(), this->m_buffer.size()));}
SecByteBlock m_buffer; AlignedSecByteBlock m_buffer;
size_t m_leftOver; size_t m_leftOver;
}; };
@ -460,6 +463,8 @@ struct CRYPTOPP_NO_VTABLE CFB_CipherConcretePolicy : public BASE
{ {
typedef WT WordType; typedef WT WordType;
virtual ~CFB_CipherConcretePolicy() {}
/// \brief Provides data alignment requirements /// \brief Provides data alignment requirements
/// \returns data alignment requirements, in bytes /// \returns data alignment requirements, in bytes
/// \details Internally, the default implementation returns 1. If the stream cipher is implemented /// \details Internally, the default implementation returns 1. If the stream cipher is implemented
@ -494,8 +499,8 @@ struct CRYPTOPP_NO_VTABLE CFB_CipherConcretePolicy : public BASE
/// \returns reference to the next feedback register word /// \returns reference to the next feedback register word
inline RegisterOutput& operator()(WordType &registerWord) inline RegisterOutput& operator()(WordType &registerWord)
{ {
CRYPTOPP_ASSERT(IsAligned<WordType>(m_output)); //CRYPTOPP_ASSERT(IsAligned<WordType>(m_output));
CRYPTOPP_ASSERT(IsAligned<WordType>(m_input)); //CRYPTOPP_ASSERT(IsAligned<WordType>(m_input));
if (!NativeByteOrderIs(B::ToEnum())) if (!NativeByteOrderIs(B::ToEnum()))
registerWord = ByteReverse(registerWord); registerWord = ByteReverse(registerWord);
@ -508,18 +513,26 @@ struct CRYPTOPP_NO_VTABLE CFB_CipherConcretePolicy : public BASE
} }
else else
{ {
WordType ct = *(const WordType *)m_input ^ registerWord; // WordType ct = *(const WordType *)m_input ^ registerWord;
WordType ct = GetWord<WordType>(false, NativeByteOrder::ToEnum(), m_input) ^ registerWord;
registerWord = ct; registerWord = ct;
*(WordType*)m_output = ct;
// *(WordType*)m_output = ct;
PutWord<WordType>(false, NativeByteOrder::ToEnum(), m_output, ct);
m_input += sizeof(WordType); m_input += sizeof(WordType);
m_output += sizeof(WordType); m_output += sizeof(WordType);
} }
} }
else else
{ {
WordType ct = *(const WordType *)m_input; // WordType ct = *(const WordType *)m_input;
*(WordType*)m_output = registerWord ^ ct; WordType ct = GetWord<WordType>(false, NativeByteOrder::ToEnum(), m_input);
// *(WordType*)m_output = registerWord ^ ct;
PutWord<WordType>(false, NativeByteOrder::ToEnum(), m_output, registerWord ^ ct);
registerWord = ct; registerWord = ct;
m_input += sizeof(WordType); m_input += sizeof(WordType);
m_output += sizeof(WordType); m_output += sizeof(WordType);
} }
@ -604,7 +617,7 @@ public:
/// dominant one. For example on x86 <tt>AES/GCM</tt> returns "AESNI" rather than /// dominant one. For example on x86 <tt>AES/GCM</tt> returns "AESNI" rather than
/// "CLMUL" or "AES+SSE4.1" or "AES+CLMUL" or "AES+SSE4.1+CLMUL". /// "CLMUL" or "AES+SSE4.1" or "AES+CLMUL" or "AES+SSE4.1+CLMUL".
/// \note Provider is not universally implemented yet. /// \note Provider is not universally implemented yet.
virtual std::string AlgorithmProvider() const { return this->GetPolicy().AlgorithmProvider(); } std::string AlgorithmProvider() const { return this->GetPolicy().AlgorithmProvider(); }
typedef typename BASE::PolicyInterface PolicyInterface; typedef typename BASE::PolicyInterface PolicyInterface;