Skip to content

Commit

Permalink
refactor: add a s2n_libcrypto_is_openssl() helper function (aws#4930)
Browse files Browse the repository at this point in the history
  • Loading branch information
toidiu authored Dec 4, 2024
1 parent 68e5508 commit ecf2835
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 18 deletions.
23 changes: 15 additions & 8 deletions crypto/s2n_fips.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,24 @@

static bool s2n_fips_mode_enabled = false;

/* FIPS mode can be checked if OpenSSL was configured and built for FIPS which then defines OPENSSL_FIPS.
/* Check if the linked libcrypto has FIPS mode enabled.
*
* AWS-LC always defines FIPS_mode() that you can call and check what the library was built with. It does not define
* a public OPENSSL_FIPS/AWSLC_FIPS macro that we can (or need to) check here
* This method indicates the state of the libcrypto, NOT the state
* of s2n-tls and should ONLY be called during library initialization (i.e.
* s2n_init()). For example, if s2n-tls is using Openssl and FIPS_mode_set(1)
* is called after s2n_init() is called, then this method will return true
* while s2n_is_in_fips_mode() will return false and s2n-tls will not operate
* in FIPS mode.
*
* Safeguard with macro's, for example because Libressl dosn't define
* FIPS_mode() by default.
* For AWS-LC, the FIPS_mode() method is always defined. If AWS-LC was built to
* support FIPS, FIPS_mode() always returns 1.
*
* Note: FIPS_mode() does not change the FIPS state of libcrypto. This only returns the current state. Applications
* using s2n must call FIPS_mode_set(1) prior to s2n_init.
* */
* For OpenSSL, OPENSSL_FIPS is defined if the libcrypto was built to support
* FIPS. The FIPS_mode() method is only present if OPENSSL_FIPS is defined, and
* only returns 1 if FIPS_mode_set(1) was used to enable FIPS mode.
* Applications wanting to enable FIPS mode with OpenSSL must call
* FIPS_mode_set(1) prior to calling s2n_init().
*/
bool s2n_libcrypto_is_fips(void)
{
#if defined(OPENSSL_FIPS) || defined(OPENSSL_IS_AWSLC)
Expand Down
1 change: 0 additions & 1 deletion crypto/s2n_fips.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

int s2n_fips_init(void);
bool s2n_is_in_fips_mode(void);
bool s2n_libcrypto_is_fips(void);

struct s2n_cipher_suite;
S2N_RESULT s2n_fips_validate_cipher_suite(const struct s2n_cipher_suite *cipher_suite, bool *valid);
Expand Down
24 changes: 20 additions & 4 deletions crypto/s2n_libcrypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,16 +99,32 @@ static S2N_RESULT s2n_libcrypto_validate_expected_version_number(void)
}

/* s2n_libcrypto_is_*() encodes the libcrypto version used at build-time.
* Currently only captures AWS-LC and BoringSSL. When a libcrypto-dependent
* branch is required, we prefer these functions where possible to reduce
# #ifs and avoid potential bugs where the header containing the #define is not
* included.
*
* When a libcrypto-dependent branch is required, we prefer these functions
* where possible to reduce #ifs and avoid potential bugs where the header
* containing the #define is not included.
*/

#if defined(OPENSSL_IS_AWSLC) && defined(OPENSSL_IS_BORINGSSL)
#error "Both OPENSSL_IS_AWSLC and OPENSSL_IS_BORINGSSL are defined at the same time!"
#endif

/* Attempt to detect if the libcrypto is OpenSSL.
*
* This check should be updated if s2n-tls adds support for a new libcrypto.
*
* Since several libcrypto implementations (such as BoringSSL and AWS-LC) are
* ABI compatible forks of OpenSSL, detecting OpenSSL is done by checking the
* absence of other known libcrypto variants.
*/
bool s2n_libcrypto_is_openssl()
{
bool is_other_libcrypto_variant =
s2n_libcrypto_is_boringssl() || s2n_libcrypto_is_libressl() || s2n_libcrypto_is_awslc();

return !is_other_libcrypto_variant;
}

bool s2n_libcrypto_is_awslc()
{
#if defined(OPENSSL_IS_AWSLC)
Expand Down
1 change: 1 addition & 0 deletions crypto/s2n_openssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#define S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND 0
#endif

bool s2n_libcrypto_is_openssl();
bool s2n_libcrypto_is_awslc();
bool s2n_libcrypto_is_boringssl();
bool s2n_libcrypto_is_libressl();
46 changes: 46 additions & 0 deletions tests/unit/s2n_build_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,43 @@ S2N_RESULT s2n_test_lowercase_copy(const char *input, char *destination, size_t
return S2N_RESULT_OK;
}

S2N_RESULT s2n_check_supported_libcrypto(const char *s2n_libcrypto)
{
RESULT_ENSURE_REF(s2n_libcrypto);

/* List of supported libcrypto variants we test with */
const struct {
const char *libcrypto;
bool is_openssl;
} supported_libcrypto[] = {
{ .libcrypto = "awslc", .is_openssl = false },
{ .libcrypto = "awslc-fips", .is_openssl = false },
{ .libcrypto = "awslc-fips-2022", .is_openssl = false },
{ .libcrypto = "boringssl", .is_openssl = false },
{ .libcrypto = "libressl", .is_openssl = false },
{ .libcrypto = "openssl-1.0.2", .is_openssl = true },
{ .libcrypto = "openssl-1.0.2-fips", .is_openssl = true },
{ .libcrypto = "openssl-1.1.1", .is_openssl = true },
{ .libcrypto = "openssl-3.0", .is_openssl = true },
};

for (size_t i = 0; i < s2n_array_len(supported_libcrypto); i++) {
/* The linked libcryto is one of the known supported libcrypto variants */
if (strcmp(s2n_libcrypto, supported_libcrypto[i].libcrypto) == 0) {
if (supported_libcrypto[i].is_openssl) {
EXPECT_TRUE(s2n_libcrypto_is_openssl());
} else {
EXPECT_FALSE(s2n_libcrypto_is_openssl());
}

return S2N_RESULT_OK;
}
}

/* Testing with an unexpected libcrypto. */
return S2N_RESULT_ERROR;
}

int main()
{
BEGIN_TEST();
Expand Down Expand Up @@ -131,6 +168,15 @@ int main()
}
};

/* Ensure we are testing with supported libcryto variants.
*
* We need to update s2n_libcrypto_is_openssl() when adding support
* for a new libcrypto.
*/
{
EXPECT_OK(s2n_check_supported_libcrypto(s2n_libcrypto));
};

END_TEST();
return 0;
}
24 changes: 20 additions & 4 deletions tests/unit/s2n_openssl_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,31 @@ int main(int argc, char** argv)
END_TEST();
}

