diff -rup openssl-1.0.2k/crypto/o_init.c openssl-1.0.2k-new/crypto/o_init.c --- openssl-1.0.2k/crypto/o_init.c 2017-01-26 05:22:03.000000000 -0800 +++ openssl-1.0.2k-new/crypto/o_init.c 2017-07-27 17:18:49.016782797 -0700 @@ -57,10 +57,57 @@ #include <openssl/err.h> #ifdef OPENSSL_FIPS # include <openssl/fips.h> +# include <openssl/fips_rand.h> # include <openssl/rand.h> #endif /* + * + * Enable FIPS mode based on host FIPS mode / env variable. + */ +#if defined(OPENSSL_FIPS) +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> + +#define FIPS_MODE_SWITCH_FILE "/proc/sys/crypto/fips_enabled" +#define FIPS_MODE_SWITCH_FILE2 "/etc/vmware/system_fips" + +static void init_fips_mode(void) +{ + char buf[2] = "0"; + int fd; + + if (getenv("OPENSSL_FORCE_FIPS_MODE") != NULL) + { + buf[0] = '1'; + } + else if (access(FIPS_MODE_SWITCH_FILE2, F_OK) != -1) + { + buf[0] = '1'; + } + else if ((fd = open(FIPS_MODE_SWITCH_FILE, O_RDONLY)) >= 0) + { + while (read(fd, buf, sizeof(buf)) < 0 && errno == EINTR); + close(fd); + } + /* Failure reading the fips mode switch file means just not + * switching into FIPS mode. We would break too many things + * otherwise. + */ + + if (buf[0] == '1') + { + FIPS_mode_set(1); + } +} +#endif + + +/* * Perform any essential OpenSSL initialization operations. Currently only * sets FIPS callbacks */ @@ -79,6 +126,17 @@ void OPENSSL_init(void) FIPS_set_error_callbacks(ERR_put_error, ERR_add_error_vdata); FIPS_set_malloc_callbacks(CRYPTO_malloc, CRYPTO_free); RAND_init_fips(); + /* + * VMware patch + * + * Calling RAND_init_fips() followed by + * RAND_set_rand_method(FIPS_rand_get_method()) will + * cause OpenSSL to use the FIPS default DRBG + * in lieu of the non-compliant OpenSSL default RAND. This + * requires FIPS-capable OpenSSL. + */ + RAND_set_rand_method(FIPS_rand_get_method()); + init_fips_mode(); /* VMware patch -- check a system file */ #endif #if 0 fprintf(stderr, "Called OPENSSL_init\n");