diff --git a/configure.ac b/configure.ac index 1c58470..f2f7e92 100644 --- a/configure.ac +++ b/configure.ac @@ -118,6 +118,7 @@ AC_TYPE_UINT16_T AC_TYPE_UINT32_T AC_TYPE_UINT64_T AC_TYPE_UINT8_T +AC_TYPE_UINTPTR_T # Checks for library functions. AC_FUNC_FORK diff --git a/src/crypto/crypto.cc b/src/crypto/crypto.cc index 8179b1b..31104b6 100644 --- a/src/crypto/crypto.cc +++ b/src/crypto/crypto.cc @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "byteorder.h" @@ -47,33 +48,34 @@ long int myatoi( const char *str ) } AlignedBuffer::AlignedBuffer( size_t len, const char *data ) - : m_len( len ), m_data( NULL ) + : m_len( len ), m_allocated( NULL ), m_data( NULL ) { - void *ptr = NULL; - #if defined(HAVE_POSIX_MEMALIGN) - if( (0 != posix_memalign( (void **)&ptr, 16, len )) || (ptr == NULL) ) { + if ( ( 0 != posix_memalign( &m_allocated, 16, len ) ) + || ( m_allocated == NULL ) ) { throw std::bad_alloc(); } -#else - // Some platforms will align malloc. Let's try that first. - if( ! (ptr = malloc(len)) ) { - throw std::bad_alloc(); - } - if( (uintptr_t)ptr & 0xF ) { - // The pointer wasn't 16-byte aligned, so try again with valloc - free(ptr); - if( ! (ptr = valloc(len)) ) { - throw std::bad_alloc(); - } - if( (uintptr_t)ptr & 0xF ) { - free(ptr); - throw std::bad_alloc(); - } - } -#endif /* !defined(HAVE_POSIX_MEMALIGN) */ + m_data = (char *) m_allocated; - m_data = (char *) ptr; +#else + /* malloc() a region 15 bytes larger than we need, and find + the aligned offset within. */ + m_allocated = malloc( 15 + len ); + if ( m_allocated == NULL ) { + throw std::bad_alloc(); + } + + uintptr_t iptr = (uintptr_t) m_allocated; + if ( iptr & 0xF ) { + iptr += 16 - ( iptr & 0xF ); + } + assert( !( iptr & 0xF ) ); + assert( iptr >= (uintptr_t) m_allocated ); + assert( iptr <= ( 15 + (uintptr_t) m_allocated ) ); + + m_data = (char *) iptr; + +#endif /* !defined(HAVE_POSIX_MEMALIGN) */ if ( data ) { memcpy( m_data, data, len ); diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h index ddbf12f..eab73be 100644 --- a/src/crypto/crypto.h +++ b/src/crypto/crypto.h @@ -42,13 +42,14 @@ namespace Crypto { class AlignedBuffer { private: size_t m_len; + void *m_allocated; char *m_data; public: AlignedBuffer( size_t len, const char *data = NULL ); ~AlignedBuffer() { - free( m_data ); + free( m_allocated ); } char * data( void ) const { return m_data; }