mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-08 18:42:04 -04:00
Merge branch '1196-misaligned-address-in-siphash-c' into 'master'
Resolve "Misaligned address in siphash.c" Closes #1196 See merge request isc-projects/bind9!2279
This commit is contained in:
commit
0d795ed907
6 changed files with 221 additions and 43 deletions
|
|
@ -279,6 +279,9 @@
|
|||
/* define if OpenSSL supports Ed448 */
|
||||
#undef HAVE_OPENSSL_ED448
|
||||
|
||||
/* define if OpenSSL supports SipHash */
|
||||
#undef HAVE_OPENSSL_SIPHASH
|
||||
|
||||
/* Define to 1 if you have the `processor_bind' function. */
|
||||
#undef HAVE_PROCESSOR_BIND
|
||||
|
||||
|
|
|
|||
30
configure
vendored
30
configure
vendored
|
|
@ -16596,6 +16596,36 @@ $as_echo "no" >&6; }
|
|||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SipHash support" >&5
|
||||
$as_echo_n "checking for SipHash support... " >&6; }
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/opensslv.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10101010L
|
||||
#error OpenSSL >= 1.1.1a required for working SipHash initialization
|
||||
#endif
|
||||
EVP_PKEY *key = EVP_PKEY_new_raw_private_key(
|
||||
EVP_PKEY_SIPHASH, NULL, NULL, 0);
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
|
||||
$as_echo "#define HAVE_OPENSSL_SIPHASH 1" >>confdefs.h
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
|
||||
#
|
||||
# Check for OpenSSL SHA-1 support
|
||||
#
|
||||
|
|
|
|||
13
configure.ac
13
configure.ac
|
|
@ -776,6 +776,19 @@ AC_COMPILE_IFELSE(
|
|||
AC_MSG_RESULT([yes])],
|
||||
[AC_MSG_RESULT([no])])
|
||||
|
||||
AC_MSG_CHECKING([for SipHash support])
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([[#include <openssl/evp.h>
|
||||
#include <openssl/opensslv.h>]],
|
||||
[[#if OPENSSL_VERSION_NUMBER < 0x10101010L
|
||||
#error OpenSSL >= 1.1.1a required for working SipHash initialization
|
||||
#endif
|
||||
EVP_PKEY *key = EVP_PKEY_new_raw_private_key(
|
||||
EVP_PKEY_SIPHASH, NULL, NULL, 0);]])],
|
||||
[AC_DEFINE([HAVE_OPENSSL_SIPHASH], [1], [define if OpenSSL supports SipHash])
|
||||
AC_MSG_RESULT([yes])],
|
||||
[AC_MSG_RESULT([no])])
|
||||
|
||||
#
|
||||
# Check for OpenSSL SHA-1 support
|
||||
#
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ ISC_LANG_BEGINDECLS
|
|||
|
||||
void
|
||||
isc_siphash24(const uint8_t *key,
|
||||
const uint8_t *in, size_t inlen,
|
||||
const uint8_t *in, const size_t inlen,
|
||||
uint8_t *out);
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
|
|
|||
|
|
@ -13,83 +13,165 @@
|
|||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
#include <isc/endian.h>
|
||||
#include <isc/util.h>
|
||||
#include <isc/siphash.h>
|
||||
|
||||
#if HAVE_OPENSSL_SIPHASH
|
||||
#include <openssl/evp.h>
|
||||
|
||||
void
|
||||
isc_siphash24(const uint8_t *k,
|
||||
const uint8_t *in, const size_t inlen,
|
||||
uint8_t *out)
|
||||
{
|
||||
REQUIRE(k != NULL);
|
||||
REQUIRE(out != NULL);
|
||||
size_t outlen = 8;
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
|
||||
EVP_MD_CTX *mctx = EVP_MD_CTX_new();
|
||||
EVP_PKEY *key = EVP_PKEY_new_raw_private_key(EVP_PKEY_SIPHASH, NULL,
|
||||
k, 16);
|
||||
RUNTIME_CHECK(mctx != NULL);
|
||||
RUNTIME_CHECK(key != NULL);
|
||||
|
||||
RUNTIME_CHECK(EVP_DigestSignInit(mctx, &pctx, NULL, NULL, key) == 1);
|
||||
RUNTIME_CHECK(EVP_PKEY_CTX_ctrl(pctx, EVP_PKEY_SIPHASH,
|
||||
EVP_PKEY_OP_SIGNCTX,
|
||||
EVP_PKEY_CTRL_SET_DIGEST_SIZE, outlen,
|
||||
NULL) == 1);
|
||||
RUNTIME_CHECK(EVP_DigestSignUpdate(mctx, in, inlen) == 1);
|
||||
RUNTIME_CHECK(EVP_DigestSignFinal(mctx, out, &outlen) == 1);
|
||||
|
||||
ENSURE(outlen == 8);
|
||||
|
||||
EVP_PKEY_free(key);
|
||||
EVP_MD_CTX_free(mctx);
|
||||
}
|
||||
|
||||
#else /* HAVE_OPENSSL_SIPHASH */
|
||||
|
||||
/*
|
||||
* The fallback implementation is based on SipHash reference C implementation by
|
||||
*
|
||||
* Copyright (c) 2012-2016 Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
|
||||
* Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
|
||||
*
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright
|
||||
* and related and neighboring rights to this software to the public domain
|
||||
* worldwide. This software is distributed without any warranty. You should
|
||||
* have received a copy of the CC0 Public Domain Dedication along with this
|
||||
* software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#define cROUNDS 2
|
||||
#define dROUNDS 4
|
||||
|
||||
/*
|
||||
* The implementation is based on SipHash reference C implementation by
|
||||
*
|
||||
* Copyright (c) 2012-2016 Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
|
||||
* Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
|
||||
*
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright
|
||||
* and related and neighboring rights to this software to the public domain
|
||||
* worldwide. This software is distributed without any warranty. You should
|
||||
* have received a copy of the CC0 Public Domain Dedication along with this
|
||||
* software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#define cROUNDS 2
|
||||
#define dROUNDS 4
|
||||
|
||||
#define ROTATE(x, b) (uint64_t)( ((x) << (b)) | ( (x) >> (64 - (b))) )
|
||||
|
||||
#define HALF_ROUND(a, b, c, d, s, t) \
|
||||
a += b; c += d; \
|
||||
b = ROTATE(b, s) ^ a; \
|
||||
d = ROTATE(d, t) ^ c; \
|
||||
#define HALF_ROUND(a, b, c, d, s, t) \
|
||||
a += b; c += d; \
|
||||
b = ROTATE(b, s) ^ a; \
|
||||
d = ROTATE(d, t) ^ c; \
|
||||
a = ROTATE(a, 32);
|
||||
|
||||
#define FULL_ROUND(v0, v1, v2, v3) \
|
||||
HALF_ROUND(v0, v1, v2, v3, 13, 16); \
|
||||
#define FULL_ROUND(v0, v1, v2, v3) \
|
||||
HALF_ROUND(v0, v1, v2, v3, 13, 16); \
|
||||
HALF_ROUND(v2, v1, v0, v3, 17, 21);
|
||||
|
||||
#define DOUBLE_ROUND(v0, v1, v2, v3) \
|
||||
#define DOUBLE_ROUND(v0, v1, v2, v3) \
|
||||
FULL_ROUND(v0, v1, v2, v3) \
|
||||
FULL_ROUND(v0, v1, v2, v3)
|
||||
|
||||
#define SIPROUND FULL_ROUND
|
||||
|
||||
#define U32TO8_LE(p, v) \
|
||||
(p)[0] = (uint8_t)((v)); \
|
||||
(p)[1] = (uint8_t)((v) >> 8); \
|
||||
(p)[2] = (uint8_t)((v) >> 16); \
|
||||
(p)[3] = (uint8_t)((v) >> 24);
|
||||
|
||||
#define U64TO8_LE(p, v) \
|
||||
U32TO8_LE((p), (uint32_t)((v))); \
|
||||
U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
|
||||
|
||||
#define U8TO64_LE(p) \
|
||||
(((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) | \
|
||||
((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) | \
|
||||
((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) | \
|
||||
((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
|
||||
|
||||
void
|
||||
isc_siphash24(const uint8_t *k, const uint8_t *in, size_t inlen, uint8_t *out)
|
||||
isc_siphash24(const uint8_t *k,
|
||||
const uint8_t *in, const size_t inlen,
|
||||
uint8_t *out)
|
||||
{
|
||||
const uint64_t *key = (const uint64_t *)k;
|
||||
uint64_t k0 = le64toh(key[0]);
|
||||
uint64_t k1 = le64toh(key[1]);
|
||||
REQUIRE(k != NULL);
|
||||
REQUIRE(out != NULL);
|
||||
|
||||
uint64_t k0 = U8TO64_LE(k);
|
||||
uint64_t k1 = U8TO64_LE(k + 8);
|
||||
|
||||
uint64_t v0 = 0x736f6d6570736575ULL ^ k0;
|
||||
uint64_t v1 = 0x646f72616e646f6dULL ^ k1;
|
||||
uint64_t v2 = 0x6c7967656e657261ULL ^ k0;
|
||||
uint64_t v3 = 0x7465646279746573ULL ^ k1;
|
||||
|
||||
size_t left = inlen;
|
||||
|
||||
uint64_t b = ((uint64_t)inlen) << 56;
|
||||
|
||||
const uint64_t *inbuf = (const uint64_t *)in;
|
||||
while (left >= 8) {
|
||||
uint64_t m = le64toh(*inbuf);
|
||||
const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t));
|
||||
const size_t left = inlen & 7;
|
||||
|
||||
for (; in != end; in += 8) {
|
||||
uint64_t m = U8TO64_LE(in);
|
||||
|
||||
v3 ^= m;
|
||||
|
||||
SIPROUND(v0, v1, v2, v3);
|
||||
SIPROUND(v0, v1, v2, v3);
|
||||
for (size_t i = 0; i < cROUNDS; ++i) {
|
||||
SIPROUND(v0, v1, v2, v3);
|
||||
}
|
||||
|
||||
v0 ^= m;
|
||||
|
||||
inbuf++; left -= 8;
|
||||
}
|
||||
|
||||
const uint8_t *end = in + (inlen - left);
|
||||
|
||||
switch (left) {
|
||||
case 7:
|
||||
b |= ((uint64_t)end[6]) << 48;
|
||||
b |= ((uint64_t)in[6]) << 48;
|
||||
/* FALLTHROUGH */
|
||||
case 6:
|
||||
b |= ((uint64_t)end[5]) << 40;
|
||||
b |= ((uint64_t)in[5]) << 40;
|
||||
/* FALLTHROUGH */
|
||||
case 5:
|
||||
b |= ((uint64_t)end[4]) << 32;
|
||||
b |= ((uint64_t)in[4]) << 32;
|
||||
/* FALLTHROUGH */
|
||||
case 4:
|
||||
b |= ((uint64_t)end[3]) << 24;
|
||||
b |= ((uint64_t)in[3]) << 24;
|
||||
/* FALLTHROUGH */
|
||||
case 3:
|
||||
b |= ((uint64_t)end[2]) << 16;
|
||||
b |= ((uint64_t)in[2]) << 16;
|
||||
/* FALLTHROUGH */
|
||||
case 2:
|
||||
b |= ((uint64_t)end[1]) << 8;
|
||||
b |= ((uint64_t)in[1]) << 8;
|
||||
/* FALLTHROUGH */
|
||||
case 1:
|
||||
b |= ((uint64_t)end[0]);
|
||||
b |= ((uint64_t)in[0]);
|
||||
/* FALLTHROUGH */
|
||||
case 0:
|
||||
break;
|
||||
|
|
@ -100,20 +182,20 @@ isc_siphash24(const uint8_t *k, const uint8_t *in, size_t inlen, uint8_t *out)
|
|||
|
||||
v3 ^= b;
|
||||
|
||||
SIPROUND(v0, v1, v2, v3);
|
||||
SIPROUND(v0, v1, v2, v3);
|
||||
for (size_t i = 0; i < cROUNDS; ++i) {
|
||||
SIPROUND(v0, v1, v2, v3);
|
||||
}
|
||||
|
||||
v0 ^= b;
|
||||
|
||||
v2 ^= 0xff;
|
||||
|
||||
SIPROUND(v0, v1, v2, v3);
|
||||
SIPROUND(v0, v1, v2, v3);
|
||||
SIPROUND(v0, v1, v2, v3);
|
||||
SIPROUND(v0, v1, v2, v3);
|
||||
for (size_t i = 0; i < dROUNDS; ++i) {
|
||||
SIPROUND(v0, v1, v2, v3);
|
||||
}
|
||||
|
||||
b = v0 ^ v1 ^ v2 ^ v3;
|
||||
|
||||
uint64_t *outbuf = (uint64_t *)out;
|
||||
*outbuf = htole64(b);
|
||||
U64TO8_LE(out, b);
|
||||
}
|
||||
#endif /* HAVE_OPENSSL_SIPHASH */
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include <stddef.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include <sched.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define UNIT_TESTING
|
||||
|
|
@ -22,7 +23,35 @@
|
|||
|
||||
#include <isc/siphash.h>
|
||||
|
||||
void
|
||||
native_isc_siphash24(const uint8_t *,
|
||||
const uint8_t *, const size_t,
|
||||
uint8_t *);
|
||||
|
||||
#if HAVE_OPENSSL_SIPHASH
|
||||
|
||||
void
|
||||
openssl_isc_siphash24(const uint8_t *,
|
||||
const uint8_t *, const size_t,
|
||||
uint8_t *);
|
||||
|
||||
#undef HAVE_OPENSSL_SIPHASH
|
||||
#define isc_siphash24 native_isc_siphash24
|
||||
#include "../siphash.c"
|
||||
#undef isc_siphash24
|
||||
|
||||
#define HAVE_OPENSSL_SIPHASH 1
|
||||
#define isc_siphash24 openssl_isc_siphash24
|
||||
#include "../siphash.c"
|
||||
#undef isc_siphash24
|
||||
|
||||
#else
|
||||
|
||||
#define isc_siphash24 native_isc_siphash24
|
||||
#include "../siphash.c"
|
||||
#undef isc_siphash24
|
||||
|
||||
#endif
|
||||
|
||||
const uint8_t vectors[64][8] = {
|
||||
{ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, },
|
||||
|
|
@ -91,8 +120,9 @@ const uint8_t vectors[64][8] = {
|
|||
{ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, },
|
||||
};
|
||||
|
||||
#if HAVE_OPENSSL_SIPHASH
|
||||
static void
|
||||
isc_siphash24_test(void **state) {
|
||||
openssl_isc_siphash24_test(void **state) {
|
||||
UNUSED(state);
|
||||
|
||||
uint8_t in[64], out[8], key[16];
|
||||
|
|
@ -102,14 +132,34 @@ isc_siphash24_test(void **state) {
|
|||
|
||||
for (int i = 0; i < 64; i++) {
|
||||
in[i] = i;
|
||||
isc_siphash24(key, in, i, out);
|
||||
openssl_isc_siphash24(key, in, i, out);
|
||||
assert_memory_equal(out, vectors[i], 8);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
native_isc_siphash24_test(void **state) {
|
||||
UNUSED(state);
|
||||
|
||||
uint8_t in[64], out[8], key[16];
|
||||
for (int i = 0; i < 16; i++) {
|
||||
key[i] = i;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 64; i++) {
|
||||
in[i] = i;
|
||||
native_isc_siphash24(key, in, i, out);
|
||||
assert_memory_equal(out, vectors[i], 8);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
const struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test(isc_siphash24_test),
|
||||
#if HAVE_OPENSSL_SIPHASH
|
||||
cmocka_unit_test(openssl_isc_siphash24_test),
|
||||
#endif
|
||||
cmocka_unit_test(native_isc_siphash24_test),
|
||||
};
|
||||
|
||||
return (cmocka_run_group_tests(tests, NULL, NULL));
|
||||
|
|
|
|||
Loading…
Reference in a new issue