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 cryptopp-users-unsubscr...@googlegroups.com.
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 cryptopp-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to