if (strcmp(env_libcrypto, "boringssl") == 0) {
/* Confirm "S2N_LIBCRYPTO" env variable matches the linked libcrypto. */
if (strstr(env_libcrypto, "awslc") != NULL) {
EXPECT_TRUE(s2n_libcrypto_is_awslc());
EXPECT_FALSE(s2n_libcrypto_is_boringssl());
EXPECT_FALSE(s2n_libcrypto_is_libressl());
EXPECT_FALSE(s2n_libcrypto_is_openssl());
} else if (strcmp(env_libcrypto, "boringssl") == 0) {
EXPECT_FALSE(s2n_libcrypto_is_awslc());
EXPECT_TRUE(s2n_libcrypto_is_boringssl());
} else if (strstr(env_libcrypto, "awslc") != NULL) {
EXPECT_TRUE(s2n_libcrypto_is_awslc());
EXPECT_FALSE(s2n_libcrypto_is_libressl());
EXPECT_FALSE(s2n_libcrypto_is_openssl());
} else if (strcmp(env_libcrypto, "libressl") == 0) {
EXPECT_FALSE(s2n_libcrypto_is_awslc());
EXPECT_FALSE(s2n_libcrypto_is_boringssl());
} else {
EXPECT_TRUE(s2n_libcrypto_is_libressl());
EXPECT_FALSE(s2n_libcrypto_is_openssl());
} else if (strstr(env_libcrypto, "openssl") != NULL) {
EXPECT_FALSE(s2n_libcrypto_is_awslc());
EXPECT_FALSE(s2n_libcrypto_is_boringssl());
EXPECT_FALSE(s2n_libcrypto_is_libressl());
EXPECT_TRUE(s2n_libcrypto_is_openssl());
} else if (strcmp(env_libcrypto, "default") == 0) {
/* running with the default libcrypto on path */
} else {
FAIL_MSG("Testing with an unexpected libcrypto.");
}

END_TEST();
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/s2n_pq_kem_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ int main()

#if defined(OPENSSL_IS_AWSLC) && defined(AWSLC_API_VERSION)
/* If using non-FIPS AWS-LC >= v1.6 (API vers. 21), expect Kyber512 KEM from AWS-LC */
if (!s2n_libcrypto_is_fips() && AWSLC_API_VERSION >= 21) {
if (!s2n_is_in_fips_mode() && AWSLC_API_VERSION >= 21) {
EXPECT_TRUE(s2n_libcrypto_supports_evp_kem());
}
#endif
Expand Down
3 changes: 3 additions & 0 deletions utils/s2n_random.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@
#include <errno.h>
#include <limits.h>
#include <openssl/engine.h>
/* LibreSSL requires <openssl/rand.h> include.
* https://github.com/aws/s2n-tls/issues/153#issuecomment-129651643
*/
#include <openssl/rand.h>
#include <pthread.h>
#include <stdint.h>
Expand Down

0 comments on commit ecf2835

Please sign in to comment.