Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable UBE backends and move out of module #2022

Merged
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions crypto/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,8 @@ add_library(
trust_token/trust_token.c
trust_token/voprf.c
ube/ube.c
ube/fork_detect.c
ube/snapsafe_detect.c
x509/a_digest.c
x509/a_sign.c
x509/a_verify.c
Expand Down Expand Up @@ -799,8 +801,6 @@ if(BUILD_TESTING)
fipsmodule/pbkdf/pbkdf_test.cc
fipsmodule/rand/ctrdrbg_test.cc
fipsmodule/rand/cpu_jitter_test.cc
fipsmodule/rand/fork_detect_test.cc
fipsmodule/rand/snapsafe_detect_test.cc
fipsmodule/rand/new_rand_test.cc
fipsmodule/service_indicator/service_indicator_test.cc
fipsmodule/sha/sha_test.cc
Expand Down Expand Up @@ -837,6 +837,8 @@ if(BUILD_TESTING)
thread_test.cc
trust_token/trust_token_test.cc
ube/ube_test.cc
ube/fork_detect_test.cc
ube/snapsafe_detect_test.cc
x509/tab_test.cc
x509/x509_test.cc
x509/x509_time_test.cc
Expand Down
2 changes: 0 additions & 2 deletions crypto/fipsmodule/bcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,7 @@
#include "modes/polyval.c"
#include "pbkdf/pbkdf.c"
#include "rand/ctrdrbg.c"
#include "rand/fork_detect.c"
#include "rand/rand.c"
#include "rand/snapsafe_detect.c"
#include "rand/urandom.c"
#include "rsa/blinding.c"
#include "rsa/padding.c"
Expand Down
99 changes: 77 additions & 22 deletions crypto/fipsmodule/rand/new_rand_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,40 @@
#include "new_rand_internal.h"
#include "../../ube/internal.h"

#include "../../test/test_util.h"

#include <thread>

// TODO
// Remove when promoting to default
#if !defined(BORINGSSL_PREFIX)

class newRandTest : public ::testing::Test {
public:
void SetUp() override {
uint64_t current_generation_number = 0;
ube_detection_supported_ = CRYPTO_get_ube_generation_number(
&current_generation_number);
}

void TearDown() override {
allow_mocked_ube_detection_FOR_TESTING(0);
}

protected:
bool UbeIsSupported(void) {
return ube_detection_supported_;
}

void allowMockedUbeIfNecessary(void) {
if (ube_detection_supported_) {
allow_mocked_ube_detection_FOR_TESTING(1);
}
}

bool ube_detection_supported_ = false;
};

#define COMPILATION_UNIT_NR_PREFIX
#include "new_rand_prefix.h"

Expand Down Expand Up @@ -46,27 +74,11 @@ static void randBasicTests(bool *returnFlag) {
*returnFlag = true;
}

TEST(NewRand, Basic) {
#if defined(OPENSSL_THREADS)
constexpr size_t kNumThreads = 10;
bool myFlags[kNumThreads] = {false};
std::thread myThreads[kNumThreads];

for (size_t i = 0; i < kNumThreads; i++) {
myThreads[i] = std::thread(randBasicTests, &myFlags[i]);
}
for (size_t i = 0; i < kNumThreads; i++) {
myThreads[i].join();
ASSERT_TRUE(myFlags[i]) << "Thread " << i << " failed.";
}
#else
bool myFlag = false;
randBasicTests(&myFlag);
ASSERT_TRUE(myFlag);
#endif
TEST_F(newRandTest, Basic) {
ASSERT_TRUE(threadTest(10, randBasicTests));
}

TEST(NewRand, ReseedInterval) {
static void randReseedIntervalUbeIsSupportedTests(bool *returnFlag) {
uint8_t *randomness = (uint8_t *) OPENSSL_zalloc(CTR_DRBG_MAX_GENERATE_LENGTH * 5 + 1);
bssl::UniquePtr<uint8_t> deleter(randomness);
uint64_t reseed_calls_since_initialization = get_thread_reseed_calls_since_initialization();
Expand Down Expand Up @@ -103,6 +115,48 @@ TEST(NewRand, ReseedInterval) {
ASSERT_TRUE(RAND_bytes(randomness, request_len_new_reseed));
ASSERT_EQ(get_thread_reseed_calls_since_initialization(), reseed_calls_since_initialization + 2);
ASSERT_EQ(get_thread_generate_calls_since_seed(), 1ULL);

*returnFlag = true;
}

TEST_F(newRandTest, ReseedIntervalWhenUbeIsSupported) {
if (!UbeIsSupported()) {
GTEST_SKIP() << "UBE detection is not supported";
}
ASSERT_TRUE(threadTest(10, randReseedIntervalUbeIsSupportedTests));
}

static void randReseedIntervalUbeNotSupportedTests(bool *returnFlag) {
uint8_t *randomness = (uint8_t *) OPENSSL_zalloc(CTR_DRBG_MAX_GENERATE_LENGTH);
bssl::UniquePtr<uint8_t> deleter(randomness);
uint64_t generate_calls_since_seed = get_thread_generate_calls_since_seed();
uint64_t reseed_calls_since_initialization = get_thread_reseed_calls_since_initialization();

if (kCtrDrbgReseedInterval - generate_calls_since_seed < 2) {
// Ensure the reseed interval doesn't conflict with logic below.
ASSERT_TRUE(RAND_bytes(randomness, 1));
ASSERT_TRUE(RAND_bytes(randomness, 1));
}

// Each invocation of the randomness generation induce a reseed due to UBE
// detection not being supported.
ASSERT_TRUE(RAND_bytes(randomness, 1));
ASSERT_EQ(get_thread_generate_calls_since_seed(), 1ULL);
ASSERT_EQ(get_thread_reseed_calls_since_initialization(), reseed_calls_since_initialization + 1);

ASSERT_TRUE(RAND_bytes(randomness, 1));
ASSERT_EQ(get_thread_generate_calls_since_seed(), 1ULL);
ASSERT_EQ(get_thread_reseed_calls_since_initialization(), reseed_calls_since_initialization + 2);

*returnFlag = true;
}

TEST_F(newRandTest, ReseedIntervalWhenUbeNotSupported) {
andrewhop marked this conversation as resolved.
Show resolved Hide resolved

if (UbeIsSupported()) {
GTEST_SKIP() << "UBE detection is supported";
}
ASSERT_TRUE(threadTest(10, randReseedIntervalUbeNotSupportedTests));
}

static void MockedUbeDetection(std::function<void(uint64_t)> set_detection_method_gn) {
Expand Down Expand Up @@ -135,15 +189,16 @@ static void MockedUbeDetection(std::function<void(uint64_t)> set_detection_metho
ASSERT_EQ(get_thread_generate_calls_since_seed(), 2ULL);
}

TEST(NewRand, UbeDetectionForkMocked) {
TEST_F(newRandTest, UbeDetectionMocked) {

allowMockedUbeIfNecessary();

MockedUbeDetection(
[](uint64_t gn) {
set_fork_generation_number_FOR_TESTING(gn);
}
);
}

TEST(NewRand, UbeDetectionSnapsafeMocked) {
MockedUbeDetection(
[](uint64_t gn) {
set_snapsafe_generation_number_FOR_TESTING(static_cast<uint32_t>(gn));
Expand Down
4 changes: 2 additions & 2 deletions crypto/fipsmodule/rand/rand.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
#include <openssl/type_check.h>

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

Expand Down
4 changes: 2 additions & 2 deletions crypto/fipsmodule/rand/urandom_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#include "getrandom_fillin.h"
#include "internal.h"
#include "snapsafe_detect.h"
#include "../../ube/snapsafe_detect.h"

#if defined(OPENSSL_X86_64) && !defined(BORINGSSL_SHARED_LIBRARY) && \
!defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) && \
Expand All @@ -33,7 +33,7 @@
#include <sys/syscall.h>
#include <sys/user.h>

#include "fork_detect.h"
#include "../../ube/fork_detect.h"
#include "getrandom_fillin.h"

#include <cstdlib>
Expand Down
2 changes: 1 addition & 1 deletion crypto/fipsmodule/rsa/rsa_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
#include "../bn/internal.h"
#include "../../internal.h"
#include "../delocate.h"
#include "../rand/fork_detect.h"
#include "../../ube/fork_detect.h"

static int ensure_fixed_copy(BIGNUM **out, const BIGNUM *in, int width) {
if (*out != NULL) {
Expand Down
2 changes: 1 addition & 1 deletion crypto/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@
#include <openssl/stack.h>
#include <openssl/thread.h>

#include "fipsmodule/rand/snapsafe_detect.h"
#include "ube/snapsafe_detect.h"

#include <assert.h>
#include <string.h>
Expand Down
2 changes: 1 addition & 1 deletion crypto/rand_extra/rand_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#include <openssl/span.h>

#include "../fipsmodule/rand/fork_detect.h"
#include "../ube/fork_detect.h"
#include "../fipsmodule/rand/internal.h"
#include "../test/abi_test.h"
#include "../test/test_util.h"
Expand Down
69 changes: 69 additions & 0 deletions crypto/test/test_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@

#include "test_util.h"

#include <fstream>
#include <ostream>
#include <stdio.h>

#include "../internal.h"
#include "openssl/pem.h"
Expand Down Expand Up @@ -156,3 +158,70 @@ void CustomDataFree(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
free(ptr);
}

bool osIsAmazonLinux(void) {
bool res = false;
#if defined(OPENSSL_LINUX)
// Per https://docs.aws.amazon.com/linux/al2023/ug/naming-and-versioning.html.
std::ifstream amazonLinuxSpecificFile("/etc/amazon-linux-release-cpe");
if (amazonLinuxSpecificFile.is_open()) {
// Definitely on Amazon Linux.
amazonLinuxSpecificFile.close();
return true;
}

// /etc/amazon-linux-release-cpe was introduced in AL2023. For earlier, parse
// and read /etc/system-release-cpe.
std::ifstream osRelease("/etc/system-release-cpe");
if (!osRelease.is_open()) {
return false;
}

std::string line;
while (std::getline(osRelease, line)) {
// AL2:
// $ cat /etc/system-release-cpe
// cpe:2.3:o:amazon:amazon_linux:2
//
// AL2023:
// $ cat /etc/system-release-cpe
// cpe:2.3:o:amazon:amazon_linux:2023
if (line.find("amazon") != std::string::npos) {
res = true;
} else if (line.find("amazon_linux") != std::string::npos) {
res = true;
}
}
osRelease.close();
#endif
return res;
}

bool threadTest(const size_t numberOfThreads, std::function<void(bool*)> testFunc) {
bool res = true;

#if defined(OPENSSL_THREADS)
// char to be able to pass-as-reference.
std::vector<char> retValueVec(numberOfThreads, 0);
std::vector<std::thread> threadVec;

for (size_t i = 0; i < numberOfThreads; i++) {
threadVec.emplace_back(testFunc, reinterpret_cast<bool*>(&retValueVec[i]));
}

for (auto& thread : threadVec) {
thread.join();
}

for (size_t i = 0; i < numberOfThreads; i++) {
if (!static_cast<bool>(retValueVec[i])) {
fprintf(stderr, "Thread %lu failed\n", (long unsigned int) i);
res = false;
}
}

#else
testFunc(&res);
#endif

return res;
}
12 changes: 12 additions & 0 deletions crypto/test/test_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
#include <stdio.h>
#include <string.h>

#include <functional>
#include <iosfwd>
#include <string>
#include <thread>
#include <vector>

#include <openssl/span.h>
Expand Down Expand Up @@ -103,6 +105,16 @@ size_t createTempFILEpath(char buffer[PATH_MAX]);
FILE* createRawTempFILE();
TempFILE createTempFILE();

// Returns true if operating system is Amazon Linux and false otherwise.
// Determined at run-time and requires read-permissions to /etc.
bool osIsAmazonLinux(void);

// Executes |testFunc| simultaneously in |numberThreads| number of threads. If
// OPENSSL_THREADS is not defined, executes |testFunc| a single time
// non-concurrently.
bool threadTest(const size_t numberOfThreads,
std::function<void(bool*)> testFunc);

// CustomData is for testing new structs that we add support for |ex_data|.
typedef struct {
int custom_data;
Expand Down
Loading
Loading