diff options
author | Yawning Angel <yawning@schwanenlied.me> | 2015-03-22 22:31:08 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2015-03-23 09:20:02 -0400 |
commit | 732f522a42702494c4029da568a2603bb963e402 (patch) | |
tree | bc4821f16b5b8684e0002e62bbc54bb46e2f307d | |
parent | 9063f29160615b379f907009e7158f1fcf1ed84c (diff) | |
download | tor-732f522a42702494c4029da568a2603bb963e402.tar.gz tor-732f522a42702494c4029da568a2603bb963e402.zip |
Fix unaligned access in SipHash-2-4.
The compiler is allowed to assume that a "uint64_t *" is aligned
correctly, and will inline a version of memcpy that acts as such.
Use "uint8_t *", so the compiler does the right thing.
-rw-r--r-- | changes/bug15436 | 4 | ||||
-rw-r--r-- | src/ext/csiphash.c | 16 |
2 files changed, 17 insertions, 3 deletions
diff --git a/changes/bug15436 b/changes/bug15436 new file mode 100644 index 0000000000..4fa44d1e16 --- /dev/null +++ b/changes/bug15436 @@ -0,0 +1,4 @@ + o Minor bugfixes (portability): + - Use the correct datatype in the SipHash-2-4 function to prevent compilers + from assuming any sort of alignment. Fixes bug 15436; bugfix on + 0.2.5.3-alpha. diff --git a/src/ext/csiphash.c b/src/ext/csiphash.c index c247886038..979990f639 100644 --- a/src/ext/csiphash.c +++ b/src/ext/csiphash.c @@ -100,10 +100,18 @@ uint64_t siphash24(const void *src, unsigned long src_sz, const struct sipkey *k uint64_t k0 = key->k0; uint64_t k1 = key->k1; uint64_t b = (uint64_t)src_sz << 56; +#ifdef UNALIGNED_OK const uint64_t *in = (uint64_t*)src; +#else + /* On platforms where alignment matters, if 'in' is a pointer to a + * datatype that must be aligned, the compiler is allowed to + * generate code that assumes that it is aligned as such. + */ + const uint8_t *in = (uint8_t *)src; +#endif - uint64_t t; - uint8_t *pt, *m; + uint64_t t; + uint8_t *pt, *m; uint64_t v0 = k0 ^ 0x736f6d6570736575ULL; uint64_t v1 = k1 ^ 0x646f72616e646f6dULL; @@ -113,12 +121,14 @@ uint64_t siphash24(const void *src, unsigned long src_sz, const struct sipkey *k while (src_sz >= 8) { #ifdef UNALIGNED_OK uint64_t mi = _le64toh(*in); + in += 1; #else uint64_t mi; memcpy(&mi, in, 8); mi = _le64toh(mi); + in += 8; #endif - in += 1; src_sz -= 8; + src_sz -= 8; v3 ^= mi; DOUBLE_ROUND(v0,v1,v2,v3); v0 ^= mi; |