Hi Everyone,
We've been working on AltiVec and Power8. We mostly have AES done except
for some memory errors. AltiVec and Power8 solve the unaligned buffer
problem by masking the low-order address bits so everything is aligned.
They turn an address like 0xAAAAAAA8 into 0xAAAAAAA0, so we've got some
wild writes.
The processor has revealed some issues in our code. One of the controls I
want to put in place is debug assert the buffer alignments. I think the
first defense is to make the code debug itself, so this will relieve us of
doing it:
void CBC_Encryption::ProcessData(byte *outString, const byte *inString,
size_t length)
{
// If this fires you should align your buffers. There's a non-trival
penalty for some processors
CRYPTOPP_ASSERT(IsAlignedOn(inString,
m_cipher->OptimalDataAlignment()));
CRYPTOPP_ASSERT(IsAlignedOn(outString,
m_cipher->OptimalDataAlignment()));
CRYPTOPP_ASSERT(length%BlockSize()==0);
...
}
Because users expect things to "just work", we need to fixup the buffers on
the fly:
bool align = !IsAlignedOn(m_register, alignment) ||
!IsAlignedOn(inString, alignment) || !IsAlignedOn(outString, alignment);
if (align)
{
AlignedSecByteBlock i(length), o(length), x;
std::memcpy(i, inString, blockSize);
std::memcpy(o, outString, blockSize);
if (!m_register.empty()) {x = m_register;}
m_cipher->AdvancedProcessBlocks(i, x, o, blockSize,
BlockTransformation::BT_XorInput);
if (length > blockSize)
m_cipher->AdvancedProcessBlocks(i+blockSize, o, o+blockSize,
length-blockSize, BlockTransformation::BT_XorInput);
std::memcpy(m_register, o + length - blockSize, blockSize);
std::memcpy(outString, o, length);
}
In the future you may see some asserts firing in debug builds. For the
Crypto++ project, this is our big offender:
https://github.com/weidai11/cryptopp/blob/master/validat1.cpp#L2078. All
the byte buffers are misaligned and suffer the masking. We will be
switching to an AlignedSecByteBlock or CRYPTOPP_ALIGN_DATA(16).
If the assert fires for your project, then you should align your buffers.
If you find std:;string's are causing your problems, then you can use the
library's aligned allocator:
typedef std::basic_string<char, std::char_traits<char>,
AllocatorWithCleanup<char, true> > aligned_string;
Jeff
--
--
You received this message because you are subscribed to the "Crypto++ Users"
Google Group.
To unsubscribe, send an email to [email protected].
More information about Crypto++ and this group is available at
http://www.cryptopp.com.
---
You received this message because you are subscribed to the Google Groups
"Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.