diff --git a/CMakeLists.txt b/CMakeLists.txt index 06e0f568..5412a374 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -187,6 +187,8 @@ set(demos demo_zuc ) +include(CheckSymbolExists) + # when an option has been enabled, `cmake ..` will not refresh the value # use `cmake .. -DENABLE_XXX=OFF` to disable the option @@ -254,16 +256,29 @@ endif() option(ENABLE_INTEL_RDRAND "Enable Intel RDRAND instructions" OFF) option(ENABLE_INTEL_RDSEED "Enable Intel RDSEED instructions" OFF) -if (${CMAKE_SYSTEM_PROCESSOR} MATCHES x86_64) - set(ENABLE_INTEL_RDRAND ON) -endif() + if (ENABLE_INTEL_RDRAND) - message(STATUS "ENABLE_INTEL_RDRAND") - list(APPEND src src/rdrand.c) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mrdrnd") + include(CheckSourceCompiles) + set(CMAKE_REQUIRED_FLAGS "-rdrand") + check_source_compiles(C + "#include int main(void) { unsigned long long val; _rdrand64_step(&val); return 0; }" + HAVE_INTEL_RDRAND) + if (HAVE_INTEL_RDRAND) + message(STATUS "ENABLE_INTEL_RDRAND") + add_definitions(-DINTEL_RDRAND) + list(APPEND src src/rdrand.c) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mrdrnd") + endif() if (ENABLE_INTEL_RDSEED) - add_definitions(-DINTEL_RDSEED) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mrdseed") + set(CMAKE_REQUIRED_FLAGS "-rdseed") + check_source_compiles(C + "#include int main(void) { unsigned long long val; _rdseed64_step(&val); return 0; }" + HAVE_INTEL_RDSEED) + if (HAVE_INTEL_RDSEED) + message(STATUS "ENABLE_INTEL_RDSEED") + add_definitions(-DINTEL_RDSEED) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mrdseed") + endif() endif() endif() @@ -275,16 +290,20 @@ if (ENABLE_GMT_0105_RNG) list(APPEND tests sm3_rng sm4_cbc_mac sm4_rng) endif() + +check_symbol_exists(getentropy "unistd.h" HAVE_GETENTROPY) if (WIN32) list(APPEND src src/rand_win.c src/http_win.c) elseif (APPLE) list(APPEND src src/rand_apple.c src/http.c) -elseif (ANDROID) - list(APPEND src src/rand.c src/http.c) -else() +elseif (HAVE_GETENTROPY) list(APPEND src src/rand_unix.c src/http.c) + message(STATUS "have getentropy") +else() + list(APPEND src src/rand.c src/http.c) endif() + option(ENABLE_HTTP_TESTS "Enable HTTP GET/POST related tests" OFF) if (ENABLE_HTTP_TESTS) message(STATUS "ENABLE_HTTP_TESTS") diff --git a/tools/rand.c b/tools/rand.c index 07af527d..b71610b5 100644 --- a/tools/rand.c +++ b/tools/rand.c @@ -17,7 +17,7 @@ #include -static const char *options = "[-hex] [-rdrand] -outlen num [-out file]"; +static const char *options = "[-hex] [-rdrand|-rdseed] -outlen num [-out file]"; int rand_main(int argc, char **argv) { @@ -25,6 +25,7 @@ int rand_main(int argc, char **argv) char *prog = argv[0]; int hex = 0; int rdrand = 0; + int rdseed = 0; int outlen = 0; char *outfile = NULL; FILE *outfp = stdout; @@ -47,6 +48,8 @@ int rand_main(int argc, char **argv) hex = 1; } else if (!strcmp(*argv, "-rdrand")) { rdrand = 1; + } else if (!strcmp(*argv, "-rdseed")) { + rdseed = 1; } else if (!strcmp(*argv, "-outlen")) { if (--argc < 1) goto bad; outlen = atoi(*(++argv)); @@ -82,12 +85,23 @@ bad: size_t len = outlen < sizeof(buf) ? outlen : sizeof(buf); if (rdrand) { -/* +#ifdef INTEL_RDRAND if (rdrand_bytes(buf, len) != 1) { fprintf(stderr, "%s: inner error\n", prog); goto end; } -*/ +#else + fprintf(stderr, "%s: `-rdrand` is not supported on your platform\n", prog); +#endif + } else if (rdseed) { +#ifdef INTEL_RDSEED + if (rdseed_bytes(buf, len) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } +#else + fprintf(stderr, "%s: `-rdseed` is not supported on your platform\n", prog); +#endif } else { if (rand_bytes(buf, len) != 1) { fprintf(stderr, "%s: inner error\n", prog);