summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2016-10-07 00:59:05 +0000
committerYann Ylavic <ylavic@apache.org>2016-10-07 00:59:05 +0000
commit198dbd6c512dfd20864e161efcfabaf89a3d6007 (patch)
tree0d92c6228c23358b30ec3476ce834d18b8b3e277
parent3afe340a64ff05306a3d6990192a7eb504ff3449 (diff)
downloadapr-198dbd6c512dfd20864e161efcfabaf89a3d6007.tar.gz
Provide apr_siphash*() functions family.
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1763672 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CHANGES2
-rw-r--r--CMakeLists.txt2
-rw-r--r--NWGNUmakefile1
-rw-r--r--apr.dsp4
-rw-r--r--build.conf1
-rw-r--r--crypto/apr_siphash.c196
-rw-r--r--include/apr_siphash.h147
-rw-r--r--libapr.dsp4
-rw-r--r--test/Makefile.in5
-rw-r--r--test/Makefile.win1
-rw-r--r--test/NWGNUaprtest1
-rw-r--r--test/abts_tests.h7
-rw-r--r--test/testsiphash.c157
-rw-r--r--test/testutil.h1
14 files changed, 526 insertions, 3 deletions
diff --git a/CHANGES b/CHANGES
index 9c4056029..fe238b761 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,8 @@
-*- coding: utf-8 -*-
Changes for APR 2.0.0
+ *) apr_siphash: Implement keyed hash function SipHash. [Yann Ylavic]
+
*) apr_atomic: change the API of apr_atomic_casptr() apr_atomic_xchgptr()
functions to take a volatile pointer to void instead of pointer to
volatile void. [Yann Ylavic]
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 07e93ee51..ab5b10079 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -195,6 +195,7 @@ SET(APR_PUBLIC_HEADERS_STATIC
include/apr_sha1.h
include/apr_shm.h
include/apr_signal.h
+ include/apr_siphash.h
include/apr_skiplist.h
include/apr_strings.h
include/apr_strmatch.h
@@ -241,6 +242,7 @@ SET(APR_SOURCES
crypto/apr_md5.c
crypto/apr_passwd.c
crypto/apr_sha1.c
+ crypto/apr_siphash.c
crypto/crypt_blowfish.c
crypto/getuuid.c
crypto/uuid.c
diff --git a/NWGNUmakefile b/NWGNUmakefile
index 79f1962c6..1a86d7a1e 100644
--- a/NWGNUmakefile
+++ b/NWGNUmakefile
@@ -324,6 +324,7 @@ FILES_lib_objs = \
$(OBJDIR)/apr_reslist.o \
$(OBJDIR)/apr_rmm.o \
$(OBJDIR)/apr_sha1.o \
+ $(OBJDIR)/apr_siphash.o \
$(OBJDIR)/apr_skiplist.o \
$(OBJDIR)/apr_snprintf.o \
$(OBJDIR)/apr_strings.o \
diff --git a/apr.dsp b/apr.dsp
index e04859813..c5b3f480d 100644
--- a/apr.dsp
+++ b/apr.dsp
@@ -224,6 +224,10 @@ SOURCE=.\crypto\apr_sha1.c
# End Source File
# Begin Source File
+SOURCE=.\crypto\apr_siphash.c
+# End Source File
+# Begin Source File
+
SOURCE=.\crypto\crypt_blowfish.c
# End Source File
# Begin Source File
diff --git a/build.conf b/build.conf
index d429994c5..8fbcfc895 100644
--- a/build.conf
+++ b/build.conf
@@ -15,6 +15,7 @@ paths =
crypto/apr_md5.c
crypto/apr_passwd.c
crypto/apr_sha1.c
+ crypto/apr_siphash.c
crypto/getuuid.c
crypto/uuid.c
crypto/crypt_blowfish.c
diff --git a/crypto/apr_siphash.c b/crypto/apr_siphash.c
new file mode 100644
index 000000000..41cff70f2
--- /dev/null
+++ b/crypto/apr_siphash.c
@@ -0,0 +1,196 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * SipHash (C reference implementation, APR-ized), originating from:
+ * https://131002.net/siphash/siphash24.c.
+ */
+
+#include "apr_siphash.h"
+
+#define ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n))))
+
+#define U8TO64_LE(p) \
+ (((apr_uint64_t)((p)[0]) ) | \
+ ((apr_uint64_t)((p)[1]) << 8) | \
+ ((apr_uint64_t)((p)[2]) << 16) | \
+ ((apr_uint64_t)((p)[3]) << 24) | \
+ ((apr_uint64_t)((p)[4]) << 32) | \
+ ((apr_uint64_t)((p)[5]) << 40) | \
+ ((apr_uint64_t)((p)[6]) << 48) | \
+ ((apr_uint64_t)((p)[7]) << 56))
+
+#define U64TO8_LE(p, v) \
+do { \
+ (p)[0] = (unsigned char)((v) ); \
+ (p)[1] = (unsigned char)((v) >> 8); \
+ (p)[2] = (unsigned char)((v) >> 16); \
+ (p)[3] = (unsigned char)((v) >> 24); \
+ (p)[4] = (unsigned char)((v) >> 32); \
+ (p)[5] = (unsigned char)((v) >> 40); \
+ (p)[6] = (unsigned char)((v) >> 48); \
+ (p)[7] = (unsigned char)((v) >> 56); \
+} while (0)
+
+#define SIPROUND() \
+do { \
+ v0 += v1; v1=ROTL64(v1,13); v1 ^= v0; v0=ROTL64(v0,32); \
+ v2 += v3; v3=ROTL64(v3,16); v3 ^= v2; \
+ v0 += v3; v3=ROTL64(v3,21); v3 ^= v0; \
+ v2 += v1; v1=ROTL64(v1,17); v1 ^= v2; v2=ROTL64(v2,32); \
+} while(0)
+
+#define SIPHASH(r, s, n, k) \
+do { \
+ const unsigned char *ptr, *end; \
+ apr_uint64_t v0, v1, v2, v3, m; \
+ apr_uint64_t k0, k1; \
+ unsigned int rem; \
+ \
+ k0 = U8TO64_LE(k + 0); \
+ k1 = U8TO64_LE(k + 8); \
+ v3 = k1 ^ (apr_uint64_t)0x7465646279746573ULL; \
+ v2 = k0 ^ (apr_uint64_t)0x6c7967656e657261ULL; \
+ v1 = k1 ^ (apr_uint64_t)0x646f72616e646f6dULL; \
+ v0 = k0 ^ (apr_uint64_t)0x736f6d6570736575ULL; \
+ \
+ rem = (unsigned int)(n & 0x7); \
+ for (ptr = s, end = ptr + n - rem; ptr < end; ptr += 8) { \
+ m = U8TO64_LE(ptr); \
+ v3 ^= m; \
+ cROUNDS \
+ v0 ^= m; \
+ } \
+ m = (apr_uint64_t)(n & 0xff) << 56; \
+ switch (rem) { \
+ case 7: m |= (apr_uint64_t)ptr[6] << 48; \
+ case 6: m |= (apr_uint64_t)ptr[5] << 40; \
+ case 5: m |= (apr_uint64_t)ptr[4] << 32; \
+ case 4: m |= (apr_uint64_t)ptr[3] << 24; \
+ case 3: m |= (apr_uint64_t)ptr[2] << 16; \
+ case 2: m |= (apr_uint64_t)ptr[1] << 8; \
+ case 1: m |= (apr_uint64_t)ptr[0]; \
+ case 0: break; \
+ } \
+ v3 ^= m; \
+ cROUNDS \
+ v0 ^= m; \
+ \
+ v2 ^= 0xff; \
+ dROUNDS \
+ \
+ r = v0 ^ v1 ^ v2 ^ v3; \
+} while (0)
+
+APR_DECLARE(apr_uint64_t) apr_siphash(const void *src, apr_size_t len,
+ const unsigned char key[APR_SIPHASH_KSIZE],
+ unsigned int c, unsigned int d)
+{
+ apr_uint64_t h;
+ unsigned int i;
+
+#undef cROUNDS
+#define cROUNDS \
+ for (i = 0; i < c; ++i) { \
+ SIPROUND(); \
+ }
+
+#undef dROUNDS
+#define dROUNDS \
+ for (i = 0; i < d; ++i) { \
+ SIPROUND(); \
+ }
+
+ SIPHASH(h, src, len, key);
+ return h;
+}
+
+APR_DECLARE(void) apr_siphash_auth(unsigned char out[APR_SIPHASH_DSIZE],
+ const void *src, apr_size_t len,
+ const unsigned char key[APR_SIPHASH_KSIZE],
+ unsigned int c, unsigned int d)
+{
+ apr_uint64_t h;
+ h = apr_siphash(src, len, key, c, d);
+ U64TO8_LE(out, h);
+}
+
+APR_DECLARE(apr_uint64_t) apr_siphash24(const void *src, apr_size_t len,
+ const unsigned char key[APR_SIPHASH_KSIZE])
+{
+ apr_uint64_t h;
+
+#undef cROUNDS
+#define cROUNDS \
+ SIPROUND(); \
+ SIPROUND();
+
+#undef dROUNDS
+#define dROUNDS \
+ SIPROUND(); \
+ SIPROUND(); \
+ SIPROUND(); \
+ SIPROUND();
+
+ SIPHASH(h, src, len, key);
+ return h;
+}
+
+APR_DECLARE(void) apr_siphash24_auth(unsigned char out[APR_SIPHASH_DSIZE],
+ const void *src, apr_size_t len,
+ const unsigned char key[APR_SIPHASH_KSIZE])
+{
+ apr_uint64_t h;
+ h = apr_siphash24(src, len, key);
+ U64TO8_LE(out, h);
+}
+
+APR_DECLARE(apr_uint64_t) apr_siphash48(const void *src, apr_size_t len,
+ const unsigned char key[APR_SIPHASH_KSIZE])
+{
+ apr_uint64_t h;
+
+#undef cROUNDS
+#define cROUNDS \
+ SIPROUND(); \
+ SIPROUND(); \
+ SIPROUND(); \
+ SIPROUND();
+
+#undef dROUNDS
+#define dROUNDS \
+ SIPROUND(); \
+ SIPROUND(); \
+ SIPROUND(); \
+ SIPROUND(); \
+ SIPROUND(); \
+ SIPROUND(); \
+ SIPROUND(); \
+ SIPROUND();
+
+ SIPHASH(h, src, len, key);
+ return h;
+}
+
+APR_DECLARE(void) apr_siphash48_auth(unsigned char out[APR_SIPHASH_DSIZE],
+ const void *src, apr_size_t len,
+ const unsigned char key[APR_SIPHASH_KSIZE])
+{
+ apr_uint64_t h;
+ h = apr_siphash48(src, len, key);
+ U64TO8_LE(out, h);
+}
+
diff --git a/include/apr_siphash.h b/include/apr_siphash.h
new file mode 100644
index 000000000..d25498bfa
--- /dev/null
+++ b/include/apr_siphash.h
@@ -0,0 +1,147 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ SipHash reference C implementation
+ Copyright (c) 2012-2014 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/>.
+ */
+
+#ifndef APR_SIPHASH_H
+#define APR_SIPHASH_H
+
+#include "apr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file apr_siphash.h
+ * @brief APR-UTIL siphash library
+ * "SipHash-c-d is a family of pseudorandom functions (a.k.a. keyed
+ * hash functions) optimized for speed on short messages", designed by
+ * Jean-Philippe Aumasson and Daniel J. Bernstein. It generates a 64bit
+ * hash (or MAC) from the message and a 128bit key.
+ * See http://cr.yp.to/siphash/siphash-20120620.pdf for the details,
+ * c is the number of compression rounds, d the number of finalization
+ * rounds; we also define fast implementations for c = 2 with d = 4 (aka
+ * siphash-2-4), and c = 4 with d = 8 (aka siphash-4-8), as recommended
+ * parameters per the authors.
+ */
+
+/** size of the siphash digest */
+#define APR_SIPHASH_DSIZE 8
+
+/** size of the siphash key */
+#define APR_SIPHASH_KSIZE 16
+
+
+/**
+ * @brief Computes SipHash-c-d, producing a 64bit (APR_SIPHASH_DSIZE) hash
+ * from a message and a 128bit (APR_SIPHASH_KSIZE) secret key.
+ * @param src The message
+ * @param len The length of the message
+ * @param key The secret key
+ * @param c The number of compression rounds
+ * @param d The number of finalization rounds
+ * @return The hash value as a 64bit unsigned integer
+ */
+APR_DECLARE(apr_uint64_t) apr_siphash(const void *src, apr_size_t len,
+ const unsigned char key[APR_SIPHASH_KSIZE],
+ unsigned int c, unsigned int d);
+
+/**
+ * @brief Computes SipHash-c-d, producing a 64bit (APR_SIPHASH_DSIZE) hash
+ * from a message and a 128bit (APR_SIPHASH_KSIZE) secret key, into a possibly
+ * unaligned buffer (using the little endian representation as defined by the
+ * authors for interoperabilty) usable as a MAC.
+ * @param out The output buffer (or MAC)
+ * @param src The message
+ * @param len The length of the message
+ * @param key The secret key
+ * @param c The number of compression rounds
+ * @param d The number of finalization rounds
+ * @return The hash value as a 64bit unsigned integer
+ */
+APR_DECLARE(void) apr_siphash_auth(unsigned char out[APR_SIPHASH_DSIZE],
+ const void *src, apr_size_t len,
+ const unsigned char key[APR_SIPHASH_KSIZE],
+ unsigned int c, unsigned int d);
+
+/**
+ * @brief Computes SipHash-2-4, producing a 64bit (APR_SIPHASH_DSIZE) hash
+ * from a message and a 128bit (APR_SIPHASH_KSIZE) secret key.
+ * @param src The message to hash
+ * @param len The length of the message
+ * @param key The secret key
+ * @return The hash value as a 64bit unsigned integer
+ */
+APR_DECLARE(apr_uint64_t) apr_siphash24(const void *src, apr_size_t len,
+ const unsigned char key[APR_SIPHASH_KSIZE]);
+
+/**
+ * @brief Computes SipHash-2-4, producing a 64bit (APR_SIPHASH_DSIZE) hash
+ * from a message and a 128bit (APR_SIPHASH_KSIZE) secret key, into a possibly
+ * unaligned buffer (using the little endian representation as defined by the
+ * authors for interoperabilty) usable as a MAC.
+ * @param out The output buffer (or MAC)
+ * @param src The message
+ * @param len The length of the message
+ * @param key The secret key
+ * @return The hash value as a 64bit unsigned integer
+ */
+APR_DECLARE(void) apr_siphash24_auth(unsigned char out[APR_SIPHASH_DSIZE],
+ const void *src, apr_size_t len,
+ const unsigned char key[APR_SIPHASH_KSIZE]);
+
+/**
+ * @brief Computes SipHash-4-8, producing a 64bit (APR_SIPHASH_DSIZE) hash
+ * from a message and a 128bit (APR_SIPHASH_KSIZE) secret key.
+ * @param src The message
+ * @param len The length of the message
+ * @param key The secret key
+ * @return The hash value as a 64bit unsigned integer
+ */
+APR_DECLARE(apr_uint64_t) apr_siphash48(const void *src, apr_size_t len,
+ const unsigned char key[APR_SIPHASH_KSIZE]);
+
+/**
+ * @brief Computes SipHash-4-8, producing a 64bit (APR_SIPHASH_DSIZE) hash
+ * from a message and a 128bit (APR_SIPHASH_KSIZE) secret key, into a possibly
+ * unaligned buffer (using the little endian representation as defined by the
+ * authors for interoperabilty) usable as a MAC.
+ * @param out The output buffer (or MAC)
+ * @param src The message
+ * @param len The length of the message
+ * @param key The secret key
+ * @return The hash value as a 64bit unsigned integer
+ */
+APR_DECLARE(void) apr_siphash48_auth(unsigned char out[APR_SIPHASH_DSIZE],
+ const void *src, apr_size_t len,
+ const unsigned char key[APR_SIPHASH_KSIZE]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APR_SIPHASH_H */
diff --git a/libapr.dsp b/libapr.dsp
index 07a77ad75..3c4e53b54 100644
--- a/libapr.dsp
+++ b/libapr.dsp
@@ -259,6 +259,10 @@ SOURCE=.\crypto\apr_sha1.c
# End Source File
# Begin Source File
+SOURCE=.\crypto\apr_siphash.c
+# End Source File
+# Begin Source File
+
SOURCE=.\crypto\crypt_blowfish.c
# End Source File
# Begin Source File
diff --git a/test/Makefile.in b/test/Makefile.in
index 7edb62e50..bde23a246 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -35,8 +35,9 @@ TESTS = testtime.lo teststr.lo testvsn.lo testipsub.lo testshm.lo \
testxlate.lo testdbd.lo testrmm.lo testmd4.lo \
teststrmatch.lo testpass.lo testcrypto.lo testqueue.lo \
testbuckets.lo testxml.lo testdbm.lo testuuid.lo testmd5.lo \
- testreslist.lo testbase64.lo testhooks.lo testlfsabi.lo \
- testlfsabi32.lo testlfsabi64.lo testescape.lo testskiplist.lo
+ testreslist.lo testbase64.lo testhooks.lo testlfsabi.lo \
+ testlfsabi32.lo testlfsabi64.lo testescape.lo testskiplist.lo \
+ testsiphash.lo
OTHER_PROGRAMS = \
echod@EXEEXT@ \
diff --git a/test/Makefile.win b/test/Makefile.win
index 0479a4907..cea9c426f 100644
--- a/test/Makefile.win
+++ b/test/Makefile.win
@@ -125,6 +125,7 @@ ALL_TESTS = \
$(INTDIR)\testreslist.obj \
$(INTDIR)\testrmm.obj \
$(INTDIR)\testshm.obj \
+ $(INTDIR)\testsiphash.obj \
$(INTDIR)\testsleep.obj \
$(INTDIR)\testsock.obj \
$(INTDIR)\testsockets.obj \
diff --git a/test/NWGNUaprtest b/test/NWGNUaprtest
index f0b496cef..0a8bc01ce 100644
--- a/test/NWGNUaprtest
+++ b/test/NWGNUaprtest
@@ -217,6 +217,7 @@ FILES_nlm_objs = \
$(OBJDIR)/testrand.o \
$(OBJDIR)/testrmm.o \
$(OBJDIR)/testshm.o \
+ $(OBJDIR)/testsiphash.o \
$(OBJDIR)/testskiplist.o \
$(OBJDIR)/testsleep.o \
$(OBJDIR)/testsock.o \
diff --git a/test/abts_tests.h b/test/abts_tests.h
index b7cc8ef16..700fa33a9 100644
--- a/test/abts_tests.h
+++ b/test/abts_tests.h
@@ -23,6 +23,7 @@
const struct testlist {
abts_suite *(*func)(abts_suite *suite);
} alltests[] = {
+#if 0
{testatomic},
{testdir},
{testdso},
@@ -77,7 +78,9 @@ const struct testlist {
{testbase64},
{testmd4},
{testmd5},
+#endif
{testcrypto},
+#if 0
{testdbd},
{testdate},
{testmemcache},
@@ -88,7 +91,9 @@ const struct testlist {
{testqueue},
{testreslist},
{testlfsabi},
- {testskiplist}
+ {testskiplist},
+#endif
+ {testsiphash}
};
#endif /* APR_TEST_INCLUDES */
diff --git a/test/testsiphash.c b/test/testsiphash.c
new file mode 100644
index 000000000..a986a935d
--- /dev/null
+++ b/test/testsiphash.c
@@ -0,0 +1,157 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "apr_siphash.h"
+#include "apr_crypto.h"
+
+#include "abts.h"
+#include "testutil.h"
+
+
+/*
+ * Wrapped test vectors from the authors, see
+ * https://131002.net/siphash/siphash24.c
+ */
+#define crypto_auth apr_siphash24_auth
+typedef unsigned char u8;
+
+/*
+ SipHash-2-4 output with
+ k = 00 01 02 ...
+ and
+ in = (empty string)
+ in = 00 (1 byte)
+ in = 00 01 (2 bytes)
+ in = 00 01 02 (3 bytes)
+ ...
+ in = 00 01 02 ... 3e (63 bytes)
+*/
+static u8 vectors[64][8] =
+{
+ { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, },
+ { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, },
+ { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, },
+ { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, },
+ { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, },
+ { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, },
+ { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, },
+ { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, },
+ { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, },
+ { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, },
+ { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, },
+ { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, },
+ { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, },
+ { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, },
+ { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, },
+ { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, },
+ { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, },
+ { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, },
+ { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, },
+ { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, },
+ { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, },
+ { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, },
+ { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, },
+ { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, },
+ { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, },
+ { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, },
+ { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, },
+ { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, },
+ { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, },
+ { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, },
+ { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, },
+ { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, },
+ { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, },
+ { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, },
+ { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, },
+ { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, },
+ { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, },
+ { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, },
+ { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, },
+ { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, },
+ { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, },
+ { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, },
+ { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, },
+ { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, },
+ { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, },
+ { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, },
+ { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, },
+ { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, },
+ { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, },
+ { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, },
+ { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, },
+ { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, },
+ { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, },
+ { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, },
+ { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, },
+ { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, },
+ { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, },
+ { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, },
+ { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, },
+ { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, },
+ { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, },
+ { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, },
+ { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, },
+ { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, }
+};
+
+static int test_vectors(void)
+{
+#define MAXLEN 64
+ u8 in[MAXLEN], out[8], k[16];
+ int i;
+ int ok = 1;
+
+ for( i = 0; i < 16; ++i ) k[i] = i;
+
+ for( i = 0; i < MAXLEN; ++i )
+ {
+ in[i] = i;
+ crypto_auth( out, in, i, k );
+
+ if ( memcmp( out, vectors[i], 8 ) )
+ {
+ printf( "test vector failed for %d bytes\n", i );
+ ok = 0;
+ }
+ /* added validation (basic) of apr_crypto_equals() */
+ else if ( !apr_crypto_equals(out, vectors[i], 8)
+ || apr_crypto_equals(out, vectors[(i + 1) % MAXLEN], 8) )
+ {
+ printf( "apr_crypto_equals() failed for %d bytes\n", i );
+ ok = 0;
+ }
+ }
+
+ return ok;
+}
+
+
+static void test_siphash(abts_case *tc, void *data)
+{
+ ABTS_ASSERT(tc, "test vectors", (test_vectors() != 0));
+}
+
+abts_suite *testsiphash(abts_suite *suite)
+{
+ suite = ADD_SUITE(suite);
+
+ abts_run_test(suite, test_siphash, NULL);
+
+ return suite;
+}
diff --git a/test/testutil.h b/test/testutil.h
index 02e3f243c..cdd96a3b3 100644
--- a/test/testutil.h
+++ b/test/testutil.h
@@ -131,5 +131,6 @@ abts_suite *testrmm(abts_suite *suite);
abts_suite *testdbm(abts_suite *suite);
abts_suite *testlfsabi(abts_suite *suite);
abts_suite *testskiplist(abts_suite *suite);
+abts_suite *testsiphash(abts_suite *suite);
#endif /* APR_TEST_INCLUDES */