]> source.dussan.org Git - rspamd.git/commitdiff
Add reference implementation of siphash.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 8 Apr 2015 10:26:40 +0000 (11:26 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 8 Apr 2015 10:26:40 +0000 (11:26 +0100)
src/libcryptobox/CMakeLists.txt
src/libcryptobox/cryptobox.c
src/libcryptobox/siphash/ref.c [new file with mode: 0644]
src/libcryptobox/siphash/siphash.c [new file with mode: 0644]
src/libcryptobox/siphash/siphash.h [new file with mode: 0644]

index b5fa56fe96623f636c493b03c1707ff3631da7c9..59e5133beec818f9dd8832a30fa4e94725f4b2fc 100644 (file)
@@ -6,6 +6,8 @@ TARGET_ARCHITECTURE(ARCH)
 SET(CHACHASRC ${CMAKE_CURRENT_SOURCE_DIR}/chacha20/chacha.c 
        ${CMAKE_CURRENT_SOURCE_DIR}/chacha20/ref.c)
 SET(POLYSRC ${CMAKE_CURRENT_SOURCE_DIR}/poly1305/poly1305.c)
+SET(SIPHASHSRC ${CMAKE_CURRENT_SOURCE_DIR}/siphash/siphash.c
+       ${CMAKE_CURRENT_SOURCE_DIR}/siphash/ref.c)
 
 # For now we support only x86_64 architecture with optimizations
 IF(${ARCH} STREQUAL "x86_64")
@@ -54,4 +56,5 @@ CONFIGURE_FILE(platform_config.h.in platform_config.h)
 INCLUDE_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}")
 SET(LIBCRYPTOBOXSRC ${CMAKE_CURRENT_SOURCE_DIR}/cryptobox.c)
 
-SET(RSPAMD_CRYPTOBOX ${LIBCRYPTOBOXSRC} ${CHACHASRC} ${POLYSRC} ${CURVESRC} PARENT_SCOPE)
\ No newline at end of file
+SET(RSPAMD_CRYPTOBOX ${LIBCRYPTOBOXSRC} ${CHACHASRC} ${POLYSRC} ${SIPHASHSRC}
+       ${CURVESRC} PARENT_SCOPE)
\ No newline at end of file
index 8674867d6ec113e92f012b18cf88441378aee06c..70e6992c6a8298e3da9f15f472060642c0fdd835 100644 (file)
@@ -26,6 +26,7 @@
 #include "chacha20/chacha.h"
 #include "poly1305/poly1305.h"
 #include "curve25519/curve25519.h"
+#include "siphash/siphash.h"
 #include "ottery.h"
 #ifdef HAVE_CPUID_H
 #include <cpuid.h>
@@ -117,6 +118,7 @@ rspamd_cryptobox_init (void)
 
        chacha_load ();
        poly1305_load ();
+       siphash_load ();
 }
 
 void
