From 1ea6d8f6a02007c9fe97866632f0ba68dd28bfc3 Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Thu, 24 Oct 2024 15:43:01 -0700 Subject: [PATCH 01/24] Implements tree-DRBG --- CMakeLists.txt | 3 +- crypto/CMakeLists.txt | 8 +- crypto/fipsmodule/bcm.c | 3 +- crypto/fipsmodule/rand/cpu_jitter_test.cc | 4 - .../fipsmodule/rand/entropy/entropy_sources.c | 61 +-- crypto/fipsmodule/rand/entropy/internal.h | 33 +- .../rand/entropy/tree_drbg_jitter_entropy.c | 465 ++++++++++++++++++ crypto/fipsmodule/rand/new_rand.c | 39 +- tool/bssl_bm.h | 2 - tool/speed.cc | 8 +- 10 files changed, 547 insertions(+), 79 deletions(-) create mode 100644 crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 7225a0f183..a709dbf0c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,9 +41,9 @@ enable_language(C) if(FIPS) message(STATUS "FIPS build mode configured") + # Keep below to allow existing rand.c implementation and testing to function. if(ENABLE_FIPS_ENTROPY_CPU_JITTER) add_definitions(-DFIPS_ENTROPY_SOURCE_JITTER_CPU) - add_subdirectory(third_party/jitterentropy) message(STATUS "FIPS entropy source method configured: CPU Jitter") else() add_definitions(-DFIPS_ENTROPY_SOURCE_PASSIVE) @@ -1020,6 +1020,7 @@ if(BUILD_TESTING) endmacro() endif() +add_subdirectory(third_party/jitterentropy) add_subdirectory(crypto) if(BUILD_LIBSSL) add_subdirectory(ssl) diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt index ed66baafb1..b8be55400d 100644 --- a/crypto/CMakeLists.txt +++ b/crypto/CMakeLists.txt @@ -592,13 +592,7 @@ target_include_directories(crypto_objects BEFORE PRIVATE ${PROJECT_BINARY_DIR}/s target_include_directories(crypto_objects PRIVATE ${PROJECT_SOURCE_DIR}/include) function(build_libcrypto name module_source) - if(FIPS AND ENABLE_FIPS_ENTROPY_CPU_JITTER) - # If the jitter cpu entropy source is enabled add an object dependency to - # the libcrypto target. - add_library(${name} $ ${CRYPTO_FIPS_OBJECTS} ${module_source} $) - else() - add_library(${name} $ ${CRYPTO_FIPS_OBJECTS} ${module_source}) - endif() + add_library(${name} $ ${CRYPTO_FIPS_OBJECTS} ${module_source} $) if(FIPS_DELOCATE OR FIPS_SHARED) add_dependencies(${name} bcm_o_target) diff --git a/crypto/fipsmodule/bcm.c b/crypto/fipsmodule/bcm.c index ca3e3c7526..9477b9061a 100644 --- a/crypto/fipsmodule/bcm.c +++ b/crypto/fipsmodule/bcm.c @@ -36,6 +36,7 @@ #include "rand/new_rand.c" #include "rand/entropy/entropy_sources.c" +#include "rand/entropy/tree_drbg_jitter_entropy.c" #include #include @@ -263,12 +264,10 @@ static void BORINGSSL_bcm_power_on_self_test(void) { OPENSSL_cpuid_setup(); #endif -#if defined(FIPS_ENTROPY_SOURCE_JITTER_CPU) if (jent_entropy_init()) { fprintf(stderr, "CPU Jitter entropy RNG initialization failed.\n"); goto err; } -#endif #if !defined(OPENSSL_ASAN) // Integrity tests cannot run under ASAN because it involves reading the full diff --git a/crypto/fipsmodule/rand/cpu_jitter_test.cc b/crypto/fipsmodule/rand/cpu_jitter_test.cc index 1ac0f9eb4f..a1872f52f0 100644 --- a/crypto/fipsmodule/rand/cpu_jitter_test.cc +++ b/crypto/fipsmodule/rand/cpu_jitter_test.cc @@ -1,8 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 OR ISC -#if defined(BORINGSSL_FIPS) && defined(FIPS_ENTROPY_SOURCE_JITTER_CPU) - #include #include "../../test/test_util.h" @@ -67,5 +65,3 @@ TEST(CPUJitterEntropyTest, Basic) { unsigned int jitter_version = 3040000; EXPECT_EQ(jitter_version, jent_version()); } - -#endif diff --git a/crypto/fipsmodule/rand/entropy/entropy_sources.c b/crypto/fipsmodule/rand/entropy/entropy_sources.c index d874b7fc73..651adcfac5 100644 --- a/crypto/fipsmodule/rand/entropy/entropy_sources.c +++ b/crypto/fipsmodule/rand/entropy/entropy_sources.c @@ -10,19 +10,8 @@ #include "../internal.h" #include "../../delocate.h" -static int entropy_default_initialize(void) { - return 1; -} - -static void entropy_default_cleanup(void) { -} - -static int entropy_default_get_seed(uint8_t seed[CTR_DRBG_ENTROPY_LEN]) { - CRYPTO_sysrand_for_seed(seed, CTR_DRBG_ENTROPY_LEN); - return 1; -} - -static int entropy_default_get_prediction_resistance( +static int entropy_get_prediction_resistance( + const struct entropy_source_t *entropy_source, uint8_t pred_resistance[RAND_PRED_RESISTANCE_LEN]) { if (have_fast_rdrand() == 1 && rdrand(pred_resistance, RAND_PRED_RESISTANCE_LEN) != 1) { @@ -31,41 +20,43 @@ static int entropy_default_get_prediction_resistance( return 1; } -static int entropy_default_randomize(void) { - return 1; -} - -// The default entropy source configuration using -// - OS randomness source for seeding. -// - Doesn't have a extra entropy source. +// - Tree DRBG with Jitter Entropy as root for seeding. +// - OS as personalization string source. // - If run-time is on an Intel CPU and it supports rdrand, use it as a source // for prediction resistance. Otherwise, no source. -DEFINE_LOCAL_DATA(struct entropy_source, default_entropy_source) { - out->initialize = entropy_default_initialize; - out->cleanup = entropy_default_cleanup; - out->get_seed = entropy_default_get_seed; - out->get_extra_entropy = NULL; +DEFINE_LOCAL_DATA(struct entropy_source_methods, tree_jitter_entropy_source_methods) { + out->initialize = tree_jitter_initialize; + out->zeroize_thread = tree_jitter_zeroize_thread_drbg; + out->free_thread = tree_jitter_free_thread_drbg; + out->get_seed = tree_jitter_get_seed; + out->get_personalization_string = NULL; if (have_fast_rdrand() == 1) { - out->get_prediction_resistance = entropy_default_get_prediction_resistance; + out->get_prediction_resistance = entropy_get_prediction_resistance; } else { out->get_prediction_resistance = NULL; } - out->randomize = entropy_default_randomize; } -const struct entropy_source * get_entropy_source(void) { - const struct entropy_source *ent_source = default_entropy_source(); +struct entropy_source_t * get_entropy_source(void) { + + struct entropy_source_t *entropy_source = OPENSSL_zalloc(sizeof(struct entropy_source_t)); + if (entropy_source == NULL) { + return NULL; + } + + entropy_source->methods = tree_jitter_entropy_source_methods(); // Make sure that the function table contains the minimal number of callbacks // that we expect. Also make sure that the entropy source is initialized such // that calling code can assume that. - if (ent_source->cleanup == NULL || - ent_source->get_seed == NULL || - ent_source->randomize == NULL || - ent_source->initialize == NULL || - ent_source->initialize() != 1) { + if (entropy_source->methods == NULL || + entropy_source->methods->zeroize_thread == NULL || + entropy_source->methods->free_thread == NULL || + entropy_source->methods->get_seed == NULL || + entropy_source->methods->initialize == NULL || + entropy_source->methods->initialize(entropy_source) != 1) { return NULL; } - return ent_source; + return entropy_source; } diff --git a/crypto/fipsmodule/rand/entropy/internal.h b/crypto/fipsmodule/rand/entropy/internal.h index dc93136e7f..1879021ade 100644 --- a/crypto/fipsmodule/rand/entropy/internal.h +++ b/crypto/fipsmodule/rand/entropy/internal.h @@ -12,18 +12,33 @@ extern "C" { #endif -// I could make these array types! -struct entropy_source { - int (*initialize)(void); - void (*cleanup)(void); - int (*get_seed)(uint8_t seed[CTR_DRBG_ENTROPY_LEN]); - int (*get_extra_entropy)(uint8_t extra_entropy[CTR_DRBG_ENTROPY_LEN]); - int (*get_prediction_resistance)(uint8_t pred_resistance[RAND_PRED_RESISTANCE_LEN]); - int (*randomize)(void); +#define ENTROPY_JITTER_MAX_NUM_TRIES (3) + +struct entropy_source_t { + void *state; + const struct entropy_source_methods *methods; +}; + +struct entropy_source_methods { + int (*initialize)(struct entropy_source_t *entropy_source); + void (*zeroize_thread)(struct entropy_source_t *entropy_source); + void (*free_thread)(struct entropy_source_t *entropy_source); + int (*get_seed)(const struct entropy_source_t *entropy_source, + uint8_t seed[CTR_DRBG_ENTROPY_LEN]); + int (*get_personalization_string)(const struct entropy_source_t *entropy_source, + uint8_t personalization_string[CTR_DRBG_ENTROPY_LEN]); + int (*get_prediction_resistance)(const struct entropy_source_t *entropy_source, + uint8_t pred_resistance[RAND_PRED_RESISTANCE_LEN]); }; // get_entropy_source will return an entropy source configured for the platform. -const struct entropy_source * get_entropy_source(void); +struct entropy_source_t * get_entropy_source(void); + +OPENSSL_EXPORT int tree_jitter_initialize(struct entropy_source_t *entropy_source); +OPENSSL_EXPORT void tree_jitter_zeroize_thread_drbg(struct entropy_source_t *entropy_source); +OPENSSL_EXPORT void tree_jitter_free_thread_drbg(struct entropy_source_t *entropy_source); +OPENSSL_EXPORT int tree_jitter_get_seed( + const struct entropy_source_t *entropy_source, uint8_t seed[CTR_DRBG_ENTROPY_LEN]); #if defined(__cplusplus) } // extern C diff --git a/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c b/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c new file mode 100644 index 0000000000..44408361df --- /dev/null +++ b/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c @@ -0,0 +1,465 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR ISC + +#include +#include +#include + +#include "internal.h" +#include "../internal.h" +#include "../../delocate.h" +#include "../../../internal.h" +#include "../../../ube/internal.h" + +#include "../../../../third_party/jitterentropy/jitterentropy.h" + +// Randomness generation implements thread-local "frontend" DRBGs that serve +// requests for randomness from consumers through exported functions such as +// RAND_bytes(). This file implements a tree-DRBG from SP800-90C as a seed +// entropy source for the frontend DRBGs. The implemented tree-DRBG has the +// following characteristics: +// - A per-thread seed DRBG that serves seed requests for a thread-local +// frontend DRBG. +// - A global seed DRBG that serves seed requests from the thread-local seed +// DRBGs. +// - A root seed source that serves seed requests from the global seed DRBG. +// The root seed source is a global instance of Jitter Entropy. +// +// The dependency tree looks as follows: +// +// per-thread +// +-----------+ +// | CTR-DRBG | -| +// +-----------+ -| +// +-----------+ --| per-process per-process +// | CTR-DRBG | ---| --> +-----------+ +---------------+ +// +-----------+ -----> | CTR-DRBG | --> |Jitter Entropy | +// ... --> +-----------+ +---------------+ +// +-----------+ -----| +// | CTR-DRBG |-| +// +-----------+ +// +// Memory life-cycle: The thread-local DRBGs has the same storage duration as +// their corresponding thread-local frontend DRBGs. The per-process DRBG and +// Jitter Entropy instance has a storage duration that extends to the duration +// of AWS-LC being loaded into the process. The per-process memory is lazily +// allocated. + +// To serve seed requests from the frontend DRBGs the following +// |struct entropy_source_methods| interface functions are implemented: +// - tree_jitter_initialize +// - tree_jitter_zeroize_thread_drbg +// - tree_jitter_free_thread_drbg +// - tree_jitter_get_seed + + +// TREE_JITTER_GLOBAL_DRBG_MAX_GENERATE = 2^24 +#define TREE_JITTER_GLOBAL_DRBG_MAX_GENERATE 0xFFFFFF +// TREE_JITTER_THREAD_DRBG_MAX_GENERATE = 2^20 +#define TREE_JITTER_THREAD_DRBG_MAX_GENERATE 0xFFFFF + +struct tree_jitter_drbg_t { + // is_global is 1 if this object is the per-process seed DRBG. Otherwise 0. + char is_global; + + // drbg is the DRBG state. + CTR_DRBG_STATE drbg; + + // generate_calls_since_seed is the number of generate calls made on |drbg| + // since it was last (re)seeded. Must be bounded by |kReseedInterval|. + uint64_t generate_calls_since_seed; + + // max_generate_calls is the maximum number of generate calls that can be + // invoked on |drbg| without a reseed. + uint64_t max_generate_calls; + + // reseed_calls_since_initialization is the number of reseed calls made of + // |drbg| since its initialization. + uint64_t reseed_calls_since_initialization; + + // generation_number caches the UBE generation number. + uint64_t generation_number; + + // ube_protection denotes whether this object is protected from UBEs. + char ube_protection; + + // Jitter entropy state. NULL if not the per-process seed DRBG. + struct rand_data *jitter_ec; +}; + +// Per-process seed DRBG locks. +DEFINE_BSS_GET(struct tree_jitter_drbg_t *, global_seed_drbg) +DEFINE_STATIC_ONCE(global_seed_drbg_once) +DEFINE_STATIC_ONCE(global_seed_drbg_zeroize_once) +DEFINE_STATIC_MUTEX(global_seed_drbg_lock) + +// tree_jitter_get_root_seed generates |CTR_DRBG_ENTROPY_LEN| bytes of output +// from the Jitter Entropy instance configured in |tree_jitter_drbg|. The output +// is returned in |seed_out|. +// Access to this function must be synchronized. +static void tree_jitter_get_root_seed( + struct tree_jitter_drbg_t *tree_jitter_drbg, + uint8_t seed_out[CTR_DRBG_ENTROPY_LEN]) { + + if (tree_jitter_drbg->jitter_ec == NULL) { + abort(); + } + + // |jent_read_entropy| has a false positive health test failure rate of 2^-22. + // To avoid aborting so frequently, we retry 3 times. + char jitter_generated_output = 0; + for (size_t num_tries = 1; num_tries <= ENTROPY_JITTER_MAX_NUM_TRIES; num_tries++) { + + // Try to generate the required number of bytes with Jitter. + // If successful break out from the loop, otherwise try again. + if (jent_read_entropy(tree_jitter_drbg->jitter_ec, (char *) seed_out, + CTR_DRBG_ENTROPY_LEN) == (ssize_t) CTR_DRBG_ENTROPY_LEN) { + jitter_generated_output = 1; + break; + } + + // If Jitter entropy failed to produce entropy we need to reset it. + jent_entropy_collector_free(tree_jitter_drbg->jitter_ec); + tree_jitter_drbg->jitter_ec = NULL; + tree_jitter_drbg->jitter_ec = jent_entropy_collector_alloc(0, JENT_FORCE_FIPS); + if (tree_jitter_drbg->jitter_ec == NULL) { + abort(); + } + } + + if (jitter_generated_output != 1) { + abort(); + } +} + +// tree_jitter_drbg_maybe_get_pred_resistance generates RAND_PRED_RESISTANCE_LEN +// bytes for prediction resistance and returns them in |pred_resistance|. +// However, it only generate bytes if |tree_jitter_drbg| meets the conditions: +// 1) is not the global seed DRBG 2) is not protected from UBEs. If bytes are +// generated, |pre_resistance_len| is set to RAND_PRED_RESISTANCE_LEN and is +// otherwise not mutated. +static void tree_jitter_drbg_maybe_get_pred_resistance( + struct tree_jitter_drbg_t *tree_jitter_drbg, + uint8_t pred_resistance[RAND_PRED_RESISTANCE_LEN], + size_t *pred_resistance_len) { + + if (tree_jitter_drbg->is_global == 0 && + tree_jitter_drbg->ube_protection != 1) { + CRYPTO_sysrand_for_seed(pred_resistance, RAND_PRED_RESISTANCE_LEN); + *pred_resistance_len = RAND_PRED_RESISTANCE_LEN; + } +} + +// tree_jitter_check_drbg_must_reseed computes whether |state| must be +// randomized to ensure uniqueness. +// +// Return 1 if |state| must be randomized. 0 otherwise. +static int tree_jitter_check_drbg_must_reseed( + struct tree_jitter_drbg_t *tree_jitter_drbg) { + + uint64_t current_generation_number = 0; + if (CRYPTO_get_ube_generation_number(¤t_generation_number) != 1 && + current_generation_number != tree_jitter_drbg->generation_number) { + tree_jitter_drbg->generation_number = current_generation_number; + return 1; + } + + if (tree_jitter_drbg->generate_calls_since_seed + 1 > tree_jitter_drbg->max_generate_calls) { + return 1; + } + + return 0; +} + +// tree_jitter_drbg_derive_seed generates a CTR_DRBG_ENTROPY_LEN byte seed from +// the DRBG configured in |tree_jitter_drbg|. The generated bytes are returned +// in |seed_out|. +// +// |tree_jitter_drbg_derive_seed| automatically handles reseeding the +// associated DRBG if required. In addition, if UBE detection is not supported +// prediction resistance is used to ensure bytes are generated safely. +static void tree_jitter_drbg_derive_seed( + struct tree_jitter_drbg_t *tree_jitter_drbg, + uint8_t seed_out[CTR_DRBG_ENTROPY_LEN]) { + + if (tree_jitter_drbg == NULL) { + abort(); + } + + if (tree_jitter_check_drbg_must_reseed(tree_jitter_drbg) == 1) { + uint8_t seed_drbg[CTR_DRBG_ENTROPY_LEN]; + if (tree_jitter_drbg->is_global == 1) { + tree_jitter_get_root_seed(tree_jitter_drbg, seed_drbg); + } else { + CRYPTO_STATIC_MUTEX_lock_write(global_seed_drbg_lock_bss_get()); + tree_jitter_drbg_derive_seed(*global_seed_drbg_bss_get(), seed_drbg); + CRYPTO_STATIC_MUTEX_unlock_write(global_seed_drbg_lock_bss_get()); + } + + if (CTR_DRBG_reseed(&(tree_jitter_drbg->drbg), seed_drbg, NULL, 0) != 1) { + abort(); + } + OPENSSL_cleanse(seed_drbg, CTR_DRBG_ENTROPY_LEN); + tree_jitter_drbg->reseed_calls_since_initialization += 1; + tree_jitter_drbg->generate_calls_since_seed = 0; + } + + uint8_t pred_resistance[RAND_PRED_RESISTANCE_LEN]; + size_t pred_resistance_len = 0; + tree_jitter_drbg_maybe_get_pred_resistance(tree_jitter_drbg, + pred_resistance, &pred_resistance_len); + + OPENSSL_STATIC_ASSERT(CTR_DRBG_ENTROPY_LEN <= CTR_DRBG_MAX_GENERATE_LENGTH, + CTR_DRBG_ENTROPY_LEN_is_too_large_compared_to_CTR_DRBG_MAX_GENERATE_LENGTH) + + if (!CTR_DRBG_generate(&(tree_jitter_drbg->drbg), seed_out, CTR_DRBG_ENTROPY_LEN, + pred_resistance, pred_resistance_len)) { + abort(); + } + OPENSSL_cleanse(pred_resistance, RAND_PRED_RESISTANCE_LEN); + tree_jitter_drbg->generate_calls_since_seed += 1; +} + +// tree_jitter_drbg_derive_seed generates a CTR_DRBG_ENTROPY_LEN byte seed from +// the DRBG configured in |entropy_source|. The generated bytes are returned +// in |seed_out|. This function is the entry point for generating output from +// the tree DRBG. +// +// Return 1 on success and 0 otherwise. +int tree_jitter_get_seed(const struct entropy_source_t *entropy_source, + uint8_t seed_out[CTR_DRBG_ENTROPY_LEN]) { + + GUARD_PTR_ABORT(entropy_source); + GUARD_PTR_ABORT(seed_out); + + struct tree_jitter_drbg_t *tree_jitter_drbg_thread = + (struct tree_jitter_drbg_t *) entropy_source->state; + tree_jitter_drbg_derive_seed(tree_jitter_drbg_thread, seed_out); + + return 1; +} + +static void tree_jitter_initialize_once(void) { + + struct tree_jitter_drbg_t *tree_jitter_drbg_global = + OPENSSL_zalloc(sizeof(struct tree_jitter_drbg_t)); + if (tree_jitter_drbg_global == NULL) { + abort(); + } + + tree_jitter_drbg_global->is_global = 1; + tree_jitter_drbg_global->generate_calls_since_seed = 0; + tree_jitter_drbg_global->max_generate_calls = TREE_JITTER_GLOBAL_DRBG_MAX_GENERATE; + tree_jitter_drbg_global->reseed_calls_since_initialization = 0; + uint64_t current_generation_number = 0; + if (CRYPTO_get_ube_generation_number(¤t_generation_number) != 1) { + tree_jitter_drbg_global->generation_number = 0; + } else { + tree_jitter_drbg_global->generation_number = current_generation_number; + } + + // The first parameter passed to |jent_entropy_collector_alloc| function is + // the desired oversampling rate. Passing a 0 tells Jitter module to use + // the default rate (which is 3 in Jitter v3.1.0). + tree_jitter_drbg_global->jitter_ec = jent_entropy_collector_alloc(0, JENT_FORCE_FIPS); + if (tree_jitter_drbg_global->jitter_ec == NULL) { + abort(); + } + + uint8_t seed_drbg[CTR_DRBG_ENTROPY_LEN]; + tree_jitter_get_root_seed(tree_jitter_drbg_global, seed_drbg); + if (!CTR_DRBG_init(&(tree_jitter_drbg_global->drbg), seed_drbg, NULL, 0)) { + abort(); + } + OPENSSL_cleanse(seed_drbg, CTR_DRBG_ENTROPY_LEN); + + *global_seed_drbg_bss_get() = tree_jitter_drbg_global; +} + +// tree_jitter_initialize initalizes a thread-local seed DRBG as configures +// it in |entropy_source|. If the global seed DRBG has not been initialized yet +// it's also initialized. +// +// Returns 1 on success and 0 otherwise. +int tree_jitter_initialize(struct entropy_source_t *entropy_source) { + + GUARD_PTR_ABORT(entropy_source); + + // Initialize the per-thread seed drbg. + struct tree_jitter_drbg_t *tree_jitter_drbg = + OPENSSL_zalloc(sizeof(struct tree_jitter_drbg_t)); + if (tree_jitter_drbg == NULL) { + abort(); + } + + // Initialize the global seed DRBG if haven't already. + CRYPTO_once(global_seed_drbg_once_bss_get(), tree_jitter_initialize_once); + + // Initialize the per-thread seed DRBG. + uint8_t seed_drbg[CTR_DRBG_ENTROPY_LEN]; + CRYPTO_STATIC_MUTEX_lock_write(global_seed_drbg_lock_bss_get()); + tree_jitter_drbg_derive_seed(*global_seed_drbg_bss_get(), seed_drbg); + CRYPTO_STATIC_MUTEX_unlock_write(global_seed_drbg_lock_bss_get()); + + if (!CTR_DRBG_init(&(tree_jitter_drbg->drbg), seed_drbg, NULL, 0)) { + abort(); + } + OPENSSL_cleanse(seed_drbg, CTR_DRBG_ENTROPY_LEN); + + tree_jitter_drbg->generate_calls_since_seed = 0; + tree_jitter_drbg->max_generate_calls = TREE_JITTER_THREAD_DRBG_MAX_GENERATE; + tree_jitter_drbg->reseed_calls_since_initialization = 0; + uint64_t current_generation_number = 0; + if (CRYPTO_get_ube_generation_number(¤t_generation_number) != 1) { + tree_jitter_drbg->ube_protection = 0; + tree_jitter_drbg->generation_number = 0; + } else { + tree_jitter_drbg->ube_protection = 1; + tree_jitter_drbg->generation_number = current_generation_number; + } + + entropy_source->state = tree_jitter_drbg; + + return 1; +} + +#if defined(_MSC_VER) +#pragma section(".CRT$XCU", read) +static void tree_jitter_free_global_drbg(void); +static void windows_install_tree_jitter_free_global_drbg(void) { + atexit(&tree_jitter_free_global_drbg); +} +__declspec(allocate(".CRT$XCU")) void(*tree_jitter_drbg_destructor)(void) = + windows_install_tree_jitter_free_global_drbg; +#else +static void tree_jitter_free_global_drbg(void) __attribute__ ((destructor)); +#endif + +// The memory life-time for thread-local seed DRBGs is handled differently +// compared to the global seed DRBG (and Jitter Entropy instance). The frontend +// DRBG thread-local destuctors will invoke |tree_jitter_free_thread_drbg| using +// their reference to it. The global seed DRBG and Jitter Entropy instance will +// be released by a destructor. This ensures that the global seed DRBG life-time +// extends to the entire process life-time if the lazy initialization happened. +// Obviously, any dlclose on AWS-LC will release the memory early but that's +// correct behaviour. + +// tree_jitter_free_global_drbg frees the memory allocated for the global seed +// DRBG and Jitter Entropy instance. +static void tree_jitter_free_global_drbg(void) { + + CRYPTO_STATIC_MUTEX_lock_write(global_seed_drbg_lock_bss_get()); + + struct tree_jitter_drbg_t *global_tree_jitter_drbg = *global_seed_drbg_bss_get(); + if (*global_seed_drbg_bss_get() == NULL) { + return; + } + + if (global_tree_jitter_drbg->is_global != 1) { + // Should not happen. + abort(); + } + + jent_entropy_collector_free(global_tree_jitter_drbg->jitter_ec); + OPENSSL_free(global_tree_jitter_drbg); + + *global_seed_drbg_bss_get() = NULL; + + CRYPTO_STATIC_MUTEX_unlock_write(global_seed_drbg_lock_bss_get()); +} + +// tree_jitter_zeroize_thread_drbg frees the thread-local seed DRBG +// associated with the entropy source |entropy_source|. +void tree_jitter_free_thread_drbg(struct entropy_source_t *entropy_source) { + + GUARD_PTR_ABORT(entropy_source); + + struct tree_jitter_drbg_t *tree_jitter_drbg = + (struct tree_jitter_drbg_t *) entropy_source->state; + if (tree_jitter_drbg == NULL) { + return; + } + + OPENSSL_free(tree_jitter_drbg); + entropy_source->state = NULL; +} + +// Per ISO/IEC 19790-2012 7.9.7 "zeroization" can be random data just not other +// SSP/CSP's. The Jitter Entropy instance doesn't have any practical state; it's +// a live entropy source. The zeroization strategy used for the DRBG's is to +// reseed with random data, that in turn, will override all states in the tree +// with random data. The zeroization of the tree DRBG executes after the +// frontend DRBGs have been locked - they can't release any generated output. +// Therefore, the randomness generation layer ensures that no output from an the +// tree DRBG is used to generate any output that is later released. Randomizing +// the tree DRBG states therefore effectively "zeroize" the state. +// +// If there aren't any threads running, the zeroizer for the global seed DRBG +// won't execute. But the destructor responsible for releasing the memory +// allocated for the global seed DRBG and Jitter Entropy instance, will still +// execute, in turn, zeroize it. +// +// One could override the DRBG states with zero's. However, doing the small +// extra work to use random data (from the OS source) ensures that even if some +// output where to escape from the randomness generation, it will still be sound +// practically. + +// tree_jitter_zeroize_drbg zeroizes the DRBG state configured in +// |tree_jitter_drbg|. +static void tree_jitter_zeroize_drbg( + struct tree_jitter_drbg_t *tree_jitter_drbg) { + + uint8_t random_data[CTR_DRBG_ENTROPY_LEN]; + CRYPTO_sysrand_if_available(random_data, CTR_DRBG_ENTROPY_LEN); + + if (CTR_DRBG_reseed(&(tree_jitter_drbg->drbg), random_data, NULL, 0) != 1) { + abort(); + } + OPENSSL_cleanse(random_data, CTR_DRBG_ENTROPY_LEN); + tree_jitter_drbg->reseed_calls_since_initialization += 1; + tree_jitter_drbg->generate_calls_since_seed = 0; +} + +// tree_jitter_zeroize_thread_drbg is similar to but also handles +// synchronizing access to the global seed DRBG +static void tree_jitter_zeroize_global_drbg(void) { + + CRYPTO_STATIC_MUTEX_lock_write(global_seed_drbg_lock_bss_get()); + + struct tree_jitter_drbg_t *tree_jitter_drbg = *global_seed_drbg_bss_get(); + if (*global_seed_drbg_bss_get() == NULL) { + return; + } + + if (tree_jitter_drbg->is_global != 1) { + // Should not happen. + abort(); + } + + tree_jitter_zeroize_drbg(tree_jitter_drbg); + + CRYPTO_STATIC_MUTEX_unlock_write(global_seed_drbg_lock_bss_get()); +} + +// tree_jitter_zeroize_thread_drbg zeroizes the thread-local seed DRBG +// associated with the entropy source |entropy_source|. It also executes +// zeroization of the global seed DRBG if applicable. +void tree_jitter_zeroize_thread_drbg(struct entropy_source_t *entropy_source) { + + GUARD_PTR_ABORT(entropy_source); + + CRYPTO_once(global_seed_drbg_zeroize_once_bss_get(), tree_jitter_zeroize_global_drbg); + + struct tree_jitter_drbg_t *tree_jitter_drbg = + (struct tree_jitter_drbg_t *) entropy_source->state; + if (tree_jitter_drbg == NULL) { + return; + } + + if (tree_jitter_drbg->is_global == 1) { + // Should not happen. + abort(); + } + + tree_jitter_zeroize_drbg(tree_jitter_drbg); +} diff --git a/crypto/fipsmodule/rand/new_rand.c b/crypto/fipsmodule/rand/new_rand.c index 2e4ab5bb38..9484206989 100644 --- a/crypto/fipsmodule/rand/new_rand.c +++ b/crypto/fipsmodule/rand/new_rand.c @@ -32,7 +32,7 @@ struct rand_thread_local_state { uint64_t generation_number; // Entropy source. UBE volatile state. - const struct entropy_source *entropy_source; + struct entropy_source_t *entropy_source; // Backward and forward references to nodes in a doubly-linked list. struct rand_thread_local_state *next; @@ -60,7 +60,7 @@ static void rand_thread_local_state_clear_all(void) __attribute__ ((destructor)) // At process exit not all threads will be scheduled and proper exited. To // ensure no secret state is left, globally clear all thread-local states. This -// is a FIPS-derived requirement: SSPs must be cleared. +// is a FIPS-derived requirement, see ISO/IEC 19790-2012 7.9.7. // // This is problematic because a thread might be scheduled and return // randomness from a non-valid state. The linked application should obviously @@ -72,6 +72,11 @@ static void rand_thread_local_state_clear_all(void) __attribute__ ((destructor)) // generation can occur after a thread-local state has been locked. It also // ensures |rand_thread_local_state_free| cannot free any thread state while we // own the lock. +// +// When we a thread-local DRBGs is gated from returning output, we can +// invoke the entropy source zeroization from |state->entropy_source|. The +// entropy source implementation can assume that any returned seed is never +// used to generate any randomness that is later returned to a consumer. static void rand_thread_local_state_clear_all(void) { CRYPTO_STATIC_MUTEX_lock_write(thread_local_states_list_lock_bss_get()); for (struct rand_thread_local_state *state = *thread_states_list_head_bss_get(); @@ -79,6 +84,11 @@ static void rand_thread_local_state_clear_all(void) { CRYPTO_MUTEX_lock_write(&state->state_clear_lock); CTR_DRBG_clear(&state->drbg); } + + for (struct rand_thread_local_state *state = *thread_states_list_head_bss_get(); + state != NULL; state = state->next) { + state->entropy_source->methods->zeroize_thread(state->entropy_source); + } } static void thread_local_list_delete_node( @@ -165,9 +175,10 @@ static void rand_thread_local_state_free(void *state_in) { // Potentially, something could kill the thread before an entropy source has // been associated to the thread-local randomness generator object. if (state->entropy_source != NULL) { - state->entropy_source->cleanup(); + state->entropy_source->methods->free_thread(state->entropy_source); } + OPENSSL_free(state->entropy_source); OPENSSL_free(state); } @@ -197,7 +208,7 @@ static int rand_ensure_valid_state(const struct rand_thread_local_state *state) // imply that an UBE occurred. It can also mean that no UBE detection is // supported or that UBE detection failed. In these cases, |state| must also be // randomized to ensure uniqueness. Any special future cases can be handled in -// this function. +// this function. // // Return 0 if |state| must be randomized. 1 otherwise. static int rand_check_ctr_drbg_uniqueness(struct rand_thread_local_state *state) { @@ -223,7 +234,7 @@ static int rand_check_ctr_drbg_uniqueness(struct rand_thread_local_state *state) // |*pred_resistance_len| is set to 0 if no prediction resistance source is // available and |RAND_PRED_RESISTANCE_LEN| otherwise. static void rand_maybe_get_ctr_drbg_pred_resistance( - const struct entropy_source *entropy_source, + const struct entropy_source_t *entropy_source, uint8_t pred_resistance[RAND_PRED_RESISTANCE_LEN], size_t *pred_resistance_len) { @@ -232,8 +243,9 @@ static void rand_maybe_get_ctr_drbg_pred_resistance( *pred_resistance_len = 0; - if (entropy_source->get_prediction_resistance != NULL) { - if (entropy_source->get_prediction_resistance(pred_resistance) != 1) { + if (entropy_source->methods->get_prediction_resistance != NULL) { + if (entropy_source->methods->get_prediction_resistance( + entropy_source, pred_resistance) != 1) { abort(); } *pred_resistance_len = RAND_PRED_RESISTANCE_LEN; @@ -249,7 +261,7 @@ static void rand_maybe_get_ctr_drbg_pred_resistance( // |*extra_entropy_len| is set to 0 if no extra entropy source // is available and |CTR_DRBG_ENTROPY_LEN| otherwise. static void rand_get_ctr_drbg_seed_entropy( - const struct entropy_source *entropy_source, + const struct entropy_source_t *entropy_source, uint8_t seed[CTR_DRBG_ENTROPY_LEN], uint8_t extra_entropy[CTR_DRBG_ENTROPY_LEN], size_t *extra_entropy_len) { @@ -260,14 +272,15 @@ static void rand_get_ctr_drbg_seed_entropy( *extra_entropy_len = 0; // If the seed source is missing it is impossible to source any entropy. - if (entropy_source->get_seed(seed) != 1) { + if (entropy_source->methods->get_seed(entropy_source, seed) != 1) { abort(); } - // Not all entropy source configurations will have an extra entropy source. - // Hence, it's optional. But use it if configured. - if (entropy_source->get_extra_entropy != NULL) { - if(entropy_source->get_extra_entropy(extra_entropy) != 1) { + // Not all entropy source configurations will have a personalization string + // source. Hence, it's optional. But use it if configured. + if (entropy_source->methods->get_personalization_string != NULL) { + if(entropy_source->methods->get_personalization_string( + entropy_source, personalization_string) != 1) { abort(); } *extra_entropy_len = CTR_DRBG_ENTROPY_LEN; diff --git a/tool/bssl_bm.h b/tool/bssl_bm.h index 2671b162f6..1f58a66a8a 100644 --- a/tool/bssl_bm.h +++ b/tool/bssl_bm.h @@ -30,9 +30,7 @@ #if defined(INTERNAL_TOOL) #include <../crypto/ec_extra/internal.h> #include <../crypto/trust_token/internal.h> -#if defined(FIPS_ENTROPY_SOURCE_JITTER_CPU) #include "../third_party/jitterentropy/jitterentropy.h" -#endif // FIPS_ENTROPY_SOURCE_JITTER_CPU #endif // INTERNAL_TOOL #define BM_NAMESPACE bssl diff --git a/tool/speed.cc b/tool/speed.cc index c5d1fedcd5..ca224847b2 100644 --- a/tool/speed.cc +++ b/tool/speed.cc @@ -2348,8 +2348,8 @@ static bool SpeedSelfTest(const std::string &selected) { results.Print("self-test"); return true; } +#endif -#if defined(FIPS_ENTROPY_SOURCE_JITTER_CPU) static bool SpeedJitter(size_t chunk_size) { struct rand_data *jitter_ec = jent_entropy_collector_alloc(0, JENT_FORCE_FIPS); @@ -2385,8 +2385,6 @@ static bool SpeedJitter(std::string selected) { } return true; } -#endif -#endif static bool SpeedDHcheck(size_t prime_bit_length) { @@ -2905,12 +2903,10 @@ bool Speed(const std::vector &args) { if (!SpeedSelfTest(selected)) { return false; } -#if defined(FIPS_ENTROPY_SOURCE_JITTER_CPU) +#endif if (!SpeedJitter(selected)) { return false; } -#endif -#endif } if (g_print_json) { From 407ab80a36c62ed873f6005b25dec2b188a57d16 Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Thu, 7 Nov 2024 11:09:55 -0800 Subject: [PATCH 02/24] Use correct variable name --- crypto/fipsmodule/rand/new_rand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/fipsmodule/rand/new_rand.c b/crypto/fipsmodule/rand/new_rand.c index 9484206989..20b5badfe7 100644 --- a/crypto/fipsmodule/rand/new_rand.c +++ b/crypto/fipsmodule/rand/new_rand.c @@ -280,7 +280,7 @@ static void rand_get_ctr_drbg_seed_entropy( // source. Hence, it's optional. But use it if configured. if (entropy_source->methods->get_personalization_string != NULL) { if(entropy_source->methods->get_personalization_string( - entropy_source, personalization_string) != 1) { + entropy_source, extra_entropy) != 1) { abort(); } *extra_entropy_len = CTR_DRBG_ENTROPY_LEN; From 3c536681f7d18c54688bf63518f806a56c4751c3 Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Thu, 7 Nov 2024 12:34:15 -0800 Subject: [PATCH 03/24] Only build jitter speed when building for internal type --- tool/speed.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tool/speed.cc b/tool/speed.cc index ca224847b2..5233f10cf9 100644 --- a/tool/speed.cc +++ b/tool/speed.cc @@ -2350,6 +2350,7 @@ static bool SpeedSelfTest(const std::string &selected) { } #endif +#if defined(INTERNAL_TOOL) static bool SpeedJitter(size_t chunk_size) { struct rand_data *jitter_ec = jent_entropy_collector_alloc(0, JENT_FORCE_FIPS); @@ -2385,6 +2386,7 @@ static bool SpeedJitter(std::string selected) { } return true; } +#endif static bool SpeedDHcheck(size_t prime_bit_length) { @@ -2904,9 +2906,11 @@ bool Speed(const std::vector &args) { return false; } #endif +#if defined(INTERNAL_TOOL) if (!SpeedJitter(selected)) { return false; } +#endif } if (g_print_json) { From 0a63ba0f55017061ac853815351eebd268dd2065 Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Thu, 7 Nov 2024 14:54:17 -0800 Subject: [PATCH 04/24] Attempt to support other Windows compilers than just MSVC for Jitter --- third_party/jitterentropy/CMakeLists.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/third_party/jitterentropy/CMakeLists.txt b/third_party/jitterentropy/CMakeLists.txt index a74eebd80b..a53cb1d2d7 100644 --- a/third_party/jitterentropy/CMakeLists.txt +++ b/third_party/jitterentropy/CMakeLists.txt @@ -16,10 +16,15 @@ set(JITTER_SOURCES include_directories(${PROJECT_SOURCE_DIR}/include) -if(MSVC) - set(JITTER_COMPILE_FLAGS "/Od /W4 /DYNAMICBASE /DAWSLC") +if(WIN32) + if(MSVC) + set(JITTER_COMPILE_FLAGS "/Od /W4 /DYNAMICBASE /DAWSLC") + else() + set(JITTER_COMPILE_FLAGS "-DAWSLC -fwrapv --param ssp-buffer-size=4 -fvisibility=hidden -Wcast-align -Wmissing-field-initializers -Wshadow -Wswitch-enum -Wextra -Wall -pedantic -O0 -fwrapv -Wconversion") + endif() else() - set(JITTER_COMPILE_FLAGS "-DAWSLC -fwrapv --param ssp-buffer-size=4 -fvisibility=hidden -fPIE -Wcast-align -Wmissing-field-initializers -Wshadow -Wswitch-enum -Wextra -Wall -pedantic -fPIC -O0 -fwrapv -Wconversion") + set(CMAKE_POSITION_INDEPENDENT_CODE true) + set(JITTER_COMPILE_FLAGS "-DAWSLC -fwrapv --param ssp-buffer-size=4 -fvisibility=hidden -Wcast-align -Wmissing-field-initializers -Wshadow -Wswitch-enum -Wextra -Wall -pedantic -O0 -fwrapv -Wconversion") endif() set_source_files_properties(${JITTER_SOURCES} PROPERTIES COMPILE_FLAGS ${JITTER_COMPILE_FLAGS}) From 700cc221528abd7f13b49bad0610677ddef1a653 Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Thu, 7 Nov 2024 17:34:07 -0800 Subject: [PATCH 05/24] Make Jitter more portable and fix old compiler issues... --- third_party/jitterentropy/CMakeLists.txt | 9 ++++++++- .../arch/jitterentropy-base-windows.h | 7 +++++-- .../jitterentropy/jitterentropy-noise.c | 20 +++++++++---------- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/third_party/jitterentropy/CMakeLists.txt b/third_party/jitterentropy/CMakeLists.txt index a53cb1d2d7..9cf0536d07 100644 --- a/third_party/jitterentropy/CMakeLists.txt +++ b/third_party/jitterentropy/CMakeLists.txt @@ -24,7 +24,14 @@ if(WIN32) endif() else() set(CMAKE_POSITION_INDEPENDENT_CODE true) - set(JITTER_COMPILE_FLAGS "-DAWSLC -fwrapv --param ssp-buffer-size=4 -fvisibility=hidden -Wcast-align -Wmissing-field-initializers -Wshadow -Wswitch-enum -Wextra -Wall -pedantic -O0 -fwrapv -Wconversion") + set(JITTER_COMPILE_FLAGS "-DAWSLC -fwrapv --param ssp-buffer-size=4 -fvisibility=hidden -Wcast-align -Wmissing-field-initializers -Wshadow -Wswitch-enum -Wextra -Wall -pedantic -O0 -fwrapv") + if (GCC AND CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.3") + # -Wconversion was changed from GCC version 4.3. Prior it was meant as + # an aid in translating code from old C to modern C. It was not meant + # to help detect troublesome implicit conversions. + # https://gcc.gnu.org/wiki/NewWconversion. + list(APPEND JITTER_COMPILE_FLAGS -Wconversion) + endif() endif() set_source_files_properties(${JITTER_SOURCES} PROPERTIES COMPILE_FLAGS ${JITTER_COMPILE_FLAGS}) diff --git a/third_party/jitterentropy/arch/jitterentropy-base-windows.h b/third_party/jitterentropy/arch/jitterentropy-base-windows.h index 8b437f79bc..f92adebf32 100644 --- a/third_party/jitterentropy/arch/jitterentropy-base-windows.h +++ b/third_party/jitterentropy/arch/jitterentropy-base-windows.h @@ -42,12 +42,13 @@ #ifndef _JITTERENTROPY_BASE_X86_H #define _JITTERENTROPY_BASE_X86_H +#include + #if defined(_MSC_VER) -typedef __int64 ssize_t; +typedef uint64_t ssize_t; #include #endif -#include #include #include #include @@ -61,6 +62,7 @@ typedef __int64 ssize_t; #include #endif +#if defined(JENT_CONF_ENABLE_INTERNAL_TIMER) static void jent_get_nstime(uint64_t *out) { #if defined(_M_ARM) || defined(_M_ARM64) @@ -77,6 +79,7 @@ static void jent_get_nstime(uint64_t *out) #endif } +#endif static inline void *jent_zalloc(size_t len) { diff --git a/third_party/jitterentropy/jitterentropy-noise.c b/third_party/jitterentropy/jitterentropy-noise.c index 3f767d2602..5537f72bcb 100644 --- a/third_party/jitterentropy/jitterentropy-noise.c +++ b/third_party/jitterentropy/jitterentropy-noise.c @@ -80,7 +80,7 @@ static uint64_t jent_loop_shuffle(unsigned int bits, unsigned int min) * entropy pool using a hash. * * @ec [in] entropy collector struct -- may be NULL - * @time [in] time delta to be injected + * @time_delta [in] time delta to be injected * @loop_cnt [in] if a value not equal to 0 is set, use the given value as * number of loops to perform the hash operation * @stuck [in] Is the time delta identified as stuck? @@ -88,7 +88,7 @@ static uint64_t jent_loop_shuffle(unsigned int bits, unsigned int min) * Output: * updated hash context */ -static void jent_hash_time(struct rand_data *ec, uint64_t time, +static void jent_hash_time(struct rand_data *ec, uint64_t time_delta, uint64_t loop_cnt, unsigned int stuck) { HASH_CTX_ON_STACK(ctx); @@ -159,7 +159,7 @@ static void jent_hash_time(struct rand_data *ec, uint64_t time, * according to section 3.1.5. */ if (!stuck) - sha3_update(ec->hash_state, (uint8_t *)&time, sizeof(uint64_t)); + sha3_update(ec->hash_state, (uint8_t *)&time_delta, sizeof(uint64_t)); jent_memset_secure(&ctx, SHA_MAX_CTX_SIZE); jent_memset_secure(intermediary, sizeof(intermediary)); @@ -193,7 +193,7 @@ static inline uint32_t xoshiro128starstar(uint32_t *s) static void jent_memaccess(struct rand_data *ec, uint64_t loop_cnt) { - uint64_t i = 0, time = 0; + uint64_t i = 0, time_delta = 0; union { uint32_t u[4]; uint8_t b[sizeof(uint32_t) * 4]; @@ -221,8 +221,8 @@ static void jent_memaccess(struct rand_data *ec, uint64_t loop_cnt) * timing, so we can now benefit from the Central Limit Theorem! */ for (i = 0; i < sizeof(prngState); i++) { - jent_get_nstime_internal(ec, &time); - prngState.b[i] ^= (uint8_t)(time & 0xff); + jent_get_nstime_internal(ec, &time_delta); + prngState.b[i] ^= (uint8_t)(time_delta & 0xff); } /* @@ -336,7 +336,7 @@ unsigned int jent_measure_jitter(struct rand_data *ec, uint64_t loop_cnt, uint64_t *ret_current_delta) { - uint64_t time = 0; + uint64_t time_stamp = 0; uint64_t current_delta = 0; unsigned int stuck; @@ -347,10 +347,10 @@ unsigned int jent_measure_jitter(struct rand_data *ec, * Get time stamp and calculate time delta to previous * invocation to measure the timing variations */ - jent_get_nstime_internal(ec, &time); - current_delta = jent_delta(ec->prev_time, time) / + jent_get_nstime_internal(ec, &time_stamp); + current_delta = jent_delta(ec->prev_time, time_stamp) / ec->jent_common_timer_gcd; - ec->prev_time = time; + ec->prev_time = time_stamp; /* Check whether we have a stuck measurement. */ stuck = jent_stuck(ec, current_delta); From 5e2b9a880e97d00a32ac655af8dcfe5da9eab5ec Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Thu, 7 Nov 2024 17:45:39 -0800 Subject: [PATCH 06/24] Append as string not a list... --- third_party/jitterentropy/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/third_party/jitterentropy/CMakeLists.txt b/third_party/jitterentropy/CMakeLists.txt index 9cf0536d07..116f29e91a 100644 --- a/third_party/jitterentropy/CMakeLists.txt +++ b/third_party/jitterentropy/CMakeLists.txt @@ -30,11 +30,11 @@ else() # an aid in translating code from old C to modern C. It was not meant # to help detect troublesome implicit conversions. # https://gcc.gnu.org/wiki/NewWconversion. - list(APPEND JITTER_COMPILE_FLAGS -Wconversion) + string(APPEND JITTER_COMPILE_FLAGS " -Wconversion") endif() endif() -set_source_files_properties(${JITTER_SOURCES} PROPERTIES COMPILE_FLAGS ${JITTER_COMPILE_FLAGS}) +set_source_files_properties(${JITTER_SOURCES} PROPERTIES COMPILE_FLAGS "${JITTER_COMPILE_FLAGS}") add_library(jitterentropy OBJECT ${JITTER_SOURCES}) add_dependencies(jitterentropy boringssl_prefix_symbols) target_include_directories(jitterentropy BEFORE PRIVATE ${PROJECT_BINARY_DIR}/symbol_prefix_include) From d23e82042bfbcacd1d139ac69b3bdcb719185bd2 Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Fri, 8 Nov 2024 06:45:37 -0800 Subject: [PATCH 07/24] Consider older cmake that doesn't support APPEND for string command --- third_party/jitterentropy/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/jitterentropy/CMakeLists.txt b/third_party/jitterentropy/CMakeLists.txt index 116f29e91a..282d8f96a4 100644 --- a/third_party/jitterentropy/CMakeLists.txt +++ b/third_party/jitterentropy/CMakeLists.txt @@ -30,7 +30,7 @@ else() # an aid in translating code from old C to modern C. It was not meant # to help detect troublesome implicit conversions. # https://gcc.gnu.org/wiki/NewWconversion. - string(APPEND JITTER_COMPILE_FLAGS " -Wconversion") + set(JITTER_COMPILE_FLAGS "${JITTER_COMPILE_FLAGS} -Wconversion") endif() endif() From aaa85758f610b2e3765cf2d1ce050887e660aa4e Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Fri, 8 Nov 2024 06:54:51 -0800 Subject: [PATCH 08/24] This function is in fact used outside the internal timer config --- third_party/jitterentropy/arch/jitterentropy-base-windows.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/third_party/jitterentropy/arch/jitterentropy-base-windows.h b/third_party/jitterentropy/arch/jitterentropy-base-windows.h index f92adebf32..e03ac4b801 100644 --- a/third_party/jitterentropy/arch/jitterentropy-base-windows.h +++ b/third_party/jitterentropy/arch/jitterentropy-base-windows.h @@ -62,7 +62,6 @@ typedef uint64_t ssize_t; #include #endif -#if defined(JENT_CONF_ENABLE_INTERNAL_TIMER) static void jent_get_nstime(uint64_t *out) { #if defined(_M_ARM) || defined(_M_ARM64) @@ -79,7 +78,6 @@ static void jent_get_nstime(uint64_t *out) #endif } -#endif static inline void *jent_zalloc(size_t len) { From 733212278d42a3816ff5bb8d7462d45f1d76685b Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Fri, 8 Nov 2024 07:12:02 -0800 Subject: [PATCH 09/24] Use signed type instead of the incorrect unsigned type --- third_party/jitterentropy/arch/jitterentropy-base-windows.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/jitterentropy/arch/jitterentropy-base-windows.h b/third_party/jitterentropy/arch/jitterentropy-base-windows.h index e03ac4b801..a0ce4274cb 100644 --- a/third_party/jitterentropy/arch/jitterentropy-base-windows.h +++ b/third_party/jitterentropy/arch/jitterentropy-base-windows.h @@ -45,7 +45,7 @@ #include #if defined(_MSC_VER) -typedef uint64_t ssize_t; +typedef int64_t ssize_t; #include #endif From 71cff8dff447d10e01a0557ce603da03c58d7927 Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Fri, 8 Nov 2024 07:53:54 -0800 Subject: [PATCH 10/24] Avoid unused function warnings --- third_party/jitterentropy/arch/jitterentropy-base-windows.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/third_party/jitterentropy/arch/jitterentropy-base-windows.h b/third_party/jitterentropy/arch/jitterentropy-base-windows.h index a0ce4274cb..d44b08e9c5 100644 --- a/third_party/jitterentropy/arch/jitterentropy-base-windows.h +++ b/third_party/jitterentropy/arch/jitterentropy-base-windows.h @@ -55,6 +55,9 @@ typedef int64_t ssize_t; #if defined(AWSLC) #include +#define JITTER_ENTROPY_UNUSED OPENSSL_UNUSED +#else +#define JITTER_ENTROPY_UNUSED #endif #if defined(_M_ARM) || defined(_M_ARM64) @@ -62,7 +65,7 @@ typedef int64_t ssize_t; #include #endif -static void jent_get_nstime(uint64_t *out) +JITTER_ENTROPY_UNUSED static void jent_get_nstime(uint64_t *out) { #if defined(_M_ARM) || defined(_M_ARM64) From 7567e8ff2416a645dfe52b4f909d55716847b444 Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Fri, 8 Nov 2024 08:00:53 -0800 Subject: [PATCH 11/24] Didn't help, revert and try to silence globally for the CPU jitter library build --- third_party/jitterentropy/CMakeLists.txt | 2 +- third_party/jitterentropy/arch/jitterentropy-base-windows.h | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/third_party/jitterentropy/CMakeLists.txt b/third_party/jitterentropy/CMakeLists.txt index 282d8f96a4..e86ab3e022 100644 --- a/third_party/jitterentropy/CMakeLists.txt +++ b/third_party/jitterentropy/CMakeLists.txt @@ -20,7 +20,7 @@ if(WIN32) if(MSVC) set(JITTER_COMPILE_FLAGS "/Od /W4 /DYNAMICBASE /DAWSLC") else() - set(JITTER_COMPILE_FLAGS "-DAWSLC -fwrapv --param ssp-buffer-size=4 -fvisibility=hidden -Wcast-align -Wmissing-field-initializers -Wshadow -Wswitch-enum -Wextra -Wall -pedantic -O0 -fwrapv -Wconversion") + set(JITTER_COMPILE_FLAGS "-DAWSLC -fwrapv --param ssp-buffer-size=4 -fvisibility=hidden -Wcast-align -Wmissing-field-initializers -Wshadow -Wswitch-enum -Wno-unused-function -Wextra -Wall -pedantic -O0 -fwrapv -Wconversion") endif() else() set(CMAKE_POSITION_INDEPENDENT_CODE true) diff --git a/third_party/jitterentropy/arch/jitterentropy-base-windows.h b/third_party/jitterentropy/arch/jitterentropy-base-windows.h index d44b08e9c5..a0ce4274cb 100644 --- a/third_party/jitterentropy/arch/jitterentropy-base-windows.h +++ b/third_party/jitterentropy/arch/jitterentropy-base-windows.h @@ -55,9 +55,6 @@ typedef int64_t ssize_t; #if defined(AWSLC) #include -#define JITTER_ENTROPY_UNUSED OPENSSL_UNUSED -#else -#define JITTER_ENTROPY_UNUSED #endif #if defined(_M_ARM) || defined(_M_ARM64) @@ -65,7 +62,7 @@ typedef int64_t ssize_t; #include #endif -JITTER_ENTROPY_UNUSED static void jent_get_nstime(uint64_t *out) +static void jent_get_nstime(uint64_t *out) { #if defined(_M_ARM) || defined(_M_ARM64) From 2ba13652171f972232960c49469a33738a598c8a Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Fri, 8 Nov 2024 08:07:07 -0800 Subject: [PATCH 12/24] Nope, revert that, and just inline... --- third_party/jitterentropy/CMakeLists.txt | 2 +- third_party/jitterentropy/arch/jitterentropy-base-windows.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/third_party/jitterentropy/CMakeLists.txt b/third_party/jitterentropy/CMakeLists.txt index e86ab3e022..282d8f96a4 100644 --- a/third_party/jitterentropy/CMakeLists.txt +++ b/third_party/jitterentropy/CMakeLists.txt @@ -20,7 +20,7 @@ if(WIN32) if(MSVC) set(JITTER_COMPILE_FLAGS "/Od /W4 /DYNAMICBASE /DAWSLC") else() - set(JITTER_COMPILE_FLAGS "-DAWSLC -fwrapv --param ssp-buffer-size=4 -fvisibility=hidden -Wcast-align -Wmissing-field-initializers -Wshadow -Wswitch-enum -Wno-unused-function -Wextra -Wall -pedantic -O0 -fwrapv -Wconversion") + set(JITTER_COMPILE_FLAGS "-DAWSLC -fwrapv --param ssp-buffer-size=4 -fvisibility=hidden -Wcast-align -Wmissing-field-initializers -Wshadow -Wswitch-enum -Wextra -Wall -pedantic -O0 -fwrapv -Wconversion") endif() else() set(CMAKE_POSITION_INDEPENDENT_CODE true) diff --git a/third_party/jitterentropy/arch/jitterentropy-base-windows.h b/third_party/jitterentropy/arch/jitterentropy-base-windows.h index a0ce4274cb..b5fed7c291 100644 --- a/third_party/jitterentropy/arch/jitterentropy-base-windows.h +++ b/third_party/jitterentropy/arch/jitterentropy-base-windows.h @@ -62,7 +62,7 @@ typedef int64_t ssize_t; #include #endif -static void jent_get_nstime(uint64_t *out) +static inline void jent_get_nstime(uint64_t *out) { #if defined(_M_ARM) || defined(_M_ARM64) From 547cfcd9876ddc878e5d90fc5c32ec4e0e42a14b Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Fri, 8 Nov 2024 14:33:23 -0800 Subject: [PATCH 13/24] Allow other compilers to set Wconversion --- third_party/jitterentropy/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/jitterentropy/CMakeLists.txt b/third_party/jitterentropy/CMakeLists.txt index 282d8f96a4..3b107addcf 100644 --- a/third_party/jitterentropy/CMakeLists.txt +++ b/third_party/jitterentropy/CMakeLists.txt @@ -25,7 +25,7 @@ if(WIN32) else() set(CMAKE_POSITION_INDEPENDENT_CODE true) set(JITTER_COMPILE_FLAGS "-DAWSLC -fwrapv --param ssp-buffer-size=4 -fvisibility=hidden -Wcast-align -Wmissing-field-initializers -Wshadow -Wswitch-enum -Wextra -Wall -pedantic -O0 -fwrapv") - if (GCC AND CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.3") + if ((NOT GCC) OR (GCC AND CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.3")) # -Wconversion was changed from GCC version 4.3. Prior it was meant as # an aid in translating code from old C to modern C. It was not meant # to help detect troublesome implicit conversions. From 65754014c7ac58cba252fd5070d147f3c76477bf Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Fri, 8 Nov 2024 14:37:26 -0800 Subject: [PATCH 14/24] Add personalization string callback to match description --- crypto/fipsmodule/rand/entropy/entropy_sources.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crypto/fipsmodule/rand/entropy/entropy_sources.c b/crypto/fipsmodule/rand/entropy/entropy_sources.c index 651adcfac5..a97bd6b581 100644 --- a/crypto/fipsmodule/rand/entropy/entropy_sources.c +++ b/crypto/fipsmodule/rand/entropy/entropy_sources.c @@ -20,6 +20,13 @@ static int entropy_get_prediction_resistance( return 1; } +static int entropy_get_personalization_string( + const struct entropy_source_t *entropy_source, + uint8_t personalization_string[CTR_DRBG_ENTROPY_LEN]) { + CRYPTO_sysrand(personalization_string, CTR_DRBG_ENTROPY_LEN); + return 1; +} + // - Tree DRBG with Jitter Entropy as root for seeding. // - OS as personalization string source. // - If run-time is on an Intel CPU and it supports rdrand, use it as a source @@ -29,7 +36,7 @@ DEFINE_LOCAL_DATA(struct entropy_source_methods, tree_jitter_entropy_source_meth out->zeroize_thread = tree_jitter_zeroize_thread_drbg; out->free_thread = tree_jitter_free_thread_drbg; out->get_seed = tree_jitter_get_seed; - out->get_personalization_string = NULL; + out->get_personalization_string = entropy_get_personalization_string; if (have_fast_rdrand() == 1) { out->get_prediction_resistance = entropy_get_prediction_resistance; } else { From 443c1c883a0774daf26a3709a3340749c00d017c Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Mon, 11 Nov 2024 07:19:38 -0800 Subject: [PATCH 15/24] Fix leak on error-path --- crypto/fipsmodule/rand/entropy/entropy_sources.c | 1 + 1 file changed, 1 insertion(+) diff --git a/crypto/fipsmodule/rand/entropy/entropy_sources.c b/crypto/fipsmodule/rand/entropy/entropy_sources.c index a97bd6b581..df28a9e6d9 100644 --- a/crypto/fipsmodule/rand/entropy/entropy_sources.c +++ b/crypto/fipsmodule/rand/entropy/entropy_sources.c @@ -62,6 +62,7 @@ struct entropy_source_t * get_entropy_source(void) { entropy_source->methods->get_seed == NULL || entropy_source->methods->initialize == NULL || entropy_source->methods->initialize(entropy_source) != 1) { + OPENSSL_free(entropy_source); return NULL; } From 48d19d63a4d2a71b37f7f25477d6efc751491bcc Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Mon, 11 Nov 2024 07:25:17 -0800 Subject: [PATCH 16/24] Fix typo --- crypto/fipsmodule/rand/new_rand.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crypto/fipsmodule/rand/new_rand.c b/crypto/fipsmodule/rand/new_rand.c index 20b5badfe7..a929986c5f 100644 --- a/crypto/fipsmodule/rand/new_rand.c +++ b/crypto/fipsmodule/rand/new_rand.c @@ -73,10 +73,10 @@ static void rand_thread_local_state_clear_all(void) __attribute__ ((destructor)) // ensures |rand_thread_local_state_free| cannot free any thread state while we // own the lock. // -// When we a thread-local DRBGs is gated from returning output, we can -// invoke the entropy source zeroization from |state->entropy_source|. The -// entropy source implementation can assume that any returned seed is never -// used to generate any randomness that is later returned to a consumer. +// When a thread-local DRBGs is gated from returning output, we can invoke the +// entropy source zeroization from |state->entropy_source|. The entropy source +// implementation can assume that any returned seed is never used to generate +// any randomness that is later returned to a consumer. static void rand_thread_local_state_clear_all(void) { CRYPTO_STATIC_MUTEX_lock_write(thread_local_states_list_lock_bss_get()); for (struct rand_thread_local_state *state = *thread_states_list_head_bss_get(); From 92a5a0f0018ff32a0a0ef52923516a9a3e0a8469 Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Mon, 11 Nov 2024 07:34:45 -0800 Subject: [PATCH 17/24] expand diagram --- .../rand/entropy/tree_drbg_jitter_entropy.c | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c b/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c index 44408361df..6a2019b4bd 100644 --- a/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c +++ b/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c @@ -27,17 +27,24 @@ // // The dependency tree looks as follows: // -// per-thread -// +-----------+ -// | CTR-DRBG | -| -// +-----------+ -| -// +-----------+ --| per-process per-process -// | CTR-DRBG | ---| --> +-----------+ +---------------+ -// +-----------+ -----> | CTR-DRBG | --> |Jitter Entropy | -// ... --> +-----------+ +---------------+ -// +-----------+ -----| -// | CTR-DRBG |-| -// +-----------+ +// entropy_source +// interface +// | +// new_rand.c | tree_drbg_jitter_entropy.c +// | +// front-end | tree-DRBG +// per-thread | per-thread +// +-----------+ | +-----------+ +// | CTR-DRBG | --> | CTR-DRBG | -| +// +-----------+ | +-----------+ -| +// +-----------+ | +-----------+ --| per-process per-process +// | CTR-DRBG | --> | CTR-DRBG | ---| --> +-----------+ +---------------+ +// +-----------+ | +-----------+ -----> | CTR-DRBG | --> |Jitter Entropy | +// ... | ... --> +-----------+ +---------------+ +// +-----------+ | +-----------+ -----| +// | CTR-DRBG | --> | CTR-DRBG |-| +// +-----------+ | +-----------+ +// | // // Memory life-cycle: The thread-local DRBGs has the same storage duration as // their corresponding thread-local frontend DRBGs. The per-process DRBG and From 24391952257668ceedb7b9aa2e432267549c0eb2 Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Mon, 11 Nov 2024 07:37:21 -0800 Subject: [PATCH 18/24] use fixed-sized width that we tend to use anyway. --- crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c b/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c index 6a2019b4bd..2ae4f57317 100644 --- a/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c +++ b/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c @@ -60,6 +60,8 @@ // - tree_jitter_get_seed +// Placeholder right now until SP800-90C is ratified that might specify these +// further. // TREE_JITTER_GLOBAL_DRBG_MAX_GENERATE = 2^24 #define TREE_JITTER_GLOBAL_DRBG_MAX_GENERATE 0xFFFFFF // TREE_JITTER_THREAD_DRBG_MAX_GENERATE = 2^20 @@ -67,7 +69,7 @@ struct tree_jitter_drbg_t { // is_global is 1 if this object is the per-process seed DRBG. Otherwise 0. - char is_global; + uint8_t is_global; // drbg is the DRBG state. CTR_DRBG_STATE drbg; @@ -88,7 +90,7 @@ struct tree_jitter_drbg_t { uint64_t generation_number; // ube_protection denotes whether this object is protected from UBEs. - char ube_protection; + uint8_t ube_protection; // Jitter entropy state. NULL if not the per-process seed DRBG. struct rand_data *jitter_ec; From e5278655c12b529f440bdf7cd6a00c55d81da7db Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Mon, 11 Nov 2024 12:55:01 -0800 Subject: [PATCH 19/24] Use existing counter in DRBG object --- .../rand/entropy/tree_drbg_jitter_entropy.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c b/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c index 2ae4f57317..b15545e369 100644 --- a/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c +++ b/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c @@ -74,10 +74,6 @@ struct tree_jitter_drbg_t { // drbg is the DRBG state. CTR_DRBG_STATE drbg; - // generate_calls_since_seed is the number of generate calls made on |drbg| - // since it was last (re)seeded. Must be bounded by |kReseedInterval|. - uint64_t generate_calls_since_seed; - // max_generate_calls is the maximum number of generate calls that can be // invoked on |drbg| without a reseed. uint64_t max_generate_calls; @@ -173,7 +169,7 @@ static int tree_jitter_check_drbg_must_reseed( return 1; } - if (tree_jitter_drbg->generate_calls_since_seed + 1 > tree_jitter_drbg->max_generate_calls) { + if (tree_jitter_drbg->drbg.reseed_counter > tree_jitter_drbg->max_generate_calls) { return 1; } @@ -210,7 +206,6 @@ static void tree_jitter_drbg_derive_seed( } OPENSSL_cleanse(seed_drbg, CTR_DRBG_ENTROPY_LEN); tree_jitter_drbg->reseed_calls_since_initialization += 1; - tree_jitter_drbg->generate_calls_since_seed = 0; } uint8_t pred_resistance[RAND_PRED_RESISTANCE_LEN]; @@ -226,7 +221,6 @@ static void tree_jitter_drbg_derive_seed( abort(); } OPENSSL_cleanse(pred_resistance, RAND_PRED_RESISTANCE_LEN); - tree_jitter_drbg->generate_calls_since_seed += 1; } // tree_jitter_drbg_derive_seed generates a CTR_DRBG_ENTROPY_LEN byte seed from @@ -257,7 +251,6 @@ static void tree_jitter_initialize_once(void) { } tree_jitter_drbg_global->is_global = 1; - tree_jitter_drbg_global->generate_calls_since_seed = 0; tree_jitter_drbg_global->max_generate_calls = TREE_JITTER_GLOBAL_DRBG_MAX_GENERATE; tree_jitter_drbg_global->reseed_calls_since_initialization = 0; uint64_t current_generation_number = 0; @@ -315,7 +308,6 @@ int tree_jitter_initialize(struct entropy_source_t *entropy_source) { } OPENSSL_cleanse(seed_drbg, CTR_DRBG_ENTROPY_LEN); - tree_jitter_drbg->generate_calls_since_seed = 0; tree_jitter_drbg->max_generate_calls = TREE_JITTER_THREAD_DRBG_MAX_GENERATE; tree_jitter_drbg->reseed_calls_since_initialization = 0; uint64_t current_generation_number = 0; @@ -426,7 +418,6 @@ static void tree_jitter_zeroize_drbg( } OPENSSL_cleanse(random_data, CTR_DRBG_ENTROPY_LEN); tree_jitter_drbg->reseed_calls_since_initialization += 1; - tree_jitter_drbg->generate_calls_since_seed = 0; } // tree_jitter_zeroize_thread_drbg is similar to but also handles From b7ce18ae12d3e073511b18339f88fa556fc47447 Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Mon, 11 Nov 2024 13:12:06 -0800 Subject: [PATCH 20/24] Add function description --- crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c b/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c index b15545e369..3c8d54ee99 100644 --- a/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c +++ b/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c @@ -242,6 +242,7 @@ int tree_jitter_get_seed(const struct entropy_source_t *entropy_source, return 1; } +// tree_jitter_initialize initalizes the global seed DRBG. static void tree_jitter_initialize_once(void) { struct tree_jitter_drbg_t *tree_jitter_drbg_global = @@ -278,7 +279,7 @@ static void tree_jitter_initialize_once(void) { *global_seed_drbg_bss_get() = tree_jitter_drbg_global; } -// tree_jitter_initialize initalizes a thread-local seed DRBG as configures +// tree_jitter_initialize initalizes a thread-local seed DRBG and configures // it in |entropy_source|. If the global seed DRBG has not been initialized yet // it's also initialized. // From 165ab84a99394e8195b0e54d97bcdd64260f768c Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Mon, 11 Nov 2024 13:12:44 -0800 Subject: [PATCH 21/24] Update jitter entropy version mention --- crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c b/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c index 3c8d54ee99..e9802fa8dc 100644 --- a/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c +++ b/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c @@ -263,7 +263,7 @@ static void tree_jitter_initialize_once(void) { // The first parameter passed to |jent_entropy_collector_alloc| function is // the desired oversampling rate. Passing a 0 tells Jitter module to use - // the default rate (which is 3 in Jitter v3.1.0). + // the default rate (which is 3 in Jitter v3.4.0). tree_jitter_drbg_global->jitter_ec = jent_entropy_collector_alloc(0, JENT_FORCE_FIPS); if (tree_jitter_drbg_global->jitter_ec == NULL) { abort(); From d0ac20cfb86af3e2a8efd45e430691bbc6974937 Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Mon, 11 Nov 2024 13:14:27 -0800 Subject: [PATCH 22/24] Typo's --- crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c b/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c index e9802fa8dc..04a539187e 100644 --- a/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c +++ b/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c @@ -242,7 +242,7 @@ int tree_jitter_get_seed(const struct entropy_source_t *entropy_source, return 1; } -// tree_jitter_initialize initalizes the global seed DRBG. +// tree_jitter_initialize initializes the global seed DRBG. static void tree_jitter_initialize_once(void) { struct tree_jitter_drbg_t *tree_jitter_drbg_global = @@ -279,7 +279,7 @@ static void tree_jitter_initialize_once(void) { *global_seed_drbg_bss_get() = tree_jitter_drbg_global; } -// tree_jitter_initialize initalizes a thread-local seed DRBG and configures +// tree_jitter_initialize initializes a thread-local seed DRBG and configures // it in |entropy_source|. If the global seed DRBG has not been initialized yet // it's also initialized. // From fb5bc0323c71f779c0a8ceff3f076d69cb0617e2 Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Tue, 12 Nov 2024 11:11:03 -0800 Subject: [PATCH 23/24] Use correct method name --- crypto/fipsmodule/rand/entropy/entropy_sources.c | 8 ++++---- crypto/fipsmodule/rand/entropy/internal.h | 4 ++-- crypto/fipsmodule/rand/new_rand.c | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/crypto/fipsmodule/rand/entropy/entropy_sources.c b/crypto/fipsmodule/rand/entropy/entropy_sources.c index df28a9e6d9..333713ed98 100644 --- a/crypto/fipsmodule/rand/entropy/entropy_sources.c +++ b/crypto/fipsmodule/rand/entropy/entropy_sources.c @@ -20,10 +20,10 @@ static int entropy_get_prediction_resistance( return 1; } -static int entropy_get_personalization_string( +static int entropy_get_extra_entropy( const struct entropy_source_t *entropy_source, - uint8_t personalization_string[CTR_DRBG_ENTROPY_LEN]) { - CRYPTO_sysrand(personalization_string, CTR_DRBG_ENTROPY_LEN); + uint8_t extra_entropy[CTR_DRBG_ENTROPY_LEN]) { + CRYPTO_sysrand(extra_entropy, CTR_DRBG_ENTROPY_LEN); return 1; } @@ -36,7 +36,7 @@ DEFINE_LOCAL_DATA(struct entropy_source_methods, tree_jitter_entropy_source_meth out->zeroize_thread = tree_jitter_zeroize_thread_drbg; out->free_thread = tree_jitter_free_thread_drbg; out->get_seed = tree_jitter_get_seed; - out->get_personalization_string = entropy_get_personalization_string; + out->get_extra_entropy = entropy_get_extra_entropy; if (have_fast_rdrand() == 1) { out->get_prediction_resistance = entropy_get_prediction_resistance; } else { diff --git a/crypto/fipsmodule/rand/entropy/internal.h b/crypto/fipsmodule/rand/entropy/internal.h index 1879021ade..8900b81f76 100644 --- a/crypto/fipsmodule/rand/entropy/internal.h +++ b/crypto/fipsmodule/rand/entropy/internal.h @@ -25,8 +25,8 @@ struct entropy_source_methods { void (*free_thread)(struct entropy_source_t *entropy_source); int (*get_seed)(const struct entropy_source_t *entropy_source, uint8_t seed[CTR_DRBG_ENTROPY_LEN]); - int (*get_personalization_string)(const struct entropy_source_t *entropy_source, - uint8_t personalization_string[CTR_DRBG_ENTROPY_LEN]); + int (*get_extra_entropy)(const struct entropy_source_t *entropy_source, + uint8_t extra_entropy[CTR_DRBG_ENTROPY_LEN]); int (*get_prediction_resistance)(const struct entropy_source_t *entropy_source, uint8_t pred_resistance[RAND_PRED_RESISTANCE_LEN]); }; diff --git a/crypto/fipsmodule/rand/new_rand.c b/crypto/fipsmodule/rand/new_rand.c index a929986c5f..92c5fd8940 100644 --- a/crypto/fipsmodule/rand/new_rand.c +++ b/crypto/fipsmodule/rand/new_rand.c @@ -278,8 +278,8 @@ static void rand_get_ctr_drbg_seed_entropy( // Not all entropy source configurations will have a personalization string // source. Hence, it's optional. But use it if configured. - if (entropy_source->methods->get_personalization_string != NULL) { - if(entropy_source->methods->get_personalization_string( + if (entropy_source->methods->get_extra_entropy != NULL) { + if(entropy_source->methods->get_extra_entropy( entropy_source, extra_entropy) != 1) { abort(); } From cfd04e672655cd0c12be49e395bf5f57597dcbd3 Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Wed, 13 Nov 2024 06:45:22 -0800 Subject: [PATCH 24/24] Typo --- crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c b/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c index 04a539187e..574e783e82 100644 --- a/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c +++ b/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c @@ -392,7 +392,7 @@ void tree_jitter_free_thread_drbg(struct entropy_source_t *entropy_source) { // reseed with random data, that in turn, will override all states in the tree // with random data. The zeroization of the tree DRBG executes after the // frontend DRBGs have been locked - they can't release any generated output. -// Therefore, the randomness generation layer ensures that no output from an the +// Therefore, the randomness generation layer ensures that no output from the // tree DRBG is used to generate any output that is later released. Randomizing // the tree DRBG states therefore effectively "zeroize" the state. //