|
|
081b2d |
From 5909e20899334816f36cac0e47105e56df52ad3c Mon Sep 17 00:00:00 2001
|
|
|
081b2d |
From: William Brown <firstyear@redhat.com>
|
|
|
081b2d |
Date: Mon, 30 Oct 2017 12:01:34 +1000
|
|
|
081b2d |
Subject: [PATCH] Ticket 49424 - Resolve csiphash alignment issues
|
|
|
081b2d |
|
|
|
081b2d |
Bug Description: On some platforms, uint64_t is not the same size
|
|
|
081b2d |
as a void * - as well, if the input is not aligned correctly, then
|
|
|
081b2d |
a number of nasty crashes can result
|
|
|
081b2d |
|
|
|
081b2d |
Fix Description: Instead of relying on alignment to be correct,
|
|
|
081b2d |
we should memcpy the data to inputs instead.
|
|
|
081b2d |
|
|
|
081b2d |
https://pagure.io/389-ds-base/issue/49424
|
|
|
081b2d |
|
|
|
081b2d |
Author: wibrown
|
|
|
081b2d |
|
|
|
081b2d |
Review by: lslebodn, cgrzemba, vashirov, mreynolds (Thanks!)
|
|
|
081b2d |
|
|
|
081b2d |
(cherry picked from commit 751446440f5269a246e6e652a64e63aa5933734a)
|
|
|
081b2d |
---
|
|
|
081b2d |
src/libsds/external/csiphash/csiphash.c | 52 +++++++++++++++++++--------------
|
|
|
081b2d |
src/libsds/test/test_sds_csiphash.c | 43 +++++++++++++++++++++------
|
|
|
081b2d |
2 files changed, 64 insertions(+), 31 deletions(-)
|
|
|
081b2d |
|
|
|
081b2d |
diff --git a/src/libsds/external/csiphash/csiphash.c b/src/libsds/external/csiphash/csiphash.c
|
|
|
081b2d |
index 0089c82f7..2351db6cf 100644
|
|
|
081b2d |
--- a/src/libsds/external/csiphash/csiphash.c
|
|
|
081b2d |
+++ b/src/libsds/external/csiphash/csiphash.c
|
|
|
081b2d |
@@ -32,6 +32,9 @@
|
|
|
081b2d |
#include <inttypes.h>
|
|
|
081b2d |
#include <stddef.h> /* for size_t */
|
|
|
081b2d |
|
|
|
081b2d |
+#include <stdlib.h> /* calloc,free */
|
|
|
081b2d |
+#include <string.h> /* memcpy */
|
|
|
081b2d |
+
|
|
|
081b2d |
#include <config.h>
|
|
|
081b2d |
|
|
|
081b2d |
#if defined(HAVE_SYS_ENDIAN_H)
|
|
|
081b2d |
@@ -75,11 +78,24 @@
|
|
|
081b2d |
uint64_t
|
|
|
081b2d |
sds_siphash13(const void *src, size_t src_sz, const char key[16])
|
|
|
081b2d |
{
|
|
|
081b2d |
- const uint64_t *_key = (uint64_t *)key;
|
|
|
081b2d |
+ uint64_t _key[2] = {0};
|
|
|
081b2d |
+ memcpy(_key, key, 16);
|
|
|
081b2d |
uint64_t k0 = _le64toh(_key[0]);
|
|
|
081b2d |
uint64_t k1 = _le64toh(_key[1]);
|
|
|
081b2d |
uint64_t b = (uint64_t)src_sz << 56;
|
|
|
081b2d |
- const uint64_t *in = (uint64_t *)src;
|
|
|
081b2d |
+
|
|
|
081b2d |
+ size_t input_sz = (src_sz / sizeof(uint64_t)) + 1;
|
|
|
081b2d |
+
|
|
|
081b2d |
+ /* Account for non-uint64_t alligned input */
|
|
|
081b2d |
+ /* Could make this stack allocation */
|
|
|
081b2d |
+ uint64_t *in = calloc(1, input_sz * sizeof(uint64_t));
|
|
|
081b2d |
+ /*
|
|
|
081b2d |
+ * Because all crypto code sucks, they modify *in
|
|
|
081b2d |
+ * during operation, so we stash a copy of the ptr here.
|
|
|
081b2d |
+ * alternately, we could use stack allocated array, but gcc
|
|
|
081b2d |
+ * will complain about the vla being unbounded.
|
|
|
081b2d |
+ */
|
|
|
081b2d |
+ uint64_t *in_ptr = memcpy(in, src, src_sz);
|
|
|
081b2d |
|
|
|
081b2d |
uint64_t v0 = k0 ^ 0x736f6d6570736575ULL;
|
|
|
081b2d |
uint64_t v1 = k1 ^ 0x646f72616e646f6dULL;
|
|
|
081b2d |
@@ -96,27 +112,15 @@ sds_siphash13(const void *src, size_t src_sz, const char key[16])
|
|
|
081b2d |
v0 ^= mi;
|
|
|
081b2d |
}
|
|
|
081b2d |
|
|
|
081b2d |
+ /*
|
|
|
081b2d |
+ * Because we allocate in as size + 1, we can over-read 0
|
|
|
081b2d |
+ * for this buffer to be padded correctly. in here is a pointer to the
|
|
|
081b2d |
+ * excess data because the while loop above increments the in pointer
|
|
|
081b2d |
+ * to point to the excess once src_sz drops < 8.
|
|
|
081b2d |
+ */
|
|
|
081b2d |
uint64_t t = 0;
|
|
|
081b2d |
- uint8_t *pt = (uint8_t *)&t;
|
|
|
081b2d |
- uint8_t *m = (uint8_t *)in;
|
|
|
081b2d |
-
|
|
|
081b2d |
- switch (src_sz) {
|
|
|
081b2d |
- case 7:
|
|
|
081b2d |
- pt[6] = m[6]; /* FALLTHRU */
|
|
|
081b2d |
- case 6:
|
|
|
081b2d |
- pt[5] = m[5]; /* FALLTHRU */
|
|
|
081b2d |
- case 5:
|
|
|
081b2d |
- pt[4] = m[4]; /* FALLTHRU */
|
|
|
081b2d |
- case 4:
|
|
|
081b2d |
- *((uint32_t *)&pt[0]) = *((uint32_t *)&m[0]);
|
|
|
081b2d |
- break;
|
|
|
081b2d |
- case 3:
|
|
|
081b2d |
- pt[2] = m[2]; /* FALLTHRU */
|
|
|
081b2d |
- case 2:
|
|
|
081b2d |
- pt[1] = m[1]; /* FALLTHRU */
|
|
|
081b2d |
- case 1:
|
|
|
081b2d |
- pt[0] = m[0]; /* FALLTHRU */
|
|
|
081b2d |
- }
|
|
|
081b2d |
+ memcpy(&t, in, sizeof(uint64_t));
|
|
|
081b2d |
+
|
|
|
081b2d |
b |= _le64toh(t);
|
|
|
081b2d |
|
|
|
081b2d |
v3 ^= b;
|
|
|
081b2d |
@@ -126,5 +130,9 @@ sds_siphash13(const void *src, size_t src_sz, const char key[16])
|
|
|
081b2d |
v2 ^= 0xff;
|
|
|
081b2d |
// dround
|
|
|
081b2d |
dROUND(v0, v1, v2, v3);
|
|
|
081b2d |
+
|
|
|
081b2d |
+ free(in_ptr);
|
|
|
081b2d |
+
|
|
|
081b2d |
return (v0 ^ v1) ^ (v2 ^ v3);
|
|
|
081b2d |
}
|
|
|
081b2d |
+
|
|
|
081b2d |
diff --git a/src/libsds/test/test_sds_csiphash.c b/src/libsds/test/test_sds_csiphash.c
|
|
|
081b2d |
index cdb6b7f46..cc9a6b2b5 100644
|
|
|
081b2d |
--- a/src/libsds/test/test_sds_csiphash.c
|
|
|
081b2d |
+++ b/src/libsds/test/test_sds_csiphash.c
|
|
|
081b2d |
@@ -25,23 +25,48 @@
|
|
|
081b2d |
static void
|
|
|
081b2d |
test_siphash(void **state __attribute__((unused)))
|
|
|
081b2d |
{
|
|
|
081b2d |
-
|
|
|
081b2d |
- //
|
|
|
081b2d |
uint64_t value = 0;
|
|
|
081b2d |
uint64_t hashout = 0;
|
|
|
081b2d |
char key[16] = {0};
|
|
|
081b2d |
|
|
|
081b2d |
- uint64_t test_a = 15794382300316794652U;
|
|
|
081b2d |
- uint64_t test_b = 13042610424265326907U;
|
|
|
081b2d |
+ uint64_t test_simple = 15794382300316794652U;
|
|
|
081b2d |
|
|
|
081b2d |
- // Initial simple test
|
|
|
081b2d |
+ /* Initial simple test */
|
|
|
081b2d |
value = htole64(5);
|
|
|
081b2d |
hashout = sds_siphash13(&value, sizeof(uint64_t), key);
|
|
|
081b2d |
- assert_true(hashout == test_a);
|
|
|
081b2d |
+ assert_int_equal(hashout, test_simple);
|
|
|
081b2d |
+
|
|
|
081b2d |
+ /* Test a range of input sizes to check endianness behaviour */
|
|
|
081b2d |
+
|
|
|
081b2d |
+ hashout = sds_siphash13("a", 1, key);
|
|
|
081b2d |
+ assert_int_equal(hashout, 0x407448d2b89b1813U);
|
|
|
081b2d |
+
|
|
|
081b2d |
+ hashout = sds_siphash13("aa", 2, key);
|
|
|
081b2d |
+ assert_int_equal(hashout, 0x7910e0436ed8d1deU);
|
|
|
081b2d |
+
|
|
|
081b2d |
+ hashout = sds_siphash13("aaa", 3, key);
|
|
|
081b2d |
+ assert_int_equal(hashout, 0xf752893a6c769652U);
|
|
|
081b2d |
+
|
|
|
081b2d |
+ hashout = sds_siphash13("aaaa", 4, key);
|
|
|
081b2d |
+ assert_int_equal(hashout, 0x8b02350718d87164U);
|
|
|
081b2d |
+
|
|
|
081b2d |
+ hashout = sds_siphash13("aaaaa", 5, key);
|
|
|
081b2d |
+ assert_int_equal(hashout, 0x92a991474c7eef2U);
|
|
|
081b2d |
+
|
|
|
081b2d |
+ hashout = sds_siphash13("aaaaaa", 6, key);
|
|
|
081b2d |
+ assert_int_equal(hashout, 0xf0ab815a640277ccU);
|
|
|
081b2d |
+
|
|
|
081b2d |
+ hashout = sds_siphash13("aaaaaaa", 7, key);
|
|
|
081b2d |
+ assert_int_equal(hashout, 0x33f3c6d7dbc82c0dU);
|
|
|
081b2d |
+
|
|
|
081b2d |
+ hashout = sds_siphash13("aaaaaaaa", 8, key);
|
|
|
081b2d |
+ assert_int_equal(hashout, 0xc501b12e18428c92U);
|
|
|
081b2d |
+
|
|
|
081b2d |
+ hashout = sds_siphash13("aaaaaaaabbbb", 12, key);
|
|
|
081b2d |
+ assert_int_equal(hashout, 0xcddca673069ade64U);
|
|
|
081b2d |
|
|
|
081b2d |
- char *test = "abc";
|
|
|
081b2d |
- hashout = sds_siphash13(test, 4, key);
|
|
|
081b2d |
- assert_true(hashout == test_b);
|
|
|
081b2d |
+ hashout = sds_siphash13("aaaaaaaabbbbbbbb", 16, key);
|
|
|
081b2d |
+ assert_int_equal(hashout, 0xdc54f0bfc0e1deb0U);
|
|
|
081b2d |
}
|
|
|
081b2d |
|
|
|
081b2d |
int
|
|
|
081b2d |
--
|
|
|
081b2d |
2.13.6
|
|
|
081b2d |
|