diff --git a/src/libcryptobox/siphash/ref.c b/src/libcryptobox/siphash/ref.c
new file mode 100644 (file)
index 0000000..2b20ae3
--- /dev/null
@@ -0,0 +1,151 @@
+/* Copyright (c) 2015, Vsevolod Stakhov
+ * Copyright (c) 2012-2014 Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
+ * Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *       * Redistributions of source code must retain the above copyright
+ *         notice, this list of conditions and the following disclaimer.
+ *       * Redistributions in binary form must reproduce the above copyright
+ *         notice, this list of conditions and the following disclaimer in the
+ *         documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+/* default: SipHash-2-4 */
+#define cROUNDS 2
+#define dROUNDS 4
+
+#define ROTL(x,b) (uint64_t)( ((x) << (b)) | ( (x) >> (64 - (b))) )
+
+#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));
+
+#if BYTE_ORDER != LITTLE_ENDIAN
+#define U8TO64_LE(p) \
+       (((uint64_t)((p)[0]) <<  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))
+#else
+#define U8TO64_LE(p) (*(uint64_t*)(p))
+#endif
+
+#define SIPROUND                                        \
+  do {                                                  \
+    v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
+    v2 += v3; v3=ROTL(v3,16); v3 ^= v2;                 \
+    v0 += v3; v3=ROTL(v3,21); v3 ^= v0;                 \
+    v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
+  } while(0)
+
+
+void
+siphash_ref (uint8_t *out, const uint8_t *in, uint64_t inlen, const uint8_t *k)
+{
+       /* "somepseudorandomlygeneratedbytes" */
+       uint64_t v0 = 0x736f6d6570736575ULL;
+       uint64_t v1 = 0x646f72616e646f6dULL;
+       uint64_t v2 = 0x6c7967656e657261ULL;
+       uint64_t v3 = 0x7465646279746573ULL;
+       uint64_t b;
+       uint64_t k0 = U8TO64_LE(k);
+       uint64_t k1 = U8TO64_LE(k + 8);
+       uint64_t m;
+       int i;
+       const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t));
+       const int left = inlen & 7;
+       b = ((uint64_t) inlen) << 56;
+       v3 ^= k1;
+       v2 ^= k0;
+       v1 ^= k1;
+       v0 ^= k0;
+
+#ifdef DOUBLE
+       v1 ^= 0xee;
+#endif
+
+       for (; in != end; in += 8) {
+               m = U8TO64_LE(in);
+               v3 ^= m;
+
+               for (i = 0; i < cROUNDS; ++i)
+                       SIPROUND
+                       ;
+
+               v0 ^= m;
+       }
+
+       switch (left) {
+       case 7:
+               b |= ((uint64_t) in[6]) << 48;
+       case 6:
+               b |= ((uint64_t) in[5]) << 40;
+       case 5:
+               b |= ((uint64_t) in[4]) << 32;
+       case 4:
+               b |= ((uint64_t) in[3]) << 24;
+       case 3:
+               b |= ((uint64_t) in[2]) << 16;
+       case 2:
+               b |= ((uint64_t) in[1]) << 8;
+       case 1:
+               b |= ((uint64_t) in[0]);
+               break;
+       case 0:
+               break;
+       }
+
+       v3 ^= b;
+
+       for (i = 0; i < cROUNDS; ++i)
+               SIPROUND
+               ;
+
+       v0 ^= b;
+
+#ifndef DOUBLE
+       v2 ^= 0xff;
+#else
+       v2 ^= 0xee;
+#endif
+
+       for (i = 0; i < dROUNDS; ++i)
+               SIPROUND
+               ;
+
+       b = v0 ^ v1 ^ v2 ^ v3;
+       U64TO8_LE(out, b);
+
+#ifdef DOUBLE
+       v1 ^= 0xdd;
+
+       TRACE;
+       for( i=0; i<dROUNDS; ++i ) SIPROUND;
+
+       b = v0 ^ v1 ^ v2 ^ v3;
+       U64TO8_LE( out+8, b );
+#endif
+}
diff --git a/src/libcryptobox/siphash/siphash.c b/src/libcryptobox/siphash/siphash.c
new file mode 100644 (file)
index 0000000..de5a18e
--- /dev/null
@@ -0,0 +1,75 @@
+/* Copyright (c) 2015, Vsevolod Stakhov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *       * Redistributions of source code must retain the above copyright
+ *         notice, this list of conditions and the following disclaimer.
+ *       * Redistributions in binary form must reproduce the above copyright
+ *         notice, this list of conditions and the following disclaimer in the
+ *         documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "cryptobox.h"
+#include "siphash.h"
+#include "platform_config.h"
+
+extern unsigned long cpu_config;
+
+typedef struct siphash_impl_t
+{
+       unsigned long cpu_flags;
+       const char *desc;
+
+       void (*siphash)(uint8_t *out, const uint8_t *in, uint64_t inlen, const uint8_t *k);
+} siphash_impl_t;
+
+#define SIPHASH_DECLARE(ext) \
+       void siphash_##ext(uint8_t *out, const uint8_t *in, uint64_t inlen, const uint8_t *k);
+
+#define SIPHASH_IMPL(cpuflags, desc, ext) \
+       {(cpuflags), desc, siphash_##ext}
+
+
+SIPHASH_DECLARE(ref)
+#define SIPHASH_GENERIC SIPHASH_IMPL(0, "generic", ref)
+
+/* list implemenations from most optimized to least, with generic as the last entry */
+static const siphash_impl_t siphash_list[] = {
+               SIPHASH_GENERIC,
+};
+
+static const siphash_impl_t *siphash_opt = &siphash_list[0];
+
+void
+siphash_load(void)
+{
+       guint i;
+
+       if (cpu_config != 0) {
+               for (i = 0; i < G_N_ELEMENTS(siphash_list); i++) {
+                       if (siphash_list[i].cpu_flags & cpu_config) {
+                               siphash_opt = &siphash_list[i];
+                               break;
+                       }
+               }
+       }
+}
+
+void siphash24 (unsigned char *out, const unsigned char *in,
+               unsigned long long inlen, const unsigned char *k)
+{
+       siphash_opt->siphash (out, in, inlen, k);
+}
diff --git a/src/libcryptobox/siphash/siphash.h b/src/libcryptobox/siphash/siphash.h
new file mode 100644 (file)
index 0000000..667f391
--- /dev/null
@@ -0,0 +1,41 @@
+/* Copyright (c) 2015, Vsevolod Stakhov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *       * Redistributions of source code must retain the above copyright
+ *         notice, this list of conditions and the following disclaimer.
+ *       * Redistributions in binary form must reproduce the above copyright
+ *         notice, this list of conditions and the following disclaimer in the
+ *         documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef SIPHASH_H_
+#define SIPHASH_H_
+
+#include <stddef.h>
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+void siphash_load (void);
+void siphash24 (unsigned char *out,
+               const unsigned char *in,
+               unsigned long long inlen,
+               const unsigned char *k);
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* SIPHASH_H_ */