From 7784104dd8719c78a0d25eb729d876477d6d406e Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Fri, 14 Apr 2017 11:16:20 -0700 Subject: [PATCH] Move much of rand/ into the FIPS module. Support for platforms that we don't support FIPS on doesn't need to be in the module. Also, functions for dealing with whether fork-unsafe buffering is enabled are left out because they aren't implementing any cryptography and they use global r/w state, making their inclusion painful. Change-Id: I71a0123db6f5449e9dfc7ec7dea0944428e661aa Reviewed-on: https://boringssl-review.googlesource.com/15084 Reviewed-by: Adam Langley --- crypto/CMakeLists.txt | 6 +- crypto/bn/random.c | 2 +- crypto/fipsmodule/CMakeLists.txt | 13 ++ crypto/fipsmodule/bcm.c | 11 +- crypto/fipsmodule/delocate.h | 17 ++- .../rand/asm/rdrand-x86_64.pl | 2 +- crypto/{ => fipsmodule}/rand/ctrdrbg.c | 2 +- crypto/{ => fipsmodule}/rand/ctrdrbg_test.cc | 2 +- .../rand/ctrdrbg_vector_test.cc | 4 +- .../{ => fipsmodule}/rand/ctrdrbg_vectors.txt | 0 crypto/{ => fipsmodule}/rand/internal.h | 4 +- crypto/{ => fipsmodule}/rand/rand.c | 52 +------- crypto/{ => fipsmodule}/rand/urandom.c | 112 ++++++++++++------ crypto/rand/CMakeLists.txt | 38 ------ crypto/rand_extra/CMakeLists.txt | 12 ++ crypto/{rand => rand_extra}/deterministic.c | 2 +- crypto/{rand => rand_extra}/forkunsafe.c | 2 +- crypto/{rand => rand_extra}/fuchsia.c | 2 +- crypto/rand_extra/rand_extra.c | 68 +++++++++++ crypto/{rand => rand_extra}/windows.c | 2 +- crypto/thread_test.c | 14 ++- util/all_tests.json | 2 +- 22 files changed, 219 insertions(+), 150 deletions(-) rename crypto/{ => fipsmodule}/rand/asm/rdrand-x86_64.pl (97%) rename crypto/{ => fipsmodule}/rand/ctrdrbg.c (99%) rename crypto/{ => fipsmodule}/rand/ctrdrbg_test.cc (98%) rename crypto/{ => fipsmodule}/rand/ctrdrbg_vector_test.cc (97%) rename crypto/{ => fipsmodule}/rand/ctrdrbg_vectors.txt (100%) rename crypto/{ => fipsmodule}/rand/internal.h (98%) rename crypto/{ => fipsmodule}/rand/rand.c (89%) rename crypto/{ => fipsmodule}/rand/urandom.c (67%) delete mode 100644 crypto/rand/CMakeLists.txt create mode 100644 crypto/rand_extra/CMakeLists.txt rename crypto/{rand => rand_extra}/deterministic.c (97%) rename crypto/{rand => rand_extra}/forkunsafe.c (97%) rename crypto/{rand => rand_extra}/fuchsia.c (97%) create mode 100644 crypto/rand_extra/rand_extra.c rename crypto/{rand => rand_extra}/windows.c (97%) diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt index 6991ac9e..be36c4b9 100644 --- a/crypto/CMakeLists.txt +++ b/crypto/CMakeLists.txt @@ -90,7 +90,7 @@ add_subdirectory(curve25519) # Level 1, depends only on 0.* add_subdirectory(digest_extra) add_subdirectory(cipher) -add_subdirectory(rand) +add_subdirectory(rand_extra) add_subdirectory(bio) add_subdirectory(bn) add_subdirectory(obj) @@ -177,7 +177,7 @@ add_library( $ $ $ - $ + $ $ $ $ @@ -245,7 +245,7 @@ add_executable( ec/ec_test.cc err/err_test.cc evp/evp_extra_test.cc - rand/ctrdrbg_test.cc + fipsmodule/rand/ctrdrbg_test.cc rsa/rsa_test.cc $ diff --git a/crypto/bn/random.c b/crypto/bn/random.c index 55eca80f..4b3da752 100644 --- a/crypto/bn/random.c +++ b/crypto/bn/random.c @@ -117,7 +117,7 @@ #include #include "../internal.h" -#include "../rand/internal.h" +#include "../fipsmodule/rand/internal.h" static const uint8_t kZeroAdditionalData[32] = {0}; diff --git a/crypto/fipsmodule/CMakeLists.txt b/crypto/fipsmodule/CMakeLists.txt index 375a3db6..4c20218d 100644 --- a/crypto/fipsmodule/CMakeLists.txt +++ b/crypto/fipsmodule/CMakeLists.txt @@ -14,6 +14,7 @@ if (${ARCH} STREQUAL "x86_64") vpaes-x86_64.${ASM_EXT} aesni-gcm-x86_64.${ASM_EXT} ghash-x86_64.${ASM_EXT} + rdrand-x86_64.${ASM_EXT} ) endif() @@ -85,6 +86,7 @@ perlasm(ghash-x86_64.${ASM_EXT} modes/asm/ghash-x86_64.pl) perlasm(ghash-x86.${ASM_EXT} modes/asm/ghash-x86.pl) perlasm(md5-586.${ASM_EXT} md5/asm/md5-586.pl) perlasm(md5-x86_64.${ASM_EXT} md5/asm/md5-x86_64.pl) +perlasm(rdrand-x86_64.${ASM_EXT} rand/asm/rdrand-x86_64.pl) perlasm(sha1-586.${ASM_EXT} sha/asm/sha1-586.pl) perlasm(sha1-armv4-large.${ASM_EXT} sha/asm/sha1-armv4-large.pl) perlasm(sha1-armv8.${ASM_EXT} sha/asm/sha1-armv8.pl) @@ -198,3 +200,14 @@ add_executable( target_link_libraries(gcm_test crypto) add_dependencies(all_tests gcm_test) + +add_executable( + ctrdrbg_vector_test + + rand/ctrdrbg_vector_test.cc + + $ +) + +target_link_libraries(ctrdrbg_vector_test crypto) +add_dependencies(all_tests ctrdrbg_vector_test) diff --git a/crypto/fipsmodule/bcm.c b/crypto/fipsmodule/bcm.c index b93ab834..e90f0a4e 100644 --- a/crypto/fipsmodule/bcm.c +++ b/crypto/fipsmodule/bcm.c @@ -12,6 +12,10 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#if !defined(_GNU_SOURCE) +#define _GNU_SOURCE /* needed for syscall() on Linux. */ +#endif + #include #include #include @@ -19,13 +23,13 @@ #include #include #include -#include #include +#include #include #include #include "../internal.h" -#include "../rand/internal.h" +#include "rand/internal.h" #include "aes/aes.c" #include "aes/key_wrap.c" @@ -41,6 +45,9 @@ #include "modes/gcm.c" #include "modes/ofb.c" #include "modes/polyval.c" +#include "rand/ctrdrbg.c" +#include "rand/rand.c" +#include "rand/urandom.c" #include "sha/sha1-altivec.c" #include "sha/sha1.c" #include "sha/sha256.c" diff --git a/crypto/fipsmodule/delocate.h b/crypto/fipsmodule/delocate.h index 676073c3..f4ee3c8a 100644 --- a/crypto/fipsmodule/delocate.h +++ b/crypto/fipsmodule/delocate.h @@ -21,13 +21,24 @@ #if defined(BORINGSSL_FIPS) -#define DEFINE_BSS_GET(type, name) \ +#define DEFINE_BSS_GET(type, name) \ static type name __attribute__((used)); \ type *name##_bss_get(void); +/* For FIPS builds we require that CRYPTO_ONCE_INIT be zero. */ +#define DEFINE_STATIC_ONCE(name) DEFINE_BSS_GET(CRYPTO_once_t, name) +/* For FIPS builds we require that CRYPTO_STATIC_MUTEX_INIT be zero. */ +#define DEFINE_STATIC_MUTEX(name) \ + DEFINE_BSS_GET(struct CRYPTO_STATIC_MUTEX, name) #else #define DEFINE_BSS_GET(type, name) \ - static type name; \ + static type name; \ static type *name##_bss_get(void) { return &name; } +#define DEFINE_STATIC_ONCE(name) \ + static CRYPTO_once_t name = CRYPTO_ONCE_INIT; \ + static CRYPTO_once_t *name##_bss_get(void) { return &name; } +#define DEFINE_STATIC_MUTEX(name) \ + static struct CRYPTO_STATIC_MUTEX name = CRYPTO_STATIC_MUTEX_INIT; \ + static struct CRYPTO_STATIC_MUTEX *name##_bss_get(void) { return &name; } #endif /* DEFINE_METHOD_FUNCTION defines a function named |name| which returns a @@ -53,7 +64,7 @@ * order is undefined. See FIPS.md for more details. */ #define DEFINE_METHOD_FUNCTION(type, name) \ DEFINE_BSS_GET(type, name##_storage) \ - DEFINE_BSS_GET(CRYPTO_once_t, name##_once) \ + DEFINE_STATIC_ONCE(name##_once) \ static void name##_do_init(type *out); \ static void name##_init(void) { name##_do_init(name##_storage_bss_get()); } \ const type *name(void) { \ diff --git a/crypto/rand/asm/rdrand-x86_64.pl b/crypto/fipsmodule/rand/asm/rdrand-x86_64.pl similarity index 97% rename from crypto/rand/asm/rdrand-x86_64.pl rename to crypto/fipsmodule/rand/asm/rdrand-x86_64.pl index c32a55c4..3583d4ce 100644 --- a/crypto/rand/asm/rdrand-x86_64.pl +++ b/crypto/fipsmodule/rand/asm/rdrand-x86_64.pl @@ -19,7 +19,7 @@ $output = shift; if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; -( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +( $xlate="${dir}../../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; open OUT,"| \"$^X\" $xlate $flavour $output"; diff --git a/crypto/rand/ctrdrbg.c b/crypto/fipsmodule/rand/ctrdrbg.c similarity index 99% rename from crypto/rand/ctrdrbg.c rename to crypto/fipsmodule/rand/ctrdrbg.c index 2b22f5d9..5920837b 100644 --- a/crypto/rand/ctrdrbg.c +++ b/crypto/fipsmodule/rand/ctrdrbg.c @@ -18,7 +18,7 @@ #include #include "internal.h" -#include "../cipher/internal.h" +#include "../../cipher/internal.h" /* Section references in this file refer to SP 800-90Ar1: diff --git a/crypto/rand/ctrdrbg_test.cc b/crypto/fipsmodule/rand/ctrdrbg_test.cc similarity index 98% rename from crypto/rand/ctrdrbg_test.cc rename to crypto/fipsmodule/rand/ctrdrbg_test.cc index 2ff1027a..a35e6b08 100644 --- a/crypto/rand/ctrdrbg_test.cc +++ b/crypto/fipsmodule/rand/ctrdrbg_test.cc @@ -18,7 +18,7 @@ #include #include "internal.h" -#include "../test/test_util.h" +#include "../../test/test_util.h" TEST(CTRDRBGTest, Basic) { diff --git a/crypto/rand/ctrdrbg_vector_test.cc b/crypto/fipsmodule/rand/ctrdrbg_vector_test.cc similarity index 97% rename from crypto/rand/ctrdrbg_vector_test.cc rename to crypto/fipsmodule/rand/ctrdrbg_vector_test.cc index 7c938615..4680e6e6 100644 --- a/crypto/rand/ctrdrbg_vector_test.cc +++ b/crypto/fipsmodule/rand/ctrdrbg_vector_test.cc @@ -17,8 +17,8 @@ #include #include "internal.h" -#include "../test/test_util.h" -#include "../test/file_test.h" +#include "../../test/test_util.h" +#include "../../test/file_test.h" static bool TestCTRDRBG(FileTest *t, void *arg) { diff --git a/crypto/rand/ctrdrbg_vectors.txt b/crypto/fipsmodule/rand/ctrdrbg_vectors.txt similarity index 100% rename from crypto/rand/ctrdrbg_vectors.txt rename to crypto/fipsmodule/rand/ctrdrbg_vectors.txt diff --git a/crypto/rand/internal.h b/crypto/fipsmodule/rand/internal.h similarity index 98% rename from crypto/rand/internal.h rename to crypto/fipsmodule/rand/internal.h index 349daf07..f569c382 100644 --- a/crypto/rand/internal.h +++ b/crypto/fipsmodule/rand/internal.h @@ -17,8 +17,8 @@ #include -#include "../internal.h" -#include "../fipsmodule/modes/internal.h" +#include "../../internal.h" +#include "../modes/internal.h" #if defined(__cplusplus) extern "C" { diff --git a/crypto/rand/rand.c b/crypto/fipsmodule/rand/rand.c similarity index 89% rename from crypto/rand/rand.c rename to crypto/fipsmodule/rand/rand.c index 028979a9..e42ad461 100644 --- a/crypto/rand/rand.c +++ b/crypto/fipsmodule/rand/rand.c @@ -23,7 +23,7 @@ #include #include "internal.h" -#include "../internal.h" +#include "../../internal.h" /* It's assumed that the operating system always has an unfailing source of @@ -261,53 +261,3 @@ int RAND_bytes(uint8_t *out, size_t out_len) { int RAND_pseudo_bytes(uint8_t *buf, size_t len) { return RAND_bytes(buf, len); } - -void RAND_seed(const void *buf, int num) { - /* OpenSSH calls |RAND_seed| before jailing on the assumption that any needed - * file descriptors etc will be opened. */ - uint8_t unused; - RAND_bytes(&unused, sizeof(unused)); -} - -int RAND_load_file(const char *path, long num) { - if (num < 0) { /* read the "whole file" */ - return 1; - } else if (num <= INT_MAX) { - return (int) num; - } else { - return INT_MAX; - } -} - -const char *RAND_file_name(char *buf, size_t num) { return NULL; } - -void RAND_add(const void *buf, int num, double entropy) {} - -int RAND_egd(const char *path) { - return 255; -} - -int RAND_poll(void) { - return 1; -} - -int RAND_status(void) { - return 1; -} - -static const struct rand_meth_st kSSLeayMethod = { - RAND_seed, - RAND_bytes, - RAND_cleanup, - RAND_add, - RAND_pseudo_bytes, - RAND_status, -}; - -RAND_METHOD *RAND_SSLeay(void) { - return (RAND_METHOD*) &kSSLeayMethod; -} - -void RAND_set_rand_method(const RAND_METHOD *method) {} - -void RAND_cleanup(void) {} diff --git a/crypto/rand/urandom.c b/crypto/fipsmodule/rand/urandom.c similarity index 67% rename from crypto/rand/urandom.c rename to crypto/fipsmodule/rand/urandom.c index f3aab448..474c4bcd 100644 --- a/crypto/rand/urandom.c +++ b/crypto/fipsmodule/rand/urandom.c @@ -12,10 +12,6 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#if !defined(_GNU_SOURCE) -#define _GNU_SOURCE /* needed for syscall() on Linux. */ -#endif - #include #if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_FUCHSIA) && \ @@ -38,7 +34,8 @@ #include #include "internal.h" -#include "../internal.h" +#include "../delocate.h" +#include "../../internal.h" #if defined(OPENSSL_LINUX) @@ -78,30 +75,42 @@ #endif /* OPENSSL_LINUX */ -/* requested_lock is used to protect the |*_requested| variables. */ -static struct CRYPTO_STATIC_MUTEX requested_lock = CRYPTO_STATIC_MUTEX_INIT; +/* rand_lock is used to protect the |*_requested| variables. */ +DEFINE_STATIC_MUTEX(rand_lock); /* The following constants are magic values of |urandom_fd|. */ -static const int kUnset = -2; +static const int kUnset = 0; static const int kHaveGetrandom = -3; /* urandom_fd_requested is set by |RAND_set_urandom_fd|. It's protected by - * |requested_lock|. */ -static int urandom_fd_requested = -2 /* kUnset */; + * |rand_lock|. */ +DEFINE_BSS_GET(int, urandom_fd_requested); /* urandom_fd is a file descriptor to /dev/urandom. It's protected by |once|. */ -static int urandom_fd = -2 /* kUnset */; +DEFINE_BSS_GET(int, urandom_fd); -static CRYPTO_once_t once = CRYPTO_ONCE_INIT; +DEFINE_STATIC_ONCE(rand_once); + +#if defined(USE_SYS_getrandom) || defined(BORINGSSL_FIPS) +/* message writes |msg| to stderr. We use this because referencing |stderr| + * with |fprintf| generates relocations, which is a problem inside the FIPS + * module. */ +static void message(const char *msg) { + ssize_t r; + do { + r = write(2, msg, strlen(msg)); + } while (r == -1 && errno == EINTR); +} +#endif /* init_once initializes the state of this module to values previously * requested. This is the only function that modifies |urandom_fd| and * |urandom_buffering|, whose values may be read safely after calling the * once. */ static void init_once(void) { - CRYPTO_STATIC_MUTEX_lock_read(&requested_lock); - int fd = urandom_fd_requested; - CRYPTO_STATIC_MUTEX_unlock_read(&requested_lock); + CRYPTO_STATIC_MUTEX_lock_read(rand_lock_bss_get()); + int fd = *urandom_fd_requested_bss_get(); + CRYPTO_STATIC_MUTEX_unlock_read(rand_lock_bss_get()); #if defined(USE_SYS_getrandom) uint8_t dummy; @@ -109,20 +118,21 @@ static void init_once(void) { syscall(SYS_getrandom, &dummy, sizeof(dummy), GRND_NONBLOCK); if (getrandom_ret == 1) { - urandom_fd = kHaveGetrandom; + *urandom_fd_bss_get() = kHaveGetrandom; return; } else if (getrandom_ret == -1 && errno == EAGAIN) { - fprintf(stderr, - "getrandom indicates that the entropy pool has not been " - "initialized. Rather than continue with poor entropy, this process " - "will block until entropy is available.\n"); + message( + "getrandom indicates that the entropy pool has not been initialized. " + "Rather than continue with poor entropy, this process will block until " + "entropy is available.\n"); + do { getrandom_ret = syscall(SYS_getrandom, &dummy, sizeof(dummy), 0 /* no flags */); } while (getrandom_ret == -1 && errno == EINTR); if (getrandom_ret == 1) { - urandom_fd = kHaveGetrandom; + *urandom_fd_bss_get() = kHaveGetrandom; return; } } @@ -138,6 +148,19 @@ static void init_once(void) { abort(); } + assert(kUnset == 0); + if (fd == kUnset) { + /* Because we want to keep |urandom_fd| in the BSS, we have to initialise + * it to zero. But zero is a valid file descriptor too. Thus if open + * returns zero for /dev/urandom, we dup it to get a non-zero number. */ + fd = dup(fd); + close(kUnset); + + if (fd <= 0) { + abort(); + } + } + #if defined(BORINGSSL_FIPS) /* In FIPS mode we ensure that the kernel has sufficient entropy before * continuing. This is automatically handled by getrandom, which requires @@ -147,9 +170,9 @@ static void init_once(void) { for (;;) { int entropy_bits; if (ioctl(fd, RNDGETENTCNT, &entropy_bits)) { - fprintf(stderr, - "RNDGETENTCNT on /dev/urandom failed. We cannot continue in this " - "case when in FIPS mode.\n"); + message( + "RNDGETENTCNT on /dev/urandom failed. We cannot continue in this " + "case when in FIPS mode.\n"); abort(); } @@ -159,10 +182,10 @@ static void init_once(void) { } if (first_iteration) { - fprintf(stderr, - "The kernel entropy pool contains too few bits: have %d, want " - "%d. This process is built in FIPS mode and will block until " - "sufficient entropy is available.\n", entropy_bits, kBitsNeeded); + message( + "The kernel entropy pool contains too few bits. This process is " + "built in FIPS mode and will block until sufficient entropy is " + "available.\n"); } first_iteration = 0; @@ -182,7 +205,7 @@ static void init_once(void) { abort(); } } - urandom_fd = fd; + *urandom_fd_bss_get() = fd; } void RAND_set_urandom_fd(int fd) { @@ -191,14 +214,27 @@ void RAND_set_urandom_fd(int fd) { abort(); } - CRYPTO_STATIC_MUTEX_lock_write(&requested_lock); - urandom_fd_requested = fd; - CRYPTO_STATIC_MUTEX_unlock_write(&requested_lock); + assert(kUnset == 0); + if (fd == kUnset) { + /* Because we want to keep |urandom_fd| in the BSS, we have to initialise + * it to zero. But zero is a valid file descriptor too. Thus if dup + * returned zero we dup it again to get a non-zero number. */ + fd = dup(fd); + close(kUnset); - CRYPTO_once(&once, init_once); - if (urandom_fd == kHaveGetrandom) { + if (fd <= 0) { + abort(); + } + } + + CRYPTO_STATIC_MUTEX_lock_write(rand_lock_bss_get()); + *urandom_fd_requested_bss_get() = fd; + CRYPTO_STATIC_MUTEX_unlock_write(rand_lock_bss_get()); + + CRYPTO_once(rand_once_bss_get(), init_once); + if (*urandom_fd_bss_get() == kHaveGetrandom) { close(fd); - } else if (urandom_fd != fd) { + } else if (*urandom_fd_bss_get() != fd) { abort(); // Already initialized. } } @@ -215,7 +251,7 @@ static char fill_with_entropy(uint8_t *out, size_t len) { while (len > 0) { ssize_t r; - if (urandom_fd == kHaveGetrandom) { + if (*urandom_fd_bss_get() == kHaveGetrandom) { #if defined(USE_SYS_getrandom) do { r = syscall(SYS_getrandom, out, len, 0 /* no flags */); @@ -236,7 +272,7 @@ static char fill_with_entropy(uint8_t *out, size_t len) { #endif } else { do { - r = read(urandom_fd, out, len); + r = read(*urandom_fd_bss_get(), out, len); } while (r == -1 && errno == EINTR); } @@ -256,7 +292,7 @@ void CRYPTO_sysrand(uint8_t *out, size_t requested) { return; } - CRYPTO_once(&once, init_once); + CRYPTO_once(rand_once_bss_get(), init_once); if (!fill_with_entropy(out, requested)) { abort(); diff --git a/crypto/rand/CMakeLists.txt b/crypto/rand/CMakeLists.txt deleted file mode 100644 index c2b1fda1..00000000 --- a/crypto/rand/CMakeLists.txt +++ /dev/null @@ -1,38 +0,0 @@ -include_directories(../../include) - -if (${ARCH} STREQUAL "x86_64") - set( - RAND_ARCH_SOURCES - - rdrand-x86_64.${ASM_EXT} - ) -endif() - -add_library( - rand - - OBJECT - - ctrdrbg.c - deterministic.c - forkunsafe.c - fuchsia.c - rand.c - urandom.c - windows.c - - ${RAND_ARCH_SOURCES} -) - -perlasm(rdrand-x86_64.${ASM_EXT} asm/rdrand-x86_64.pl) - -add_executable( - ctrdrbg_vector_test - - ctrdrbg_vector_test.cc - - $ -) - -target_link_libraries(ctrdrbg_vector_test crypto) -add_dependencies(all_tests ctrdrbg_vector_test) diff --git a/crypto/rand_extra/CMakeLists.txt b/crypto/rand_extra/CMakeLists.txt new file mode 100644 index 00000000..2841ef62 --- /dev/null +++ b/crypto/rand_extra/CMakeLists.txt @@ -0,0 +1,12 @@ +include_directories(../../include) + +add_library( + rand_extra + + OBJECT + + forkunsafe.c + fuchsia.c + rand_extra.c + windows.c +) diff --git a/crypto/rand/deterministic.c b/crypto/rand_extra/deterministic.c similarity index 97% rename from crypto/rand/deterministic.c rename to crypto/rand_extra/deterministic.c index 8c754c1e..5d3a9ce4 100644 --- a/crypto/rand/deterministic.c +++ b/crypto/rand_extra/deterministic.c @@ -20,8 +20,8 @@ #include -#include "internal.h" #include "../internal.h" +#include "../fipsmodule/rand/internal.h" /* g_num_calls is the number of calls to |CRYPTO_sysrand| that have occurred. diff --git a/crypto/rand/forkunsafe.c b/crypto/rand_extra/forkunsafe.c similarity index 97% rename from crypto/rand/forkunsafe.c rename to crypto/rand_extra/forkunsafe.c index e9badc9d..1a3977f8 100644 --- a/crypto/rand/forkunsafe.c +++ b/crypto/rand_extra/forkunsafe.c @@ -16,7 +16,7 @@ #include -#include "internal.h" +#include "../fipsmodule/rand/internal.h" /* g_buffering_enabled is true if fork-unsafe buffering has been enabled. */ diff --git a/crypto/rand/fuchsia.c b/crypto/rand_extra/fuchsia.c similarity index 97% rename from crypto/rand/fuchsia.c rename to crypto/rand_extra/fuchsia.c index 2e138d0a..fae29894 100644 --- a/crypto/rand/fuchsia.c +++ b/crypto/rand_extra/fuchsia.c @@ -21,7 +21,7 @@ #include -#include "internal.h" +#include "../fipsmodule/rand/internal.h" void CRYPTO_sysrand(uint8_t *out, size_t requested) { while (requested > 0) { diff --git a/crypto/rand_extra/rand_extra.c b/crypto/rand_extra/rand_extra.c new file mode 100644 index 00000000..8fce3c89 --- /dev/null +++ b/crypto/rand_extra/rand_extra.c @@ -0,0 +1,68 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + + +void RAND_seed(const void *buf, int num) { + /* OpenSSH calls |RAND_seed| before jailing on the assumption that any needed + * file descriptors etc will be opened. */ + uint8_t unused; + RAND_bytes(&unused, sizeof(unused)); +} + +int RAND_load_file(const char *path, long num) { + if (num < 0) { /* read the "whole file" */ + return 1; + } else if (num <= INT_MAX) { + return (int) num; + } else { + return INT_MAX; + } +} + +const char *RAND_file_name(char *buf, size_t num) { return NULL; } + +void RAND_add(const void *buf, int num, double entropy) {} + +int RAND_egd(const char *path) { + return 255; +} + +int RAND_poll(void) { + return 1; +} + +int RAND_status(void) { + return 1; +} + +static const struct rand_meth_st kSSLeayMethod = { + RAND_seed, + RAND_bytes, + RAND_cleanup, + RAND_add, + RAND_pseudo_bytes, + RAND_status, +}; + +RAND_METHOD *RAND_SSLeay(void) { + return (RAND_METHOD*) &kSSLeayMethod; +} + +void RAND_set_rand_method(const RAND_METHOD *method) {} + +void RAND_cleanup(void) {} diff --git a/crypto/rand/windows.c b/crypto/rand_extra/windows.c similarity index 97% rename from crypto/rand/windows.c rename to crypto/rand_extra/windows.c index f47182d9..fb948472 100644 --- a/crypto/rand/windows.c +++ b/crypto/rand_extra/windows.c @@ -32,7 +32,7 @@ OPENSSL_MSVC_PRAGMA(warning(push, 3)) OPENSSL_MSVC_PRAGMA(warning(pop)) -#include "internal.h" +#include "../fipsmodule/rand/internal.h" void CRYPTO_sysrand(uint8_t *out, size_t requested) { diff --git a/crypto/thread_test.c b/crypto/thread_test.c index 714bef7a..4763fd39 100644 --- a/crypto/thread_test.c +++ b/crypto/thread_test.c @@ -103,6 +103,9 @@ static void call_once_thread(void) { static CRYPTO_once_t once_init_value = CRYPTO_ONCE_INIT; static CRYPTO_once_t once_bss; +static struct CRYPTO_STATIC_MUTEX mutex_init_value = CRYPTO_STATIC_MUTEX_INIT; +static struct CRYPTO_STATIC_MUTEX mutex_bss; + static int test_once(void) { if (g_once_init_called != 0) { fprintf(stderr, "g_once_init_called was non-zero at start.\n"); @@ -127,13 +130,20 @@ static int test_once(void) { } if (FIPS_mode()) { - /* Our FIPS tooling currently requires that |CRYPTO_ONCE_INIT| is all - * zeros, so the |CRYPTO_once_t| is placed in the bss. */ + /* Our FIPS tooling currently requires that |CRYPTO_ONCE_INIT| and + * |CRYPTO_STATIC_MUTEX_INIT| are all zeros and so can be placed in the BSS + * section. */ if (OPENSSL_memcmp((void *)&once_init_value, (void *)&once_bss, sizeof(CRYPTO_once_t)) != 0) { fprintf(stderr, "CRYPTO_ONCE_INIT did not expand to all zeros.\n"); return 0; } + + if (OPENSSL_memcmp((void *)&mutex_init_value, (void *)&mutex_bss, + sizeof(struct CRYPTO_STATIC_MUTEX)) != 0) { + fprintf(stderr, "CRYPTO_STATIC_MUTEX did not expand to all zeros.\n"); + return 0; + } } return 1; diff --git a/util/all_tests.json b/util/all_tests.json index ff82a6dc..f34e7c4d 100644 --- a/util/all_tests.json +++ b/util/all_tests.json @@ -54,7 +54,7 @@ ["crypto/pkcs8/pkcs8_test"], ["crypto/poly1305/poly1305_test", "crypto/poly1305/poly1305_tests.txt"], ["crypto/pool/pool_test"], - ["crypto/rand/ctrdrbg_vector_test", "crypto/rand/ctrdrbg_vectors.txt"], + ["crypto/fipsmodule/ctrdrbg_vector_test", "crypto/fipsmodule/rand/ctrdrbg_vectors.txt"], ["crypto/refcount_test"], ["crypto/thread_test"], ["crypto/x509/x509_test"],