Add --disable-asm option to disable assembly implementations.

Check that fesetenv() and fegetenv() are available. If they aren't, still
compile the floating-point implementation of poly1305, but never pick it
in sodium_init().

This helps libsodium compile and work on Emscripten and on environments with
an incomplete libc.
This commit is contained in:
Frank Denis 2013-04-28 09:41:00 -07:00
parent 942c371d3c
commit 210de1570a
3 changed files with 49 additions and 9 deletions

View File

@ -179,6 +179,20 @@ AC_CHECK_HEADERS([wmmintrin.h], [], [], [
#pragma GCC target("aes") #pragma GCC target("aes")
]) ])
AC_MSG_CHECKING(for access to floating-point rounding mode)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <fenv.h>
#pragma STDC FENV_ACCESS ON
]], [[
const int previous_rounding_mode = fegetround();
fesetround(FE_TONEAREST);
fesetround(previous_rounding_mode);
]])],
[AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_FENV_H], [1], [floating-point rounding mode is accessible])
],
[AC_MSG_RESULT(no)])
dnl Checks for typedefs, structures, and compiler characteristics. dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_BIGENDIAN( AC_C_BIGENDIAN(
@ -201,10 +215,11 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
CPPFLAGS="$CPPFLAGS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS" CPPFLAGS="$CPPFLAGS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS"
]) ])
AC_MSG_CHECKING(whether we can assemble basic amd64 code)
HAVE_AMD64_ASM_V=0 HAVE_AMD64_ASM_V=0
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ AS_IF([test "$enable_asm" != "no"],[
]], [[ AC_MSG_CHECKING(whether we can assemble basic amd64 code)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
]], [[
#if defined(__amd64) || defined(__amd64__) || defined(__x86_64__) #if defined(__amd64) || defined(__amd64__) || defined(__x86_64__)
/* neat */ /* neat */
#else #else
@ -212,10 +227,11 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#endif #endif
__asm__("pxor %xmm12,%xmm6"); __asm__("pxor %xmm12,%xmm6");
]])], ]])],
[AC_MSG_RESULT(yes) [AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_AMD64_ASM], [1], [basic amd64 code can be assembled]) AC_DEFINE([HAVE_AMD64_ASM], [1], [basic amd64 code can be assembled])
HAVE_AMD64_ASM_V=1], HAVE_AMD64_ASM_V=1],
[AC_MSG_RESULT(no)]) [AC_MSG_RESULT(no)])
])
AM_CONDITIONAL([HAVE_AMD64_ASM], [test $HAVE_AMD64_ASM_V = 1]) AM_CONDITIONAL([HAVE_AMD64_ASM], [test $HAVE_AMD64_ASM_V = 1])
AC_SUBST(HAVE_AMD64_ASM_V) AC_SUBST(HAVE_AMD64_ASM_V)
@ -267,6 +283,19 @@ AC_ARG_ENABLE(pie,
[AS_HELP_STRING(--enable-pie,Produce position independent executables @<:@default=yes@:>@)], [AS_HELP_STRING(--enable-pie,Produce position independent executables @<:@default=yes@:>@)],
enable_pie=$enableval, enable_pie="maybe") enable_pie=$enableval, enable_pie="maybe")
AC_ARG_ENABLE(asm,
[AS_HELP_STRING(--disable-asm,Disable assembly implementations)],
[
AS_IF([test "x$enableval" = "xno"], [
enable_asm="no"
], [
enable_asm="yes"
])
],
[
enable_asm="yes"
])
AC_ARG_ENABLE(ssp, AC_ARG_ENABLE(ssp,
[AS_HELP_STRING(--disable-ssp,Don't compile with -fstack-protector)], [AS_HELP_STRING(--disable-ssp,Don't compile with -fstack-protector)],
[AS_IF([test "x$enableval" = "xno"], [ [AS_IF([test "x$enableval" = "xno"], [

View File

@ -4,7 +4,9 @@ D. J. Bernstein
Public domain. Public domain.
*/ */
#include <fenv.h> #ifdef HAVE_FENV_H
# include <fenv.h>
#endif
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
@ -12,7 +14,9 @@ Public domain.
#include "crypto_onetimeauth_poly1305_53.h" #include "crypto_onetimeauth_poly1305_53.h"
#include "utils.h" #include "utils.h"
#pragma STDC FENV_ACCESS ON #ifdef HAVE_FENV_H
# pragma STDC FENV_ACCESS ON
#endif
typedef uint8_t uchar; typedef uint8_t uchar;
typedef int32_t int32; typedef int32_t int32;
@ -238,12 +242,14 @@ int crypto_onetimeauth(unsigned char *out,const unsigned char *m,unsigned long l
register uint64 g3; register uint64 g3;
register uint64 g4; register uint64 g4;
#ifdef HAVE_FENV_H
const int previous_rounding_mode = fegetround(); const int previous_rounding_mode = fegetround();
if (previous_rounding_mode != FE_TONEAREST) { if (previous_rounding_mode != FE_TONEAREST) {
if (fesetround(FE_TONEAREST) != 0) { if (fesetround(FE_TONEAREST) != 0) {
return -1; return -1;
} }
} }
#endif
r00 = *(uchar *) (r + 0); r00 = *(uchar *) (r + 0);
constants = (char *) &poly1305_53_constants; constants = (char *) &poly1305_53_constants;
@ -1627,10 +1633,13 @@ nomorebytes:;
f3 >>= 8; f3 >>= 8;
*(uchar *) (out + 15) = f3; *(uchar *) (out + 15) = f3;
#ifdef HAVE_FENV_H
if (previous_rounding_mode != FE_TONEAREST && if (previous_rounding_mode != FE_TONEAREST &&
fesetround(previous_rounding_mode) != 0) { fesetround(previous_rounding_mode) != 0) {
abort(); abort();
} }
#endif
return 0; return 0;
} }

View File

@ -123,7 +123,9 @@ crypto_onetimeauth_poly1305_implementation *
crypto_onetimeauth_pick_best_implementation(void) crypto_onetimeauth_pick_best_implementation(void)
{ {
crypto_onetimeauth_poly1305_implementation *implementations[] = { crypto_onetimeauth_poly1305_implementation *implementations[] = {
#ifdef HAVE_FENV_H
&crypto_onetimeauth_poly1305_53_implementation, &crypto_onetimeauth_poly1305_53_implementation,
#endif
&crypto_onetimeauth_poly1305_ref_implementation, &crypto_onetimeauth_poly1305_ref_implementation,
NULL NULL
}; };