summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Ramacher <sebastian+dev@ramacher.at>2013-10-28 02:52:39 +0100
committerSebastian Ramacher <sebastian+dev@ramacher.at>2013-10-28 17:57:36 +0100
commit8b68505248a54477f7cb81b30e33520d9c5d1083 (patch)
treed7c3f7b766ffa99f8edf4105d3ae8f907edde473
parent8cde8b9893819e9586bde2ce9be84f24689ff0d9 (diff)
downloadpycrypto-8b68505248a54477f7cb81b30e33520d9c5d1083.tar.gz
Make sure that ek and dk are aligned at 16 byte boundaries
ek and dk are used as operands in instructions that require 16 byte alignment. Thanks to Greg Price for finding this issue. Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
-rw-r--r--configure.ac1
-rw-r--r--setup.py4
-rw-r--r--src/AESNI.c48
3 files changed, 49 insertions, 4 deletions
diff --git a/configure.ac b/configure.ac
index b62db5e..5f22d00 100644
--- a/configure.ac
+++ b/configure.ac
@@ -103,5 +103,6 @@ AC_TYPE_UINT8_T
# Checks for library functions.
AC_FUNC_MALLOC
AC_CHECK_FUNCS([memmove memset])
+AC_CHECK_FUNCS([posix_memalign aligned_alloc _aligned_malloc])
AC_OUTPUT
diff --git a/setup.py b/setup.py
index 998122e..5269e9d 100644
--- a/setup.py
+++ b/setup.py
@@ -166,6 +166,10 @@ class PCTBuildExt (build_ext):
if not ac.get("HAVE_WMMINTRIN_H"):
# AES-NI instrincs not available
self.__remove_extensions(["Crypto.Cipher._AESNI"])
+ elif not (ac.get("HAVE_POSIX_MEMALIGN") or ac.get("HAVE_ALIGNED_ALLOC")
+ or ac.get("HAVE__ALIGNED_MALLOC")):
+ # no function to allocate aligned memory is available
+ self.__remove_extensions(["Crypto.Cipher._AESNI"])
elif ac.get("HAVE_MAES"):
# -maes has to be passed to the compiler to use the AES-NI instrincs
self.__add_extension_compile_option(["Crypto.Cipher._AESNI"],
diff --git a/src/AESNI.c b/src/AESNI.c
index 81c6e9c..bd03cc8 100644
--- a/src/AESNI.c
+++ b/src/AESNI.c
@@ -22,8 +22,12 @@
* ===================================================================
*/
-#include "Python.h"
+#include "pycrypto_common.h"
#include <wmmintrin.h>
+#include <stdlib.h>
+#if defined(HAVE__ALIGNED_MALLOC)
+#include <malloc.h>
+#endif
#define MODULE_NAME _AESNI
#define BLOCK_SIZE 16
@@ -36,9 +40,9 @@
typedef unsigned char u8;
typedef struct {
- __m128i ek[MAXNR + 1];
- __m128i dk[MAXNR + 1];
- int rounds;
+ __m128i* ek;
+ __m128i* dk;
+ int rounds;
} block_state;
/* Helper functions to expand keys */
@@ -161,6 +165,36 @@ static void block_init(block_state* self, unsigned char* key, int keylen)
"AES key must be either 16, 24, or 32 bytes long");
return;
}
+
+ /* ensure that self->ek and self->dk are aligned to 16 byte boundaries */
+ void* tek = NULL;
+ void* tdk = NULL;
+#if defined(HAVE_POSIX_MEMALIGN)
+ /* posix_memalign is defined by POSIX */
+ posix_memalign(&tek, 16, (nr + 1) * sizeof(__m128i));
+ posix_memalign(&tdk, 16, (nr + 1) * sizeof(__m128i));
+#elif defined(HAVE_ALIGNED_ALLOC)
+ /* aligned_alloc is defined by C11 */
+ tek = aligned_alloc(16, (nr + 1) * sizeof(__m128i));
+ tdk = aligned_alloc(16, (nr + 1) * sizeof(__m128i));
+#elif defined(HAVE__ALIGNED_MALLOC)
+ /* _aligned_malloc is available on Windows */
+ tek = _aligned_malloc(16, (nr + 1) * sizeof(__m128i));
+ tdk = _aligned_malloc(16, (nr + 1) * sizeof(__m128i));
+#else
+#error "No function to allocate aligned memory is available."
+#endif
+ if (!tek || !tdk) {
+ free(tek);
+ free(tdk);
+ PyErr_SetString(PyExc_MemoryError,
+ "failed to allocate memory for keys");
+ return;
+ }
+
+ self->ek = tek;
+ self->dk = tdk;
+
self->rounds = nr;
aes_key_setup_enc(self->ek, key, keylen);
aes_key_setup_dec(self->dk, self->ek, nr);
@@ -168,6 +202,12 @@ static void block_init(block_state* self, unsigned char* key, int keylen)
static void block_finalize(block_state* self)
{
+ /* overwrite contents of ek and dk */
+ memset(self->ek, 0, (self->rounds + 1) * sizeof(__m128i));
+ memset(self->dk, 0, (self->rounds + 1) * sizeof(__m128i));
+
+ free(self->ek);
+ free(self->dk);
}
static void block_encrypt(block_state* self, const u8* in, u8* out)