diff --git a/misc.h b/misc.h index e3980441..f846e72a 100644 --- a/misc.h +++ b/misc.h @@ -423,6 +423,19 @@ inline void memmove_s(void *dest, size_t sizeInBytes, const void *src, size_t co # define memmove_s CryptoPP::memmove_s #endif +//! \brief Swaps two variables which are arrays +//! \details C++03 does not provide support for std::swap(__m128i a, __m128i b) +//! because __m128i is an unsigned long long[2]. Most compilers +//! support it out of the box, but Sun Studio C++ compilers 12.2 and 12.3 do not. +//! \sa How to swap two __m128i variables +//! in C++03 given its an opaque type and an array? on Stack Overflow. +template +inline void vec_swap(T& a, T& b) +{ + T t; + t=a, a=b, b=t; +} + #endif // __STDC_WANT_SECURE_LIB__ //! \brief Memory block initializer and eraser that attempts to survive optimizations diff --git a/rijndael.cpp b/rijndael.cpp index 9139c227..05ba5d57 100644 --- a/rijndael.cpp +++ b/rijndael.cpp @@ -275,11 +275,9 @@ void Rijndael::Base::UncheckedSetKey(const byte *userKey, unsigned int keylen, c unsigned int i, j; #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x5120) - // __m128i is an unsigned long long[2], and support for swapping it was not formally added until C++11. + // __m128i is an unsigned long long[2], and support for swapping it was not added until C++11. // SunCC 12.1 - 12.3 fail to consume the swap; while SunCC 12.4 consumes it without -std=c++11. - __m128i t = *(__m128i *)(rk); - *(__m128i *)(rk) = *(__m128i *)(rk+4*m_rounds); - *(__m128i *)(rk+4*m_rounds) = t; + vec_swap(*(__m128i *)(rk), *(__m128i *)(rk+4*m_rounds)); #else std::swap(*(__m128i *)(void *)(rk), *(__m128i *)(void *)(rk+4*m_rounds)); #endif