diff --git a/configure.ac b/configure.ac index bb4c61af..0e21bb31 100644 --- a/configure.ac +++ b/configure.ac @@ -506,6 +506,23 @@ __m512i y = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), [AC_MSG_RESULT(no)]) CFLAGS="$oldcflags" + oldcflags="$CFLAGS" + AX_CHECK_COMPILE_FLAG([-mrdrnd], [CFLAGS="$CFLAGS -mrdrnd"]) + AC_MSG_CHECKING(for RDRAND) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifdef __native_client__ +# error NativeClient detected - Avoiding RDRAND opcodes +#endif +#pragma GCC target("rdrnd") +#include +]], [[ unsigned long long x; _rdrand64_step(&x); ]])], + [AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_RDRAND], [1], [rdrand is available]) + AX_CHECK_COMPILE_FLAG([-mrdrnd], [CFLAGS_RDRAND="-mrdrnd"]) + ], + [AC_MSG_RESULT(no)]) + CFLAGS="$oldcflags" + ]) AC_SUBST(CFLAGS_MMX) @@ -518,6 +535,7 @@ AC_SUBST(CFLAGS_AVX2) AC_SUBST(CFLAGS_AVX512F) AC_SUBST(CFLAGS_AESNI) AC_SUBST(CFLAGS_PCLMUL) +AC_SUBST(CFLAGS_RDRAND) AC_CHECK_HEADERS([sys/mman.h intrin.h]) diff --git a/src/libsodium/Makefile.am b/src/libsodium/Makefile.am index eaea532d..58056911 100644 --- a/src/libsodium/Makefile.am +++ b/src/libsodium/Makefile.am @@ -94,20 +94,6 @@ libsodium_la_SOURCES = \ sodium/utils.c \ sodium/version.c -if !EMSCRIPTEN -libsodium_la_SOURCES += \ - randombytes/salsa20/randombytes_salsa20_random.c - -if NATIVECLIENT -libsodium_la_SOURCES += \ - randombytes/nativeclient/randombytes_nativeclient.c -else -libsodium_la_SOURCES += \ - randombytes/sysrandom/randombytes_sysrandom.c -endif - -endif - if HAVE_TI_MODE libsodium_la_SOURCES += \ crypto_core/ed25519/ref10/fe_51/base.h \ @@ -185,6 +171,8 @@ libsodium_la_SOURCES += \ crypto_stream/xchacha20/stream_xchacha20.c endif +randombytes_salsa20_randombytes_salsa20_random_CFLAGS = @CFLAGS_RDRAND@ + libsodium_la_LDFLAGS = \ $(AM_LDFLAGS) \ -export-dynamic \ @@ -208,7 +196,27 @@ SUBDIRS = \ include libsodium_la_LIBADD = libaesni.la libsse2.la libssse3.la libsse41.la libavx2.la libavx512f.la -noinst_LTLIBRARIES = libaesni.la libsse2.la libssse3.la libsse41.la libavx2.la libavx512f.la +noinst_LTLIBRARIES = libaesni.la libsse2.la libssse3.la libsse41.la libavx2.la libavx512f.la + +librdrand_la_LDFLAGS = $(libsodium_la_LDFLAGS) +librdrand_la_CPPFLAGS = $(libsodium_la_CPPFLAGS) \ + @CFLAGS_RDRAND@ +librdrand_la_SOURCES = \ + randombytes/salsa20/randombytes_salsa20_random.c + +if !EMSCRIPTEN +libsodium_la_LIBADD += librdrand.la +noinst_LTLIBRARIES += librdrand.la + +if NATIVECLIENT +libsodium_la_SOURCES += \ + randombytes/nativeclient/randombytes_nativeclient.c +else +libsodium_la_SOURCES += \ + randombytes/sysrandom/randombytes_sysrandom.c +endif + +endif libaesni_la_LDFLAGS = $(libsodium_la_LDFLAGS) libaesni_la_CPPFLAGS = $(libsodium_la_CPPFLAGS) \ diff --git a/src/libsodium/include/sodium/runtime.h b/src/libsodium/include/sodium/runtime.h index d35083d9..7f15d58e 100644 --- a/src/libsodium/include/sodium/runtime.h +++ b/src/libsodium/include/sodium/runtime.h @@ -38,6 +38,9 @@ int sodium_runtime_has_pclmul(void); SODIUM_EXPORT_WEAK int sodium_runtime_has_aesni(void); +SODIUM_EXPORT_WEAK +int sodium_runtime_has_rdrand(void); + /* ------------------------------------------------------------------------- */ int _sodium_runtime_get_cpu_features(void); diff --git a/src/libsodium/sodium/runtime.c b/src/libsodium/sodium/runtime.c index ec5d884f..ba1000f4 100644 --- a/src/libsodium/sodium/runtime.c +++ b/src/libsodium/sodium/runtime.c @@ -19,6 +19,7 @@ typedef struct CPUFeatures_ { int has_avx512f; int has_pclmul; int has_aesni; + int has_rdrand; } CPUFeatures; static CPUFeatures _cpu_features; @@ -34,6 +35,7 @@ static CPUFeatures _cpu_features; #define CPUID_ECX_XSAVE 0x04000000 #define CPUID_ECX_OSXSAVE 0x08000000 #define CPUID_ECX_AVX 0x10000000 +#define CPUID_ECX_RDRAND 0x40000000 #define CPUID_EDX_SSE2 0x04000000 @@ -196,6 +198,12 @@ _sodium_runtime_intel_cpu_features(CPUFeatures * const cpu_features) cpu_features->has_aesni = 0; #endif +#ifdef HAVE_RDRAND + cpu_features->has_rdrand = ((cpu_info[2] & CPUID_ECX_RDRAND) != 0x0); +#else + cpu_features->has_rdrand = 0; +#endif + return 0; } @@ -270,3 +278,9 @@ sodium_runtime_has_aesni(void) { return _cpu_features.has_aesni; } + +int +sodium_runtime_has_rdrand(void) +{ + return _cpu_features.has_rdrand; +} diff --git a/test/default/sodium_core.c b/test/default/sodium_core.c index d8d368d6..a3985b0e 100644 --- a/test/default/sodium_core.c +++ b/test/default/sodium_core.c @@ -28,6 +28,7 @@ main(void) (void) sodium_runtime_has_avx512f(); (void) sodium_runtime_has_pclmul(); (void) sodium_runtime_has_aesni(); + (void) sodium_runtime_has_rdrand(); sodium_set_misuse_handler(misuse_handler); #ifndef __EMSCRIPTEN__