Skip to content

Commit

Permalink
Setup for testing
Browse files Browse the repository at this point in the history
  • Loading branch information
justsmth committed Jun 14, 2024
1 parent 389c564 commit 29b569b
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 54 deletions.
23 changes: 14 additions & 9 deletions crypto/fipsmodule/rand/rand.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@
#include <openssl/type_check.h>

#include "../../internal.h"
#include "snapsafe_detect.h"
#include "fork_detect.h"
#include "internal.h"
#include "snapsafe_detect.h"


// It's assumed that the operating system always has an unfailing source of
Expand Down Expand Up @@ -388,7 +388,7 @@ void RAND_bytes_with_additional_data(uint8_t *out, size_t out_len,

uint32_t snapsafe_generation_id = 0;
int snapsafe_status = CRYPTO_get_snapsafe_generation(&snapsafe_generation_id);

// Additional data is mixed into every CTR-DRBG call to protect, as best we
// can, against forks & VM clones. We do not over-read this information and
// don't reseed with it so, from the point of view of FIPS, this doesn't
Expand All @@ -402,9 +402,10 @@ void RAND_bytes_with_additional_data(uint8_t *out, size_t out_len,
// entropy is used. This can be expensive (one read per |RAND_bytes| call)
// and so is disabled when we have fork detection, or if the application has
// promised not to fork.
// snapsafe_status is only 0 when the kernel has snapsafe support, but it failed
// to initialize. Otherwise, snapsafe_status is 1.
if ((snapsafe_status != 0 && fork_generation != 0) || fork_unsafe_buffering) {
// snapsafe_status is only 0 when the kernel has snapsafe support, but it
// failed to initialize. Otherwise, snapsafe_status is 1.
if ((snapsafe_status != 0 && fork_generation != 0) ||
fork_unsafe_buffering) {
OPENSSL_memset(additional_data, 0, sizeof(additional_data));
} else if (!have_rdrand()) {
// No alternative so block for OS entropy.
Expand Down Expand Up @@ -520,6 +521,12 @@ void RAND_bytes_with_additional_data(uint8_t *out, size_t out_len,
state->snapsafe_generation_id = snapsafe_generation_id;
OPENSSL_cleanse(seed, CTR_DRBG_ENTROPY_LEN);
OPENSSL_cleanse(add_data_for_reseed, CTR_DRBG_ENTROPY_LEN);

CRYPTO_get_snapsafe_generation(&snapsafe_generation_id);
if (snapsafe_generation_id != state->snapsafe_generation_id) {
// Unexpected change to snapsafe generation id
abort();
}
} else {
#if defined(BORINGSSL_FIPS)
CRYPTO_STATIC_MUTEX_lock_read(state_clear_all_lock_bss_get());
Expand Down Expand Up @@ -564,12 +571,10 @@ int RAND_bytes(uint8_t *out, size_t out_len) {
}

int RAND_priv_bytes(uint8_t *out, size_t out_len) {
return RAND_bytes(out, out_len);
return RAND_bytes(out, out_len);
}

int RAND_pseudo_bytes(uint8_t *buf, size_t len) {
return RAND_bytes(buf, len);
}
int RAND_pseudo_bytes(uint8_t *buf, size_t len) { return RAND_bytes(buf, len); }

void RAND_get_system_entropy_for_custom_prng(uint8_t *buf, size_t len) {
if (len > 256) {
Expand Down
51 changes: 40 additions & 11 deletions crypto/fipsmodule/rand/snapsafe_detect.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,17 @@

#include <openssl/crypto.h>

#include "../delocate.h"
#include "snapsafe_detect.h"

/* Test mode state */
#define SNAPSAFE_TEST_MODE_DISABLED 0x00
#define SNAPSAFE_TEST_MODE_ENABLED 0x01
DEFINE_STATIC_MUTEX(test_mode_mutex);
static volatile int test_mode_enabled = 0;
static volatile uint32_t test_mode_sgn = 0;
static volatile int test_mode_status = 1;

#if defined(OPENSSL_LINUX) && !defined(FIPS)

#include <fcntl.h>
Expand All @@ -15,20 +24,12 @@
#include <sys/mman.h>
#include <sys/random.h>
#include <unistd.h>
#include "../delocate.h"

/* Snapsafety state */
#define SNAPSAFETY_STATE_FAILED_INITIALISE 0x00
#define SNAPSAFETY_STATE_SUCCESS_INITIALISE 0x01
#define SNAPSAFETY_STATE_NOT_SUPPORTED 0x02

/* Test mode state */
#define SNAPSAFE_TEST_MODE_DISABLED 0x00
#define SNAPSAFE_TEST_MODE_ENABLED 0x01
DEFINE_STATIC_MUTEX(test_mode_mutex);
static int test_mode = 0;
static uint32_t test_mode_sgn = 0;

/* Sysgenid state */
/* These values can be found here: https://lkml.org/lkml/2021/3/8/677 */
#define SYSGENID_IOCTL 0xE4
Expand Down Expand Up @@ -108,11 +109,10 @@ static uint32_t aws_snapsafe_read_sgn(void) {
int CRYPTO_get_snapsafe_generation(uint32_t *snapsafe_generation_number) {
CRYPTO_once(aws_snapsafe_init_bss_get(), do_aws_snapsafe_init);

// Only the test_mode can change after initialization
CRYPTO_STATIC_MUTEX_lock_read(test_mode_mutex_bss_get());
if (test_mode == SNAPSAFE_TEST_MODE_ENABLED) {
if (test_mode_enabled == SNAPSAFE_TEST_MODE_ENABLED) {
*snapsafe_generation_number = test_mode_sgn;
return 1;
return test_mode_status;
}
CRYPTO_STATIC_MUTEX_unlock_read(test_mode_mutex_bss_get());

Expand All @@ -135,8 +135,37 @@ int CRYPTO_get_snapsafe_generation(uint32_t *snapsafe_generation_number) {
#else // !defined(OPENSSL_LINUX) || defined(FIPS)

int CRYPTO_get_snapsafe_generation(uint32_t *snapsafe_generation_number) {
CRYPTO_STATIC_MUTEX_lock_read(test_mode_mutex_bss_get());
if (test_mode_enabled == SNAPSAFE_TEST_MODE_ENABLED) {
*snapsafe_generation_number = test_mode_sgn;
return test_mode_status;
}
CRYPTO_STATIC_MUTEX_unlock_read(test_mode_mutex_bss_get());

*snapsafe_generation_number = 0;
return 1;
}

#endif // defined(OPENSSL_LINUX) && !defined(FIPS)

OPENSSL_EXPORT void HAZMAT_snapsafe_testing_status(int status) {
CRYPTO_STATIC_MUTEX_lock_write(test_mode_mutex_bss_get());
test_mode_status = status;
CRYPTO_STATIC_MUTEX_unlock_write(test_mode_mutex_bss_get());
}

OPENSSL_EXPORT void HAZMAT_snapsafe_testing(int enable) {
CRYPTO_STATIC_MUTEX_lock_write(test_mode_mutex_bss_get());
if (enable == 0) {
test_mode_enabled = SNAPSAFE_TEST_MODE_DISABLED;
} else {
test_mode_enabled = SNAPSAFE_TEST_MODE_ENABLED;
}
CRYPTO_STATIC_MUTEX_unlock_write(test_mode_mutex_bss_get());
}

OPENSSL_EXPORT void HAZMAT_snapsafe_testing_value(uint32_t val) {
CRYPTO_STATIC_MUTEX_lock_write(test_mode_mutex_bss_get());
test_mode_sgn = val;
CRYPTO_STATIC_MUTEX_unlock_write(test_mode_mutex_bss_get());
}
54 changes: 20 additions & 34 deletions crypto/fipsmodule/rand/snapsafe_detect.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,55 +20,41 @@ extern "C" {
#define AWSLC_SYSGENID_FILE_PATH "/dev/sysgenid"
#endif

// Experimental support for Snapsafe-type uniqueness breaking event (ube)
// detection.
// Snapsafe-type uniqueness breaking event (ube detection.
//
// CRYPTO_get_snapsafe_generation returns the snapsafe generation number for the
// current process, or zero if not supported on the platform. The snapsafe
// generation number is a non-zero, strictly-monotonic counter with the property
// that, if queried in an address space and then again in a subsequently
// resumed snapshot/VM, the resumed address space will observe a greater value.
// CRYPTO_get_snapsafe_generation provides the snapsafe generation number for the
// current process. The snapsafe generation number is a non-zero, strictly-monotonic
// counter with the property that, if queried in an address space and then again in
// a subsequently resumed snapshot/VM, the resumed address space will observe a greater value.
//
// We use SysGenID to detect resumed snapshot/VM events. See
// https://lkml.org/lkml/2021/3/8/677 for details about how SysGenID works.
// We make light use of the SysGenId capabilities and only use the following
// supported functions on the device: |open| and |mmap|.
//
// SysGenID is very new and the interface is not yet finalised. Therefore, we
// we only use this as a hardening mechanism and fail open. Hence the
// experimental note in the beginning.
//
// |CRYPTO_get_snapsafe_generation| expects exclusive write access to memory
// pointed to by |snapsafe_generation_number parameter|. If this can not be
// guaranteed (e.g. |snapsafe_generation_number| is a shared variable), caller
// must synchronise access.
// |CRYPTO_get_snapsafe_generation| returns 0 only when the filesystem
// presents SysGenID interface (typically `/dev/sysgenid`) but the library
// is unable to initialize its use. In all other cases, it returns 1.
OPENSSL_EXPORT int CRYPTO_get_snapsafe_generation(
uint32_t *snapsafe_generation_number);

// Below functions are strictly for testing only!

// CRYPTO_snapsafe_detect_ignore_for_testing is an internal detail used for
// testing purposes.
OPENSSL_EXPORT void CRYPTO_snapsafe_detect_ignore_for_testing(void);

// HAZMAT_overwrite_sysgenid_for_testing is an internal detail used for testing
// purposes. Call |HAZMAT_overwrite_sysgenid_for_testing| after test suite has
// run. Function allocates memory and associates it with the SysGenID callback
// pointer.
// HAZMAT_snapsafe_testing is an internal function used for testing snapsafe.
// Call |HAZMAT_sysgenid_testing| with a non-zero value to enable testing, otherwise
// testing will be disabled.
// Returns 1 if succesfull and 0 otherwise.
OPENSSL_EXPORT int HAZMAT_overwrite_sysgenid_for_testing(void);
OPENSSL_EXPORT void HAZMAT_snapsafe_testing(int enable);

// HAZMAT_reset_sysgenid_for_testing is an internal detail used for testing
// purposes. It frees memory allocated in
// |HAZMAT_overwrite_sysgenid_for_testing| and deassociates the SysGenID
// callback pointer.
OPENSSL_EXPORT void HAZMAT_reset_sysgenid_for_testing(void);
// HAZMAT_snapsafe_testing_status is an internal function used for testing snapsafe.
// The value |val| passed to this function will be used as the snapsafe status
// returned by |CRYPTO_get_snapsafe_generation| when testing has been enabled.
OPENSSL_EXPORT void HAZMAT_snapsafe_testing_status(int status);

// HAZMAT_overwrite_sysgenid_for_testing is an internal detail used for testing
// purposes. It assigns value |val| to the memory allocated in
// |HAZMAT_overwrite_sysgenid_for_testing|, which will be the new SysGenID
// value.
OPENSSL_EXPORT void HAZMAT_set_overwritten_sysgenid_for_testing(uint32_t val);
// HAZMAT_snapsafe_testing_value is an internal function used for testing snapsafe.
// The value |val| passed to this function will be used as the snapsafe generation
// number when testing has been enabled.
OPENSSL_EXPORT void HAZMAT_snapsafe_testing_value(uint32_t val);

#ifdef __cplusplus
}
Expand Down

0 comments on commit 29b569b

Please sign in to comment.