Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:FrontRunner
gnutls.26407
gnutls-FIPS-force-self-test.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File gnutls-FIPS-force-self-test.patch of Package gnutls.26407
Index: gnutls-3.7.3/doc/Makefile.am =================================================================== --- gnutls-3.7.3.orig/doc/Makefile.am 2022-07-08 13:35:05.577272530 +0200 +++ gnutls-3.7.3/doc/Makefile.am 2022-07-08 14:46:23.460305049 +0200 @@ -1070,6 +1070,8 @@ FUNCS += functions/gnutls_fips140_pop_context.short FUNCS += functions/gnutls_fips140_push_context FUNCS += functions/gnutls_fips140_push_context.short +FUNCS += functions/gnutls_fips140_run_self_tests +FUNCS += functions/gnutls_fips140_run_self_tests.short FUNCS += functions/gnutls_fips140_set_mode FUNCS += functions/gnutls_fips140_set_mode.short FUNCS += functions/gnutls_get_library_config Index: gnutls-3.7.3/doc/manpages/Makefile.am =================================================================== --- gnutls-3.7.3.orig/doc/manpages/Makefile.am 2022-07-08 13:35:05.577272530 +0200 +++ gnutls-3.7.3/doc/manpages/Makefile.am 2022-07-08 14:46:23.460305049 +0200 @@ -375,6 +375,7 @@ APIMANS += gnutls_fips140_mode_enabled.3 APIMANS += gnutls_fips140_pop_context.3 APIMANS += gnutls_fips140_push_context.3 +APIMANS += gnutls_fips140_run_self_tests.3 APIMANS += gnutls_fips140_set_mode.3 APIMANS += gnutls_get_library_config.3 APIMANS += gnutls_get_system_config_file.3 Index: gnutls-3.7.3/lib/fips.c =================================================================== --- gnutls-3.7.3.orig/lib/fips.c 2022-07-08 14:46:23.404304679 +0200 +++ gnutls-3.7.3/lib/fips.c 2022-07-08 14:46:56.952527793 +0200 @@ -278,8 +278,6 @@ { int ret; - _gnutls_switch_lib_state(LIB_STATE_SELFTEST); - /* Tests the FIPS algorithms used by nettle internally. * In our case we test AES-CBC since nettle's AES is used by * the DRBG-AES. @@ -288,118 +286,94 @@ /* ciphers - one test per cipher */ ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_AES_128_CBC); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } return 0; - -error: - _gnutls_switch_lib_state(LIB_STATE_ERROR); - _gnutls_audit_log(NULL, "FIPS140-2 self testing part1 failed\n"); - - return GNUTLS_E_SELF_TEST_ERROR; } int _gnutls_fips_perform_self_checks2(void) { int ret; - _gnutls_switch_lib_state(LIB_STATE_SELFTEST); - /* Tests the FIPS algorithms */ /* ciphers - one test per cipher */ ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_3DES_CBC); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_AES_256_CBC); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_AES_256_GCM); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_AES_256_XTS); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_AES_256_CFB8); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } /* Digest tests */ ret = gnutls_digest_self_test(0, GNUTLS_DIG_SHA3_224); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } ret = gnutls_digest_self_test(0, GNUTLS_DIG_SHA3_256); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } ret = gnutls_digest_self_test(0, GNUTLS_DIG_SHA3_384); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } ret = gnutls_digest_self_test(0, GNUTLS_DIG_SHA3_512); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } /* MAC (includes message digest test) */ ret = gnutls_mac_self_test(0, GNUTLS_MAC_SHA1); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } ret = gnutls_mac_self_test(0, GNUTLS_MAC_SHA224); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } ret = gnutls_mac_self_test(0, GNUTLS_MAC_SHA256); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } ret = gnutls_mac_self_test(0, GNUTLS_MAC_SHA384); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } ret = gnutls_mac_self_test(0, GNUTLS_MAC_SHA512); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } ret = gnutls_mac_self_test(0, GNUTLS_MAC_AES_CMAC_256); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } /* KDF */ @@ -414,107 +388,88 @@ ret = _gnutls_prf_raw(GNUTLS_MAC_SHA256, secret.size, secret.data, label.size, (char*)label.data, seed.size, seed.data, expected.size, derived); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } ret = memcmp(derived, expected.data, expected.size); if (ret != 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } /* PK */ ret = gnutls_pk_self_test(0, GNUTLS_PK_RSA); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } - ret = gnutls_pk_self_test(0, GNUTLS_PK_DSA); + // Removed from self-test since this would cause lib to be put + // into FIPS error state. + /*ret = gnutls_pk_self_test(0, GNUTLS_PK_DSA); if (ret < 0) { - gnutls_assert(); - goto error; - } + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + }*/ ret = gnutls_pk_self_test(0, GNUTLS_PK_EC); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } ret = gnutls_pk_self_test(0, GNUTLS_PK_DH); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } /* HKDF */ ret = gnutls_hkdf_self_test(0, GNUTLS_MAC_SHA256); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } /* PBKDF2 */ ret = gnutls_pbkdf2_self_test(0, GNUTLS_MAC_SHA256); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } /* TLS-PRF */ ret = gnutls_tlsprf_self_test(0, GNUTLS_MAC_SHA256); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } if (_gnutls_rnd_ops.self_test == NULL) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } /* this does not require rng initialization */ ret = _gnutls_rnd_ops.self_test(); if (ret < 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } if (_skip_integrity_checks == 0) { ret = check_binary_integrity(GNUTLS_LIBRARY_NAME, "gnutls_global_init"); if (ret == 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } ret = check_binary_integrity(NETTLE_LIBRARY_NAME, "nettle_aes_set_encrypt_key"); if (ret == 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } ret = check_binary_integrity(HOGWEED_LIBRARY_NAME, "nettle_mpz_sizeinbase_256_u"); if (ret == 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } ret = check_binary_integrity(GMP_LIBRARY_NAME, "__gmpz_init"); if (ret == 0) { - gnutls_assert(); - goto error; + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } } return 0; - -error: - _gnutls_switch_lib_state(LIB_STATE_ERROR); - _gnutls_audit_log(NULL, "FIPS140-2 self testing part 2 failed\n"); - - return GNUTLS_E_SELF_TEST_ERROR; } #endif @@ -793,3 +748,67 @@ (void)state; #endif } + +/** + * gnutls_fips140_run_self_tests: + * + * Manually perform the second round of the FIPS140 self-tests, + * including: + * + * - Known answer tests (KAT) for the selected set of symmetric + * cipher, MAC, public key, KDF, and DRBG + * - Library integrity checks + * + * Upon failure with FIPS140 mode enabled, it makes the library + * unusable. This function is not thread-safe. + * + * Returns: 0 upon success, a negative error code otherwise + * + * Since: 3.7.3 + */ +int +gnutls_fips140_run_self_tests(void) +{ +#ifdef ENABLE_FIPS140 + int ret; + unsigned prev_lib_state; + gnutls_fips140_context_t fips_context = NULL; + + /* Save the FIPS context, because self tests change it */ + if (gnutls_fips140_mode_enabled() != GNUTLS_FIPS140_DISABLED) { + if (gnutls_fips140_context_init(&fips_context) < 0 || + gnutls_fips140_push_context(fips_context) < 0) { + gnutls_fips140_context_deinit(fips_context); + fips_context = NULL; + } + } + + /* Temporarily switch to LIB_STATE_SELFTEST as some of the + * algorithms are implemented using special constructs in + * self-tests (such as deterministic variants) */ + prev_lib_state = _gnutls_get_lib_state(); + _gnutls_switch_lib_state(LIB_STATE_SELFTEST); + + ret = _gnutls_fips_perform_self_checks2(); + if (gnutls_fips140_mode_enabled() != GNUTLS_FIPS140_DISABLED && + ret < 0) { + _gnutls_switch_lib_state(LIB_STATE_ERROR); + _gnutls_audit_log(NULL, "FIPS140-2 self testing part 2 failed\n"); + } else { + /* Restore the previous library state */ + _gnutls_switch_lib_state(prev_lib_state); + } + + /* Restore the previous FIPS context */ + if (gnutls_fips140_mode_enabled() != GNUTLS_FIPS140_DISABLED && fips_context) { + if (gnutls_fips140_pop_context() < 0) { + _gnutls_switch_lib_state(LIB_STATE_ERROR); + _gnutls_audit_log(NULL, "FIPS140-2 context restoration failed\n"); + } + gnutls_fips140_context_deinit(fips_context); + } + return ret; +#else + return 0; +#endif +} Index: gnutls-3.7.3/lib/global.c =================================================================== --- gnutls-3.7.3.orig/lib/global.c 2022-07-08 13:35:05.577272530 +0200 +++ gnutls-3.7.3/lib/global.c 2022-07-08 14:46:23.460305049 +0200 @@ -336,9 +336,12 @@ /* first round of self checks, these are done on the * nettle algorithms which are used internally */ + _gnutls_switch_lib_state(LIB_STATE_SELFTEST); ret = _gnutls_fips_perform_self_checks1(); - if (res != 2) { - if (ret < 0) { + if (ret < 0) { + _gnutls_switch_lib_state(LIB_STATE_ERROR); + _gnutls_audit_log(NULL, "FIPS140-2 self testing part1 failed\n"); + if (res != 2) { gnutls_assert(); goto out; } @@ -355,9 +358,12 @@ * (e.g., AESNI overridden AES). They are after _gnutls_register_accel_crypto() * intentionally */ if (res != 0) { + _gnutls_switch_lib_state(LIB_STATE_SELFTEST); ret = _gnutls_fips_perform_self_checks2(); - if (res != 2) { - if (ret < 0) { + if (ret < 0) { + _gnutls_switch_lib_state(LIB_STATE_ERROR); + _gnutls_audit_log(NULL, "FIPS140-2 self testing part 2 failed\n"); + if (res != 2) { gnutls_assert(); goto out; } Index: gnutls-3.7.3/lib/includes/gnutls/gnutls.h.in =================================================================== --- gnutls-3.7.3.orig/lib/includes/gnutls/gnutls.h.in 2022-07-08 13:35:05.577272530 +0200 +++ gnutls-3.7.3/lib/includes/gnutls/gnutls.h.in 2022-07-08 14:46:23.460305049 +0200 @@ -3394,6 +3394,8 @@ int gnutls_fips140_push_context(gnutls_fips140_context_t context); int gnutls_fips140_pop_context(void); +int gnutls_fips140_run_self_tests(void); + /* Gnutls error codes. The mapping to a TLS alert is also shown in * comments. */ Index: gnutls-3.7.3/lib/libgnutls.map =================================================================== --- gnutls-3.7.3.orig/lib/libgnutls.map 2022-07-08 13:35:05.577272530 +0200 +++ gnutls-3.7.3/lib/libgnutls.map 2022-07-08 14:46:23.460305049 +0200 @@ -1376,10 +1376,19 @@ gnutls_fips140_push_context; gnutls_fips140_pop_context; gnutls_get_library_config; + gnutls_fips140_run_self_tests; local: *; } GNUTLS_3_7_2; +GNUTLS_3_7_7 +{ + global: + gnutls_fips140_run_self_tests; + local: + *; +} GNUTLS_3_7_3; + GNUTLS_FIPS140_3_4 { global: gnutls_cipher_self_test; Index: gnutls-3.7.3/tests/fips-test.c =================================================================== --- gnutls-3.7.3.orig/tests/fips-test.c 2022-07-08 14:46:23.456305023 +0200 +++ gnutls-3.7.3/tests/fips-test.c 2022-07-08 14:46:23.460305049 +0200 @@ -459,7 +459,8 @@ /* Verify a signature created with SHA-1; approved */ FIPS_PUSH_CONTEXT(); - ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA1, 0, &data, + ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA1, + GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1, &data, &rsa2342_sha1_sig); if (ret < 0) { fail("gnutls_pubkey_verify_data2 failed\n"); @@ -493,6 +494,15 @@ } FIPS_POP_CONTEXT(APPROVED); + /* run self-tests manually */ + FIPS_PUSH_CONTEXT(); + ret = gnutls_rnd(GNUTLS_RND_RANDOM, key16, sizeof(key16)); + ret = gnutls_fips140_run_self_tests(); + if (ret < 0) { + fail("gnutls_fips140_run_self_tests failed\n"); + } + FIPS_POP_CONTEXT(APPROVED); + /* Test when FIPS140 is set to error state */ _gnutls_lib_simulate_error(); @@ -535,6 +545,7 @@ } gnutls_fips140_context_deinit(fips_context); + gnutls_global_deinit(); return; }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor