diff options
-rw-r--r-- | src/ext/csiphash.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/src/ext/csiphash.c b/src/ext/csiphash.c index 5df41d71f..2f37a5f22 100644 --- a/src/ext/csiphash.c +++ b/src/ext/csiphash.c @@ -31,6 +31,7 @@ #include "torint.h" #include "siphash.h" +#include <string.h> #if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ @@ -73,6 +74,11 @@ HALF_ROUND(v0,v1,v2,v3,13,16); \ HALF_ROUND(v2,v1,v0,v3,17,21); +#if (defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined(_M_X64) || defined(__INTEL__)) +# define UNALIGNED_OK 1 +#endif uint64_t siphash24(const void *src, unsigned long src_sz, const struct sipkey *key) { uint64_t k0 = key->k0; @@ -89,7 +95,13 @@ uint64_t siphash24(const void *src, unsigned long src_sz, const struct sipkey *k uint64_t v3 = k1 ^ 0x7465646279746573ULL; while (src_sz >= 8) { +#ifdef UNALIGNED_OK uint64_t mi = _le64toh(*in); +#else + uint64_t mi; + memcpy(&mi, in, 8); + mi = _le64toh(mi); +#endif in += 1; src_sz -= 8; v3 ^= mi; DOUBLE_ROUND(v0,v1,v2,v3); @@ -101,7 +113,11 @@ uint64_t siphash24(const void *src, unsigned long src_sz, const struct sipkey *k case 7: pt[6] = m[6]; case 6: pt[5] = m[5]; case 5: pt[4] = m[4]; +#ifdef UNALIGNED_OK case 4: *((uint32_t*)&pt[0]) = *((uint32_t*)&m[0]); break; +#else + case 4: pt[3] = m[3]; +#endif case 3: pt[2] = m[2]; case 2: pt[1] = m[1]; case 1: pt[0] = m[0]; @@ -115,3 +131,4 @@ uint64_t siphash24(const void *src, unsigned long src_sz, const struct sipkey *k DOUBLE_ROUND(v0,v1,v2,v3); return (v0 ^ v1) ^ (v2 ^ v3); } + |