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

feat: Option to disable RAND engine override #5108

Merged
merged 3 commits into from
Feb 19, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ loaded in an application with an otherwise conflicting libcrypto version." OFF)
option(S2N_LTO, "Enables link time optimizations when building s2n-tls." OFF)
option(S2N_STACKTRACE "Enables stacktrace functionality in s2n-tls. Note that this functionality is
only available on platforms that support execinfo." ON)
option(S2N_OVERRIDE_LIBCRYPTO_RAND_ENGINE "Allow s2n-tls to override the libcrypto random implementation with the custom
s2n-tls implementation, when appropriate. Disabling this flag is not recommended. See docs/BUILD.md for details." ON)
option(COVERAGE "Enable profiling collection for code coverage calculation" OFF)
option(BUILD_TESTING "Build tests for s2n-tls. By default only unit tests are built." ON)
option(S2N_INTEG_TESTS "Enable the integrationv2 tests" OFF)
Expand Down Expand Up @@ -247,6 +249,11 @@ if (COVERAGE)
target_link_options(${PROJECT_NAME} PUBLIC -fprofile-instr-generate -fcoverage-mapping)
endif()

if (NOT S2N_OVERRIDE_LIBCRYPTO_RAND_ENGINE)
message(STATUS "Disabling libcrypto RAND engine override")
add_definitions(-DS2N_DISABLE_RAND_ENGINE_OVERRIDE)
endif()

# For interning, we need to find the static libcrypto library. Cmake configs
# can branch on the variable BUILD_SHARED_LIBS to e.g. avoid having to define
# multiple targets. An example is AWS-LC:
Expand Down
52 changes: 52 additions & 0 deletions codebuild/spec/buildspec_disable_rand_override.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You may not use
# this file except in compliance with the License. A copy of the License is
# located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied. See the License for the specific language governing permissions and
# limitations under the License.
version: 0.2

env:
shell: bash
variables:
# Select a libcrypto where s2n-tls will override the RAND engine by default.
S2N_LIBCRYPTO: "openssl-1.0.2"

phases:
build:
on-failure: ABORT
commands:
- |
cmake . -Brand_override_enabled \
-DCMAKE_PREFIX_PATH=/usr/local/"${S2N_LIBCRYPTO}" \
-DCMAKE_BUILD_TYPE=RelWithDebInfo
- cmake --build ./rand_override_enabled -- -j $(nproc)
- |
cmake . -Brand_override_disabled \
-DCMAKE_PREFIX_PATH=/usr/local/"${S2N_LIBCRYPTO}" \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DS2N_OVERRIDE_LIBCRYPTO_RAND_ENGINE=0
- cmake --build ./rand_override_disabled -- -j $(nproc)
post_build:
on-failure: ABORT
commands:
- export CTEST_OUTPUT_ON_FAILURE=1
- export CTEST_PARALLEL_LEVEL=$(nproc)
# Run the s2n-tls tests with the assumption that the RAND engine override feature will be
# disabled. This will enable tests that ensure it's disabled.
- export S2N_DISABLE_RAND_ENGINE_OVERRIDE_EXPECTED=1
- make -C rand_override_disabled test
# If the RAND engine override is not actually disabled, tests that expect it to be should fail.
- echo "The following is a negative test, and is expected to fail."
- |
! make -C rand_override_enabled test -- ARGS="-R 's2n_random_test'"
# The tests should succeed without this assumption.
- unset S2N_DISABLE_RAND_ENGINE_OVERRIDE_EXPECTED
- make -C rand_override_enabled test -- ARGS="-R 's2n_random_test'"
6 changes: 6 additions & 0 deletions codebuild/spec/buildspec_generalbatch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -277,3 +277,9 @@ batch:
privileged-mode: true
compute-type: BUILD_GENERAL1_LARGE
image: 024603541914.dkr.ecr.us-west-2.amazonaws.com/docker:ubuntu22codebuild
- identifier: DisableRandOverride
buildspec: codebuild/spec/buildspec_disable_rand_override.yml
env:
privileged-mode: true
compute-type: BUILD_GENERAL1_LARGE
image: 024603541914.dkr.ecr.us-west-2.amazonaws.com/docker:ubuntu22codebuild
14 changes: 14 additions & 0 deletions docs/BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,20 @@ The entire list of s2n-tls CMake options can be viewed with the following comman
cmake . -LH
```

### RAND engine override

By default, s2n-tls may override the libcrypto random implementation with its custom implementation. This allows the libcrypto APIs invoked by s2n-tls to internally use the s2n-tls random implementation when fetching random bytes.

The motivation for this behavior is twofold:
1. Ensure that s2n-tls usage is safe when linked to a libcrypto with known issues in its random implementation, such as OpenSSL 1.0.2. See https://wiki.openssl.org/index.php/Random_fork-safety for details.
2. Ensure that s2n-tls usage is safe when used in snapshot environments. Some applications, such as [Lambda SnapStart](https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html), take a snapshot of the memory and disk state, and later restore this state to a virtual machine. Precautions must be taken when running inside a restored snapshot environment to ensure that randomly generated data remains unique between restored snapshots. See the Lambda SnapStart documentation for details: https://docs.aws.amazon.com/lambda/latest/dg/snapstart-uniqueness.html

When both of the above concerns are known to be mitigated in the linked libcrypto's random implementation, s2n-tls will not override the libcrypto's implementation, as is the case for AWS-LC.

The s2n-tls RAND engine may conflict with some environments that use the same libcrypto as s2n-tls, if, for example, the environment has certain requirements for the libcrypto RAND engine that the s2n-tls implementation doesn't provide, or if the environment implements its own RAND engine. In this case, consider enabling libcrypto interning with the `S2N_INTERN_LIBCRYPTO` CMake option, which will build s2n-tls with its own libcrypto that's isolated from the rest of the environment.

If the s2n-tls RAND engine conflicts with your environment and enabling libcrypto interning is not a viable option, s2n-tls can be forced to disable overriding the RAND engine by setting the `S2N_OVERRIDE_LIBCRYPTO_RAND_ENGINE` CMake flag to false when building s2n-tls. This is not recommended unless both of concerns described above are confirmed to be inapplicable to your use case.

## Building with a specific libcrypto

s2n-tls has a dependency on a libcrypto library. A supported libcrypto must be linked to s2n-tls when building. The following libcrypto libraries are currently supported:
Expand Down
8 changes: 8 additions & 0 deletions tests/unit/s2n_random_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,14 @@ int main(int argc, char **argv)
EXPECT_TRUE(s2n_libcrypto_is_openssl());
EXPECT_FALSE(s2n_is_in_fips_mode());
}

/* Ensure that disabling the S2N_OVERRIDE_LIBCRYPTO_RAND_ENGINE CMake option disables the
* custom rand override feature. When the S2N_DISABLE_RAND_ENGINE_OVERRIDE_EXPECTED
* environment variable is set, this CMake option is expected to be disabled.
*/
if (getenv("S2N_DISABLE_RAND_ENGINE_OVERRIDE_EXPECTED")) {
EXPECT_FALSE(s2n_supports_custom_rand());
}
};

/* For each test case, creates a child process that runs the test case.
Expand Down
2 changes: 2 additions & 0 deletions utils/s2n_random.c
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,8 @@ bool s2n_supports_custom_rand(void)
{
#if !defined(S2N_LIBCRYPTO_SUPPORTS_ENGINE)
return false;
#elif defined(S2N_DISABLE_RAND_ENGINE_OVERRIDE)
return false;
#else
return s2n_libcrypto_is_openssl() && !s2n_is_in_fips_mode();
#endif
Expand Down
Loading