Commit c558c0ec authored by Andrew Bennett's avatar Andrew Bennett Committed by Michael Hamburg

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
parent e22c9671
......@@ -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 $@
......
/* 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 <endian.h>
#elif defined(__OpenBSD__)
# include <sys/endian.h>
#elif defined(__APPLE__)
# include <libkern/OSByteOrder.h>
# define htole64(x) OSSwapHostToLittleInt64(x)
# define le64toh(x) OSSwapLittleToHostInt64(x)
#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
# include <sys/endian.h>
# define le64toh(x) letoh64(x)
#elif defined(__sun) && defined(__SVR4)
# include <sys/byteorder.h>
# define htole64(x) LE_64(x)
# define le64toh(x) LE_64(x)
#elif defined(_WIN16) || defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__)
# include <winsock2.h>
# include <sys/param.h>
# 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__
......@@ -9,6 +9,9 @@
#define _XOPEN_SOURCE 600
#define __STDC_WANT_LIB_EXT1__ 1 /* for memset_s */
#include <string.h>
#if defined(__sun) && defined(__SVR4)
extern int posix_memalign(void **, size_t, size_t);
#endif
#include <assert.h>
#include <stdint.h>
......@@ -16,13 +19,11 @@
#include <decaf/common.h>
#ifndef __APPLE__
#ifndef _BSD_SOURCE
#define _BSD_SOURCE 1
#endif
#include <endian.h>
#endif
#include "portable_endian.h"
#include <stdlib.h>
#include <sys/types.h>
......@@ -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.
......
......@@ -23,33 +23,7 @@
#include <fcntl.h>
#include <unistd.h>
/* Subset of Mathias Panzenböck's portable endian code, public domain */
#if defined(__linux__) || defined(__CYGWIN__)
# include <endian.h>
#elif defined(__OpenBSD__)
# include <sys/endian.h>
#elif defined(__APPLE__)
# include <libkern/OSByteOrder.h>
# define htole64(x) OSSwapHostToLittleInt64(x)
# define le64toh(x) OSSwapLittleToHostInt64(x)
#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
# include <sys/endian.h>
# define le64toh(x) letoh64(x)
#elif defined(_WIN16) || defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__)
# include <winsock2.h>
# include <sys/param.h>
# 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
......
......@@ -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
......
......@@ -208,7 +208,7 @@ static void test_elligator() {
SecureBuffer *alts2[NHINTS];
bool successes2[NHINTS];
for (int i=0; i<NTESTS/10 && (i<10 || test.passing_now); i++) {
for (unsigned int i=0; i<NTESTS/10 && (i<10 || test.passing_now); i++) {
size_t len = (i % (2*Point::HASH_BYTES + 3));
SecureBuffer b1(len);
if (i!=Point::HASH_BYTES) rng.read(b1); /* special test case */
......@@ -222,7 +222,7 @@ static void test_elligator() {
Point s = Point::from_hash(b1), ss=s;
for (int j=0; j<(i&3); j++) ss = ss.debugging_torque();
for (unsigned int j=0; j<(i&3); j++) ss = ss.debugging_torque();
ss = ss.debugging_pscale(rng);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment