Add PtrAdd and PtrSub helper functions

This helps contain UB on pointer subtraction by ensuring a ptrdiff_t is used. The code is a little uglier but it is also more portable.
pull/687/head
Jeffrey Walton 2018-07-10 05:00:02 -04:00
parent c186689273
commit c6c44aa5d1
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
7 changed files with 468 additions and 446 deletions

File diff suppressed because it is too large Load Diff

View File

@ -150,16 +150,16 @@ size_t BlockTransformation::AdvancedProcessBlocks(const byte *inBlocks, const by
CRYPTOPP_ASSERT(outBlocks); CRYPTOPP_ASSERT(outBlocks);
CRYPTOPP_ASSERT(length); CRYPTOPP_ASSERT(length);
const ptrdiff_t blockSize = BlockSize(); const unsigned int blockSize = BlockSize();
ptrdiff_t inIncrement = (flags & (BT_InBlockIsCounter|BT_DontIncrementInOutPointers)) ? 0 : blockSize; size_t inIncrement = (flags & (BT_InBlockIsCounter|BT_DontIncrementInOutPointers)) ? 0 : blockSize;
ptrdiff_t xorIncrement = xorBlocks ? blockSize : 0; size_t xorIncrement = xorBlocks ? blockSize : 0;
ptrdiff_t outIncrement = (flags & BT_DontIncrementInOutPointers) ? 0 : blockSize; size_t outIncrement = (flags & BT_DontIncrementInOutPointers) ? 0 : blockSize;
if (flags & BT_ReverseDirection) if (flags & BT_ReverseDirection)
{ {
inBlocks += static_cast<ptrdiff_t>(length - blockSize); inBlocks = PtrAdd(inBlocks, length - blockSize);
xorBlocks += static_cast<ptrdiff_t>(length - blockSize); xorBlocks = PtrAdd(xorBlocks, length - blockSize);
outBlocks += static_cast<ptrdiff_t>(length - blockSize); outBlocks = PtrAdd(outBlocks, length - blockSize);
inIncrement = 0-inIncrement; inIncrement = 0-inIncrement;
xorIncrement = 0-xorIncrement; xorIncrement = 0-xorIncrement;
outIncrement = 0-outIncrement; outIncrement = 0-outIncrement;
@ -184,9 +184,9 @@ size_t BlockTransformation::AdvancedProcessBlocks(const byte *inBlocks, const by
if (flags & BT_InBlockIsCounter) if (flags & BT_InBlockIsCounter)
const_cast<byte *>(inBlocks)[blockSize-1]++; const_cast<byte *>(inBlocks)[blockSize-1]++;
inBlocks += inIncrement; inBlocks = PtrAdd(inBlocks, inIncrement);
outBlocks += outIncrement; outBlocks = PtrAdd(outBlocks, outIncrement);
xorBlocks += xorIncrement; xorBlocks = PtrAdd(xorBlocks, xorIncrement);
length -= blockSize; length -= blockSize;
} }

View File

@ -189,7 +189,7 @@ size_t MeterFilter::PutMaybeModifiable(byte *begin, size_t length, int messageEn
FILTER_OUTPUT_MAYBE_MODIFIABLE(1, m_begin, t = (size_t)SaturatingSubtract(m_rangesToSkip.front().position, m_currentMessageBytes), false, modifiable); FILTER_OUTPUT_MAYBE_MODIFIABLE(1, m_begin, t = (size_t)SaturatingSubtract(m_rangesToSkip.front().position, m_currentMessageBytes), false, modifiable);
CRYPTOPP_ASSERT(t < m_length); CRYPTOPP_ASSERT(t < m_length);
m_begin += t; m_begin = PtrAdd(m_begin, t);
m_length -= t; m_length -= t;
m_currentMessageBytes += t; m_currentMessageBytes += t;
m_totalBytes += t; m_totalBytes += t;
@ -203,7 +203,7 @@ size_t MeterFilter::PutMaybeModifiable(byte *begin, size_t length, int messageEn
m_rangesToSkip.pop_front(); m_rangesToSkip.pop_front();
} }
m_begin += t; m_begin = PtrAdd(m_begin, t);
m_length -= t; m_length -= t;
m_currentMessageBytes += t; m_currentMessageBytes += t;
m_totalBytes += t; m_totalBytes += t;
@ -277,7 +277,7 @@ byte *FilterWithBufferedInput::BlockQueue::GetContigousBlocks(size_t &numberOfBy
{ {
numberOfBytes = STDMIN(numberOfBytes, STDMIN(size_t(m_buffer.end()-m_begin), m_size)); numberOfBytes = STDMIN(numberOfBytes, STDMIN(size_t(m_buffer.end()-m_begin), m_size));
byte *ptr = m_begin; byte *ptr = m_begin;
m_begin += numberOfBytes; m_begin = PtrAdd(m_begin, numberOfBytes);
m_size -= numberOfBytes; m_size -= numberOfBytes;
if (m_size == 0 || m_begin == m_buffer.end()) if (m_size == 0 || m_begin == m_buffer.end())
m_begin = m_buffer; m_begin = m_buffer;
@ -308,7 +308,7 @@ void FilterWithBufferedInput::BlockQueue::Put(const byte *inString, size_t lengt
size_t len = STDMIN(length, size_t(m_buffer.end()-end)); size_t len = STDMIN(length, size_t(m_buffer.end()-end));
memcpy(end, inString, len); memcpy(end, inString, len);
if (len < length) if (len < length)
memcpy(m_buffer, inString+len, length-len); memcpy(m_buffer, PtrAdd(inString, len), length-len);
m_size += length; m_size += length;
} }
@ -364,7 +364,7 @@ size_t FilterWithBufferedInput::PutMaybeModifiable(byte *inString, size_t length
CRYPTOPP_ASSERT(m_queue.CurrentSize() == 0); CRYPTOPP_ASSERT(m_queue.CurrentSize() == 0);
m_queue.ResetQueue(m_blockSize, (2*m_blockSize+m_lastSize-2)/m_blockSize); m_queue.ResetQueue(m_blockSize, (2*m_blockSize+m_lastSize-2)/m_blockSize);
inString += len; inString = PtrAdd(inString, len);
newLength -= m_firstSize; newLength -= m_firstSize;
m_firstInputDone = true; m_firstInputDone = true;
} }
@ -385,7 +385,7 @@ size_t FilterWithBufferedInput::PutMaybeModifiable(byte *inString, size_t length
{ {
size_t len = newLength - m_lastSize; size_t len = newLength - m_lastSize;
NextPutMaybeModifiable(inString, len, modifiable); NextPutMaybeModifiable(inString, len, modifiable);
inString += len; inString = PtrAdd(inString, len);
newLength -= len; newLength -= len;
} }
} }
@ -402,7 +402,7 @@ size_t FilterWithBufferedInput::PutMaybeModifiable(byte *inString, size_t length
CRYPTOPP_ASSERT(m_queue.CurrentSize() < m_blockSize); CRYPTOPP_ASSERT(m_queue.CurrentSize() < m_blockSize);
size_t len = m_blockSize - m_queue.CurrentSize(); size_t len = m_blockSize - m_queue.CurrentSize();
m_queue.Put(inString, len); m_queue.Put(inString, len);
inString += len; inString = PtrAdd(inString, len);
NextPutModifiable(m_queue.GetBlock(), m_blockSize); NextPutModifiable(m_queue.GetBlock(), m_blockSize);
newLength -= m_blockSize; newLength -= m_blockSize;
} }
@ -411,7 +411,7 @@ size_t FilterWithBufferedInput::PutMaybeModifiable(byte *inString, size_t length
{ {
size_t len = RoundDownToMultipleOf(newLength - m_lastSize, m_blockSize); size_t len = RoundDownToMultipleOf(newLength - m_lastSize, m_blockSize);
NextPutMaybeModifiable(inString, len, modifiable); NextPutMaybeModifiable(inString, len, modifiable);
inString += len; inString = PtrAdd(inString, len);
newLength -= len; newLength -= len;
} }
} }
@ -463,7 +463,7 @@ void FilterWithBufferedInput::NextPutMultiple(const byte *inString, size_t lengt
{ {
CRYPTOPP_ASSERT(length >= m_blockSize); CRYPTOPP_ASSERT(length >= m_blockSize);
NextPutSingle(inString); NextPutSingle(inString);
inString += m_blockSize; inString = PtrAdd(inString, m_blockSize);
length -= m_blockSize; length -= m_blockSize;
} }
} }
@ -679,7 +679,7 @@ void StreamTransformationFilter::NextPutMultiple(const byte *inString, size_t le
len = length; len = length;
m_cipher.ProcessString(space, inString, len); m_cipher.ProcessString(space, inString, len);
AttachedTransformation()->PutModifiable(space, len); AttachedTransformation()->PutModifiable(space, len);
inString += len; inString = PtrAdd(inString, len);
length -= len; length -= len;
} }
while (length > 0); while (length > 0);
@ -719,8 +719,8 @@ void StreamTransformationFilter::LastPut(const byte *inString, size_t length)
{ {
const size_t leftOver = length % m_mandatoryBlockSize; const size_t leftOver = length % m_mandatoryBlockSize;
space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, m_reservedBufferSize); space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, m_reservedBufferSize);
length -= leftOver; length -= leftOver;
if (length) if (length)
{ {
// Process full blocks // Process full blocks
@ -1196,7 +1196,7 @@ size_t StringStore::TransferTo2(BufferedTransformation &target, lword &transferB
{ {
lword position = 0; lword position = 0;
size_t blockedBytes = CopyRangeTo2(target, position, transferBytes, channel, blocking); size_t blockedBytes = CopyRangeTo2(target, position, transferBytes, channel, blocking);
m_count += (size_t)position; m_count += static_cast<size_t>(position);
transferBytes = position; transferBytes = position;
return blockedBytes; return blockedBytes;
} }
@ -1205,9 +1205,9 @@ size_t StringStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, l
{ {
size_t i = UnsignedMin(m_length, m_count+begin); size_t i = UnsignedMin(m_length, m_count+begin);
size_t len = UnsignedMin(m_length-i, end-begin); size_t len = UnsignedMin(m_length-i, end-begin);
size_t blockedBytes = target.ChannelPut2(channel, m_store+i, len, 0, blocking); size_t blockedBytes = target.ChannelPut2(channel, PtrAdd(m_store, i), len, 0, blocking);
if (!blockedBytes) if (!blockedBytes)
begin += len; begin = PtrAdd(begin, len);
return blockedBytes; return blockedBytes;
} }
@ -1240,7 +1240,7 @@ size_t NullStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lwo
size_t blockedBytes = target.ChannelPut2(channel, nullBytes, len, 0, blocking); size_t blockedBytes = target.ChannelPut2(channel, nullBytes, len, 0, blocking);
if (blockedBytes) if (blockedBytes)
return blockedBytes; return blockedBytes;
begin += len; begin = PtrAdd(begin, len);
} }
return 0; return 0;
} }
@ -1249,8 +1249,7 @@ size_t NullStore::TransferTo2(BufferedTransformation &target, lword &transferByt
{ {
lword begin = 0; lword begin = 0;
size_t blockedBytes = NullStore::CopyRangeTo2(target, begin, transferBytes, channel, blocking); size_t blockedBytes = NullStore::CopyRangeTo2(target, begin, transferBytes, channel, blocking);
transferBytes = begin; transferBytes = begin; m_size -= begin;
m_size -= begin;
return blockedBytes; return blockedBytes;
} }

26
misc.h
View File

@ -360,6 +360,32 @@ template <class T, class F, int instance>
// ************** misc functions *************** // ************** misc functions ***************
/// \brief Create a pointer with an offset
/// \tparam PTR a pointer type
/// \tparam OFF a size type
/// \param pointer a pointer
/// \param offset a offset into the pointer
/// \details PtrAdd can be used to squash Clang and GCC
/// UBsan findings for pointer addition and subtraction.
template <typename PTR, typename OFF>
inline PTR PtrAdd(PTR pointer, OFF offset)
{
return pointer+static_cast<ptrdiff_t>(offset);
}
/// \brief Create a pointer with an offset
/// \tparam PTR a pointer type
/// \tparam OFF a size type
/// \param pointer a pointer
/// \param offset a offset into the pointer
/// \details PtrSub can be used to squash Clang and GCC
/// UBsan findings for pointer addition and subtraction.
template <typename PTR, typename OFF>
inline PTR PtrSub(PTR pointer, OFF offset)
{
return pointer-static_cast<ptrdiff_t>(offset);
}
#if (!__STDC_WANT_SECURE_LIB__ && !defined(_MEMORY_S_DEFINED)) || defined(CRYPTOPP_WANT_SECURE_LIB) #if (!__STDC_WANT_SECURE_LIB__ && !defined(_MEMORY_S_DEFINED)) || defined(CRYPTOPP_WANT_SECURE_LIB)
/// \brief Bounds checking replacement for memcpy() /// \brief Bounds checking replacement for memcpy()

View File

@ -36,21 +36,22 @@ void CFB_ModePolicy::Iterate(byte *output, const byte *input, CipherDir dir, siz
CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation()); CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation());
CRYPTOPP_ASSERT(m_register.size() == BlockSize()); CRYPTOPP_ASSERT(m_register.size() == BlockSize());
CRYPTOPP_ASSERT(m_temp.size() == BlockSize()); CRYPTOPP_ASSERT(m_temp.size() == BlockSize());
CRYPTOPP_ASSERT(iterationCount > 0);
const ptrdiff_t s = BlockSize(); const unsigned int s = BlockSize();
if (dir == ENCRYPTION) if (dir == ENCRYPTION)
{ {
m_cipher->ProcessAndXorBlock(m_register, input, output); m_cipher->ProcessAndXorBlock(m_register, input, output);
if (iterationCount > 1) if (iterationCount > 1)
m_cipher->AdvancedProcessBlocks(output, input+s, output+s, (iterationCount-1)*s, 0); m_cipher->AdvancedProcessBlocks(output, PtrAdd(input,s), PtrAdd(output,s), (iterationCount-1)*s, 0);
memcpy(m_register, output+(iterationCount-1)*s, s); memcpy(m_register, PtrAdd(output,(iterationCount-1)*s), s);
} }
else else
{ {
// make copy first in case of in-place decryption // make copy first in case of in-place decryption
memcpy(m_temp, input+(iterationCount-1)*s, s); memcpy(m_temp, PtrAdd(input,(iterationCount-1)*s), s);
if (iterationCount > 1) if (iterationCount > 1)
m_cipher->AdvancedProcessBlocks(input, input+s, output+s, (iterationCount-1)*s, BlockTransformation::BT_ReverseDirection); m_cipher->AdvancedProcessBlocks(input, PtrAdd(input,s), PtrAdd(output,s), (iterationCount-1)*s, BlockTransformation::BT_ReverseDirection);
m_cipher->ProcessAndXorBlock(m_register, input, output); m_cipher->ProcessAndXorBlock(m_register, input, output);
memcpy(m_register, m_temp, s); memcpy(m_register, m_temp, s);
} }
@ -62,8 +63,8 @@ void CFB_ModePolicy::TransformRegister()
CRYPTOPP_ASSERT(m_register.size() == BlockSize()); CRYPTOPP_ASSERT(m_register.size() == BlockSize());
CRYPTOPP_ASSERT(m_temp.size() == BlockSize()); CRYPTOPP_ASSERT(m_temp.size() == BlockSize());
m_cipher->ProcessBlock(m_register, m_temp);
const ptrdiff_t updateSize = BlockSize()-m_feedbackSize; const ptrdiff_t updateSize = BlockSize()-m_feedbackSize;
m_cipher->ProcessBlock(m_register, m_temp);
memmove_s(m_register, m_register.size(), m_register+m_feedbackSize, updateSize); 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); memcpy_s(m_register+updateSize, m_register.size()-updateSize, m_temp, m_feedbackSize);
} }
@ -94,19 +95,20 @@ byte* CFB_ModePolicy::GetRegisterBegin()
{ {
CRYPTOPP_ASSERT(!m_register.empty()); CRYPTOPP_ASSERT(!m_register.empty());
CRYPTOPP_ASSERT(BlockSize() >= m_feedbackSize); CRYPTOPP_ASSERT(BlockSize() >= m_feedbackSize);
return m_register + static_cast<ptrdiff_t>(BlockSize() - m_feedbackSize); return PtrAdd(m_register.begin(), BlockSize() - m_feedbackSize);
} }
void OFB_ModePolicy::WriteKeystream(byte *keystreamBuffer, size_t iterationCount) void OFB_ModePolicy::WriteKeystream(byte *keystreamBuffer, size_t iterationCount)
{ {
CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation()); CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation());
CRYPTOPP_ASSERT(m_register.size() == BlockSize()); CRYPTOPP_ASSERT(m_register.size() == BlockSize());
CRYPTOPP_ASSERT(iterationCount > 0);
const ptrdiff_t s = BlockSize(); const unsigned int s = BlockSize();
m_cipher->ProcessBlock(m_register, keystreamBuffer); m_cipher->ProcessBlock(m_register, keystreamBuffer);
if (iterationCount > 1) if (iterationCount > 1)
m_cipher->AdvancedProcessBlocks(keystreamBuffer, NULLPTR, keystreamBuffer+s, s*(iterationCount-1), 0); m_cipher->AdvancedProcessBlocks(keystreamBuffer, NULLPTR, PtrAdd(keystreamBuffer, s), s*(iterationCount-1), 0);
memcpy(m_register, keystreamBuffer+s*(iterationCount-1), s); memcpy(m_register, PtrAdd(keystreamBuffer, (iterationCount-1)*s), s);
} }
void OFB_ModePolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length) void OFB_ModePolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length)
@ -140,8 +142,8 @@ void CTR_ModePolicy::OperateKeystream(KeystreamOperation /*operation*/, byte *ou
CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation()); CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation());
CRYPTOPP_ASSERT(m_counterArray.size() == BlockSize()); CRYPTOPP_ASSERT(m_counterArray.size() == BlockSize());
const ptrdiff_t s = BlockSize(); const unsigned int s = BlockSize();
const ptrdiff_t inputIncrement = input ? s : 0; const unsigned int inputIncrement = input ? s : 0;
while (iterationCount) while (iterationCount)
{ {
@ -151,8 +153,8 @@ void CTR_ModePolicy::OperateKeystream(KeystreamOperation /*operation*/, byte *ou
if ((m_counterArray[s-1] = lsb + (byte)blocks) == 0) if ((m_counterArray[s-1] = lsb + (byte)blocks) == 0)
IncrementCounterBy256(); IncrementCounterBy256();
output += blocks*s; output = PtrAdd(output, blocks*s);
input += blocks*inputIncrement; input = PtrAdd(input, blocks*inputIncrement);
iterationCount -= blocks; iterationCount -= blocks;
} }
} }
@ -197,18 +199,18 @@ void CBC_Encryption::ProcessData(byte *outString, const byte *inString, size_t l
CRYPTOPP_ASSERT(m_register.size() == BlockSize()); CRYPTOPP_ASSERT(m_register.size() == BlockSize());
if (!length) return; if (!length) return;
const ptrdiff_t blockSize = BlockSize(); const unsigned int blockSize = BlockSize();
m_cipher->AdvancedProcessBlocks(inString, m_register, outString, blockSize, BlockTransformation::BT_XorInput); m_cipher->AdvancedProcessBlocks(inString, m_register, outString, blockSize, BlockTransformation::BT_XorInput);
if (length > blockSize) if (length > blockSize)
m_cipher->AdvancedProcessBlocks(inString+blockSize, outString, outString+blockSize, length-blockSize, BlockTransformation::BT_XorInput); m_cipher->AdvancedProcessBlocks(PtrAdd(inString,blockSize), outString, PtrAdd(outString,blockSize), length-blockSize, BlockTransformation::BT_XorInput);
memcpy(m_register, outString + length - blockSize, blockSize); memcpy(m_register, PtrAdd(outString, length - blockSize), blockSize);
} }
size_t CBC_CTS_Encryption::ProcessLastBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength) size_t CBC_CTS_Encryption::ProcessLastBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength)
{ {
CRYPTOPP_UNUSED(outLength); CRYPTOPP_UNUSED(outLength);
const size_t used = inLength; const size_t used = inLength;
const ptrdiff_t blockSize = static_cast<ptrdiff_t>(BlockSize()); const unsigned int blockSize = BlockSize();
if (inLength <= BlockSize()) if (inLength <= BlockSize())
{ {
@ -222,16 +224,17 @@ size_t CBC_CTS_Encryption::ProcessLastBlock(byte *outString, size_t outLength, c
else else
{ {
// steal from next to last block // steal from next to last block
xorbuf(m_register, inString, BlockSize()); xorbuf(m_register, inString, blockSize);
m_cipher->ProcessBlock(m_register); m_cipher->ProcessBlock(m_register);
inString += blockSize; inLength -= blockSize; inString = PtrAdd(inString, blockSize);
memcpy(outString+blockSize, m_register, inLength); inLength -= blockSize;
memcpy(PtrAdd(outString, blockSize), m_register, inLength);
} }
// output last full ciphertext block // output last full ciphertext block
xorbuf(m_register, inString, inLength); xorbuf(m_register, inString, inLength);
m_cipher->ProcessBlock(m_register); m_cipher->ProcessBlock(m_register);
memcpy(outString, m_register, BlockSize()); memcpy(outString, m_register, blockSize);
return used; return used;
} }
@ -248,10 +251,10 @@ void CBC_Decryption::ProcessData(byte *outString, const byte *inString, size_t l
if (!length) {return;} if (!length) {return;}
// save copy now in case of in-place decryption // save copy now in case of in-place decryption
const ptrdiff_t blockSize = BlockSize(); const unsigned int blockSize = BlockSize();
memcpy(m_temp, inString+length-blockSize, blockSize); memcpy(m_temp, PtrAdd(inString,length-blockSize), blockSize);
if (length > blockSize) if (length > blockSize)
m_cipher->AdvancedProcessBlocks(inString+blockSize, inString, outString+blockSize, length-blockSize, BlockTransformation::BT_ReverseDirection|BlockTransformation::BT_AllowParallel); m_cipher->AdvancedProcessBlocks(PtrAdd(inString,blockSize), inString, PtrAdd(outString,blockSize), length-blockSize, BlockTransformation::BT_ReverseDirection|BlockTransformation::BT_AllowParallel);
m_cipher->ProcessAndXorBlock(inString, m_register, outString); m_cipher->ProcessAndXorBlock(inString, m_register, outString);
m_register.swap(m_temp); m_register.swap(m_temp);
} }
@ -262,7 +265,7 @@ size_t CBC_CTS_Decryption::ProcessLastBlock(byte *outString, size_t outLength, c
const byte *pn1, *pn2; const byte *pn1, *pn2;
const size_t used = inLength; const size_t used = inLength;
const bool stealIV = inLength <= BlockSize(); const bool stealIV = inLength <= BlockSize();
const ptrdiff_t blockSize = static_cast<ptrdiff_t>(BlockSize()); const unsigned int blockSize = BlockSize();
if (stealIV) if (stealIV)
{ {
@ -271,7 +274,7 @@ size_t CBC_CTS_Decryption::ProcessLastBlock(byte *outString, size_t outLength, c
} }
else else
{ {
pn1 = inString + blockSize; pn1 = PtrAdd(inString, blockSize);
pn2 = inString; pn2 = inString;
inLength -= blockSize; inLength -= blockSize;
} }
@ -287,7 +290,7 @@ size_t CBC_CTS_Decryption::ProcessLastBlock(byte *outString, size_t outLength, c
} }
else else
{ {
memcpy(outString+blockSize, m_temp, inLength); memcpy(PtrAdd(outString, blockSize), m_temp, inLength);
// decrypt next to last plaintext block // decrypt next to last plaintext block
memcpy(m_temp, pn1, inLength); memcpy(m_temp, pn1, inLength);
m_cipher->ProcessBlock(m_temp); m_cipher->ProcessBlock(m_temp);

View File

@ -82,11 +82,12 @@ bool CPU_ProbeARMv7()
else else
{ {
// ARMv7 added movt and movw // ARMv7 added movt and movw
int a; //int a;
asm volatile("movw %0,%1 \n" //asm volatile("movw %0,%1 \n"
"movt %0,%1 \n" // "movt %0,%1 \n"
: "=r"(a) : "i"(0x1234)); // : "=r"(a) : "i"(0x1234));
result = (a == 0x12341234); //result = (a == 0x12341234);
return true;
} }
sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR); sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR);

View File

@ -35,26 +35,23 @@ void AdditiveCipherTemplate<S>::GenerateBlock(byte *outString, size_t length)
{ {
if (m_leftOver > 0) if (m_leftOver > 0)
{ {
size_t len = STDMIN(m_leftOver, length); const size_t len = STDMIN(m_leftOver, length);
memcpy(outString, KeystreamBufferEnd()-m_leftOver, len); memcpy(outString, PtrSub(KeystreamBufferEnd(), m_leftOver), len);
length -= len;
m_leftOver -= len;
outString += len;
if (!length) length -= len; m_leftOver -= len;
return; outString = PtrAdd(outString, len);
if (!length) {return;}
} }
CRYPTOPP_ASSERT(m_leftOver == 0);
PolicyInterface &policy = this->AccessPolicy(); PolicyInterface &policy = this->AccessPolicy();
unsigned int bytesPerIteration = policy.GetBytesPerIteration(); unsigned int bytesPerIteration = policy.GetBytesPerIteration();
if (length >= bytesPerIteration) if (length >= bytesPerIteration)
{ {
size_t iterations = length / bytesPerIteration; const size_t iterations = length / bytesPerIteration;
policy.WriteKeystream(outString, iterations); policy.WriteKeystream(outString, iterations);
outString += iterations * bytesPerIteration;
length -= iterations * bytesPerIteration; length -= iterations * bytesPerIteration;
outString = PtrAdd(outString, iterations * bytesPerIteration);
} }
if (length > 0) if (length > 0)
@ -73,35 +70,31 @@ void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inStrin
{ {
if (m_leftOver > 0) if (m_leftOver > 0)
{ {
size_t len = STDMIN(m_leftOver, length); const size_t len = STDMIN(m_leftOver, length);
xorbuf(outString, inString, KeystreamBufferEnd()-m_leftOver, len); xorbuf(outString, inString, KeystreamBufferEnd()-m_leftOver, len);
length -= len;
m_leftOver -= len;
inString += len;
outString += len;
if (!length) length -= len; m_leftOver -= len;
return; inString = PtrAdd(inString, len);
outString = PtrAdd(outString, len);
if (!length) {return;}
} }
CRYPTOPP_ASSERT(m_leftOver == 0);
PolicyInterface &policy = this->AccessPolicy(); PolicyInterface &policy = this->AccessPolicy();
unsigned int bytesPerIteration = policy.GetBytesPerIteration(); unsigned int bytesPerIteration = policy.GetBytesPerIteration();
if (policy.CanOperateKeystream() && length >= bytesPerIteration) if (policy.CanOperateKeystream() && length >= bytesPerIteration)
{ {
size_t iterations = length / bytesPerIteration; const size_t iterations = length / bytesPerIteration;
unsigned int alignment = policy.GetAlignment(); unsigned int alignment = policy.GetAlignment();
KeystreamOperation operation = KeystreamOperation((IsAlignedOn(inString, alignment) * 2) | (int)IsAlignedOn(outString, alignment)); KeystreamOperation operation = KeystreamOperation((IsAlignedOn(inString, alignment) * 2) | (int)IsAlignedOn(outString, alignment));
policy.OperateKeystream(operation, outString, inString, iterations); policy.OperateKeystream(operation, outString, inString, iterations);
inString += iterations * bytesPerIteration; inString = PtrAdd(inString, iterations * bytesPerIteration);
outString += iterations * bytesPerIteration; outString = PtrAdd(outString, iterations * bytesPerIteration);
length -= iterations * bytesPerIteration; length -= iterations * bytesPerIteration;
if (!length) if (!length) {return;}
return;
} }
size_t bufferByteSize = m_buffer.size(); size_t bufferByteSize = m_buffer.size();
@ -111,9 +104,10 @@ void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inStrin
{ {
policy.WriteKeystream(m_buffer, bufferIterations); policy.WriteKeystream(m_buffer, bufferIterations);
xorbuf(outString, inString, KeystreamBufferBegin(), bufferByteSize); xorbuf(outString, inString, KeystreamBufferBegin(), bufferByteSize);
length -= bufferByteSize; length -= bufferByteSize;
inString += bufferByteSize; inString = PtrAdd(inString, bufferByteSize);
outString += bufferByteSize; outString = PtrAdd(outString, bufferByteSize);
} }
if (length > 0) if (length > 0)
@ -181,6 +175,7 @@ void CFB_CipherTemplate<BASE>::Resynchronize(const byte *iv, int length)
template <class BASE> template <class BASE>
void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString, size_t length) void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString, size_t length)
{ {
CRYPTOPP_ASSERT(outString); CRYPTOPP_ASSERT(inString);
CRYPTOPP_ASSERT(length % this->MandatoryBlockSize() == 0); CRYPTOPP_ASSERT(length % this->MandatoryBlockSize() == 0);
PolicyInterface &policy = this->AccessPolicy(); PolicyInterface &policy = this->AccessPolicy();
@ -190,30 +185,28 @@ void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString
if (m_leftOver) if (m_leftOver)
{ {
size_t len = STDMIN(m_leftOver, length); const size_t len = STDMIN(m_leftOver, length);
CombineMessageAndShiftRegister(outString, reg + bytesPerIteration - m_leftOver, inString, len); CombineMessageAndShiftRegister(outString, PtrAdd(reg, bytesPerIteration - m_leftOver), inString, len);
m_leftOver -= len;
length -= len; m_leftOver -= len; length -= len;
inString += len; inString = PtrAdd(inString, len);
outString += len; outString = PtrAdd(outString, len);
if (!length) {return;}
} }
if (!length)
return;
CRYPTOPP_ASSERT(m_leftOver == 0);
if (policy.CanIterate() && length >= bytesPerIteration && IsAlignedOn(outString, alignment)) if (policy.CanIterate() && length >= bytesPerIteration && IsAlignedOn(outString, alignment))
{ {
const CipherDir cipherDir = GetCipherDir(*this);
if (IsAlignedOn(inString, alignment)) if (IsAlignedOn(inString, alignment))
policy.Iterate(outString, inString, GetCipherDir(*this), length / bytesPerIteration); policy.Iterate(outString, inString, cipherDir, length / bytesPerIteration);
else else
{ {
memcpy(outString, inString, length); memcpy(outString, inString, length);
policy.Iterate(outString, outString, GetCipherDir(*this), length / bytesPerIteration); policy.Iterate(outString, outString, cipherDir, length / bytesPerIteration);
} }
inString += length - length % bytesPerIteration; inString = PtrAdd(inString, length - length % bytesPerIteration);
outString += length - length % bytesPerIteration; outString = PtrAdd(outString, length - length % bytesPerIteration);
length %= bytesPerIteration; length %= bytesPerIteration;
} }
@ -222,8 +215,8 @@ void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString
policy.TransformRegister(); policy.TransformRegister();
CombineMessageAndShiftRegister(outString, reg, inString, bytesPerIteration); CombineMessageAndShiftRegister(outString, reg, inString, bytesPerIteration);
length -= bytesPerIteration; length -= bytesPerIteration;
inString += bytesPerIteration; inString = PtrAdd(inString, bytesPerIteration);
outString += bytesPerIteration; outString = PtrAdd(outString, bytesPerIteration);
} }
if (length > 0) if (length > 0)
@ -244,7 +237,7 @@ void CFB_EncryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output,
template <class BASE> template <class BASE>
void CFB_DecryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length) void CFB_DecryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length)
{ {
for (unsigned int i=0; i<length; i++) for (size_t i=0; i<length; i++)
{ {
byte b = message[i]; byte b = message[i];
output[i] = reg[i] ^ b; output[i] = reg[i] ^ b;