Skip to content

Commit

Permalink
Implements tree-DRBG
Browse files Browse the repository at this point in the history
  • Loading branch information
torben-hansen committed Nov 7, 2024
1 parent 3b6651c commit 1ea6d8f
Show file tree
Hide file tree
Showing 10 changed files with 547 additions and 79 deletions.
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -1020,6 +1020,7 @@ if(BUILD_TESTING)
endmacro()
endif()

add_subdirectory(third_party/jitterentropy)
add_subdirectory(crypto)
if(BUILD_LIBSSL)
add_subdirectory(ssl)
Expand Down
8 changes: 1 addition & 7 deletions crypto/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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} $<TARGET_OBJECTS:crypto_objects> ${CRYPTO_FIPS_OBJECTS} ${module_source} $<TARGET_OBJECTS:jitterentropy>)
else()
add_library(${name} $<TARGET_OBJECTS:crypto_objects> ${CRYPTO_FIPS_OBJECTS} ${module_source})
endif()
add_library(${name} $<TARGET_OBJECTS:crypto_objects> ${CRYPTO_FIPS_OBJECTS} ${module_source} $<TARGET_OBJECTS:jitterentropy>)

if(FIPS_DELOCATE OR FIPS_SHARED)
add_dependencies(${name} bcm_o_target)
Expand Down
3 changes: 1 addition & 2 deletions crypto/fipsmodule/bcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@

#include "rand/new_rand.c"
#include "rand/entropy/entropy_sources.c"
#include "rand/entropy/tree_drbg_jitter_entropy.c"

#include <openssl/digest.h>
#include <openssl/hmac.h>
Expand Down Expand Up @@ -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
Expand Down
4 changes: 0 additions & 4 deletions crypto/fipsmodule/rand/cpu_jitter_test.cc
Original file line number Diff line number Diff line change
@@ -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 <gtest/gtest.h>

#include "../../test/test_util.h"
Expand Down Expand Up @@ -67,5 +65,3 @@ TEST(CPUJitterEntropyTest, Basic) {
unsigned int jitter_version = 3040000;
EXPECT_EQ(jitter_version, jent_version());
}

#endif
61 changes: 26 additions & 35 deletions crypto/fipsmodule/rand/entropy/entropy_sources.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
}
33 changes: 24 additions & 9 deletions crypto/fipsmodule/rand/entropy/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit 1ea6d8f

Please sign in to comment.