diff --git a/cryptlib.cpp b/cryptlib.cpp index 2b232dcf..0f38cc76 100644 --- a/cryptlib.cpp +++ b/cryptlib.cpp @@ -150,16 +150,16 @@ size_t BlockTransformation::AdvancedProcessBlocks(const byte *inBlocks, const by CRYPTOPP_ASSERT(outBlocks); CRYPTOPP_ASSERT(length); - const size_t blockSize = BlockSize(); + const ptrdiff_t blockSize = BlockSize(); ptrdiff_t inIncrement = (flags & (BT_InBlockIsCounter|BT_DontIncrementInOutPointers)) ? 0 : blockSize; ptrdiff_t xorIncrement = xorBlocks ? blockSize : 0; ptrdiff_t outIncrement = (flags & BT_DontIncrementInOutPointers) ? 0 : blockSize; if (flags & BT_ReverseDirection) { - inBlocks += static_cast(length) - blockSize; - xorBlocks += static_cast(length) - blockSize; - outBlocks += static_cast(length) - blockSize; + inBlocks += static_cast(length - blockSize); + xorBlocks += static_cast(length - blockSize); + outBlocks += static_cast(length - blockSize); inIncrement = 0-inIncrement; xorIncrement = 0-xorIncrement; outIncrement = 0-outIncrement; diff --git a/datatest.cpp b/datatest.cpp index fc9b69b0..b83cbcce 100644 --- a/datatest.cpp +++ b/datatest.cpp @@ -503,7 +503,9 @@ void TestSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters) StreamTransformationFilter encFilter(*encryptor, new StringSink(encrypted), static_cast(paddingScheme)); - RandomizedTransfer(StringStore(plaintext).Ref(), encFilter, true); + + StringStore pstore(plaintext); + RandomizedTransfer(pstore, encFilter, true); encFilter.MessageEnd(); if (test != "EncryptXorDigest") @@ -523,11 +525,15 @@ void TestSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters) std::cout << "\n"; SignalTestFailure(); } + std::string decrypted; StreamTransformationFilter decFilter(*decryptor, new StringSink(decrypted), static_cast(paddingScheme)); - RandomizedTransfer(StringStore(encrypted).Ref(), decFilter, true); + + StringStore cstore(encrypted); + RandomizedTransfer(cstore, decFilter, true); decFilter.MessageEnd(); + if (decrypted != plaintext) { std::cout << "\nincorrectly decrypted: "; diff --git a/modes.cpp b/modes.cpp index c82cbe6d..2a4f0cf9 100644 --- a/modes.cpp +++ b/modes.cpp @@ -37,7 +37,7 @@ void CFB_ModePolicy::Iterate(byte *output, const byte *input, CipherDir dir, siz CRYPTOPP_ASSERT(m_register.size() == BlockSize()); CRYPTOPP_ASSERT(m_temp.size() == BlockSize()); - const unsigned int s = BlockSize(); + const ptrdiff_t s = BlockSize(); if (dir == ENCRYPTION) { m_cipher->ProcessAndXorBlock(m_register, input, output); @@ -63,7 +63,7 @@ void CFB_ModePolicy::TransformRegister() CRYPTOPP_ASSERT(m_temp.size() == BlockSize()); m_cipher->ProcessBlock(m_register, m_temp); - const unsigned int updateSize = BlockSize()-m_feedbackSize; + const ptrdiff_t updateSize = BlockSize()-m_feedbackSize; memmove_s(m_register, m_register.size(), m_register+m_feedbackSize, updateSize); memcpy_s(m_register+updateSize, m_register.size()-updateSize, m_temp, m_feedbackSize); } @@ -90,12 +90,19 @@ void CFB_ModePolicy::ResizeBuffers() m_temp.New(BlockSize()); } +byte* CFB_ModePolicy::GetRegisterBegin() +{ + CRYPTOPP_ASSERT(!m_register.empty()); + CRYPTOPP_ASSERT(BlockSize() >= m_feedbackSize); + return m_register + static_cast(BlockSize() - m_feedbackSize); +} + void OFB_ModePolicy::WriteKeystream(byte *keystreamBuffer, size_t iterationCount) { CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation()); CRYPTOPP_ASSERT(m_register.size() == BlockSize()); - const unsigned int s = BlockSize(); + const ptrdiff_t s = BlockSize(); m_cipher->ProcessBlock(m_register, keystreamBuffer); if (iterationCount > 1) m_cipher->AdvancedProcessBlocks(keystreamBuffer, NULLPTR, keystreamBuffer+s, s*(iterationCount-1), 0); @@ -117,7 +124,7 @@ void CTR_ModePolicy::SeekToIteration(lword iterationCount) for (int i=BlockSize()-1; i>=0; i--) { unsigned int sum = m_register[i] + byte(iterationCount) + carry; - m_counterArray[i] = (byte) sum; + m_counterArray[i] = static_cast(sum); carry = sum >> 8; iterationCount >>= 8; } @@ -133,8 +140,8 @@ void CTR_ModePolicy::OperateKeystream(KeystreamOperation /*operation*/, byte *ou CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation()); CRYPTOPP_ASSERT(m_counterArray.size() == BlockSize()); - const unsigned int s = BlockSize(); - const unsigned int inputIncrement = input ? s : 0; + const ptrdiff_t s = BlockSize(); + const ptrdiff_t inputIncrement = input ? s : 0; while (iterationCount) { @@ -190,7 +197,7 @@ void CBC_Encryption::ProcessData(byte *outString, const byte *inString, size_t l CRYPTOPP_ASSERT(m_register.size() == BlockSize()); if (!length) return; - const unsigned int blockSize = BlockSize(); + const ptrdiff_t blockSize = BlockSize(); m_cipher->AdvancedProcessBlocks(inString, m_register, outString, blockSize, BlockTransformation::BT_XorInput); if (length > blockSize) m_cipher->AdvancedProcessBlocks(inString+blockSize, outString, outString+blockSize, length-blockSize, BlockTransformation::BT_XorInput); @@ -200,7 +207,9 @@ void CBC_Encryption::ProcessData(byte *outString, const byte *inString, size_t l size_t CBC_CTS_Encryption::ProcessLastBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength) { CRYPTOPP_UNUSED(outLength); - size_t used = inLength; + const size_t used = inLength; + const ptrdiff_t blockSize = static_cast(BlockSize()); + if (inLength <= BlockSize()) { if (!m_stolenIV) @@ -215,9 +224,8 @@ size_t CBC_CTS_Encryption::ProcessLastBlock(byte *outString, size_t outLength, c // steal from next to last block xorbuf(m_register, inString, BlockSize()); m_cipher->ProcessBlock(m_register); - inString += BlockSize(); - inLength -= BlockSize(); - memcpy(outString+BlockSize(), m_register, inLength); + inString += blockSize; inLength -= blockSize; + memcpy(outString+blockSize, m_register, inLength); } // output last full ciphertext block @@ -236,12 +244,12 @@ void CBC_Decryption::ResizeBuffers() void CBC_Decryption::ProcessData(byte *outString, const byte *inString, size_t length) { - if (!length) - return; CRYPTOPP_ASSERT(length%BlockSize()==0); + if (!length) {return;} - const unsigned int blockSize = BlockSize(); - memcpy(m_temp, inString+length-blockSize, blockSize); // save copy now in case of in-place decryption + // save copy now in case of in-place decryption + const ptrdiff_t blockSize = BlockSize(); + memcpy(m_temp, inString+length-blockSize, blockSize); if (length > blockSize) m_cipher->AdvancedProcessBlocks(inString+blockSize, inString, outString+blockSize, length-blockSize, BlockTransformation::BT_ReverseDirection|BlockTransformation::BT_AllowParallel); m_cipher->ProcessAndXorBlock(inString, m_register, outString); @@ -252,8 +260,9 @@ size_t CBC_CTS_Decryption::ProcessLastBlock(byte *outString, size_t outLength, c { CRYPTOPP_UNUSED(outLength); const byte *pn1, *pn2; - bool stealIV = inLength <= BlockSize(); - size_t used = inLength; + const size_t used = inLength; + const bool stealIV = inLength <= BlockSize(); + const ptrdiff_t blockSize = static_cast(BlockSize()); if (stealIV) { @@ -262,13 +271,13 @@ size_t CBC_CTS_Decryption::ProcessLastBlock(byte *outString, size_t outLength, c } else { - pn1 = inString + BlockSize(); + pn1 = inString + blockSize; pn2 = inString; - inLength -= BlockSize(); + inLength -= blockSize; } // decrypt last partial plaintext block - memcpy(m_temp, pn2, BlockSize()); + memcpy(m_temp, pn2, blockSize); m_cipher->ProcessBlock(m_temp); xorbuf(m_temp, pn1, inLength); @@ -278,11 +287,11 @@ size_t CBC_CTS_Decryption::ProcessLastBlock(byte *outString, size_t outLength, c } else { - memcpy(outString+BlockSize(), m_temp, inLength); + memcpy(outString+blockSize, m_temp, inLength); // decrypt next to last plaintext block memcpy(m_temp, pn1, inLength); m_cipher->ProcessBlock(m_temp); - xorbuf(outString, m_temp, m_register, BlockSize()); + xorbuf(outString, m_temp, m_register, blockSize); } return used; diff --git a/modes.h b/modes.h index dd7f71a7..d4ebdcd8 100644 --- a/modes.h +++ b/modes.h @@ -51,6 +51,11 @@ class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CipherModeBase : public SymmetricCipher public: virtual ~CipherModeBase() {} + // Algorithm class + std::string AlgorithmProvider() const { + return m_cipher != NULLPTR ? m_cipher->AlgorithmProvider() : "C++"; + } + /// \brief Returns smallest valid key length /// \returns the minimum key length, in bytes size_t MinKeyLength() const {return m_cipher->MinKeyLength();} @@ -121,7 +126,11 @@ public: protected: CipherModeBase() : m_cipher(NULLPTR) {} - inline unsigned int BlockSize() const {CRYPTOPP_ASSERT(m_register.size() > 0); return static_cast(m_register.size());} + inline unsigned int BlockSize() const + { + CRYPTOPP_ASSERT(m_register.size() > 0); + return static_cast(m_register.size()); + } virtual void SetFeedbackSize(unsigned int feedbackSize) { if (!(feedbackSize == 0 || feedbackSize == BlockSize())) @@ -131,7 +140,7 @@ protected: virtual void ResizeBuffers(); BlockCipher *m_cipher; - AlignedSecByteBlock m_register; + SecByteBlock m_register; }; /// \brief Block cipher mode of operation common operations @@ -157,34 +166,41 @@ class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_ModePolicy : public ModePolicyCommonTe { public: CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "CFB";} - std::string AlgorithmProvider() const { return m_cipher->AlgorithmProvider(); } - virtual ~CFB_ModePolicy() {} + IV_Requirement IVRequirement() const {return RANDOM_IV;} protected: unsigned int GetBytesPerIteration() const {return m_feedbackSize;} - byte * GetRegisterBegin() {return m_register + BlockSize() - m_feedbackSize;} bool CanIterate() const {return m_feedbackSize == BlockSize();} void Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount); void TransformRegister(); void CipherResynchronize(const byte *iv, size_t length); void SetFeedbackSize(unsigned int feedbackSize); void ResizeBuffers(); + byte * GetRegisterBegin(); SecByteBlock m_temp; unsigned int m_feedbackSize; }; -inline void CopyOrZero(void *dest, size_t d, const void *src, size_t s) +/// \brief Initialize a block of memory +/// \param dest the destination block of memory +/// \param dsize the size of the destination block, in bytes +/// \param src the source block of memory +/// \param ssize the size of the source block, in bytes +/// \details CopyOrZero copies ssize bytes from source to destination if +/// src is not NULL. If src is NULL then dest is zero'd. Bounds are not +/// checked at runtime. Debug builds assert if ssize exceeds dsize. +inline void CopyOrZero(void *dest, size_t dsize, const void *src, size_t ssize) { CRYPTOPP_ASSERT(dest); - CRYPTOPP_ASSERT(d >= s); + CRYPTOPP_ASSERT(dsize >= ssize); - if (src) - memcpy_s(dest, d, src, s); + if (src != NULLPTR) + memcpy_s(dest, dsize, src, ssize); else - memset(dest, 0, d); + memset(dest, 0, dsize); } /// \brief OFB block cipher mode of operation @@ -192,12 +208,11 @@ class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE OFB_ModePolicy : public ModePolicyCommonTe { public: CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "OFB";} - std::string AlgorithmProvider() const { return m_cipher->AlgorithmProvider(); } bool CipherIsRandomAccess() const {return false;} IV_Requirement IVRequirement() const {return UNIQUE_IV;} -private: +protected: unsigned int GetBytesPerIteration() const {return BlockSize();} unsigned int GetIterationsToBuffer() const {return m_cipher->OptimalNumberOfParallelBlocks();} void WriteKeystream(byte *keystreamBuffer, size_t iterationCount); @@ -209,7 +224,6 @@ class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CTR_ModePolicy : public ModePolicyCommonTe { public: CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "CTR";} - std::string AlgorithmProvider() const { return m_cipher->AlgorithmProvider(); } virtual ~CTR_ModePolicy() {} bool CipherIsRandomAccess() const {return true;} @@ -227,7 +241,7 @@ protected: void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length); void SeekToIteration(lword iterationCount); - AlignedSecByteBlock m_counterArray; + SecByteBlock m_counterArray; }; /// \brief Block cipher mode of operation default implementation @@ -254,12 +268,11 @@ class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ECB_OneWay : public BlockOrientedCipherMod { public: CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECB";} - std::string AlgorithmProvider() const { return m_cipher->AlgorithmProvider(); } void SetKey(const byte *key, size_t length, const NameValuePairs ¶ms = g_nullNameValuePairs) {m_cipher->SetKey(key, length, params); BlockOrientedCipherModeBase::ResizeBuffers();} IV_Requirement IVRequirement() const {return NOT_RESYNCHRONIZABLE;} - unsigned int OptimalBlockSize() const {return BlockSize() * m_cipher->OptimalNumberOfParallelBlocks();} + unsigned int OptimalBlockSize() const {return static_cast(BlockSize() * m_cipher->OptimalNumberOfParallelBlocks());} void ProcessData(byte *outString, const byte *inString, size_t length); }; @@ -268,7 +281,6 @@ class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_ModeBase : public BlockOrientedCipherM { public: CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "CBC";} - std::string AlgorithmProvider() const { return m_cipher->AlgorithmProvider(); } IV_Requirement IVRequirement() const {return UNPREDICTABLE_RANDOM_IV;} bool RequireAlignedInput() const {return false;} @@ -288,7 +300,6 @@ class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_CTS_Encryption : public CBC_Encryption { public: CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "CBC/CTS";} - std::string AlgorithmProvider() const { return m_cipher->AlgorithmProvider(); } void SetStolenIV(byte *iv) {m_stolenIV = iv;} unsigned int MinLastBlockSize() const {return BlockSize()+1;} @@ -314,7 +325,7 @@ public: protected: virtual void ResizeBuffers(); - AlignedSecByteBlock m_temp; + SecByteBlock m_temp; }; /// \brief CBC-CTS block cipher mode of operation decryption operation @@ -338,8 +349,6 @@ public: /// Shoup's ECIES. static std::string CRYPTOPP_API StaticAlgorithmName() {return CIPHER::StaticAlgorithmName() + "/" + BASE::StaticAlgorithmName();} - std::string AlgorithmProvider() const - { return this->m_cipher->AlgorithmProvider(); } /// \brief Construct a CipherModeFinalTemplate CipherModeFinalTemplate_CipherHolder() @@ -380,6 +389,11 @@ public: this->m_cipher = &this->m_object; this->SetKey(key, length, MakeParameters(Name::IV(), ConstByteArrayParameter(iv, this->m_cipher->BlockSize()))(Name::FeedbackSize(), feedbackSize)); } + + // Algorithm class + std::string AlgorithmProvider() const { + return this->m_cipher->AlgorithmProvider(); + } }; /// \tparam BASE CipherModeFinalTemplate_CipherHolder base class @@ -414,8 +428,10 @@ public: /// \note AlgorithmName is not universally implemented yet std::string AlgorithmName() const {return (this->m_cipher ? this->m_cipher->AlgorithmName() + "/" : std::string("")) + BASE::StaticAlgorithmName();} + + // Algorithm class std::string AlgorithmProvider() const - { return this->m_cipher ? this->m_cipher->AlgorithmProvider() : "C++"; } + {return this->m_cipher->AlgorithmProvider();} }; CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate >; diff --git a/neon-simd.cpp b/neon-simd.cpp index dcc4d3a0..2dd1fa27 100644 --- a/neon-simd.cpp +++ b/neon-simd.cpp @@ -64,8 +64,7 @@ bool CPU_ProbeARMv7() return false; } return result; -# else - +# elif defined(__arm__) // longjmp and clobber warnings. Volatile is required. // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854 volatile bool result = true;