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 all 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
76 changes: 54 additions & 22 deletions crypto/fipsmodule/rand/new_rand_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
#include "new_rand_internal.h"
#include "../../ube/internal.h"

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

#include <thread>

// TODO
Expand All @@ -20,6 +23,8 @@

#define MAX_REQUEST_SIZE (CTR_DRBG_MAX_GENERATE_LENGTH * 2 + 1)

class newRandTest : public ubeTest {};

static void randBasicTests(bool *returnFlag) {
// Do not use stack arrays for these. For example, Alpine OS has too low
// default thread stack size limit to accommodate.
Expand All @@ -46,27 +51,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 +92,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 +166,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) {

allowMockedUbe();

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
6 changes: 3 additions & 3 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 Expand Up @@ -610,7 +610,7 @@ int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);

if (getenv("BORINGSSL_IGNORE_MADV_WIPEONFORK")) {
CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing();
CRYPTO_fork_detect_ignore_madv_wipeonfork_FOR_TESTING();
}

return RUN_ALL_TESTS();
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
4 changes: 2 additions & 2 deletions 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 All @@ -41,7 +41,7 @@
static void maybe_disable_some_fork_detect_mechanisms(void) {
#if defined(OPENSSL_LINUX)
if (getenv("BORINGSSL_IGNORE_MADV_WIPEONFORK")) {
CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing();
CRYPTO_fork_detect_ignore_madv_wipeonfork_FOR_TESTING();
}
#endif
}
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
34 changes: 34 additions & 0 deletions crypto/test/ube_test.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

#ifndef OPENSSL_HEADER_CRYPTO_TEST_UBE_TEST_H
#define OPENSSL_HEADER_CRYPTO_TEST_UBE_TEST_H

#include <gtest/gtest.h>

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

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

void TearDown() override {
disable_mocked_ube_detection_FOR_TESTING();
}

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

void allowMockedUbe(void) const {
allow_mocked_ube_detection_FOR_TESTING();
}

bool ube_detection_supported_ = false;
};

#endif // OPENSSL_HEADER_CRYPTO_TEST_UBE_TEST_H
Loading
Loading