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: Add FIPS mode getter API #4450

Merged
merged 6 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
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
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 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_is_fips(bool *fips);

goatgoose marked this conversation as resolved.
Show resolved Hide resolved
/**
* 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_is_fips(bool *fips)
{
POSIX_ENSURE_REF(fips);
*fips = false;
POSIX_ENSURE(s2n_is_initialized(), S2N_ERR_NOT_INITIALIZED);

if (s2n_is_in_fips_mode()) {
*fips = true;
}
goatgoose marked this conversation as resolved.
Show resolved Hide resolved

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 = false;
EXPECT_SUCCESS(s2n_is_fips(&fips));

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

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
48 changes: 48 additions & 0 deletions tests/unit/s2n_fips_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* 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 "crypto/s2n_fips.h"

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

int main()
{
BEGIN_TEST_NO_INIT();

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

EXPECT_SUCCESS(s2n_init());

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

/* FIPS value matches s2n_is_in_fips_mode() */
{
bool fips = false;
EXPECT_SUCCESS(s2n_is_fips(&fips));
EXPECT_EQUAL(fips, s2n_is_in_fips_mode());
}
}

END_TEST();
}
Loading