Skip to content

Commit

Permalink
Merge branch 'main' of github.com:aws/aws-lc
Browse files Browse the repository at this point in the history
  • Loading branch information
pittma committed Aug 7, 2024
2 parents c439bf0 + bf1556b commit abe1124
Show file tree
Hide file tree
Showing 156 changed files with 8,001 additions and 3,656 deletions.
4 changes: 3 additions & 1 deletion .github/docker_images/cmake_build_versions/cmake_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ set -ex -o pipefail

echo "Building CMake Version: ${CMAKE_VERSION:-unknown}"

NUM_CPU_THREADS=$(grep -c ^processor /proc/cpuinfo)

# At the moment this works fine for all versions, in the future build logic can be modified to
# look at it ${CMAKE_VERSION}.
./configure --prefix=/opt/cmake --system-curl --system-libarchive
make
make -j"${NUM_CPU_THREADS}"
make install
34 changes: 34 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Go Compatability
on:
push:
branches: [ '*' ]
pull_request:
branches: [ '*' ]
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}
cancel-in-progress: true
env:
DOCKER_BUILDKIT: 1
GOPROXY: https://proxy.golang.org,direct
jobs:
go-version-1_17_13:
if: github.repository_owner == 'aws'
env:
GOROOT: "/usr/local/go"
GO_ARCHIVE: "go1.17.13.linux-amd64.tar.gz"
runs-on: ubuntu-latest
steps:
- name: Install OS Dependencies
run: |
which go
sudo apt-get update
sudo apt-get -y --no-install-recommends install cmake gcc ninja-build make
sudo rm -rf /usr/local/go
sudo rm /usr/bin/go
wget -q "https://dl.google.com/go/${GO_ARCHIVE}"
sudo tar -C /usr/local -xf $GO_ARCHIVE
echo "${GOROOT}/bin" >> $GITHUB_PATH
- uses: actions/checkout@v3
- name: Run integration build
run: |
./tests/ci/run_fips_tests.sh
2 changes: 1 addition & 1 deletion BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ If in doubt, use the most recent stable version of each build tool.
`PERL_EXECUTABLE`.
* To build without Perl (not recommended) see [this section.](#using-pre-generated-build-files)

* [Go](https://golang.org/dl/) 1.18 or later is required. If not found by
* [Go](https://golang.org/dl/) 1.17.13 or later is required. If not found by
CMake, the go executable may be configured explicitly by setting
`GO_EXECUTABLE`.
* To build without Go (not recommended) see [this section.](#using-pre-generated-build-files)
Expand Down
2 changes: 1 addition & 1 deletion cmake/go.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ elseif(NOT DISABLE_GO)
string(REGEX MATCH "([0-9]+\\.)*[0-9]+" go_version ${go_version_output})

# This should track /go.mod and /BUILDING.md
set(minimum_go_version "1.18")
set(minimum_go_version "1.17.13")
if(go_version VERSION_LESS minimum_go_version)
message(FATAL_ERROR "Go compiler version must be at least ${minimum_go_version}. Found version ${go_version}")
else()
Expand Down
8 changes: 7 additions & 1 deletion crypto/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,8 @@ add_library(
lhash/lhash.c
mem.c
ml_kem/ml_kem_512_ipd.c
ml_kem/ml_kem_768_ipd.c
ml_kem/ml_kem_1024_ipd.c
ml_kem/ml_kem.c
obj/obj.c
obj/obj_xref.c
Expand Down Expand Up @@ -699,7 +701,11 @@ else()
build_libcrypto(crypto $<TARGET_OBJECTS:fipsmodule>)
endif()

if(NOT ANDROID)
# CMAKE_SYSTEM_NAME is "Generic" for embedded OSes:
# https://cmake.org/cmake/help/book/mastering-cmake/chapter/Cross%20Compiling%20With%20CMake.html#toolchain-files
#
# For now we assume embedded OSes do not have threads.
if(NOT (ANDROID OR CMAKE_SYSTEM_NAME STREQUAL "Generic"))
find_package(Threads REQUIRED)
target_link_libraries(crypto PUBLIC Threads::Threads)
endif()
Expand Down
68 changes: 59 additions & 9 deletions crypto/bio/bio.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,17 +212,26 @@ int BIO_gets(BIO *bio, char *buf, int len) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return -2;
}
int ret = 0;
if (HAS_CALLBACK(bio)) {
ret = (int)bio->callback_ex(bio, BIO_CB_GETS, buf, len, 0, 0L, 1L, NULL);
if (ret <= 0) {
return ret;
}
}
if (!bio->init) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
return -2;
}
if (len <= 0) {
return 0;
}
int ret = bio->method->bgets(bio, buf, len);
ret = bio->method->bgets(bio, buf, len);
if (ret > 0) {
bio->num_read += ret;
}
ret = call_bio_callback_with_processed(bio, BIO_CB_GETS | BIO_CB_RETURN, buf,
len, ret);
return ret;
}

Expand Down Expand Up @@ -299,13 +308,42 @@ int BIO_write_all(BIO *bio, const void *data, size_t len) {
}

int BIO_puts(BIO *bio, const char *in) {
size_t len = strlen(in);
if (len > INT_MAX) {
// |BIO_write| and the return value both assume the string fits in |int|.
OPENSSL_PUT_ERROR(BIO, ERR_R_OVERFLOW);
return -1;
// Check for bwrites here since we use that if bputs is NULL
if (bio == NULL || bio->method == NULL || (bio->method->bwrite == NULL &&
bio->method->bputs == NULL)) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return -2;
}
return BIO_write(bio, in, (int)len);
int ret = 0;
if(HAS_CALLBACK(bio)) {
ret = (int)bio->callback_ex(bio, BIO_CB_PUTS, in, 0, 0, 0L, 1L, NULL);
if (ret <= 0) {
return ret;
}
}

if (!bio->init) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
return -2;
}
if (bio->method->bputs != NULL) {
ret = bio->method->bputs(bio, in);
} else {
const size_t len = strlen(in);
if (len > INT_MAX) {
// |BIO_write| and the return value both assume the string fits in |int|.
OPENSSL_PUT_ERROR(BIO, ERR_R_OVERFLOW);
return -1;
}
ret = bio->method->bwrite(bio, in, len);
}
if (ret > 0) {
bio->num_write += ret;
}
ret = call_bio_callback_with_processed(bio, BIO_CB_PUTS | BIO_CB_RETURN,
in, 0, ret);

return ret;
}

int BIO_flush(BIO *bio) {
Expand All @@ -321,8 +359,20 @@ long BIO_ctrl(BIO *bio, int cmd, long larg, void *parg) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return -2;
}
long ret = 0;
if (HAS_CALLBACK(bio)) {
ret = bio->callback_ex(bio, BIO_CB_CTRL, parg, 0, cmd, larg, 1L, NULL);
if (ret <= 0) {
return ret;
}
}

return bio->method->ctrl(bio, cmd, larg, parg);
ret = bio->method->ctrl(bio, cmd, larg, parg);
if (HAS_CALLBACK(bio)) {
ret = bio->callback_ex(bio, BIO_CB_CTRL | BIO_CB_RETURN, parg, 0, cmd, larg,
ret, NULL);
}
return ret;
}

