Skip to content

Commit

Permalink
feat: Add FIPS mode getter API
Browse files Browse the repository at this point in the history
  • Loading branch information
goatgoose committed Mar 6, 2024
1 parent 5b83319 commit 33b38be
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 0 deletions.
16 changes: 16 additions & 0 deletions api/s2n.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,22 @@ S2N_API extern int s2n_init(void);
*/
S2N_API extern int s2n_cleanup(void);

/**
* Determines whether s2n-tls is in FIPS mode.
*
* s2n-tls enters FIPS mode on initialization when the linked libcrypto has FIPS mode enabled. Some
* libcryptos, such as AWS-LC-FIPS, have FIPS mode enabled by default. With other libcryptos, such
* as OpenSSL, FIPS mode must be enabled before initialization by calling `FIPS_mode_set()`.
*
* s2n-tls MUST be linked to a FIPS libcrypto and MUST be in FIPS mode in order to comply with FIPS
* requirements. Applications desiring FIPS compliance should use this API to ensure that s2n-tls
* has been properly linked with a FIPS libcrypto and has successfully entered FIPS mode.
*
* @param fips_mode Set to true if s2n-tls is in FIPS mode, set to false otherwise.
* @returns S2N_SUCCESS on success. S2N_FAILURE on failure.
*/
S2N_API extern int s2n_get_fips_mode(bool *fips_mode);

/**
* Creates a new s2n_config object. This object can (and should) be associated with many connection
* objects.
Expand Down
16 changes: 16 additions & 0 deletions crypto/s2n_fips.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

#include <openssl/crypto.h>

#include "utils/s2n_init.h"
#include "utils/s2n_safety.h"

#if defined(S2N_INTERN_LIBCRYPTO) && defined(OPENSSL_FIPS)
#error "Interning with OpenSSL fips-validated libcrypto is not currently supported. See https://github.com/aws/s2n-tls/issues/2741"
#endif
Expand Down Expand Up @@ -60,3 +63,16 @@ int s2n_is_in_fips_mode(void)
{
return s2n_fips_mode;
}

int s2n_get_fips_mode(bool *fips_mode)
{
POSIX_ENSURE_REF(fips_mode);
*fips_mode = false;
POSIX_ENSURE(s2n_is_initialized(), S2N_ERR_NOT_INITIALIZED);

if (s2n_is_in_fips_mode()) {
*fips_mode = true;
}

return S2N_SUCCESS;
}
12 changes: 12 additions & 0 deletions tests/unit/s2n_build_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,18 @@ int main()
END_TEST();
}

/* Ensure that FIPS mode is enabled when linked to AWS-LC-FIPS, and disabled when linked to AWS-LC */
if (strstr(s2n_libcrypto, "awslc") != NULL) {
bool fips_mode = false;
EXPECT_SUCCESS(s2n_get_fips_mode(&fips_mode));

if (strstr(s2n_libcrypto, "fips") != NULL) {
EXPECT_TRUE(fips_mode);
} else {
EXPECT_FALSE(fips_mode);
}
}

char s2n_libcrypto_copy[MAX_LIBCRYPTO_NAME_LEN] = { 0 };
EXPECT_TRUE(strlen(s2n_libcrypto) < MAX_LIBCRYPTO_NAME_LEN);
EXPECT_OK(s2n_test_lowercase_copy(s2n_libcrypto, &s2n_libcrypto_copy[0], s2n_array_len(s2n_libcrypto_copy)));
Expand Down
47 changes: 47 additions & 0 deletions tests/unit/s2n_fips_mode_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* 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.
*/

#include "api/s2n.h"
#include "crypto/s2n_fips.h"
#include "s2n_test.h"

int main()
{
BEGIN_TEST_NO_INIT();

/* s2n_get_fips_mode() fails before init */
{
bool fips_mode = true;
EXPECT_FAILURE_WITH_ERRNO(s2n_get_fips_mode(&fips_mode), S2N_ERR_NOT_INITIALIZED);
EXPECT_FALSE(fips_mode);
}

EXPECT_SUCCESS(s2n_init());

/* Test s2n_get_fips_mode() after init */
{
/* Safety */
EXPECT_FAILURE_WITH_ERRNO(s2n_get_fips_mode(NULL), S2N_ERR_NULL);

/* FIPS mode matches s2n_is_in_fips_mode() */
{
bool fips_mode = false;
EXPECT_SUCCESS(s2n_get_fips_mode(&fips_mode));
EXPECT_EQUAL(fips_mode, s2n_is_in_fips_mode());
}
}

END_TEST();
}

0 comments on commit 33b38be

Please sign in to comment.