diff options
author | robot-contrib <robot-contrib@yandex-team.com> | 2022-07-09 10:40:08 +0300 |
---|---|---|
committer | robot-contrib <robot-contrib@yandex-team.com> | 2022-07-09 10:40:08 +0300 |
commit | 22acf19be42357b6bb0e7d601b0dc28695191463 (patch) | |
tree | a35a222fffb28fcf8a82dd7efe67f2276bfd1858 /contrib/restricted/aws/s2n/tls | |
parent | 7a7d303e197aa7e4f43c61cc289d8652df38ab43 (diff) | |
download | ydb-22acf19be42357b6bb0e7d601b0dc28695191463.tar.gz |
Update contrib/restricted/aws/s2n to 1.3.16
Diffstat (limited to 'contrib/restricted/aws/s2n/tls')
19 files changed, 246 insertions, 23 deletions
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.c index bbc37e475a..067a9d3eaf 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.c @@ -115,7 +115,8 @@ static int s2n_extensions_client_supported_versions_process(struct s2n_connectio conn->actual_protocol_version = MAX(client_version, conn->actual_protocol_version); } - S2N_ERROR_IF(conn->actual_protocol_version == s2n_unknown_protocol_version, S2N_ERR_UNKNOWN_PROTOCOL_VERSION); + POSIX_ENSURE(conn->client_protocol_version != s2n_unknown_protocol_version, S2N_ERR_UNKNOWN_PROTOCOL_VERSION); + POSIX_ENSURE(conn->actual_protocol_version != s2n_unknown_protocol_version, S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED); return S2N_SUCCESS; } @@ -126,10 +127,12 @@ static int s2n_client_supported_versions_recv(struct s2n_connection *conn, struc return S2N_SUCCESS; } - if (s2n_extensions_client_supported_versions_process(conn, in) < 0) { + int result = s2n_extensions_client_supported_versions_process(conn, in); + if (result != S2N_SUCCESS) { s2n_queue_reader_unsupported_protocol_version_alert(conn); - POSIX_BAIL(S2N_ERR_BAD_MESSAGE); + POSIX_ENSURE(s2n_errno != S2N_ERR_SAFETY, S2N_ERR_BAD_MESSAGE); } + POSIX_GUARD(result); return S2N_SUCCESS; } diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.c index 1c808f1d8c..4e4aa5d3bc 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.c @@ -147,6 +147,12 @@ int s2n_extension_recv(const s2n_extension_type *extension_type, struct s2n_conn *# If the original session did not use the "extended_master_secret" *# extension but the new ServerHello contains the extension, the *# client MUST abort the handshake. + * + *= https://tools.ietf.org/rfc/rfc8446#4.1.4 + *# As with the ServerHello, a HelloRetryRequest MUST NOT contain any + *# extensions that were not first offered by the client in its + *# ClientHello, with the exception of optionally the "cookie" (see + *# Section 4.2.2) extension. **/ if (extension_type->is_response && !S2N_CBIT_TEST(conn->extension_requests_sent, extension_id)) { @@ -161,7 +167,9 @@ int s2n_extension_recv(const s2n_extension_type *extension_type, struct s2n_conn POSIX_GUARD(extension_type->recv(conn, in)); /* Set request bit flag */ - if (!extension_type->is_response) { + if (extension_type->is_response) { + S2N_CBIT_SET(conn->extension_responses_received, extension_id); + } else { S2N_CBIT_SET(conn->extension_requests_received, extension_id); } diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_key_share.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_key_share.c index 46f5deb1d5..02fa59ac3e 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_key_share.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_key_share.c @@ -28,7 +28,7 @@ static int s2n_server_key_share_recv(struct s2n_connection *conn, struct s2n_stu const s2n_extension_type s2n_server_key_share_extension = { .iana_value = TLS_EXTENSION_KEY_SHARE, .minimum_version = S2N_TLS13, - .is_response = false, + .is_response = true, .send = s2n_server_key_share_send, .recv = s2n_server_key_share_recv, .should_send = s2n_extension_always_send, diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_psk.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_psk.c index 9a36caff9f..09e525fa93 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_psk.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_psk.c @@ -60,9 +60,9 @@ static int s2n_server_psk_recv(struct s2n_connection *conn, struct s2n_stuffer * * Any other mode selected by the server is invalid because it was not offered by the client. * A key_share extension MUST have been received in order to use a pre-shared key in (EC)DHE key exchange mode. */ - s2n_extension_type_id key_share_ext_id; + s2n_extension_type_id key_share_ext_id = s2n_unsupported_extension; POSIX_GUARD(s2n_extension_supported_iana_value_to_id(TLS_EXTENSION_KEY_SHARE, &key_share_ext_id)); - POSIX_ENSURE(S2N_CBIT_TEST(conn->extension_requests_received, key_share_ext_id), S2N_ERR_MISSING_EXTENSION); + POSIX_ENSURE(S2N_CBIT_TEST(conn->extension_responses_received, key_share_ext_id), S2N_ERR_MISSING_EXTENSION); /* From RFC section: https://tools.ietf.org/html/rfc8446#section-4.2.8.1 * Any future values that are allocated must ensure that the transmitted protocol messages diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_supported_versions.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_supported_versions.c index 53e387d8cc..55a3e4ebd2 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_supported_versions.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_supported_versions.c @@ -70,6 +70,18 @@ static int s2n_extensions_server_supported_versions_process(struct s2n_connectio uint16_t server_version = (server_version_parts[0] * 10) + server_version_parts[1]; + /** + *= https://tools.ietf.org/rfc/rfc8446#4.1.4 + *# The value of selected_version in the HelloRetryRequest + *# "supported_versions" extension MUST be retained in the ServerHello, + *# and a client MUST abort the handshake with an "illegal_parameter" + *# alert if the value changes. + **/ + if (s2n_is_hello_retry_handshake(conn) && !s2n_is_hello_retry_message(conn)) { + POSIX_ENSURE(conn->server_protocol_version == server_version, + S2N_ERR_BAD_MESSAGE); + } + POSIX_ENSURE_GTE(server_version, S2N_TLS13); POSIX_ENSURE_LTE(server_version, highest_supported_version); POSIX_ENSURE_GTE(server_version, minimum_supported_version); diff --git a/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.c b/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.c index 10407f487a..b7268e55f5 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.c +++ b/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.c @@ -82,6 +82,33 @@ const struct s2n_cipher_preferences cipher_preferences_20210831 = { .suites = cipher_suites_20210831, }; +/* + * These cipher suites were chosen based on the following specification: + * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r2.pdf + */ +struct s2n_cipher_suite *cipher_suites_default_fips[] = { + /* tls1.2 with ECDSA */ + &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256, + &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384, + &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256, + &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384, + + /* tls1.2 with RSA */ + &s2n_ecdhe_rsa_with_aes_128_gcm_sha256, + &s2n_ecdhe_rsa_with_aes_256_gcm_sha384, + &s2n_ecdhe_rsa_with_aes_128_cbc_sha256, + &s2n_ecdhe_rsa_with_aes_256_cbc_sha384, + &s2n_dhe_rsa_with_aes_128_cbc_sha256, + &s2n_dhe_rsa_with_aes_256_cbc_sha256, + &s2n_dhe_rsa_with_aes_128_gcm_sha256, + &s2n_dhe_rsa_with_aes_256_gcm_sha384, +}; + +const struct s2n_cipher_preferences cipher_preferences_default_fips = { + .count = s2n_array_len(cipher_suites_default_fips), + .suites = cipher_suites_default_fips, +}; + /* s2n's list of cipher suites, in order of preference, as of 2014-06-01 */ struct s2n_cipher_suite *cipher_suites_20140601[] = { &s2n_dhe_rsa_with_aes_128_cbc_sha256, diff --git a/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.h b/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.h index 7156c68185..c7305a3908 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.h +++ b/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.h @@ -51,6 +51,7 @@ extern const struct s2n_cipher_preferences cipher_preferences_20210816_gcm; extern const struct s2n_cipher_preferences cipher_preferences_20210825; extern const struct s2n_cipher_preferences cipher_preferences_20210825_gcm; extern const struct s2n_cipher_preferences cipher_preferences_20210831; +extern const struct s2n_cipher_preferences cipher_preferences_default_fips; extern const struct s2n_cipher_preferences cipher_preferences_test_all; diff --git a/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c b/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c index cf82b7c6f4..e18efb0c87 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c +++ b/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c @@ -1124,6 +1124,23 @@ int s2n_set_cipher_as_client(struct s2n_connection *conn, uint8_t wire[S2N_TLS_C POSIX_GUARD(s2n_connection_get_security_policy(conn, &security_policy)); POSIX_ENSURE_REF(security_policy); + /** + * Ensure that the wire cipher suite is contained in the security + * policy, and thus was offered by the client. + * + *= https://tools.ietf.org/rfc/rfc8446#4.1.3 + *# A client which receives a + *# cipher suite that was not offered MUST abort the handshake with an + *# "illegal_parameter" alert. + * + *= https://tools.ietf.org/rfc/rfc8446#4.1.4 + *# A client which receives a cipher suite that was not offered MUST + *# abort the handshake. + * + *= https://tools.ietf.org/rfc/rfc8446#4.1.4 + *# Upon receipt of a HelloRetryRequest, the client MUST check the + *# legacy_version, legacy_session_id_echo, cipher_suite + **/ struct s2n_cipher_suite *cipher_suite = NULL; for (size_t i = 0; i < security_policy->cipher_preferences->count; i++) { const uint8_t *ours = security_policy->cipher_preferences->suites[i]->iana_value; @@ -1133,6 +1150,7 @@ int s2n_set_cipher_as_client(struct s2n_connection *conn, uint8_t wire[S2N_TLS_C } } POSIX_ENSURE(cipher_suite != NULL, S2N_ERR_CIPHER_NOT_SUPPORTED); + POSIX_ENSURE(cipher_suite->available, S2N_ERR_CIPHER_NOT_SUPPORTED); /** Clients MUST verify @@ -1145,7 +1163,13 @@ int s2n_set_cipher_as_client(struct s2n_connection *conn, uint8_t wire[S2N_TLS_C S2N_ERR_CIPHER_NOT_SUPPORTED); } - /* Verify cipher suite sent in server hello is the same as sent in hello retry */ + /** + *= https://tools.ietf.org/rfc/rfc8446#4.1.4 + *# Upon receiving + *# the ServerHello, clients MUST check that the cipher suite supplied in + *# the ServerHello is the same as that in the HelloRetryRequest and + *# otherwise abort the handshake with an "illegal_parameter" alert. + **/ if (s2n_is_hello_retry_handshake(conn) && !s2n_is_hello_retry_message(conn)) { POSIX_ENSURE(conn->secure.cipher_suite->iana_value == cipher_suite->iana_value, S2N_ERR_CIPHER_NOT_SUPPORTED); return S2N_SUCCESS; diff --git a/contrib/restricted/aws/s2n/tls/s2n_client_hello.c b/contrib/restricted/aws/s2n/tls/s2n_client_hello.c index 149f4d4b53..0553d1fe14 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_client_hello.c +++ b/contrib/restricted/aws/s2n/tls/s2n_client_hello.c @@ -433,9 +433,28 @@ int s2n_process_client_hello(struct s2n_connection *conn) /* Find potential certificate matches before we choose the cipher. */ POSIX_GUARD(s2n_conn_find_name_matching_certs(conn)); + /* Save the previous cipher suite */ + uint8_t previous_cipher_suite_iana[S2N_TLS_CIPHER_SUITE_LEN] = { 0 }; + POSIX_CHECKED_MEMCPY(previous_cipher_suite_iana, conn->secure.cipher_suite->iana_value, S2N_TLS_CIPHER_SUITE_LEN); + /* Now choose the ciphers we have certs for. */ POSIX_GUARD(s2n_set_cipher_as_tls_server(conn, client_hello->cipher_suites.data, client_hello->cipher_suites.size / 2)); + /* Check if this is the second client hello in a hello retry handshake */ + if (s2n_is_hello_retry_handshake(conn) && + conn->handshake.message_number > 0) { + + /** + *= https://tools.ietf.org/rfc/rfc8446#4.1.4 + *# Servers MUST ensure that they negotiate the + *# same cipher suite when receiving a conformant updated ClientHello (if + *# the server selects the cipher suite as the first step in the + *# negotiation, then this will happen automatically). + **/ + POSIX_ENSURE(s2n_constant_time_equals(previous_cipher_suite_iana, conn->secure.cipher_suite->iana_value, + S2N_TLS_CIPHER_SUITE_LEN),S2N_ERR_BAD_MESSAGE); + } + /* If we're using a PSK, we don't need to choose a signature algorithm or certificate, * because no additional auth is required. */ if (conn->psk_params.chosen_psk != NULL) { diff --git a/contrib/restricted/aws/s2n/tls/s2n_connection.h b/contrib/restricted/aws/s2n/tls/s2n_connection.h index 09e1f19724..be375551b1 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_connection.h +++ b/contrib/restricted/aws/s2n/tls/s2n_connection.h @@ -144,7 +144,7 @@ struct s2n_connection { void *send_io_context; void *recv_io_context; - /* Track request extensions to ensure correct response extension behavior. + /* Track request/response extensions to ensure correct response extension behavior. * * We need to track client and server extensions separately because some * extensions (like request_status and other Certificate extensions) can @@ -152,6 +152,7 @@ struct s2n_connection { */ s2n_extension_bitfield extension_requests_sent; s2n_extension_bitfield extension_requests_received; + s2n_extension_bitfield extension_responses_received; /* Is this connection a client or a server connection */ s2n_mode mode; diff --git a/contrib/restricted/aws/s2n/tls/s2n_ecc_preferences.c b/contrib/restricted/aws/s2n/tls/s2n_ecc_preferences.c index f1632a0a53..53b9e95a13 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_ecc_preferences.c +++ b/contrib/restricted/aws/s2n/tls/s2n_ecc_preferences.c @@ -33,6 +33,15 @@ const struct s2n_ecc_named_curve *const s2n_ecc_pref_list_20200310[] = { &s2n_ecc_curve_secp384r1, }; +/* + * These curves were chosen based on the following specification: + * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r2.pdf + */ +const struct s2n_ecc_named_curve *const s2n_ecc_pref_list_default_fips[] = { + &s2n_ecc_curve_secp256r1, + &s2n_ecc_curve_secp384r1, +}; + const struct s2n_ecc_named_curve *const s2n_ecc_pref_list_20201021[] = { &s2n_ecc_curve_secp256r1, &s2n_ecc_curve_secp384r1, @@ -62,6 +71,11 @@ const struct s2n_ecc_preferences s2n_ecc_preferences_20200310 = { .ecc_curves = s2n_ecc_pref_list_20200310, }; +const struct s2n_ecc_preferences s2n_ecc_preferences_default_fips = { + .count = s2n_array_len(s2n_ecc_pref_list_default_fips), + .ecc_curves = s2n_ecc_pref_list_default_fips, +}; + const struct s2n_ecc_preferences s2n_ecc_preferences_20201021 = { .count = s2n_array_len(s2n_ecc_pref_list_20201021), .ecc_curves = s2n_ecc_pref_list_20201021, @@ -92,10 +106,10 @@ int s2n_check_ecc_preferences_curves_list(const struct s2n_ecc_preferences *ecc_ for (size_t j = 0; j < s2n_all_supported_curves_list_len; j++) { if (named_curve->iana_id == s2n_all_supported_curves_list[j]->iana_id) { curve_found = 1; - break; + break; } } - check *= curve_found; + check *= curve_found; if (check == 0) { POSIX_BAIL(S2N_ERR_ECDHE_UNSUPPORTED_CURVE); } diff --git a/contrib/restricted/aws/s2n/tls/s2n_ecc_preferences.h b/contrib/restricted/aws/s2n/tls/s2n_ecc_preferences.h index 564d722726..3d4a168264 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_ecc_preferences.h +++ b/contrib/restricted/aws/s2n/tls/s2n_ecc_preferences.h @@ -27,6 +27,7 @@ struct s2n_ecc_preferences { }; extern const struct s2n_ecc_preferences s2n_ecc_preferences_20140601; extern const struct s2n_ecc_preferences s2n_ecc_preferences_20200310; +extern const struct s2n_ecc_preferences s2n_ecc_preferences_default_fips; extern const struct s2n_ecc_preferences s2n_ecc_preferences_20201021; extern const struct s2n_ecc_preferences s2n_ecc_preferences_20210816; extern const struct s2n_ecc_preferences s2n_ecc_preferences_test_all; diff --git a/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c b/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c index 3c490212a7..a1f5c1215f 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c +++ b/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c @@ -1365,6 +1365,11 @@ int s2n_negotiate_impl(struct s2n_connection *conn, s2n_blocked_status *blocked) /* Flush any pending I/O or alert messages */ POSIX_GUARD(s2n_flush(conn, blocked)); + /* If the connection is closed, the handshake will never complete. */ + if (conn->closed) { + POSIX_BAIL(S2N_ERR_CLOSED); + } + /* If the handshake was paused, retry the current message */ if (conn->handshake.paused) { *blocked = S2N_BLOCKED_ON_APPLICATION_INPUT; diff --git a/contrib/restricted/aws/s2n/tls/s2n_security_policies.c b/contrib/restricted/aws/s2n/tls/s2n_security_policies.c index 90c0cb16a3..d8a041aca5 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_security_policies.c +++ b/contrib/restricted/aws/s2n/tls/s2n_security_policies.c @@ -36,6 +36,21 @@ const struct s2n_security_policy security_policy_default_tls13 = { .ecc_preferences = &s2n_ecc_preferences_20200310, }; +/* + * This security policy is derived from the following specification: + * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r2.pdf + * + * Supports TLS1.2 + */ +const struct s2n_security_policy security_policy_default_fips = { + .minimum_protocol_version = S2N_TLS12, + .cipher_preferences = &cipher_preferences_default_fips, + .kem_preferences = &kem_preferences_null, + .signature_preferences = &s2n_signature_preferences_default_fips, + .certificate_signature_preferences = &s2n_signature_preferences_default_fips, + .ecc_preferences = &s2n_ecc_preferences_default_fips, +}; + const struct s2n_security_policy security_policy_20190801 = { .minimum_protocol_version = S2N_TLS10, .cipher_preferences = &cipher_preferences_20190801, @@ -362,7 +377,7 @@ const struct s2n_security_policy security_policy_kms_pq_tls_1_0_2020_02 = { }; const struct s2n_security_policy security_policy_pq_sike_test_tls_1_0_2019_11 = { - .minimum_protocol_version = S2N_TLS10, + .minimum_protocol_version = S2N_TLS10, .cipher_preferences = &cipher_preferences_pq_sike_test_tls_1_0_2019_11, .kem_preferences = &kem_preferences_pq_sike_test_tls_1_0_2019_11, .signature_preferences = &s2n_signature_preferences_20140601, @@ -370,7 +385,7 @@ const struct s2n_security_policy security_policy_pq_sike_test_tls_1_0_2019_11 = }; const struct s2n_security_policy security_policy_pq_sike_test_tls_1_0_2020_02 = { - .minimum_protocol_version = S2N_TLS10, + .minimum_protocol_version = S2N_TLS10, .cipher_preferences = &cipher_preferences_pq_sike_test_tls_1_0_2020_02, .kem_preferences = &kem_preferences_pq_sike_test_tls_1_0_2020_02, .signature_preferences = &s2n_signature_preferences_20140601, @@ -734,7 +749,7 @@ const struct s2n_security_policy security_policy_null = { struct s2n_security_policy_selection security_policy_selection[] = { { .version="default", .security_policy=&security_policy_20170210, .ecc_extension_required=0, .pq_kem_extension_required=0 }, { .version="default_tls13", .security_policy=&security_policy_default_tls13, .ecc_extension_required=0, .pq_kem_extension_required=0 }, - { .version="default_fips", .security_policy=&security_policy_20170405, .ecc_extension_required=0, .pq_kem_extension_required=0 }, + { .version="default_fips", .security_policy=&security_policy_default_fips, .ecc_extension_required=0, .pq_kem_extension_required=0 }, { .version="ELBSecurityPolicy-TLS-1-0-2015-04", .security_policy=&security_policy_elb_2015_04, .ecc_extension_required=0, .pq_kem_extension_required=0 }, /* Not a mistake. TLS-1-0-2015-05 and 2016-08 are equivalent */ { .version="ELBSecurityPolicy-TLS-1-0-2015-05", .security_policy=&security_policy_elb_2016_08, .ecc_extension_required=0, .pq_kem_extension_required=0 }, @@ -743,9 +758,9 @@ struct s2n_security_policy_selection security_policy_selection[] = { { .version="ELBSecurityPolicy-TLS-1-2-2017-01", .security_policy=&security_policy_elb_tls_1_2_2017_01, .ecc_extension_required=0, .pq_kem_extension_required=0 }, { .version="ELBSecurityPolicy-TLS-1-2-Ext-2018-06", .security_policy=&security_policy_elb_tls_1_2_ext_2018_06, .ecc_extension_required=0, .pq_kem_extension_required=0 }, { .version="ELBSecurityPolicy-FS-2018-06", .security_policy=&security_policy_elb_fs_2018_06, .ecc_extension_required=0, .pq_kem_extension_required=0 }, - { .version="ELBSecurityPolicy-FS-1-2-2019-08", .security_policy=&security_policy_elb_fs_1_2_2019_08, .ecc_extension_required=0, .pq_kem_extension_required=0 }, - { .version="ELBSecurityPolicy-FS-1-1-2019-08", .security_policy=&security_policy_elb_fs_1_1_2019_08, .ecc_extension_required=0, .pq_kem_extension_required=0 }, - { .version="ELBSecurityPolicy-FS-1-2-Res-2019-08", .security_policy=&security_policy_elb_fs_1_2_Res_2019_08, .ecc_extension_required=0, .pq_kem_extension_required=0 }, + { .version="ELBSecurityPolicy-FS-1-2-2019-08", .security_policy=&security_policy_elb_fs_1_2_2019_08, .ecc_extension_required=0, .pq_kem_extension_required=0 }, + { .version="ELBSecurityPolicy-FS-1-1-2019-08", .security_policy=&security_policy_elb_fs_1_1_2019_08, .ecc_extension_required=0, .pq_kem_extension_required=0 }, + { .version="ELBSecurityPolicy-FS-1-2-Res-2019-08", .security_policy=&security_policy_elb_fs_1_2_Res_2019_08, .ecc_extension_required=0, .pq_kem_extension_required=0 }, { .version="CloudFront-Upstream", .security_policy=&security_policy_cloudfront_upstream, .ecc_extension_required=0, .pq_kem_extension_required=0 }, { .version="CloudFront-Upstream-TLS-1-0", .security_policy=&security_policy_cloudfront_upstream_tls10, .ecc_extension_required=0, .pq_kem_extension_required=0 }, { .version="CloudFront-Upstream-TLS-1-1", .security_policy=&security_policy_cloudfront_upstream_tls11, .ecc_extension_required=0, .pq_kem_extension_required=0 }, diff --git a/contrib/restricted/aws/s2n/tls/s2n_security_policies.h b/contrib/restricted/aws/s2n/tls/s2n_security_policies.h index be28fb584a..e4fec2c492 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_security_policies.h +++ b/contrib/restricted/aws/s2n/tls/s2n_security_policies.h @@ -63,6 +63,7 @@ extern const struct s2n_security_policy security_policy_20190214_gcm; extern const struct s2n_security_policy security_policy_20190801; extern const struct s2n_security_policy security_policy_20190802; extern const struct s2n_security_policy security_policy_default_tls13; +extern const struct s2n_security_policy security_policy_default_fips; extern const struct s2n_security_policy security_policy_test_all; extern const struct s2n_security_policy security_policy_test_all_tls12; diff --git a/contrib/restricted/aws/s2n/tls/s2n_server_extensions.c b/contrib/restricted/aws/s2n/tls/s2n_server_extensions.c index b604556009..f0cb6d6d39 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_server_extensions.c +++ b/contrib/restricted/aws/s2n/tls/s2n_server_extensions.c @@ -58,13 +58,20 @@ int s2n_server_extensions_recv(struct s2n_connection *conn, struct s2n_stuffer * s2n_parsed_extensions_list parsed_extension_list = { 0 }; POSIX_GUARD(s2n_extension_list_parse(in, &parsed_extension_list)); - /* Process supported_versions first so that we know which extensions list to use. + /** + * Process supported_versions first so that we know which extensions list to use. * - If the supported_versions extension exists, then it will set server_protocol_version. * - If the supported_versions extension does not exist, then the server_protocol_version will remain - * unknown and we will use the default list of allowed extension types. */ + * unknown and we will use the default list of allowed extension types. + **/ POSIX_GUARD(s2n_extension_process(&s2n_server_supported_versions_extension, conn, &parsed_extension_list)); if (s2n_is_hello_retry_message(conn)) { + /** + *= https://tools.ietf.org/rfc/rfc8446#4.1.4 + *# Otherwise, the client MUST process all extensions in the + *# HelloRetryRequest + */ POSIX_GUARD(s2n_extension_list_process(S2N_EXTENSION_LIST_HELLO_RETRY_REQUEST, conn, &parsed_extension_list)); } else if (conn->server_protocol_version >= S2N_TLS13) { POSIX_GUARD(s2n_extension_list_process(S2N_EXTENSION_LIST_SERVER_HELLO_TLS13, conn, &parsed_extension_list)); diff --git a/contrib/restricted/aws/s2n/tls/s2n_server_hello.c b/contrib/restricted/aws/s2n/tls/s2n_server_hello.c index 632f745478..efe4c08114 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_server_hello.c +++ b/contrib/restricted/aws/s2n/tls/s2n_server_hello.c @@ -37,6 +37,7 @@ #include "utils/s2n_safety.h" #include "utils/s2n_random.h" +#include "utils/s2n_bitmap.h" /* From RFC5246 7.4.1.2. */ #define S2N_TLS_COMPRESSION_METHOD_NULL 0 @@ -51,7 +52,7 @@ const uint8_t tls11_downgrade_protection_bytes[] = { 0x44, 0x4F, 0x57, 0x4E, 0x47, 0x52, 0x44, 0x00 }; -static int s2n_hello_retry_validate(struct s2n_connection *conn) { +static int s2n_random_value_is_hello_retry(struct s2n_connection *conn) { POSIX_ENSURE_REF(conn); POSIX_ENSURE(memcmp(hello_retry_req_random, conn->handshake_params.server_random, S2N_TLS_RANDOM_DATA_LEN) == 0, @@ -107,9 +108,32 @@ static int s2n_server_hello_parse(struct s2n_connection *conn) POSIX_GUARD(s2n_stuffer_read_bytes(in, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN)); POSIX_GUARD(s2n_stuffer_read_bytes(in, conn->handshake_params.server_random, S2N_TLS_RANDOM_DATA_LEN)); - /* If the client receives a second HelloRetryRequest in the same connection, it MUST send an error. */ - if (s2n_hello_retry_validate(conn) == S2N_SUCCESS) { + uint8_t legacy_version = (uint8_t)(protocol_version[0] * 10) + protocol_version[1]; + + /** + *= https://tools.ietf.org/rfc/rfc8446#4.1.3 + *# Upon receiving a message with type server_hello, implementations MUST + *# first examine the Random value and, if it matches this value, process + *# it as described in Section 4.1.4). + **/ + if (s2n_random_value_is_hello_retry(conn) == S2N_SUCCESS) { + + /** + *= https://tools.ietf.org/rfc/rfc8446#4.1.4 + *# If a client receives a second + *# HelloRetryRequest in the same connection (i.e., where the ClientHello + *# was itself in response to a HelloRetryRequest), it MUST abort the + *# handshake with an "unexpected_message" alert. + **/ POSIX_ENSURE(!s2n_is_hello_retry_handshake(conn), S2N_ERR_INVALID_HELLO_RETRY); + + /** + *= https://tools.ietf.org/rfc/rfc8446#4.1.4 + *# Upon receipt of a HelloRetryRequest, the client MUST check the + *# legacy_version + **/ + POSIX_ENSURE(legacy_version == S2N_TLS12, S2N_ERR_INVALID_HELLO_RETRY); + POSIX_GUARD(s2n_set_hello_retry_required(conn)); } @@ -121,6 +145,17 @@ static int s2n_server_hello_parse(struct s2n_connection *conn) POSIX_ENSURE_REF(cipher_suite_wire); POSIX_GUARD(s2n_stuffer_read_uint8(in, &compression_method)); + + /** + *= https://tools.ietf.org/rfc/rfc8446#4.1.3 + *# legacy_compression_method: A single byte which MUST have the + *# value 0. + * + *= https://tools.ietf.org/rfc/rfc8446#4.1.4 + *# Upon receipt of a HelloRetryRequest, the client MUST check the + *# legacy_version, legacy_session_id_echo, cipher_suite, and + *# legacy_compression_method + **/ S2N_ERROR_IF(compression_method != S2N_TLS_COMPRESSION_METHOD_NULL, S2N_ERR_BAD_MESSAGE); bool session_ids_match = session_id_len != 0 && session_id_len == conn->session_id_len @@ -131,16 +166,43 @@ static int s2n_server_hello_parse(struct s2n_connection *conn) POSIX_GUARD(s2n_server_extensions_recv(conn, in)); + /** + *= https://tools.ietf.org/rfc/rfc8446#4.1.4 + *# The server's extensions MUST contain "supported_versions". + **/ + if (s2n_is_hello_retry_message(conn)) { + s2n_extension_type_id supported_versions_id = s2n_unsupported_extension; + POSIX_GUARD(s2n_extension_supported_iana_value_to_id(TLS_EXTENSION_SUPPORTED_VERSIONS, &supported_versions_id)); + POSIX_ENSURE(S2N_CBIT_TEST(conn->extension_responses_received, supported_versions_id), + S2N_ERR_MISSING_EXTENSION); + } + if (conn->server_protocol_version >= S2N_TLS13) { + + /** + *= https://www.rfc-editor.org/rfc/rfc8446#section-4.1.3 + *# A client which + *# receives a legacy_session_id_echo field that does not match what + *# it sent in the ClientHello MUST abort the handshake with an + *# "illegal_parameter" alert. + * + *= https://tools.ietf.org/rfc/rfc8446#4.1.4 + *# Upon receipt of a HelloRetryRequest, the client MUST check the + *# legacy_version, legacy_session_id_echo + **/ POSIX_ENSURE(session_ids_match || (session_id_len == 0 && conn->session_id_len == 0), S2N_ERR_BAD_MESSAGE); + conn->actual_protocol_version = conn->server_protocol_version; POSIX_GUARD(s2n_set_cipher_as_client(conn, cipher_suite_wire)); } else { - conn->server_protocol_version = (uint8_t)(protocol_version[0] * 10) + protocol_version[1]; + conn->server_protocol_version = legacy_version; POSIX_ENSURE(!s2n_client_detect_downgrade_mechanism(conn), S2N_ERR_PROTOCOL_DOWNGRADE_DETECTED); POSIX_ENSURE(!s2n_connection_is_quic_enabled(conn), S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED); + /* Hello retries are only supported in >=TLS1.3. */ + POSIX_ENSURE(!s2n_is_hello_retry_handshake(conn), S2N_ERR_BAD_MESSAGE); + /* *= https://tools.ietf.org/rfc/rfc8446#appendix-D.3 *# A client that attempts to send 0-RTT data MUST fail a connection if diff --git a/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.c b/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.c index 6ccddacab6..2ccc0fd651 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.c +++ b/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.c @@ -260,6 +260,28 @@ const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_20200207[] = { &s2n_ecdsa_sha1, }; +/* + * These signature schemes were chosen based on the following specification: + * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r2.pdf + */ +const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_default_fips[] = { + /* RSA PKCS1 - TLS1.2 */ + &s2n_rsa_pkcs1_sha256, + &s2n_rsa_pkcs1_sha384, + &s2n_rsa_pkcs1_sha512, + + /* ECDSA - TLS 1.2 */ + &s2n_ecdsa_sha256, /* same iana value as TLS 1.3 s2n_ecdsa_secp256r1_sha256 */ + &s2n_ecdsa_sha384, /* same iana value as TLS 1.3 s2n_ecdsa_secp384r1_sha384 */ + &s2n_ecdsa_sha512, + &s2n_ecdsa_sha224, +}; + +const struct s2n_signature_preferences s2n_signature_preferences_default_fips = { + .count = s2n_array_len(s2n_sig_scheme_pref_list_default_fips), + .signature_schemes = s2n_sig_scheme_pref_list_default_fips, +}; + /* Add s2n_ecdsa_secp521r1_sha512 */ const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_20201021[] = { /* RSA PSS */ diff --git a/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.h b/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.h index 3f78d8a500..d8eee975ab 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.h +++ b/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.h @@ -77,6 +77,7 @@ extern const struct s2n_signature_preferences s2n_signature_preferences_20140601 extern const struct s2n_signature_preferences s2n_signature_preferences_20200207; extern const struct s2n_signature_preferences s2n_signature_preferences_20201021; extern const struct s2n_signature_preferences s2n_signature_preferences_20210816; +extern const struct s2n_signature_preferences s2n_signature_preferences_default_fips; extern const struct s2n_signature_preferences s2n_signature_preferences_null; extern const struct s2n_signature_preferences s2n_certificate_signature_preferences_20201110; |