Skip to content

Commit

Permalink
feat: Option to disable RAND engine override
Browse files Browse the repository at this point in the history
  • Loading branch information
goatgoose committed Feb 12, 2025
1 parent 203cc5c commit d5fc754
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 0 deletions.
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 this the case for AWS-LC.

The s2n-tls RAND engine may conflict with some environments that link to 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 not be applicable for 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

0 comments on commit d5fc754

Please sign in to comment.