From c558c0ecdb71ac865e41f2d735eb222f311d340e Mon Sep 17 00:00:00 2001 From: Andrew Bennett Date: Wed, 2 Mar 2016 11:35:29 -0700 Subject: [PATCH] x86_64/i386 and illumos/solaris/SunOS compatibility fixes. * SunOS linker doesn't support --gc-sections * Add portable_endian.h with __sun version of htole64 and le64toh * Replace portable endian code in shake.c with inclusion of portable_endian.h * Replace portable endian code in word.h with inclusion of portable_endian.h * Add explicit extern reference to word.h for posix_memalign when __sun defined * Replace references to u_int*_t with uint*_t * rdtsc call in shake.c was only working on 32-bit i386 * rdtsc call in bench_decaf.cxx was inaccurate on 64-bit x86_64 when clang absent * Fix two signed/unsigned comparison errors in test_decaf.cxx --- Makefile | 3 +++ src/include/portable_endian.h | 37 +++++++++++++++++++++++++++ src/include/word.h | 15 ++++------- src/shake.c | 47 ++++++++++++----------------------- test/bench_decaf.cxx | 14 ++++++++--- test/test_decaf.cxx | 4 +-- 6 files changed, 73 insertions(+), 47 deletions(-) create mode 100644 src/include/portable_endian.h diff --git a/Makefile b/Makefile index 5d849fc..b85dc4d 100644 --- a/Makefile +++ b/Makefile @@ -237,6 +237,9 @@ $(BUILD_LIB)/libdecaf.so.1: $(LIBCOMPONENTS) ifeq ($(UNAME),Darwin) libtool -macosx_version_min $(MACOSX_VERSION_MIN) -dynamic -dead_strip -lc -x -o $@ \ $(LIBCOMPONENTS) +else ifeq ($(UNAME),SunOS) + $(LD) $(LDFLAGS) -shared -Wl,-soname,`basename $@` -o $@ $(LIBCOMPONENTS) + strip --discard-all $@ else $(LD) $(LDFLAGS) -shared -Wl,-soname,`basename $@` -Wl,--gc-sections -o $@ $(LIBCOMPONENTS) strip --discard-all $@ diff --git a/src/include/portable_endian.h b/src/include/portable_endian.h new file mode 100644 index 0000000..24da917 --- /dev/null +++ b/src/include/portable_endian.h @@ -0,0 +1,37 @@ +/* Subset of Mathias Panzenböck's portable endian code, public domain */ + +#ifndef __PORTABLE_ENDIAN_H__ +#define __PORTABLE_ENDIAN_H__ + +#if defined(__linux__) || defined(__CYGWIN__) +# include +#elif defined(__OpenBSD__) +# include +#elif defined(__APPLE__) +# include +# define htole64(x) OSSwapHostToLittleInt64(x) +# define le64toh(x) OSSwapLittleToHostInt64(x) +#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) +# include +# define le64toh(x) letoh64(x) +#elif defined(__sun) && defined(__SVR4) +# include +# define htole64(x) LE_64(x) +# define le64toh(x) LE_64(x) +#elif defined(_WIN16) || defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__) +# include +# include +# if BYTE_ORDER == LITTLE_ENDIAN +# define htole64(x) (x) +# define le64toh(x) (x) +# elif BYTE_ORDER == BIG_ENDIAN +# define htole64(x) __builtin_bswap64(x) +# define le64toh(x) __builtin_bswap64(x) +# else +# error byte order not supported +# endif +#else +# error platform not supported +#endif + +#endif // __PORTABLE_ENDIAN_H__ diff --git a/src/include/word.h b/src/include/word.h index 5c74af6..4f157d2 100644 --- a/src/include/word.h +++ b/src/include/word.h @@ -9,6 +9,9 @@ #define _XOPEN_SOURCE 600 #define __STDC_WANT_LIB_EXT1__ 1 /* for memset_s */ #include +#if defined(__sun) && defined(__SVR4) +extern int posix_memalign(void **, size_t, size_t); +#endif #include #include @@ -16,13 +19,11 @@ #include - -#ifndef __APPLE__ #ifndef _BSD_SOURCE #define _BSD_SOURCE 1 #endif -#include -#endif + +#include "portable_endian.h" #include #include @@ -170,12 +171,6 @@ typedef struct { #define br_is_zero word_is_zero #endif - -#ifdef __APPLE__ - static INLINE uint64_t htole64 (uint64_t x) { return x; } - static INLINE uint64_t letoh64 (uint64_t x) { return x; } -#endif - /** * Really call memset, in a way that prevents the compiler from optimizing it out. * @param p The object to zeroize. diff --git a/src/shake.c b/src/shake.c index 8f83b9b..e138e46 100644 --- a/src/shake.c +++ b/src/shake.c @@ -23,33 +23,7 @@ #include #include -/* Subset of Mathias Panzenböck's portable endian code, public domain */ -#if defined(__linux__) || defined(__CYGWIN__) -# include -#elif defined(__OpenBSD__) -# include -#elif defined(__APPLE__) -# include -# define htole64(x) OSSwapHostToLittleInt64(x) -# define le64toh(x) OSSwapLittleToHostInt64(x) -#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) -# include -# define le64toh(x) letoh64(x) -#elif defined(_WIN16) || defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__) -# include -# include -# if BYTE_ORDER == LITTLE_ENDIAN -# define htole64(x) (x) -# define le64toh(x) (x) -# elif BYTE_ORDER == BIG_ENDIAN -# define htole64(x) __builtin_bswap64(x) -# define le64toh(x) __builtin_bswap64(x) -# else -# error byte order not supported -# endif -#else -# error platform not supported -#endif +#include "portable_endian.h" /* The internal, non-opaque definition of the decaf_sponge struct. */ typedef union { @@ -292,7 +266,7 @@ static void get_cpu_entropy(uint8_t *entropy, size_t len) { # if (defined(__i386__) || defined(__x86_64__)) static char tested = 0, have_rdrand = 0; if (!tested) { - u_int32_t a,b,c,d; + uint32_t a,b,c,d; a=1; __asm__("cpuid" : "+a"(a), "=b"(b), "=c"(c), "=d"(d)); have_rdrand = (c>>30)&1; tested = 1; @@ -314,9 +288,20 @@ static void get_cpu_entropy(uint8_t *entropy, size_t len) { *eo ^= out; } } else if (len>=8) { - uint64_t out; - __asm__ __volatile__ ("rdtsc" : "=A"(out)); - *(uint64_t*) entropy ^= out; +#ifndef __has_builtin +#define __has_builtin(X) 0 +#endif +#if defined(__clang__) && __has_builtin(__builtin_readcyclecounter) + *(uint64_t*) entropy ^= __builtin_readcyclecounter(); +#elif defined(__x86_64__) + uint32_t lobits, hibits; + __asm__ __volatile__ ("rdtsc" : "=a"(lobits), "=d"(hibits)); + *(uint64_t*) entropy ^= (lobits | ((uint64_t)(hibits) << 32)); +#elif defined(__i386__) + uint64_t __value; + __asm__ __volatile__ ("rdtsc" : "=A"(__value)); + *(uint64_t*) entropy ^= __value; +#endif } #else diff --git a/test/bench_decaf.cxx b/test/bench_decaf.cxx index c1666ee..e412d5e 100644 --- a/test/bench_decaf.cxx +++ b/test/bench_decaf.cxx @@ -43,11 +43,17 @@ static double now(void) { #define rdtsc __builtin_readcyclecounter #else static inline uint64_t rdtsc(void) { - u_int64_t out = 0; -# if (defined(__i386__) || defined(__x86_64__)) - __asm__ __volatile__ ("rdtsc" : "=A"(out)); +# if defined(__x86_64__) + uint32_t lobits, hibits; + __asm__ __volatile__ ("rdtsc" : "=a"(lobits), "=d"(hibits)); + return (lobits | ((uint64_t)(hibits) << 32)); +# elif defined(__i386__) + uint64_t __value; + __asm__ __volatile__ ("rdtsc" : "=A"(__value)); + return __value; +# else + return 0; # endif - return out; } #endif diff --git a/test/test_decaf.cxx b/test/test_decaf.cxx index eb7eb5b..48718c0 100644 --- a/test/test_decaf.cxx +++ b/test/test_decaf.cxx @@ -208,7 +208,7 @@ static void test_elligator() { SecureBuffer *alts2[NHINTS]; bool successes2[NHINTS]; - for (int i=0; i