Increase use of ptrdiff_t when performing pointer math

Increase use of ptrdiff_t when performing pointer math
Reduce AlgorithmProvider overrides
Fix CPU_ProbeARMv7 on Aarch64
This commit is contained in:
Jeffrey Walton 2018-07-09 06:31:17 -04:00
parent 86773e942c
commit 4c5487b0e4
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
5 changed files with 82 additions and 52 deletions

View File

@ -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<ptrdiff_t>(length) - blockSize;
xorBlocks += static_cast<ptrdiff_t>(length) - blockSize;
outBlocks += static_cast<ptrdiff_t>(length) - blockSize;
inBlocks += static_cast<ptrdiff_t>(length - blockSize);
xorBlocks += static_cast<ptrdiff_t>(length - blockSize);
outBlocks += static_cast<ptrdiff_t>(length - blockSize);
inIncrement = 0-inIncrement;
xorIncrement = 0-xorIncrement;
outIncrement = 0-outIncrement;

View File

@ -503,7 +503,9 @@ void TestSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters)
StreamTransformationFilter encFilter(*encryptor, new StringSink(encrypted),
static_cast<BlockPaddingSchemeDef::BlockPaddingScheme>(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<BlockPaddingSchemeDef::BlockPaddingScheme>(paddingScheme));
RandomizedTransfer(StringStore(encrypted).Ref(), decFilter, true);
StringStore cstore(encrypted);
RandomizedTransfer(cstore, decFilter, true);
decFilter.MessageEnd();
if (decrypted != plaintext)
{
std::cout << "\nincorrectly decrypted: ";

View File

@ -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<ptrdiff_t>(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<byte>(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<ptrdiff_t>(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<ptrdiff_t>(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;

60
modes.h
View File

@ -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<unsigned int>(m_register.size());}
inline unsigned int BlockSize() const
{
CRYPTOPP_ASSERT(m_register.size() > 0);
return static_cast<unsigned int>(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 &params = 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<unsigned int>(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<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >;

View File

@ -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;