char *BIO_ptr_ctrl(BIO *b, int cmd, long larg) {
Expand Down Expand Up @@ -838,7 +888,7 @@ void BIO_set_shutdown(BIO *bio, int shutdown) { bio->shutdown = shutdown; }
int BIO_get_shutdown(BIO *bio) { return bio->shutdown; }

int BIO_meth_set_puts(BIO_METHOD *method, int (*puts)(BIO *, const char *)) {
// Ignore the parameter. We implement |BIO_puts| using |BIO_write|.
method->bputs = puts;
return 1;
}

Expand Down
180 changes: 180 additions & 0 deletions crypto/bio/bio_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1095,3 +1095,183 @@ TEST(BIOTest, ReadWriteEx) {
EXPECT_FALSE(BIO_read_ex(bio.get(), nullptr, 0, &read));
EXPECT_EQ(read, (size_t)0);
}

TEST(BIOTest, TestPutsAsWrite) {
// By default, |BIO_puts| acts as |BIO_write|.
bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
ASSERT_TRUE(bio);

// Test basic puts and read
uint8_t buf[32];
EXPECT_EQ(12, BIO_puts(bio.get(), "hello world\n"));
EXPECT_EQ(12, BIO_read(bio.get(), buf, sizeof(buf)));
}

namespace {
// Define custom BIO and BIO_METHODS to test BIO_puts without write
static int customPuts(BIO *b, const char *in) {
return 0;
}
static int customNew(BIO *b) {
b->init=1;
return 1;
}
static const BIO_METHOD custom_method = {
BIO_TYPE_NONE, "CustomBioMethod", NULL /* write */,
NULL, customPuts, NULL,
NULL, customNew, NULL,
NULL
};

static const BIO_METHOD *BIO_cust(void) { return &custom_method; }

TEST(BIOTest, TestCustomPuts) {
bssl::UniquePtr<BIO> bio(BIO_new(BIO_cust()));
ASSERT_TRUE(bio);

ASSERT_EQ(0, BIO_puts(bio.get(), "hello world"));

// Test setting new puts method by creating a new BIO
bssl::UniquePtr<BIO_METHOD> method(BIO_meth_new(0, nullptr));
ASSERT_TRUE(method);
ASSERT_TRUE(BIO_meth_set_create(
method.get(), [](BIO *b) -> int {
BIO_set_init(b, 1);
return 1;
}));
ASSERT_TRUE(BIO_meth_set_puts(
method.get(), [](BIO *b, const char *in) -> int {
return 100;
}
));
bssl::UniquePtr<BIO> bio1(BIO_new(method.get()));
ASSERT_TRUE(bio1);
ASSERT_TRUE(bio1.get()->method->bputs);
ASSERT_FALSE(bio1.get()->method->bwrite);
// The new BIO_puts should only return 100
ASSERT_EQ(100, BIO_puts(bio1.get(), "hello world"));
}

TEST(BIOTest, TestPutsNullMethod) {
// Create new BIO to test when neither puts nor write is set
bssl::UniquePtr<BIO_METHOD> method(BIO_meth_new(0, nullptr));
ASSERT_TRUE(method);
ASSERT_TRUE(BIO_meth_set_create(
method.get(), [](BIO *b) -> int {
BIO_set_init(b, 1);
return 1;
}));
bssl::UniquePtr<BIO> bio(BIO_new(method.get()));
ASSERT_TRUE(bio);

ASSERT_FALSE(bio.get()->method->bputs);
ASSERT_FALSE(bio.get()->method->bwrite);
ASSERT_EQ(-2, BIO_puts(bio.get(), "hello world"));
}
} //namespace

TEST(BIOTest, TestPutsCallbacks) {
bio_callback_cleanup();
BIO* bio = BIO_new(BIO_s_mem());
ASSERT_TRUE(bio);

BIO_set_callback_ex(bio, bio_cb_ex);

EXPECT_EQ(TEST_DATA_WRITTEN, BIO_puts(bio, "12345"));

ASSERT_EQ(param_oper_ex[0], BIO_CB_PUTS);
ASSERT_EQ(param_oper_ex[1], BIO_CB_PUTS | BIO_CB_RETURN);

ASSERT_EQ(param_argp_ex[0], param_argp_ex[1]);
ASSERT_EQ(param_ret_ex[0], 1);
ASSERT_EQ(param_ret_ex[1], TEST_DATA_WRITTEN);

// len unused in puts callback
ASSERT_FALSE(param_len_ex[0]);
ASSERT_FALSE(param_len_ex[1]);

ASSERT_EQ(param_argi_ex[0], 0);
ASSERT_EQ(param_argi_ex[1], 0);
ASSERT_EQ(param_argl_ex[0], 0);
ASSERT_EQ(param_argl_ex[1], 0);

ASSERT_EQ(param_processed_ex[0], 0u);
ASSERT_EQ(param_processed_ex[1], 5u);

// The mock should be "full" at this point
ASSERT_EQ(test_count_ex, CB_TEST_COUNT);

bio_callback_cleanup();
ASSERT_EQ(BIO_free(bio), 1);
}

TEST(BIOTest, TestGetsCallback) {
bio_callback_cleanup();

BIO* bio = BIO_new(BIO_s_mem());
ASSERT_TRUE(bio);
// write data to BIO, then set callback
EXPECT_EQ(TEST_DATA_WRITTEN, BIO_write(bio, "12345", TEST_DATA_WRITTEN));
char buf[TEST_BUF_LEN];
BIO_set_callback_ex(bio, bio_cb_ex);

ASSERT_EQ(TEST_DATA_WRITTEN, BIO_gets(bio, buf, sizeof(buf)));

ASSERT_EQ(param_oper_ex[0], BIO_CB_GETS);
ASSERT_EQ(param_oper_ex[1], BIO_CB_GETS | BIO_CB_RETURN);

ASSERT_EQ(param_argp_ex[0], param_argp_ex[1]);
ASSERT_EQ(param_ret_ex[0], 1);
ASSERT_EQ(param_ret_ex[1], TEST_DATA_WRITTEN);

ASSERT_EQ(param_len_ex[0], (size_t)TEST_BUF_LEN);
ASSERT_EQ(param_len_ex[1], (size_t)TEST_BUF_LEN);

ASSERT_EQ(param_argi_ex[0], 0);
ASSERT_EQ(param_argi_ex[1], 0);
ASSERT_EQ(param_argl_ex[0], 0);
ASSERT_EQ(param_argl_ex[1], 0);

ASSERT_EQ(param_processed_ex[0], 0u);
ASSERT_EQ(param_processed_ex[1], 5u);

ASSERT_EQ(test_count_ex, CB_TEST_COUNT);

bio_callback_cleanup();
ASSERT_EQ(BIO_free(bio), 1);
}

TEST(BIOTest, TestCtrlCallback) {
bio_callback_cleanup();

BIO* bio = BIO_new(BIO_s_mem());
ASSERT_TRUE(bio);
BIO_set_callback_ex(bio, bio_cb_ex);

char buf[TEST_BUF_LEN];
// Test BIO_ctrl. This is not normally called directly so we can use one of
// the macros such as BIO_reset to test it
ASSERT_EQ(BIO_reset(bio), 1);

ASSERT_EQ(param_oper_ex[0], BIO_CB_CTRL);
ASSERT_EQ(param_oper_ex[1], BIO_CB_CTRL | BIO_CB_RETURN);

// argi in this case in the cmd sent to the ctrl method
ASSERT_EQ(param_argi_ex[0], BIO_CTRL_RESET);
ASSERT_EQ(param_argi_ex[1], BIO_CTRL_RESET);

// BIO_ctrl of a memory bio sets ret to 1 when it calls the reset method
ASSERT_EQ(param_ret_ex[0], 1);
ASSERT_EQ(param_ret_ex[1], 1);

// processed is unused in ctrl
ASSERT_EQ(param_processed_ex[0], 0u);
ASSERT_EQ(param_processed_ex[1], 0u);

bio_callback_cleanup();
// check that BIO_reset was called correctly
ASSERT_EQ(BIO_gets(bio, buf, sizeof(buf)), 0);

bio_callback_cleanup();
ASSERT_EQ(BIO_free(bio), 1);
}
Loading

0 comments on commit abe1124

Please sign in to comment.