aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/aws/s2n/tls
diff options
context:
space:
mode:
authororivej <orivej@yandex-team.ru>2022-02-10 16:45:01 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:01 +0300
commit2d37894b1b037cf24231090eda8589bbb44fb6fc (patch)
treebe835aa92c6248212e705f25388ebafcf84bc7a1 /contrib/restricted/aws/s2n/tls
parent718c552901d703c502ccbefdfc3c9028d608b947 (diff)
downloadydb-2d37894b1b037cf24231090eda8589bbb44fb6fc.tar.gz
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/restricted/aws/s2n/tls')
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_alpn.c258
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_alpn.h54
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_key_share.c1042
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_key_share.h54
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_max_frag_len.c150
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_max_frag_len.h52
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_pq_kem.c178
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_pq_kem.h54
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.c542
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.h44
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.c102
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.h50
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_sct_list.c118
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_sct_list.h52
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_server_name.c220
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_server_name.h52
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_session_ticket.c164
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_session_ticket.h50
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_signature_algorithms.c128
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_signature_algorithms.h54
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_status_request.c182
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_status_request.h52
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_groups.c402
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_groups.h54
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.c306
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.h52
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.c206
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.h58
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_ec_point_format.c182
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_ec_point_format.h58
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.c368
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.h102
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.c424
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.h198
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.c242
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.h52
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_key_share.c66
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_key_share.h56
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_quic_transport_params.c154
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_quic_transport_params.h40
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_alpn.c162
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_alpn.h40
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_certificate_status.c160
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_certificate_status.h50
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_key_share.c860
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_key_share.h60
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_max_fragment_length.c122
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_max_fragment_length.h40
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.c174
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.h54
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_sct_list.c134
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_sct_list.h40
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_server_name.c102
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_server_name.h40
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_session_ticket.c136
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_session_ticket.h54
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_signature_algorithms.c84
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_signature_algorithms.h40
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_status_request.c132
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_status_request.h54
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_supported_versions.c212
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_supported_versions.h54
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_supported_versions.c62
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_supported_versions.h42
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_aead.c156
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_alerts.c370
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_alerts.h50
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_async_pkey.c822
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_async_pkey.h142
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_auth_selection.c456
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_auth_selection.h54
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_cbc.c206
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_change_cipher_spec.c180
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.c2254
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.h206
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c2530
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_cipher_suites.h344
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_client_cert.c198
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_client_cert_verify.c182
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_client_finished.c220
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_client_hello.c1020
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_client_hello.h98
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.c634
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.h70
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_config.c1720
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_config.h230
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_connection.c2708
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_connection.h698
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_connection_evp_digests.c280
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_connection_evp_digests.h140
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_crypto.h146
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_crypto_constants.h100
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_ecc_preferences.c222
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_ecc_preferences.h70
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_encrypted_extensions.c110
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_establish_session.c110
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_handshake.c662
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_handshake.h440
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_handshake_io.c2430
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_handshake_transcript.c272
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_kem.c1018
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_kem.h362
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_kem_preferences.c276
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_kem_preferences.h108
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_kex.c514
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_kex.h110
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_kex_data.h80
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_key_update.c230
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_key_update.h68
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_ocsp_stapling.c80
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_post_handshake.c138
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_post_handshake.h42
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_prf.c1384
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_prf.h140
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_protocol_preferences.c110
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_psk.c604
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_psk.h126
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_quic_support.c230
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_quic_support.h152
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_record.h68
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_record_read.c420
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_record_read.h110
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_record_read_aead.c254
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_record_read_cbc.c260
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_record_read_composite.c228
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_record_read_stream.c196
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_record_write.c910
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_recv.c458
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_resume.c1424
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_resume.h144
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_security_policies.c1652
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_security_policies.h236
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_send.c434
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_server_cert.c142
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_server_cert_request.c394
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_server_done.c70
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_server_extensions.c144
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_server_extensions.h44
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_server_finished.c262
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_server_hello.c502
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_server_hello_retry.c262
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_server_key_exchange.c670
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_server_key_exchange.h70
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_server_new_session_ticket.c152
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_shutdown.c110
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.c580
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.h82
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_signature_scheme.c682
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_signature_scheme.h162
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_tls.c78
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_tls.h200
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_tls13.c150
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_tls13.h102
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_tls13_certificate_verify.c394
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_tls13_certificate_verify.h42
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.c802
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.h80
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_tls_digest_preferences.h76
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_tls_parameters.h536
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_x509_validator.c1226
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_x509_validator.h268
161 files changed, 25479 insertions, 25479 deletions
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_alpn.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_alpn.c
index 7ad2946880..e66b7c0478 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_alpn.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_alpn.c
@@ -1,129 +1,129 @@
-/*
- * 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 <sys/param.h>
-#include <stdint.h>
-
-#include "tls/extensions/s2n_client_alpn.h"
-
-#include "tls/extensions/s2n_extension_type.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls_parameters.h"
-
-#include "utils/s2n_safety.h"
-
-static bool s2n_client_alpn_should_send(struct s2n_connection *conn);
-static int s2n_client_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-static int s2n_client_alpn_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_client_alpn_extension = {
- .iana_value = TLS_EXTENSION_ALPN,
- .is_response = false,
- .send = s2n_client_alpn_send,
- .recv = s2n_client_alpn_recv,
- .should_send = s2n_client_alpn_should_send,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static bool s2n_client_alpn_should_send(struct s2n_connection *conn)
-{
- struct s2n_blob *client_app_protocols;
-
- return s2n_connection_get_protocol_preferences(conn, &client_app_protocols) == S2N_SUCCESS
- && client_app_protocols->size != 0 && client_app_protocols->data != NULL;
-}
-
-static int s2n_client_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- struct s2n_blob *client_app_protocols;
- GUARD(s2n_connection_get_protocol_preferences(conn, &client_app_protocols));
- notnull_check(client_app_protocols);
-
- GUARD(s2n_stuffer_write_uint16(out, client_app_protocols->size));
- GUARD(s2n_stuffer_write(out, client_app_protocols));
-
- return S2N_SUCCESS;
-}
-
-static int s2n_client_alpn_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- uint16_t size_of_all;
- struct s2n_stuffer client_protos = {0};
- struct s2n_stuffer server_protos = {0};
-
- struct s2n_blob *server_app_protocols;
- GUARD(s2n_connection_get_protocol_preferences(conn, &server_app_protocols));
-
- if (!server_app_protocols->size) {
- /* No protocols configured, nothing to do */
- return S2N_SUCCESS;
- }
-
- GUARD(s2n_stuffer_read_uint16(extension, &size_of_all));
- if (size_of_all > s2n_stuffer_data_available(extension) || size_of_all < 3) {
- /* Malformed length, ignore the extension */
- return S2N_SUCCESS;
- }
-
- struct s2n_blob client_app_protocols = { 0 };
- client_app_protocols.size = size_of_all;
- client_app_protocols.data = s2n_stuffer_raw_read(extension, size_of_all);
- notnull_check(client_app_protocols.data);
-
- /* Find a matching protocol */
- GUARD(s2n_stuffer_init(&client_protos, &client_app_protocols));
- GUARD(s2n_stuffer_write(&client_protos, &client_app_protocols));
- GUARD(s2n_stuffer_init(&server_protos, server_app_protocols));
- GUARD(s2n_stuffer_write(&server_protos, server_app_protocols));
-
- while (s2n_stuffer_data_available(&server_protos)) {
- uint8_t length;
- uint8_t server_protocol[255];
- GUARD(s2n_stuffer_read_uint8(&server_protos, &length));
- GUARD(s2n_stuffer_read_bytes(&server_protos, server_protocol, length));
-
- while (s2n_stuffer_data_available(&client_protos)) {
- uint8_t client_length;
- GUARD(s2n_stuffer_read_uint8(&client_protos, &client_length));
- S2N_ERROR_IF(client_length > s2n_stuffer_data_available(&client_protos), S2N_ERR_BAD_MESSAGE);
- if (client_length != length) {
- GUARD(s2n_stuffer_skip_read(&client_protos, client_length));
- } else {
- uint8_t client_protocol[255];
- GUARD(s2n_stuffer_read_bytes(&client_protos, client_protocol, client_length));
- if (memcmp(client_protocol, server_protocol, client_length) == 0) {
- memcpy_check(conn->application_protocol, client_protocol, client_length);
- conn->application_protocol[client_length] = '\0';
- return S2N_SUCCESS;
- }
- }
- }
-
- GUARD(s2n_stuffer_reread(&client_protos));
- }
- return S2N_SUCCESS;
-}
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-int s2n_extensions_client_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- return s2n_extension_send(&s2n_client_alpn_extension, conn, out);
-}
-
-int s2n_recv_client_alpn(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- return s2n_extension_recv(&s2n_client_alpn_extension, conn, extension);
-}
+/*
+ * 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 <sys/param.h>
+#include <stdint.h>
+
+#include "tls/extensions/s2n_client_alpn.h"
+
+#include "tls/extensions/s2n_extension_type.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls_parameters.h"
+
+#include "utils/s2n_safety.h"
+
+static bool s2n_client_alpn_should_send(struct s2n_connection *conn);
+static int s2n_client_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+static int s2n_client_alpn_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_client_alpn_extension = {
+ .iana_value = TLS_EXTENSION_ALPN,
+ .is_response = false,
+ .send = s2n_client_alpn_send,
+ .recv = s2n_client_alpn_recv,
+ .should_send = s2n_client_alpn_should_send,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static bool s2n_client_alpn_should_send(struct s2n_connection *conn)
+{
+ struct s2n_blob *client_app_protocols;
+
+ return s2n_connection_get_protocol_preferences(conn, &client_app_protocols) == S2N_SUCCESS
+ && client_app_protocols->size != 0 && client_app_protocols->data != NULL;
+}
+
+static int s2n_client_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ struct s2n_blob *client_app_protocols;
+ GUARD(s2n_connection_get_protocol_preferences(conn, &client_app_protocols));
+ notnull_check(client_app_protocols);
+
+ GUARD(s2n_stuffer_write_uint16(out, client_app_protocols->size));
+ GUARD(s2n_stuffer_write(out, client_app_protocols));
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_client_alpn_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ uint16_t size_of_all;
+ struct s2n_stuffer client_protos = {0};
+ struct s2n_stuffer server_protos = {0};
+
+ struct s2n_blob *server_app_protocols;
+ GUARD(s2n_connection_get_protocol_preferences(conn, &server_app_protocols));
+
+ if (!server_app_protocols->size) {
+ /* No protocols configured, nothing to do */
+ return S2N_SUCCESS;
+ }
+
+ GUARD(s2n_stuffer_read_uint16(extension, &size_of_all));
+ if (size_of_all > s2n_stuffer_data_available(extension) || size_of_all < 3) {
+ /* Malformed length, ignore the extension */
+ return S2N_SUCCESS;
+ }
+
+ struct s2n_blob client_app_protocols = { 0 };
+ client_app_protocols.size = size_of_all;
+ client_app_protocols.data = s2n_stuffer_raw_read(extension, size_of_all);
+ notnull_check(client_app_protocols.data);
+
+ /* Find a matching protocol */
+ GUARD(s2n_stuffer_init(&client_protos, &client_app_protocols));
+ GUARD(s2n_stuffer_write(&client_protos, &client_app_protocols));
+ GUARD(s2n_stuffer_init(&server_protos, server_app_protocols));
+ GUARD(s2n_stuffer_write(&server_protos, server_app_protocols));
+
+ while (s2n_stuffer_data_available(&server_protos)) {
+ uint8_t length;
+ uint8_t server_protocol[255];
+ GUARD(s2n_stuffer_read_uint8(&server_protos, &length));
+ GUARD(s2n_stuffer_read_bytes(&server_protos, server_protocol, length));
+
+ while (s2n_stuffer_data_available(&client_protos)) {
+ uint8_t client_length;
+ GUARD(s2n_stuffer_read_uint8(&client_protos, &client_length));
+ S2N_ERROR_IF(client_length > s2n_stuffer_data_available(&client_protos), S2N_ERR_BAD_MESSAGE);
+ if (client_length != length) {
+ GUARD(s2n_stuffer_skip_read(&client_protos, client_length));
+ } else {
+ uint8_t client_protocol[255];
+ GUARD(s2n_stuffer_read_bytes(&client_protos, client_protocol, client_length));
+ if (memcmp(client_protocol, server_protocol, client_length) == 0) {
+ memcpy_check(conn->application_protocol, client_protocol, client_length);
+ conn->application_protocol[client_length] = '\0';
+ return S2N_SUCCESS;
+ }
+ }
+ }
+
+ GUARD(s2n_stuffer_reread(&client_protos));
+ }
+ return S2N_SUCCESS;
+}
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+int s2n_extensions_client_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ return s2n_extension_send(&s2n_client_alpn_extension, conn, out);
+}
+
+int s2n_recv_client_alpn(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ return s2n_extension_recv(&s2n_client_alpn_extension, conn, extension);
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_alpn.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_alpn.h
index d25bbb027b..177ca5daea 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_alpn.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_alpn.h
@@ -1,27 +1,27 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/extensions/s2n_extension_type.h"
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-extern const s2n_extension_type s2n_client_alpn_extension;
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-extern int s2n_extensions_client_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-extern int s2n_recv_client_alpn(struct s2n_connection *conn, struct s2n_stuffer *extension);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/extensions/s2n_extension_type.h"
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+extern const s2n_extension_type s2n_client_alpn_extension;
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+extern int s2n_extensions_client_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+extern int s2n_recv_client_alpn(struct s2n_connection *conn, struct s2n_stuffer *extension);
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_key_share.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_key_share.c
index 1e3ea069f2..97797cc054 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_key_share.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_key_share.c
@@ -1,521 +1,521 @@
-/*
- * 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 "tls/extensions/s2n_client_key_share.h"
-#include "tls/extensions/s2n_key_share.h"
-#include "tls/s2n_security_policies.h"
-#include "tls/s2n_kem_preferences.h"
-
-#include "error/s2n_errno.h"
-#include "stuffer/s2n_stuffer.h"
-#include "utils/s2n_safety.h"
-#include "tls/s2n_tls13.h"
-#include "crypto/s2n_fips.h"
-
-#define S2N_IS_KEY_SHARE_LIST_EMPTY(preferred_key_shares) (preferred_key_shares & 1)
-#define S2N_IS_KEY_SHARE_REQUESTED(preferred_key_shares, i) ((preferred_key_shares >> (i + 1)) & 1)
-/**
- * Specified in https://tools.ietf.org/html/rfc8446#section-4.2.8
- * "The "key_share" extension contains the endpoint's cryptographic parameters."
- *
- * Structure:
- * Extension type (2 bytes)
- * Extension data size (2 bytes)
- * Client shares size (2 bytes)
- * Client shares:
- * Named group (2 bytes)
- * Key share size (2 bytes)
- * Key share (variable size)
- *
- * This extension only modifies the connection's client ecc_evp_params. It does
- * not make any decisions about which set of params to use.
- *
- * The server will NOT alert when processing a client extension that violates the RFC.
- * So the server will accept:
- * - Multiple key shares for the same named group. The server will accept the first
- * key share for the group and ignore any duplicates.
- * - Key shares for named groups not in the client's supported_groups extension.
- **/
-
-static int s2n_client_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-static int s2n_client_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_client_key_share_extension = {
- .iana_value = TLS_EXTENSION_KEY_SHARE,
- .is_response = false,
- .send = s2n_client_key_share_send,
- .recv = s2n_client_key_share_recv,
- .should_send = s2n_extension_send_if_tls13_connection,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static int s2n_generate_preferred_ecc_key_shares(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- notnull_check(conn);
- uint8_t preferred_key_shares = conn->preferred_key_shares;
- struct s2n_ecc_evp_params *ecc_evp_params = NULL;
-
- const struct s2n_ecc_preferences *ecc_pref = NULL;
- GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
- notnull_check(ecc_pref);
-
- /* If lsb is set, skip keyshare generation for all curve */
- if (S2N_IS_KEY_SHARE_LIST_EMPTY(preferred_key_shares)) {
- return S2N_SUCCESS;
- }
-
- for (size_t i = 0; i < ecc_pref->count; i++) {
- /* If a bit in the bitmap (minus the lsb) is set, generate keyshare for the corresponding curve */
- if (S2N_IS_KEY_SHARE_REQUESTED(preferred_key_shares, i)) {
- ecc_evp_params = &conn->secure.client_ecc_evp_params[i];
- ecc_evp_params->negotiated_curve = ecc_pref->ecc_curves[i];
- GUARD(s2n_ecdhe_parameters_send(ecc_evp_params, out));
- }
- }
-
- return S2N_SUCCESS;
-}
-
-static int s2n_generate_default_ecc_key_share(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- notnull_check(conn);
- const struct s2n_ecc_preferences *ecc_pref = NULL;
- GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
- notnull_check(ecc_pref);
-
- struct s2n_ecc_evp_params *ecc_evp_params = NULL;
- ecc_evp_params = &conn->secure.client_ecc_evp_params[0];
- ecc_evp_params->negotiated_curve = ecc_pref->ecc_curves[0];
- GUARD(s2n_ecdhe_parameters_send(ecc_evp_params, out));
-
- return S2N_SUCCESS;
-}
-
-static int s2n_generate_pq_hybrid_key_share(struct s2n_stuffer *out, struct s2n_kem_group_params *kem_group_params) {
- notnull_check(out);
- notnull_check(kem_group_params);
-
- /* This function should never be called when in FIPS mode */
- ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS);
-
- const struct s2n_kem_group *kem_group = kem_group_params->kem_group;
- notnull_check(kem_group);
-
- /* The structure of the PQ share is:
- * IANA ID (2 bytes)
- * || total share size (2 bytes)
- * || size of ECC key share (2 bytes)
- * || ECC key share (variable bytes)
- * || size of PQ key share (2 bytes)
- * || PQ key share (variable bytes) */
- GUARD(s2n_stuffer_write_uint16(out, kem_group->iana_id));
-
- struct s2n_stuffer_reservation total_share_size = {0};
- GUARD(s2n_stuffer_reserve_uint16(out, &total_share_size));
-
- struct s2n_ecc_evp_params *ecc_params = &kem_group_params->ecc_params;
- ecc_params->negotiated_curve = kem_group->curve;
- GUARD(s2n_stuffer_write_uint16(out, ecc_params->negotiated_curve->share_size));
- GUARD(s2n_ecc_evp_generate_ephemeral_key(ecc_params));
- GUARD(s2n_ecc_evp_write_params_point(ecc_params, out));
-
- struct s2n_kem_params *kem_params = &kem_group_params->kem_params;
- kem_params->kem = kem_group->kem;
- GUARD(s2n_kem_send_public_key(out, kem_params));
-
- GUARD(s2n_stuffer_write_vector_size(&total_share_size));
-
- return S2N_SUCCESS;
-}
-
-static int s2n_generate_default_pq_hybrid_key_share(struct s2n_connection *conn, struct s2n_stuffer *out) {
- notnull_check(conn);
- notnull_check(out);
-
- /* Client should skip sending PQ groups/key shares if in FIPS mode */
- if (s2n_is_in_fips_mode()) {
- return S2N_SUCCESS;
- }
-
- const struct s2n_kem_preferences *kem_pref = NULL;
- GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
- notnull_check(kem_pref);
-
- if (kem_pref->tls13_kem_group_count == 0) {
- return S2N_SUCCESS;
- }
-
- /* We only send a single PQ key share - the highest preferred one */
- struct s2n_kem_group_params *kem_group_params = &conn->secure.client_kem_group_params[0];
- kem_group_params->kem_group = kem_pref->tls13_kem_groups[0];
-
- GUARD(s2n_generate_pq_hybrid_key_share(out, kem_group_params));
-
- return S2N_SUCCESS;
-}
-
-static int s2n_wipe_all_client_keyshares(struct s2n_connection *conn) {
- notnull_check(conn);
-
- const struct s2n_ecc_preferences *ecc_pref = NULL;
- GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
- notnull_check(ecc_pref);
-
- const struct s2n_kem_preferences *kem_pref = NULL;
- GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
- notnull_check(kem_pref);
-
- for (size_t i = 0; i < ecc_pref->count; i++) {
- GUARD(s2n_ecc_evp_params_free(&conn->secure.client_ecc_evp_params[i]));
- conn->secure.client_ecc_evp_params[i].negotiated_curve = NULL;
- }
-
- for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) {
- GUARD(s2n_kem_group_free(&conn->secure.client_kem_group_params[i]));
- conn->secure.client_kem_group_params[i].kem_group = NULL;
- conn->secure.client_kem_group_params[i].kem_params.kem = NULL;
- conn->secure.client_kem_group_params[i].ecc_params.negotiated_curve = NULL;
- }
-
- return S2N_SUCCESS;
-}
-
-static int s2n_send_hrr_ecc_keyshare(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- notnull_check(conn);
- const struct s2n_ecc_named_curve *server_negotiated_curve = NULL;
- struct s2n_ecc_evp_params *ecc_evp_params = NULL;
-
- const struct s2n_ecc_preferences *ecc_pref = NULL;
- GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
- notnull_check(ecc_pref);
-
- server_negotiated_curve = conn->secure.server_ecc_evp_params.negotiated_curve;
- ENSURE_POSIX(server_negotiated_curve != NULL, S2N_ERR_BAD_KEY_SHARE);
- ENSURE_POSIX(s2n_ecc_preferences_includes_curve(ecc_pref, server_negotiated_curve->iana_id),
- S2N_ERR_INVALID_HELLO_RETRY);
-
- for (size_t i = 0; i < ecc_pref->count; i++) {
- if (ecc_pref->ecc_curves[i]->iana_id == server_negotiated_curve->iana_id) {
- ecc_evp_params = &conn->secure.client_ecc_evp_params[i];
- ENSURE_POSIX(ecc_evp_params->evp_pkey == NULL, S2N_ERR_INVALID_HELLO_RETRY);
- }
- }
-
- /* None of the previously generated keyshares were selected for negotiation, so wipe them */
- GUARD(s2n_wipe_all_client_keyshares(conn));
- /* Generate the keyshare for the server negotiated curve */
- ecc_evp_params->negotiated_curve = server_negotiated_curve;
- GUARD(s2n_ecdhe_parameters_send(ecc_evp_params, out));
-
- return S2N_SUCCESS;
-}
-
-static int s2n_send_hrr_pq_hybrid_keyshare(struct s2n_connection *conn, struct s2n_stuffer *out) {
- notnull_check(conn);
- notnull_check(out);
-
- /* If in FIPS mode, the client should not have sent any PQ IDs
- * in the supported_groups list of the initial ClientHello */
- ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS);
-
- const struct s2n_kem_preferences *kem_pref = NULL;
- GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
- notnull_check(kem_pref);
-
- const struct s2n_kem_group *server_negotiated_kem_group = conn->secure.server_kem_group_params.kem_group;
- ENSURE_POSIX(server_negotiated_kem_group != NULL, S2N_ERR_INVALID_HELLO_RETRY);
- ENSURE_POSIX(s2n_kem_preferences_includes_tls13_kem_group(kem_pref, server_negotiated_kem_group->iana_id),
- S2N_ERR_INVALID_HELLO_RETRY);
- struct s2n_kem_group_params *kem_group_params = NULL;
-
- for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) {
- if (kem_pref->tls13_kem_groups[i]->iana_id == server_negotiated_kem_group->iana_id) {
- kem_group_params = &conn->secure.client_kem_group_params[i];
- ENSURE_POSIX(kem_group_params->kem_group == NULL, S2N_ERR_INVALID_HELLO_RETRY);
- ENSURE_POSIX(kem_group_params->ecc_params.evp_pkey == NULL, S2N_ERR_INVALID_HELLO_RETRY);
- ENSURE_POSIX(kem_group_params->kem_params.private_key.data == NULL, S2N_ERR_INVALID_HELLO_RETRY);
- }
- }
-
- /* None of the previously generated keyshares were selected for negotiation, so wipe them */
- GUARD(s2n_wipe_all_client_keyshares(conn));
- /* Generate the keyshare for the server negotiated KEM group */
- kem_group_params->kem_group = server_negotiated_kem_group;
- GUARD(s2n_generate_pq_hybrid_key_share(out, kem_group_params));
-
- return S2N_SUCCESS;
-}
-
-/* From https://tools.ietf.org/html/rfc8446#section-4.1.2
- * If a "key_share" extension was supplied in the HelloRetryRequest,
- * replace the list of shares with a list containing a single
- * KeyShareEntry from the indicated group.*/
-static int s2n_send_hrr_keyshare(struct s2n_connection *conn, struct s2n_stuffer *out) {
- notnull_check(conn);
- notnull_check(out);
-
- if (conn->secure.server_kem_group_params.kem_group != NULL) {
- GUARD(s2n_send_hrr_pq_hybrid_keyshare(conn, out));
- } else {
- GUARD(s2n_send_hrr_ecc_keyshare(conn, out));
- }
-
- return S2N_SUCCESS;
-}
-
-static int s2n_ecdhe_supported_curves_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- if (!conn->preferred_key_shares) {
- GUARD(s2n_generate_default_ecc_key_share(conn, out));
- return S2N_SUCCESS;
- }
-
- GUARD(s2n_generate_preferred_ecc_key_shares(conn, out));
- return S2N_SUCCESS;
-}
-
-static int s2n_client_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- struct s2n_stuffer_reservation shares_size = {0};
- GUARD(s2n_stuffer_reserve_uint16(out, &shares_size));
-
- if (s2n_is_hello_retry_handshake(conn)) {
- GUARD(s2n_send_hrr_keyshare(conn, out));
- } else {
- GUARD(s2n_generate_default_pq_hybrid_key_share(conn, out));
- GUARD(s2n_ecdhe_supported_curves_send(conn, out));
- }
-
- GUARD(s2n_stuffer_write_vector_size(&shares_size));
-
- return S2N_SUCCESS;
-}
-
-static int s2n_client_key_share_parse_ecc(struct s2n_stuffer *key_share, const struct s2n_ecc_named_curve *curve,
- struct s2n_ecc_evp_params *ecc_params) {
- notnull_check(key_share);
- notnull_check(curve);
- notnull_check(ecc_params);
-
- struct s2n_blob point_blob = { 0 };
- GUARD(s2n_ecc_evp_read_params_point(key_share, curve->share_size, &point_blob));
-
- /* Ignore curves with points we can't parse */
- ecc_params->negotiated_curve = curve;
- if (s2n_ecc_evp_parse_params_point(&point_blob, ecc_params) != S2N_SUCCESS) {
- ecc_params->negotiated_curve = NULL;
- GUARD(s2n_ecc_evp_params_free(ecc_params));
- }
-
- return S2N_SUCCESS;
-}
-
-static int s2n_client_key_share_recv_ecc(struct s2n_connection *conn, struct s2n_stuffer *key_share,
- uint16_t curve_iana_id, bool *match) {
- notnull_check(conn);
- notnull_check(key_share);
- notnull_check(match);
-
- const struct s2n_ecc_preferences *ecc_pref = NULL;
- GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
- notnull_check(ecc_pref);
-
- const struct s2n_ecc_named_curve *curve = NULL;
- struct s2n_ecc_evp_params *client_ecc_params = NULL;
- for (size_t i = 0; i < ecc_pref->count; i++) {
- if (curve_iana_id == ecc_pref->ecc_curves[i]->iana_id) {
- curve = ecc_pref->ecc_curves[i];
- client_ecc_params = &conn->secure.client_ecc_evp_params[i];
- break;
- }
- }
-
- /* Ignore unsupported curves */
- if (!curve || !client_ecc_params) {
- return S2N_SUCCESS;
- }
-
- /* Ignore curves that we've already received material for */
- if (client_ecc_params->negotiated_curve) {
- return S2N_SUCCESS;
- }
-
- /* Ignore curves with unexpected share sizes */
- if (key_share->blob.size != curve->share_size) {
- return S2N_SUCCESS;
- }
-
- GUARD(s2n_client_key_share_parse_ecc(key_share, curve, client_ecc_params));
- /* negotiated_curve will be non-NULL if the key share was parsed successfully */
- if (client_ecc_params->negotiated_curve) {
- *match = true;
- }
-
- return S2N_SUCCESS;
-}
-
-static int s2n_client_key_share_recv_pq_hybrid(struct s2n_connection *conn, struct s2n_stuffer *key_share,
- uint16_t kem_group_iana_id, bool *match) {
- notnull_check(conn);
- notnull_check(key_share);
- notnull_check(match);
-
- const struct s2n_kem_preferences *kem_pref = NULL;
- GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
- notnull_check(kem_pref);
-
- ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS);
-
- const struct s2n_kem_group *kem_group = NULL;
- struct s2n_kem_group_params *client_kem_group_params = NULL;
- for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) {
- if (kem_group_iana_id == kem_pref->tls13_kem_groups[i]->iana_id) {
- kem_group = kem_pref->tls13_kem_groups[i];
- client_kem_group_params = &conn->secure.client_kem_group_params[i];
- break;
- }
- }
-
- /* Ignore unsupported KEM groups */
- if (!kem_group || !client_kem_group_params) {
- return S2N_SUCCESS;
- }
-
- /* Ignore KEM groups that we've already received material for */
- if (client_kem_group_params->kem_group) {
- return S2N_SUCCESS;
- }
-
- /* Ignore KEM groups with unexpected overall total share sizes */
- if (key_share->blob.size != kem_group->client_share_size) {
- return S2N_SUCCESS;
- }
-
- uint16_t ec_share_size = 0;
- GUARD(s2n_stuffer_read_uint16(key_share, &ec_share_size));
- /* Ignore KEM groups with unexpected ECC share sizes */
- if (ec_share_size != kem_group->curve->share_size) {
- return S2N_SUCCESS;
- }
-
- GUARD(s2n_client_key_share_parse_ecc(key_share, kem_group->curve, &client_kem_group_params->ecc_params));
- /* If we were unable to parse the EC portion of the share, negotiated_curve
- * will be NULL, and we should ignore the entire key share. */
- if (!client_kem_group_params->ecc_params.negotiated_curve) {
- return S2N_SUCCESS;
- }
-
- /* Note: the PQ share size is validated in s2n_kem_recv_public_key() */
- /* Ignore groups with PQ public keys we can't parse */
- client_kem_group_params->kem_params.kem = kem_group->kem;
- if (s2n_kem_recv_public_key(key_share, &client_kem_group_params->kem_params) != S2N_SUCCESS) {
- client_kem_group_params->kem_group = NULL;
- client_kem_group_params->kem_params.kem = NULL;
- client_kem_group_params->ecc_params.negotiated_curve = NULL;
- /* s2n_kem_group_free() will free both the ECC and KEM params */
- GUARD(s2n_kem_group_free(client_kem_group_params));
- return S2N_SUCCESS;
- }
-
- client_kem_group_params->kem_group = kem_group;
- *match = true;
- return S2N_SUCCESS;
-}
-
-static int s2n_client_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) {
- notnull_check(conn);
- notnull_check(extension);
-
- if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
- return S2N_SUCCESS;
- }
-
- const struct s2n_ecc_preferences *ecc_pref = NULL;
- GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
- notnull_check(ecc_pref);
-
- const struct s2n_kem_preferences *kem_pref = NULL;
- GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
- notnull_check(kem_pref);
-
- uint16_t key_shares_size;
- GUARD(s2n_stuffer_read_uint16(extension, &key_shares_size));
- ENSURE_POSIX(s2n_stuffer_data_available(extension) >= key_shares_size, S2N_ERR_BAD_MESSAGE);
-
- uint16_t named_group, share_size;
- bool match_found = false;
- /* bytes_processed is declared as a uint32_t to avoid integer overflow in later calculations */
- uint32_t bytes_processed = 0;
-
- while (bytes_processed < key_shares_size) {
- GUARD(s2n_stuffer_read_uint16(extension, &named_group));
- GUARD(s2n_stuffer_read_uint16(extension, &share_size));
-
- ENSURE_POSIX(s2n_stuffer_data_available(extension) >= share_size, S2N_ERR_BAD_MESSAGE);
- bytes_processed += share_size + S2N_SIZE_OF_NAMED_GROUP + S2N_SIZE_OF_KEY_SHARE_SIZE;
-
- struct s2n_blob key_share_blob = { .size = share_size, .data = s2n_stuffer_raw_read(extension, share_size) };
- notnull_check(key_share_blob.data);
- struct s2n_stuffer key_share = { 0 };
- GUARD(s2n_stuffer_init(&key_share, &key_share_blob));
- GUARD(s2n_stuffer_skip_write(&key_share, share_size));
-
- /* Try to parse the share as ECC, then as PQ/hybrid; will ignore
- * shares for unrecognized groups. */
- GUARD(s2n_client_key_share_recv_ecc(conn, &key_share, named_group, &match_found));
- if (!s2n_is_in_fips_mode()) {
- GUARD(s2n_client_key_share_recv_pq_hybrid(conn, &key_share, named_group, &match_found));
- }
- }
-
- /* If there were no matching key shares, then we received an empty key share extension
- * or we didn't match a key share with a supported group. We should send a retry. */
- if (!match_found) {
- GUARD(s2n_set_hello_retry_required(conn));
- }
-
- return S2N_SUCCESS;
-}
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-uint32_t s2n_extensions_client_key_share_size(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- const struct s2n_ecc_preferences *ecc_pref = NULL;
- GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
- notnull_check(ecc_pref);
-
- uint32_t s2n_client_key_share_extension_size = S2N_SIZE_OF_EXTENSION_TYPE
- + S2N_SIZE_OF_EXTENSION_DATA_SIZE
- + S2N_SIZE_OF_CLIENT_SHARES_SIZE;
-
- s2n_client_key_share_extension_size += S2N_SIZE_OF_KEY_SHARE_SIZE + S2N_SIZE_OF_NAMED_GROUP;
- s2n_client_key_share_extension_size += ecc_pref->ecc_curves[0]->share_size;
-
- return s2n_client_key_share_extension_size;
-}
-
-int s2n_extensions_client_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- return s2n_extension_send(&s2n_client_key_share_extension, conn, out);
-}
-
-int s2n_extensions_client_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- return s2n_extension_recv(&s2n_client_key_share_extension, conn, extension);
-}
+/*
+ * 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 "tls/extensions/s2n_client_key_share.h"
+#include "tls/extensions/s2n_key_share.h"
+#include "tls/s2n_security_policies.h"
+#include "tls/s2n_kem_preferences.h"
+
+#include "error/s2n_errno.h"
+#include "stuffer/s2n_stuffer.h"
+#include "utils/s2n_safety.h"
+#include "tls/s2n_tls13.h"
+#include "crypto/s2n_fips.h"
+
+#define S2N_IS_KEY_SHARE_LIST_EMPTY(preferred_key_shares) (preferred_key_shares & 1)
+#define S2N_IS_KEY_SHARE_REQUESTED(preferred_key_shares, i) ((preferred_key_shares >> (i + 1)) & 1)
+/**
+ * Specified in https://tools.ietf.org/html/rfc8446#section-4.2.8
+ * "The "key_share" extension contains the endpoint's cryptographic parameters."
+ *
+ * Structure:
+ * Extension type (2 bytes)
+ * Extension data size (2 bytes)
+ * Client shares size (2 bytes)
+ * Client shares:
+ * Named group (2 bytes)
+ * Key share size (2 bytes)
+ * Key share (variable size)
+ *
+ * This extension only modifies the connection's client ecc_evp_params. It does
+ * not make any decisions about which set of params to use.
+ *
+ * The server will NOT alert when processing a client extension that violates the RFC.
+ * So the server will accept:
+ * - Multiple key shares for the same named group. The server will accept the first
+ * key share for the group and ignore any duplicates.
+ * - Key shares for named groups not in the client's supported_groups extension.
+ **/
+
+static int s2n_client_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+static int s2n_client_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_client_key_share_extension = {
+ .iana_value = TLS_EXTENSION_KEY_SHARE,
+ .is_response = false,
+ .send = s2n_client_key_share_send,
+ .recv = s2n_client_key_share_recv,
+ .should_send = s2n_extension_send_if_tls13_connection,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static int s2n_generate_preferred_ecc_key_shares(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ notnull_check(conn);
+ uint8_t preferred_key_shares = conn->preferred_key_shares;
+ struct s2n_ecc_evp_params *ecc_evp_params = NULL;
+
+ const struct s2n_ecc_preferences *ecc_pref = NULL;
+ GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
+ notnull_check(ecc_pref);
+
+ /* If lsb is set, skip keyshare generation for all curve */
+ if (S2N_IS_KEY_SHARE_LIST_EMPTY(preferred_key_shares)) {
+ return S2N_SUCCESS;
+ }
+
+ for (size_t i = 0; i < ecc_pref->count; i++) {
+ /* If a bit in the bitmap (minus the lsb) is set, generate keyshare for the corresponding curve */
+ if (S2N_IS_KEY_SHARE_REQUESTED(preferred_key_shares, i)) {
+ ecc_evp_params = &conn->secure.client_ecc_evp_params[i];
+ ecc_evp_params->negotiated_curve = ecc_pref->ecc_curves[i];
+ GUARD(s2n_ecdhe_parameters_send(ecc_evp_params, out));
+ }
+ }
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_generate_default_ecc_key_share(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ notnull_check(conn);
+ const struct s2n_ecc_preferences *ecc_pref = NULL;
+ GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
+ notnull_check(ecc_pref);
+
+ struct s2n_ecc_evp_params *ecc_evp_params = NULL;
+ ecc_evp_params = &conn->secure.client_ecc_evp_params[0];
+ ecc_evp_params->negotiated_curve = ecc_pref->ecc_curves[0];
+ GUARD(s2n_ecdhe_parameters_send(ecc_evp_params, out));
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_generate_pq_hybrid_key_share(struct s2n_stuffer *out, struct s2n_kem_group_params *kem_group_params) {
+ notnull_check(out);
+ notnull_check(kem_group_params);
+
+ /* This function should never be called when in FIPS mode */
+ ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS);
+
+ const struct s2n_kem_group *kem_group = kem_group_params->kem_group;
+ notnull_check(kem_group);
+
+ /* The structure of the PQ share is:
+ * IANA ID (2 bytes)
+ * || total share size (2 bytes)
+ * || size of ECC key share (2 bytes)
+ * || ECC key share (variable bytes)
+ * || size of PQ key share (2 bytes)
+ * || PQ key share (variable bytes) */
+ GUARD(s2n_stuffer_write_uint16(out, kem_group->iana_id));
+
+ struct s2n_stuffer_reservation total_share_size = {0};
+ GUARD(s2n_stuffer_reserve_uint16(out, &total_share_size));
+
+ struct s2n_ecc_evp_params *ecc_params = &kem_group_params->ecc_params;
+ ecc_params->negotiated_curve = kem_group->curve;
+ GUARD(s2n_stuffer_write_uint16(out, ecc_params->negotiated_curve->share_size));
+ GUARD(s2n_ecc_evp_generate_ephemeral_key(ecc_params));
+ GUARD(s2n_ecc_evp_write_params_point(ecc_params, out));
+
+ struct s2n_kem_params *kem_params = &kem_group_params->kem_params;
+ kem_params->kem = kem_group->kem;
+ GUARD(s2n_kem_send_public_key(out, kem_params));
+
+ GUARD(s2n_stuffer_write_vector_size(&total_share_size));
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_generate_default_pq_hybrid_key_share(struct s2n_connection *conn, struct s2n_stuffer *out) {
+ notnull_check(conn);
+ notnull_check(out);
+
+ /* Client should skip sending PQ groups/key shares if in FIPS mode */
+ if (s2n_is_in_fips_mode()) {
+ return S2N_SUCCESS;
+ }
+
+ const struct s2n_kem_preferences *kem_pref = NULL;
+ GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
+ notnull_check(kem_pref);
+
+ if (kem_pref->tls13_kem_group_count == 0) {
+ return S2N_SUCCESS;
+ }
+
+ /* We only send a single PQ key share - the highest preferred one */
+ struct s2n_kem_group_params *kem_group_params = &conn->secure.client_kem_group_params[0];
+ kem_group_params->kem_group = kem_pref->tls13_kem_groups[0];
+
+ GUARD(s2n_generate_pq_hybrid_key_share(out, kem_group_params));
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_wipe_all_client_keyshares(struct s2n_connection *conn) {
+ notnull_check(conn);
+
+ const struct s2n_ecc_preferences *ecc_pref = NULL;
+ GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
+ notnull_check(ecc_pref);
+
+ const struct s2n_kem_preferences *kem_pref = NULL;
+ GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
+ notnull_check(kem_pref);
+
+ for (size_t i = 0; i < ecc_pref->count; i++) {
+ GUARD(s2n_ecc_evp_params_free(&conn->secure.client_ecc_evp_params[i]));
+ conn->secure.client_ecc_evp_params[i].negotiated_curve = NULL;
+ }
+
+ for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) {
+ GUARD(s2n_kem_group_free(&conn->secure.client_kem_group_params[i]));
+ conn->secure.client_kem_group_params[i].kem_group = NULL;
+ conn->secure.client_kem_group_params[i].kem_params.kem = NULL;
+ conn->secure.client_kem_group_params[i].ecc_params.negotiated_curve = NULL;
+ }
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_send_hrr_ecc_keyshare(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ notnull_check(conn);
+ const struct s2n_ecc_named_curve *server_negotiated_curve = NULL;
+ struct s2n_ecc_evp_params *ecc_evp_params = NULL;
+
+ const struct s2n_ecc_preferences *ecc_pref = NULL;
+ GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
+ notnull_check(ecc_pref);
+
+ server_negotiated_curve = conn->secure.server_ecc_evp_params.negotiated_curve;
+ ENSURE_POSIX(server_negotiated_curve != NULL, S2N_ERR_BAD_KEY_SHARE);
+ ENSURE_POSIX(s2n_ecc_preferences_includes_curve(ecc_pref, server_negotiated_curve->iana_id),
+ S2N_ERR_INVALID_HELLO_RETRY);
+
+ for (size_t i = 0; i < ecc_pref->count; i++) {
+ if (ecc_pref->ecc_curves[i]->iana_id == server_negotiated_curve->iana_id) {
+ ecc_evp_params = &conn->secure.client_ecc_evp_params[i];
+ ENSURE_POSIX(ecc_evp_params->evp_pkey == NULL, S2N_ERR_INVALID_HELLO_RETRY);
+ }
+ }
+
+ /* None of the previously generated keyshares were selected for negotiation, so wipe them */
+ GUARD(s2n_wipe_all_client_keyshares(conn));
+ /* Generate the keyshare for the server negotiated curve */
+ ecc_evp_params->negotiated_curve = server_negotiated_curve;
+ GUARD(s2n_ecdhe_parameters_send(ecc_evp_params, out));
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_send_hrr_pq_hybrid_keyshare(struct s2n_connection *conn, struct s2n_stuffer *out) {
+ notnull_check(conn);
+ notnull_check(out);
+
+ /* If in FIPS mode, the client should not have sent any PQ IDs
+ * in the supported_groups list of the initial ClientHello */
+ ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS);
+
+ const struct s2n_kem_preferences *kem_pref = NULL;
+ GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
+ notnull_check(kem_pref);
+
+ const struct s2n_kem_group *server_negotiated_kem_group = conn->secure.server_kem_group_params.kem_group;
+ ENSURE_POSIX(server_negotiated_kem_group != NULL, S2N_ERR_INVALID_HELLO_RETRY);
+ ENSURE_POSIX(s2n_kem_preferences_includes_tls13_kem_group(kem_pref, server_negotiated_kem_group->iana_id),
+ S2N_ERR_INVALID_HELLO_RETRY);
+ struct s2n_kem_group_params *kem_group_params = NULL;
+
+ for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) {
+ if (kem_pref->tls13_kem_groups[i]->iana_id == server_negotiated_kem_group->iana_id) {
+ kem_group_params = &conn->secure.client_kem_group_params[i];
+ ENSURE_POSIX(kem_group_params->kem_group == NULL, S2N_ERR_INVALID_HELLO_RETRY);
+ ENSURE_POSIX(kem_group_params->ecc_params.evp_pkey == NULL, S2N_ERR_INVALID_HELLO_RETRY);
+ ENSURE_POSIX(kem_group_params->kem_params.private_key.data == NULL, S2N_ERR_INVALID_HELLO_RETRY);
+ }
+ }
+
+ /* None of the previously generated keyshares were selected for negotiation, so wipe them */
+ GUARD(s2n_wipe_all_client_keyshares(conn));
+ /* Generate the keyshare for the server negotiated KEM group */
+ kem_group_params->kem_group = server_negotiated_kem_group;
+ GUARD(s2n_generate_pq_hybrid_key_share(out, kem_group_params));
+
+ return S2N_SUCCESS;
+}
+
+/* From https://tools.ietf.org/html/rfc8446#section-4.1.2
+ * If a "key_share" extension was supplied in the HelloRetryRequest,
+ * replace the list of shares with a list containing a single
+ * KeyShareEntry from the indicated group.*/
+static int s2n_send_hrr_keyshare(struct s2n_connection *conn, struct s2n_stuffer *out) {
+ notnull_check(conn);
+ notnull_check(out);
+
+ if (conn->secure.server_kem_group_params.kem_group != NULL) {
+ GUARD(s2n_send_hrr_pq_hybrid_keyshare(conn, out));
+ } else {
+ GUARD(s2n_send_hrr_ecc_keyshare(conn, out));
+ }
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_ecdhe_supported_curves_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ if (!conn->preferred_key_shares) {
+ GUARD(s2n_generate_default_ecc_key_share(conn, out));
+ return S2N_SUCCESS;
+ }
+
+ GUARD(s2n_generate_preferred_ecc_key_shares(conn, out));
+ return S2N_SUCCESS;
+}
+
+static int s2n_client_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ struct s2n_stuffer_reservation shares_size = {0};
+ GUARD(s2n_stuffer_reserve_uint16(out, &shares_size));
+
+ if (s2n_is_hello_retry_handshake(conn)) {
+ GUARD(s2n_send_hrr_keyshare(conn, out));
+ } else {
+ GUARD(s2n_generate_default_pq_hybrid_key_share(conn, out));
+ GUARD(s2n_ecdhe_supported_curves_send(conn, out));
+ }
+
+ GUARD(s2n_stuffer_write_vector_size(&shares_size));
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_client_key_share_parse_ecc(struct s2n_stuffer *key_share, const struct s2n_ecc_named_curve *curve,
+ struct s2n_ecc_evp_params *ecc_params) {
+ notnull_check(key_share);
+ notnull_check(curve);
+ notnull_check(ecc_params);
+
+ struct s2n_blob point_blob = { 0 };
+ GUARD(s2n_ecc_evp_read_params_point(key_share, curve->share_size, &point_blob));
+
+ /* Ignore curves with points we can't parse */
+ ecc_params->negotiated_curve = curve;
+ if (s2n_ecc_evp_parse_params_point(&point_blob, ecc_params) != S2N_SUCCESS) {
+ ecc_params->negotiated_curve = NULL;
+ GUARD(s2n_ecc_evp_params_free(ecc_params));
+ }
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_client_key_share_recv_ecc(struct s2n_connection *conn, struct s2n_stuffer *key_share,
+ uint16_t curve_iana_id, bool *match) {
+ notnull_check(conn);
+ notnull_check(key_share);
+ notnull_check(match);
+
+ const struct s2n_ecc_preferences *ecc_pref = NULL;
+ GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
+ notnull_check(ecc_pref);
+
+ const struct s2n_ecc_named_curve *curve = NULL;
+ struct s2n_ecc_evp_params *client_ecc_params = NULL;
+ for (size_t i = 0; i < ecc_pref->count; i++) {
+ if (curve_iana_id == ecc_pref->ecc_curves[i]->iana_id) {
+ curve = ecc_pref->ecc_curves[i];
+ client_ecc_params = &conn->secure.client_ecc_evp_params[i];
+ break;
+ }
+ }
+
+ /* Ignore unsupported curves */
+ if (!curve || !client_ecc_params) {
+ return S2N_SUCCESS;
+ }
+
+ /* Ignore curves that we've already received material for */
+ if (client_ecc_params->negotiated_curve) {
+ return S2N_SUCCESS;
+ }
+
+ /* Ignore curves with unexpected share sizes */
+ if (key_share->blob.size != curve->share_size) {
+ return S2N_SUCCESS;
+ }
+
+ GUARD(s2n_client_key_share_parse_ecc(key_share, curve, client_ecc_params));
+ /* negotiated_curve will be non-NULL if the key share was parsed successfully */
+ if (client_ecc_params->negotiated_curve) {
+ *match = true;
+ }
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_client_key_share_recv_pq_hybrid(struct s2n_connection *conn, struct s2n_stuffer *key_share,
+ uint16_t kem_group_iana_id, bool *match) {
+ notnull_check(conn);
+ notnull_check(key_share);
+ notnull_check(match);
+
+ const struct s2n_kem_preferences *kem_pref = NULL;
+ GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
+ notnull_check(kem_pref);
+
+ ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS);
+
+ const struct s2n_kem_group *kem_group = NULL;
+ struct s2n_kem_group_params *client_kem_group_params = NULL;
+ for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) {
+ if (kem_group_iana_id == kem_pref->tls13_kem_groups[i]->iana_id) {
+ kem_group = kem_pref->tls13_kem_groups[i];
+ client_kem_group_params = &conn->secure.client_kem_group_params[i];
+ break;
+ }
+ }
+
+ /* Ignore unsupported KEM groups */
+ if (!kem_group || !client_kem_group_params) {
+ return S2N_SUCCESS;
+ }
+
+ /* Ignore KEM groups that we've already received material for */
+ if (client_kem_group_params->kem_group) {
+ return S2N_SUCCESS;
+ }
+
+ /* Ignore KEM groups with unexpected overall total share sizes */
+ if (key_share->blob.size != kem_group->client_share_size) {
+ return S2N_SUCCESS;
+ }
+
+ uint16_t ec_share_size = 0;
+ GUARD(s2n_stuffer_read_uint16(key_share, &ec_share_size));
+ /* Ignore KEM groups with unexpected ECC share sizes */
+ if (ec_share_size != kem_group->curve->share_size) {
+ return S2N_SUCCESS;
+ }
+
+ GUARD(s2n_client_key_share_parse_ecc(key_share, kem_group->curve, &client_kem_group_params->ecc_params));
+ /* If we were unable to parse the EC portion of the share, negotiated_curve
+ * will be NULL, and we should ignore the entire key share. */
+ if (!client_kem_group_params->ecc_params.negotiated_curve) {
+ return S2N_SUCCESS;
+ }
+
+ /* Note: the PQ share size is validated in s2n_kem_recv_public_key() */
+ /* Ignore groups with PQ public keys we can't parse */
+ client_kem_group_params->kem_params.kem = kem_group->kem;
+ if (s2n_kem_recv_public_key(key_share, &client_kem_group_params->kem_params) != S2N_SUCCESS) {
+ client_kem_group_params->kem_group = NULL;
+ client_kem_group_params->kem_params.kem = NULL;
+ client_kem_group_params->ecc_params.negotiated_curve = NULL;
+ /* s2n_kem_group_free() will free both the ECC and KEM params */
+ GUARD(s2n_kem_group_free(client_kem_group_params));
+ return S2N_SUCCESS;
+ }
+
+ client_kem_group_params->kem_group = kem_group;
+ *match = true;
+ return S2N_SUCCESS;
+}
+
+static int s2n_client_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) {
+ notnull_check(conn);
+ notnull_check(extension);
+
+ if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
+ return S2N_SUCCESS;
+ }
+
+ const struct s2n_ecc_preferences *ecc_pref = NULL;
+ GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
+ notnull_check(ecc_pref);
+
+ const struct s2n_kem_preferences *kem_pref = NULL;
+ GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
+ notnull_check(kem_pref);
+
+ uint16_t key_shares_size;
+ GUARD(s2n_stuffer_read_uint16(extension, &key_shares_size));
+ ENSURE_POSIX(s2n_stuffer_data_available(extension) >= key_shares_size, S2N_ERR_BAD_MESSAGE);
+
+ uint16_t named_group, share_size;
+ bool match_found = false;
+ /* bytes_processed is declared as a uint32_t to avoid integer overflow in later calculations */
+ uint32_t bytes_processed = 0;
+
+ while (bytes_processed < key_shares_size) {
+ GUARD(s2n_stuffer_read_uint16(extension, &named_group));
+ GUARD(s2n_stuffer_read_uint16(extension, &share_size));
+
+ ENSURE_POSIX(s2n_stuffer_data_available(extension) >= share_size, S2N_ERR_BAD_MESSAGE);
+ bytes_processed += share_size + S2N_SIZE_OF_NAMED_GROUP + S2N_SIZE_OF_KEY_SHARE_SIZE;
+
+ struct s2n_blob key_share_blob = { .size = share_size, .data = s2n_stuffer_raw_read(extension, share_size) };
+ notnull_check(key_share_blob.data);
+ struct s2n_stuffer key_share = { 0 };
+ GUARD(s2n_stuffer_init(&key_share, &key_share_blob));
+ GUARD(s2n_stuffer_skip_write(&key_share, share_size));
+
+ /* Try to parse the share as ECC, then as PQ/hybrid; will ignore
+ * shares for unrecognized groups. */
+ GUARD(s2n_client_key_share_recv_ecc(conn, &key_share, named_group, &match_found));
+ if (!s2n_is_in_fips_mode()) {
+ GUARD(s2n_client_key_share_recv_pq_hybrid(conn, &key_share, named_group, &match_found));
+ }
+ }
+
+ /* If there were no matching key shares, then we received an empty key share extension
+ * or we didn't match a key share with a supported group. We should send a retry. */
+ if (!match_found) {
+ GUARD(s2n_set_hello_retry_required(conn));
+ }
+
+ return S2N_SUCCESS;
+}
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+uint32_t s2n_extensions_client_key_share_size(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ const struct s2n_ecc_preferences *ecc_pref = NULL;
+ GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
+ notnull_check(ecc_pref);
+
+ uint32_t s2n_client_key_share_extension_size = S2N_SIZE_OF_EXTENSION_TYPE
+ + S2N_SIZE_OF_EXTENSION_DATA_SIZE
+ + S2N_SIZE_OF_CLIENT_SHARES_SIZE;
+
+ s2n_client_key_share_extension_size += S2N_SIZE_OF_KEY_SHARE_SIZE + S2N_SIZE_OF_NAMED_GROUP;
+ s2n_client_key_share_extension_size += ecc_pref->ecc_curves[0]->share_size;
+
+ return s2n_client_key_share_extension_size;
+}
+
+int s2n_extensions_client_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ return s2n_extension_send(&s2n_client_key_share_extension, conn, out);
+}
+
+int s2n_extensions_client_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ return s2n_extension_recv(&s2n_client_key_share_extension, conn, extension);
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_key_share.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_key_share.h
index 365bc2ecf1..9977625680 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_key_share.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_key_share.h
@@ -1,27 +1,27 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-extern const s2n_extension_type s2n_client_key_share_extension;
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-extern int s2n_extensions_client_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-extern uint32_t s2n_extensions_client_key_share_size(struct s2n_connection *conn);
-extern int s2n_extensions_client_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+extern const s2n_extension_type s2n_client_key_share_extension;
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+extern int s2n_extensions_client_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+extern uint32_t s2n_extensions_client_key_share_size(struct s2n_connection *conn);
+extern int s2n_extensions_client_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_max_frag_len.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_max_frag_len.c
index 6f419250db..880193a1a1 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_max_frag_len.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_max_frag_len.c
@@ -1,75 +1,75 @@
-/*
- * 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 <sys/param.h>
-#include <stdint.h>
-
-#include "tls/extensions/s2n_client_max_frag_len.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls_parameters.h"
-
-#include "utils/s2n_safety.h"
-
-static bool s2n_client_max_frag_len_should_send(struct s2n_connection *conn);
-static int s2n_client_max_frag_len_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-static int s2n_client_max_frag_len_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_client_max_frag_len_extension = {
- .iana_value = TLS_EXTENSION_MAX_FRAG_LEN,
- .is_response = false,
- .send = s2n_client_max_frag_len_send,
- .recv = s2n_client_max_frag_len_recv,
- .should_send = s2n_client_max_frag_len_should_send,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static bool s2n_client_max_frag_len_should_send(struct s2n_connection *conn)
-{
- return conn->config->mfl_code != S2N_TLS_MAX_FRAG_LEN_EXT_NONE;
-}
-
-static int s2n_client_max_frag_len_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- return s2n_stuffer_write_uint8(out, conn->config->mfl_code);
-}
-
-static int s2n_client_max_frag_len_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- if (!conn->config->accept_mfl) {
- return S2N_SUCCESS;
- }
-
- uint8_t mfl_code;
- GUARD(s2n_stuffer_read_uint8(extension, &mfl_code));
- if (mfl_code > S2N_TLS_MAX_FRAG_LEN_4096 || mfl_code_to_length[mfl_code] > S2N_TLS_MAXIMUM_FRAGMENT_LENGTH) {
- return S2N_SUCCESS;
- }
-
- conn->mfl_code = mfl_code;
- conn->max_outgoing_fragment_length = mfl_code_to_length[mfl_code];
- return S2N_SUCCESS;
-}
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-int s2n_extensions_client_max_frag_len_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- return s2n_extension_send(&s2n_client_max_frag_len_extension, conn, out);
-}
-
-int s2n_recv_client_max_frag_len(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- return s2n_extension_recv(&s2n_client_max_frag_len_extension, conn, extension);
-}
+/*
+ * 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 <sys/param.h>
+#include <stdint.h>
+
+#include "tls/extensions/s2n_client_max_frag_len.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls_parameters.h"
+
+#include "utils/s2n_safety.h"
+
+static bool s2n_client_max_frag_len_should_send(struct s2n_connection *conn);
+static int s2n_client_max_frag_len_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+static int s2n_client_max_frag_len_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_client_max_frag_len_extension = {
+ .iana_value = TLS_EXTENSION_MAX_FRAG_LEN,
+ .is_response = false,
+ .send = s2n_client_max_frag_len_send,
+ .recv = s2n_client_max_frag_len_recv,
+ .should_send = s2n_client_max_frag_len_should_send,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static bool s2n_client_max_frag_len_should_send(struct s2n_connection *conn)
+{
+ return conn->config->mfl_code != S2N_TLS_MAX_FRAG_LEN_EXT_NONE;
+}
+
+static int s2n_client_max_frag_len_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ return s2n_stuffer_write_uint8(out, conn->config->mfl_code);
+}
+
+static int s2n_client_max_frag_len_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ if (!conn->config->accept_mfl) {
+ return S2N_SUCCESS;
+ }
+
+ uint8_t mfl_code;
+ GUARD(s2n_stuffer_read_uint8(extension, &mfl_code));
+ if (mfl_code > S2N_TLS_MAX_FRAG_LEN_4096 || mfl_code_to_length[mfl_code] > S2N_TLS_MAXIMUM_FRAGMENT_LENGTH) {
+ return S2N_SUCCESS;
+ }
+
+ conn->mfl_code = mfl_code;
+ conn->max_outgoing_fragment_length = mfl_code_to_length[mfl_code];
+ return S2N_SUCCESS;
+}
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+int s2n_extensions_client_max_frag_len_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ return s2n_extension_send(&s2n_client_max_frag_len_extension, conn, out);
+}
+
+int s2n_recv_client_max_frag_len(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ return s2n_extension_recv(&s2n_client_max_frag_len_extension, conn, extension);
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_max_frag_len.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_max_frag_len.h
index cb822a5410..49bb3be845 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_max_frag_len.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_max_frag_len.h
@@ -1,26 +1,26 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-extern const s2n_extension_type s2n_client_max_frag_len_extension;
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-extern int s2n_extensions_client_max_frag_len_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-extern int s2n_recv_client_max_frag_len(struct s2n_connection *conn, struct s2n_stuffer *extension);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+extern const s2n_extension_type s2n_client_max_frag_len_extension;
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+extern int s2n_extensions_client_max_frag_len_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+extern int s2n_recv_client_max_frag_len(struct s2n_connection *conn, struct s2n_stuffer *extension);
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_pq_kem.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_pq_kem.c
index b553cdf6ca..450e293299 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_pq_kem.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_pq_kem.c
@@ -1,89 +1,89 @@
-/*
- * 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 <stdint.h>
-#include <sys/param.h>
-
-#include "tls/extensions/s2n_client_pq_kem.h"
-#include "tls/s2n_kem.h"
-#include "tls/s2n_security_policies.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls_parameters.h"
-
-#include "utils/s2n_safety.h"
-
-static bool s2n_client_pq_kem_should_send(struct s2n_connection *conn);
-static int s2n_client_pq_kem_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-static int s2n_client_pq_kem_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_client_pq_kem_extension = {
- .iana_value = TLS_EXTENSION_PQ_KEM_PARAMETERS,
- .is_response = false,
- .send = s2n_client_pq_kem_send,
- .recv = s2n_client_pq_kem_recv,
- .should_send = s2n_client_pq_kem_should_send,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static bool s2n_client_pq_kem_should_send(struct s2n_connection *conn)
-{
- const struct s2n_security_policy *security_policy;
- return s2n_connection_get_security_policy(conn, &security_policy) == S2N_SUCCESS
- && s2n_pq_kem_is_extension_required(security_policy);
-}
-
-static int s2n_client_pq_kem_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- const struct s2n_kem_preferences *kem_preferences = NULL;
- GUARD(s2n_connection_get_kem_preferences(conn, &kem_preferences));
- notnull_check(kem_preferences);
-
- GUARD(s2n_stuffer_write_uint16(out, kem_preferences->kem_count * sizeof(kem_extension_size)));
- for (int i = 0; i < kem_preferences->kem_count; i++) {
- GUARD(s2n_stuffer_write_uint16(out, kem_preferences->kems[i]->kem_extension_id));
- }
-
- return S2N_SUCCESS;
-}
-
-static int s2n_client_pq_kem_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- uint16_t size_of_all;
- struct s2n_blob *proposed_kems = &conn->secure.client_pq_kem_extension;
-
- GUARD(s2n_stuffer_read_uint16(extension, &size_of_all));
- if (size_of_all > s2n_stuffer_data_available(extension) || size_of_all % sizeof(kem_extension_size)) {
- /* Malformed length, ignore the extension */
- return S2N_SUCCESS;
- }
-
- proposed_kems->size = size_of_all;
- proposed_kems->data = s2n_stuffer_raw_read(extension, proposed_kems->size);
- notnull_check(proposed_kems->data);
-
- return S2N_SUCCESS;
-}
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-int s2n_extensions_client_pq_kem_send(struct s2n_connection *conn, struct s2n_stuffer *out, uint16_t pq_kem_list_size)
-{
- return s2n_extension_send(&s2n_client_pq_kem_extension, conn, out);
-}
-
-int s2n_recv_pq_kem_extension(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- return s2n_extension_recv(&s2n_client_pq_kem_extension, conn, extension);
-}
+/*
+ * 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 <stdint.h>
+#include <sys/param.h>
+
+#include "tls/extensions/s2n_client_pq_kem.h"
+#include "tls/s2n_kem.h"
+#include "tls/s2n_security_policies.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls_parameters.h"
+
+#include "utils/s2n_safety.h"
+
+static bool s2n_client_pq_kem_should_send(struct s2n_connection *conn);
+static int s2n_client_pq_kem_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+static int s2n_client_pq_kem_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_client_pq_kem_extension = {
+ .iana_value = TLS_EXTENSION_PQ_KEM_PARAMETERS,
+ .is_response = false,
+ .send = s2n_client_pq_kem_send,
+ .recv = s2n_client_pq_kem_recv,
+ .should_send = s2n_client_pq_kem_should_send,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static bool s2n_client_pq_kem_should_send(struct s2n_connection *conn)
+{
+ const struct s2n_security_policy *security_policy;
+ return s2n_connection_get_security_policy(conn, &security_policy) == S2N_SUCCESS
+ && s2n_pq_kem_is_extension_required(security_policy);
+}
+
+static int s2n_client_pq_kem_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ const struct s2n_kem_preferences *kem_preferences = NULL;
+ GUARD(s2n_connection_get_kem_preferences(conn, &kem_preferences));
+ notnull_check(kem_preferences);
+
+ GUARD(s2n_stuffer_write_uint16(out, kem_preferences->kem_count * sizeof(kem_extension_size)));
+ for (int i = 0; i < kem_preferences->kem_count; i++) {
+ GUARD(s2n_stuffer_write_uint16(out, kem_preferences->kems[i]->kem_extension_id));
+ }
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_client_pq_kem_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ uint16_t size_of_all;
+ struct s2n_blob *proposed_kems = &conn->secure.client_pq_kem_extension;
+
+ GUARD(s2n_stuffer_read_uint16(extension, &size_of_all));
+ if (size_of_all > s2n_stuffer_data_available(extension) || size_of_all % sizeof(kem_extension_size)) {
+ /* Malformed length, ignore the extension */
+ return S2N_SUCCESS;
+ }
+
+ proposed_kems->size = size_of_all;
+ proposed_kems->data = s2n_stuffer_raw_read(extension, proposed_kems->size);
+ notnull_check(proposed_kems->data);
+
+ return S2N_SUCCESS;
+}
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+int s2n_extensions_client_pq_kem_send(struct s2n_connection *conn, struct s2n_stuffer *out, uint16_t pq_kem_list_size)
+{
+ return s2n_extension_send(&s2n_client_pq_kem_extension, conn, out);
+}
+
+int s2n_recv_pq_kem_extension(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ return s2n_extension_recv(&s2n_client_pq_kem_extension, conn, extension);
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_pq_kem.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_pq_kem.h
index bc7dd6868e..91934773f3 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_pq_kem.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_pq_kem.h
@@ -1,27 +1,27 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/extensions/s2n_extension_type.h"
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-extern const s2n_extension_type s2n_client_pq_kem_extension;
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-extern int s2n_extensions_client_pq_kem_send(struct s2n_connection *conn, struct s2n_stuffer *out, uint16_t pq_kem_list_size);
-extern int s2n_recv_pq_kem_extension(struct s2n_connection *conn, struct s2n_stuffer *extension);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/extensions/s2n_extension_type.h"
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+extern const s2n_extension_type s2n_client_pq_kem_extension;
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+extern int s2n_extensions_client_pq_kem_send(struct s2n_connection *conn, struct s2n_stuffer *out, uint16_t pq_kem_list_size);
+extern int s2n_recv_pq_kem_extension(struct s2n_connection *conn, struct s2n_stuffer *extension);
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.c
index 0d8cecefab..6e058d4392 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.c
@@ -1,271 +1,271 @@
-/*
- * 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 <sys/param.h>
-#include <stdint.h>
-
-#include "crypto/s2n_hash.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls_parameters.h"
-
-#include "utils/s2n_safety.h"
-
-#define SIZE_OF_BINDER_SIZE sizeof(uint8_t)
-#define SIZE_OF_BINDER_LIST_SIZE sizeof(uint16_t)
-
-static bool s2n_client_psk_should_send(struct s2n_connection *conn);
-static int s2n_client_psk_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-static int s2n_client_psk_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_client_psk_extension = {
- .iana_value = TLS_EXTENSION_PRE_SHARED_KEY,
- .is_response = false,
- .send = s2n_client_psk_send,
- .recv = s2n_client_psk_recv,
- .should_send = s2n_client_psk_should_send,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static bool s2n_client_psk_should_send(struct s2n_connection *conn)
-{
- return conn && s2n_connection_get_protocol_version(conn) >= S2N_TLS13
- && conn->psk_params.psk_list.len;
-}
-
-static int s2n_client_psk_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- notnull_check(conn);
-
- struct s2n_psk_parameters *psk_params = &conn->psk_params;
- struct s2n_array *psk_list = &psk_params->psk_list;
-
- struct s2n_stuffer_reservation identity_list_size;
- GUARD(s2n_stuffer_reserve_uint16(out, &identity_list_size));
-
- uint16_t binder_list_size = SIZE_OF_BINDER_LIST_SIZE;
-
- for (size_t i = 0; i < psk_list->len; i++) {
- struct s2n_psk *psk = NULL;
- GUARD_AS_POSIX(s2n_array_get(psk_list, i, (void**) &psk));
- notnull_check(psk);
-
- /* Write the identity */
- GUARD(s2n_stuffer_write_uint16(out, psk->identity.size));
- GUARD(s2n_stuffer_write(out, &psk->identity));
- GUARD(s2n_stuffer_write_uint32(out, 0));
-
- /* Calculate binder size */
- uint8_t hash_size = 0;
- GUARD(s2n_hash_digest_size(psk->hash_alg, &hash_size));
- binder_list_size += hash_size + SIZE_OF_BINDER_SIZE;
- }
-
- GUARD(s2n_stuffer_write_vector_size(&identity_list_size));
-
- /* Calculating the binders requires a complete ClientHello, and at this point
- * the extension size, extension list size, and message size are all blank.
- *
- * We'll write placeholder data to ensure the extension and extension list sizes
- * are calculated correctly, then rewrite the binders with real data later. */
- psk_params->binder_list_size = binder_list_size;
- GUARD(s2n_stuffer_skip_write(out, binder_list_size));
-
- return S2N_SUCCESS;
-}
-
-/* Match a PSK identity received from the client against the server's known PSK identities.
- *
- * While both the client's offered identities and whether a match was found are public, we should make an attempt
- * to keep the server's known identities a secret. We will make comparisons to the server's identities constant
- * time (to hide partial matches) and not end the search early when a match is found (to hide the ordering).
- *
- * Keeping these comparisons constant time is not high priority. There's no known attack using these timings,
- * and an attacker could probably guess the server's known identities just by observing the public identities
- * sent by clients.
- */
-static S2N_RESULT s2n_match_psk_identity(struct s2n_array *known_psks, const struct s2n_blob *wire_identity,
- struct s2n_psk **match)
-{
- ENSURE_REF(match);
- ENSURE_REF(wire_identity);
- ENSURE_REF(known_psks);
-
- *match = NULL;
-
- for (size_t i = 0; i < known_psks->len; i++) {
- struct s2n_psk *psk = NULL;
- GUARD_RESULT(s2n_array_get(known_psks, i, (void**)&psk));
- ENSURE_REF(psk);
-
- ENSURE_REF(psk->identity.data);
- ENSURE_REF(wire_identity->data);
-
- uint32_t compare_size = MIN(wire_identity->size, psk->identity.size);
- if (s2n_constant_time_equals(psk->identity.data, wire_identity->data, compare_size)
- & (psk->identity.size == wire_identity->size) & (!*match)) {
- *match = psk;
- }
- }
- return S2N_RESULT_OK;
-}
-
-static S2N_RESULT s2n_client_psk_recv_identity_list(struct s2n_connection *conn, struct s2n_stuffer *wire_identities_in)
-{
- ENSURE_REF(conn);
- ENSURE_REF(wire_identities_in);
-
- uint8_t wire_index = 0;
- while (s2n_stuffer_data_available(wire_identities_in) > 0) {
- uint16_t identity_size = 0;
- GUARD_AS_RESULT(s2n_stuffer_read_uint16(wire_identities_in, &identity_size));
-
- uint8_t *identity_data;
- ENSURE_REF(identity_data = s2n_stuffer_raw_read(wire_identities_in, identity_size));
-
- struct s2n_blob identity = { 0 };
- GUARD_AS_RESULT(s2n_blob_init(&identity, identity_data, identity_size));
-
- /* TODO: Validate obfuscated_ticket_age when using session tickets:
- * https://github.com/awslabs/s2n/issues/2417
- *
- * "For identities established externally, an obfuscated_ticket_age of 0 SHOULD be
- * used, and servers MUST ignore the value."
- */
- uint32_t obfuscated_ticket_age = 0;
- GUARD_AS_RESULT(s2n_stuffer_read_uint32(wire_identities_in, &obfuscated_ticket_age));
-
- /* TODO: Implement the callback to choose a PSK: https://github.com/awslabs/s2n/issues/2397
- *
- * When we don't have a callback configured to choose a PSK, we should fall back to accepting
- * the first PSK identity that also exists in our list of supported PSKs. */
- GUARD_RESULT(s2n_match_psk_identity(&conn->psk_params.psk_list, &identity, &conn->psk_params.chosen_psk));
-
- if (conn->psk_params.chosen_psk) {
- conn->psk_params.chosen_psk_wire_index = wire_index;
- return S2N_RESULT_OK;
- }
-
- wire_index++;
- }
- return S2N_RESULT_OK;
-}
-
-static S2N_RESULT s2n_client_psk_recv_binder_list(struct s2n_connection *conn, struct s2n_blob *partial_client_hello,
- struct s2n_stuffer *wire_binders_in)
-{
- ENSURE_REF(conn);
- ENSURE_REF(wire_binders_in);
-
- uint8_t wire_index = 0;
- while (s2n_stuffer_data_available(wire_binders_in) > 0) {
- uint8_t wire_binder_size = 0;
- GUARD_AS_RESULT(s2n_stuffer_read_uint8(wire_binders_in, &wire_binder_size));
-
- uint8_t *wire_binder_data;
- ENSURE_REF(wire_binder_data = s2n_stuffer_raw_read(wire_binders_in, wire_binder_size));
-
- struct s2n_blob wire_binder = { 0 };
- GUARD_AS_RESULT(s2n_blob_init(&wire_binder, wire_binder_data, wire_binder_size));
-
- if (wire_index == conn->psk_params.chosen_psk_wire_index) {
- GUARD_AS_RESULT(s2n_psk_verify_binder(conn, conn->psk_params.chosen_psk,
- partial_client_hello, &wire_binder));
- return S2N_RESULT_OK;
- }
- wire_index++;
- }
- BAIL(S2N_ERR_BAD_MESSAGE);
-}
-
-static S2N_RESULT s2n_client_psk_recv_identities(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- ENSURE_REF(conn);
-
- uint16_t identity_list_size = 0;
- GUARD_AS_RESULT(s2n_stuffer_read_uint16(extension, &identity_list_size));
-
- uint8_t *identity_list_data;
- ENSURE_REF(identity_list_data = s2n_stuffer_raw_read(extension, identity_list_size));
-
- struct s2n_blob identity_list_blob = { 0 };
- GUARD_AS_RESULT(s2n_blob_init(&identity_list_blob, identity_list_data, identity_list_size));
-
- struct s2n_stuffer identity_list = { 0 };
- GUARD_AS_RESULT(s2n_stuffer_init(&identity_list, &identity_list_blob));
- GUARD_AS_RESULT(s2n_stuffer_skip_write(&identity_list, identity_list_blob.size));
-
- return s2n_client_psk_recv_identity_list(conn, &identity_list);
-}
-
-static S2N_RESULT s2n_client_psk_recv_binders(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- ENSURE_REF(conn);
-
- uint16_t binder_list_size = 0;
- GUARD_AS_RESULT(s2n_stuffer_read_uint16(extension, &binder_list_size));
-
- uint8_t *binder_list_data;
- ENSURE_REF(binder_list_data = s2n_stuffer_raw_read(extension, binder_list_size));
-
- struct s2n_blob binder_list_blob = { 0 };
- GUARD_AS_RESULT(s2n_blob_init(&binder_list_blob, binder_list_data, binder_list_size));
-
- struct s2n_stuffer binder_list = { 0 };
- GUARD_AS_RESULT(s2n_stuffer_init(&binder_list, &binder_list_blob));
- GUARD_AS_RESULT(s2n_stuffer_skip_write(&binder_list, binder_list_blob.size));
-
- /* Record the ClientHello message up to but not including the binder list.
- * This is required to calculate the binder for the chosen PSK. */
- struct s2n_blob partial_client_hello = { 0 };
- const struct s2n_stuffer *client_hello = &conn->handshake.io;
- uint32_t binders_size = binder_list_blob.size + SIZE_OF_BINDER_LIST_SIZE;
- ENSURE_GTE(client_hello->write_cursor, binders_size);
- uint16_t partial_client_hello_size = client_hello->write_cursor - binders_size;
- GUARD_AS_RESULT(s2n_blob_slice(&client_hello->blob, &partial_client_hello, 0, partial_client_hello_size));
-
- return s2n_client_psk_recv_binder_list(conn, &partial_client_hello, &binder_list);
-}
-
-int s2n_client_psk_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- notnull_check(conn);
-
- if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
- return S2N_SUCCESS;
- }
-
- if (s2n_result_is_error(s2n_client_psk_recv_identities(conn, extension))) {
- /* https://tools.ietf.org/html/rfc8446#section-4.2.11:
- * "If no acceptable PSKs are found, the server SHOULD perform a non-PSK
- * handshake if possible."
- */
- conn->psk_params.chosen_psk = NULL;
- }
-
- if (conn->psk_params.chosen_psk) {
- /* https://tools.ietf.org/html/rfc8446#section-4.2.11:
- * "Prior to accepting PSK key establishment, the server MUST validate
- * the corresponding binder value. If this value is not present or does
- * not validate, the server MUST abort the handshake."
- */
- GUARD_AS_POSIX(s2n_client_psk_recv_binders(conn, extension));
- }
-
- /* At this point, we have either chosen a PSK or fallen back to a full handshake.
- * Wipe any PSKs not chosen. */
- GUARD_AS_POSIX(s2n_psk_parameters_free_unused_psks(&conn->psk_params));
-
- return S2N_SUCCESS;
-}
+/*
+ * 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 <sys/param.h>
+#include <stdint.h>
+
+#include "crypto/s2n_hash.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls_parameters.h"
+
+#include "utils/s2n_safety.h"
+
+#define SIZE_OF_BINDER_SIZE sizeof(uint8_t)
+#define SIZE_OF_BINDER_LIST_SIZE sizeof(uint16_t)
+
+static bool s2n_client_psk_should_send(struct s2n_connection *conn);
+static int s2n_client_psk_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+static int s2n_client_psk_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_client_psk_extension = {
+ .iana_value = TLS_EXTENSION_PRE_SHARED_KEY,
+ .is_response = false,
+ .send = s2n_client_psk_send,
+ .recv = s2n_client_psk_recv,
+ .should_send = s2n_client_psk_should_send,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static bool s2n_client_psk_should_send(struct s2n_connection *conn)
+{
+ return conn && s2n_connection_get_protocol_version(conn) >= S2N_TLS13
+ && conn->psk_params.psk_list.len;
+}
+
+static int s2n_client_psk_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ notnull_check(conn);
+
+ struct s2n_psk_parameters *psk_params = &conn->psk_params;
+ struct s2n_array *psk_list = &psk_params->psk_list;
+
+ struct s2n_stuffer_reservation identity_list_size;
+ GUARD(s2n_stuffer_reserve_uint16(out, &identity_list_size));
+
+ uint16_t binder_list_size = SIZE_OF_BINDER_LIST_SIZE;
+
+ for (size_t i = 0; i < psk_list->len; i++) {
+ struct s2n_psk *psk = NULL;
+ GUARD_AS_POSIX(s2n_array_get(psk_list, i, (void**) &psk));
+ notnull_check(psk);
+
+ /* Write the identity */
+ GUARD(s2n_stuffer_write_uint16(out, psk->identity.size));
+ GUARD(s2n_stuffer_write(out, &psk->identity));
+ GUARD(s2n_stuffer_write_uint32(out, 0));
+
+ /* Calculate binder size */
+ uint8_t hash_size = 0;
+ GUARD(s2n_hash_digest_size(psk->hash_alg, &hash_size));
+ binder_list_size += hash_size + SIZE_OF_BINDER_SIZE;
+ }
+
+ GUARD(s2n_stuffer_write_vector_size(&identity_list_size));
+
+ /* Calculating the binders requires a complete ClientHello, and at this point
+ * the extension size, extension list size, and message size are all blank.
+ *
+ * We'll write placeholder data to ensure the extension and extension list sizes
+ * are calculated correctly, then rewrite the binders with real data later. */
+ psk_params->binder_list_size = binder_list_size;
+ GUARD(s2n_stuffer_skip_write(out, binder_list_size));
+
+ return S2N_SUCCESS;
+}
+
+/* Match a PSK identity received from the client against the server's known PSK identities.
+ *
+ * While both the client's offered identities and whether a match was found are public, we should make an attempt
+ * to keep the server's known identities a secret. We will make comparisons to the server's identities constant
+ * time (to hide partial matches) and not end the search early when a match is found (to hide the ordering).
+ *
+ * Keeping these comparisons constant time is not high priority. There's no known attack using these timings,
+ * and an attacker could probably guess the server's known identities just by observing the public identities
+ * sent by clients.
+ */
+static S2N_RESULT s2n_match_psk_identity(struct s2n_array *known_psks, const struct s2n_blob *wire_identity,
+ struct s2n_psk **match)
+{
+ ENSURE_REF(match);
+ ENSURE_REF(wire_identity);
+ ENSURE_REF(known_psks);
+
+ *match = NULL;
+
+ for (size_t i = 0; i < known_psks->len; i++) {
+ struct s2n_psk *psk = NULL;
+ GUARD_RESULT(s2n_array_get(known_psks, i, (void**)&psk));
+ ENSURE_REF(psk);
+
+ ENSURE_REF(psk->identity.data);
+ ENSURE_REF(wire_identity->data);
+
+ uint32_t compare_size = MIN(wire_identity->size, psk->identity.size);
+ if (s2n_constant_time_equals(psk->identity.data, wire_identity->data, compare_size)
+ & (psk->identity.size == wire_identity->size) & (!*match)) {
+ *match = psk;
+ }
+ }
+ return S2N_RESULT_OK;
+}
+
+static S2N_RESULT s2n_client_psk_recv_identity_list(struct s2n_connection *conn, struct s2n_stuffer *wire_identities_in)
+{
+ ENSURE_REF(conn);
+ ENSURE_REF(wire_identities_in);
+
+ uint8_t wire_index = 0;
+ while (s2n_stuffer_data_available(wire_identities_in) > 0) {
+ uint16_t identity_size = 0;
+ GUARD_AS_RESULT(s2n_stuffer_read_uint16(wire_identities_in, &identity_size));
+
+ uint8_t *identity_data;
+ ENSURE_REF(identity_data = s2n_stuffer_raw_read(wire_identities_in, identity_size));
+
+ struct s2n_blob identity = { 0 };
+ GUARD_AS_RESULT(s2n_blob_init(&identity, identity_data, identity_size));
+
+ /* TODO: Validate obfuscated_ticket_age when using session tickets:
+ * https://github.com/awslabs/s2n/issues/2417
+ *
+ * "For identities established externally, an obfuscated_ticket_age of 0 SHOULD be
+ * used, and servers MUST ignore the value."
+ */
+ uint32_t obfuscated_ticket_age = 0;
+ GUARD_AS_RESULT(s2n_stuffer_read_uint32(wire_identities_in, &obfuscated_ticket_age));
+
+ /* TODO: Implement the callback to choose a PSK: https://github.com/awslabs/s2n/issues/2397
+ *
+ * When we don't have a callback configured to choose a PSK, we should fall back to accepting
+ * the first PSK identity that also exists in our list of supported PSKs. */
+ GUARD_RESULT(s2n_match_psk_identity(&conn->psk_params.psk_list, &identity, &conn->psk_params.chosen_psk));
+
+ if (conn->psk_params.chosen_psk) {
+ conn->psk_params.chosen_psk_wire_index = wire_index;
+ return S2N_RESULT_OK;
+ }
+
+ wire_index++;
+ }
+ return S2N_RESULT_OK;
+}
+
+static S2N_RESULT s2n_client_psk_recv_binder_list(struct s2n_connection *conn, struct s2n_blob *partial_client_hello,
+ struct s2n_stuffer *wire_binders_in)
+{
+ ENSURE_REF(conn);
+ ENSURE_REF(wire_binders_in);
+
+ uint8_t wire_index = 0;
+ while (s2n_stuffer_data_available(wire_binders_in) > 0) {
+ uint8_t wire_binder_size = 0;
+ GUARD_AS_RESULT(s2n_stuffer_read_uint8(wire_binders_in, &wire_binder_size));
+
+ uint8_t *wire_binder_data;
+ ENSURE_REF(wire_binder_data = s2n_stuffer_raw_read(wire_binders_in, wire_binder_size));
+
+ struct s2n_blob wire_binder = { 0 };
+ GUARD_AS_RESULT(s2n_blob_init(&wire_binder, wire_binder_data, wire_binder_size));
+
+ if (wire_index == conn->psk_params.chosen_psk_wire_index) {
+ GUARD_AS_RESULT(s2n_psk_verify_binder(conn, conn->psk_params.chosen_psk,
+ partial_client_hello, &wire_binder));
+ return S2N_RESULT_OK;
+ }
+ wire_index++;
+ }
+ BAIL(S2N_ERR_BAD_MESSAGE);
+}
+
+static S2N_RESULT s2n_client_psk_recv_identities(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ ENSURE_REF(conn);
+
+ uint16_t identity_list_size = 0;
+ GUARD_AS_RESULT(s2n_stuffer_read_uint16(extension, &identity_list_size));
+
+ uint8_t *identity_list_data;
+ ENSURE_REF(identity_list_data = s2n_stuffer_raw_read(extension, identity_list_size));
+
+ struct s2n_blob identity_list_blob = { 0 };
+ GUARD_AS_RESULT(s2n_blob_init(&identity_list_blob, identity_list_data, identity_list_size));
+
+ struct s2n_stuffer identity_list = { 0 };
+ GUARD_AS_RESULT(s2n_stuffer_init(&identity_list, &identity_list_blob));
+ GUARD_AS_RESULT(s2n_stuffer_skip_write(&identity_list, identity_list_blob.size));
+
+ return s2n_client_psk_recv_identity_list(conn, &identity_list);
+}
+
+static S2N_RESULT s2n_client_psk_recv_binders(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ ENSURE_REF(conn);
+
+ uint16_t binder_list_size = 0;
+ GUARD_AS_RESULT(s2n_stuffer_read_uint16(extension, &binder_list_size));
+
+ uint8_t *binder_list_data;
+ ENSURE_REF(binder_list_data = s2n_stuffer_raw_read(extension, binder_list_size));
+
+ struct s2n_blob binder_list_blob = { 0 };
+ GUARD_AS_RESULT(s2n_blob_init(&binder_list_blob, binder_list_data, binder_list_size));
+
+ struct s2n_stuffer binder_list = { 0 };
+ GUARD_AS_RESULT(s2n_stuffer_init(&binder_list, &binder_list_blob));
+ GUARD_AS_RESULT(s2n_stuffer_skip_write(&binder_list, binder_list_blob.size));
+
+ /* Record the ClientHello message up to but not including the binder list.
+ * This is required to calculate the binder for the chosen PSK. */
+ struct s2n_blob partial_client_hello = { 0 };
+ const struct s2n_stuffer *client_hello = &conn->handshake.io;
+ uint32_t binders_size = binder_list_blob.size + SIZE_OF_BINDER_LIST_SIZE;
+ ENSURE_GTE(client_hello->write_cursor, binders_size);
+ uint16_t partial_client_hello_size = client_hello->write_cursor - binders_size;
+ GUARD_AS_RESULT(s2n_blob_slice(&client_hello->blob, &partial_client_hello, 0, partial_client_hello_size));
+
+ return s2n_client_psk_recv_binder_list(conn, &partial_client_hello, &binder_list);
+}
+
+int s2n_client_psk_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ notnull_check(conn);
+
+ if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
+ return S2N_SUCCESS;
+ }
+
+ if (s2n_result_is_error(s2n_client_psk_recv_identities(conn, extension))) {
+ /* https://tools.ietf.org/html/rfc8446#section-4.2.11:
+ * "If no acceptable PSKs are found, the server SHOULD perform a non-PSK
+ * handshake if possible."
+ */
+ conn->psk_params.chosen_psk = NULL;
+ }
+
+ if (conn->psk_params.chosen_psk) {
+ /* https://tools.ietf.org/html/rfc8446#section-4.2.11:
+ * "Prior to accepting PSK key establishment, the server MUST validate
+ * the corresponding binder value. If this value is not present or does
+ * not validate, the server MUST abort the handshake."
+ */
+ GUARD_AS_POSIX(s2n_client_psk_recv_binders(conn, extension));
+ }
+
+ /* At this point, we have either chosen a PSK or fallen back to a full handshake.
+ * Wipe any PSKs not chosen. */
+ GUARD_AS_POSIX(s2n_psk_parameters_free_unused_psks(&conn->psk_params));
+
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.h
index 0e12137676..a317ace2bc 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.h
@@ -1,22 +1,22 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/extensions/s2n_extension_type.h"
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-extern const s2n_extension_type s2n_client_psk_extension;
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/extensions/s2n_extension_type.h"
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+extern const s2n_extension_type s2n_client_psk_extension;
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.c
index 502b84b624..3a012f47d1 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.c
@@ -1,51 +1,51 @@
-/*
- * 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 <sys/param.h>
-#include <stdint.h>
-
-#include "tls/extensions/s2n_client_renegotiation_info.h"
-#include "tls/s2n_tls.h"
-
-#include "utils/s2n_safety.h"
-
-static int s2n_client_renegotiation_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_client_renegotiation_info_extension = {
- .iana_value = TLS_EXTENSION_RENEGOTIATION_INFO,
- .is_response = false,
- .send = s2n_extension_send_unimplemented,
- .recv = s2n_client_renegotiation_recv,
- .should_send = s2n_extension_never_send,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static int s2n_client_renegotiation_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- /* RFC5746 Section 3.2: The renegotiated_connection field is of zero length for the initial handshake. */
- uint8_t renegotiated_connection_len;
- GUARD(s2n_stuffer_read_uint8(extension, &renegotiated_connection_len));
- S2N_ERROR_IF(s2n_stuffer_data_available(extension) || renegotiated_connection_len, S2N_ERR_NON_EMPTY_RENEGOTIATION_INFO);
-
- conn->secure_renegotiation = 1;
- return S2N_SUCCESS;
-}
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-int s2n_recv_client_renegotiation_info(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- return s2n_extension_recv(&s2n_client_renegotiation_info_extension, conn, extension);
-}
+/*
+ * 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 <sys/param.h>
+#include <stdint.h>
+
+#include "tls/extensions/s2n_client_renegotiation_info.h"
+#include "tls/s2n_tls.h"
+
+#include "utils/s2n_safety.h"
+
+static int s2n_client_renegotiation_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_client_renegotiation_info_extension = {
+ .iana_value = TLS_EXTENSION_RENEGOTIATION_INFO,
+ .is_response = false,
+ .send = s2n_extension_send_unimplemented,
+ .recv = s2n_client_renegotiation_recv,
+ .should_send = s2n_extension_never_send,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static int s2n_client_renegotiation_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ /* RFC5746 Section 3.2: The renegotiated_connection field is of zero length for the initial handshake. */
+ uint8_t renegotiated_connection_len;
+ GUARD(s2n_stuffer_read_uint8(extension, &renegotiated_connection_len));
+ S2N_ERROR_IF(s2n_stuffer_data_available(extension) || renegotiated_connection_len, S2N_ERR_NON_EMPTY_RENEGOTIATION_INFO);
+
+ conn->secure_renegotiation = 1;
+ return S2N_SUCCESS;
+}
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+int s2n_recv_client_renegotiation_info(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ return s2n_extension_recv(&s2n_client_renegotiation_info_extension, conn, extension);
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.h
index d1e37e9677..dbc98ddf80 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.h
@@ -1,25 +1,25 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-extern const s2n_extension_type s2n_client_renegotiation_info_extension;
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-int s2n_recv_client_renegotiation_info(struct s2n_connection *conn, struct s2n_stuffer *extension);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+extern const s2n_extension_type s2n_client_renegotiation_info_extension;
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+int s2n_recv_client_renegotiation_info(struct s2n_connection *conn, struct s2n_stuffer *extension);
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_sct_list.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_sct_list.c
index ecf86b2647..d3f699c8c3 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_sct_list.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_sct_list.c
@@ -1,59 +1,59 @@
-/*
- * 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 <sys/param.h>
-#include <stdint.h>
-
-#include "tls/extensions/s2n_client_sct_list.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls_parameters.h"
-
-#include "utils/s2n_safety.h"
-
-static bool s2n_client_sct_list_should_send(struct s2n_connection *conn);
-static int s2n_client_sct_list_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_client_sct_list_extension = {
- .iana_value = TLS_EXTENSION_SCT_LIST,
- .is_response = false,
- .send = s2n_extension_send_noop,
- .recv = s2n_client_sct_list_recv,
- .should_send = s2n_client_sct_list_should_send,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static bool s2n_client_sct_list_should_send(struct s2n_connection *conn)
-{
- return conn->config->ct_type != S2N_CT_SUPPORT_NONE;
-}
-
-static int s2n_client_sct_list_recv(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- conn->ct_level_requested = S2N_CT_SUPPORT_REQUEST;
- /* Skip reading the extension, per RFC6962 (3.1.1) it SHOULD be empty anyway */
- return S2N_SUCCESS;
-}
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-int s2n_extensions_client_sct_list_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- return s2n_extension_send(&s2n_client_sct_list_extension, conn, out);
-}
-
-int s2n_recv_client_sct_list(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- return s2n_extension_recv(&s2n_client_sct_list_extension, conn, extension);
-}
+/*
+ * 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 <sys/param.h>
+#include <stdint.h>
+
+#include "tls/extensions/s2n_client_sct_list.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls_parameters.h"
+
+#include "utils/s2n_safety.h"
+
+static bool s2n_client_sct_list_should_send(struct s2n_connection *conn);
+static int s2n_client_sct_list_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_client_sct_list_extension = {
+ .iana_value = TLS_EXTENSION_SCT_LIST,
+ .is_response = false,
+ .send = s2n_extension_send_noop,
+ .recv = s2n_client_sct_list_recv,
+ .should_send = s2n_client_sct_list_should_send,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static bool s2n_client_sct_list_should_send(struct s2n_connection *conn)
+{
+ return conn->config->ct_type != S2N_CT_SUPPORT_NONE;
+}
+
+static int s2n_client_sct_list_recv(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ conn->ct_level_requested = S2N_CT_SUPPORT_REQUEST;
+ /* Skip reading the extension, per RFC6962 (3.1.1) it SHOULD be empty anyway */
+ return S2N_SUCCESS;
+}
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+int s2n_extensions_client_sct_list_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ return s2n_extension_send(&s2n_client_sct_list_extension, conn, out);
+}
+
+int s2n_recv_client_sct_list(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ return s2n_extension_recv(&s2n_client_sct_list_extension, conn, extension);
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_sct_list.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_sct_list.h
index 9d7a75e7cb..2f03d9baff 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_sct_list.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_sct_list.h
@@ -1,26 +1,26 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-extern const s2n_extension_type s2n_client_sct_list_extension;
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-extern int s2n_extensions_client_sct_list_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-extern int s2n_recv_client_sct_list(struct s2n_connection *conn, struct s2n_stuffer *extension);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+extern const s2n_extension_type s2n_client_sct_list_extension;
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+extern int s2n_extensions_client_sct_list_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+extern int s2n_recv_client_sct_list(struct s2n_connection *conn, struct s2n_stuffer *extension);
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_server_name.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_server_name.c
index c9eaca23a9..904976e4cc 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_server_name.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_server_name.c
@@ -1,110 +1,110 @@
-/*
- * 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 <sys/param.h>
-#include <stdint.h>
-
-#include "tls/extensions/s2n_client_server_name.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls_parameters.h"
-
-#include "utils/s2n_safety.h"
-
-#define S2N_NAME_TYPE_HOST_NAME 0
-
-static bool s2n_client_server_name_should_send(struct s2n_connection *conn);
-static int s2n_client_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-static int s2n_client_server_name_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_client_server_name_extension = {
- .iana_value = TLS_EXTENSION_SERVER_NAME,
- .is_response = false,
- .send = s2n_client_server_name_send,
- .recv = s2n_client_server_name_recv,
- .should_send = s2n_client_server_name_should_send,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static bool s2n_client_server_name_should_send(struct s2n_connection *conn)
-{
- return conn && strlen(conn->server_name) > 0;
-}
-
-static int s2n_client_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- struct s2n_stuffer_reservation server_name_list_size = {0};
- GUARD(s2n_stuffer_reserve_uint16(out, &server_name_list_size));
-
- /* NameType, as described by RFC6066.
- * host_name is currently the only possible NameType defined. */
- GUARD(s2n_stuffer_write_uint8(out, S2N_NAME_TYPE_HOST_NAME));
-
- GUARD(s2n_stuffer_write_uint16(out, strlen(conn->server_name)));
- GUARD(s2n_stuffer_write_bytes(out, (const uint8_t *) conn->server_name, strlen(conn->server_name)));
-
- GUARD(s2n_stuffer_write_vector_size(&server_name_list_size));
- return S2N_SUCCESS;
-}
-
-static int s2n_client_server_name_check(struct s2n_connection *conn, struct s2n_stuffer *extension, uint16_t *server_name_len)
-{
- notnull_check(conn);
-
- uint16_t size_of_all;
- GUARD(s2n_stuffer_read_uint16(extension, &size_of_all));
- lte_check(size_of_all, s2n_stuffer_data_available(extension));
-
- uint8_t server_name_type;
- GUARD(s2n_stuffer_read_uint8(extension, &server_name_type));
- eq_check(server_name_type, S2N_NAME_TYPE_HOST_NAME);
-
- GUARD(s2n_stuffer_read_uint16(extension, server_name_len));
- lt_check(*server_name_len, sizeof(conn->server_name));
- lte_check(*server_name_len, s2n_stuffer_data_available(extension));
-
- return S2N_SUCCESS;
-}
-
-static int s2n_client_server_name_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- notnull_check(conn);
-
- /* Exit early if we've already parsed the server name */
- if (conn->server_name[0]) {
- return S2N_SUCCESS;
- }
-
- /* Ignore if malformed. We just won't use the server name. */
- uint16_t server_name_len;
- if (s2n_client_server_name_check(conn, extension, &server_name_len) != S2N_SUCCESS) {
- return S2N_SUCCESS;
- }
-
- uint8_t *server_name;
- notnull_check(server_name = s2n_stuffer_raw_read(extension, server_name_len));
- memcpy_check(conn->server_name, server_name, server_name_len);
-
- return S2N_SUCCESS;
-}
-
-int s2n_extensions_client_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- return s2n_extension_send(&s2n_client_server_name_extension, conn, out);
-}
-
-int s2n_parse_client_hello_server_name(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- return s2n_extension_recv(&s2n_client_server_name_extension, conn, extension);
-}
+/*
+ * 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 <sys/param.h>
+#include <stdint.h>
+
+#include "tls/extensions/s2n_client_server_name.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls_parameters.h"
+
+#include "utils/s2n_safety.h"
+
+#define S2N_NAME_TYPE_HOST_NAME 0
+
+static bool s2n_client_server_name_should_send(struct s2n_connection *conn);
+static int s2n_client_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+static int s2n_client_server_name_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_client_server_name_extension = {
+ .iana_value = TLS_EXTENSION_SERVER_NAME,
+ .is_response = false,
+ .send = s2n_client_server_name_send,
+ .recv = s2n_client_server_name_recv,
+ .should_send = s2n_client_server_name_should_send,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static bool s2n_client_server_name_should_send(struct s2n_connection *conn)
+{
+ return conn && strlen(conn->server_name) > 0;
+}
+
+static int s2n_client_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ struct s2n_stuffer_reservation server_name_list_size = {0};
+ GUARD(s2n_stuffer_reserve_uint16(out, &server_name_list_size));
+
+ /* NameType, as described by RFC6066.
+ * host_name is currently the only possible NameType defined. */
+ GUARD(s2n_stuffer_write_uint8(out, S2N_NAME_TYPE_HOST_NAME));
+
+ GUARD(s2n_stuffer_write_uint16(out, strlen(conn->server_name)));
+ GUARD(s2n_stuffer_write_bytes(out, (const uint8_t *) conn->server_name, strlen(conn->server_name)));
+
+ GUARD(s2n_stuffer_write_vector_size(&server_name_list_size));
+ return S2N_SUCCESS;
+}
+
+static int s2n_client_server_name_check(struct s2n_connection *conn, struct s2n_stuffer *extension, uint16_t *server_name_len)
+{
+ notnull_check(conn);
+
+ uint16_t size_of_all;
+ GUARD(s2n_stuffer_read_uint16(extension, &size_of_all));
+ lte_check(size_of_all, s2n_stuffer_data_available(extension));
+
+ uint8_t server_name_type;
+ GUARD(s2n_stuffer_read_uint8(extension, &server_name_type));
+ eq_check(server_name_type, S2N_NAME_TYPE_HOST_NAME);
+
+ GUARD(s2n_stuffer_read_uint16(extension, server_name_len));
+ lt_check(*server_name_len, sizeof(conn->server_name));
+ lte_check(*server_name_len, s2n_stuffer_data_available(extension));
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_client_server_name_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ notnull_check(conn);
+
+ /* Exit early if we've already parsed the server name */
+ if (conn->server_name[0]) {
+ return S2N_SUCCESS;
+ }
+
+ /* Ignore if malformed. We just won't use the server name. */
+ uint16_t server_name_len;
+ if (s2n_client_server_name_check(conn, extension, &server_name_len) != S2N_SUCCESS) {
+ return S2N_SUCCESS;
+ }
+
+ uint8_t *server_name;
+ notnull_check(server_name = s2n_stuffer_raw_read(extension, server_name_len));
+ memcpy_check(conn->server_name, server_name, server_name_len);
+
+ return S2N_SUCCESS;
+}
+
+int s2n_extensions_client_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ return s2n_extension_send(&s2n_client_server_name_extension, conn, out);
+}
+
+int s2n_parse_client_hello_server_name(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ return s2n_extension_recv(&s2n_client_server_name_extension, conn, extension);
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_server_name.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_server_name.h
index a6c2f2250a..a6dde369dc 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_server_name.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_server_name.h
@@ -1,26 +1,26 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/extensions/s2n_extension_type.h"
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-extern const s2n_extension_type s2n_client_server_name_extension;
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-extern int s2n_extensions_client_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-extern int s2n_parse_client_hello_server_name(struct s2n_connection *conn, struct s2n_stuffer *extension);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/extensions/s2n_extension_type.h"
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+extern const s2n_extension_type s2n_client_server_name_extension;
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+extern int s2n_extensions_client_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+extern int s2n_parse_client_hello_server_name(struct s2n_connection *conn, struct s2n_stuffer *extension);
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_session_ticket.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_session_ticket.c
index 3628f7be9a..96ef1b7308 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_session_ticket.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_session_ticket.c
@@ -1,82 +1,82 @@
-/*
- * 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 <sys/param.h>
-#include <stdint.h>
-
-#include "tls/extensions/s2n_client_session_ticket.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls_parameters.h"
-#include "tls/s2n_resume.h"
-
-#include "utils/s2n_safety.h"
-
-static bool s2n_client_session_ticket_should_send(struct s2n_connection *conn);
-static int s2n_client_session_ticket_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-static int s2n_client_session_ticket_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_client_session_ticket_extension = {
- .iana_value = TLS_EXTENSION_SESSION_TICKET,
- .is_response = false,
- .send = s2n_client_session_ticket_send,
- .recv = s2n_client_session_ticket_recv,
- .should_send = s2n_client_session_ticket_should_send,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static bool s2n_client_session_ticket_should_send(struct s2n_connection *conn)
-{
- return conn->config->use_tickets;
-}
-
-static int s2n_client_session_ticket_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- GUARD(s2n_stuffer_write(out, &conn->client_ticket));
- return S2N_SUCCESS;
-}
-
-static int s2n_client_session_ticket_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- if (conn->config->use_tickets != 1) {
- /* Ignore the extension. */
- return S2N_SUCCESS;
- }
-
- /* s2n server does not support session ticket with CLIENT_AUTH enabled */
- if (s2n_connection_is_client_auth_enabled(conn) > 0) {
- return S2N_SUCCESS;
- }
-
- if (s2n_stuffer_data_available(extension) == S2N_TICKET_SIZE_IN_BYTES) {
- conn->session_ticket_status = S2N_DECRYPT_TICKET;
- GUARD(s2n_stuffer_copy(extension, &conn->client_ticket_to_decrypt, S2N_TICKET_SIZE_IN_BYTES));
- } else if (s2n_config_is_encrypt_decrypt_key_available(conn->config) == 1) {
- conn->session_ticket_status = S2N_NEW_TICKET;
- }
-
- return S2N_SUCCESS;
-}
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-int s2n_extensions_client_session_ticket_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- return s2n_extension_send(&s2n_client_session_ticket_extension, conn, out);
-}
-
-int s2n_recv_client_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- return s2n_extension_recv(&s2n_client_session_ticket_extension, conn, extension);
-}
+/*
+ * 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 <sys/param.h>
+#include <stdint.h>
+
+#include "tls/extensions/s2n_client_session_ticket.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls_parameters.h"
+#include "tls/s2n_resume.h"
+
+#include "utils/s2n_safety.h"
+
+static bool s2n_client_session_ticket_should_send(struct s2n_connection *conn);
+static int s2n_client_session_ticket_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+static int s2n_client_session_ticket_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_client_session_ticket_extension = {
+ .iana_value = TLS_EXTENSION_SESSION_TICKET,
+ .is_response = false,
+ .send = s2n_client_session_ticket_send,
+ .recv = s2n_client_session_ticket_recv,
+ .should_send = s2n_client_session_ticket_should_send,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static bool s2n_client_session_ticket_should_send(struct s2n_connection *conn)
+{
+ return conn->config->use_tickets;
+}
+
+static int s2n_client_session_ticket_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ GUARD(s2n_stuffer_write(out, &conn->client_ticket));
+ return S2N_SUCCESS;
+}
+
+static int s2n_client_session_ticket_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ if (conn->config->use_tickets != 1) {
+ /* Ignore the extension. */
+ return S2N_SUCCESS;
+ }
+
+ /* s2n server does not support session ticket with CLIENT_AUTH enabled */
+ if (s2n_connection_is_client_auth_enabled(conn) > 0) {
+ return S2N_SUCCESS;
+ }
+
+ if (s2n_stuffer_data_available(extension) == S2N_TICKET_SIZE_IN_BYTES) {
+ conn->session_ticket_status = S2N_DECRYPT_TICKET;
+ GUARD(s2n_stuffer_copy(extension, &conn->client_ticket_to_decrypt, S2N_TICKET_SIZE_IN_BYTES));
+ } else if (s2n_config_is_encrypt_decrypt_key_available(conn->config) == 1) {
+ conn->session_ticket_status = S2N_NEW_TICKET;
+ }
+
+ return S2N_SUCCESS;
+}
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+int s2n_extensions_client_session_ticket_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ return s2n_extension_send(&s2n_client_session_ticket_extension, conn, out);
+}
+
+int s2n_recv_client_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ return s2n_extension_recv(&s2n_client_session_ticket_extension, conn, extension);
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_session_ticket.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_session_ticket.h
index e0cdd7225c..4b3b045dcd 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_session_ticket.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_session_ticket.h
@@ -1,25 +1,25 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-extern const s2n_extension_type s2n_client_session_ticket_extension;
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-extern int s2n_extensions_client_session_ticket_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-extern int s2n_recv_client_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *extension);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+extern const s2n_extension_type s2n_client_session_ticket_extension;
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+extern int s2n_extensions_client_session_ticket_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+extern int s2n_recv_client_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *extension);
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_signature_algorithms.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_signature_algorithms.c
index 6d6124a261..9986a2cad1 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_signature_algorithms.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_signature_algorithms.c
@@ -1,64 +1,64 @@
-/*
- * 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 <sys/param.h>
-#include <stdint.h>
-
-#include "tls/extensions/s2n_client_signature_algorithms.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls_parameters.h"
-#include "tls/s2n_signature_algorithms.h"
-
-#include "utils/s2n_safety.h"
-
-static bool s2n_client_signature_algorithms_should_send(struct s2n_connection *conn);
-static int s2n_client_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_client_signature_algorithms_extension = {
- .iana_value = TLS_EXTENSION_SIGNATURE_ALGORITHMS,
- .is_response = false,
- .send = s2n_send_supported_sig_scheme_list,
- .recv = s2n_client_signature_algorithms_recv,
- .should_send = s2n_client_signature_algorithms_should_send,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static bool s2n_client_signature_algorithms_should_send(struct s2n_connection *conn)
-{
- return s2n_connection_get_protocol_version(conn) >= S2N_TLS12;
-}
-
-static int s2n_client_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- return s2n_recv_supported_sig_scheme_list(extension, &conn->handshake_params.client_sig_hash_algs);
-}
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-int s2n_extensions_client_signature_algorithms_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- return s2n_extension_send(&s2n_client_signature_algorithms_extension, conn, out);
-}
-
-int s2n_extensions_client_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- return s2n_extension_recv(&s2n_client_signature_algorithms_extension, conn, extension);
-}
-
-int s2n_extensions_client_signature_algorithms_size(struct s2n_connection *conn)
-{
- /* extra 6 = 2 from extension type, 2 from extension size, 2 from list length */
- return s2n_supported_sig_scheme_list_size(conn) + 6;
-}
+/*
+ * 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 <sys/param.h>
+#include <stdint.h>
+
+#include "tls/extensions/s2n_client_signature_algorithms.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls_parameters.h"
+#include "tls/s2n_signature_algorithms.h"
+
+#include "utils/s2n_safety.h"
+
+static bool s2n_client_signature_algorithms_should_send(struct s2n_connection *conn);
+static int s2n_client_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_client_signature_algorithms_extension = {
+ .iana_value = TLS_EXTENSION_SIGNATURE_ALGORITHMS,
+ .is_response = false,
+ .send = s2n_send_supported_sig_scheme_list,
+ .recv = s2n_client_signature_algorithms_recv,
+ .should_send = s2n_client_signature_algorithms_should_send,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static bool s2n_client_signature_algorithms_should_send(struct s2n_connection *conn)
+{
+ return s2n_connection_get_protocol_version(conn) >= S2N_TLS12;
+}
+
+static int s2n_client_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ return s2n_recv_supported_sig_scheme_list(extension, &conn->handshake_params.client_sig_hash_algs);
+}
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+int s2n_extensions_client_signature_algorithms_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ return s2n_extension_send(&s2n_client_signature_algorithms_extension, conn, out);
+}
+
+int s2n_extensions_client_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ return s2n_extension_recv(&s2n_client_signature_algorithms_extension, conn, extension);
+}
+
+int s2n_extensions_client_signature_algorithms_size(struct s2n_connection *conn)
+{
+ /* extra 6 = 2 from extension type, 2 from extension size, 2 from list length */
+ return s2n_supported_sig_scheme_list_size(conn) + 6;
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_signature_algorithms.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_signature_algorithms.h
index 817594f6f7..0832d40460 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_signature_algorithms.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_signature_algorithms.h
@@ -1,27 +1,27 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/extensions/s2n_extension_type.h"
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-extern const s2n_extension_type s2n_client_signature_algorithms_extension;
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-int s2n_extensions_client_signature_algorithms_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-int s2n_extensions_client_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-int s2n_extensions_client_signature_algorithms_size(struct s2n_connection *conn);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/extensions/s2n_extension_type.h"
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+extern const s2n_extension_type s2n_client_signature_algorithms_extension;
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+int s2n_extensions_client_signature_algorithms_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+int s2n_extensions_client_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+int s2n_extensions_client_signature_algorithms_size(struct s2n_connection *conn);
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_status_request.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_status_request.c
index 62e3df4aa8..e5144fba8b 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_status_request.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_status_request.c
@@ -1,91 +1,91 @@
-/*
- * 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 <sys/param.h>
-#include <stdint.h>
-
-#include "tls/extensions/s2n_client_status_request.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls_parameters.h"
-
-#include "utils/s2n_safety.h"
-
-static bool s2n_client_status_request_should_send(struct s2n_connection *conn);
-static int s2n_client_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-static int s2n_client_status_request_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_client_status_request_extension = {
- .iana_value = TLS_EXTENSION_STATUS_REQUEST,
- .is_response = false,
- .send = s2n_client_status_request_send,
- .recv = s2n_client_status_request_recv,
- .should_send = s2n_client_status_request_should_send,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static bool s2n_client_status_request_should_send(struct s2n_connection *conn)
-{
- return conn->config->status_request_type != S2N_STATUS_REQUEST_NONE;
-}
-
-static int s2n_client_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- GUARD(s2n_stuffer_write_uint8(out, (uint8_t) conn->config->status_request_type));
-
- /* responder_id_list
- *
- * From https://tools.ietf.org/html/rfc6066#section-8:
- * A zero-length "responder_id_list" sequence has the special meaning that the responders are implicitly
- * known to the server, e.g., by prior arrangement */
- GUARD(s2n_stuffer_write_uint16(out, 0));
-
- /* request_extensions
- *
- * From https://tools.ietf.org/html/rfc6066#section-8:
- * A zero-length "request_extensions" value means that there are no extensions. */
- GUARD(s2n_stuffer_write_uint16(out, 0));
-
- return S2N_SUCCESS;
-}
-
-static int s2n_client_status_request_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- if (s2n_stuffer_data_available(extension) < 5) {
- /* Malformed length, ignore the extension */
- return S2N_SUCCESS;
- }
-
- uint8_t type;
- GUARD(s2n_stuffer_read_uint8(extension, &type));
- if (type != (uint8_t) S2N_STATUS_REQUEST_OCSP) {
- /* We only support OCSP (type 1), ignore the extension */
- return S2N_SUCCESS;
- }
-
- conn->status_type = (s2n_status_request_type) type;
- return S2N_SUCCESS;
-}
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-int s2n_extensions_client_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- return s2n_extension_send(&s2n_client_status_request_extension, conn, out);
-}
-
-int s2n_recv_client_status_request(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- return s2n_extension_recv(&s2n_client_status_request_extension, conn, extension);
-}
+/*
+ * 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 <sys/param.h>
+#include <stdint.h>
+
+#include "tls/extensions/s2n_client_status_request.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls_parameters.h"
+
+#include "utils/s2n_safety.h"
+
+static bool s2n_client_status_request_should_send(struct s2n_connection *conn);
+static int s2n_client_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+static int s2n_client_status_request_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_client_status_request_extension = {
+ .iana_value = TLS_EXTENSION_STATUS_REQUEST,
+ .is_response = false,
+ .send = s2n_client_status_request_send,
+ .recv = s2n_client_status_request_recv,
+ .should_send = s2n_client_status_request_should_send,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static bool s2n_client_status_request_should_send(struct s2n_connection *conn)
+{
+ return conn->config->status_request_type != S2N_STATUS_REQUEST_NONE;
+}
+
+static int s2n_client_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ GUARD(s2n_stuffer_write_uint8(out, (uint8_t) conn->config->status_request_type));
+
+ /* responder_id_list
+ *
+ * From https://tools.ietf.org/html/rfc6066#section-8:
+ * A zero-length "responder_id_list" sequence has the special meaning that the responders are implicitly
+ * known to the server, e.g., by prior arrangement */
+ GUARD(s2n_stuffer_write_uint16(out, 0));
+
+ /* request_extensions
+ *
+ * From https://tools.ietf.org/html/rfc6066#section-8:
+ * A zero-length "request_extensions" value means that there are no extensions. */
+ GUARD(s2n_stuffer_write_uint16(out, 0));
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_client_status_request_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ if (s2n_stuffer_data_available(extension) < 5) {
+ /* Malformed length, ignore the extension */
+ return S2N_SUCCESS;
+ }
+
+ uint8_t type;
+ GUARD(s2n_stuffer_read_uint8(extension, &type));
+ if (type != (uint8_t) S2N_STATUS_REQUEST_OCSP) {
+ /* We only support OCSP (type 1), ignore the extension */
+ return S2N_SUCCESS;
+ }
+
+ conn->status_type = (s2n_status_request_type) type;
+ return S2N_SUCCESS;
+}
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+int s2n_extensions_client_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ return s2n_extension_send(&s2n_client_status_request_extension, conn, out);
+}
+
+int s2n_recv_client_status_request(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ return s2n_extension_recv(&s2n_client_status_request_extension, conn, extension);
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_status_request.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_status_request.h
index f1274143da..b3862755fc 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_status_request.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_status_request.h
@@ -1,26 +1,26 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/extensions/s2n_extension_type.h"
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-extern const s2n_extension_type s2n_client_status_request_extension;
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-extern int s2n_extensions_client_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-extern int s2n_recv_client_status_request(struct s2n_connection *conn, struct s2n_stuffer *extension);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/extensions/s2n_extension_type.h"
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+extern const s2n_extension_type s2n_client_status_request_extension;
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+extern int s2n_extensions_client_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+extern int s2n_recv_client_status_request(struct s2n_connection *conn, struct s2n_stuffer *extension);
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_groups.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_groups.c
index d01017e244..9c1bf71092 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_groups.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_groups.c
@@ -1,201 +1,201 @@
-/*
- * 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 <sys/param.h>
-#include <stdint.h>
-
-#include "tls/extensions/s2n_client_supported_groups.h"
-#include "tls/extensions/s2n_ec_point_format.h"
-
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls_parameters.h"
-#include "tls/s2n_security_policies.h"
-
-#include "utils/s2n_safety.h"
-#include "crypto/s2n_fips.h"
-#include "tls/s2n_tls13.h"
-
-static int s2n_client_supported_groups_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-static int s2n_client_supported_groups_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_client_supported_groups_extension = {
- .iana_value = TLS_EXTENSION_SUPPORTED_GROUPS,
- .is_response = false,
- .send = s2n_client_supported_groups_send,
- .recv = s2n_client_supported_groups_recv,
- .should_send = s2n_extension_should_send_if_ecc_enabled,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-bool s2n_extension_should_send_if_ecc_enabled(struct s2n_connection *conn)
-{
- const struct s2n_security_policy *security_policy;
- return s2n_connection_get_security_policy(conn, &security_policy) == S2N_SUCCESS
- && s2n_ecc_is_extension_required(security_policy);
-}
-
-static int s2n_client_supported_groups_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- notnull_check(conn);
-
- const struct s2n_ecc_preferences *ecc_pref = NULL;
- GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
- notnull_check(ecc_pref);
-
- const struct s2n_kem_preferences *kem_pref = NULL;
- GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
- notnull_check(kem_pref);
-
- /* Group list len */
- struct s2n_stuffer_reservation group_list_len = { 0 };
- GUARD(s2n_stuffer_reserve_uint16(out, &group_list_len));
-
- /* Send KEM groups list first */
- if (s2n_connection_get_protocol_version(conn) >= S2N_TLS13 && !s2n_is_in_fips_mode()) {
- for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) {
- GUARD(s2n_stuffer_write_uint16(out, kem_pref->tls13_kem_groups[i]->iana_id));
- }
- }
-
- /* Then send curve list */
- for (size_t i = 0; i < ecc_pref->count; i++) {
- GUARD(s2n_stuffer_write_uint16(out, ecc_pref->ecc_curves[i]->iana_id));
- }
-
- GUARD(s2n_stuffer_write_vector_size(&group_list_len));
-
- return S2N_SUCCESS;
-}
-
-/* Populates the appropriate index of either the mutually_supported_curves or
- * mutually_supported_kem_groups array based on the received IANA ID. Will
- * ignore unrecognized IANA IDs (and return success). */
-static int s2n_client_supported_groups_recv_iana_id(struct s2n_connection *conn, uint16_t iana_id) {
- notnull_check(conn);
-
- const struct s2n_ecc_preferences *ecc_pref = NULL;
- GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
- notnull_check(ecc_pref);
-
- for (size_t i = 0; i < ecc_pref->count; i++) {
- const struct s2n_ecc_named_curve *supported_curve = ecc_pref->ecc_curves[i];
- if (iana_id == supported_curve->iana_id) {
- conn->secure.mutually_supported_curves[i] = supported_curve;
- return S2N_SUCCESS;
- }
- }
-
- /* Return early if in FIPS mode, or if TLS 1.3 is disabled, so as to ignore PQ IDs */
- if (s2n_is_in_fips_mode() || s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
- return S2N_SUCCESS;
- }
-
- const struct s2n_kem_preferences *kem_pref = NULL;
- GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
- notnull_check(kem_pref);
-
- for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) {
- const struct s2n_kem_group *supported_kem_group = kem_pref->tls13_kem_groups[i];
- if (iana_id == supported_kem_group->iana_id) {
- conn->secure.mutually_supported_kem_groups[i] = supported_kem_group;
- return S2N_SUCCESS;
- }
- }
-
- return S2N_SUCCESS;
-}
-
-static int s2n_choose_supported_group(struct s2n_connection *conn) {
- notnull_check(conn);
-
- const struct s2n_ecc_preferences *ecc_pref = NULL;
- GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
- notnull_check(ecc_pref);
-
- const struct s2n_kem_preferences *kem_pref = NULL;
- GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
- notnull_check(kem_pref);
-
- /* Ensure that only the intended group will be non-NULL (if no group is chosen, everything
- * should be NULL). */
- conn->secure.server_kem_group_params.kem_group = NULL;
- conn->secure.server_kem_group_params.ecc_params.negotiated_curve = NULL;
- conn->secure.server_kem_group_params.kem_params.kem = NULL;
- conn->secure.server_ecc_evp_params.negotiated_curve = NULL;
-
- /* Prefer to negotiate hybrid PQ over ECC. If in FIPS mode, we will never choose a
- * PQ group because the mutually_supported_kem_groups array will not have been
- * populated with anything. */
- for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) {
- const struct s2n_kem_group *candidate_kem_group = conn->secure.mutually_supported_kem_groups[i];
- if (candidate_kem_group != NULL) {
- conn->secure.server_kem_group_params.kem_group = candidate_kem_group;
- conn->secure.server_kem_group_params.ecc_params.negotiated_curve = candidate_kem_group->curve;
- conn->secure.server_kem_group_params.kem_params.kem = candidate_kem_group->kem;
- return S2N_SUCCESS;
- }
- }
-
- for (size_t i = 0; i < ecc_pref->count; i++) {
- const struct s2n_ecc_named_curve *candidate_curve = conn->secure.mutually_supported_curves[i];
- if (candidate_curve != NULL) {
- conn->secure.server_ecc_evp_params.negotiated_curve = candidate_curve;
- return S2N_SUCCESS;
- }
- }
-
- return S2N_SUCCESS;
-}
-
-static int s2n_client_supported_groups_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) {
- notnull_check(conn);
- notnull_check(extension);
-
- uint16_t size_of_all;
- GUARD(s2n_stuffer_read_uint16(extension, &size_of_all));
- if (size_of_all > s2n_stuffer_data_available(extension) || (size_of_all % sizeof(uint16_t))) {
- /* Malformed length, ignore the extension */
- return S2N_SUCCESS;
- }
-
- for (size_t i = 0; i < (size_of_all / sizeof(uint16_t)); i++) {
- uint16_t iana_id;
- GUARD(s2n_stuffer_read_uint16(extension, &iana_id));
- GUARD(s2n_client_supported_groups_recv_iana_id(conn, iana_id));
- }
-
- GUARD(s2n_choose_supported_group(conn));
-
- return S2N_SUCCESS;
-}
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-int s2n_extensions_client_supported_groups_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- GUARD(s2n_extension_send(&s2n_client_supported_groups_extension, conn, out));
-
- /* The original send method also sent ec point formats. To avoid breaking
- * anything, I'm going to let it continue writing point formats.
- */
- GUARD(s2n_extension_send(&s2n_client_ec_point_format_extension, conn, out));
-
- return S2N_SUCCESS;
-}
-
-int s2n_recv_client_supported_groups(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- return s2n_extension_recv(&s2n_client_supported_groups_extension, conn, extension);
-}
+/*
+ * 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 <sys/param.h>
+#include <stdint.h>
+
+#include "tls/extensions/s2n_client_supported_groups.h"
+#include "tls/extensions/s2n_ec_point_format.h"
+
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls_parameters.h"
+#include "tls/s2n_security_policies.h"
+
+#include "utils/s2n_safety.h"
+#include "crypto/s2n_fips.h"
+#include "tls/s2n_tls13.h"
+
+static int s2n_client_supported_groups_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+static int s2n_client_supported_groups_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_client_supported_groups_extension = {
+ .iana_value = TLS_EXTENSION_SUPPORTED_GROUPS,
+ .is_response = false,
+ .send = s2n_client_supported_groups_send,
+ .recv = s2n_client_supported_groups_recv,
+ .should_send = s2n_extension_should_send_if_ecc_enabled,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+bool s2n_extension_should_send_if_ecc_enabled(struct s2n_connection *conn)
+{
+ const struct s2n_security_policy *security_policy;
+ return s2n_connection_get_security_policy(conn, &security_policy) == S2N_SUCCESS
+ && s2n_ecc_is_extension_required(security_policy);
+}
+
+static int s2n_client_supported_groups_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ notnull_check(conn);
+
+ const struct s2n_ecc_preferences *ecc_pref = NULL;
+ GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
+ notnull_check(ecc_pref);
+
+ const struct s2n_kem_preferences *kem_pref = NULL;
+ GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
+ notnull_check(kem_pref);
+
+ /* Group list len */
+ struct s2n_stuffer_reservation group_list_len = { 0 };
+ GUARD(s2n_stuffer_reserve_uint16(out, &group_list_len));
+
+ /* Send KEM groups list first */
+ if (s2n_connection_get_protocol_version(conn) >= S2N_TLS13 && !s2n_is_in_fips_mode()) {
+ for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) {
+ GUARD(s2n_stuffer_write_uint16(out, kem_pref->tls13_kem_groups[i]->iana_id));
+ }
+ }
+
+ /* Then send curve list */
+ for (size_t i = 0; i < ecc_pref->count; i++) {
+ GUARD(s2n_stuffer_write_uint16(out, ecc_pref->ecc_curves[i]->iana_id));
+ }
+
+ GUARD(s2n_stuffer_write_vector_size(&group_list_len));
+
+ return S2N_SUCCESS;
+}
+
+/* Populates the appropriate index of either the mutually_supported_curves or
+ * mutually_supported_kem_groups array based on the received IANA ID. Will
+ * ignore unrecognized IANA IDs (and return success). */
+static int s2n_client_supported_groups_recv_iana_id(struct s2n_connection *conn, uint16_t iana_id) {
+ notnull_check(conn);
+
+ const struct s2n_ecc_preferences *ecc_pref = NULL;
+ GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
+ notnull_check(ecc_pref);
+
+ for (size_t i = 0; i < ecc_pref->count; i++) {
+ const struct s2n_ecc_named_curve *supported_curve = ecc_pref->ecc_curves[i];
+ if (iana_id == supported_curve->iana_id) {
+ conn->secure.mutually_supported_curves[i] = supported_curve;
+ return S2N_SUCCESS;
+ }
+ }
+
+ /* Return early if in FIPS mode, or if TLS 1.3 is disabled, so as to ignore PQ IDs */
+ if (s2n_is_in_fips_mode() || s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
+ return S2N_SUCCESS;
+ }
+
+ const struct s2n_kem_preferences *kem_pref = NULL;
+ GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
+ notnull_check(kem_pref);
+
+ for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) {
+ const struct s2n_kem_group *supported_kem_group = kem_pref->tls13_kem_groups[i];
+ if (iana_id == supported_kem_group->iana_id) {
+ conn->secure.mutually_supported_kem_groups[i] = supported_kem_group;
+ return S2N_SUCCESS;
+ }
+ }
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_choose_supported_group(struct s2n_connection *conn) {
+ notnull_check(conn);
+
+ const struct s2n_ecc_preferences *ecc_pref = NULL;
+ GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
+ notnull_check(ecc_pref);
+
+ const struct s2n_kem_preferences *kem_pref = NULL;
+ GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
+ notnull_check(kem_pref);
+
+ /* Ensure that only the intended group will be non-NULL (if no group is chosen, everything
+ * should be NULL). */
+ conn->secure.server_kem_group_params.kem_group = NULL;
+ conn->secure.server_kem_group_params.ecc_params.negotiated_curve = NULL;
+ conn->secure.server_kem_group_params.kem_params.kem = NULL;
+ conn->secure.server_ecc_evp_params.negotiated_curve = NULL;
+
+ /* Prefer to negotiate hybrid PQ over ECC. If in FIPS mode, we will never choose a
+ * PQ group because the mutually_supported_kem_groups array will not have been
+ * populated with anything. */
+ for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) {
+ const struct s2n_kem_group *candidate_kem_group = conn->secure.mutually_supported_kem_groups[i];
+ if (candidate_kem_group != NULL) {
+ conn->secure.server_kem_group_params.kem_group = candidate_kem_group;
+ conn->secure.server_kem_group_params.ecc_params.negotiated_curve = candidate_kem_group->curve;
+ conn->secure.server_kem_group_params.kem_params.kem = candidate_kem_group->kem;
+ return S2N_SUCCESS;
+ }
+ }
+
+ for (size_t i = 0; i < ecc_pref->count; i++) {
+ const struct s2n_ecc_named_curve *candidate_curve = conn->secure.mutually_supported_curves[i];
+ if (candidate_curve != NULL) {
+ conn->secure.server_ecc_evp_params.negotiated_curve = candidate_curve;
+ return S2N_SUCCESS;
+ }
+ }
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_client_supported_groups_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) {
+ notnull_check(conn);
+ notnull_check(extension);
+
+ uint16_t size_of_all;
+ GUARD(s2n_stuffer_read_uint16(extension, &size_of_all));
+ if (size_of_all > s2n_stuffer_data_available(extension) || (size_of_all % sizeof(uint16_t))) {
+ /* Malformed length, ignore the extension */
+ return S2N_SUCCESS;
+ }
+
+ for (size_t i = 0; i < (size_of_all / sizeof(uint16_t)); i++) {
+ uint16_t iana_id;
+ GUARD(s2n_stuffer_read_uint16(extension, &iana_id));
+ GUARD(s2n_client_supported_groups_recv_iana_id(conn, iana_id));
+ }
+
+ GUARD(s2n_choose_supported_group(conn));
+
+ return S2N_SUCCESS;
+}
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+int s2n_extensions_client_supported_groups_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ GUARD(s2n_extension_send(&s2n_client_supported_groups_extension, conn, out));
+
+ /* The original send method also sent ec point formats. To avoid breaking
+ * anything, I'm going to let it continue writing point formats.
+ */
+ GUARD(s2n_extension_send(&s2n_client_ec_point_format_extension, conn, out));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_recv_client_supported_groups(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ return s2n_extension_recv(&s2n_client_supported_groups_extension, conn, extension);
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_groups.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_groups.h
index d1590938b8..e5b798543e 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_groups.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_groups.h
@@ -1,27 +1,27 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/extensions/s2n_extension_type.h"
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-extern const s2n_extension_type s2n_client_supported_groups_extension;
-bool s2n_extension_should_send_if_ecc_enabled(struct s2n_connection *conn);
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-int s2n_extensions_client_supported_groups_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-int s2n_recv_client_supported_groups(struct s2n_connection *conn, struct s2n_stuffer *extension);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/extensions/s2n_extension_type.h"
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+extern const s2n_extension_type s2n_client_supported_groups_extension;
+bool s2n_extension_should_send_if_ecc_enabled(struct s2n_connection *conn);
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+int s2n_extensions_client_supported_groups_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+int s2n_recv_client_supported_groups(struct s2n_connection *conn, struct s2n_stuffer *extension);
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 3b686e12f6..d0ec8cb329 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
@@ -1,153 +1,153 @@
-/*
- * 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 <sys/param.h>
-#include <stdint.h>
-
-#include "tls/extensions/s2n_client_supported_versions.h"
-#include "tls/extensions/s2n_supported_versions.h"
-#include "tls/s2n_alerts.h"
-#include "tls/s2n_cipher_preferences.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls_parameters.h"
-
-#include "utils/s2n_safety.h"
-
-/**
- * Specified in https://tools.ietf.org/html/rfc8446#section-4.2.1
- *
- * "The "supported_versions" extension is used by the client to indicate
- * which versions of TLS it supports and by the server to indicate which
- * version it is using. The extension contains a list of supported
- * versions in preference order, with the most preferred version first."
- *
- * Structure:
- * Extension type (2 bytes)
- * Extension size (2 bytes)
- * Version list length (1 byte)
- * Version list (number of versions * 2 bytes)
- *
- * Note: We assume in these functions that the supported version numbers
- * are consecutive. This is true because S2N does not support SSLv2, and
- * is already an assumption made in the old client hello version handling.
- **/
-
-static int s2n_client_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-static int s2n_client_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *in);
-
-const s2n_extension_type s2n_client_supported_versions_extension = {
- .iana_value = TLS_EXTENSION_SUPPORTED_VERSIONS,
- .is_response = false,
- .send = s2n_client_supported_versions_send,
- .recv = s2n_client_supported_versions_recv,
- .should_send = s2n_extension_send_if_tls13_connection,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static int s2n_client_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- uint8_t highest_supported_version = conn->client_protocol_version;
- uint8_t minimum_supported_version;
- GUARD(s2n_connection_get_minimum_supported_version(conn, &minimum_supported_version));
-
- uint8_t version_list_length = highest_supported_version - minimum_supported_version + 1;
- GUARD(s2n_stuffer_write_uint8(out, version_list_length * S2N_TLS_PROTOCOL_VERSION_LEN));
-
- for (uint8_t i = highest_supported_version; i >= minimum_supported_version; i--) {
- GUARD(s2n_stuffer_write_uint8(out, i / 10));
- GUARD(s2n_stuffer_write_uint8(out, i % 10));
- }
-
- return S2N_SUCCESS;
-}
-
-static int s2n_extensions_client_supported_versions_process(struct s2n_connection *conn, struct s2n_stuffer *extension) {
- uint8_t highest_supported_version = conn->server_protocol_version;
- uint8_t minimum_supported_version;
- GUARD(s2n_connection_get_minimum_supported_version(conn, &minimum_supported_version));
-
- uint8_t size_of_version_list;
- GUARD(s2n_stuffer_read_uint8(extension, &size_of_version_list));
- S2N_ERROR_IF(size_of_version_list != s2n_stuffer_data_available(extension), S2N_ERR_BAD_MESSAGE);
- S2N_ERROR_IF(size_of_version_list % S2N_TLS_PROTOCOL_VERSION_LEN != 0, S2N_ERR_BAD_MESSAGE);
-
- conn->client_protocol_version = s2n_unknown_protocol_version;
- conn->actual_protocol_version = s2n_unknown_protocol_version;
-
- for (int i = 0; i < size_of_version_list; i += S2N_TLS_PROTOCOL_VERSION_LEN) {
- uint8_t client_version_parts[S2N_TLS_PROTOCOL_VERSION_LEN];
- GUARD(s2n_stuffer_read_bytes(extension, client_version_parts, S2N_TLS_PROTOCOL_VERSION_LEN));
-
- /* If the client version is outside of our supported versions, then ignore the value.
- * S2N does not support SSLv2 except for upgrading connections. Since this extension is
- * a TLS1.3 extension, we will skip any SSLv2 values. */
- if (client_version_parts[0] != 3 || client_version_parts[1] > 4) {
- continue;
- }
-
- uint16_t client_version = (client_version_parts[0] * 10) + client_version_parts[1];
-
- conn->client_protocol_version = MAX(client_version, conn->client_protocol_version);
-
- if (client_version > highest_supported_version) {
- continue;
- }
-
- if (client_version < minimum_supported_version) {
- continue;
- }
-
- /* We ignore the client's preferred order and instead choose
- * the highest version that both client and server support. */
- 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);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_client_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *in)
-{
- if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
- return S2N_SUCCESS;
- }
-
- if (s2n_extensions_client_supported_versions_process(conn, in) < 0) {
- s2n_queue_reader_unsupported_protocol_version_alert(conn);
- S2N_ERROR(S2N_ERR_BAD_MESSAGE);
- }
- return S2N_SUCCESS;
-}
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-int s2n_extensions_client_supported_versions_size(struct s2n_connection *conn) {
- uint8_t minimum_supported_version;
- GUARD(s2n_connection_get_minimum_supported_version(conn, &minimum_supported_version));
- uint8_t highest_supported_version = conn->client_protocol_version;
-
- uint8_t version_list_length = highest_supported_version - minimum_supported_version + 1;
-
- return version_list_length * S2N_TLS_PROTOCOL_VERSION_LEN + 5;
-}
-
-int s2n_extensions_client_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) {
- return s2n_extension_recv(&s2n_client_supported_versions_extension, conn, extension);
-}
-
-int s2n_extensions_client_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out) {
- return s2n_extension_send(&s2n_client_supported_versions_extension, conn, out);
-}
+/*
+ * 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 <sys/param.h>
+#include <stdint.h>
+
+#include "tls/extensions/s2n_client_supported_versions.h"
+#include "tls/extensions/s2n_supported_versions.h"
+#include "tls/s2n_alerts.h"
+#include "tls/s2n_cipher_preferences.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls_parameters.h"
+
+#include "utils/s2n_safety.h"
+
+/**
+ * Specified in https://tools.ietf.org/html/rfc8446#section-4.2.1
+ *
+ * "The "supported_versions" extension is used by the client to indicate
+ * which versions of TLS it supports and by the server to indicate which
+ * version it is using. The extension contains a list of supported
+ * versions in preference order, with the most preferred version first."
+ *
+ * Structure:
+ * Extension type (2 bytes)
+ * Extension size (2 bytes)
+ * Version list length (1 byte)
+ * Version list (number of versions * 2 bytes)
+ *
+ * Note: We assume in these functions that the supported version numbers
+ * are consecutive. This is true because S2N does not support SSLv2, and
+ * is already an assumption made in the old client hello version handling.
+ **/
+
+static int s2n_client_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+static int s2n_client_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *in);
+
+const s2n_extension_type s2n_client_supported_versions_extension = {
+ .iana_value = TLS_EXTENSION_SUPPORTED_VERSIONS,
+ .is_response = false,
+ .send = s2n_client_supported_versions_send,
+ .recv = s2n_client_supported_versions_recv,
+ .should_send = s2n_extension_send_if_tls13_connection,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static int s2n_client_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ uint8_t highest_supported_version = conn->client_protocol_version;
+ uint8_t minimum_supported_version;
+ GUARD(s2n_connection_get_minimum_supported_version(conn, &minimum_supported_version));
+
+ uint8_t version_list_length = highest_supported_version - minimum_supported_version + 1;
+ GUARD(s2n_stuffer_write_uint8(out, version_list_length * S2N_TLS_PROTOCOL_VERSION_LEN));
+
+ for (uint8_t i = highest_supported_version; i >= minimum_supported_version; i--) {
+ GUARD(s2n_stuffer_write_uint8(out, i / 10));
+ GUARD(s2n_stuffer_write_uint8(out, i % 10));
+ }
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_extensions_client_supported_versions_process(struct s2n_connection *conn, struct s2n_stuffer *extension) {
+ uint8_t highest_supported_version = conn->server_protocol_version;
+ uint8_t minimum_supported_version;
+ GUARD(s2n_connection_get_minimum_supported_version(conn, &minimum_supported_version));
+
+ uint8_t size_of_version_list;
+ GUARD(s2n_stuffer_read_uint8(extension, &size_of_version_list));
+ S2N_ERROR_IF(size_of_version_list != s2n_stuffer_data_available(extension), S2N_ERR_BAD_MESSAGE);
+ S2N_ERROR_IF(size_of_version_list % S2N_TLS_PROTOCOL_VERSION_LEN != 0, S2N_ERR_BAD_MESSAGE);
+
+ conn->client_protocol_version = s2n_unknown_protocol_version;
+ conn->actual_protocol_version = s2n_unknown_protocol_version;
+
+ for (int i = 0; i < size_of_version_list; i += S2N_TLS_PROTOCOL_VERSION_LEN) {
+ uint8_t client_version_parts[S2N_TLS_PROTOCOL_VERSION_LEN];
+ GUARD(s2n_stuffer_read_bytes(extension, client_version_parts, S2N_TLS_PROTOCOL_VERSION_LEN));
+
+ /* If the client version is outside of our supported versions, then ignore the value.
+ * S2N does not support SSLv2 except for upgrading connections. Since this extension is
+ * a TLS1.3 extension, we will skip any SSLv2 values. */
+ if (client_version_parts[0] != 3 || client_version_parts[1] > 4) {
+ continue;
+ }
+
+ uint16_t client_version = (client_version_parts[0] * 10) + client_version_parts[1];
+
+ conn->client_protocol_version = MAX(client_version, conn->client_protocol_version);
+
+ if (client_version > highest_supported_version) {
+ continue;
+ }
+
+ if (client_version < minimum_supported_version) {
+ continue;
+ }
+
+ /* We ignore the client's preferred order and instead choose
+ * the highest version that both client and server support. */
+ 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);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_client_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *in)
+{
+ if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
+ return S2N_SUCCESS;
+ }
+
+ if (s2n_extensions_client_supported_versions_process(conn, in) < 0) {
+ s2n_queue_reader_unsupported_protocol_version_alert(conn);
+ S2N_ERROR(S2N_ERR_BAD_MESSAGE);
+ }
+ return S2N_SUCCESS;
+}
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+int s2n_extensions_client_supported_versions_size(struct s2n_connection *conn) {
+ uint8_t minimum_supported_version;
+ GUARD(s2n_connection_get_minimum_supported_version(conn, &minimum_supported_version));
+ uint8_t highest_supported_version = conn->client_protocol_version;
+
+ uint8_t version_list_length = highest_supported_version - minimum_supported_version + 1;
+
+ return version_list_length * S2N_TLS_PROTOCOL_VERSION_LEN + 5;
+}
+
+int s2n_extensions_client_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) {
+ return s2n_extension_recv(&s2n_client_supported_versions_extension, conn, extension);
+}
+
+int s2n_extensions_client_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out) {
+ return s2n_extension_send(&s2n_client_supported_versions_extension, conn, out);
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.h
index c3657953c9..b9deabe628 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.h
@@ -1,26 +1,26 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-extern const s2n_extension_type s2n_client_supported_versions_extension;
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-extern int s2n_extensions_client_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-extern int s2n_extensions_client_supported_versions_size(struct s2n_connection *conn);
-extern int s2n_extensions_client_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+extern const s2n_extension_type s2n_client_supported_versions_extension;
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+extern int s2n_extensions_client_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+extern int s2n_extensions_client_supported_versions_size(struct s2n_connection *conn);
+extern int s2n_extensions_client_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out);
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.c
index add1f64269..7e8885bc0b 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.c
@@ -1,103 +1,103 @@
-/*
- * 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 "tls/extensions/s2n_cookie.h"
-#include "tls/s2n_tls.h"
-
-#define S2N_SIZE_OF_EXTENSION_TYPE 2
-#define S2N_SIZE_OF_EXTENSION_DATA_SIZE 2
-#define S2N_SIZE_OF_COOKIE_DATA_SIZE 2
-
-const s2n_extension_type s2n_client_cookie_extension = {
- .iana_value = TLS_EXTENSION_COOKIE,
- .is_response = true,
- .send = s2n_extension_send_noop,
- .recv = s2n_extension_recv_noop,
- .should_send = s2n_extension_never_send,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static bool s2n_cookie_should_send(struct s2n_connection *conn);
-static int s2n_cookie_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-static int s2n_cookie_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_server_cookie_extension = {
- .iana_value = TLS_EXTENSION_COOKIE,
- .is_response = false,
- .send = s2n_cookie_send,
- .recv = s2n_cookie_recv,
- .should_send = s2n_cookie_should_send,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static bool s2n_cookie_should_send(struct s2n_connection *conn)
-{
- return s2n_extension_send_if_tls13_connection(conn)
- && conn && s2n_stuffer_data_available(&conn->cookie_stuffer) > 0;
-}
-
-static int s2n_cookie_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- notnull_check(conn);
- uint16_t cookie_size = s2n_stuffer_data_available(&conn->cookie_stuffer);
- GUARD(s2n_stuffer_write_uint16(out, cookie_size));
- GUARD(s2n_stuffer_copy(&conn->cookie_stuffer, out, cookie_size));
- return S2N_SUCCESS;
-}
-
-static int s2n_cookie_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- notnull_check(conn);
- if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
- return S2N_SUCCESS;
- }
-
- uint16_t cookie_len;
- GUARD(s2n_stuffer_read_uint16(extension, &cookie_len));
- ENSURE_POSIX(s2n_stuffer_data_available(extension) == cookie_len, S2N_ERR_BAD_MESSAGE);
-
- GUARD(s2n_stuffer_wipe(&conn->cookie_stuffer));
- GUARD(s2n_stuffer_resize(&conn->cookie_stuffer, cookie_len));
- GUARD(s2n_stuffer_copy(extension, &conn->cookie_stuffer, cookie_len));
- return S2N_SUCCESS;
-}
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-int s2n_extensions_cookie_size(struct s2n_connection *conn)
-{
- GUARD(s2n_stuffer_reread(&conn->cookie_stuffer));
-
- if (s2n_stuffer_data_available(&conn->cookie_stuffer) == 0) {
- return 0;
- }
-
- const int cookie_extension_size = S2N_SIZE_OF_EXTENSION_TYPE
- + S2N_SIZE_OF_EXTENSION_DATA_SIZE
- + S2N_SIZE_OF_COOKIE_DATA_SIZE
- + s2n_stuffer_data_available(&conn->cookie_stuffer);
-
- return cookie_extension_size;
-}
-
-int s2n_extensions_cookie_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- return s2n_extension_send(&s2n_server_cookie_extension, conn, extension);
-}
-
-int s2n_extensions_cookie_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- return s2n_extension_send(&s2n_server_cookie_extension, conn, out);
-}
+/*
+ * 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 "tls/extensions/s2n_cookie.h"
+#include "tls/s2n_tls.h"
+
+#define S2N_SIZE_OF_EXTENSION_TYPE 2
+#define S2N_SIZE_OF_EXTENSION_DATA_SIZE 2
+#define S2N_SIZE_OF_COOKIE_DATA_SIZE 2
+
+const s2n_extension_type s2n_client_cookie_extension = {
+ .iana_value = TLS_EXTENSION_COOKIE,
+ .is_response = true,
+ .send = s2n_extension_send_noop,
+ .recv = s2n_extension_recv_noop,
+ .should_send = s2n_extension_never_send,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static bool s2n_cookie_should_send(struct s2n_connection *conn);
+static int s2n_cookie_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+static int s2n_cookie_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_server_cookie_extension = {
+ .iana_value = TLS_EXTENSION_COOKIE,
+ .is_response = false,
+ .send = s2n_cookie_send,
+ .recv = s2n_cookie_recv,
+ .should_send = s2n_cookie_should_send,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static bool s2n_cookie_should_send(struct s2n_connection *conn)
+{
+ return s2n_extension_send_if_tls13_connection(conn)
+ && conn && s2n_stuffer_data_available(&conn->cookie_stuffer) > 0;
+}
+
+static int s2n_cookie_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ notnull_check(conn);
+ uint16_t cookie_size = s2n_stuffer_data_available(&conn->cookie_stuffer);
+ GUARD(s2n_stuffer_write_uint16(out, cookie_size));
+ GUARD(s2n_stuffer_copy(&conn->cookie_stuffer, out, cookie_size));
+ return S2N_SUCCESS;
+}
+
+static int s2n_cookie_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ notnull_check(conn);
+ if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
+ return S2N_SUCCESS;
+ }
+
+ uint16_t cookie_len;
+ GUARD(s2n_stuffer_read_uint16(extension, &cookie_len));
+ ENSURE_POSIX(s2n_stuffer_data_available(extension) == cookie_len, S2N_ERR_BAD_MESSAGE);
+
+ GUARD(s2n_stuffer_wipe(&conn->cookie_stuffer));
+ GUARD(s2n_stuffer_resize(&conn->cookie_stuffer, cookie_len));
+ GUARD(s2n_stuffer_copy(extension, &conn->cookie_stuffer, cookie_len));
+ return S2N_SUCCESS;
+}
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+int s2n_extensions_cookie_size(struct s2n_connection *conn)
+{
+ GUARD(s2n_stuffer_reread(&conn->cookie_stuffer));
+
+ if (s2n_stuffer_data_available(&conn->cookie_stuffer) == 0) {
+ return 0;
+ }
+
+ const int cookie_extension_size = S2N_SIZE_OF_EXTENSION_TYPE
+ + S2N_SIZE_OF_EXTENSION_DATA_SIZE
+ + S2N_SIZE_OF_COOKIE_DATA_SIZE
+ + s2n_stuffer_data_available(&conn->cookie_stuffer);
+
+ return cookie_extension_size;
+}
+
+int s2n_extensions_cookie_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ return s2n_extension_send(&s2n_server_cookie_extension, conn, extension);
+}
+
+int s2n_extensions_cookie_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ return s2n_extension_send(&s2n_server_cookie_extension, conn, out);
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.h
index 115226d9d4..4a77ba323e 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.h
@@ -1,29 +1,29 @@
-/*
- * 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.
- */
-
-
-#pragma once
-
-#include "tls/extensions/s2n_extension_type.h"
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-extern const s2n_extension_type s2n_client_cookie_extension;
-extern const s2n_extension_type s2n_server_cookie_extension;
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-int s2n_extensions_cookie_size(struct s2n_connection *conn);
-int s2n_extensions_cookie_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-int s2n_extensions_cookie_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+/*
+ * 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.
+ */
+
+
+#pragma once
+
+#include "tls/extensions/s2n_extension_type.h"
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+extern const s2n_extension_type s2n_client_cookie_extension;
+extern const s2n_extension_type s2n_server_cookie_extension;
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+int s2n_extensions_cookie_size(struct s2n_connection *conn);
+int s2n_extensions_cookie_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+int s2n_extensions_cookie_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_ec_point_format.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_ec_point_format.c
index ac6a162efb..cb720581a6 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_ec_point_format.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_ec_point_format.c
@@ -1,91 +1,91 @@
-/*
- * 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 <sys/param.h>
-#include <stdint.h>
-
-#include "tls/extensions/s2n_client_supported_groups.h"
-#include "tls/extensions/s2n_ec_point_format.h"
-#include "tls/s2n_tls.h"
-
-#include "utils/s2n_safety.h"
-
-static int s2n_ec_point_format_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-static int s2n_ec_point_format_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_client_ec_point_format_extension = {
- .iana_value = TLS_EXTENSION_EC_POINT_FORMATS,
- .is_response = false,
- .send = s2n_ec_point_format_send,
- .recv = s2n_ec_point_format_recv,
- .should_send = s2n_extension_should_send_if_ecc_enabled,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static bool s2n_server_ec_point_format_should_send(struct s2n_connection *conn);
-
-const s2n_extension_type s2n_server_ec_point_format_extension = {
- .iana_value = TLS_EXTENSION_EC_POINT_FORMATS,
- .is_response = true,
- .send = s2n_ec_point_format_send,
- .recv = s2n_extension_recv_noop,
- .should_send = s2n_server_ec_point_format_should_send,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static bool s2n_server_ec_point_format_should_send(struct s2n_connection *conn)
-{
- return conn && conn->secure.cipher_suite
- && s2n_kex_includes(conn->secure.cipher_suite->key_exchange_alg, &s2n_ecdhe);
-}
-
-static int s2n_ec_point_format_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- /* Point format list len. We only support one. */
- GUARD(s2n_stuffer_write_uint8(out, 1));
-
- /* Only allow uncompressed format */
- GUARD(s2n_stuffer_write_uint8(out, TLS_EC_POINT_FORMAT_UNCOMPRESSED));
-
- return S2N_SUCCESS;
-}
-
-static int s2n_ec_point_format_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- /**
- * Only uncompressed points are supported by the server and the client must include it in
- * the extension. Just skip the extension.
- */
- conn->ec_point_formats = 1;
- return S2N_SUCCESS;
-}
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-int s2n_server_ecc_point_format_extension_size(struct s2n_connection *conn)
-{
- if (s2n_server_ec_point_format_extension.should_send(conn) && s2n_server_can_send_ec_point_formats(conn)) {
- return sizeof(uint16_t) /* extension type */
- + sizeof(uint16_t) /* extension size */
- + sizeof(uint8_t) /* point list size */
- + sizeof(uint8_t); /* point */
- }
- return 0;
-}
-
-int s2n_recv_client_ec_point_formats(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- return s2n_extension_recv(&s2n_client_ec_point_format_extension, conn, extension);
-}
+/*
+ * 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 <sys/param.h>
+#include <stdint.h>
+
+#include "tls/extensions/s2n_client_supported_groups.h"
+#include "tls/extensions/s2n_ec_point_format.h"
+#include "tls/s2n_tls.h"
+
+#include "utils/s2n_safety.h"
+
+static int s2n_ec_point_format_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+static int s2n_ec_point_format_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_client_ec_point_format_extension = {
+ .iana_value = TLS_EXTENSION_EC_POINT_FORMATS,
+ .is_response = false,
+ .send = s2n_ec_point_format_send,
+ .recv = s2n_ec_point_format_recv,
+ .should_send = s2n_extension_should_send_if_ecc_enabled,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static bool s2n_server_ec_point_format_should_send(struct s2n_connection *conn);
+
+const s2n_extension_type s2n_server_ec_point_format_extension = {
+ .iana_value = TLS_EXTENSION_EC_POINT_FORMATS,
+ .is_response = true,
+ .send = s2n_ec_point_format_send,
+ .recv = s2n_extension_recv_noop,
+ .should_send = s2n_server_ec_point_format_should_send,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static bool s2n_server_ec_point_format_should_send(struct s2n_connection *conn)
+{
+ return conn && conn->secure.cipher_suite
+ && s2n_kex_includes(conn->secure.cipher_suite->key_exchange_alg, &s2n_ecdhe);
+}
+
+static int s2n_ec_point_format_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ /* Point format list len. We only support one. */
+ GUARD(s2n_stuffer_write_uint8(out, 1));
+
+ /* Only allow uncompressed format */
+ GUARD(s2n_stuffer_write_uint8(out, TLS_EC_POINT_FORMAT_UNCOMPRESSED));
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_ec_point_format_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ /**
+ * Only uncompressed points are supported by the server and the client must include it in
+ * the extension. Just skip the extension.
+ */
+ conn->ec_point_formats = 1;
+ return S2N_SUCCESS;
+}
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+int s2n_server_ecc_point_format_extension_size(struct s2n_connection *conn)
+{
+ if (s2n_server_ec_point_format_extension.should_send(conn) && s2n_server_can_send_ec_point_formats(conn)) {
+ return sizeof(uint16_t) /* extension type */
+ + sizeof(uint16_t) /* extension size */
+ + sizeof(uint8_t) /* point list size */
+ + sizeof(uint8_t); /* point */
+ }
+ return 0;
+}
+
+int s2n_recv_client_ec_point_formats(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ return s2n_extension_recv(&s2n_client_ec_point_format_extension, conn, extension);
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_ec_point_format.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_ec_point_format.h
index ac01ad7672..4e7cf3065d 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_ec_point_format.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_ec_point_format.h
@@ -1,29 +1,29 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/extensions/s2n_extension_type.h"
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-#define TLS_EC_POINT_FORMAT_UNCOMPRESSED 0
-
-extern const s2n_extension_type s2n_client_ec_point_format_extension;
-extern const s2n_extension_type s2n_server_ec_point_format_extension;
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-int s2n_server_ecc_point_format_extension_size(struct s2n_connection *conn);
-int s2n_recv_client_ec_point_formats(struct s2n_connection *conn, struct s2n_stuffer *extension);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/extensions/s2n_extension_type.h"
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+#define TLS_EC_POINT_FORMAT_UNCOMPRESSED 0
+
+extern const s2n_extension_type s2n_client_ec_point_format_extension;
+extern const s2n_extension_type s2n_server_ec_point_format_extension;
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+int s2n_server_ecc_point_format_extension_size(struct s2n_connection *conn);
+int s2n_recv_client_ec_point_formats(struct s2n_connection *conn, struct s2n_stuffer *extension);
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.c
index 11c840d66a..81c9e9bf5a 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.c
@@ -1,184 +1,184 @@
-/*
- * 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 "s2n_extension_list.h"
-#include "s2n_extension_type.h"
-#include "s2n_extension_type_lists.h"
-
-#include <s2n.h>
-
-#include "error/s2n_errno.h"
-#include "utils/s2n_safety.h"
-
-#define s2n_parsed_extension_is_empty(parsed_extension) ((parsed_extension)->extension.data == NULL)
-
-static const s2n_parsed_extension empty_parsed_extensions[S2N_PARSED_EXTENSIONS_COUNT] = { 0 };
-
-int s2n_extension_list_send(s2n_extension_list_id list_type, struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- s2n_extension_type_list *extension_type_list;
- GUARD(s2n_extension_type_list_get(list_type, &extension_type_list));
-
- struct s2n_stuffer_reservation total_extensions_size = {0};
- GUARD(s2n_stuffer_reserve_uint16(out, &total_extensions_size));
-
- for (int i = 0; i < extension_type_list->count; i++) {
- GUARD(s2n_extension_send(extension_type_list->extension_types[i], conn, out));
- }
-
- GUARD(s2n_stuffer_write_vector_size(&total_extensions_size));
- return S2N_SUCCESS;
-}
-
-int s2n_extension_list_recv(s2n_extension_list_id list_type, struct s2n_connection *conn, struct s2n_stuffer *in)
-{
- s2n_parsed_extensions_list parsed_extension_list = { 0 };
- GUARD(s2n_extension_list_parse(in, &parsed_extension_list));
- GUARD(s2n_extension_list_process(list_type, conn, &parsed_extension_list));
- return S2N_SUCCESS;
-}
-
-static int s2n_extension_process_impl(const s2n_extension_type *extension_type, s2n_extension_type_id extension_id,
- struct s2n_connection *conn, s2n_parsed_extension *parsed_extensions)
-{
- notnull_check(extension_type);
- notnull_check(parsed_extensions);
-
- if (s2n_parsed_extension_is_empty(&parsed_extensions[extension_id])) {
- GUARD(s2n_extension_is_missing(extension_type, conn));
- return S2N_SUCCESS;
- }
-
- ENSURE_POSIX(parsed_extensions[extension_id].extension_type == extension_type->iana_value,
- S2N_ERR_INVALID_PARSED_EXTENSIONS);
-
- struct s2n_stuffer extension_stuffer;
- GUARD(s2n_stuffer_init(&extension_stuffer, &parsed_extensions[extension_id].extension));
- GUARD(s2n_stuffer_skip_write(&extension_stuffer, parsed_extensions[extension_id].extension.size));
-
- GUARD(s2n_extension_recv(extension_type, conn, &extension_stuffer));
-
- return S2N_SUCCESS;
-}
-
-int s2n_extension_process(const s2n_extension_type *extension_type, struct s2n_connection *conn,
- s2n_parsed_extensions_list *parsed_extension_list)
-{
- notnull_check(parsed_extension_list);
- notnull_check(extension_type);
-
- s2n_extension_type_id extension_id;
- GUARD(s2n_extension_supported_iana_value_to_id(extension_type->iana_value, &extension_id));
-
- int result = s2n_extension_process_impl(extension_type, extension_id, conn, parsed_extension_list->parsed_extensions);
-
- /* Wipe parsed_extension.
- * We can check for unprocessed extensions later by checking for non-blank parsed_extensions. */
- parsed_extension_list->parsed_extensions[extension_id] = empty_parsed_extensions[0];
-
- return result;
-}
-
-int s2n_extension_list_process(s2n_extension_list_id list_type, struct s2n_connection *conn,
- s2n_parsed_extensions_list *parsed_extension_list)
-{
- notnull_check(parsed_extension_list);
-
- s2n_extension_type_list *extension_type_list;
- GUARD(s2n_extension_type_list_get(list_type, &extension_type_list));
-
- for (int i = 0; i < extension_type_list->count; i++) {
- GUARD(s2n_extension_process(extension_type_list->extension_types[i],
- conn, parsed_extension_list));
- }
-
- /* If parsed_extension_list.parsed_extensions is not completely wiped at this point,
- * then we have received an extension not allowed on this message type.
- *
- * According to the RFC, we should alert and close the connection.
- * From https://tools.ietf.org/html/rfc8446#section-4.2:
- * If an implementation receives an extension which it recognizes and which is not
- * specified for the message in which it appears, it MUST abort the handshake with an
- * "illegal_parameter" alert.
- *
- * However, to be more tolerant of non-compliant peers, we will just ignore and not
- * process the illegal extensions, treating them as if they are unsupported.
- */
-
- return S2N_SUCCESS;
-}
-
-static int s2n_extension_parse(struct s2n_stuffer *in, s2n_parsed_extension *parsed_extensions)
-{
- notnull_check(parsed_extensions);
-
- uint16_t extension_type;
- ENSURE_POSIX(s2n_stuffer_read_uint16(in, &extension_type) == S2N_SUCCESS,
- S2N_ERR_BAD_MESSAGE);
-
- uint16_t extension_size;
- ENSURE_POSIX(s2n_stuffer_read_uint16(in, &extension_size) == S2N_SUCCESS,
- S2N_ERR_BAD_MESSAGE);
-
- uint8_t *extension_data = s2n_stuffer_raw_read(in, extension_size);
- ENSURE_POSIX(extension_data != NULL, S2N_ERR_BAD_MESSAGE);
-
- s2n_extension_type_id extension_id;
- if (s2n_extension_supported_iana_value_to_id(extension_type, &extension_id) != S2N_SUCCESS) {
- /* Ignore unknown extensions */
- return S2N_SUCCESS;
- }
-
- s2n_parsed_extension *parsed_extension = &parsed_extensions[extension_id];
-
- /* Error if extension is a duplicate */
- ENSURE_POSIX(s2n_parsed_extension_is_empty(parsed_extension),
- S2N_ERR_DUPLICATE_EXTENSION);
-
- /* Fill in parsed extension */
- parsed_extension->extension_type = extension_type;
- GUARD(s2n_blob_init(&parsed_extension->extension, extension_data, extension_size));
-
- return S2N_SUCCESS;
-}
-
-int s2n_extension_list_parse(struct s2n_stuffer *in, s2n_parsed_extensions_list *parsed_extension_list)
-{
- notnull_check(in);
- notnull_check(parsed_extension_list);
-
- memset_check((s2n_parsed_extension*) parsed_extension_list->parsed_extensions,
- 0, sizeof(parsed_extension_list->parsed_extensions));
-
- uint16_t total_extensions_size;
- if (s2n_stuffer_read_uint16(in, &total_extensions_size) != S2N_SUCCESS) {
- total_extensions_size = 0;
- }
-
- uint8_t *extensions_data = s2n_stuffer_raw_read(in, total_extensions_size);
- ENSURE_POSIX(extensions_data != NULL, S2N_ERR_BAD_MESSAGE);
-
- GUARD(s2n_blob_init(&parsed_extension_list->raw, extensions_data, total_extensions_size));
-
- struct s2n_stuffer extensions_stuffer;
- GUARD(s2n_stuffer_init(&extensions_stuffer, &parsed_extension_list->raw));
- GUARD(s2n_stuffer_skip_write(&extensions_stuffer, total_extensions_size));
-
- while (s2n_stuffer_data_available(&extensions_stuffer)) {
- GUARD(s2n_extension_parse(&extensions_stuffer, parsed_extension_list->parsed_extensions));
- }
-
- return S2N_SUCCESS;
-}
+/*
+ * 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 "s2n_extension_list.h"
+#include "s2n_extension_type.h"
+#include "s2n_extension_type_lists.h"
+
+#include <s2n.h>
+
+#include "error/s2n_errno.h"
+#include "utils/s2n_safety.h"
+
+#define s2n_parsed_extension_is_empty(parsed_extension) ((parsed_extension)->extension.data == NULL)
+
+static const s2n_parsed_extension empty_parsed_extensions[S2N_PARSED_EXTENSIONS_COUNT] = { 0 };
+
+int s2n_extension_list_send(s2n_extension_list_id list_type, struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ s2n_extension_type_list *extension_type_list;
+ GUARD(s2n_extension_type_list_get(list_type, &extension_type_list));
+
+ struct s2n_stuffer_reservation total_extensions_size = {0};
+ GUARD(s2n_stuffer_reserve_uint16(out, &total_extensions_size));
+
+ for (int i = 0; i < extension_type_list->count; i++) {
+ GUARD(s2n_extension_send(extension_type_list->extension_types[i], conn, out));
+ }
+
+ GUARD(s2n_stuffer_write_vector_size(&total_extensions_size));
+ return S2N_SUCCESS;
+}
+
+int s2n_extension_list_recv(s2n_extension_list_id list_type, struct s2n_connection *conn, struct s2n_stuffer *in)
+{
+ s2n_parsed_extensions_list parsed_extension_list = { 0 };
+ GUARD(s2n_extension_list_parse(in, &parsed_extension_list));
+ GUARD(s2n_extension_list_process(list_type, conn, &parsed_extension_list));
+ return S2N_SUCCESS;
+}
+
+static int s2n_extension_process_impl(const s2n_extension_type *extension_type, s2n_extension_type_id extension_id,
+ struct s2n_connection *conn, s2n_parsed_extension *parsed_extensions)
+{
+ notnull_check(extension_type);
+ notnull_check(parsed_extensions);
+
+ if (s2n_parsed_extension_is_empty(&parsed_extensions[extension_id])) {
+ GUARD(s2n_extension_is_missing(extension_type, conn));
+ return S2N_SUCCESS;
+ }
+
+ ENSURE_POSIX(parsed_extensions[extension_id].extension_type == extension_type->iana_value,
+ S2N_ERR_INVALID_PARSED_EXTENSIONS);
+
+ struct s2n_stuffer extension_stuffer;
+ GUARD(s2n_stuffer_init(&extension_stuffer, &parsed_extensions[extension_id].extension));
+ GUARD(s2n_stuffer_skip_write(&extension_stuffer, parsed_extensions[extension_id].extension.size));
+
+ GUARD(s2n_extension_recv(extension_type, conn, &extension_stuffer));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_extension_process(const s2n_extension_type *extension_type, struct s2n_connection *conn,
+ s2n_parsed_extensions_list *parsed_extension_list)
+{
+ notnull_check(parsed_extension_list);
+ notnull_check(extension_type);
+
+ s2n_extension_type_id extension_id;
+ GUARD(s2n_extension_supported_iana_value_to_id(extension_type->iana_value, &extension_id));
+
+ int result = s2n_extension_process_impl(extension_type, extension_id, conn, parsed_extension_list->parsed_extensions);
+
+ /* Wipe parsed_extension.
+ * We can check for unprocessed extensions later by checking for non-blank parsed_extensions. */
+ parsed_extension_list->parsed_extensions[extension_id] = empty_parsed_extensions[0];
+
+ return result;
+}
+
+int s2n_extension_list_process(s2n_extension_list_id list_type, struct s2n_connection *conn,
+ s2n_parsed_extensions_list *parsed_extension_list)
+{
+ notnull_check(parsed_extension_list);
+
+ s2n_extension_type_list *extension_type_list;
+ GUARD(s2n_extension_type_list_get(list_type, &extension_type_list));
+
+ for (int i = 0; i < extension_type_list->count; i++) {
+ GUARD(s2n_extension_process(extension_type_list->extension_types[i],
+ conn, parsed_extension_list));
+ }
+
+ /* If parsed_extension_list.parsed_extensions is not completely wiped at this point,
+ * then we have received an extension not allowed on this message type.
+ *
+ * According to the RFC, we should alert and close the connection.
+ * From https://tools.ietf.org/html/rfc8446#section-4.2:
+ * If an implementation receives an extension which it recognizes and which is not
+ * specified for the message in which it appears, it MUST abort the handshake with an
+ * "illegal_parameter" alert.
+ *
+ * However, to be more tolerant of non-compliant peers, we will just ignore and not
+ * process the illegal extensions, treating them as if they are unsupported.
+ */
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_extension_parse(struct s2n_stuffer *in, s2n_parsed_extension *parsed_extensions)
+{
+ notnull_check(parsed_extensions);
+
+ uint16_t extension_type;
+ ENSURE_POSIX(s2n_stuffer_read_uint16(in, &extension_type) == S2N_SUCCESS,
+ S2N_ERR_BAD_MESSAGE);
+
+ uint16_t extension_size;
+ ENSURE_POSIX(s2n_stuffer_read_uint16(in, &extension_size) == S2N_SUCCESS,
+ S2N_ERR_BAD_MESSAGE);
+
+ uint8_t *extension_data = s2n_stuffer_raw_read(in, extension_size);
+ ENSURE_POSIX(extension_data != NULL, S2N_ERR_BAD_MESSAGE);
+
+ s2n_extension_type_id extension_id;
+ if (s2n_extension_supported_iana_value_to_id(extension_type, &extension_id) != S2N_SUCCESS) {
+ /* Ignore unknown extensions */
+ return S2N_SUCCESS;
+ }
+
+ s2n_parsed_extension *parsed_extension = &parsed_extensions[extension_id];
+
+ /* Error if extension is a duplicate */
+ ENSURE_POSIX(s2n_parsed_extension_is_empty(parsed_extension),
+ S2N_ERR_DUPLICATE_EXTENSION);
+
+ /* Fill in parsed extension */
+ parsed_extension->extension_type = extension_type;
+ GUARD(s2n_blob_init(&parsed_extension->extension, extension_data, extension_size));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_extension_list_parse(struct s2n_stuffer *in, s2n_parsed_extensions_list *parsed_extension_list)
+{
+ notnull_check(in);
+ notnull_check(parsed_extension_list);
+
+ memset_check((s2n_parsed_extension*) parsed_extension_list->parsed_extensions,
+ 0, sizeof(parsed_extension_list->parsed_extensions));
+
+ uint16_t total_extensions_size;
+ if (s2n_stuffer_read_uint16(in, &total_extensions_size) != S2N_SUCCESS) {
+ total_extensions_size = 0;
+ }
+
+ uint8_t *extensions_data = s2n_stuffer_raw_read(in, total_extensions_size);
+ ENSURE_POSIX(extensions_data != NULL, S2N_ERR_BAD_MESSAGE);
+
+ GUARD(s2n_blob_init(&parsed_extension_list->raw, extensions_data, total_extensions_size));
+
+ struct s2n_stuffer extensions_stuffer;
+ GUARD(s2n_stuffer_init(&extensions_stuffer, &parsed_extension_list->raw));
+ GUARD(s2n_stuffer_skip_write(&extensions_stuffer, total_extensions_size));
+
+ while (s2n_stuffer_data_available(&extensions_stuffer)) {
+ GUARD(s2n_extension_parse(&extensions_stuffer, parsed_extension_list->parsed_extensions));
+ }
+
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.h
index 3609587ac4..35582e5638 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.h
@@ -1,51 +1,51 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "stuffer/s2n_stuffer.h"
-#include "tls/extensions/s2n_extension_type.h"
-
-#define S2N_PARSED_EXTENSIONS_COUNT S2N_SUPPORTED_EXTENSIONS_COUNT
-
-typedef struct {
- uint16_t extension_type;
- struct s2n_blob extension;
-} s2n_parsed_extension;
-
-typedef struct {
- s2n_parsed_extension parsed_extensions[S2N_PARSED_EXTENSIONS_COUNT];
- struct s2n_blob raw; /* Needed by some ClientHello APIs */
-} s2n_parsed_extensions_list;
-
-typedef enum {
- S2N_EXTENSION_LIST_CLIENT_HELLO = 0,
- S2N_EXTENSION_LIST_SERVER_HELLO_DEFAULT,
- S2N_EXTENSION_LIST_SERVER_HELLO_TLS13,
- S2N_EXTENSION_LIST_ENCRYPTED_EXTENSIONS,
- S2N_EXTENSION_LIST_CERT_REQ,
- S2N_EXTENSION_LIST_CERTIFICATE,
- S2N_EXTENSION_LIST_EMPTY,
- S2N_EXTENSION_LIST_IDS_COUNT,
-} s2n_extension_list_id;
-
-int s2n_extension_list_send(s2n_extension_list_id list_type, struct s2n_connection *conn, struct s2n_stuffer *out);
-int s2n_extension_list_recv(s2n_extension_list_id list_type, struct s2n_connection *conn, struct s2n_stuffer *in);
-
-int s2n_extension_process(const s2n_extension_type *extension_type, struct s2n_connection *conn,
- s2n_parsed_extensions_list *parsed_extension_list);
-int s2n_extension_list_process(s2n_extension_list_id list_type, struct s2n_connection *conn,
- s2n_parsed_extensions_list *parsed_extension_list);
-int s2n_extension_list_parse(struct s2n_stuffer *in, s2n_parsed_extensions_list *parsed_extension_list);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "stuffer/s2n_stuffer.h"
+#include "tls/extensions/s2n_extension_type.h"
+
+#define S2N_PARSED_EXTENSIONS_COUNT S2N_SUPPORTED_EXTENSIONS_COUNT
+
+typedef struct {
+ uint16_t extension_type;
+ struct s2n_blob extension;
+} s2n_parsed_extension;
+
+typedef struct {
+ s2n_parsed_extension parsed_extensions[S2N_PARSED_EXTENSIONS_COUNT];
+ struct s2n_blob raw; /* Needed by some ClientHello APIs */
+} s2n_parsed_extensions_list;
+
+typedef enum {
+ S2N_EXTENSION_LIST_CLIENT_HELLO = 0,
+ S2N_EXTENSION_LIST_SERVER_HELLO_DEFAULT,
+ S2N_EXTENSION_LIST_SERVER_HELLO_TLS13,
+ S2N_EXTENSION_LIST_ENCRYPTED_EXTENSIONS,
+ S2N_EXTENSION_LIST_CERT_REQ,
+ S2N_EXTENSION_LIST_CERTIFICATE,
+ S2N_EXTENSION_LIST_EMPTY,
+ S2N_EXTENSION_LIST_IDS_COUNT,
+} s2n_extension_list_id;
+
+int s2n_extension_list_send(s2n_extension_list_id list_type, struct s2n_connection *conn, struct s2n_stuffer *out);
+int s2n_extension_list_recv(s2n_extension_list_id list_type, struct s2n_connection *conn, struct s2n_stuffer *in);
+
+int s2n_extension_process(const s2n_extension_type *extension_type, struct s2n_connection *conn,
+ s2n_parsed_extensions_list *parsed_extension_list);
+int s2n_extension_list_process(s2n_extension_list_id list_type, struct s2n_connection *conn,
+ s2n_parsed_extensions_list *parsed_extension_list);
+int s2n_extension_list_parse(struct s2n_stuffer *in, s2n_parsed_extensions_list *parsed_extension_list);
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 a961692f92..040c57a16c 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.c
@@ -1,212 +1,212 @@
-/*
- * 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 <s2n.h>
-
-#include "error/s2n_errno.h"
-#include "tls/extensions/s2n_extension_type.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_tls13.h"
-#include "utils/s2n_bitmap.h"
-#include "utils/s2n_safety.h"
-
-#define TLS_EXTENSION_DATA_LENGTH_BYTES 2
-
-/* Because there are 65536 possible extension IANAs, we will only
- * put the lowest (and most common) in a lookup table to conserve space. */
-#define S2N_MAX_INDEXED_EXTENSION_IANA 60
-
-const s2n_extension_type_id s2n_unsupported_extension = S2N_SUPPORTED_EXTENSIONS_COUNT;
-s2n_extension_type_id s2n_extension_ianas_to_ids[S2N_MAX_INDEXED_EXTENSION_IANA];
-
-int s2n_extension_type_init()
-{
- /* Initialize to s2n_unsupported_extension */
- for (int i = 0; i < S2N_MAX_INDEXED_EXTENSION_IANA; i++) {
- s2n_extension_ianas_to_ids[i] = s2n_unsupported_extension;
- }
-
- /* Reverse the mapping */
- for (int i = 0; i < S2N_SUPPORTED_EXTENSIONS_COUNT; i++) {
- uint16_t iana_value = s2n_supported_extensions[i];
- if (iana_value < S2N_MAX_INDEXED_EXTENSION_IANA) {
- s2n_extension_ianas_to_ids[iana_value] = i;
- }
- }
-
- return S2N_SUCCESS;
-}
-
-/* Convert the IANA value (which ranges from 0->65535) to an id with a more
- * constrained range. That id can be used for bitfields, array indexes, etc.
- * to avoid allocating too much memory. */
-s2n_extension_type_id s2n_extension_iana_value_to_id(const uint16_t iana_value)
-{
- /* Check the lookup table */
- if (iana_value < S2N_MAX_INDEXED_EXTENSION_IANA) {
- return s2n_extension_ianas_to_ids[iana_value];
- }
-
- /* Fall back to the full list. We can handle this more
- * efficiently later if our extension list gets long. */
- for (int i = 0; i < S2N_SUPPORTED_EXTENSIONS_COUNT; i++) {
- if (s2n_supported_extensions[i] == iana_value) {
- return i;
- }
- }
-
- return s2n_unsupported_extension;
-}
-
-int s2n_extension_supported_iana_value_to_id(const uint16_t iana_value, s2n_extension_type_id *internal_id)
-{
- notnull_check(internal_id);
-
- *internal_id = s2n_extension_iana_value_to_id(iana_value);
- S2N_ERROR_IF(*internal_id == s2n_unsupported_extension, S2N_ERR_UNRECOGNIZED_EXTENSION);
- return S2N_SUCCESS;
-}
-
-int s2n_extension_send(const s2n_extension_type *extension_type, struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- notnull_check(extension_type);
- notnull_check(extension_type->should_send);
- notnull_check(extension_type->send);
- notnull_check(conn);
-
- s2n_extension_type_id extension_id;
- GUARD(s2n_extension_supported_iana_value_to_id(extension_type->iana_value, &extension_id));
-
- /* Do not send response if request not received. */
- if (extension_type->is_response &&
- !S2N_CBIT_TEST(conn->extension_requests_received, extension_id)) {
- return S2N_SUCCESS;
- }
-
- /* Check if we need to send. Some extensions are only sent if specific conditions are met. */
- if (!extension_type->should_send(conn)) {
- return S2N_SUCCESS;
- }
-
- /* Write extension type */
- GUARD(s2n_stuffer_write_uint16(out, extension_type->iana_value));
-
- /* Reserve space for extension size */
- struct s2n_stuffer_reservation extension_size_bytes = {0};
- GUARD(s2n_stuffer_reserve_uint16(out, &extension_size_bytes));
-
- /* Write extension data */
- GUARD(extension_type->send(conn, out));
-
- /* Record extension size */
- GUARD(s2n_stuffer_write_vector_size(&extension_size_bytes));
-
- /* Set request bit flag */
- if (!extension_type->is_response) {
- S2N_CBIT_SET(conn->extension_requests_sent, extension_id);
- }
-
- return S2N_SUCCESS;
-}
-
-int s2n_extension_recv(const s2n_extension_type *extension_type, struct s2n_connection *conn, struct s2n_stuffer *in)
-{
- notnull_check(extension_type);
- notnull_check(extension_type->recv);
- notnull_check(conn);
-
- s2n_extension_type_id extension_id;
- GUARD(s2n_extension_supported_iana_value_to_id(extension_type->iana_value, &extension_id));
-
- /* Do not accept a response if we did not send a request */
- if(extension_type->is_response &&
- !S2N_CBIT_TEST(conn->extension_requests_sent, extension_id)) {
- S2N_ERROR(S2N_ERR_UNSUPPORTED_EXTENSION);
- }
-
- GUARD(extension_type->recv(conn, in));
-
- /* Set request bit flag */
- if (!extension_type->is_response) {
- S2N_CBIT_SET(conn->extension_requests_received, extension_id);
- }
-
- return S2N_SUCCESS;
-}
-
-int s2n_extension_is_missing(const s2n_extension_type *extension_type, struct s2n_connection *conn)
-{
- notnull_check(extension_type);
- notnull_check(extension_type->if_missing);
- notnull_check(conn);
-
- s2n_extension_type_id extension_id;
- GUARD(s2n_extension_supported_iana_value_to_id(extension_type->iana_value, &extension_id));
-
- /* Do not consider an extension missing if we did not send a request */
- if(extension_type->is_response &&
- !S2N_CBIT_TEST(conn->extension_requests_sent, extension_id)) {
- return S2N_SUCCESS;
- }
-
- GUARD(extension_type->if_missing(conn));
-
- return S2N_SUCCESS;
-}
-
-int s2n_extension_send_unimplemented(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- S2N_ERROR(S2N_ERR_UNIMPLEMENTED);
-}
-
-int s2n_extension_recv_unimplemented(struct s2n_connection *conn, struct s2n_stuffer *in)
-{
- S2N_ERROR(S2N_ERR_UNIMPLEMENTED);
-}
-
-int s2n_extension_send_noop(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- return S2N_SUCCESS;
-}
-
-int s2n_extension_recv_noop(struct s2n_connection *conn, struct s2n_stuffer *in)
-{
- return S2N_SUCCESS;
-}
-
-bool s2n_extension_always_send(struct s2n_connection *conn)
-{
- return true;
-}
-
-bool s2n_extension_never_send(struct s2n_connection *conn)
-{
- return false;
-}
-
-bool s2n_extension_send_if_tls13_connection(struct s2n_connection *conn)
-{
- return s2n_connection_get_protocol_version(conn) >= S2N_TLS13;
-}
-
-int s2n_extension_error_if_missing(struct s2n_connection *conn)
-{
- S2N_ERROR(S2N_ERR_MISSING_EXTENSION);
-}
-
-int s2n_extension_noop_if_missing(struct s2n_connection *conn)
-{
- return S2N_SUCCESS;
-}
+/*
+ * 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 <s2n.h>
+
+#include "error/s2n_errno.h"
+#include "tls/extensions/s2n_extension_type.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_tls13.h"
+#include "utils/s2n_bitmap.h"
+#include "utils/s2n_safety.h"
+
+#define TLS_EXTENSION_DATA_LENGTH_BYTES 2
+
+/* Because there are 65536 possible extension IANAs, we will only
+ * put the lowest (and most common) in a lookup table to conserve space. */
+#define S2N_MAX_INDEXED_EXTENSION_IANA 60
+
+const s2n_extension_type_id s2n_unsupported_extension = S2N_SUPPORTED_EXTENSIONS_COUNT;
+s2n_extension_type_id s2n_extension_ianas_to_ids[S2N_MAX_INDEXED_EXTENSION_IANA];
+
+int s2n_extension_type_init()
+{
+ /* Initialize to s2n_unsupported_extension */
+ for (int i = 0; i < S2N_MAX_INDEXED_EXTENSION_IANA; i++) {
+ s2n_extension_ianas_to_ids[i] = s2n_unsupported_extension;
+ }
+
+ /* Reverse the mapping */
+ for (int i = 0; i < S2N_SUPPORTED_EXTENSIONS_COUNT; i++) {
+ uint16_t iana_value = s2n_supported_extensions[i];
+ if (iana_value < S2N_MAX_INDEXED_EXTENSION_IANA) {
+ s2n_extension_ianas_to_ids[iana_value] = i;
+ }
+ }
+
+ return S2N_SUCCESS;
+}
+
+/* Convert the IANA value (which ranges from 0->65535) to an id with a more
+ * constrained range. That id can be used for bitfields, array indexes, etc.
+ * to avoid allocating too much memory. */
+s2n_extension_type_id s2n_extension_iana_value_to_id(const uint16_t iana_value)
+{
+ /* Check the lookup table */
+ if (iana_value < S2N_MAX_INDEXED_EXTENSION_IANA) {
+ return s2n_extension_ianas_to_ids[iana_value];
+ }
+
+ /* Fall back to the full list. We can handle this more
+ * efficiently later if our extension list gets long. */
+ for (int i = 0; i < S2N_SUPPORTED_EXTENSIONS_COUNT; i++) {
+ if (s2n_supported_extensions[i] == iana_value) {
+ return i;
+ }
+ }
+
+ return s2n_unsupported_extension;
+}
+
+int s2n_extension_supported_iana_value_to_id(const uint16_t iana_value, s2n_extension_type_id *internal_id)
+{
+ notnull_check(internal_id);
+
+ *internal_id = s2n_extension_iana_value_to_id(iana_value);
+ S2N_ERROR_IF(*internal_id == s2n_unsupported_extension, S2N_ERR_UNRECOGNIZED_EXTENSION);
+ return S2N_SUCCESS;
+}
+
+int s2n_extension_send(const s2n_extension_type *extension_type, struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ notnull_check(extension_type);
+ notnull_check(extension_type->should_send);
+ notnull_check(extension_type->send);
+ notnull_check(conn);
+
+ s2n_extension_type_id extension_id;
+ GUARD(s2n_extension_supported_iana_value_to_id(extension_type->iana_value, &extension_id));
+
+ /* Do not send response if request not received. */
+ if (extension_type->is_response &&
+ !S2N_CBIT_TEST(conn->extension_requests_received, extension_id)) {
+ return S2N_SUCCESS;
+ }
+
+ /* Check if we need to send. Some extensions are only sent if specific conditions are met. */
+ if (!extension_type->should_send(conn)) {
+ return S2N_SUCCESS;
+ }
+
+ /* Write extension type */
+ GUARD(s2n_stuffer_write_uint16(out, extension_type->iana_value));
+
+ /* Reserve space for extension size */
+ struct s2n_stuffer_reservation extension_size_bytes = {0};
+ GUARD(s2n_stuffer_reserve_uint16(out, &extension_size_bytes));
+
+ /* Write extension data */
+ GUARD(extension_type->send(conn, out));
+
+ /* Record extension size */
+ GUARD(s2n_stuffer_write_vector_size(&extension_size_bytes));
+
+ /* Set request bit flag */
+ if (!extension_type->is_response) {
+ S2N_CBIT_SET(conn->extension_requests_sent, extension_id);
+ }
+
+ return S2N_SUCCESS;
+}
+
+int s2n_extension_recv(const s2n_extension_type *extension_type, struct s2n_connection *conn, struct s2n_stuffer *in)
+{
+ notnull_check(extension_type);
+ notnull_check(extension_type->recv);
+ notnull_check(conn);
+
+ s2n_extension_type_id extension_id;
+ GUARD(s2n_extension_supported_iana_value_to_id(extension_type->iana_value, &extension_id));
+
+ /* Do not accept a response if we did not send a request */
+ if(extension_type->is_response &&
+ !S2N_CBIT_TEST(conn->extension_requests_sent, extension_id)) {
+ S2N_ERROR(S2N_ERR_UNSUPPORTED_EXTENSION);
+ }
+
+ GUARD(extension_type->recv(conn, in));
+
+ /* Set request bit flag */
+ if (!extension_type->is_response) {
+ S2N_CBIT_SET(conn->extension_requests_received, extension_id);
+ }
+
+ return S2N_SUCCESS;
+}
+
+int s2n_extension_is_missing(const s2n_extension_type *extension_type, struct s2n_connection *conn)
+{
+ notnull_check(extension_type);
+ notnull_check(extension_type->if_missing);
+ notnull_check(conn);
+
+ s2n_extension_type_id extension_id;
+ GUARD(s2n_extension_supported_iana_value_to_id(extension_type->iana_value, &extension_id));
+
+ /* Do not consider an extension missing if we did not send a request */
+ if(extension_type->is_response &&
+ !S2N_CBIT_TEST(conn->extension_requests_sent, extension_id)) {
+ return S2N_SUCCESS;
+ }
+
+ GUARD(extension_type->if_missing(conn));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_extension_send_unimplemented(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ S2N_ERROR(S2N_ERR_UNIMPLEMENTED);
+}
+
+int s2n_extension_recv_unimplemented(struct s2n_connection *conn, struct s2n_stuffer *in)
+{
+ S2N_ERROR(S2N_ERR_UNIMPLEMENTED);
+}
+
+int s2n_extension_send_noop(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ return S2N_SUCCESS;
+}
+
+int s2n_extension_recv_noop(struct s2n_connection *conn, struct s2n_stuffer *in)
+{
+ return S2N_SUCCESS;
+}
+
+bool s2n_extension_always_send(struct s2n_connection *conn)
+{
+ return true;
+}
+
+bool s2n_extension_never_send(struct s2n_connection *conn)
+{
+ return false;
+}
+
+bool s2n_extension_send_if_tls13_connection(struct s2n_connection *conn)
+{
+ return s2n_connection_get_protocol_version(conn) >= S2N_TLS13;
+}
+
+int s2n_extension_error_if_missing(struct s2n_connection *conn)
+{
+ S2N_ERROR(S2N_ERR_MISSING_EXTENSION);
+}
+
+int s2n_extension_noop_if_missing(struct s2n_connection *conn)
+{
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.h
index 22e01b2005..674c8e63dd 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.h
@@ -1,99 +1,99 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <stdbool.h>
-
-#include "stuffer/s2n_stuffer.h"
-#include "tls/s2n_tls_parameters.h"
-
-#define S2N_EXTENSION_TYPE_FIELD_LENGTH 2
-#define S2N_EXTENSION_LENGTH_FIELD_LENGTH 2
-
-/* The number of extensions supported by S2N */
-#define S2N_SUPPORTED_EXTENSIONS_COUNT (sizeof(s2n_supported_extensions) / sizeof(s2n_supported_extensions[0]))
-
-/* The number of bytes needed to assign 1 bit to every supported extension.
- * The +1 is necessary to handle any remainder left over when dividing. */
-#define S2N_SUPPORTED_EXTENSIONS_BITFIELD_LEN ((S2N_SUPPORTED_EXTENSIONS_COUNT / sizeof(char)) + 1)
-
-struct s2n_connection;
-typedef struct {
- uint16_t iana_value;
- unsigned is_response:1;
-
- int (*send) (struct s2n_connection *conn, struct s2n_stuffer *out);
- int (*recv) (struct s2n_connection *conn, struct s2n_stuffer *in);
-
- /* Returns true or false to indicate whether the extension should be sent */
- bool (*should_send) (struct s2n_connection *conn);
-
- /* Handler called if an extension is not received */
- int (*if_missing) (struct s2n_connection *conn);
-} s2n_extension_type;
-
-static const uint16_t s2n_supported_extensions[] = {
- TLS_EXTENSION_RENEGOTIATION_INFO,
- TLS_EXTENSION_PQ_KEM_PARAMETERS,
- TLS_EXTENSION_SERVER_NAME,
- TLS_EXTENSION_MAX_FRAG_LEN,
- TLS_EXTENSION_STATUS_REQUEST,
- TLS_EXTENSION_SUPPORTED_GROUPS,
- TLS_EXTENSION_EC_POINT_FORMATS,
- TLS_EXTENSION_SIGNATURE_ALGORITHMS,
- TLS_EXTENSION_ALPN,
- TLS_EXTENSION_SCT_LIST,
- TLS_EXTENSION_SESSION_TICKET,
- TLS_EXTENSION_SUPPORTED_VERSIONS,
- TLS_EXTENSION_KEY_SHARE,
- TLS_EXTENSION_COOKIE,
- TLS_QUIC_TRANSPORT_PARAMETERS,
- TLS_EXTENSION_PRE_SHARED_KEY,
-};
-
-typedef char s2n_extension_bitfield[S2N_SUPPORTED_EXTENSIONS_BITFIELD_LEN];
-
-typedef uint8_t s2n_extension_type_id;
-extern const s2n_extension_type_id s2n_unsupported_extension;
-
-int s2n_extension_send(const s2n_extension_type *extension_type, struct s2n_connection *conn, struct s2n_stuffer *out);
-int s2n_extension_recv(const s2n_extension_type *extension_type, struct s2n_connection *conn, struct s2n_stuffer *in);
-int s2n_extension_is_missing(const s2n_extension_type *extension_type, struct s2n_connection *conn);
-
-/* Map from TLS IANA value to internal s2n id.
- * All possible IANA values is a large space, so using an internal id gives us more
- * flexibility when using arrays / bitfields / etc. */
-int s2n_extension_supported_iana_value_to_id(const uint16_t iana_value, s2n_extension_type_id *internal_id);
-
-/* Initializer */
-int s2n_extension_type_init();
-
-/* Common implementations for send */
-int s2n_extension_send_unimplemented(struct s2n_connection *conn, struct s2n_stuffer *out);
-int s2n_extension_send_noop(struct s2n_connection *conn, struct s2n_stuffer *out);
-
-/* Common implementations for recv */
-int s2n_extension_recv_unimplemented(struct s2n_connection *conn, struct s2n_stuffer *in);
-int s2n_extension_recv_noop(struct s2n_connection *conn, struct s2n_stuffer *out);
-
-/* Common implementations for should_send */
-bool s2n_extension_always_send(struct s2n_connection *conn);
-bool s2n_extension_never_send(struct s2n_connection *conn);
-bool s2n_extension_send_if_tls13_connection(struct s2n_connection *conn);
-
-/* Common implementations for if_missing */
-int s2n_extension_error_if_missing(struct s2n_connection *conn);
-int s2n_extension_noop_if_missing(struct s2n_connection *conn);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stdbool.h>
+
+#include "stuffer/s2n_stuffer.h"
+#include "tls/s2n_tls_parameters.h"
+
+#define S2N_EXTENSION_TYPE_FIELD_LENGTH 2
+#define S2N_EXTENSION_LENGTH_FIELD_LENGTH 2
+
+/* The number of extensions supported by S2N */
+#define S2N_SUPPORTED_EXTENSIONS_COUNT (sizeof(s2n_supported_extensions) / sizeof(s2n_supported_extensions[0]))
+
+/* The number of bytes needed to assign 1 bit to every supported extension.
+ * The +1 is necessary to handle any remainder left over when dividing. */
+#define S2N_SUPPORTED_EXTENSIONS_BITFIELD_LEN ((S2N_SUPPORTED_EXTENSIONS_COUNT / sizeof(char)) + 1)
+
+struct s2n_connection;
+typedef struct {
+ uint16_t iana_value;
+ unsigned is_response:1;
+
+ int (*send) (struct s2n_connection *conn, struct s2n_stuffer *out);
+ int (*recv) (struct s2n_connection *conn, struct s2n_stuffer *in);
+
+ /* Returns true or false to indicate whether the extension should be sent */
+ bool (*should_send) (struct s2n_connection *conn);
+
+ /* Handler called if an extension is not received */
+ int (*if_missing) (struct s2n_connection *conn);
+} s2n_extension_type;
+
+static const uint16_t s2n_supported_extensions[] = {
+ TLS_EXTENSION_RENEGOTIATION_INFO,
+ TLS_EXTENSION_PQ_KEM_PARAMETERS,
+ TLS_EXTENSION_SERVER_NAME,
+ TLS_EXTENSION_MAX_FRAG_LEN,
+ TLS_EXTENSION_STATUS_REQUEST,
+ TLS_EXTENSION_SUPPORTED_GROUPS,
+ TLS_EXTENSION_EC_POINT_FORMATS,
+ TLS_EXTENSION_SIGNATURE_ALGORITHMS,
+ TLS_EXTENSION_ALPN,
+ TLS_EXTENSION_SCT_LIST,
+ TLS_EXTENSION_SESSION_TICKET,
+ TLS_EXTENSION_SUPPORTED_VERSIONS,
+ TLS_EXTENSION_KEY_SHARE,
+ TLS_EXTENSION_COOKIE,
+ TLS_QUIC_TRANSPORT_PARAMETERS,
+ TLS_EXTENSION_PRE_SHARED_KEY,
+};
+
+typedef char s2n_extension_bitfield[S2N_SUPPORTED_EXTENSIONS_BITFIELD_LEN];
+
+typedef uint8_t s2n_extension_type_id;
+extern const s2n_extension_type_id s2n_unsupported_extension;
+
+int s2n_extension_send(const s2n_extension_type *extension_type, struct s2n_connection *conn, struct s2n_stuffer *out);
+int s2n_extension_recv(const s2n_extension_type *extension_type, struct s2n_connection *conn, struct s2n_stuffer *in);
+int s2n_extension_is_missing(const s2n_extension_type *extension_type, struct s2n_connection *conn);
+
+/* Map from TLS IANA value to internal s2n id.
+ * All possible IANA values is a large space, so using an internal id gives us more
+ * flexibility when using arrays / bitfields / etc. */
+int s2n_extension_supported_iana_value_to_id(const uint16_t iana_value, s2n_extension_type_id *internal_id);
+
+/* Initializer */
+int s2n_extension_type_init();
+
+/* Common implementations for send */
+int s2n_extension_send_unimplemented(struct s2n_connection *conn, struct s2n_stuffer *out);
+int s2n_extension_send_noop(struct s2n_connection *conn, struct s2n_stuffer *out);
+
+/* Common implementations for recv */
+int s2n_extension_recv_unimplemented(struct s2n_connection *conn, struct s2n_stuffer *in);
+int s2n_extension_recv_noop(struct s2n_connection *conn, struct s2n_stuffer *out);
+
+/* Common implementations for should_send */
+bool s2n_extension_always_send(struct s2n_connection *conn);
+bool s2n_extension_never_send(struct s2n_connection *conn);
+bool s2n_extension_send_if_tls13_connection(struct s2n_connection *conn);
+
+/* Common implementations for if_missing */
+int s2n_extension_error_if_missing(struct s2n_connection *conn);
+int s2n_extension_noop_if_missing(struct s2n_connection *conn);
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.c
index 86e55bbd8a..ed4c196f59 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.c
@@ -1,121 +1,121 @@
-/*
- * 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 <s2n.h>
-
-#include "tls/extensions/s2n_extension_type_lists.h"
-#include "tls/s2n_connection.h"
-
-#include "tls/extensions/s2n_cookie.h"
-#include "tls/extensions/s2n_client_supported_versions.h"
-#include "tls/extensions/s2n_client_signature_algorithms.h"
-#include "tls/extensions/s2n_client_max_frag_len.h"
-#include "tls/extensions/s2n_client_session_ticket.h"
-#include "tls/extensions/s2n_client_server_name.h"
-#include "tls/extensions/s2n_client_alpn.h"
-#include "tls/extensions/s2n_client_status_request.h"
-#include "tls/extensions/s2n_client_key_share.h"
-#include "tls/extensions/s2n_client_sct_list.h"
-#include "tls/extensions/s2n_client_supported_groups.h"
-#include "tls/extensions/s2n_client_pq_kem.h"
-#include "tls/extensions/s2n_client_psk.h"
-#include "tls/extensions/s2n_client_renegotiation_info.h"
-#include "tls/extensions/s2n_ec_point_format.h"
-#include "tls/extensions/s2n_quic_transport_params.h"
-#include "tls/extensions/s2n_server_certificate_status.h"
-#include "tls/extensions/s2n_server_renegotiation_info.h"
-#include "tls/extensions/s2n_server_alpn.h"
-#include "tls/extensions/s2n_server_status_request.h"
-#include "tls/extensions/s2n_server_sct_list.h"
-#include "tls/extensions/s2n_server_max_fragment_length.h"
-#include "tls/extensions/s2n_server_session_ticket.h"
-#include "tls/extensions/s2n_server_server_name.h"
-#include "tls/extensions/s2n_server_signature_algorithms.h"
-#include "tls/extensions/s2n_server_supported_versions.h"
-#include "tls/extensions/s2n_server_key_share.h"
-
-static const s2n_extension_type *const client_hello_extensions[] = {
- &s2n_client_supported_versions_extension,
- &s2n_client_key_share_extension,
- &s2n_client_signature_algorithms_extension,
- &s2n_client_server_name_extension,
- &s2n_client_alpn_extension,
- &s2n_client_status_request_extension,
- &s2n_client_sct_list_extension,
- &s2n_client_max_frag_len_extension,
- &s2n_client_session_ticket_extension,
- &s2n_client_supported_groups_extension,
- &s2n_client_ec_point_format_extension,
- &s2n_client_pq_kem_extension,
- &s2n_client_renegotiation_info_extension,
- &s2n_client_cookie_extension,
- &s2n_quic_transport_parameters_extension,
- &s2n_client_psk_extension /* MUST be last */
-};
-
-static const s2n_extension_type *const tls12_server_hello_extensions[] = {
- &s2n_server_supported_versions_extension,
- &s2n_server_server_name_extension,
- &s2n_server_ec_point_format_extension,
- &s2n_server_renegotiation_info_extension,
- &s2n_server_alpn_extension,
- &s2n_server_status_request_extension,
- &s2n_server_sct_list_extension,
- &s2n_server_max_fragment_length_extension,
- &s2n_server_session_ticket_extension,
-};
-
-static const s2n_extension_type *const tls13_server_hello_extensions[] = {
- &s2n_server_supported_versions_extension,
- &s2n_server_key_share_extension,
- &s2n_server_cookie_extension,
-};
-
-static const s2n_extension_type *const encrypted_extensions[] = {
- &s2n_server_server_name_extension,
- &s2n_server_max_fragment_length_extension,
- &s2n_server_alpn_extension,
- &s2n_quic_transport_parameters_extension,
-};
-
-static const s2n_extension_type *const cert_req_extensions[] = {
- &s2n_server_signature_algorithms_extension,
-};
-
-static const s2n_extension_type *const certificate_extensions[] = {
- &s2n_tls13_server_status_request_extension,
- &s2n_server_sct_list_extension,
-};
-
-#define S2N_EXTENSION_LIST(list) { .extension_types = (list), .count = s2n_array_len(list) }
-
-static s2n_extension_type_list extension_lists[] = {
- [S2N_EXTENSION_LIST_CLIENT_HELLO] = S2N_EXTENSION_LIST(client_hello_extensions),
- [S2N_EXTENSION_LIST_SERVER_HELLO_DEFAULT] = S2N_EXTENSION_LIST(tls12_server_hello_extensions),
- [S2N_EXTENSION_LIST_SERVER_HELLO_TLS13] = S2N_EXTENSION_LIST(tls13_server_hello_extensions),
- [S2N_EXTENSION_LIST_ENCRYPTED_EXTENSIONS] = S2N_EXTENSION_LIST(encrypted_extensions),
- [S2N_EXTENSION_LIST_CERT_REQ] = S2N_EXTENSION_LIST(cert_req_extensions),
- [S2N_EXTENSION_LIST_CERTIFICATE] = S2N_EXTENSION_LIST(certificate_extensions),
- [S2N_EXTENSION_LIST_EMPTY] = { .extension_types = NULL, .count = 0 },
-};
-
-int s2n_extension_type_list_get(s2n_extension_list_id list_type, s2n_extension_type_list **extension_list)
-{
- notnull_check(extension_list);
- lt_check(list_type, s2n_array_len(extension_lists));
-
- *extension_list = &extension_lists[list_type];
- return S2N_SUCCESS;
-}
+/*
+ * 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 <s2n.h>
+
+#include "tls/extensions/s2n_extension_type_lists.h"
+#include "tls/s2n_connection.h"
+
+#include "tls/extensions/s2n_cookie.h"
+#include "tls/extensions/s2n_client_supported_versions.h"
+#include "tls/extensions/s2n_client_signature_algorithms.h"
+#include "tls/extensions/s2n_client_max_frag_len.h"
+#include "tls/extensions/s2n_client_session_ticket.h"
+#include "tls/extensions/s2n_client_server_name.h"
+#include "tls/extensions/s2n_client_alpn.h"
+#include "tls/extensions/s2n_client_status_request.h"
+#include "tls/extensions/s2n_client_key_share.h"
+#include "tls/extensions/s2n_client_sct_list.h"
+#include "tls/extensions/s2n_client_supported_groups.h"
+#include "tls/extensions/s2n_client_pq_kem.h"
+#include "tls/extensions/s2n_client_psk.h"
+#include "tls/extensions/s2n_client_renegotiation_info.h"
+#include "tls/extensions/s2n_ec_point_format.h"
+#include "tls/extensions/s2n_quic_transport_params.h"
+#include "tls/extensions/s2n_server_certificate_status.h"
+#include "tls/extensions/s2n_server_renegotiation_info.h"
+#include "tls/extensions/s2n_server_alpn.h"
+#include "tls/extensions/s2n_server_status_request.h"
+#include "tls/extensions/s2n_server_sct_list.h"
+#include "tls/extensions/s2n_server_max_fragment_length.h"
+#include "tls/extensions/s2n_server_session_ticket.h"
+#include "tls/extensions/s2n_server_server_name.h"
+#include "tls/extensions/s2n_server_signature_algorithms.h"
+#include "tls/extensions/s2n_server_supported_versions.h"
+#include "tls/extensions/s2n_server_key_share.h"
+
+static const s2n_extension_type *const client_hello_extensions[] = {
+ &s2n_client_supported_versions_extension,
+ &s2n_client_key_share_extension,
+ &s2n_client_signature_algorithms_extension,
+ &s2n_client_server_name_extension,
+ &s2n_client_alpn_extension,
+ &s2n_client_status_request_extension,
+ &s2n_client_sct_list_extension,
+ &s2n_client_max_frag_len_extension,
+ &s2n_client_session_ticket_extension,
+ &s2n_client_supported_groups_extension,
+ &s2n_client_ec_point_format_extension,
+ &s2n_client_pq_kem_extension,
+ &s2n_client_renegotiation_info_extension,
+ &s2n_client_cookie_extension,
+ &s2n_quic_transport_parameters_extension,
+ &s2n_client_psk_extension /* MUST be last */
+};
+
+static const s2n_extension_type *const tls12_server_hello_extensions[] = {
+ &s2n_server_supported_versions_extension,
+ &s2n_server_server_name_extension,
+ &s2n_server_ec_point_format_extension,
+ &s2n_server_renegotiation_info_extension,
+ &s2n_server_alpn_extension,
+ &s2n_server_status_request_extension,
+ &s2n_server_sct_list_extension,
+ &s2n_server_max_fragment_length_extension,
+ &s2n_server_session_ticket_extension,
+};
+
+static const s2n_extension_type *const tls13_server_hello_extensions[] = {
+ &s2n_server_supported_versions_extension,
+ &s2n_server_key_share_extension,
+ &s2n_server_cookie_extension,
+};
+
+static const s2n_extension_type *const encrypted_extensions[] = {
+ &s2n_server_server_name_extension,
+ &s2n_server_max_fragment_length_extension,
+ &s2n_server_alpn_extension,
+ &s2n_quic_transport_parameters_extension,
+};
+
+static const s2n_extension_type *const cert_req_extensions[] = {
+ &s2n_server_signature_algorithms_extension,
+};
+
+static const s2n_extension_type *const certificate_extensions[] = {
+ &s2n_tls13_server_status_request_extension,
+ &s2n_server_sct_list_extension,
+};
+
+#define S2N_EXTENSION_LIST(list) { .extension_types = (list), .count = s2n_array_len(list) }
+
+static s2n_extension_type_list extension_lists[] = {
+ [S2N_EXTENSION_LIST_CLIENT_HELLO] = S2N_EXTENSION_LIST(client_hello_extensions),
+ [S2N_EXTENSION_LIST_SERVER_HELLO_DEFAULT] = S2N_EXTENSION_LIST(tls12_server_hello_extensions),
+ [S2N_EXTENSION_LIST_SERVER_HELLO_TLS13] = S2N_EXTENSION_LIST(tls13_server_hello_extensions),
+ [S2N_EXTENSION_LIST_ENCRYPTED_EXTENSIONS] = S2N_EXTENSION_LIST(encrypted_extensions),
+ [S2N_EXTENSION_LIST_CERT_REQ] = S2N_EXTENSION_LIST(cert_req_extensions),
+ [S2N_EXTENSION_LIST_CERTIFICATE] = S2N_EXTENSION_LIST(certificate_extensions),
+ [S2N_EXTENSION_LIST_EMPTY] = { .extension_types = NULL, .count = 0 },
+};
+
+int s2n_extension_type_list_get(s2n_extension_list_id list_type, s2n_extension_type_list **extension_list)
+{
+ notnull_check(extension_list);
+ lt_check(list_type, s2n_array_len(extension_lists));
+
+ *extension_list = &extension_lists[list_type];
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.h
index d57cfa2988..114f6ae75e 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.h
@@ -1,26 +1,26 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/extensions/s2n_extension_list.h"
-#include "tls/extensions/s2n_extension_type.h"
-
-typedef struct {
- const s2n_extension_type *const *extension_types;
- const uint8_t count;
-} s2n_extension_type_list;
-
-int s2n_extension_type_list_get(s2n_extension_list_id list_type, s2n_extension_type_list **extension_type_list);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/extensions/s2n_extension_list.h"
+#include "tls/extensions/s2n_extension_type.h"
+
+typedef struct {
+ const s2n_extension_type *const *extension_types;
+ const uint8_t count;
+} s2n_extension_type_list;
+
+int s2n_extension_type_list_get(s2n_extension_list_id list_type, s2n_extension_type_list **extension_type_list);
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_key_share.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_key_share.c
index 0b64096b2f..a91dbfd30b 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_key_share.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_key_share.c
@@ -1,33 +1,33 @@
-/*
- * 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 "tls/extensions/s2n_key_share.h"
-#include "tls/s2n_tls.h"
-#include "utils/s2n_safety.h"
-
-int s2n_ecdhe_parameters_send(struct s2n_ecc_evp_params *ecc_evp_params, struct s2n_stuffer *out)
-{
- notnull_check(out);
- notnull_check(ecc_evp_params);
- notnull_check(ecc_evp_params->negotiated_curve);
-
- GUARD(s2n_stuffer_write_uint16(out, ecc_evp_params->negotiated_curve->iana_id));
- GUARD(s2n_stuffer_write_uint16(out, ecc_evp_params->negotiated_curve->share_size));
-
- GUARD(s2n_ecc_evp_generate_ephemeral_key(ecc_evp_params));
- GUARD(s2n_ecc_evp_write_params_point(ecc_evp_params, out));
-
- return 0;
-}
+/*
+ * 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 "tls/extensions/s2n_key_share.h"
+#include "tls/s2n_tls.h"
+#include "utils/s2n_safety.h"
+
+int s2n_ecdhe_parameters_send(struct s2n_ecc_evp_params *ecc_evp_params, struct s2n_stuffer *out)
+{
+ notnull_check(out);
+ notnull_check(ecc_evp_params);
+ notnull_check(ecc_evp_params->negotiated_curve);
+
+ GUARD(s2n_stuffer_write_uint16(out, ecc_evp_params->negotiated_curve->iana_id));
+ GUARD(s2n_stuffer_write_uint16(out, ecc_evp_params->negotiated_curve->share_size));
+
+ GUARD(s2n_ecc_evp_generate_ephemeral_key(ecc_evp_params));
+ GUARD(s2n_ecc_evp_write_params_point(ecc_evp_params, out));
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_key_share.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_key_share.h
index a29fdd3806..f621d76b52 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_key_share.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_key_share.h
@@ -1,28 +1,28 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "crypto/s2n_ecc_evp.h"
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-#define S2N_SIZE_OF_EXTENSION_TYPE 2
-#define S2N_SIZE_OF_EXTENSION_DATA_SIZE 2
-#define S2N_SIZE_OF_CLIENT_SHARES_SIZE 2
-#define S2N_SIZE_OF_NAMED_GROUP 2
-#define S2N_SIZE_OF_KEY_SHARE_SIZE 2
-
-extern int s2n_ecdhe_parameters_send(struct s2n_ecc_evp_params *ecc_evp_params, struct s2n_stuffer *out);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "crypto/s2n_ecc_evp.h"
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+#define S2N_SIZE_OF_EXTENSION_TYPE 2
+#define S2N_SIZE_OF_EXTENSION_DATA_SIZE 2
+#define S2N_SIZE_OF_CLIENT_SHARES_SIZE 2
+#define S2N_SIZE_OF_NAMED_GROUP 2
+#define S2N_SIZE_OF_KEY_SHARE_SIZE 2
+
+extern int s2n_ecdhe_parameters_send(struct s2n_ecc_evp_params *ecc_evp_params, struct s2n_stuffer *out);
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_quic_transport_params.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_quic_transport_params.c
index 9b6fa1bee3..56f17abc3b 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_quic_transport_params.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_quic_transport_params.c
@@ -1,77 +1,77 @@
-/*
- * 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 "tls/extensions/s2n_quic_transport_params.h"
-
-#include "tls/s2n_connection.h"
-#include "tls/s2n_tls.h"
-
-#include "stuffer/s2n_stuffer.h"
-#include "utils/s2n_safety.h"
-
-/*
- * The quic_transport_params extension is required by the QUIC protocol to
- * negotiate additional connection parameters when using S2N.
- *
- * This extension should not be sent or received unless using S2N with QUIC.
- * S2N treats the extension data as opaque bytes and performs no validation.
- */
-
-static bool s2n_quic_transport_params_should_send(struct s2n_connection *conn)
-{
- return conn && conn->config && conn->config->quic_enabled;
-}
-
-static int s2n_quic_transport_params_if_missing(struct s2n_connection *conn)
-{
- notnull_check(conn);
- notnull_check(conn->config);
- ENSURE_POSIX(!conn->config->quic_enabled, S2N_ERR_MISSING_EXTENSION);
- return S2N_SUCCESS;
-}
-
-static int s2n_quic_transport_params_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- notnull_check(conn);
- notnull_check(out);
-
- if (conn->our_quic_transport_parameters.size) {
- GUARD(s2n_stuffer_write(out, &conn->our_quic_transport_parameters));
- }
- return S2N_SUCCESS;
-}
-
-static int s2n_quic_transport_params_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- notnull_check(conn);
- notnull_check(extension);
- notnull_check(conn->config);
- ENSURE_POSIX(conn->config->quic_enabled, S2N_ERR_UNSUPPORTED_EXTENSION);
-
- if (s2n_stuffer_data_available(extension)) {
- GUARD(s2n_alloc(&conn->peer_quic_transport_parameters, s2n_stuffer_data_available(extension)));
- GUARD(s2n_stuffer_read(extension, &conn->peer_quic_transport_parameters));
- }
- return S2N_SUCCESS;
-}
-
-const s2n_extension_type s2n_quic_transport_parameters_extension = {
- .iana_value = TLS_QUIC_TRANSPORT_PARAMETERS,
- .is_response = false,
- .send = s2n_quic_transport_params_send,
- .recv = s2n_quic_transport_params_recv,
- .should_send = s2n_quic_transport_params_should_send,
- .if_missing = s2n_quic_transport_params_if_missing,
-};
+/*
+ * 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 "tls/extensions/s2n_quic_transport_params.h"
+
+#include "tls/s2n_connection.h"
+#include "tls/s2n_tls.h"
+
+#include "stuffer/s2n_stuffer.h"
+#include "utils/s2n_safety.h"
+
+/*
+ * The quic_transport_params extension is required by the QUIC protocol to
+ * negotiate additional connection parameters when using S2N.
+ *
+ * This extension should not be sent or received unless using S2N with QUIC.
+ * S2N treats the extension data as opaque bytes and performs no validation.
+ */
+
+static bool s2n_quic_transport_params_should_send(struct s2n_connection *conn)
+{
+ return conn && conn->config && conn->config->quic_enabled;
+}
+
+static int s2n_quic_transport_params_if_missing(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+ notnull_check(conn->config);
+ ENSURE_POSIX(!conn->config->quic_enabled, S2N_ERR_MISSING_EXTENSION);
+ return S2N_SUCCESS;
+}
+
+static int s2n_quic_transport_params_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ notnull_check(conn);
+ notnull_check(out);
+
+ if (conn->our_quic_transport_parameters.size) {
+ GUARD(s2n_stuffer_write(out, &conn->our_quic_transport_parameters));
+ }
+ return S2N_SUCCESS;
+}
+
+static int s2n_quic_transport_params_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ notnull_check(conn);
+ notnull_check(extension);
+ notnull_check(conn->config);
+ ENSURE_POSIX(conn->config->quic_enabled, S2N_ERR_UNSUPPORTED_EXTENSION);
+
+ if (s2n_stuffer_data_available(extension)) {
+ GUARD(s2n_alloc(&conn->peer_quic_transport_parameters, s2n_stuffer_data_available(extension)));
+ GUARD(s2n_stuffer_read(extension, &conn->peer_quic_transport_parameters));
+ }
+ return S2N_SUCCESS;
+}
+
+const s2n_extension_type s2n_quic_transport_parameters_extension = {
+ .iana_value = TLS_QUIC_TRANSPORT_PARAMETERS,
+ .is_response = false,
+ .send = s2n_quic_transport_params_send,
+ .recv = s2n_quic_transport_params_recv,
+ .should_send = s2n_quic_transport_params_should_send,
+ .if_missing = s2n_quic_transport_params_if_missing,
+};
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_quic_transport_params.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_quic_transport_params.h
index ed0a73d140..93369b5478 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_quic_transport_params.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_quic_transport_params.h
@@ -1,20 +1,20 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/extensions/s2n_extension_type.h"
-
-extern const s2n_extension_type s2n_quic_transport_parameters_extension;
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/extensions/s2n_extension_type.h"
+
+extern const s2n_extension_type s2n_quic_transport_parameters_extension;
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_alpn.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_alpn.c
index 50dbcf11f9..a1f5ac17cf 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_alpn.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_alpn.c
@@ -1,81 +1,81 @@
-/*
- * 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 "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_safety.h"
-
-#include "tls/s2n_connection.h"
-#include "tls/s2n_tls.h"
-
-#include "tls/extensions/s2n_server_alpn.h"
-
-static bool s2n_alpn_should_send(struct s2n_connection *conn);
-static int s2n_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-static int s2n_alpn_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_server_alpn_extension = {
- .iana_value = TLS_EXTENSION_ALPN,
- .is_response = true,
- .send = s2n_alpn_send,
- .recv = s2n_alpn_recv,
- .should_send = s2n_alpn_should_send,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static bool s2n_alpn_should_send(struct s2n_connection *conn)
-{
- return conn && strlen(conn->application_protocol) > 0;
-}
-
-static int s2n_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- notnull_check(conn);
- const uint8_t application_protocol_len = strlen(conn->application_protocol);
-
- /* Size of protocol name list */
- GUARD(s2n_stuffer_write_uint16(out, application_protocol_len + sizeof(uint8_t)));
-
- /* Single entry in protocol name list */
- GUARD(s2n_stuffer_write_uint8(out, application_protocol_len));
- GUARD(s2n_stuffer_write_bytes(out, (uint8_t *) conn->application_protocol, application_protocol_len));
-
- return S2N_SUCCESS;
-}
-
-static int s2n_alpn_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- notnull_check(conn);
-
- uint16_t size_of_all;
- GUARD(s2n_stuffer_read_uint16(extension, &size_of_all));
- if (size_of_all > s2n_stuffer_data_available(extension) || size_of_all < 3) {
- /* ignore invalid extension size */
- return S2N_SUCCESS;
- }
-
- uint8_t protocol_len;
- GUARD(s2n_stuffer_read_uint8(extension, &protocol_len));
- lt_check(protocol_len, s2n_array_len(conn->application_protocol));
-
- uint8_t *protocol = s2n_stuffer_raw_read(extension, protocol_len);
- notnull_check(protocol);
-
- /* copy the first protocol name */
- memcpy_check(conn->application_protocol, protocol, protocol_len);
- conn->application_protocol[protocol_len] = '\0';
-
- return S2N_SUCCESS;
-}
+/*
+ * 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 "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_safety.h"
+
+#include "tls/s2n_connection.h"
+#include "tls/s2n_tls.h"
+
+#include "tls/extensions/s2n_server_alpn.h"
+
+static bool s2n_alpn_should_send(struct s2n_connection *conn);
+static int s2n_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+static int s2n_alpn_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_server_alpn_extension = {
+ .iana_value = TLS_EXTENSION_ALPN,
+ .is_response = true,
+ .send = s2n_alpn_send,
+ .recv = s2n_alpn_recv,
+ .should_send = s2n_alpn_should_send,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static bool s2n_alpn_should_send(struct s2n_connection *conn)
+{
+ return conn && strlen(conn->application_protocol) > 0;
+}
+
+static int s2n_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ notnull_check(conn);
+ const uint8_t application_protocol_len = strlen(conn->application_protocol);
+
+ /* Size of protocol name list */
+ GUARD(s2n_stuffer_write_uint16(out, application_protocol_len + sizeof(uint8_t)));
+
+ /* Single entry in protocol name list */
+ GUARD(s2n_stuffer_write_uint8(out, application_protocol_len));
+ GUARD(s2n_stuffer_write_bytes(out, (uint8_t *) conn->application_protocol, application_protocol_len));
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_alpn_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ notnull_check(conn);
+
+ uint16_t size_of_all;
+ GUARD(s2n_stuffer_read_uint16(extension, &size_of_all));
+ if (size_of_all > s2n_stuffer_data_available(extension) || size_of_all < 3) {
+ /* ignore invalid extension size */
+ return S2N_SUCCESS;
+ }
+
+ uint8_t protocol_len;
+ GUARD(s2n_stuffer_read_uint8(extension, &protocol_len));
+ lt_check(protocol_len, s2n_array_len(conn->application_protocol));
+
+ uint8_t *protocol = s2n_stuffer_raw_read(extension, protocol_len);
+ notnull_check(protocol);
+
+ /* copy the first protocol name */
+ memcpy_check(conn->application_protocol, protocol, protocol_len);
+ conn->application_protocol[protocol_len] = '\0';
+
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_alpn.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_alpn.h
index 5e5564dd54..ccdf3fce9c 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_alpn.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_alpn.h
@@ -1,20 +1,20 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/extensions/s2n_extension_type.h"
-
-extern const s2n_extension_type s2n_server_alpn_extension;
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/extensions/s2n_extension_type.h"
+
+extern const s2n_extension_type s2n_server_alpn_extension;
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_certificate_status.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_certificate_status.c
index a362b446af..486835689c 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_certificate_status.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_certificate_status.c
@@ -1,80 +1,80 @@
-/*
- * 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 "tls/s2n_config.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_x509_validator.h"
-#include "tls/extensions/s2n_server_certificate_status.h"
-#include "utils/s2n_safety.h"
-
-#define U24_SIZE 3
-
-/* In TLS 1.3, a response to a Status Request extension is sent as an extension with
- * status request as well as the OCSP response. This contrasts to TLS 1.2 where
- * the OCSP response is sent in the Certificate Status handshake message */
-
-static bool s2n_tls13_server_status_request_should_send(struct s2n_connection *conn);
-
-const s2n_extension_type s2n_tls13_server_status_request_extension = {
- .iana_value = TLS_EXTENSION_STATUS_REQUEST,
- .is_response = true,
- .send = s2n_server_certificate_status_send,
- .recv = s2n_server_certificate_status_recv,
- .should_send = s2n_tls13_server_status_request_should_send,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static bool s2n_tls13_server_status_request_should_send(struct s2n_connection *conn)
-{
- return s2n_server_can_send_ocsp(conn);
-}
-
-int s2n_server_certificate_status_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- notnull_check(conn);
- struct s2n_blob *ocsp_status = &conn->handshake_params.our_chain_and_key->ocsp_status;
- notnull_check(ocsp_status);
-
- GUARD(s2n_stuffer_write_uint8(out, (uint8_t) S2N_STATUS_REQUEST_OCSP));
- GUARD(s2n_stuffer_write_uint24(out, ocsp_status->size));
- GUARD(s2n_stuffer_write(out, ocsp_status));
-
- return S2N_SUCCESS;
-}
-
-int s2n_server_certificate_status_recv(struct s2n_connection *conn, struct s2n_stuffer *in)
-{
- notnull_check(conn);
-
- uint8_t type;
- GUARD(s2n_stuffer_read_uint8(in, &type));
- if (type != S2N_STATUS_REQUEST_OCSP) {
- /* We only support OCSP */
- return S2N_SUCCESS;
- }
-
- uint32_t status_size;
- GUARD(s2n_stuffer_read_uint24(in, &status_size));
- lte_check(status_size, s2n_stuffer_data_available(in));
-
- GUARD(s2n_realloc(&conn->status_response, status_size));
- GUARD(s2n_stuffer_read_bytes(in, conn->status_response.data, status_size));
-
- GUARD(s2n_x509_validator_validate_cert_stapled_ocsp_response(
- &conn->x509_validator, conn, conn->status_response.data, conn->status_response.size));
-
- return S2N_SUCCESS;
-}
+/*
+ * 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 "tls/s2n_config.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_x509_validator.h"
+#include "tls/extensions/s2n_server_certificate_status.h"
+#include "utils/s2n_safety.h"
+
+#define U24_SIZE 3
+
+/* In TLS 1.3, a response to a Status Request extension is sent as an extension with
+ * status request as well as the OCSP response. This contrasts to TLS 1.2 where
+ * the OCSP response is sent in the Certificate Status handshake message */
+
+static bool s2n_tls13_server_status_request_should_send(struct s2n_connection *conn);
+
+const s2n_extension_type s2n_tls13_server_status_request_extension = {
+ .iana_value = TLS_EXTENSION_STATUS_REQUEST,
+ .is_response = true,
+ .send = s2n_server_certificate_status_send,
+ .recv = s2n_server_certificate_status_recv,
+ .should_send = s2n_tls13_server_status_request_should_send,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static bool s2n_tls13_server_status_request_should_send(struct s2n_connection *conn)
+{
+ return s2n_server_can_send_ocsp(conn);
+}
+
+int s2n_server_certificate_status_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ notnull_check(conn);
+ struct s2n_blob *ocsp_status = &conn->handshake_params.our_chain_and_key->ocsp_status;
+ notnull_check(ocsp_status);
+
+ GUARD(s2n_stuffer_write_uint8(out, (uint8_t) S2N_STATUS_REQUEST_OCSP));
+ GUARD(s2n_stuffer_write_uint24(out, ocsp_status->size));
+ GUARD(s2n_stuffer_write(out, ocsp_status));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_server_certificate_status_recv(struct s2n_connection *conn, struct s2n_stuffer *in)
+{
+ notnull_check(conn);
+
+ uint8_t type;
+ GUARD(s2n_stuffer_read_uint8(in, &type));
+ if (type != S2N_STATUS_REQUEST_OCSP) {
+ /* We only support OCSP */
+ return S2N_SUCCESS;
+ }
+
+ uint32_t status_size;
+ GUARD(s2n_stuffer_read_uint24(in, &status_size));
+ lte_check(status_size, s2n_stuffer_data_available(in));
+
+ GUARD(s2n_realloc(&conn->status_response, status_size));
+ GUARD(s2n_stuffer_read_bytes(in, conn->status_response.data, status_size));
+
+ GUARD(s2n_x509_validator_validate_cert_stapled_ocsp_response(
+ &conn->x509_validator, conn, conn->status_response.data, conn->status_response.size));
+
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_certificate_status.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_certificate_status.h
index ad5d1f380f..0f5ef18742 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_certificate_status.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_certificate_status.h
@@ -1,25 +1,25 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/extensions/s2n_extension_type.h"
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-extern const s2n_extension_type s2n_tls13_server_status_request_extension;
-
-int s2n_server_certificate_status_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-int s2n_server_certificate_status_recv(struct s2n_connection *conn, struct s2n_stuffer *in);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/extensions/s2n_extension_type.h"
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+extern const s2n_extension_type s2n_tls13_server_status_request_extension;
+
+int s2n_server_certificate_status_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+int s2n_server_certificate_status_recv(struct s2n_connection *conn, struct s2n_stuffer *in);
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 5203e7db57..af112de0f4 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
@@ -1,430 +1,430 @@
-/*
- * 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 "tls/extensions/s2n_server_key_share.h"
-#include "tls/s2n_security_policies.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls13.h"
-
-#include "utils/s2n_safety.h"
-
-#include "crypto/s2n_fips.h"
-
-static int s2n_server_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-static int s2n_server_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_server_key_share_extension = {
- .iana_value = TLS_EXTENSION_KEY_SHARE,
- .is_response = false,
- .send = s2n_server_key_share_send,
- .recv = s2n_server_key_share_recv,
- .should_send = s2n_extension_send_if_tls13_connection,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static int s2n_server_key_share_generate_pq_hybrid(struct s2n_connection *conn, struct s2n_stuffer *out) {
- notnull_check(out);
- notnull_check(conn);
-
- ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS);
-
- struct s2n_kem_group_params *server_kem_group_params = &conn->secure.server_kem_group_params;
-
- notnull_check(server_kem_group_params->kem_group);
- GUARD(s2n_stuffer_write_uint16(out, server_kem_group_params->kem_group->iana_id));
-
- struct s2n_stuffer_reservation total_share_size = { 0 };
- GUARD(s2n_stuffer_reserve_uint16(out, &total_share_size));
-
- struct s2n_ecc_evp_params *server_ecc_params = &server_kem_group_params->ecc_params;
- notnull_check(server_ecc_params->negotiated_curve);
- GUARD(s2n_stuffer_write_uint16(out, server_ecc_params->negotiated_curve->share_size));
- GUARD(s2n_ecc_evp_generate_ephemeral_key(server_ecc_params));
- GUARD(s2n_ecc_evp_write_params_point(server_ecc_params, out));
-
- notnull_check(conn->secure.chosen_client_kem_group_params);
- struct s2n_kem_params *client_kem_params = &conn->secure.chosen_client_kem_group_params->kem_params;
- notnull_check(client_kem_params->public_key.data);
- /* s2n_kem_send_ciphertext() will generate the PQ shared secret and use
- * the client's public key to encapsulate; the PQ shared secret will be
- * stored in client_kem_params, and will be used during the hybrid shared
- * secret derivation. */
- GUARD(s2n_kem_send_ciphertext(out, client_kem_params));
-
- GUARD(s2n_stuffer_write_vector_size(&total_share_size));
- return S2N_SUCCESS;
-}
-
-/* Check that client has sent a corresponding key share for the server's KEM group */
-int s2n_server_key_share_send_check_pq_hybrid(struct s2n_connection *conn) {
- notnull_check(conn);
-
- ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS);
-
- notnull_check(conn->secure.server_kem_group_params.kem_group);
- notnull_check(conn->secure.server_kem_group_params.kem_params.kem);
- notnull_check(conn->secure.server_kem_group_params.ecc_params.negotiated_curve);
-
- const struct s2n_kem_group *server_kem_group = conn->secure.server_kem_group_params.kem_group;
-
- const struct s2n_kem_preferences *kem_pref = NULL;
- GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
- notnull_check(kem_pref);
-
- ENSURE_POSIX(s2n_kem_preferences_includes_tls13_kem_group(kem_pref, server_kem_group->iana_id),
- S2N_ERR_KEM_UNSUPPORTED_PARAMS);
-
- struct s2n_kem_group_params *client_params = conn->secure.chosen_client_kem_group_params;
- notnull_check(client_params);
-
- ENSURE_POSIX(client_params->kem_group == server_kem_group, S2N_ERR_BAD_KEY_SHARE);
-
- ENSURE_POSIX(client_params->ecc_params.negotiated_curve == server_kem_group->curve, S2N_ERR_BAD_KEY_SHARE);
- ENSURE_POSIX(client_params->ecc_params.evp_pkey != NULL, S2N_ERR_BAD_KEY_SHARE);
-
- ENSURE_POSIX(client_params->kem_params.kem == server_kem_group->kem, S2N_ERR_BAD_KEY_SHARE);
- ENSURE_POSIX(client_params->kem_params.public_key.size == server_kem_group->kem->public_key_length, S2N_ERR_BAD_KEY_SHARE);
- ENSURE_POSIX(client_params->kem_params.public_key.data != NULL, S2N_ERR_BAD_KEY_SHARE);
-
- return S2N_SUCCESS;
-}
-
-/* Check that client has sent a corresponding key share for the server's EC curve */
-int s2n_server_key_share_send_check_ecdhe(struct s2n_connection *conn) {
- notnull_check(conn);
-
- const struct s2n_ecc_preferences *ecc_pref = NULL;
- GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
- notnull_check(ecc_pref);
-
- const struct s2n_ecc_named_curve *server_curve = conn->secure.server_ecc_evp_params.negotiated_curve;
- notnull_check(server_curve);
-
- struct s2n_ecc_evp_params *client_params = NULL;
- for (size_t i = 0; i < ecc_pref->count; i++) {
- if (server_curve == ecc_pref->ecc_curves[i]) {
- client_params = &conn->secure.client_ecc_evp_params[i];
- break;
- }
- }
-
- notnull_check(client_params);
- ENSURE_POSIX(client_params->negotiated_curve == server_curve, S2N_ERR_BAD_KEY_SHARE);
- ENSURE_POSIX(client_params->evp_pkey != NULL, S2N_ERR_BAD_KEY_SHARE);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_server_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out) {
- notnull_check(conn);
- notnull_check(out);
-
- const struct s2n_ecc_named_curve *curve = conn->secure.server_ecc_evp_params.negotiated_curve;
- const struct s2n_kem_group *kem_group = conn->secure.server_kem_group_params.kem_group;
-
- /* Boolean XOR: exactly one of {server_curve, server_kem_group} should be non-null. */
- ENSURE_POSIX((curve == NULL) != (kem_group == NULL), S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
-
- /* Retry requests only require the selected named group, not an actual share.
- * https://tools.ietf.org/html/rfc8446#section-4.2.8 */
- if (s2n_is_hello_retry_message(conn)) {
- uint16_t named_group_id;
- if (curve != NULL) {
- named_group_id = curve->iana_id;
- } else {
- named_group_id = kem_group->iana_id;
- }
-
- GUARD(s2n_stuffer_write_uint16(out, named_group_id));
- return S2N_SUCCESS;
- }
-
- if (curve != NULL) {
- GUARD(s2n_server_key_share_send_check_ecdhe(conn));
- GUARD(s2n_ecdhe_parameters_send(&conn->secure.server_ecc_evp_params, out));
- } else {
- GUARD(s2n_server_key_share_send_check_pq_hybrid(conn));
- GUARD(s2n_server_key_share_generate_pq_hybrid(conn, out));
- }
-
- return S2N_SUCCESS;
-}
-
-static int s2n_server_key_share_recv_pq_hybrid(struct s2n_connection *conn, uint16_t named_group_iana,
- struct s2n_stuffer *extension) {
- notnull_check(conn);
- notnull_check(extension);
-
- /* If in FIPS mode, the client should not have sent any PQ IDs
- * in the supported_groups list of the initial ClientHello */
- ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS);
-
- const struct s2n_kem_preferences *kem_pref = NULL;
- GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
- notnull_check(kem_pref);
-
- /* This check should have been done higher up, but including it here as well for extra defense.
- * Uses S2N_ERR_ECDHE_UNSUPPORTED_CURVE for backward compatibility. */
- ENSURE_POSIX(s2n_kem_preferences_includes_tls13_kem_group(kem_pref, named_group_iana), S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
-
- size_t kem_group_index = 0;
- for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) {
- if (named_group_iana == kem_pref->tls13_kem_groups[i]->iana_id) {
- kem_group_index = i;
- break;
- }
- }
-
- struct s2n_kem_group_params *server_kem_group_params = &conn->secure.server_kem_group_params;
- server_kem_group_params->kem_group = kem_pref->tls13_kem_groups[kem_group_index];
- server_kem_group_params->kem_params.kem = kem_pref->tls13_kem_groups[kem_group_index]->kem;
- server_kem_group_params->ecc_params.negotiated_curve = kem_pref->tls13_kem_groups[kem_group_index]->curve;
-
- /* If this a HRR, the server will only have sent the named group ID. We assign the
- * appropriate KEM group params above, then exit early so that the client can
- * generate the correct key share. */
- if (s2n_is_hello_retry_message(conn)) {
- return S2N_SUCCESS;
- }
-
- /* Ensure that the server's key share corresponds with a key share previously sent by the client */
- ENSURE_POSIX(conn->secure.client_kem_group_params[kem_group_index].kem_params.private_key.data != NULL,
- S2N_ERR_BAD_KEY_SHARE);
- ENSURE_POSIX(conn->secure.client_kem_group_params[kem_group_index].ecc_params.evp_pkey != NULL,
- S2N_ERR_BAD_KEY_SHARE);
- notnull_check(conn->secure.client_kem_group_params[kem_group_index].kem_group);
- eq_check(conn->secure.client_kem_group_params[kem_group_index].kem_group->iana_id, named_group_iana);
- conn->secure.chosen_client_kem_group_params = &conn->secure.client_kem_group_params[kem_group_index];
-
- uint16_t received_total_share_size;
- GUARD(s2n_stuffer_read_uint16(extension, &received_total_share_size));
- ENSURE_POSIX(received_total_share_size == server_kem_group_params->kem_group->server_share_size, S2N_ERR_BAD_KEY_SHARE);
- ENSURE_POSIX(s2n_stuffer_data_available(extension) == received_total_share_size, S2N_ERR_BAD_KEY_SHARE);
-
- /* Parse ECC key share */
- uint16_t ecc_share_size;
- struct s2n_blob point_blob;
- GUARD(s2n_stuffer_read_uint16(extension, &ecc_share_size));
- ENSURE_POSIX(s2n_ecc_evp_read_params_point(extension, ecc_share_size, &point_blob) == S2N_SUCCESS, S2N_ERR_BAD_KEY_SHARE);
- ENSURE_POSIX(s2n_ecc_evp_parse_params_point(&point_blob, &server_kem_group_params->ecc_params) == S2N_SUCCESS, S2N_ERR_BAD_KEY_SHARE);
- ENSURE_POSIX(server_kem_group_params->ecc_params.evp_pkey != NULL, S2N_ERR_BAD_KEY_SHARE);
-
- /* Parse the PQ KEM key share */
- ENSURE_POSIX(s2n_kem_recv_ciphertext(extension, &conn->secure.chosen_client_kem_group_params->kem_params) == S2N_SUCCESS,
- S2N_ERR_BAD_KEY_SHARE);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_server_key_share_recv_ecc(struct s2n_connection *conn, uint16_t named_group_iana,
- struct s2n_stuffer *extension) {
- notnull_check(conn);
- notnull_check(extension);
-
- const struct s2n_ecc_preferences *ecc_pref = NULL;
- GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
- notnull_check(ecc_pref);
-
- /* This check should have been done higher up, but including it here as well for extra defense. */
- ENSURE_POSIX(s2n_ecc_preferences_includes_curve(ecc_pref, named_group_iana),
- S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
-
- size_t supported_curve_index = 0;
-
- for (size_t i = 0; i < ecc_pref->count; i++) {
- if (named_group_iana == ecc_pref->ecc_curves[i]->iana_id) {
- supported_curve_index = i;
- break;
- }
- }
-
- struct s2n_ecc_evp_params *server_ecc_evp_params = &conn->secure.server_ecc_evp_params;
- server_ecc_evp_params->negotiated_curve = ecc_pref->ecc_curves[supported_curve_index];
-
- /* If this is a HelloRetryRequest, we won't have a key share. We just have the selected group.
- * Set the server negotiated curve and exit early so a proper keyshare can be generated. */
- if (s2n_is_hello_retry_message(conn)) {
- return S2N_SUCCESS;
- }
-
- /* Key share not sent by client */
- S2N_ERROR_IF(conn->secure.client_ecc_evp_params[supported_curve_index].evp_pkey == NULL, S2N_ERR_BAD_KEY_SHARE);
-
- uint16_t share_size;
- S2N_ERROR_IF(s2n_stuffer_data_available(extension) < sizeof(share_size), S2N_ERR_BAD_KEY_SHARE);
- GUARD(s2n_stuffer_read_uint16(extension, &share_size));
- S2N_ERROR_IF(s2n_stuffer_data_available(extension) < share_size, S2N_ERR_BAD_KEY_SHARE);
-
- /* Proceed to parse share */
- struct s2n_blob point_blob;
- S2N_ERROR_IF(s2n_ecc_evp_read_params_point(extension, share_size, &point_blob) < 0, S2N_ERR_BAD_KEY_SHARE);
- S2N_ERROR_IF(s2n_ecc_evp_parse_params_point(&point_blob, server_ecc_evp_params) < 0, S2N_ERR_BAD_KEY_SHARE);
- S2N_ERROR_IF(server_ecc_evp_params->evp_pkey == NULL, S2N_ERR_BAD_KEY_SHARE);
-
- return S2N_SUCCESS;
-}
-
-/*
- * From https://tools.ietf.org/html/rfc8446#section-4.2.8
- *
- * If using (EC)DHE key establishment, servers offer exactly one
- * KeyShareEntry in the ServerHello. This value MUST be in the same
- * group as the KeyShareEntry value offered by the client that the
- * server has selected for the negotiated key exchange.
- */
-static int s2n_server_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
- return S2N_SUCCESS;
- }
-
- notnull_check(conn);
- notnull_check(extension);
-
- uint16_t negotiated_named_group_iana = 0;
- S2N_ERROR_IF(s2n_stuffer_data_available(extension) < sizeof(negotiated_named_group_iana), S2N_ERR_BAD_KEY_SHARE);
- GUARD(s2n_stuffer_read_uint16(extension, &negotiated_named_group_iana));
-
- const struct s2n_kem_preferences *kem_pref = NULL;
- GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
- notnull_check(kem_pref);
-
- const struct s2n_ecc_preferences *ecc_pref = NULL;
- GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
- notnull_check(ecc_pref);
-
- if (s2n_ecc_preferences_includes_curve(ecc_pref, negotiated_named_group_iana)) {
- GUARD(s2n_server_key_share_recv_ecc(conn, negotiated_named_group_iana, extension));
- } else if (s2n_kem_preferences_includes_tls13_kem_group(kem_pref, negotiated_named_group_iana)) {
- GUARD(s2n_server_key_share_recv_pq_hybrid(conn, negotiated_named_group_iana, extension));
- } else {
- S2N_ERROR(S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
- }
-
- return S2N_SUCCESS;
-}
-
-/* Selects highest priority mutually supported key share, or indicates need for HRR */
-int s2n_extensions_server_key_share_select(struct s2n_connection *conn) {
- notnull_check(conn);
-
- const struct s2n_ecc_preferences *ecc_pref = NULL;
- GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
- notnull_check(ecc_pref);
-
- const struct s2n_kem_preferences *kem_pref = NULL;
- GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
- notnull_check(kem_pref);
-
- /* Boolean XOR check. When receiving the supported_groups extension, s2n server
- * should (exclusively) set either server_curve or server_kem_group based on the
- * set of mutually supported groups. If both server_curve and server_kem_group
- * are NULL, it is because client and server do not share any mutually supported
- * groups; key negotiation is not possible and the handshake should be aborted
- * without sending HRR. (The case of both being non-NULL should never occur, and
- * is an error.) */
- const struct s2n_ecc_named_curve *server_curve = conn->secure.server_ecc_evp_params.negotiated_curve;
- const struct s2n_kem_group *server_kem_group = conn->secure.server_kem_group_params.kem_group;
- ENSURE_POSIX((server_curve == NULL) != (server_kem_group == NULL), S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
-
- /* To avoid extra round trips, we prefer to negotiate a group for which we have already
- * received a key share (even if it is different than the group previously chosen). In
- * general, we prefer to negotiate PQ over ECDHE; however, if both client and server
- * support PQ, but the client sent only EC key shares, then we will negotiate ECHDE. */
- for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) {
- if (conn->secure.mutually_supported_kem_groups[i] && conn->secure.client_kem_group_params[i].kem_group) {
- notnull_check(conn->secure.client_kem_group_params[i].ecc_params.negotiated_curve);
- notnull_check(conn->secure.client_kem_group_params[i].kem_params.kem);
-
- conn->secure.server_kem_group_params.kem_group = conn->secure.client_kem_group_params[i].kem_group;
- conn->secure.server_kem_group_params.ecc_params.negotiated_curve = conn->secure.client_kem_group_params[i].ecc_params.negotiated_curve;
- conn->secure.server_kem_group_params.kem_params.kem = conn->secure.client_kem_group_params[i].kem_params.kem;
- conn->secure.chosen_client_kem_group_params = &conn->secure.client_kem_group_params[i];
-
- conn->secure.server_ecc_evp_params.negotiated_curve = NULL;
- return S2N_SUCCESS;
- }
- }
-
- for (size_t i = 0; i < ecc_pref->count; i++) {
- if (conn->secure.mutually_supported_curves[i] && conn->secure.client_ecc_evp_params[i].negotiated_curve) {
- conn->secure.server_ecc_evp_params.negotiated_curve = conn->secure.client_ecc_evp_params[i].negotiated_curve;
-
- conn->secure.server_kem_group_params.kem_group = NULL;
- conn->secure.server_kem_group_params.ecc_params.negotiated_curve = NULL;
- conn->secure.server_kem_group_params.kem_params.kem = NULL;
- conn->secure.chosen_client_kem_group_params = NULL;
- return S2N_SUCCESS;
- }
- }
-
- /* Server and client have mutually supported groups, but the client did not send key
- * shares for any of them. Send HRR indicating the server's preference. */
- GUARD(s2n_set_hello_retry_required(conn));
- return S2N_SUCCESS;
-}
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-/*
- * Calculate the data length for Server Key Share extension
- * based on negotiated_curve selected in server_ecc_evp_params.
- *
- * Retry requests have a different key share format,
- * https://tools.ietf.org/html/rfc8446#section-4.2.8
- *
- * This functions does not error, but s2n_extensions_server_key_share_send() would
- */
-int s2n_extensions_server_key_share_send_size(struct s2n_connection *conn)
-{
- const struct s2n_ecc_named_curve* curve = conn->secure.server_ecc_evp_params.negotiated_curve;
- int key_share_size = S2N_SIZE_OF_EXTENSION_TYPE
- + S2N_SIZE_OF_EXTENSION_DATA_SIZE
- + S2N_SIZE_OF_NAMED_GROUP;
-
- /* If this is a KeyShareHelloRetryRequest we don't include the share size */
- if (s2n_is_hello_retry_message(conn)) {
- return key_share_size;
- }
-
- if (curve == NULL) {
- return 0;
- }
-
- /* If this is a full KeyShareEntry, include the share size */
- key_share_size += (S2N_SIZE_OF_KEY_SHARE_SIZE + curve->share_size);
-
- return key_share_size;
-}
-
-/*
- * Sends Key Share extension in Server Hello.
- *
- * Expects negotiated_curve to be set and generates a ephemeral key for key sharing
- */
-int s2n_extensions_server_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- return s2n_extension_send(&s2n_server_key_share_extension, conn, out);
-}
-
-/*
- * Client receives a Server Hello key share.
- *
- * If the curve is supported, conn->secure.server_ecc_evp_params will be set.
- */
-int s2n_extensions_server_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- return s2n_extension_recv(&s2n_server_key_share_extension, conn, extension);
-}
+/*
+ * 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 "tls/extensions/s2n_server_key_share.h"
+#include "tls/s2n_security_policies.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls13.h"
+
+#include "utils/s2n_safety.h"
+
+#include "crypto/s2n_fips.h"
+
+static int s2n_server_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+static int s2n_server_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_server_key_share_extension = {
+ .iana_value = TLS_EXTENSION_KEY_SHARE,
+ .is_response = false,
+ .send = s2n_server_key_share_send,
+ .recv = s2n_server_key_share_recv,
+ .should_send = s2n_extension_send_if_tls13_connection,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static int s2n_server_key_share_generate_pq_hybrid(struct s2n_connection *conn, struct s2n_stuffer *out) {
+ notnull_check(out);
+ notnull_check(conn);
+
+ ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS);
+
+ struct s2n_kem_group_params *server_kem_group_params = &conn->secure.server_kem_group_params;
+
+ notnull_check(server_kem_group_params->kem_group);
+ GUARD(s2n_stuffer_write_uint16(out, server_kem_group_params->kem_group->iana_id));
+
+ struct s2n_stuffer_reservation total_share_size = { 0 };
+ GUARD(s2n_stuffer_reserve_uint16(out, &total_share_size));
+
+ struct s2n_ecc_evp_params *server_ecc_params = &server_kem_group_params->ecc_params;
+ notnull_check(server_ecc_params->negotiated_curve);
+ GUARD(s2n_stuffer_write_uint16(out, server_ecc_params->negotiated_curve->share_size));
+ GUARD(s2n_ecc_evp_generate_ephemeral_key(server_ecc_params));
+ GUARD(s2n_ecc_evp_write_params_point(server_ecc_params, out));
+
+ notnull_check(conn->secure.chosen_client_kem_group_params);
+ struct s2n_kem_params *client_kem_params = &conn->secure.chosen_client_kem_group_params->kem_params;
+ notnull_check(client_kem_params->public_key.data);
+ /* s2n_kem_send_ciphertext() will generate the PQ shared secret and use
+ * the client's public key to encapsulate; the PQ shared secret will be
+ * stored in client_kem_params, and will be used during the hybrid shared
+ * secret derivation. */
+ GUARD(s2n_kem_send_ciphertext(out, client_kem_params));
+
+ GUARD(s2n_stuffer_write_vector_size(&total_share_size));
+ return S2N_SUCCESS;
+}
+
+/* Check that client has sent a corresponding key share for the server's KEM group */
+int s2n_server_key_share_send_check_pq_hybrid(struct s2n_connection *conn) {
+ notnull_check(conn);
+
+ ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS);
+
+ notnull_check(conn->secure.server_kem_group_params.kem_group);
+ notnull_check(conn->secure.server_kem_group_params.kem_params.kem);
+ notnull_check(conn->secure.server_kem_group_params.ecc_params.negotiated_curve);
+
+ const struct s2n_kem_group *server_kem_group = conn->secure.server_kem_group_params.kem_group;
+
+ const struct s2n_kem_preferences *kem_pref = NULL;
+ GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
+ notnull_check(kem_pref);
+
+ ENSURE_POSIX(s2n_kem_preferences_includes_tls13_kem_group(kem_pref, server_kem_group->iana_id),
+ S2N_ERR_KEM_UNSUPPORTED_PARAMS);
+
+ struct s2n_kem_group_params *client_params = conn->secure.chosen_client_kem_group_params;
+ notnull_check(client_params);
+
+ ENSURE_POSIX(client_params->kem_group == server_kem_group, S2N_ERR_BAD_KEY_SHARE);
+
+ ENSURE_POSIX(client_params->ecc_params.negotiated_curve == server_kem_group->curve, S2N_ERR_BAD_KEY_SHARE);
+ ENSURE_POSIX(client_params->ecc_params.evp_pkey != NULL, S2N_ERR_BAD_KEY_SHARE);
+
+ ENSURE_POSIX(client_params->kem_params.kem == server_kem_group->kem, S2N_ERR_BAD_KEY_SHARE);
+ ENSURE_POSIX(client_params->kem_params.public_key.size == server_kem_group->kem->public_key_length, S2N_ERR_BAD_KEY_SHARE);
+ ENSURE_POSIX(client_params->kem_params.public_key.data != NULL, S2N_ERR_BAD_KEY_SHARE);
+
+ return S2N_SUCCESS;
+}
+
+/* Check that client has sent a corresponding key share for the server's EC curve */
+int s2n_server_key_share_send_check_ecdhe(struct s2n_connection *conn) {
+ notnull_check(conn);
+
+ const struct s2n_ecc_preferences *ecc_pref = NULL;
+ GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
+ notnull_check(ecc_pref);
+
+ const struct s2n_ecc_named_curve *server_curve = conn->secure.server_ecc_evp_params.negotiated_curve;
+ notnull_check(server_curve);
+
+ struct s2n_ecc_evp_params *client_params = NULL;
+ for (size_t i = 0; i < ecc_pref->count; i++) {
+ if (server_curve == ecc_pref->ecc_curves[i]) {
+ client_params = &conn->secure.client_ecc_evp_params[i];
+ break;
+ }
+ }
+
+ notnull_check(client_params);
+ ENSURE_POSIX(client_params->negotiated_curve == server_curve, S2N_ERR_BAD_KEY_SHARE);
+ ENSURE_POSIX(client_params->evp_pkey != NULL, S2N_ERR_BAD_KEY_SHARE);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_server_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out) {
+ notnull_check(conn);
+ notnull_check(out);
+
+ const struct s2n_ecc_named_curve *curve = conn->secure.server_ecc_evp_params.negotiated_curve;
+ const struct s2n_kem_group *kem_group = conn->secure.server_kem_group_params.kem_group;
+
+ /* Boolean XOR: exactly one of {server_curve, server_kem_group} should be non-null. */
+ ENSURE_POSIX((curve == NULL) != (kem_group == NULL), S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
+
+ /* Retry requests only require the selected named group, not an actual share.
+ * https://tools.ietf.org/html/rfc8446#section-4.2.8 */
+ if (s2n_is_hello_retry_message(conn)) {
+ uint16_t named_group_id;
+ if (curve != NULL) {
+ named_group_id = curve->iana_id;
+ } else {
+ named_group_id = kem_group->iana_id;
+ }
+
+ GUARD(s2n_stuffer_write_uint16(out, named_group_id));
+ return S2N_SUCCESS;
+ }
+
+ if (curve != NULL) {
+ GUARD(s2n_server_key_share_send_check_ecdhe(conn));
+ GUARD(s2n_ecdhe_parameters_send(&conn->secure.server_ecc_evp_params, out));
+ } else {
+ GUARD(s2n_server_key_share_send_check_pq_hybrid(conn));
+ GUARD(s2n_server_key_share_generate_pq_hybrid(conn, out));
+ }
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_server_key_share_recv_pq_hybrid(struct s2n_connection *conn, uint16_t named_group_iana,
+ struct s2n_stuffer *extension) {
+ notnull_check(conn);
+ notnull_check(extension);
+
+ /* If in FIPS mode, the client should not have sent any PQ IDs
+ * in the supported_groups list of the initial ClientHello */
+ ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS);
+
+ const struct s2n_kem_preferences *kem_pref = NULL;
+ GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
+ notnull_check(kem_pref);
+
+ /* This check should have been done higher up, but including it here as well for extra defense.
+ * Uses S2N_ERR_ECDHE_UNSUPPORTED_CURVE for backward compatibility. */
+ ENSURE_POSIX(s2n_kem_preferences_includes_tls13_kem_group(kem_pref, named_group_iana), S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
+
+ size_t kem_group_index = 0;
+ for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) {
+ if (named_group_iana == kem_pref->tls13_kem_groups[i]->iana_id) {
+ kem_group_index = i;
+ break;
+ }
+ }
+
+ struct s2n_kem_group_params *server_kem_group_params = &conn->secure.server_kem_group_params;
+ server_kem_group_params->kem_group = kem_pref->tls13_kem_groups[kem_group_index];
+ server_kem_group_params->kem_params.kem = kem_pref->tls13_kem_groups[kem_group_index]->kem;
+ server_kem_group_params->ecc_params.negotiated_curve = kem_pref->tls13_kem_groups[kem_group_index]->curve;
+
+ /* If this a HRR, the server will only have sent the named group ID. We assign the
+ * appropriate KEM group params above, then exit early so that the client can
+ * generate the correct key share. */
+ if (s2n_is_hello_retry_message(conn)) {
+ return S2N_SUCCESS;
+ }
+
+ /* Ensure that the server's key share corresponds with a key share previously sent by the client */
+ ENSURE_POSIX(conn->secure.client_kem_group_params[kem_group_index].kem_params.private_key.data != NULL,
+ S2N_ERR_BAD_KEY_SHARE);
+ ENSURE_POSIX(conn->secure.client_kem_group_params[kem_group_index].ecc_params.evp_pkey != NULL,
+ S2N_ERR_BAD_KEY_SHARE);
+ notnull_check(conn->secure.client_kem_group_params[kem_group_index].kem_group);
+ eq_check(conn->secure.client_kem_group_params[kem_group_index].kem_group->iana_id, named_group_iana);
+ conn->secure.chosen_client_kem_group_params = &conn->secure.client_kem_group_params[kem_group_index];
+
+ uint16_t received_total_share_size;
+ GUARD(s2n_stuffer_read_uint16(extension, &received_total_share_size));
+ ENSURE_POSIX(received_total_share_size == server_kem_group_params->kem_group->server_share_size, S2N_ERR_BAD_KEY_SHARE);
+ ENSURE_POSIX(s2n_stuffer_data_available(extension) == received_total_share_size, S2N_ERR_BAD_KEY_SHARE);
+
+ /* Parse ECC key share */
+ uint16_t ecc_share_size;
+ struct s2n_blob point_blob;
+ GUARD(s2n_stuffer_read_uint16(extension, &ecc_share_size));
+ ENSURE_POSIX(s2n_ecc_evp_read_params_point(extension, ecc_share_size, &point_blob) == S2N_SUCCESS, S2N_ERR_BAD_KEY_SHARE);
+ ENSURE_POSIX(s2n_ecc_evp_parse_params_point(&point_blob, &server_kem_group_params->ecc_params) == S2N_SUCCESS, S2N_ERR_BAD_KEY_SHARE);
+ ENSURE_POSIX(server_kem_group_params->ecc_params.evp_pkey != NULL, S2N_ERR_BAD_KEY_SHARE);
+
+ /* Parse the PQ KEM key share */
+ ENSURE_POSIX(s2n_kem_recv_ciphertext(extension, &conn->secure.chosen_client_kem_group_params->kem_params) == S2N_SUCCESS,
+ S2N_ERR_BAD_KEY_SHARE);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_server_key_share_recv_ecc(struct s2n_connection *conn, uint16_t named_group_iana,
+ struct s2n_stuffer *extension) {
+ notnull_check(conn);
+ notnull_check(extension);
+
+ const struct s2n_ecc_preferences *ecc_pref = NULL;
+ GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
+ notnull_check(ecc_pref);
+
+ /* This check should have been done higher up, but including it here as well for extra defense. */
+ ENSURE_POSIX(s2n_ecc_preferences_includes_curve(ecc_pref, named_group_iana),
+ S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
+
+ size_t supported_curve_index = 0;
+
+ for (size_t i = 0; i < ecc_pref->count; i++) {
+ if (named_group_iana == ecc_pref->ecc_curves[i]->iana_id) {
+ supported_curve_index = i;
+ break;
+ }
+ }
+
+ struct s2n_ecc_evp_params *server_ecc_evp_params = &conn->secure.server_ecc_evp_params;
+ server_ecc_evp_params->negotiated_curve = ecc_pref->ecc_curves[supported_curve_index];
+
+ /* If this is a HelloRetryRequest, we won't have a key share. We just have the selected group.
+ * Set the server negotiated curve and exit early so a proper keyshare can be generated. */
+ if (s2n_is_hello_retry_message(conn)) {
+ return S2N_SUCCESS;
+ }
+
+ /* Key share not sent by client */
+ S2N_ERROR_IF(conn->secure.client_ecc_evp_params[supported_curve_index].evp_pkey == NULL, S2N_ERR_BAD_KEY_SHARE);
+
+ uint16_t share_size;
+ S2N_ERROR_IF(s2n_stuffer_data_available(extension) < sizeof(share_size), S2N_ERR_BAD_KEY_SHARE);
+ GUARD(s2n_stuffer_read_uint16(extension, &share_size));
+ S2N_ERROR_IF(s2n_stuffer_data_available(extension) < share_size, S2N_ERR_BAD_KEY_SHARE);
+
+ /* Proceed to parse share */
+ struct s2n_blob point_blob;
+ S2N_ERROR_IF(s2n_ecc_evp_read_params_point(extension, share_size, &point_blob) < 0, S2N_ERR_BAD_KEY_SHARE);
+ S2N_ERROR_IF(s2n_ecc_evp_parse_params_point(&point_blob, server_ecc_evp_params) < 0, S2N_ERR_BAD_KEY_SHARE);
+ S2N_ERROR_IF(server_ecc_evp_params->evp_pkey == NULL, S2N_ERR_BAD_KEY_SHARE);
+
+ return S2N_SUCCESS;
+}
+
+/*
+ * From https://tools.ietf.org/html/rfc8446#section-4.2.8
+ *
+ * If using (EC)DHE key establishment, servers offer exactly one
+ * KeyShareEntry in the ServerHello. This value MUST be in the same
+ * group as the KeyShareEntry value offered by the client that the
+ * server has selected for the negotiated key exchange.
+ */
+static int s2n_server_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
+ return S2N_SUCCESS;
+ }
+
+ notnull_check(conn);
+ notnull_check(extension);
+
+ uint16_t negotiated_named_group_iana = 0;
+ S2N_ERROR_IF(s2n_stuffer_data_available(extension) < sizeof(negotiated_named_group_iana), S2N_ERR_BAD_KEY_SHARE);
+ GUARD(s2n_stuffer_read_uint16(extension, &negotiated_named_group_iana));
+
+ const struct s2n_kem_preferences *kem_pref = NULL;
+ GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
+ notnull_check(kem_pref);
+
+ const struct s2n_ecc_preferences *ecc_pref = NULL;
+ GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
+ notnull_check(ecc_pref);
+
+ if (s2n_ecc_preferences_includes_curve(ecc_pref, negotiated_named_group_iana)) {
+ GUARD(s2n_server_key_share_recv_ecc(conn, negotiated_named_group_iana, extension));
+ } else if (s2n_kem_preferences_includes_tls13_kem_group(kem_pref, negotiated_named_group_iana)) {
+ GUARD(s2n_server_key_share_recv_pq_hybrid(conn, negotiated_named_group_iana, extension));
+ } else {
+ S2N_ERROR(S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
+ }
+
+ return S2N_SUCCESS;
+}
+
+/* Selects highest priority mutually supported key share, or indicates need for HRR */
+int s2n_extensions_server_key_share_select(struct s2n_connection *conn) {
+ notnull_check(conn);
+
+ const struct s2n_ecc_preferences *ecc_pref = NULL;
+ GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
+ notnull_check(ecc_pref);
+
+ const struct s2n_kem_preferences *kem_pref = NULL;
+ GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
+ notnull_check(kem_pref);
+
+ /* Boolean XOR check. When receiving the supported_groups extension, s2n server
+ * should (exclusively) set either server_curve or server_kem_group based on the
+ * set of mutually supported groups. If both server_curve and server_kem_group
+ * are NULL, it is because client and server do not share any mutually supported
+ * groups; key negotiation is not possible and the handshake should be aborted
+ * without sending HRR. (The case of both being non-NULL should never occur, and
+ * is an error.) */
+ const struct s2n_ecc_named_curve *server_curve = conn->secure.server_ecc_evp_params.negotiated_curve;
+ const struct s2n_kem_group *server_kem_group = conn->secure.server_kem_group_params.kem_group;
+ ENSURE_POSIX((server_curve == NULL) != (server_kem_group == NULL), S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
+
+ /* To avoid extra round trips, we prefer to negotiate a group for which we have already
+ * received a key share (even if it is different than the group previously chosen). In
+ * general, we prefer to negotiate PQ over ECDHE; however, if both client and server
+ * support PQ, but the client sent only EC key shares, then we will negotiate ECHDE. */
+ for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) {
+ if (conn->secure.mutually_supported_kem_groups[i] && conn->secure.client_kem_group_params[i].kem_group) {
+ notnull_check(conn->secure.client_kem_group_params[i].ecc_params.negotiated_curve);
+ notnull_check(conn->secure.client_kem_group_params[i].kem_params.kem);
+
+ conn->secure.server_kem_group_params.kem_group = conn->secure.client_kem_group_params[i].kem_group;
+ conn->secure.server_kem_group_params.ecc_params.negotiated_curve = conn->secure.client_kem_group_params[i].ecc_params.negotiated_curve;
+ conn->secure.server_kem_group_params.kem_params.kem = conn->secure.client_kem_group_params[i].kem_params.kem;
+ conn->secure.chosen_client_kem_group_params = &conn->secure.client_kem_group_params[i];
+
+ conn->secure.server_ecc_evp_params.negotiated_curve = NULL;
+ return S2N_SUCCESS;
+ }
+ }
+
+ for (size_t i = 0; i < ecc_pref->count; i++) {
+ if (conn->secure.mutually_supported_curves[i] && conn->secure.client_ecc_evp_params[i].negotiated_curve) {
+ conn->secure.server_ecc_evp_params.negotiated_curve = conn->secure.client_ecc_evp_params[i].negotiated_curve;
+
+ conn->secure.server_kem_group_params.kem_group = NULL;
+ conn->secure.server_kem_group_params.ecc_params.negotiated_curve = NULL;
+ conn->secure.server_kem_group_params.kem_params.kem = NULL;
+ conn->secure.chosen_client_kem_group_params = NULL;
+ return S2N_SUCCESS;
+ }
+ }
+
+ /* Server and client have mutually supported groups, but the client did not send key
+ * shares for any of them. Send HRR indicating the server's preference. */
+ GUARD(s2n_set_hello_retry_required(conn));
+ return S2N_SUCCESS;
+}
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+/*
+ * Calculate the data length for Server Key Share extension
+ * based on negotiated_curve selected in server_ecc_evp_params.
+ *
+ * Retry requests have a different key share format,
+ * https://tools.ietf.org/html/rfc8446#section-4.2.8
+ *
+ * This functions does not error, but s2n_extensions_server_key_share_send() would
+ */
+int s2n_extensions_server_key_share_send_size(struct s2n_connection *conn)
+{
+ const struct s2n_ecc_named_curve* curve = conn->secure.server_ecc_evp_params.negotiated_curve;
+ int key_share_size = S2N_SIZE_OF_EXTENSION_TYPE
+ + S2N_SIZE_OF_EXTENSION_DATA_SIZE
+ + S2N_SIZE_OF_NAMED_GROUP;
+
+ /* If this is a KeyShareHelloRetryRequest we don't include the share size */
+ if (s2n_is_hello_retry_message(conn)) {
+ return key_share_size;
+ }
+
+ if (curve == NULL) {
+ return 0;
+ }
+
+ /* If this is a full KeyShareEntry, include the share size */
+ key_share_size += (S2N_SIZE_OF_KEY_SHARE_SIZE + curve->share_size);
+
+ return key_share_size;
+}
+
+/*
+ * Sends Key Share extension in Server Hello.
+ *
+ * Expects negotiated_curve to be set and generates a ephemeral key for key sharing
+ */
+int s2n_extensions_server_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ return s2n_extension_send(&s2n_server_key_share_extension, conn, out);
+}
+
+/*
+ * Client receives a Server Hello key share.
+ *
+ * If the curve is supported, conn->secure.server_ecc_evp_params will be set.
+ */
+int s2n_extensions_server_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ return s2n_extension_recv(&s2n_server_key_share_extension, conn, extension);
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_key_share.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_key_share.h
index afc1589a18..11a289d1de 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_key_share.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_key_share.h
@@ -1,30 +1,30 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-#include "tls/extensions/s2n_key_share.h"
-
-extern const s2n_extension_type s2n_server_key_share_extension;
-
-extern int s2n_extensions_server_key_share_select(struct s2n_connection *conn);
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-extern int s2n_extensions_server_key_share_send_size(struct s2n_connection *conn);
-extern int s2n_extensions_server_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-extern int s2n_extensions_server_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+#include "tls/extensions/s2n_key_share.h"
+
+extern const s2n_extension_type s2n_server_key_share_extension;
+
+extern int s2n_extensions_server_key_share_select(struct s2n_connection *conn);
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+extern int s2n_extensions_server_key_share_send_size(struct s2n_connection *conn);
+extern int s2n_extensions_server_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+extern int s2n_extensions_server_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_max_fragment_length.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_max_fragment_length.c
index 65a0c611dc..69b1530e54 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_max_fragment_length.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_max_fragment_length.c
@@ -1,61 +1,61 @@
-/*
- * 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 "error/s2n_errno.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_safety.h"
-
-#include "tls/s2n_tls_parameters.h"
-#include "tls/s2n_connection.h"
-
-#include "tls/extensions/s2n_server_max_fragment_length.h"
-
-static bool s2n_max_fragment_length_should_send(struct s2n_connection *conn);
-static int s2n_max_fragment_length_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-static int s2n_max_fragment_length_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_server_max_fragment_length_extension = {
- .iana_value = TLS_EXTENSION_MAX_FRAG_LEN,
- .is_response = true,
- .send = s2n_max_fragment_length_send,
- .recv = s2n_max_fragment_length_recv,
- .should_send = s2n_max_fragment_length_should_send,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static bool s2n_max_fragment_length_should_send(struct s2n_connection *conn)
-{
- return conn && conn->mfl_code != S2N_TLS_MAX_FRAG_LEN_EXT_NONE;
-}
-
-static int s2n_max_fragment_length_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- notnull_check(conn);
- GUARD(s2n_stuffer_write_uint8(out, conn->mfl_code));
- return S2N_SUCCESS;
-}
-
-static int s2n_max_fragment_length_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- notnull_check(conn);
- notnull_check(conn->config);
-
- uint8_t mfl_code;
- GUARD(s2n_stuffer_read_uint8(extension, &mfl_code));
- S2N_ERROR_IF(mfl_code != conn->config->mfl_code, S2N_ERR_MAX_FRAG_LEN_MISMATCH);
- return S2N_SUCCESS;
-}
+/*
+ * 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 "error/s2n_errno.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_safety.h"
+
+#include "tls/s2n_tls_parameters.h"
+#include "tls/s2n_connection.h"
+
+#include "tls/extensions/s2n_server_max_fragment_length.h"
+
+static bool s2n_max_fragment_length_should_send(struct s2n_connection *conn);
+static int s2n_max_fragment_length_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+static int s2n_max_fragment_length_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_server_max_fragment_length_extension = {
+ .iana_value = TLS_EXTENSION_MAX_FRAG_LEN,
+ .is_response = true,
+ .send = s2n_max_fragment_length_send,
+ .recv = s2n_max_fragment_length_recv,
+ .should_send = s2n_max_fragment_length_should_send,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static bool s2n_max_fragment_length_should_send(struct s2n_connection *conn)
+{
+ return conn && conn->mfl_code != S2N_TLS_MAX_FRAG_LEN_EXT_NONE;
+}
+
+static int s2n_max_fragment_length_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ notnull_check(conn);
+ GUARD(s2n_stuffer_write_uint8(out, conn->mfl_code));
+ return S2N_SUCCESS;
+}
+
+static int s2n_max_fragment_length_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ notnull_check(conn);
+ notnull_check(conn->config);
+
+ uint8_t mfl_code;
+ GUARD(s2n_stuffer_read_uint8(extension, &mfl_code));
+ S2N_ERROR_IF(mfl_code != conn->config->mfl_code, S2N_ERR_MAX_FRAG_LEN_MISMATCH);
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_max_fragment_length.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_max_fragment_length.h
index 57211c20b8..8a8ae81ad1 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_max_fragment_length.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_max_fragment_length.h
@@ -1,20 +1,20 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/extensions/s2n_extension_type.h"
-
-extern const s2n_extension_type s2n_server_max_fragment_length_extension;
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/extensions/s2n_extension_type.h"
+
+extern const s2n_extension_type s2n_server_max_fragment_length_extension;
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.c
index f7d4ee7c97..aac791c43c 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.c
@@ -1,87 +1,87 @@
-/*
- * 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 "error/s2n_errno.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_safety.h"
-
-#include "tls/s2n_tls_parameters.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_tls.h"
-#include "tls/extensions/s2n_server_renegotiation_info.h"
-
-static bool s2n_renegotiation_info_should_send(struct s2n_connection *conn);
-static int s2n_renegotiation_info_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-static int s2n_renegotiation_info_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_server_renegotiation_info_extension = {
- .iana_value = TLS_EXTENSION_RENEGOTIATION_INFO,
- .is_response = false,
- .send = s2n_renegotiation_info_send,
- .recv = s2n_renegotiation_info_recv,
- .should_send = s2n_renegotiation_info_should_send,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static bool s2n_renegotiation_info_should_send(struct s2n_connection *conn)
-{
- return conn && conn->secure_renegotiation && s2n_connection_get_protocol_version(conn) < S2N_TLS13;
-}
-
-static int s2n_renegotiation_info_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- /* renegotiated_connection length. Zero since we don't support renegotiation. */
- GUARD(s2n_stuffer_write_uint8(out, 0));
- return S2N_SUCCESS;
-}
-
-static int s2n_renegotiation_info_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- /* RFC5746 Section 3.4: The client MUST then verify that the length of
- * the "renegotiated_connection" field is zero, and if it is not, MUST
- * abort the handshake. */
- uint8_t renegotiated_connection_len;
- GUARD(s2n_stuffer_read_uint8(extension, &renegotiated_connection_len));
- S2N_ERROR_IF(s2n_stuffer_data_available(extension), S2N_ERR_NON_EMPTY_RENEGOTIATION_INFO);
- S2N_ERROR_IF(renegotiated_connection_len, S2N_ERR_NON_EMPTY_RENEGOTIATION_INFO);
-
- notnull_check(conn);
- conn->secure_renegotiation = 1;
- return S2N_SUCCESS;
-}
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-int s2n_recv_server_renegotiation_info_ext(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- return s2n_extension_recv(&s2n_server_renegotiation_info_extension, conn, extension);
-}
-
-int s2n_send_server_renegotiation_info_ext(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- return s2n_extension_send(&s2n_server_renegotiation_info_extension, conn, out);
-}
-
-int s2n_server_renegotiation_info_ext_size(struct s2n_connection *conn)
-{
- if (s2n_renegotiation_info_should_send(conn)) {
- /* 2 for ext type, 2 for extension length, 1 for value of 0 */
- return 5;
- }
-
- return 0;
-}
+/*
+ * 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 "error/s2n_errno.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_safety.h"
+
+#include "tls/s2n_tls_parameters.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_tls.h"
+#include "tls/extensions/s2n_server_renegotiation_info.h"
+
+static bool s2n_renegotiation_info_should_send(struct s2n_connection *conn);
+static int s2n_renegotiation_info_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+static int s2n_renegotiation_info_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_server_renegotiation_info_extension = {
+ .iana_value = TLS_EXTENSION_RENEGOTIATION_INFO,
+ .is_response = false,
+ .send = s2n_renegotiation_info_send,
+ .recv = s2n_renegotiation_info_recv,
+ .should_send = s2n_renegotiation_info_should_send,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static bool s2n_renegotiation_info_should_send(struct s2n_connection *conn)
+{
+ return conn && conn->secure_renegotiation && s2n_connection_get_protocol_version(conn) < S2N_TLS13;
+}
+
+static int s2n_renegotiation_info_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ /* renegotiated_connection length. Zero since we don't support renegotiation. */
+ GUARD(s2n_stuffer_write_uint8(out, 0));
+ return S2N_SUCCESS;
+}
+
+static int s2n_renegotiation_info_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ /* RFC5746 Section 3.4: The client MUST then verify that the length of
+ * the "renegotiated_connection" field is zero, and if it is not, MUST
+ * abort the handshake. */
+ uint8_t renegotiated_connection_len;
+ GUARD(s2n_stuffer_read_uint8(extension, &renegotiated_connection_len));
+ S2N_ERROR_IF(s2n_stuffer_data_available(extension), S2N_ERR_NON_EMPTY_RENEGOTIATION_INFO);
+ S2N_ERROR_IF(renegotiated_connection_len, S2N_ERR_NON_EMPTY_RENEGOTIATION_INFO);
+
+ notnull_check(conn);
+ conn->secure_renegotiation = 1;
+ return S2N_SUCCESS;
+}
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+int s2n_recv_server_renegotiation_info_ext(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ return s2n_extension_recv(&s2n_server_renegotiation_info_extension, conn, extension);
+}
+
+int s2n_send_server_renegotiation_info_ext(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ return s2n_extension_send(&s2n_server_renegotiation_info_extension, conn, out);
+}
+
+int s2n_server_renegotiation_info_ext_size(struct s2n_connection *conn)
+{
+ if (s2n_renegotiation_info_should_send(conn)) {
+ /* 2 for ext type, 2 for extension length, 1 for value of 0 */
+ return 5;
+ }
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.h
index 3fd0f128e9..b037b2182a 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.h
@@ -1,27 +1,27 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/extensions/s2n_extension_type.h"
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-extern const s2n_extension_type s2n_server_renegotiation_info_extension;
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-int s2n_recv_server_renegotiation_info_ext(struct s2n_connection *conn, struct s2n_stuffer *extension);
-int s2n_send_server_renegotiation_info_ext(struct s2n_connection *conn, struct s2n_stuffer *out);
-int s2n_server_renegotiation_info_ext_size(struct s2n_connection *conn);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/extensions/s2n_extension_type.h"
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+extern const s2n_extension_type s2n_server_renegotiation_info_extension;
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+int s2n_recv_server_renegotiation_info_ext(struct s2n_connection *conn, struct s2n_stuffer *extension);
+int s2n_send_server_renegotiation_info_ext(struct s2n_connection *conn, struct s2n_stuffer *out);
+int s2n_server_renegotiation_info_ext_size(struct s2n_connection *conn);
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_sct_list.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_sct_list.c
index 88b2cf7837..8a8158aecf 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_sct_list.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_sct_list.c
@@ -1,67 +1,67 @@
-/*
- * 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 "stuffer/s2n_stuffer.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_tls.h"
-#include "tls/extensions/s2n_server_sct_list.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_blob.h"
-
-static bool s2n_server_sct_list_should_send(struct s2n_connection *conn);
-static int s2n_server_sct_list_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-static int s2n_server_sct_list_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_server_sct_list_extension = {
- .iana_value = TLS_EXTENSION_SCT_LIST,
- .is_response = true,
- .send = s2n_server_sct_list_send,
- .recv = s2n_server_sct_list_recv,
- .should_send = s2n_server_sct_list_should_send,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static bool s2n_server_sct_list_should_send(struct s2n_connection *conn)
-{
- return s2n_server_can_send_sct_list(conn);
-}
-
-int s2n_server_sct_list_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- notnull_check(conn);
- struct s2n_blob *sct_list = &conn->handshake_params.our_chain_and_key->sct_list;
-
- notnull_check(sct_list);
- GUARD(s2n_stuffer_write(out, sct_list));
-
- return S2N_SUCCESS;
-}
-
-int s2n_server_sct_list_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- notnull_check(conn);
-
- struct s2n_blob sct_list;
- size_t data_available = s2n_stuffer_data_available(extension);
- GUARD(s2n_blob_init(&sct_list,
- s2n_stuffer_raw_read(extension, data_available),
- data_available));
- notnull_check(sct_list.data);
-
- GUARD(s2n_dup(&sct_list, &conn->ct_response));
-
- return S2N_SUCCESS;
-}
+/*
+ * 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 "stuffer/s2n_stuffer.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_tls.h"
+#include "tls/extensions/s2n_server_sct_list.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_blob.h"
+
+static bool s2n_server_sct_list_should_send(struct s2n_connection *conn);
+static int s2n_server_sct_list_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+static int s2n_server_sct_list_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_server_sct_list_extension = {
+ .iana_value = TLS_EXTENSION_SCT_LIST,
+ .is_response = true,
+ .send = s2n_server_sct_list_send,
+ .recv = s2n_server_sct_list_recv,
+ .should_send = s2n_server_sct_list_should_send,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static bool s2n_server_sct_list_should_send(struct s2n_connection *conn)
+{
+ return s2n_server_can_send_sct_list(conn);
+}
+
+int s2n_server_sct_list_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ notnull_check(conn);
+ struct s2n_blob *sct_list = &conn->handshake_params.our_chain_and_key->sct_list;
+
+ notnull_check(sct_list);
+ GUARD(s2n_stuffer_write(out, sct_list));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_server_sct_list_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ notnull_check(conn);
+
+ struct s2n_blob sct_list;
+ size_t data_available = s2n_stuffer_data_available(extension);
+ GUARD(s2n_blob_init(&sct_list,
+ s2n_stuffer_raw_read(extension, data_available),
+ data_available));
+ notnull_check(sct_list.data);
+
+ GUARD(s2n_dup(&sct_list, &conn->ct_response));
+
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_sct_list.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_sct_list.h
index 08dd86fdb8..2632c76238 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_sct_list.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_sct_list.h
@@ -1,20 +1,20 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/extensions/s2n_extension_type.h"
-
-extern const s2n_extension_type s2n_server_sct_list_extension;
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/extensions/s2n_extension_type.h"
+
+extern const s2n_extension_type s2n_server_sct_list_extension;
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_server_name.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_server_name.c
index 22e0b03cd7..158a9eae6c 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_server_name.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_server_name.c
@@ -1,51 +1,51 @@
-/*
- * 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 "stuffer/s2n_stuffer.h"
-
-#include "tls/s2n_connection.h"
-#include "tls/extensions/s2n_server_server_name.h"
-
-static bool s2n_server_name_should_send(struct s2n_connection *conn);
-static int s2n_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-static int s2n_server_name_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_server_server_name_extension = {
- .iana_value = TLS_EXTENSION_SERVER_NAME,
- .is_response = true,
- .send = s2n_server_name_send,
- .recv = s2n_server_name_recv,
- .should_send = s2n_server_name_should_send,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static bool s2n_server_name_should_send(struct s2n_connection *conn)
-{
- return conn && conn->server_name_used && !s2n_connection_is_session_resumed(conn);
-}
-
-static int s2n_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- /* Write nothing. The extension just needs to exist. */
- return S2N_SUCCESS;
-}
-
-static int s2n_server_name_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- notnull_check(conn);
- /* Read nothing. The extension just needs to exist. */
- conn->server_name_used = 1;
- return S2N_SUCCESS;
-}
+/*
+ * 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 "stuffer/s2n_stuffer.h"
+
+#include "tls/s2n_connection.h"
+#include "tls/extensions/s2n_server_server_name.h"
+
+static bool s2n_server_name_should_send(struct s2n_connection *conn);
+static int s2n_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+static int s2n_server_name_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_server_server_name_extension = {
+ .iana_value = TLS_EXTENSION_SERVER_NAME,
+ .is_response = true,
+ .send = s2n_server_name_send,
+ .recv = s2n_server_name_recv,
+ .should_send = s2n_server_name_should_send,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static bool s2n_server_name_should_send(struct s2n_connection *conn)
+{
+ return conn && conn->server_name_used && !s2n_connection_is_session_resumed(conn);
+}
+
+static int s2n_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ /* Write nothing. The extension just needs to exist. */
+ return S2N_SUCCESS;
+}
+
+static int s2n_server_name_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ notnull_check(conn);
+ /* Read nothing. The extension just needs to exist. */
+ conn->server_name_used = 1;
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_server_name.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_server_name.h
index 2519dfcd18..8ed13d3084 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_server_name.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_server_name.h
@@ -1,20 +1,20 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/extensions/s2n_extension_type.h"
-
-extern const s2n_extension_type s2n_server_server_name_extension;
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/extensions/s2n_extension_type.h"
+
+extern const s2n_extension_type s2n_server_server_name_extension;
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_session_ticket.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_session_ticket.c
index 02a52c6cf7..74875f05a6 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_session_ticket.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_session_ticket.c
@@ -1,68 +1,68 @@
-/*
- * 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 "stuffer/s2n_stuffer.h"
-
-#include "tls/s2n_tls_parameters.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_tls.h"
-#include "tls/extensions/s2n_server_session_ticket.h"
-
-static bool s2n_session_ticket_should_send(struct s2n_connection *conn);
-static int s2n_session_ticket_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_server_session_ticket_extension = {
- .iana_value = TLS_EXTENSION_SESSION_TICKET,
- .is_response = true,
- .send = s2n_extension_send_noop,
- .recv = s2n_session_ticket_recv,
- .should_send = s2n_session_ticket_should_send,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static bool s2n_session_ticket_should_send(struct s2n_connection *conn)
-{
- return s2n_server_sending_nst(conn) && s2n_connection_get_protocol_version(conn) < S2N_TLS13;
-}
-
-static int s2n_session_ticket_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- /* Read nothing. The extension just needs to exist. */
- notnull_check(conn);
- conn->session_ticket_status = S2N_NEW_TICKET;
- return S2N_SUCCESS;
-}
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-int s2n_recv_server_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- return s2n_extension_recv(&s2n_server_session_ticket_extension, conn, extension);
-}
-
-int s2n_send_server_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- return s2n_extension_send(&s2n_server_session_ticket_extension, conn, out);
-}
-
-int s2n_server_session_ticket_ext_size(struct s2n_connection *conn)
-{
- if (s2n_session_ticket_should_send(conn)) {
- /* 2 for extension type. 2 for extension length of 0 */
- return 4;
- }
-
- return 0;
-}
+/*
+ * 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 "stuffer/s2n_stuffer.h"
+
+#include "tls/s2n_tls_parameters.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_tls.h"
+#include "tls/extensions/s2n_server_session_ticket.h"
+
+static bool s2n_session_ticket_should_send(struct s2n_connection *conn);
+static int s2n_session_ticket_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_server_session_ticket_extension = {
+ .iana_value = TLS_EXTENSION_SESSION_TICKET,
+ .is_response = true,
+ .send = s2n_extension_send_noop,
+ .recv = s2n_session_ticket_recv,
+ .should_send = s2n_session_ticket_should_send,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static bool s2n_session_ticket_should_send(struct s2n_connection *conn)
+{
+ return s2n_server_sending_nst(conn) && s2n_connection_get_protocol_version(conn) < S2N_TLS13;
+}
+
+static int s2n_session_ticket_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ /* Read nothing. The extension just needs to exist. */
+ notnull_check(conn);
+ conn->session_ticket_status = S2N_NEW_TICKET;
+ return S2N_SUCCESS;
+}
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+int s2n_recv_server_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ return s2n_extension_recv(&s2n_server_session_ticket_extension, conn, extension);
+}
+
+int s2n_send_server_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ return s2n_extension_send(&s2n_server_session_ticket_extension, conn, out);
+}
+
+int s2n_server_session_ticket_ext_size(struct s2n_connection *conn)
+{
+ if (s2n_session_ticket_should_send(conn)) {
+ /* 2 for extension type. 2 for extension length of 0 */
+ return 4;
+ }
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_session_ticket.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_session_ticket.h
index 0733c02380..2e9ba959cb 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_session_ticket.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_session_ticket.h
@@ -1,27 +1,27 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/extensions/s2n_extension_type.h"
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-extern const s2n_extension_type s2n_server_session_ticket_extension;
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-int s2n_recv_server_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *extension);
-int s2n_send_server_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *out);
-int s2n_server_session_ticket_ext_size(struct s2n_connection *conn);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/extensions/s2n_extension_type.h"
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+extern const s2n_extension_type s2n_server_session_ticket_extension;
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+int s2n_recv_server_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *extension);
+int s2n_send_server_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *out);
+int s2n_server_session_ticket_ext_size(struct s2n_connection *conn);
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_signature_algorithms.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_signature_algorithms.c
index a864012dd5..e7bd8a32cc 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_signature_algorithms.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_signature_algorithms.c
@@ -1,42 +1,42 @@
-/*
- * 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 <sys/param.h>
-#include <stdint.h>
-
-#include "tls/extensions/s2n_client_signature_algorithms.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls_parameters.h"
-#include "tls/s2n_signature_algorithms.h"
-
-#include "stuffer/s2n_stuffer.h"
-#include "utils/s2n_safety.h"
-
-static int s2n_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_server_signature_algorithms_extension = {
- .iana_value = TLS_EXTENSION_SIGNATURE_ALGORITHMS,
- .is_response = false,
- .send = s2n_send_supported_sig_scheme_list,
- .recv = s2n_signature_algorithms_recv,
- .should_send = s2n_extension_always_send,
- .if_missing = s2n_extension_error_if_missing,
-};
-
-static int s2n_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- return s2n_recv_supported_sig_scheme_list(extension, &conn->handshake_params.server_sig_hash_algs);
-}
+/*
+ * 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 <sys/param.h>
+#include <stdint.h>
+
+#include "tls/extensions/s2n_client_signature_algorithms.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls_parameters.h"
+#include "tls/s2n_signature_algorithms.h"
+
+#include "stuffer/s2n_stuffer.h"
+#include "utils/s2n_safety.h"
+
+static int s2n_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_server_signature_algorithms_extension = {
+ .iana_value = TLS_EXTENSION_SIGNATURE_ALGORITHMS,
+ .is_response = false,
+ .send = s2n_send_supported_sig_scheme_list,
+ .recv = s2n_signature_algorithms_recv,
+ .should_send = s2n_extension_always_send,
+ .if_missing = s2n_extension_error_if_missing,
+};
+
+static int s2n_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ return s2n_recv_supported_sig_scheme_list(extension, &conn->handshake_params.server_sig_hash_algs);
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_signature_algorithms.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_signature_algorithms.h
index 05a6cc2d9d..644d71770e 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_signature_algorithms.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_signature_algorithms.h
@@ -1,20 +1,20 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/extensions/s2n_extension_type.h"
-
-extern const s2n_extension_type s2n_server_signature_algorithms_extension;
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/extensions/s2n_extension_type.h"
+
+extern const s2n_extension_type s2n_server_signature_algorithms_extension;
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_status_request.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_status_request.c
index 463f0898cd..7003bf46ba 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_status_request.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_status_request.c
@@ -1,66 +1,66 @@
-/*
- * 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 "stuffer/s2n_stuffer.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls_parameters.h"
-#include "tls/extensions/s2n_server_status_request.h"
-
-static bool s2n_server_status_request_should_send(struct s2n_connection *conn);
-static int s2n_server_status_request_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-
-const s2n_extension_type s2n_server_status_request_extension = {
- .iana_value = TLS_EXTENSION_STATUS_REQUEST,
- .is_response = true,
- .send = s2n_extension_send_noop,
- .recv = s2n_server_status_request_recv,
- .should_send = s2n_server_status_request_should_send,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static bool s2n_server_status_request_should_send(struct s2n_connection *conn)
-{
- return s2n_server_can_send_ocsp(conn);
-}
-
-int s2n_server_status_request_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- /* Read nothing. The extension just needs to exist. */
- notnull_check(conn);
- conn->status_type = S2N_STATUS_REQUEST_OCSP;
- return S2N_SUCCESS;
-}
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-int s2n_server_extensions_status_request_send_size(struct s2n_connection *conn)
-{
- if (s2n_server_can_send_ocsp(conn)) {
- return 2 * sizeof(uint16_t);
- }
-
- return 0;
-}
-
-int s2n_server_extensions_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- return s2n_extension_send(&s2n_server_status_request_extension, conn, out);
-}
-
-int s2n_recv_server_status_request(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- return s2n_extension_recv(&s2n_server_status_request_extension, conn, extension);
-}
+/*
+ * 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 "stuffer/s2n_stuffer.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls_parameters.h"
+#include "tls/extensions/s2n_server_status_request.h"
+
+static bool s2n_server_status_request_should_send(struct s2n_connection *conn);
+static int s2n_server_status_request_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+
+const s2n_extension_type s2n_server_status_request_extension = {
+ .iana_value = TLS_EXTENSION_STATUS_REQUEST,
+ .is_response = true,
+ .send = s2n_extension_send_noop,
+ .recv = s2n_server_status_request_recv,
+ .should_send = s2n_server_status_request_should_send,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static bool s2n_server_status_request_should_send(struct s2n_connection *conn)
+{
+ return s2n_server_can_send_ocsp(conn);
+}
+
+int s2n_server_status_request_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ /* Read nothing. The extension just needs to exist. */
+ notnull_check(conn);
+ conn->status_type = S2N_STATUS_REQUEST_OCSP;
+ return S2N_SUCCESS;
+}
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+int s2n_server_extensions_status_request_send_size(struct s2n_connection *conn)
+{
+ if (s2n_server_can_send_ocsp(conn)) {
+ return 2 * sizeof(uint16_t);
+ }
+
+ return 0;
+}
+
+int s2n_server_extensions_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ return s2n_extension_send(&s2n_server_status_request_extension, conn, out);
+}
+
+int s2n_recv_server_status_request(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ return s2n_extension_recv(&s2n_server_status_request_extension, conn, extension);
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_status_request.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_status_request.h
index cbe695f9b4..b43ff10ca8 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_status_request.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_status_request.h
@@ -1,27 +1,27 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/extensions/s2n_extension_type.h"
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-extern const s2n_extension_type s2n_server_status_request_extension;
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-int s2n_server_extensions_status_request_send_size(struct s2n_connection *conn);
-int s2n_server_extensions_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-int s2n_recv_server_status_request(struct s2n_connection *conn, struct s2n_stuffer *extension);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/extensions/s2n_extension_type.h"
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+extern const s2n_extension_type s2n_server_status_request_extension;
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+int s2n_server_extensions_status_request_send_size(struct s2n_connection *conn);
+int s2n_server_extensions_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+int s2n_recv_server_status_request(struct s2n_connection *conn, struct s2n_stuffer *extension);
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 026cec9c21..cd0fb015dc 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
@@ -1,106 +1,106 @@
-/*
- * 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 <sys/param.h>
-#include <stdint.h>
-
-#include "tls/extensions/s2n_server_supported_versions.h"
-#include "tls/extensions/s2n_supported_versions.h"
-#include "tls/s2n_alerts.h"
-#include "tls/s2n_cipher_preferences.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls_parameters.h"
-
-#include "utils/s2n_safety.h"
-
-/**
- * Specified in https://tools.ietf.org/html/rfc8446#section-4.2.1
- *
- * "A server which negotiates TLS 1.3 MUST respond by sending a
- * "supported_versions" extension containing the selected version value
- * (0x0304)."
- *
- * Structure:
- * Extension type (2 bytes)
- * Extension size (2 bytes)
- * Selected Version (2 byte)
- **/
-
-static int s2n_server_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-static int s2n_server_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *in);
-
-const s2n_extension_type s2n_server_supported_versions_extension = {
- .iana_value = TLS_EXTENSION_SUPPORTED_VERSIONS,
- .is_response = true,
- .send = s2n_server_supported_versions_send,
- .recv = s2n_server_supported_versions_recv,
- .should_send = s2n_extension_send_if_tls13_connection,
- .if_missing = s2n_extension_noop_if_missing,
-};
-
-static int s2n_server_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- GUARD(s2n_stuffer_write_uint8(out, conn->server_protocol_version / 10));
- GUARD(s2n_stuffer_write_uint8(out, conn->server_protocol_version % 10));
-
- return S2N_SUCCESS;
-}
-
-static int s2n_extensions_server_supported_versions_process(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- uint8_t highest_supported_version = conn->client_protocol_version;
- uint8_t minimum_supported_version;
- GUARD(s2n_connection_get_minimum_supported_version(conn, &minimum_supported_version));
-
- uint8_t server_version_parts[S2N_TLS_PROTOCOL_VERSION_LEN];
- GUARD(s2n_stuffer_read_bytes(extension, server_version_parts, S2N_TLS_PROTOCOL_VERSION_LEN));
-
- uint16_t server_version = (server_version_parts[0] * 10) + server_version_parts[1];
-
- gte_check(server_version, S2N_TLS13);
- lte_check(server_version, highest_supported_version);
- gte_check(server_version, minimum_supported_version);
-
- conn->server_protocol_version = server_version;
-
- return S2N_SUCCESS;
-}
-
-static int s2n_server_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *in)
-{
- if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
- return S2N_SUCCESS;
- }
-
- S2N_ERROR_IF(s2n_extensions_server_supported_versions_process(conn, in) < 0, S2N_ERR_BAD_MESSAGE);
- return S2N_SUCCESS;
-}
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-
-int s2n_extensions_server_supported_versions_size(struct s2n_connection *conn)
-{
- return 6;
-}
-
-int s2n_extensions_server_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
-{
- return s2n_extension_recv(&s2n_server_supported_versions_extension, conn, extension);
-}
-
-int s2n_extensions_server_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- return s2n_extension_send(&s2n_server_supported_versions_extension, conn, out);
-}
+/*
+ * 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 <sys/param.h>
+#include <stdint.h>
+
+#include "tls/extensions/s2n_server_supported_versions.h"
+#include "tls/extensions/s2n_supported_versions.h"
+#include "tls/s2n_alerts.h"
+#include "tls/s2n_cipher_preferences.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls_parameters.h"
+
+#include "utils/s2n_safety.h"
+
+/**
+ * Specified in https://tools.ietf.org/html/rfc8446#section-4.2.1
+ *
+ * "A server which negotiates TLS 1.3 MUST respond by sending a
+ * "supported_versions" extension containing the selected version value
+ * (0x0304)."
+ *
+ * Structure:
+ * Extension type (2 bytes)
+ * Extension size (2 bytes)
+ * Selected Version (2 byte)
+ **/
+
+static int s2n_server_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+static int s2n_server_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *in);
+
+const s2n_extension_type s2n_server_supported_versions_extension = {
+ .iana_value = TLS_EXTENSION_SUPPORTED_VERSIONS,
+ .is_response = true,
+ .send = s2n_server_supported_versions_send,
+ .recv = s2n_server_supported_versions_recv,
+ .should_send = s2n_extension_send_if_tls13_connection,
+ .if_missing = s2n_extension_noop_if_missing,
+};
+
+static int s2n_server_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ GUARD(s2n_stuffer_write_uint8(out, conn->server_protocol_version / 10));
+ GUARD(s2n_stuffer_write_uint8(out, conn->server_protocol_version % 10));
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_extensions_server_supported_versions_process(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ uint8_t highest_supported_version = conn->client_protocol_version;
+ uint8_t minimum_supported_version;
+ GUARD(s2n_connection_get_minimum_supported_version(conn, &minimum_supported_version));
+
+ uint8_t server_version_parts[S2N_TLS_PROTOCOL_VERSION_LEN];
+ GUARD(s2n_stuffer_read_bytes(extension, server_version_parts, S2N_TLS_PROTOCOL_VERSION_LEN));
+
+ uint16_t server_version = (server_version_parts[0] * 10) + server_version_parts[1];
+
+ gte_check(server_version, S2N_TLS13);
+ lte_check(server_version, highest_supported_version);
+ gte_check(server_version, minimum_supported_version);
+
+ conn->server_protocol_version = server_version;
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_server_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *in)
+{
+ if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
+ return S2N_SUCCESS;
+ }
+
+ S2N_ERROR_IF(s2n_extensions_server_supported_versions_process(conn, in) < 0, S2N_ERR_BAD_MESSAGE);
+ return S2N_SUCCESS;
+}
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+
+int s2n_extensions_server_supported_versions_size(struct s2n_connection *conn)
+{
+ return 6;
+}
+
+int s2n_extensions_server_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ return s2n_extension_recv(&s2n_server_supported_versions_extension, conn, extension);
+}
+
+int s2n_extensions_server_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ return s2n_extension_send(&s2n_server_supported_versions_extension, conn, out);
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_supported_versions.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_supported_versions.h
index 4d49a61dea..c7312be137 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_supported_versions.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_supported_versions.h
@@ -1,27 +1,27 @@
-/*
- * 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.
- */
-
-
-#pragma once
-
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-extern const s2n_extension_type s2n_server_supported_versions_extension;
-
-/* Old-style extension functions -- remove after extensions refactor is complete */
-int s2n_extensions_server_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
-int s2n_extensions_server_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-int s2n_extensions_server_supported_versions_size(struct s2n_connection *conn);
+/*
+ * 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.
+ */
+
+
+#pragma once
+
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+extern const s2n_extension_type s2n_server_supported_versions_extension;
+
+/* Old-style extension functions -- remove after extensions refactor is complete */
+int s2n_extensions_server_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
+int s2n_extensions_server_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+int s2n_extensions_server_supported_versions_size(struct s2n_connection *conn);
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_supported_versions.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_supported_versions.c
index 018fff5b26..d02b3f920d 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_supported_versions.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_supported_versions.c
@@ -1,31 +1,31 @@
-/*
- * 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 <stdint.h>
-#include <sys/param.h>
-
-#include "tls/extensions/s2n_supported_versions.h"
-#include "tls/s2n_security_policies.h"
-
-#include "utils/s2n_safety.h"
-
-int s2n_connection_get_minimum_supported_version(struct s2n_connection *conn, uint8_t *min_version)
-{
- const struct s2n_security_policy *security_policy;
- GUARD(s2n_connection_get_security_policy(conn, &security_policy));
- *min_version = security_policy->minimum_protocol_version;
-
- return 0;
-}
+/*
+ * 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 <stdint.h>
+#include <sys/param.h>
+
+#include "tls/extensions/s2n_supported_versions.h"
+#include "tls/s2n_security_policies.h"
+
+#include "utils/s2n_safety.h"
+
+int s2n_connection_get_minimum_supported_version(struct s2n_connection *conn, uint8_t *min_version)
+{
+ const struct s2n_security_policy *security_policy;
+ GUARD(s2n_connection_get_security_policy(conn, &security_policy));
+ *min_version = security_policy->minimum_protocol_version;
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_supported_versions.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_supported_versions.h
index 44e2d17957..613830c347 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_supported_versions.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_supported_versions.h
@@ -1,21 +1,21 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-extern int s2n_connection_get_minimum_supported_version(struct s2n_connection *conn, uint8_t *min_version);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+extern int s2n_connection_get_minimum_supported_version(struct s2n_connection *conn, uint8_t *min_version);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_aead.c b/contrib/restricted/aws/s2n/tls/s2n_aead.c
index d22e782952..b7a0b23160 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_aead.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_aead.c
@@ -1,78 +1,78 @@
-/*
- * 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 "error/s2n_errno.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_mem.h"
-
-#include "tls/s2n_record.h"
-
-/* Derive the AAD for an AEAD mode cipher suite from the connection state, per
- * RFC 5246 section 6.2.3.3 */
-S2N_RESULT s2n_aead_aad_init(const struct s2n_connection *conn, uint8_t * sequence_number, uint8_t content_type, uint16_t record_length, struct s2n_stuffer *ad)
-{
- /* ad = seq_num || record_type || version || length */
- GUARD_AS_RESULT(s2n_stuffer_write_bytes(ad, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
- GUARD_AS_RESULT(s2n_stuffer_write_uint8(ad, content_type));
- GUARD_AS_RESULT(s2n_stuffer_write_uint8(ad, conn->actual_protocol_version / 10));
- GUARD_AS_RESULT(s2n_stuffer_write_uint8(ad, conn->actual_protocol_version % 10));
- GUARD_AS_RESULT(s2n_stuffer_write_uint16(ad, record_length));
-
- return S2N_RESULT_OK;
-}
-
-/* Prepares an AAD (additional authentication data) for a TLS 1.3 AEAD record */
-S2N_RESULT s2n_tls13_aead_aad_init(uint16_t record_length, uint8_t tag_length, struct s2n_stuffer *additional_data)
-{
- ENSURE_GT(tag_length, 0);
- ENSURE_REF(additional_data);
-
- /*
- * tls1.3 additional_data = opaque_type || legacy_record_version || length
- *
- * https://tools.ietf.org/html/rfc8446#section-5.2
- *
- * opaque_type: The outer opaque_type field of a TLSCiphertext record
- * is always set to the value 23 (application_data) for outward
- * compatibility with middleboxes accustomed to parsing previous
- * versions of TLS. The actual content type of the record is found
- * in TLSInnerPlaintext.type after decryption.
- * legacy_record_version: The legacy_record_version field is always
- * 0x0303. TLS 1.3 TLSCiphertexts are not generated until after
- * TLS 1.3 has been negotiated, so there are no historical
- * compatibility concerns where other values might be received. Note
- * that the handshake protocol, including the ClientHello and
- * ServerHello messages, authenticates the protocol version, so this
- * value is redundant.
- * length: The length (in bytes) of the following
- * TLSCiphertext.encrypted_record, which is the sum of the lengths of
- * the content and the padding, plus one for the inner content type,
- * plus any expansion added by the AEAD algorithm. The length
- * MUST NOT exceed 2^14 + 256 bytes. An endpoint that receives a
- * record that exceeds this length MUST terminate the connection with
- * a "record_overflow" alert.
- */
-
- uint16_t length = record_length + tag_length;
- ENSURE(length <= (1 << 14) + 256, S2N_ERR_RECORD_LIMIT);
-
- GUARD_AS_RESULT(s2n_stuffer_write_uint8(additional_data, TLS_APPLICATION_DATA)); /* fixed to 0x17 */
- GUARD_AS_RESULT(s2n_stuffer_write_uint8(additional_data, 3)); /* TLS record layer */
- GUARD_AS_RESULT(s2n_stuffer_write_uint8(additional_data, 3)); /* version fixed at 1.2 (0x0303) */
- GUARD_AS_RESULT(s2n_stuffer_write_uint16(additional_data, length));
-
- return S2N_RESULT_OK;
-}
+/*
+ * 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 "error/s2n_errno.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_mem.h"
+
+#include "tls/s2n_record.h"
+
+/* Derive the AAD for an AEAD mode cipher suite from the connection state, per
+ * RFC 5246 section 6.2.3.3 */
+S2N_RESULT s2n_aead_aad_init(const struct s2n_connection *conn, uint8_t * sequence_number, uint8_t content_type, uint16_t record_length, struct s2n_stuffer *ad)
+{
+ /* ad = seq_num || record_type || version || length */
+ GUARD_AS_RESULT(s2n_stuffer_write_bytes(ad, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
+ GUARD_AS_RESULT(s2n_stuffer_write_uint8(ad, content_type));
+ GUARD_AS_RESULT(s2n_stuffer_write_uint8(ad, conn->actual_protocol_version / 10));
+ GUARD_AS_RESULT(s2n_stuffer_write_uint8(ad, conn->actual_protocol_version % 10));
+ GUARD_AS_RESULT(s2n_stuffer_write_uint16(ad, record_length));
+
+ return S2N_RESULT_OK;
+}
+
+/* Prepares an AAD (additional authentication data) for a TLS 1.3 AEAD record */
+S2N_RESULT s2n_tls13_aead_aad_init(uint16_t record_length, uint8_t tag_length, struct s2n_stuffer *additional_data)
+{
+ ENSURE_GT(tag_length, 0);
+ ENSURE_REF(additional_data);
+
+ /*
+ * tls1.3 additional_data = opaque_type || legacy_record_version || length
+ *
+ * https://tools.ietf.org/html/rfc8446#section-5.2
+ *
+ * opaque_type: The outer opaque_type field of a TLSCiphertext record
+ * is always set to the value 23 (application_data) for outward
+ * compatibility with middleboxes accustomed to parsing previous
+ * versions of TLS. The actual content type of the record is found
+ * in TLSInnerPlaintext.type after decryption.
+ * legacy_record_version: The legacy_record_version field is always
+ * 0x0303. TLS 1.3 TLSCiphertexts are not generated until after
+ * TLS 1.3 has been negotiated, so there are no historical
+ * compatibility concerns where other values might be received. Note
+ * that the handshake protocol, including the ClientHello and
+ * ServerHello messages, authenticates the protocol version, so this
+ * value is redundant.
+ * length: The length (in bytes) of the following
+ * TLSCiphertext.encrypted_record, which is the sum of the lengths of
+ * the content and the padding, plus one for the inner content type,
+ * plus any expansion added by the AEAD algorithm. The length
+ * MUST NOT exceed 2^14 + 256 bytes. An endpoint that receives a
+ * record that exceeds this length MUST terminate the connection with
+ * a "record_overflow" alert.
+ */
+
+ uint16_t length = record_length + tag_length;
+ ENSURE(length <= (1 << 14) + 256, S2N_ERR_RECORD_LIMIT);
+
+ GUARD_AS_RESULT(s2n_stuffer_write_uint8(additional_data, TLS_APPLICATION_DATA)); /* fixed to 0x17 */
+ GUARD_AS_RESULT(s2n_stuffer_write_uint8(additional_data, 3)); /* TLS record layer */
+ GUARD_AS_RESULT(s2n_stuffer_write_uint8(additional_data, 3)); /* version fixed at 1.2 (0x0303) */
+ GUARD_AS_RESULT(s2n_stuffer_write_uint16(additional_data, length));
+
+ return S2N_RESULT_OK;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_alerts.c b/contrib/restricted/aws/s2n/tls/s2n_alerts.c
index 4aafb59900..79f14f3214 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_alerts.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_alerts.c
@@ -1,185 +1,185 @@
-/*
- * 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 <stdint.h>
-#include <sys/param.h>
-
-#include "error/s2n_errno.h"
-
-#include "tls/s2n_tls_parameters.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_record.h"
-#include "tls/s2n_resume.h"
-#include "tls/s2n_alerts.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_blob.h"
-
-#define S2N_TLS_ALERT_CLOSE_NOTIFY 0
-#define S2N_TLS_ALERT_UNEXPECTED_MSG 10
-#define S2N_TLS_ALERT_BAD_RECORD_MAC 20
-#define S2N_TLS_ALERT_DECRYPT_FAILED 21
-#define S2N_TLS_ALERT_RECORD_OVERFLOW 22
-#define S2N_TLS_ALERT_DECOMP_FAILED 30
-#define S2N_TLS_ALERT_HANDSHAKE_FAILURE 40
-#define S2N_TLS_ALERT_NO_CERTIFICATE 41
-#define S2N_TLS_ALERT_BAD_CERTIFICATE 42
-#define S2N_TLS_ALERT_UNSUPPORTED_CERT 43
-#define S2N_TLS_ALERT_CERT_REVOKED 44
-#define S2N_TLS_ALERT_CERT_EXPIRED 45
-#define S2N_TLS_ALERT_CERT_UNKNOWN 46
-#define S2N_TLS_ALERT_ILLEGAL_PARAMETER 47
-#define S2N_TLS_ALERT_UNKNOWN_CA 48
-#define S2N_TLS_ALERT_ACCESS_DENIED 49
-#define S2N_TLS_ALERT_DECODE_ERROR 50
-#define S2N_TLS_ALERT_DECRYPT_ERROR 51
-#define S2N_TLS_ALERT_EXPORT_RESTRICTED 60
-#define S2N_TLS_ALERT_PROTOCOL_VERSION 70
-#define S2N_TLS_ALERT_INSUFFICIENT_SECURITY 71
-#define S2N_TLS_ALERT_INTERNAL_ERROR 80
-#define S2N_TLS_ALERT_USER_CANCELED 90
-#define S2N_TLS_ALERT_NO_RENEGOTIATION 100
-#define S2N_TLS_ALERT_UNSUPPORTED_EXTENSION 110
-
-#define S2N_TLS_ALERT_LEVEL_WARNING 1
-#define S2N_TLS_ALERT_LEVEL_FATAL 2
-
-static bool s2n_alerts_supported(struct s2n_connection *conn)
-{
- /* If running in QUIC mode, QUIC handles alerting.
- * S2N should not send or receive alerts. */
- return conn && conn->config && !conn->config->quic_enabled;
-}
-
-static bool s2n_handle_as_warning(struct s2n_connection *conn, uint8_t level, uint8_t type)
-{
- /* Only TLS1.2 considers the alert level. The alert level field is
- * considered deprecated in TLS1.3. */
- if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
- return level == S2N_TLS_ALERT_LEVEL_WARNING
- && conn->config->alert_behavior == S2N_ALERT_IGNORE_WARNINGS;
- }
-
- /* user_canceled is the only alert currently treated as a warning in TLS1.3.
- * We need to treat it as a warning regardless of alert_behavior to avoid marking
- * correctly-closed connections as failed. */
- return type == S2N_TLS_ALERT_USER_CANCELED;
-}
-
-int s2n_process_alert_fragment(struct s2n_connection *conn)
-{
- notnull_check(conn);
- S2N_ERROR_IF(s2n_stuffer_data_available(&conn->in) == 0, S2N_ERR_BAD_MESSAGE);
- S2N_ERROR_IF(s2n_stuffer_data_available(&conn->alert_in) == 2, S2N_ERR_ALERT_PRESENT);
- ENSURE_POSIX(s2n_alerts_supported(conn), S2N_ERR_BAD_MESSAGE);
-
- while (s2n_stuffer_data_available(&conn->in)) {
- uint8_t bytes_required = 2;
-
- /* Alerts are two bytes long, but can still be fragmented or coalesced */
- if (s2n_stuffer_data_available(&conn->alert_in) == 1) {
- bytes_required = 1;
- }
-
- int bytes_to_read = MIN(bytes_required, s2n_stuffer_data_available(&conn->in));
-
- GUARD(s2n_stuffer_copy(&conn->in, &conn->alert_in, bytes_to_read));
-
- if (s2n_stuffer_data_available(&conn->alert_in) == 2) {
-
- /* Close notifications are handled as shutdowns */
- if (conn->alert_in_data[1] == S2N_TLS_ALERT_CLOSE_NOTIFY) {
- conn->closed = 1;
- return 0;
- }
-
- /* Ignore warning-level alerts if we're in warning-tolerant mode */
- if (s2n_handle_as_warning(conn, conn->alert_in_data[0], conn->alert_in_data[1])) {
- GUARD(s2n_stuffer_wipe(&conn->alert_in));
- return 0;
- }
-
- /* RFC 5077 5.1 - Expire any cached session on an error alert */
- if (s2n_allowed_to_cache_connection(conn) && conn->session_id_len) {
- conn->config->cache_delete(conn, conn->config->cache_delete_data, conn->session_id, conn->session_id_len);
- }
-
- /* All other alerts are treated as fatal errors */
- conn->closed = 1;
- S2N_ERROR(S2N_ERR_ALERT);
- }
- }
-
- return 0;
-}
-
-int s2n_queue_writer_close_alert_warning(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- uint8_t alert[2];
- alert[0] = S2N_TLS_ALERT_LEVEL_WARNING;
- alert[1] = S2N_TLS_ALERT_CLOSE_NOTIFY;
-
- struct s2n_blob out = {.data = alert,.size = sizeof(alert) };
-
- /* If there is an alert pending or we've already sent a close_notify, do nothing */
- if (s2n_stuffer_data_available(&conn->writer_alert_out) || conn->close_notify_queued) {
- return S2N_SUCCESS;
- }
-
- if (!s2n_alerts_supported(conn)) {
- return S2N_SUCCESS;
- }
-
- GUARD(s2n_stuffer_write(&conn->writer_alert_out, &out));
- conn->close_notify_queued = 1;
-
- return S2N_SUCCESS;
-}
-
-static int s2n_queue_reader_alert(struct s2n_connection *conn, uint8_t level, uint8_t error_code)
-{
- notnull_check(conn);
-
- uint8_t alert[2];
- alert[0] = level;
- alert[1] = error_code;
-
- struct s2n_blob out = {.data = alert,.size = sizeof(alert) };
-
- /* If there is an alert pending, do nothing */
- if (s2n_stuffer_data_available(&conn->reader_alert_out)) {
- return S2N_SUCCESS;
- }
-
- if (!s2n_alerts_supported(conn)) {
- return S2N_SUCCESS;
- }
-
- GUARD(s2n_stuffer_write(&conn->reader_alert_out, &out));
-
- return S2N_SUCCESS;
-}
-
-int s2n_queue_reader_unsupported_protocol_version_alert(struct s2n_connection *conn)
-{
- return s2n_queue_reader_alert(conn, S2N_TLS_ALERT_LEVEL_FATAL, S2N_TLS_ALERT_PROTOCOL_VERSION);
-}
-
-int s2n_queue_reader_handshake_failure_alert(struct s2n_connection *conn)
-{
- return s2n_queue_reader_alert(conn, S2N_TLS_ALERT_LEVEL_FATAL, S2N_TLS_ALERT_HANDSHAKE_FAILURE);
-}
+/*
+ * 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 <stdint.h>
+#include <sys/param.h>
+
+#include "error/s2n_errno.h"
+
+#include "tls/s2n_tls_parameters.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_record.h"
+#include "tls/s2n_resume.h"
+#include "tls/s2n_alerts.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_blob.h"
+
+#define S2N_TLS_ALERT_CLOSE_NOTIFY 0
+#define S2N_TLS_ALERT_UNEXPECTED_MSG 10
+#define S2N_TLS_ALERT_BAD_RECORD_MAC 20
+#define S2N_TLS_ALERT_DECRYPT_FAILED 21
+#define S2N_TLS_ALERT_RECORD_OVERFLOW 22
+#define S2N_TLS_ALERT_DECOMP_FAILED 30
+#define S2N_TLS_ALERT_HANDSHAKE_FAILURE 40
+#define S2N_TLS_ALERT_NO_CERTIFICATE 41
+#define S2N_TLS_ALERT_BAD_CERTIFICATE 42
+#define S2N_TLS_ALERT_UNSUPPORTED_CERT 43
+#define S2N_TLS_ALERT_CERT_REVOKED 44
+#define S2N_TLS_ALERT_CERT_EXPIRED 45
+#define S2N_TLS_ALERT_CERT_UNKNOWN 46
+#define S2N_TLS_ALERT_ILLEGAL_PARAMETER 47
+#define S2N_TLS_ALERT_UNKNOWN_CA 48
+#define S2N_TLS_ALERT_ACCESS_DENIED 49
+#define S2N_TLS_ALERT_DECODE_ERROR 50
+#define S2N_TLS_ALERT_DECRYPT_ERROR 51
+#define S2N_TLS_ALERT_EXPORT_RESTRICTED 60
+#define S2N_TLS_ALERT_PROTOCOL_VERSION 70
+#define S2N_TLS_ALERT_INSUFFICIENT_SECURITY 71
+#define S2N_TLS_ALERT_INTERNAL_ERROR 80
+#define S2N_TLS_ALERT_USER_CANCELED 90
+#define S2N_TLS_ALERT_NO_RENEGOTIATION 100
+#define S2N_TLS_ALERT_UNSUPPORTED_EXTENSION 110
+
+#define S2N_TLS_ALERT_LEVEL_WARNING 1
+#define S2N_TLS_ALERT_LEVEL_FATAL 2
+
+static bool s2n_alerts_supported(struct s2n_connection *conn)
+{
+ /* If running in QUIC mode, QUIC handles alerting.
+ * S2N should not send or receive alerts. */
+ return conn && conn->config && !conn->config->quic_enabled;
+}
+
+static bool s2n_handle_as_warning(struct s2n_connection *conn, uint8_t level, uint8_t type)
+{
+ /* Only TLS1.2 considers the alert level. The alert level field is
+ * considered deprecated in TLS1.3. */
+ if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
+ return level == S2N_TLS_ALERT_LEVEL_WARNING
+ && conn->config->alert_behavior == S2N_ALERT_IGNORE_WARNINGS;
+ }
+
+ /* user_canceled is the only alert currently treated as a warning in TLS1.3.
+ * We need to treat it as a warning regardless of alert_behavior to avoid marking
+ * correctly-closed connections as failed. */
+ return type == S2N_TLS_ALERT_USER_CANCELED;
+}
+
+int s2n_process_alert_fragment(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+ S2N_ERROR_IF(s2n_stuffer_data_available(&conn->in) == 0, S2N_ERR_BAD_MESSAGE);
+ S2N_ERROR_IF(s2n_stuffer_data_available(&conn->alert_in) == 2, S2N_ERR_ALERT_PRESENT);
+ ENSURE_POSIX(s2n_alerts_supported(conn), S2N_ERR_BAD_MESSAGE);
+
+ while (s2n_stuffer_data_available(&conn->in)) {
+ uint8_t bytes_required = 2;
+
+ /* Alerts are two bytes long, but can still be fragmented or coalesced */
+ if (s2n_stuffer_data_available(&conn->alert_in) == 1) {
+ bytes_required = 1;
+ }
+
+ int bytes_to_read = MIN(bytes_required, s2n_stuffer_data_available(&conn->in));
+
+ GUARD(s2n_stuffer_copy(&conn->in, &conn->alert_in, bytes_to_read));
+
+ if (s2n_stuffer_data_available(&conn->alert_in) == 2) {
+
+ /* Close notifications are handled as shutdowns */
+ if (conn->alert_in_data[1] == S2N_TLS_ALERT_CLOSE_NOTIFY) {
+ conn->closed = 1;
+ return 0;
+ }
+
+ /* Ignore warning-level alerts if we're in warning-tolerant mode */
+ if (s2n_handle_as_warning(conn, conn->alert_in_data[0], conn->alert_in_data[1])) {
+ GUARD(s2n_stuffer_wipe(&conn->alert_in));
+ return 0;
+ }
+
+ /* RFC 5077 5.1 - Expire any cached session on an error alert */
+ if (s2n_allowed_to_cache_connection(conn) && conn->session_id_len) {
+ conn->config->cache_delete(conn, conn->config->cache_delete_data, conn->session_id, conn->session_id_len);
+ }
+
+ /* All other alerts are treated as fatal errors */
+ conn->closed = 1;
+ S2N_ERROR(S2N_ERR_ALERT);
+ }
+ }
+
+ return 0;
+}
+
+int s2n_queue_writer_close_alert_warning(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ uint8_t alert[2];
+ alert[0] = S2N_TLS_ALERT_LEVEL_WARNING;
+ alert[1] = S2N_TLS_ALERT_CLOSE_NOTIFY;
+
+ struct s2n_blob out = {.data = alert,.size = sizeof(alert) };
+
+ /* If there is an alert pending or we've already sent a close_notify, do nothing */
+ if (s2n_stuffer_data_available(&conn->writer_alert_out) || conn->close_notify_queued) {
+ return S2N_SUCCESS;
+ }
+
+ if (!s2n_alerts_supported(conn)) {
+ return S2N_SUCCESS;
+ }
+
+ GUARD(s2n_stuffer_write(&conn->writer_alert_out, &out));
+ conn->close_notify_queued = 1;
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_queue_reader_alert(struct s2n_connection *conn, uint8_t level, uint8_t error_code)
+{
+ notnull_check(conn);
+
+ uint8_t alert[2];
+ alert[0] = level;
+ alert[1] = error_code;
+
+ struct s2n_blob out = {.data = alert,.size = sizeof(alert) };
+
+ /* If there is an alert pending, do nothing */
+ if (s2n_stuffer_data_available(&conn->reader_alert_out)) {
+ return S2N_SUCCESS;
+ }
+
+ if (!s2n_alerts_supported(conn)) {
+ return S2N_SUCCESS;
+ }
+
+ GUARD(s2n_stuffer_write(&conn->reader_alert_out, &out));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_queue_reader_unsupported_protocol_version_alert(struct s2n_connection *conn)
+{
+ return s2n_queue_reader_alert(conn, S2N_TLS_ALERT_LEVEL_FATAL, S2N_TLS_ALERT_PROTOCOL_VERSION);
+}
+
+int s2n_queue_reader_handshake_failure_alert(struct s2n_connection *conn)
+{
+ return s2n_queue_reader_alert(conn, S2N_TLS_ALERT_LEVEL_FATAL, S2N_TLS_ALERT_HANDSHAKE_FAILURE);
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_alerts.h b/contrib/restricted/aws/s2n/tls/s2n_alerts.h
index 74194022cc..694c64068c 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_alerts.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_alerts.h
@@ -1,25 +1,25 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <stdint.h>
-
-#include "tls/s2n_connection.h"
-
-extern int s2n_process_alert_fragment(struct s2n_connection *conn);
-extern int s2n_queue_writer_close_alert_warning(struct s2n_connection *conn);
-extern int s2n_queue_reader_unsupported_protocol_version_alert(struct s2n_connection *conn);
-extern int s2n_queue_reader_handshake_failure_alert(struct s2n_connection *conn);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#include "tls/s2n_connection.h"
+
+extern int s2n_process_alert_fragment(struct s2n_connection *conn);
+extern int s2n_queue_writer_close_alert_warning(struct s2n_connection *conn);
+extern int s2n_queue_reader_unsupported_protocol_version_alert(struct s2n_connection *conn);
+extern int s2n_queue_reader_handshake_failure_alert(struct s2n_connection *conn);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_async_pkey.c b/contrib/restricted/aws/s2n/tls/s2n_async_pkey.c
index 722b38dd98..15c539da6b 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_async_pkey.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_async_pkey.c
@@ -1,411 +1,411 @@
-/*
- * 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 "tls/s2n_async_pkey.h"
-
-#include "crypto/s2n_hash.h"
-#include "crypto/s2n_signature.h"
-#include "error/s2n_errno.h"
-#include "s2n.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_handshake.h"
-#include "utils/s2n_blob.h"
-#include "utils/s2n_mem.h"
-#include "utils/s2n_result.h"
-#include "utils/s2n_safety.h"
-
-typedef enum { S2N_ASYNC_DECRYPT, S2N_ASYNC_SIGN } s2n_async_pkey_op_type;
-
-struct s2n_async_pkey_decrypt_data {
- s2n_async_pkey_decrypt_complete on_complete;
- struct s2n_blob encrypted;
- struct s2n_blob decrypted;
- unsigned rsa_failed : 1;
-};
-
-struct s2n_async_pkey_sign_data {
- s2n_async_pkey_sign_complete on_complete;
- struct s2n_hash_state digest;
- s2n_signature_algorithm sig_alg;
- struct s2n_blob signature;
-};
-
-struct s2n_async_pkey_op {
- s2n_async_pkey_op_type type;
- struct s2n_connection *conn;
- unsigned complete : 1;
- unsigned applied : 1;
- union {
- struct s2n_async_pkey_decrypt_data decrypt;
- struct s2n_async_pkey_sign_data sign;
- } op;
-};
-
-struct s2n_async_pkey_op_actions {
- S2N_RESULT (*perform)(struct s2n_async_pkey_op *op, s2n_cert_private_key *pkey);
- S2N_RESULT (*apply)(struct s2n_async_pkey_op *op, struct s2n_connection *conn);
- S2N_RESULT (*free)(struct s2n_async_pkey_op *op);
-};
-
-static S2N_RESULT s2n_async_get_actions(s2n_async_pkey_op_type type, const struct s2n_async_pkey_op_actions **actions);
-
-static S2N_RESULT s2n_async_pkey_op_allocate(struct s2n_async_pkey_op **op);
-
-static S2N_RESULT s2n_async_pkey_sign_async(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
- struct s2n_hash_state *digest, s2n_async_pkey_sign_complete on_complete);
-static S2N_RESULT s2n_async_pkey_sign_sync(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
- struct s2n_hash_state *digest, s2n_async_pkey_sign_complete on_complete);
-
-static S2N_RESULT s2n_async_pkey_decrypt_async(struct s2n_connection *conn, struct s2n_blob *encrypted,
- struct s2n_blob * init_decrypted,
- s2n_async_pkey_decrypt_complete on_complete);
-static S2N_RESULT s2n_async_pkey_decrypt_sync(struct s2n_connection *conn, struct s2n_blob *encrypted,
- struct s2n_blob * init_decrypted,
- s2n_async_pkey_decrypt_complete on_complete);
-
-static S2N_RESULT s2n_async_pkey_decrypt_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *pkey);
-static S2N_RESULT s2n_async_pkey_decrypt_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn);
-static S2N_RESULT s2n_async_pkey_decrypt_free(struct s2n_async_pkey_op *op);
-
-static S2N_RESULT s2n_async_pkey_sign_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *pkey);
-static S2N_RESULT s2n_async_pkey_sign_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn);
-static S2N_RESULT s2n_async_pkey_sign_free(struct s2n_async_pkey_op *op);
-
-static const struct s2n_async_pkey_op_actions s2n_async_pkey_decrypt_op = { .perform = &s2n_async_pkey_decrypt_perform,
- .apply = &s2n_async_pkey_decrypt_apply,
- .free = &s2n_async_pkey_decrypt_free };
-
-static const struct s2n_async_pkey_op_actions s2n_async_pkey_sign_op = { .perform = &s2n_async_pkey_sign_perform,
- .apply = &s2n_async_pkey_sign_apply,
- .free = &s2n_async_pkey_sign_free };
-
-DEFINE_POINTER_CLEANUP_FUNC(struct s2n_async_pkey_op *, s2n_async_pkey_op_free);
-
-static S2N_RESULT s2n_async_get_actions(s2n_async_pkey_op_type type, const struct s2n_async_pkey_op_actions **actions)
-{
- ENSURE_REF(actions);
-
- switch (type) {
- case S2N_ASYNC_DECRYPT:
- *actions = &s2n_async_pkey_decrypt_op;
- return S2N_RESULT_OK;
- case S2N_ASYNC_SIGN:
- *actions = &s2n_async_pkey_sign_op;
- return S2N_RESULT_OK;
- /* No default for compiler warnings */
- }
-
- return S2N_RESULT_ERROR;
-}
-
-static S2N_RESULT s2n_async_pkey_op_allocate(struct s2n_async_pkey_op **op)
-{
- ENSURE_REF(op);
- ENSURE(*op == NULL, S2N_ERR_SAFETY);
-
- /* allocate memory */
- DEFER_CLEANUP(struct s2n_blob mem = {0}, s2n_free);
- GUARD_AS_RESULT(s2n_alloc(&mem, sizeof(struct s2n_async_pkey_op)));
- GUARD_AS_RESULT(s2n_blob_zero(&mem));
-
- *op = (void *) mem.data;
- if (s2n_blob_init(&mem, NULL, 0) != S2N_SUCCESS) {
- *op = NULL;
- return S2N_RESULT_ERROR;
- }
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_async_pkey_decrypt(struct s2n_connection *conn, struct s2n_blob *encrypted,
- struct s2n_blob *init_decrypted, s2n_async_pkey_decrypt_complete on_complete)
-{
- ENSURE_REF(conn);
- ENSURE_REF(encrypted);
- ENSURE_REF(init_decrypted);
- ENSURE_REF(on_complete);
-
- if (conn->config->async_pkey_cb) {
- GUARD_RESULT(s2n_async_pkey_decrypt_async(conn, encrypted, init_decrypted, on_complete));
- } else {
- GUARD_RESULT(s2n_async_pkey_decrypt_sync(conn, encrypted, init_decrypted, on_complete));
- }
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_async_pkey_decrypt_async(struct s2n_connection *conn, struct s2n_blob *encrypted,
- struct s2n_blob *init_decrypted, s2n_async_pkey_decrypt_complete on_complete)
-{
- ENSURE_REF(conn);
- ENSURE_REF(encrypted);
- ENSURE_REF(init_decrypted);
- ENSURE_REF(on_complete);
- ENSURE(conn->handshake.async_state == S2N_ASYNC_NOT_INVOKED, S2N_ERR_ASYNC_MORE_THAN_ONE);
-
- DEFER_CLEANUP(struct s2n_async_pkey_op *op = NULL, s2n_async_pkey_op_free_pointer);
- GUARD_RESULT(s2n_async_pkey_op_allocate(&op));
-
- op->type = S2N_ASYNC_DECRYPT;
- op->conn = conn;
-
- struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;
- decrypt->on_complete = on_complete;
-
- GUARD_AS_RESULT(s2n_dup(encrypted, &decrypt->encrypted));
- GUARD_AS_RESULT(s2n_dup(init_decrypted, &decrypt->decrypted));
-
- /* Block the handshake and set async state to invoking to block async states */
- GUARD_AS_RESULT(s2n_conn_set_handshake_read_block(conn));
- conn->handshake.async_state = S2N_ASYNC_INVOKING_CALLBACK;
-
- /* Move op to tmp to avoid DEFER_CLEANUP freeing the op, as it will be owned by callback */
- struct s2n_async_pkey_op *tmp_op = op;
- op = NULL;
-
- ENSURE(conn->config->async_pkey_cb(conn, tmp_op) == S2N_SUCCESS, S2N_ERR_ASYNC_CALLBACK_FAILED);
-
- /* Set state to waiting to allow op to be consumed by connection */
- conn->handshake.async_state = S2N_ASYNC_INVOKED_WAITING;
-
- /* Return an async blocked error to drop out of s2n_negotiate loop */
- BAIL(S2N_ERR_ASYNC_BLOCKED);
-}
-
-S2N_RESULT s2n_async_pkey_decrypt_sync(struct s2n_connection *conn, struct s2n_blob *encrypted,
- struct s2n_blob *init_decrypted, s2n_async_pkey_decrypt_complete on_complete)
-{
- ENSURE_REF(conn);
- ENSURE_REF(encrypted);
- ENSURE_REF(init_decrypted);
- ENSURE_REF(on_complete);
-
- const struct s2n_pkey *pkey = conn->handshake_params.our_chain_and_key->private_key;
-
- bool rsa_failed = s2n_pkey_decrypt(pkey, encrypted, init_decrypted) != S2N_SUCCESS;
- GUARD_AS_RESULT(on_complete(conn, rsa_failed, init_decrypted));
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_async_pkey_sign(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
- struct s2n_hash_state *digest, s2n_async_pkey_sign_complete on_complete)
-{
- ENSURE_REF(conn);
- ENSURE_REF(digest);
- ENSURE_REF(on_complete);
-
- if (conn->config->async_pkey_cb) {
- GUARD_RESULT(s2n_async_pkey_sign_async(conn, sig_alg, digest, on_complete));
- } else {
- GUARD_RESULT(s2n_async_pkey_sign_sync(conn, sig_alg, digest, on_complete));
- }
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_async_pkey_sign_async(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
- struct s2n_hash_state *digest, s2n_async_pkey_sign_complete on_complete)
-{
- ENSURE_REF(conn);
- ENSURE_REF(digest);
- ENSURE_REF(on_complete);
- ENSURE(conn->handshake.async_state == S2N_ASYNC_NOT_INVOKED, S2N_ERR_ASYNC_MORE_THAN_ONE);
-
- DEFER_CLEANUP(struct s2n_async_pkey_op *op = NULL, s2n_async_pkey_op_free_pointer);
- GUARD_RESULT(s2n_async_pkey_op_allocate(&op));
-
- op->type = S2N_ASYNC_SIGN;
- op->conn = conn;
-
- struct s2n_async_pkey_sign_data *sign = &op->op.sign;
- sign->on_complete = on_complete;
- sign->sig_alg = sig_alg;
-
- GUARD_AS_RESULT(s2n_hash_new(&sign->digest));
- GUARD_AS_RESULT(s2n_hash_copy(&sign->digest, digest));
-
- /* Block the handshake and set async state to invoking to block async states */
- GUARD_AS_RESULT(s2n_conn_set_handshake_read_block(conn));
- conn->handshake.async_state = S2N_ASYNC_INVOKING_CALLBACK;
-
- /* Move op to tmp to avoid DEFER_CLEANUP freeing the op, as it will be owned by callback */
- struct s2n_async_pkey_op *tmp_op = op;
- op = NULL;
-
- ENSURE(conn->config->async_pkey_cb(conn, tmp_op) == S2N_SUCCESS, S2N_ERR_ASYNC_CALLBACK_FAILED);
-
- /* Set state to waiting to allow op to be consumed by connection */
- conn->handshake.async_state = S2N_ASYNC_INVOKED_WAITING;
-
- /* Return an async blocked error to drop out of s2n_negotiate loop */
- BAIL(S2N_ERR_ASYNC_BLOCKED);
-}
-
-S2N_RESULT s2n_async_pkey_sign_sync(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
- struct s2n_hash_state *digest, s2n_async_pkey_sign_complete on_complete)
-{
- ENSURE_REF(conn);
- ENSURE_REF(digest);
- ENSURE_REF(on_complete);
-
- const struct s2n_pkey *pkey = conn->handshake_params.our_chain_and_key->private_key;
- DEFER_CLEANUP(struct s2n_blob signed_content = { 0 }, s2n_free);
-
- uint32_t maximum_signature_length = s2n_pkey_size(pkey);
- GUARD_AS_RESULT(s2n_alloc(&signed_content, maximum_signature_length));
-
- GUARD_AS_RESULT(s2n_pkey_sign(pkey, sig_alg, digest, &signed_content));
-
- GUARD_AS_RESULT(on_complete(conn, &signed_content));
-
- return S2N_RESULT_OK;
-}
-
-int s2n_async_pkey_op_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *key)
-{
- ENSURE_POSIX_REF(op);
- ENSURE_POSIX_REF(key);
- ENSURE_POSIX(!op->complete, S2N_ERR_ASYNC_ALREADY_PERFORMED);
-
- const struct s2n_async_pkey_op_actions *actions = NULL;
- GUARD_AS_POSIX(s2n_async_get_actions(op->type, &actions));
- notnull_check(actions);
-
- GUARD_AS_POSIX(actions->perform(op, key));
-
- op->complete = true;
-
- return S2N_SUCCESS;
-}
-
-int s2n_async_pkey_op_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn)
-{
- ENSURE_POSIX_REF(op);
- ENSURE_POSIX_REF(conn);
- ENSURE_POSIX(op->complete, S2N_ERR_ASYNC_NOT_PERFORMED);
- ENSURE_POSIX(!op->applied, S2N_ERR_ASYNC_ALREADY_APPLIED);
- /* We could have just used op->conn and removed a conn argument, but we want caller
- * to be explicit about connection it wants to resume. Plus this gives more
- * protections in cases if caller frees connection object and then tries to resume
- * the connection. */
- ENSURE_POSIX(op->conn == conn, S2N_ERR_ASYNC_WRONG_CONNECTION);
- ENSURE_POSIX(conn->handshake.async_state != S2N_ASYNC_INVOKING_CALLBACK, S2N_ERR_ASYNC_APPLY_WHILE_INVOKING);
- ENSURE_POSIX(conn->handshake.async_state == S2N_ASYNC_INVOKED_WAITING, S2N_ERR_ASYNC_WRONG_CONNECTION);
-
- const struct s2n_async_pkey_op_actions *actions = NULL;
- GUARD_AS_POSIX(s2n_async_get_actions(op->type, &actions));
- notnull_check(actions);
-
- GUARD_AS_POSIX(actions->apply(op, conn));
-
- op->applied = true;
- conn->handshake.async_state = S2N_ASYNC_INVOKED_COMPLETE;
-
- /* Free up the decrypt/sign structs to avoid storing secrets for too long */
- GUARD_AS_POSIX(actions->free(op));
-
- return S2N_SUCCESS;
-}
-
-int s2n_async_pkey_op_free(struct s2n_async_pkey_op *op)
-{
- ENSURE_POSIX_REF(op);
- const struct s2n_async_pkey_op_actions *actions = NULL;
- GUARD_AS_POSIX(s2n_async_get_actions(op->type, &actions));
- notnull_check(actions);
-
- /* If applied the decrypt/sign structs were released in apply call */
- if (!op->applied) { GUARD_AS_POSIX(actions->free(op)); }
-
- GUARD_POSIX(s2n_free_object(( uint8_t ** )&op, sizeof(struct s2n_async_pkey_op)));
-
- return S2N_SUCCESS;
-}
-
-S2N_RESULT s2n_async_pkey_decrypt_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *pkey)
-{
- ENSURE_REF(op);
- ENSURE_REF(pkey);
-
- struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;
-
- decrypt->rsa_failed = s2n_pkey_decrypt(pkey, &decrypt->encrypted, &decrypt->decrypted) != S2N_SUCCESS;
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_async_pkey_decrypt_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn)
-{
- ENSURE_REF(op);
- ENSURE_REF(conn);
-
- struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;
-
- GUARD_AS_RESULT(decrypt->on_complete(conn, decrypt->rsa_failed, &decrypt->decrypted));
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_async_pkey_decrypt_free(struct s2n_async_pkey_op *op)
-{
- ENSURE_REF(op);
-
- struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;
-
- GUARD_AS_RESULT(s2n_blob_zero(&decrypt->decrypted));
- GUARD_AS_RESULT(s2n_blob_zero(&decrypt->encrypted));
- GUARD_AS_RESULT(s2n_free(&decrypt->decrypted));
- GUARD_AS_RESULT(s2n_free(&decrypt->encrypted));
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_async_pkey_sign_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *pkey)
-{
- ENSURE_REF(op);
- ENSURE_REF(pkey);
-
- struct s2n_async_pkey_sign_data *sign = &op->op.sign;
-
- uint32_t maximum_signature_length = s2n_pkey_size(pkey);
- GUARD_AS_RESULT(s2n_alloc(&sign->signature, maximum_signature_length));
-
- GUARD_AS_RESULT(s2n_pkey_sign(pkey, sign->sig_alg, &sign->digest, &sign->signature));
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_async_pkey_sign_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn)
-{
- ENSURE_REF(op);
- ENSURE_REF(conn);
-
- struct s2n_async_pkey_sign_data *sign = &op->op.sign;
-
- GUARD_AS_RESULT(sign->on_complete(conn, &sign->signature));
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_async_pkey_sign_free(struct s2n_async_pkey_op *op)
-{
- ENSURE_REF(op);
-
- struct s2n_async_pkey_sign_data *sign = &op->op.sign;
-
- GUARD_AS_RESULT(s2n_hash_free(&sign->digest));
- GUARD_AS_RESULT(s2n_free(&sign->signature));
-
- return S2N_RESULT_OK;
-}
+/*
+ * 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 "tls/s2n_async_pkey.h"
+
+#include "crypto/s2n_hash.h"
+#include "crypto/s2n_signature.h"
+#include "error/s2n_errno.h"
+#include "s2n.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_handshake.h"
+#include "utils/s2n_blob.h"
+#include "utils/s2n_mem.h"
+#include "utils/s2n_result.h"
+#include "utils/s2n_safety.h"
+
+typedef enum { S2N_ASYNC_DECRYPT, S2N_ASYNC_SIGN } s2n_async_pkey_op_type;
+
+struct s2n_async_pkey_decrypt_data {
+ s2n_async_pkey_decrypt_complete on_complete;
+ struct s2n_blob encrypted;
+ struct s2n_blob decrypted;
+ unsigned rsa_failed : 1;
+};
+
+struct s2n_async_pkey_sign_data {
+ s2n_async_pkey_sign_complete on_complete;
+ struct s2n_hash_state digest;
+ s2n_signature_algorithm sig_alg;
+ struct s2n_blob signature;
+};
+
+struct s2n_async_pkey_op {
+ s2n_async_pkey_op_type type;
+ struct s2n_connection *conn;
+ unsigned complete : 1;
+ unsigned applied : 1;
+ union {
+ struct s2n_async_pkey_decrypt_data decrypt;
+ struct s2n_async_pkey_sign_data sign;
+ } op;
+};
+
+struct s2n_async_pkey_op_actions {
+ S2N_RESULT (*perform)(struct s2n_async_pkey_op *op, s2n_cert_private_key *pkey);
+ S2N_RESULT (*apply)(struct s2n_async_pkey_op *op, struct s2n_connection *conn);
+ S2N_RESULT (*free)(struct s2n_async_pkey_op *op);
+};
+
+static S2N_RESULT s2n_async_get_actions(s2n_async_pkey_op_type type, const struct s2n_async_pkey_op_actions **actions);
+
+static S2N_RESULT s2n_async_pkey_op_allocate(struct s2n_async_pkey_op **op);
+
+static S2N_RESULT s2n_async_pkey_sign_async(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
+ struct s2n_hash_state *digest, s2n_async_pkey_sign_complete on_complete);
+static S2N_RESULT s2n_async_pkey_sign_sync(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
+ struct s2n_hash_state *digest, s2n_async_pkey_sign_complete on_complete);
+
+static S2N_RESULT s2n_async_pkey_decrypt_async(struct s2n_connection *conn, struct s2n_blob *encrypted,
+ struct s2n_blob * init_decrypted,
+ s2n_async_pkey_decrypt_complete on_complete);
+static S2N_RESULT s2n_async_pkey_decrypt_sync(struct s2n_connection *conn, struct s2n_blob *encrypted,
+ struct s2n_blob * init_decrypted,
+ s2n_async_pkey_decrypt_complete on_complete);
+
+static S2N_RESULT s2n_async_pkey_decrypt_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *pkey);
+static S2N_RESULT s2n_async_pkey_decrypt_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn);
+static S2N_RESULT s2n_async_pkey_decrypt_free(struct s2n_async_pkey_op *op);
+
+static S2N_RESULT s2n_async_pkey_sign_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *pkey);
+static S2N_RESULT s2n_async_pkey_sign_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn);
+static S2N_RESULT s2n_async_pkey_sign_free(struct s2n_async_pkey_op *op);
+
+static const struct s2n_async_pkey_op_actions s2n_async_pkey_decrypt_op = { .perform = &s2n_async_pkey_decrypt_perform,
+ .apply = &s2n_async_pkey_decrypt_apply,
+ .free = &s2n_async_pkey_decrypt_free };
+
+static const struct s2n_async_pkey_op_actions s2n_async_pkey_sign_op = { .perform = &s2n_async_pkey_sign_perform,
+ .apply = &s2n_async_pkey_sign_apply,
+ .free = &s2n_async_pkey_sign_free };
+
+DEFINE_POINTER_CLEANUP_FUNC(struct s2n_async_pkey_op *, s2n_async_pkey_op_free);
+
+static S2N_RESULT s2n_async_get_actions(s2n_async_pkey_op_type type, const struct s2n_async_pkey_op_actions **actions)
+{
+ ENSURE_REF(actions);
+
+ switch (type) {
+ case S2N_ASYNC_DECRYPT:
+ *actions = &s2n_async_pkey_decrypt_op;
+ return S2N_RESULT_OK;
+ case S2N_ASYNC_SIGN:
+ *actions = &s2n_async_pkey_sign_op;
+ return S2N_RESULT_OK;
+ /* No default for compiler warnings */
+ }
+
+ return S2N_RESULT_ERROR;
+}
+
+static S2N_RESULT s2n_async_pkey_op_allocate(struct s2n_async_pkey_op **op)
+{
+ ENSURE_REF(op);
+ ENSURE(*op == NULL, S2N_ERR_SAFETY);
+
+ /* allocate memory */
+ DEFER_CLEANUP(struct s2n_blob mem = {0}, s2n_free);
+ GUARD_AS_RESULT(s2n_alloc(&mem, sizeof(struct s2n_async_pkey_op)));
+ GUARD_AS_RESULT(s2n_blob_zero(&mem));
+
+ *op = (void *) mem.data;
+ if (s2n_blob_init(&mem, NULL, 0) != S2N_SUCCESS) {
+ *op = NULL;
+ return S2N_RESULT_ERROR;
+ }
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_async_pkey_decrypt(struct s2n_connection *conn, struct s2n_blob *encrypted,
+ struct s2n_blob *init_decrypted, s2n_async_pkey_decrypt_complete on_complete)
+{
+ ENSURE_REF(conn);
+ ENSURE_REF(encrypted);
+ ENSURE_REF(init_decrypted);
+ ENSURE_REF(on_complete);
+
+ if (conn->config->async_pkey_cb) {
+ GUARD_RESULT(s2n_async_pkey_decrypt_async(conn, encrypted, init_decrypted, on_complete));
+ } else {
+ GUARD_RESULT(s2n_async_pkey_decrypt_sync(conn, encrypted, init_decrypted, on_complete));
+ }
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_async_pkey_decrypt_async(struct s2n_connection *conn, struct s2n_blob *encrypted,
+ struct s2n_blob *init_decrypted, s2n_async_pkey_decrypt_complete on_complete)
+{
+ ENSURE_REF(conn);
+ ENSURE_REF(encrypted);
+ ENSURE_REF(init_decrypted);
+ ENSURE_REF(on_complete);
+ ENSURE(conn->handshake.async_state == S2N_ASYNC_NOT_INVOKED, S2N_ERR_ASYNC_MORE_THAN_ONE);
+
+ DEFER_CLEANUP(struct s2n_async_pkey_op *op = NULL, s2n_async_pkey_op_free_pointer);
+ GUARD_RESULT(s2n_async_pkey_op_allocate(&op));
+
+ op->type = S2N_ASYNC_DECRYPT;
+ op->conn = conn;
+
+ struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;
+ decrypt->on_complete = on_complete;
+
+ GUARD_AS_RESULT(s2n_dup(encrypted, &decrypt->encrypted));
+ GUARD_AS_RESULT(s2n_dup(init_decrypted, &decrypt->decrypted));
+
+ /* Block the handshake and set async state to invoking to block async states */
+ GUARD_AS_RESULT(s2n_conn_set_handshake_read_block(conn));
+ conn->handshake.async_state = S2N_ASYNC_INVOKING_CALLBACK;
+
+ /* Move op to tmp to avoid DEFER_CLEANUP freeing the op, as it will be owned by callback */
+ struct s2n_async_pkey_op *tmp_op = op;
+ op = NULL;
+
+ ENSURE(conn->config->async_pkey_cb(conn, tmp_op) == S2N_SUCCESS, S2N_ERR_ASYNC_CALLBACK_FAILED);
+
+ /* Set state to waiting to allow op to be consumed by connection */
+ conn->handshake.async_state = S2N_ASYNC_INVOKED_WAITING;
+
+ /* Return an async blocked error to drop out of s2n_negotiate loop */
+ BAIL(S2N_ERR_ASYNC_BLOCKED);
+}
+
+S2N_RESULT s2n_async_pkey_decrypt_sync(struct s2n_connection *conn, struct s2n_blob *encrypted,
+ struct s2n_blob *init_decrypted, s2n_async_pkey_decrypt_complete on_complete)
+{
+ ENSURE_REF(conn);
+ ENSURE_REF(encrypted);
+ ENSURE_REF(init_decrypted);
+ ENSURE_REF(on_complete);
+
+ const struct s2n_pkey *pkey = conn->handshake_params.our_chain_and_key->private_key;
+
+ bool rsa_failed = s2n_pkey_decrypt(pkey, encrypted, init_decrypted) != S2N_SUCCESS;
+ GUARD_AS_RESULT(on_complete(conn, rsa_failed, init_decrypted));
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_async_pkey_sign(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
+ struct s2n_hash_state *digest, s2n_async_pkey_sign_complete on_complete)
+{
+ ENSURE_REF(conn);
+ ENSURE_REF(digest);
+ ENSURE_REF(on_complete);
+
+ if (conn->config->async_pkey_cb) {
+ GUARD_RESULT(s2n_async_pkey_sign_async(conn, sig_alg, digest, on_complete));
+ } else {
+ GUARD_RESULT(s2n_async_pkey_sign_sync(conn, sig_alg, digest, on_complete));
+ }
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_async_pkey_sign_async(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
+ struct s2n_hash_state *digest, s2n_async_pkey_sign_complete on_complete)
+{
+ ENSURE_REF(conn);
+ ENSURE_REF(digest);
+ ENSURE_REF(on_complete);
+ ENSURE(conn->handshake.async_state == S2N_ASYNC_NOT_INVOKED, S2N_ERR_ASYNC_MORE_THAN_ONE);
+
+ DEFER_CLEANUP(struct s2n_async_pkey_op *op = NULL, s2n_async_pkey_op_free_pointer);
+ GUARD_RESULT(s2n_async_pkey_op_allocate(&op));
+
+ op->type = S2N_ASYNC_SIGN;
+ op->conn = conn;
+
+ struct s2n_async_pkey_sign_data *sign = &op->op.sign;
+ sign->on_complete = on_complete;
+ sign->sig_alg = sig_alg;
+
+ GUARD_AS_RESULT(s2n_hash_new(&sign->digest));
+ GUARD_AS_RESULT(s2n_hash_copy(&sign->digest, digest));
+
+ /* Block the handshake and set async state to invoking to block async states */
+ GUARD_AS_RESULT(s2n_conn_set_handshake_read_block(conn));
+ conn->handshake.async_state = S2N_ASYNC_INVOKING_CALLBACK;
+
+ /* Move op to tmp to avoid DEFER_CLEANUP freeing the op, as it will be owned by callback */
+ struct s2n_async_pkey_op *tmp_op = op;
+ op = NULL;
+
+ ENSURE(conn->config->async_pkey_cb(conn, tmp_op) == S2N_SUCCESS, S2N_ERR_ASYNC_CALLBACK_FAILED);
+
+ /* Set state to waiting to allow op to be consumed by connection */
+ conn->handshake.async_state = S2N_ASYNC_INVOKED_WAITING;
+
+ /* Return an async blocked error to drop out of s2n_negotiate loop */
+ BAIL(S2N_ERR_ASYNC_BLOCKED);
+}
+
+S2N_RESULT s2n_async_pkey_sign_sync(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
+ struct s2n_hash_state *digest, s2n_async_pkey_sign_complete on_complete)
+{
+ ENSURE_REF(conn);
+ ENSURE_REF(digest);
+ ENSURE_REF(on_complete);
+
+ const struct s2n_pkey *pkey = conn->handshake_params.our_chain_and_key->private_key;
+ DEFER_CLEANUP(struct s2n_blob signed_content = { 0 }, s2n_free);
+
+ uint32_t maximum_signature_length = s2n_pkey_size(pkey);
+ GUARD_AS_RESULT(s2n_alloc(&signed_content, maximum_signature_length));
+
+ GUARD_AS_RESULT(s2n_pkey_sign(pkey, sig_alg, digest, &signed_content));
+
+ GUARD_AS_RESULT(on_complete(conn, &signed_content));
+
+ return S2N_RESULT_OK;
+}
+
+int s2n_async_pkey_op_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *key)
+{
+ ENSURE_POSIX_REF(op);
+ ENSURE_POSIX_REF(key);
+ ENSURE_POSIX(!op->complete, S2N_ERR_ASYNC_ALREADY_PERFORMED);
+
+ const struct s2n_async_pkey_op_actions *actions = NULL;
+ GUARD_AS_POSIX(s2n_async_get_actions(op->type, &actions));
+ notnull_check(actions);
+
+ GUARD_AS_POSIX(actions->perform(op, key));
+
+ op->complete = true;
+
+ return S2N_SUCCESS;
+}
+
+int s2n_async_pkey_op_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn)
+{
+ ENSURE_POSIX_REF(op);
+ ENSURE_POSIX_REF(conn);
+ ENSURE_POSIX(op->complete, S2N_ERR_ASYNC_NOT_PERFORMED);
+ ENSURE_POSIX(!op->applied, S2N_ERR_ASYNC_ALREADY_APPLIED);
+ /* We could have just used op->conn and removed a conn argument, but we want caller
+ * to be explicit about connection it wants to resume. Plus this gives more
+ * protections in cases if caller frees connection object and then tries to resume
+ * the connection. */
+ ENSURE_POSIX(op->conn == conn, S2N_ERR_ASYNC_WRONG_CONNECTION);
+ ENSURE_POSIX(conn->handshake.async_state != S2N_ASYNC_INVOKING_CALLBACK, S2N_ERR_ASYNC_APPLY_WHILE_INVOKING);
+ ENSURE_POSIX(conn->handshake.async_state == S2N_ASYNC_INVOKED_WAITING, S2N_ERR_ASYNC_WRONG_CONNECTION);
+
+ const struct s2n_async_pkey_op_actions *actions = NULL;
+ GUARD_AS_POSIX(s2n_async_get_actions(op->type, &actions));
+ notnull_check(actions);
+
+ GUARD_AS_POSIX(actions->apply(op, conn));
+
+ op->applied = true;
+ conn->handshake.async_state = S2N_ASYNC_INVOKED_COMPLETE;
+
+ /* Free up the decrypt/sign structs to avoid storing secrets for too long */
+ GUARD_AS_POSIX(actions->free(op));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_async_pkey_op_free(struct s2n_async_pkey_op *op)
+{
+ ENSURE_POSIX_REF(op);
+ const struct s2n_async_pkey_op_actions *actions = NULL;
+ GUARD_AS_POSIX(s2n_async_get_actions(op->type, &actions));
+ notnull_check(actions);
+
+ /* If applied the decrypt/sign structs were released in apply call */
+ if (!op->applied) { GUARD_AS_POSIX(actions->free(op)); }
+
+ GUARD_POSIX(s2n_free_object(( uint8_t ** )&op, sizeof(struct s2n_async_pkey_op)));
+
+ return S2N_SUCCESS;
+}
+
+S2N_RESULT s2n_async_pkey_decrypt_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *pkey)
+{
+ ENSURE_REF(op);
+ ENSURE_REF(pkey);
+
+ struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;
+
+ decrypt->rsa_failed = s2n_pkey_decrypt(pkey, &decrypt->encrypted, &decrypt->decrypted) != S2N_SUCCESS;
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_async_pkey_decrypt_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn)
+{
+ ENSURE_REF(op);
+ ENSURE_REF(conn);
+
+ struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;
+
+ GUARD_AS_RESULT(decrypt->on_complete(conn, decrypt->rsa_failed, &decrypt->decrypted));
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_async_pkey_decrypt_free(struct s2n_async_pkey_op *op)
+{
+ ENSURE_REF(op);
+
+ struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;
+
+ GUARD_AS_RESULT(s2n_blob_zero(&decrypt->decrypted));
+ GUARD_AS_RESULT(s2n_blob_zero(&decrypt->encrypted));
+ GUARD_AS_RESULT(s2n_free(&decrypt->decrypted));
+ GUARD_AS_RESULT(s2n_free(&decrypt->encrypted));
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_async_pkey_sign_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *pkey)
+{
+ ENSURE_REF(op);
+ ENSURE_REF(pkey);
+
+ struct s2n_async_pkey_sign_data *sign = &op->op.sign;
+
+ uint32_t maximum_signature_length = s2n_pkey_size(pkey);
+ GUARD_AS_RESULT(s2n_alloc(&sign->signature, maximum_signature_length));
+
+ GUARD_AS_RESULT(s2n_pkey_sign(pkey, sign->sig_alg, &sign->digest, &sign->signature));
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_async_pkey_sign_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn)
+{
+ ENSURE_REF(op);
+ ENSURE_REF(conn);
+
+ struct s2n_async_pkey_sign_data *sign = &op->op.sign;
+
+ GUARD_AS_RESULT(sign->on_complete(conn, &sign->signature));
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_async_pkey_sign_free(struct s2n_async_pkey_op *op)
+{
+ ENSURE_REF(op);
+
+ struct s2n_async_pkey_sign_data *sign = &op->op.sign;
+
+ GUARD_AS_RESULT(s2n_hash_free(&sign->digest));
+ GUARD_AS_RESULT(s2n_free(&sign->signature));
+
+ return S2N_RESULT_OK;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_async_pkey.h b/contrib/restricted/aws/s2n/tls/s2n_async_pkey.h
index d829d75a7e..2ef8386d2f 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_async_pkey.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_async_pkey.h
@@ -1,71 +1,71 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/s2n_connection.h"
-#include "utils/s2n_blob.h"
-#include "utils/s2n_result.h"
-
-typedef int (*s2n_async_pkey_sign_complete)(struct s2n_connection *conn, struct s2n_blob *signature);
-typedef int (*s2n_async_pkey_decrypt_complete)(struct s2n_connection *conn, bool rsa_failed, struct s2n_blob *decrypted);
-
-struct s2n_async_pkey_op;
-
-/* Guard to handle async states inside handler which uses async pkey operations. If async operation was not invoked
- * it means that we enter this handler for the first time and handler may or may not use async operation, so we let it
- * continue. If async operation is invoking or was invoked, but yet to be complete, we error out of the handler to let
- * s2n_handle_retry_state try again. If async operation was complete we clear the state and let s2n_handle_retry_state
- * proceed to the next handler */
-#define S2N_ASYNC_PKEY_GUARD(conn) \
- do { \
- __typeof(conn) __tmp_conn = (conn); \
- GUARD_NONNULL(__tmp_conn); \
- switch (conn->handshake.async_state) { \
- case S2N_ASYNC_NOT_INVOKED: \
- break; \
- \
- case S2N_ASYNC_INVOKING_CALLBACK: \
- case S2N_ASYNC_INVOKED_WAITING: \
- BAIL_POSIX(S2N_ERR_ASYNC_BLOCKED); \
- \
- case S2N_ASYNC_INVOKED_COMPLETE: \
- /* clean up state and return a success from handler */ \
- __tmp_conn->handshake.async_state = S2N_ASYNC_NOT_INVOKED; \
- GUARD(s2n_conn_clear_handshake_read_block(__tmp_conn)); \
- return S2N_SUCCESS; \
- } \
- } while (0)
-
-/* Macros for safe exection of async sign/decrypt.
- *
- * When operation is done asynchronously, we drop to s2n_negotiate loop with S2N_ERR_ASYNC_BLOCKED error and do not
- * perform any of the operations to follow after s2n_async* call. To enforce that there are no operations after the
- * call, we use a macro which directly returns the result of s2n_async* operation forcing compiler to error out on
- * unreachable code and forcing developer to use on_complete function instead */
-#define S2N_ASYNC_PKEY_DECRYPT(conn, encrypted, init_decrypted, on_complete) \
- return S2N_RESULT_TO_POSIX(s2n_async_pkey_decrypt(conn, encrypted, init_decrypted, on_complete));
-
-#define S2N_ASYNC_PKEY_SIGN(conn, sig_alg, digest, on_complete) \
- return S2N_RESULT_TO_POSIX(s2n_async_pkey_sign(conn, sig_alg, digest, on_complete));
-
-int s2n_async_pkey_op_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *key);
-int s2n_async_pkey_op_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn);
-int s2n_async_pkey_op_free(struct s2n_async_pkey_op *op);
-
-S2N_RESULT s2n_async_pkey_decrypt(struct s2n_connection *conn, struct s2n_blob *encrypted, struct s2n_blob *init_decrypted,
- s2n_async_pkey_decrypt_complete on_complete);
-S2N_RESULT s2n_async_pkey_sign(struct s2n_connection *conn, s2n_signature_algorithm sig_alg, struct s2n_hash_state *digest,
- s2n_async_pkey_sign_complete on_complete);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/s2n_connection.h"
+#include "utils/s2n_blob.h"
+#include "utils/s2n_result.h"
+
+typedef int (*s2n_async_pkey_sign_complete)(struct s2n_connection *conn, struct s2n_blob *signature);
+typedef int (*s2n_async_pkey_decrypt_complete)(struct s2n_connection *conn, bool rsa_failed, struct s2n_blob *decrypted);
+
+struct s2n_async_pkey_op;
+
+/* Guard to handle async states inside handler which uses async pkey operations. If async operation was not invoked
+ * it means that we enter this handler for the first time and handler may or may not use async operation, so we let it
+ * continue. If async operation is invoking or was invoked, but yet to be complete, we error out of the handler to let
+ * s2n_handle_retry_state try again. If async operation was complete we clear the state and let s2n_handle_retry_state
+ * proceed to the next handler */
+#define S2N_ASYNC_PKEY_GUARD(conn) \
+ do { \
+ __typeof(conn) __tmp_conn = (conn); \
+ GUARD_NONNULL(__tmp_conn); \
+ switch (conn->handshake.async_state) { \
+ case S2N_ASYNC_NOT_INVOKED: \
+ break; \
+ \
+ case S2N_ASYNC_INVOKING_CALLBACK: \
+ case S2N_ASYNC_INVOKED_WAITING: \
+ BAIL_POSIX(S2N_ERR_ASYNC_BLOCKED); \
+ \
+ case S2N_ASYNC_INVOKED_COMPLETE: \
+ /* clean up state and return a success from handler */ \
+ __tmp_conn->handshake.async_state = S2N_ASYNC_NOT_INVOKED; \
+ GUARD(s2n_conn_clear_handshake_read_block(__tmp_conn)); \
+ return S2N_SUCCESS; \
+ } \
+ } while (0)
+
+/* Macros for safe exection of async sign/decrypt.
+ *
+ * When operation is done asynchronously, we drop to s2n_negotiate loop with S2N_ERR_ASYNC_BLOCKED error and do not
+ * perform any of the operations to follow after s2n_async* call. To enforce that there are no operations after the
+ * call, we use a macro which directly returns the result of s2n_async* operation forcing compiler to error out on
+ * unreachable code and forcing developer to use on_complete function instead */
+#define S2N_ASYNC_PKEY_DECRYPT(conn, encrypted, init_decrypted, on_complete) \
+ return S2N_RESULT_TO_POSIX(s2n_async_pkey_decrypt(conn, encrypted, init_decrypted, on_complete));
+
+#define S2N_ASYNC_PKEY_SIGN(conn, sig_alg, digest, on_complete) \
+ return S2N_RESULT_TO_POSIX(s2n_async_pkey_sign(conn, sig_alg, digest, on_complete));
+
+int s2n_async_pkey_op_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *key);
+int s2n_async_pkey_op_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn);
+int s2n_async_pkey_op_free(struct s2n_async_pkey_op *op);
+
+S2N_RESULT s2n_async_pkey_decrypt(struct s2n_connection *conn, struct s2n_blob *encrypted, struct s2n_blob *init_decrypted,
+ s2n_async_pkey_decrypt_complete on_complete);
+S2N_RESULT s2n_async_pkey_sign(struct s2n_connection *conn, s2n_signature_algorithm sig_alg, struct s2n_hash_state *digest,
+ s2n_async_pkey_sign_complete on_complete);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_auth_selection.c b/contrib/restricted/aws/s2n/tls/s2n_auth_selection.c
index 87c6b69277..2d5070e32e 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_auth_selection.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_auth_selection.c
@@ -1,228 +1,228 @@
-/*
- * 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_certificate.h"
-#include "crypto/s2n_ecdsa.h"
-#include "crypto/s2n_signature.h"
-
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_kex.h"
-#include "tls/s2n_auth_selection.h"
-
-#include "utils/s2n_safety.h"
-
-/* This module should contain any logic related to choosing a valid combination of
- * signature algorithm, authentication method, and certificate to use for authentication.
- *
- * We choose our auth methods by:
- * 1. Finding a cipher suite with an auth method that we have valid certs for. In TLS1.3,
- * this is a no-op -- cipher suites do not specify an auth method.
- * 2. Choosing a signature algorithm that matches both the auth method (if set) and the
- * available certs.
- * 3. Selecting the cert that matches the chosen signature algorithm.
- *
- * This is a break from the original s2n pre-TLS1.3 flow, when we could choose certs and
- * ciphers at the same time. Our cipher suites differentiate between "RSA" and "ECDSA",
- * but not between "RSA" and "RSA-PSS". To make that decision, we need to wait until
- * we've chosen a signature algorithm. This allows us to use RSA-PSS with existing
- * TLS1.2 cipher suites.
- */
-
-static int s2n_get_auth_method_for_cert_type(s2n_pkey_type cert_type, s2n_authentication_method *auth_method)
-{
- switch(cert_type) {
- case S2N_PKEY_TYPE_RSA:
- case S2N_PKEY_TYPE_RSA_PSS:
- *auth_method = S2N_AUTHENTICATION_RSA;
- return S2N_SUCCESS;
- case S2N_PKEY_TYPE_ECDSA:
- *auth_method = S2N_AUTHENTICATION_ECDSA;
- return S2N_SUCCESS;
- case S2N_PKEY_TYPE_UNKNOWN:
- case S2N_PKEY_TYPE_SENTINEL:
- S2N_ERROR(S2N_ERR_CERT_TYPE_UNSUPPORTED);
- }
- S2N_ERROR(S2N_ERR_CERT_TYPE_UNSUPPORTED);
-}
-
-static int s2n_get_cert_type_for_sig_alg(s2n_signature_algorithm sig_alg, s2n_pkey_type *cert_type)
-{
- switch(sig_alg) {
- case S2N_SIGNATURE_RSA_PSS_RSAE:
- case S2N_SIGNATURE_RSA:
- *cert_type = S2N_PKEY_TYPE_RSA;
- return S2N_SUCCESS;
- case S2N_SIGNATURE_ECDSA:
- *cert_type = S2N_PKEY_TYPE_ECDSA;
- return S2N_SUCCESS;
- case S2N_SIGNATURE_RSA_PSS_PSS:
- *cert_type = S2N_PKEY_TYPE_RSA_PSS;
- return S2N_SUCCESS;
- case S2N_SIGNATURE_ANONYMOUS:
- S2N_ERROR(S2N_ERR_INVALID_SIGNATURE_ALGORITHM);
- }
- S2N_ERROR(S2N_ERR_INVALID_SIGNATURE_ALGORITHM);
-}
-
-static int s2n_is_sig_alg_valid_for_cipher_suite(s2n_signature_algorithm sig_alg, struct s2n_cipher_suite *cipher_suite)
-{
- notnull_check(cipher_suite);
-
- s2n_pkey_type cert_type_for_sig_alg;
- GUARD(s2n_get_cert_type_for_sig_alg(sig_alg, &cert_type_for_sig_alg));
-
- /* Non-ephemeral key exchange methods require encryption, and RSA-PSS certificates
- * do not support encryption.
- *
- * Therefore, if a cipher suite uses a non-ephemeral kex, then any signature
- * algorithm that requires RSA-PSS certificates is not valid.
- */
- if (cipher_suite->key_exchange_alg != NULL && !cipher_suite->key_exchange_alg->is_ephemeral) {
- ne_check(cert_type_for_sig_alg, S2N_PKEY_TYPE_RSA_PSS);
- }
-
- /* If a cipher suite includes an auth method, then the signature algorithm
- * must match that auth method.
- */
- if (cipher_suite->auth_method != S2N_AUTHENTICATION_METHOD_SENTINEL) {
- s2n_authentication_method auth_method_for_sig_alg;
- GUARD(s2n_get_auth_method_for_cert_type(cert_type_for_sig_alg, &auth_method_for_sig_alg));
- eq_check(cipher_suite->auth_method, auth_method_for_sig_alg);
- }
-
- return S2N_SUCCESS;
-}
-
-static int s2n_certs_exist_for_sig_scheme(struct s2n_connection *conn, const struct s2n_signature_scheme *sig_scheme)
-{
- notnull_check(sig_scheme);
-
- s2n_pkey_type cert_type;
- GUARD(s2n_get_cert_type_for_sig_alg(sig_scheme->sig_alg, &cert_type));
-
- /* A valid cert must exist for the authentication method. */
- struct s2n_cert_chain_and_key *cert = s2n_get_compatible_cert_chain_and_key(conn, cert_type);
- notnull_check(cert);
-
- /* For sig_algs that include a curve, the group must also match. */
- if (sig_scheme->signature_curve != NULL) {
- notnull_check(cert->private_key);
- notnull_check(cert->cert_chain);
- notnull_check(cert->cert_chain->head);
- eq_check(cert->cert_chain->head->pkey_type, S2N_PKEY_TYPE_ECDSA);
- GUARD(s2n_ecdsa_pkey_matches_curve(&cert->private_key->key.ecdsa_key, sig_scheme->signature_curve));
- }
-
- return S2N_SUCCESS;
-}
-
-static int s2n_certs_exist_for_auth_method(struct s2n_connection *conn, s2n_authentication_method auth_method)
-{
- s2n_authentication_method auth_method_for_cert_type;
- for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) {
- GUARD(s2n_get_auth_method_for_cert_type(i, &auth_method_for_cert_type));
-
- if (auth_method != S2N_AUTHENTICATION_METHOD_SENTINEL && auth_method != auth_method_for_cert_type) {
- continue;
- }
-
- if (s2n_get_compatible_cert_chain_and_key(conn, i) != NULL) {
- return S2N_SUCCESS;
- }
- }
- S2N_ERROR(S2N_ERR_CERT_TYPE_UNSUPPORTED);
-}
-
-/* A cipher suite is valid if:
- * - At least one compatible cert is configured
- *
- * TLS1.3 ciphers are valid if ANY certs are configured, as authentication
- * method is not tied to cipher suites in TLS1.3.
- *
- * This method is called by the server when choosing a cipher suite.
- */
-int s2n_is_cipher_suite_valid_for_auth(struct s2n_connection *conn, struct s2n_cipher_suite *cipher_suite)
-{
- notnull_check(cipher_suite);
-
- GUARD(s2n_certs_exist_for_auth_method(conn, cipher_suite->auth_method));
-
- return S2N_SUCCESS;
-}
-
-/* A signature algorithm is valid if:
- * - At least one compatible cert is configured.
- * - The signature algorithm is allowed by the cipher suite's auth method
- * (if running as a pre-TLS1.3 server).
- *
- * This method is called by the both server and client when choosing a signature algorithm.
- */
-int s2n_is_sig_scheme_valid_for_auth(struct s2n_connection *conn, const struct s2n_signature_scheme *sig_scheme)
-{
- notnull_check(conn);
- notnull_check(sig_scheme);
-
- struct s2n_cipher_suite *cipher_suite = conn->secure.cipher_suite;
- notnull_check(cipher_suite);
-
- GUARD(s2n_certs_exist_for_sig_scheme(conn, sig_scheme));
-
- /* For the client side, signature algorithm does not need to match the cipher suite. */
- if (conn->mode == S2N_SERVER) {
- GUARD(s2n_is_sig_alg_valid_for_cipher_suite(sig_scheme->sig_alg, cipher_suite));
- }
- return S2N_SUCCESS;
-}
-
-/* A cert is valid if:
- * - The configured cipher suite's auth method (if present) supports the cert.
- *
- * We could also verify that at least one of our supported sig algs
- * supports the cert, but that seems unnecessary. If we don't have a valid
- * sig alg, we'll fail on CertVerify.
- *
- * This method is called by the client when receiving the server's cert.
- */
-int s2n_is_cert_type_valid_for_auth(struct s2n_connection *conn, s2n_pkey_type cert_type)
-{
- notnull_check(conn);
- notnull_check(conn->secure.cipher_suite);
-
- s2n_authentication_method auth_method;
- GUARD(s2n_get_auth_method_for_cert_type(cert_type, &auth_method));
-
- if (conn->secure.cipher_suite->auth_method != S2N_AUTHENTICATION_METHOD_SENTINEL) {
- S2N_ERROR_IF(auth_method != conn->secure.cipher_suite->auth_method, S2N_ERR_CERT_TYPE_UNSUPPORTED);
- }
-
- return S2N_SUCCESS;
-}
-
-/* Choose the cert associated with our configured signature algorithm.
- *
- * This method is called by the server after configuring its cipher suite and sig algs.
- */
-int s2n_select_certs_for_server_auth(struct s2n_connection *conn, struct s2n_cert_chain_and_key **chosen_certs)
-{
- notnull_check(conn);
-
- s2n_pkey_type cert_type;
- GUARD(s2n_get_cert_type_for_sig_alg(conn->secure.conn_sig_scheme.sig_alg, &cert_type));
-
- *chosen_certs = s2n_get_compatible_cert_chain_and_key(conn, cert_type);
- S2N_ERROR_IF(*chosen_certs == NULL, S2N_ERR_CERT_TYPE_UNSUPPORTED);
-
- return S2N_SUCCESS;
-}
+/*
+ * 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_certificate.h"
+#include "crypto/s2n_ecdsa.h"
+#include "crypto/s2n_signature.h"
+
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_kex.h"
+#include "tls/s2n_auth_selection.h"
+
+#include "utils/s2n_safety.h"
+
+/* This module should contain any logic related to choosing a valid combination of
+ * signature algorithm, authentication method, and certificate to use for authentication.
+ *
+ * We choose our auth methods by:
+ * 1. Finding a cipher suite with an auth method that we have valid certs for. In TLS1.3,
+ * this is a no-op -- cipher suites do not specify an auth method.
+ * 2. Choosing a signature algorithm that matches both the auth method (if set) and the
+ * available certs.
+ * 3. Selecting the cert that matches the chosen signature algorithm.
+ *
+ * This is a break from the original s2n pre-TLS1.3 flow, when we could choose certs and
+ * ciphers at the same time. Our cipher suites differentiate between "RSA" and "ECDSA",
+ * but not between "RSA" and "RSA-PSS". To make that decision, we need to wait until
+ * we've chosen a signature algorithm. This allows us to use RSA-PSS with existing
+ * TLS1.2 cipher suites.
+ */
+
+static int s2n_get_auth_method_for_cert_type(s2n_pkey_type cert_type, s2n_authentication_method *auth_method)
+{
+ switch(cert_type) {
+ case S2N_PKEY_TYPE_RSA:
+ case S2N_PKEY_TYPE_RSA_PSS:
+ *auth_method = S2N_AUTHENTICATION_RSA;
+ return S2N_SUCCESS;
+ case S2N_PKEY_TYPE_ECDSA:
+ *auth_method = S2N_AUTHENTICATION_ECDSA;
+ return S2N_SUCCESS;
+ case S2N_PKEY_TYPE_UNKNOWN:
+ case S2N_PKEY_TYPE_SENTINEL:
+ S2N_ERROR(S2N_ERR_CERT_TYPE_UNSUPPORTED);
+ }
+ S2N_ERROR(S2N_ERR_CERT_TYPE_UNSUPPORTED);
+}
+
+static int s2n_get_cert_type_for_sig_alg(s2n_signature_algorithm sig_alg, s2n_pkey_type *cert_type)
+{
+ switch(sig_alg) {
+ case S2N_SIGNATURE_RSA_PSS_RSAE:
+ case S2N_SIGNATURE_RSA:
+ *cert_type = S2N_PKEY_TYPE_RSA;
+ return S2N_SUCCESS;
+ case S2N_SIGNATURE_ECDSA:
+ *cert_type = S2N_PKEY_TYPE_ECDSA;
+ return S2N_SUCCESS;
+ case S2N_SIGNATURE_RSA_PSS_PSS:
+ *cert_type = S2N_PKEY_TYPE_RSA_PSS;
+ return S2N_SUCCESS;
+ case S2N_SIGNATURE_ANONYMOUS:
+ S2N_ERROR(S2N_ERR_INVALID_SIGNATURE_ALGORITHM);
+ }
+ S2N_ERROR(S2N_ERR_INVALID_SIGNATURE_ALGORITHM);
+}
+
+static int s2n_is_sig_alg_valid_for_cipher_suite(s2n_signature_algorithm sig_alg, struct s2n_cipher_suite *cipher_suite)
+{
+ notnull_check(cipher_suite);
+
+ s2n_pkey_type cert_type_for_sig_alg;
+ GUARD(s2n_get_cert_type_for_sig_alg(sig_alg, &cert_type_for_sig_alg));
+
+ /* Non-ephemeral key exchange methods require encryption, and RSA-PSS certificates
+ * do not support encryption.
+ *
+ * Therefore, if a cipher suite uses a non-ephemeral kex, then any signature
+ * algorithm that requires RSA-PSS certificates is not valid.
+ */
+ if (cipher_suite->key_exchange_alg != NULL && !cipher_suite->key_exchange_alg->is_ephemeral) {
+ ne_check(cert_type_for_sig_alg, S2N_PKEY_TYPE_RSA_PSS);
+ }
+
+ /* If a cipher suite includes an auth method, then the signature algorithm
+ * must match that auth method.
+ */
+ if (cipher_suite->auth_method != S2N_AUTHENTICATION_METHOD_SENTINEL) {
+ s2n_authentication_method auth_method_for_sig_alg;
+ GUARD(s2n_get_auth_method_for_cert_type(cert_type_for_sig_alg, &auth_method_for_sig_alg));
+ eq_check(cipher_suite->auth_method, auth_method_for_sig_alg);
+ }
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_certs_exist_for_sig_scheme(struct s2n_connection *conn, const struct s2n_signature_scheme *sig_scheme)
+{
+ notnull_check(sig_scheme);
+
+ s2n_pkey_type cert_type;
+ GUARD(s2n_get_cert_type_for_sig_alg(sig_scheme->sig_alg, &cert_type));
+
+ /* A valid cert must exist for the authentication method. */
+ struct s2n_cert_chain_and_key *cert = s2n_get_compatible_cert_chain_and_key(conn, cert_type);
+ notnull_check(cert);
+
+ /* For sig_algs that include a curve, the group must also match. */
+ if (sig_scheme->signature_curve != NULL) {
+ notnull_check(cert->private_key);
+ notnull_check(cert->cert_chain);
+ notnull_check(cert->cert_chain->head);
+ eq_check(cert->cert_chain->head->pkey_type, S2N_PKEY_TYPE_ECDSA);
+ GUARD(s2n_ecdsa_pkey_matches_curve(&cert->private_key->key.ecdsa_key, sig_scheme->signature_curve));
+ }
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_certs_exist_for_auth_method(struct s2n_connection *conn, s2n_authentication_method auth_method)
+{
+ s2n_authentication_method auth_method_for_cert_type;
+ for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) {
+ GUARD(s2n_get_auth_method_for_cert_type(i, &auth_method_for_cert_type));
+
+ if (auth_method != S2N_AUTHENTICATION_METHOD_SENTINEL && auth_method != auth_method_for_cert_type) {
+ continue;
+ }
+
+ if (s2n_get_compatible_cert_chain_and_key(conn, i) != NULL) {
+ return S2N_SUCCESS;
+ }
+ }
+ S2N_ERROR(S2N_ERR_CERT_TYPE_UNSUPPORTED);
+}
+
+/* A cipher suite is valid if:
+ * - At least one compatible cert is configured
+ *
+ * TLS1.3 ciphers are valid if ANY certs are configured, as authentication
+ * method is not tied to cipher suites in TLS1.3.
+ *
+ * This method is called by the server when choosing a cipher suite.
+ */
+int s2n_is_cipher_suite_valid_for_auth(struct s2n_connection *conn, struct s2n_cipher_suite *cipher_suite)
+{
+ notnull_check(cipher_suite);
+
+ GUARD(s2n_certs_exist_for_auth_method(conn, cipher_suite->auth_method));
+
+ return S2N_SUCCESS;
+}
+
+/* A signature algorithm is valid if:
+ * - At least one compatible cert is configured.
+ * - The signature algorithm is allowed by the cipher suite's auth method
+ * (if running as a pre-TLS1.3 server).
+ *
+ * This method is called by the both server and client when choosing a signature algorithm.
+ */
+int s2n_is_sig_scheme_valid_for_auth(struct s2n_connection *conn, const struct s2n_signature_scheme *sig_scheme)
+{
+ notnull_check(conn);
+ notnull_check(sig_scheme);
+
+ struct s2n_cipher_suite *cipher_suite = conn->secure.cipher_suite;
+ notnull_check(cipher_suite);
+
+ GUARD(s2n_certs_exist_for_sig_scheme(conn, sig_scheme));
+
+ /* For the client side, signature algorithm does not need to match the cipher suite. */
+ if (conn->mode == S2N_SERVER) {
+ GUARD(s2n_is_sig_alg_valid_for_cipher_suite(sig_scheme->sig_alg, cipher_suite));
+ }
+ return S2N_SUCCESS;
+}
+
+/* A cert is valid if:
+ * - The configured cipher suite's auth method (if present) supports the cert.
+ *
+ * We could also verify that at least one of our supported sig algs
+ * supports the cert, but that seems unnecessary. If we don't have a valid
+ * sig alg, we'll fail on CertVerify.
+ *
+ * This method is called by the client when receiving the server's cert.
+ */
+int s2n_is_cert_type_valid_for_auth(struct s2n_connection *conn, s2n_pkey_type cert_type)
+{
+ notnull_check(conn);
+ notnull_check(conn->secure.cipher_suite);
+
+ s2n_authentication_method auth_method;
+ GUARD(s2n_get_auth_method_for_cert_type(cert_type, &auth_method));
+
+ if (conn->secure.cipher_suite->auth_method != S2N_AUTHENTICATION_METHOD_SENTINEL) {
+ S2N_ERROR_IF(auth_method != conn->secure.cipher_suite->auth_method, S2N_ERR_CERT_TYPE_UNSUPPORTED);
+ }
+
+ return S2N_SUCCESS;
+}
+
+/* Choose the cert associated with our configured signature algorithm.
+ *
+ * This method is called by the server after configuring its cipher suite and sig algs.
+ */
+int s2n_select_certs_for_server_auth(struct s2n_connection *conn, struct s2n_cert_chain_and_key **chosen_certs)
+{
+ notnull_check(conn);
+
+ s2n_pkey_type cert_type;
+ GUARD(s2n_get_cert_type_for_sig_alg(conn->secure.conn_sig_scheme.sig_alg, &cert_type));
+
+ *chosen_certs = s2n_get_compatible_cert_chain_and_key(conn, cert_type);
+ S2N_ERROR_IF(*chosen_certs == NULL, S2N_ERR_CERT_TYPE_UNSUPPORTED);
+
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_auth_selection.h b/contrib/restricted/aws/s2n/tls/s2n_auth_selection.h
index 2c709e99fb..370f00c4f8 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_auth_selection.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_auth_selection.h
@@ -1,27 +1,27 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/s2n_cipher_suites.h"
-
-#include "crypto/s2n_certificate.h"
-#include "crypto/s2n_signature.h"
-
-int s2n_is_cipher_suite_valid_for_auth(struct s2n_connection *conn, struct s2n_cipher_suite *cipher_suite);
-int s2n_is_sig_scheme_valid_for_auth(struct s2n_connection *conn, const struct s2n_signature_scheme *sig_scheme);
-int s2n_is_cert_type_valid_for_auth(struct s2n_connection *conn, s2n_pkey_type cert_type);
-int s2n_select_certs_for_server_auth(struct s2n_connection *conn, struct s2n_cert_chain_and_key **chosen_certs);
-
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/s2n_cipher_suites.h"
+
+#include "crypto/s2n_certificate.h"
+#include "crypto/s2n_signature.h"
+
+int s2n_is_cipher_suite_valid_for_auth(struct s2n_connection *conn, struct s2n_cipher_suite *cipher_suite);
+int s2n_is_sig_scheme_valid_for_auth(struct s2n_connection *conn, const struct s2n_signature_scheme *sig_scheme);
+int s2n_is_cert_type_valid_for_auth(struct s2n_connection *conn, s2n_pkey_type cert_type);
+int s2n_select_certs_for_server_auth(struct s2n_connection *conn, struct s2n_cert_chain_and_key **chosen_certs);
+
diff --git a/contrib/restricted/aws/s2n/tls/s2n_cbc.c b/contrib/restricted/aws/s2n/tls/s2n_cbc.c
index 5c9a8fa5b1..b2ae713e8e 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_cbc.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_cbc.c
@@ -1,103 +1,103 @@
-/*
- * 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 <sys/param.h>
-#include <stdint.h>
-
-#include "error/s2n_errno.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_mem.h"
-
-#include "crypto/s2n_hmac.h"
-
-#include "tls/s2n_record.h"
-
-/* A TLS CBC record looks like ..
- *
- * [ Payload data ] [ HMAC ] [ Padding ] [ Padding length byte ]
- *
- * Each byte in the padding is expected to be set to the same value
- * as the padding length byte. So if the padding length byte is '2'
- * then the padding will be [ '2', '2' ] (there'll be three bytes
- * set to that value if you include the padding length byte).
- *
- * The goal of s2n_verify_cbc() is to verify that the padding and hmac
- * are correct, without leaking (via timing) how much padding there
- * actually is: as this is considered secret.
- *
- * In addition to our efforts here though, s2n also wraps any CBC
- * verification error (or record parsing error in general) with
- * a randomized delay of between 1ms and 10 seconds. See s2n_connection.c.
- * This amount of delay randomization is sufficient to increase the
- * complexity of attack for even a 1 microsecond timing leak (which
- * is quite large) by a factor of around 83 trillion.
- */
-int s2n_verify_cbc(struct s2n_connection *conn, struct s2n_hmac_state *hmac, struct s2n_blob *decrypted)
-{
- /* Set up MAC copy workspace */
- struct s2n_hmac_state *copy = &conn->client->record_mac_copy_workspace;
- if (conn->mode == S2N_CLIENT) {
- copy = &conn->server->record_mac_copy_workspace;
- }
-
- uint8_t mac_digest_size;
- GUARD(s2n_hmac_digest_size(hmac->alg, &mac_digest_size));
-
- /* The record has to be at least big enough to contain the MAC,
- * plus the padding length byte */
- gt_check(decrypted->size, mac_digest_size);
-
- int payload_and_padding_size = decrypted->size - mac_digest_size;
-
- /* Determine what the padding length is */
- uint8_t padding_length = decrypted->data[decrypted->size - 1];
-
- int payload_length = MAX(payload_and_padding_size - padding_length - 1, 0);
-
- /* Update the MAC */
- GUARD(s2n_hmac_update(hmac, decrypted->data, payload_length));
- GUARD(s2n_hmac_copy(copy, hmac));
-
- /* Check the MAC */
- uint8_t check_digest[S2N_MAX_DIGEST_LEN];
- lte_check(mac_digest_size, sizeof(check_digest));
- GUARD(s2n_hmac_digest_two_compression_rounds(hmac, check_digest, mac_digest_size));
-
- int mismatches = s2n_constant_time_equals(decrypted->data + payload_length, check_digest, mac_digest_size) ^ 1;
-
- /* Compute a MAC on the rest of the data so that we perform the same number of hash operations */
- GUARD(s2n_hmac_update(copy, decrypted->data + payload_length + mac_digest_size, decrypted->size - payload_length - mac_digest_size - 1));
-
- /* SSLv3 doesn't specify what the padding should actually be */
- if (conn->actual_protocol_version == S2N_SSLv3) {
- return 0 - mismatches;
- }
-
- /* Check the maximum amount that could theoretically be padding */
- int check = MIN(255, (payload_and_padding_size - 1));
-
- int cutoff = check - padding_length;
- for (int i = 0, j = decrypted->size - 1 - check; i < check && j < decrypted->size; i++, j++) {
- uint8_t mask = ~(0xff << ((i >= cutoff) * 8));
- mismatches |= (decrypted->data[j] ^ padding_length) & mask;
- }
-
- GUARD(s2n_hmac_reset(copy));
-
- S2N_ERROR_IF(mismatches, S2N_ERR_CBC_VERIFY);
-
- return 0;
-}
+/*
+ * 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 <sys/param.h>
+#include <stdint.h>
+
+#include "error/s2n_errno.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_mem.h"
+
+#include "crypto/s2n_hmac.h"
+
+#include "tls/s2n_record.h"
+
+/* A TLS CBC record looks like ..
+ *
+ * [ Payload data ] [ HMAC ] [ Padding ] [ Padding length byte ]
+ *
+ * Each byte in the padding is expected to be set to the same value
+ * as the padding length byte. So if the padding length byte is '2'
+ * then the padding will be [ '2', '2' ] (there'll be three bytes
+ * set to that value if you include the padding length byte).
+ *
+ * The goal of s2n_verify_cbc() is to verify that the padding and hmac
+ * are correct, without leaking (via timing) how much padding there
+ * actually is: as this is considered secret.
+ *
+ * In addition to our efforts here though, s2n also wraps any CBC
+ * verification error (or record parsing error in general) with
+ * a randomized delay of between 1ms and 10 seconds. See s2n_connection.c.
+ * This amount of delay randomization is sufficient to increase the
+ * complexity of attack for even a 1 microsecond timing leak (which
+ * is quite large) by a factor of around 83 trillion.
+ */
+int s2n_verify_cbc(struct s2n_connection *conn, struct s2n_hmac_state *hmac, struct s2n_blob *decrypted)
+{
+ /* Set up MAC copy workspace */
+ struct s2n_hmac_state *copy = &conn->client->record_mac_copy_workspace;
+ if (conn->mode == S2N_CLIENT) {
+ copy = &conn->server->record_mac_copy_workspace;
+ }
+
+ uint8_t mac_digest_size;
+ GUARD(s2n_hmac_digest_size(hmac->alg, &mac_digest_size));
+
+ /* The record has to be at least big enough to contain the MAC,
+ * plus the padding length byte */
+ gt_check(decrypted->size, mac_digest_size);
+
+ int payload_and_padding_size = decrypted->size - mac_digest_size;
+
+ /* Determine what the padding length is */
+ uint8_t padding_length = decrypted->data[decrypted->size - 1];
+
+ int payload_length = MAX(payload_and_padding_size - padding_length - 1, 0);
+
+ /* Update the MAC */
+ GUARD(s2n_hmac_update(hmac, decrypted->data, payload_length));
+ GUARD(s2n_hmac_copy(copy, hmac));
+
+ /* Check the MAC */
+ uint8_t check_digest[S2N_MAX_DIGEST_LEN];
+ lte_check(mac_digest_size, sizeof(check_digest));
+ GUARD(s2n_hmac_digest_two_compression_rounds(hmac, check_digest, mac_digest_size));
+
+ int mismatches = s2n_constant_time_equals(decrypted->data + payload_length, check_digest, mac_digest_size) ^ 1;
+
+ /* Compute a MAC on the rest of the data so that we perform the same number of hash operations */
+ GUARD(s2n_hmac_update(copy, decrypted->data + payload_length + mac_digest_size, decrypted->size - payload_length - mac_digest_size - 1));
+
+ /* SSLv3 doesn't specify what the padding should actually be */
+ if (conn->actual_protocol_version == S2N_SSLv3) {
+ return 0 - mismatches;
+ }
+
+ /* Check the maximum amount that could theoretically be padding */
+ int check = MIN(255, (payload_and_padding_size - 1));
+
+ int cutoff = check - padding_length;
+ for (int i = 0, j = decrypted->size - 1 - check; i < check && j < decrypted->size; i++, j++) {
+ uint8_t mask = ~(0xff << ((i >= cutoff) * 8));
+ mismatches |= (decrypted->data[j] ^ padding_length) & mask;
+ }
+
+ GUARD(s2n_hmac_reset(copy));
+
+ S2N_ERROR_IF(mismatches, S2N_ERR_CBC_VERIFY);
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_change_cipher_spec.c b/contrib/restricted/aws/s2n/tls/s2n_change_cipher_spec.c
index 652d0f6230..19caaa96a1 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_change_cipher_spec.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_change_cipher_spec.c
@@ -1,90 +1,90 @@
-/*
- * 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 <stdint.h>
-
-#include "error/s2n_errno.h"
-
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_tls.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_safety.h"
-
-/* From RFC5246 7.1: https://tools.ietf.org/html/rfc5246#section-7.1 */
-#define CHANGE_CIPHER_SPEC_TYPE 1
-
-int s2n_basic_ccs_recv(struct s2n_connection *conn)
-{
- uint8_t type;
-
- GUARD(s2n_stuffer_read_uint8(&conn->handshake.io, &type));
- S2N_ERROR_IF(type != CHANGE_CIPHER_SPEC_TYPE, S2N_ERR_BAD_MESSAGE);
-
- return 0;
-}
-
-int s2n_client_ccs_recv(struct s2n_connection *conn)
-{
- GUARD(s2n_basic_ccs_recv(conn));
-
- /* Zero the sequence number */
- struct s2n_blob seq = {.data = conn->secure.client_sequence_number,.size = sizeof(conn->secure.client_sequence_number) };
- GUARD(s2n_blob_zero(&seq));
-
- /* Compute the finished message */
- GUARD(s2n_prf_client_finished(conn));
-
- /* Update the client to use the cipher-suite */
- conn->client = &conn->secure;
-
- /* Flush any partial alert messages that were pending.
- * If we don't do this, an attacker can inject a 1-byte alert message into the handshake
- * and cause later, valid alerts to be processed incorrectly. */
- GUARD(s2n_stuffer_wipe(&conn->alert_in));
-
- return 0;
-}
-
-int s2n_server_ccs_recv(struct s2n_connection *conn)
-{
- GUARD(s2n_basic_ccs_recv(conn));
-
- /* Zero the sequence number */
- struct s2n_blob seq = {.data = conn->secure.server_sequence_number,.size = sizeof(conn->secure.server_sequence_number) };
- GUARD(s2n_blob_zero(&seq));
-
- /* Compute the finished message */
- GUARD(s2n_prf_server_finished(conn));
-
- /* Update the secure state to active, and point the client at the active state */
- conn->server = &conn->secure;
-
- /* Flush any partial alert messages that were pending.
- * If we don't do this, an attacker can inject a 1-byte alert message into the handshake
- * and cause later, valid alerts to be processed incorrectly. */
- GUARD(s2n_stuffer_wipe(&conn->alert_in));
-
- return 0;
-}
-
-int s2n_ccs_send(struct s2n_connection *conn)
-{
- GUARD(s2n_stuffer_write_uint8(&conn->handshake.io, CHANGE_CIPHER_SPEC_TYPE));
-
- return 0;
-}
+/*
+ * 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 <stdint.h>
+
+#include "error/s2n_errno.h"
+
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_tls.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_safety.h"
+
+/* From RFC5246 7.1: https://tools.ietf.org/html/rfc5246#section-7.1 */
+#define CHANGE_CIPHER_SPEC_TYPE 1
+
+int s2n_basic_ccs_recv(struct s2n_connection *conn)
+{
+ uint8_t type;
+
+ GUARD(s2n_stuffer_read_uint8(&conn->handshake.io, &type));
+ S2N_ERROR_IF(type != CHANGE_CIPHER_SPEC_TYPE, S2N_ERR_BAD_MESSAGE);
+
+ return 0;
+}
+
+int s2n_client_ccs_recv(struct s2n_connection *conn)
+{
+ GUARD(s2n_basic_ccs_recv(conn));
+
+ /* Zero the sequence number */
+ struct s2n_blob seq = {.data = conn->secure.client_sequence_number,.size = sizeof(conn->secure.client_sequence_number) };
+ GUARD(s2n_blob_zero(&seq));
+
+ /* Compute the finished message */
+ GUARD(s2n_prf_client_finished(conn));
+
+ /* Update the client to use the cipher-suite */
+ conn->client = &conn->secure;
+
+ /* Flush any partial alert messages that were pending.
+ * If we don't do this, an attacker can inject a 1-byte alert message into the handshake
+ * and cause later, valid alerts to be processed incorrectly. */
+ GUARD(s2n_stuffer_wipe(&conn->alert_in));
+
+ return 0;
+}
+
+int s2n_server_ccs_recv(struct s2n_connection *conn)
+{
+ GUARD(s2n_basic_ccs_recv(conn));
+
+ /* Zero the sequence number */
+ struct s2n_blob seq = {.data = conn->secure.server_sequence_number,.size = sizeof(conn->secure.server_sequence_number) };
+ GUARD(s2n_blob_zero(&seq));
+
+ /* Compute the finished message */
+ GUARD(s2n_prf_server_finished(conn));
+
+ /* Update the secure state to active, and point the client at the active state */
+ conn->server = &conn->secure;
+
+ /* Flush any partial alert messages that were pending.
+ * If we don't do this, an attacker can inject a 1-byte alert message into the handshake
+ * and cause later, valid alerts to be processed incorrectly. */
+ GUARD(s2n_stuffer_wipe(&conn->alert_in));
+
+ return 0;
+}
+
+int s2n_ccs_send(struct s2n_connection *conn)
+{
+ GUARD(s2n_stuffer_write_uint8(&conn->handshake.io, CHANGE_CIPHER_SPEC_TYPE));
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.c b/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.c
index 585a1d4b3d..4343b88f00 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.c
@@ -1,1127 +1,1127 @@
-/*
- * 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 "tls/s2n_cipher_preferences.h"
-#include <s2n.h>
-#include <stdint.h>
-#include <strings.h>
-#include "tls/s2n_config.h"
-#include "tls/s2n_kem.h"
-#include "tls/s2n_kex.h"
-
-#include "error/s2n_errno.h"
-#include "utils/s2n_safety.h"
-
-/* clang-format off */
-/* TLS 1.3 cipher suites, in order of preference.
- * Can be added to other ciphers suite lists to enable
- * TLS1.3 compatibility. */
-#define S2N_TLS13_CIPHER_SUITES_20190801 \
- &s2n_tls13_aes_256_gcm_sha384, \
- &s2n_tls13_aes_128_gcm_sha256, \
- &s2n_tls13_chacha20_poly1305_sha256
-
-#define S2N_TLS13_CLOUDFRONT_CIPHER_SUITES_20200716 \
- &s2n_tls13_aes_128_gcm_sha256, \
- &s2n_tls13_aes_256_gcm_sha384, \
- &s2n_tls13_chacha20_poly1305_sha256
-
-/* s2n's list of cipher suites, in order of preferences, as of 2019-08-01 */
-struct s2n_cipher_suite *cipher_suites_20190801[] = {
- S2N_TLS13_CIPHER_SUITES_20190801,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_128_cbc_sha
-};
-
-const struct s2n_cipher_preferences cipher_preferences_20190801 = {
- .count = s2n_array_len(cipher_suites_20190801),
- .suites = cipher_suites_20190801,
-};
-
-/* 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,
- &s2n_dhe_rsa_with_aes_128_cbc_sha,
- &s2n_dhe_rsa_with_3des_ede_cbc_sha,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_3des_ede_cbc_sha,
- &s2n_rsa_with_rc4_128_sha,
- &s2n_rsa_with_rc4_128_md5
-};
-
-const struct s2n_cipher_preferences cipher_preferences_20140601 = {
- .count = s2n_array_len(cipher_suites_20140601),
- .suites = cipher_suites_20140601,
-};
-
-/* Disable SSLv3 due to POODLE */
-const struct s2n_cipher_preferences cipher_preferences_20141001 = {
- .count = s2n_array_len(cipher_suites_20140601),
- .suites = cipher_suites_20140601,
-};
-
-/* Disable RC4 */
-struct s2n_cipher_suite *cipher_suites_20150202[] = {
- &s2n_dhe_rsa_with_aes_128_cbc_sha256,
- &s2n_dhe_rsa_with_aes_128_cbc_sha,
- &s2n_dhe_rsa_with_3des_ede_cbc_sha,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_3des_ede_cbc_sha
-};
-
-const struct s2n_cipher_preferences cipher_preferences_20150202 = {
- .count = s2n_array_len(cipher_suites_20150202),
- .suites = cipher_suites_20150202,
-};
-
-/* Support AES-GCM modes */
-struct s2n_cipher_suite *cipher_suites_20150214[] = {
- &s2n_dhe_rsa_with_aes_128_gcm_sha256,
- &s2n_dhe_rsa_with_aes_128_cbc_sha256,
- &s2n_dhe_rsa_with_aes_128_cbc_sha,
- &s2n_dhe_rsa_with_3des_ede_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_3des_ede_cbc_sha
-};
-
-const struct s2n_cipher_preferences cipher_preferences_20150214 = {
- .count = s2n_array_len(cipher_suites_20150214),
- .suites = cipher_suites_20150214,
-};
-
-/* Make a CBC cipher #1 to avoid negotiating GCM with buggy Java clients */
-struct s2n_cipher_suite *cipher_suites_20160411[] = {
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &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_sha,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_256_cbc_sha256,
- &s2n_rsa_with_3des_ede_cbc_sha,
-};
-
-const struct s2n_cipher_preferences cipher_preferences_20160411 = {
- .count = s2n_array_len(cipher_suites_20160411),
- .suites = cipher_suites_20160411,
-};
-
-/* Use ECDHE instead of plain DHE. Prioritize ECDHE in favour of non ECDHE; GCM in favour of CBC; AES128 in favour of AES256. */
-struct s2n_cipher_suite *cipher_suites_20150306[] = {
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_3des_ede_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_3des_ede_cbc_sha
-};
-
-const struct s2n_cipher_preferences cipher_preferences_20150306 = {
- .count = s2n_array_len(cipher_suites_20150306),
- .suites = cipher_suites_20150306,
-};
-
-struct s2n_cipher_suite *cipher_suites_20160804[] = {
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_256_cbc_sha256,
- &s2n_rsa_with_3des_ede_cbc_sha
-};
-
-const struct s2n_cipher_preferences cipher_preferences_20160804 = {
- .count = s2n_array_len(cipher_suites_20160804),
- .suites = cipher_suites_20160804,
-};
-
-struct s2n_cipher_suite *cipher_suites_20160824[] = {
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_128_cbc_sha
-};
-
-const struct s2n_cipher_preferences cipher_preferences_20160824 = {
- .count = s2n_array_len(cipher_suites_20160824),
- .suites = cipher_suites_20160824,
-};
-
-/* Add ChaCha20 suite */
-struct s2n_cipher_suite *cipher_suites_20170210[] = {
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_128_cbc_sha
-};
-
-const struct s2n_cipher_preferences cipher_preferences_20170210 = {
- .count = s2n_array_len(cipher_suites_20170210),
- .suites = cipher_suites_20170210,
-};
-
-/* Same as 20160411, but with ChaCha20 added as 1st in Preference List */
-struct s2n_cipher_suite *cipher_suites_20190122[] = {
- &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &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_sha,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_256_cbc_sha256,
- &s2n_rsa_with_3des_ede_cbc_sha,
-};
-
-const struct s2n_cipher_preferences cipher_preferences_20190122 = {
- .count = s2n_array_len(cipher_suites_20190122),
- .suites = cipher_suites_20190122,
-};
-
-/* Same as 20160804, but with ChaCha20 added as 2nd in Preference List */
-struct s2n_cipher_suite *cipher_suites_20190121[] = {
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_256_cbc_sha256,
- &s2n_rsa_with_3des_ede_cbc_sha
-};
-
-const struct s2n_cipher_preferences cipher_preferences_20190121 = {
- .count = s2n_array_len(cipher_suites_20190121),
- .suites = cipher_suites_20190121,
-};
-
-/* Same as 20160411, but with ChaCha20 in 3rd Place after CBC and GCM */
-struct s2n_cipher_suite *cipher_suites_20190120[] = {
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_256_cbc_sha256,
- &s2n_rsa_with_3des_ede_cbc_sha,
-};
-
-const struct s2n_cipher_preferences cipher_preferences_20190120 = {
- .count = s2n_array_len(cipher_suites_20190120),
- .suites = cipher_suites_20190120,
-};
-
-/* Preferences optimized for interop, includes ECDSA priortitized. DHE and 3DES are added(at the lowest preference). */
-struct s2n_cipher_suite *cipher_suites_20190214[] = {
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_256_cbc_sha256,
- &s2n_rsa_with_3des_ede_cbc_sha,
- &s2n_dhe_rsa_with_aes_128_cbc_sha,
- &s2n_dhe_rsa_with_aes_128_gcm_sha256,
- &s2n_dhe_rsa_with_aes_256_gcm_sha384,
- &s2n_dhe_rsa_with_aes_128_cbc_sha256,
- &s2n_dhe_rsa_with_aes_256_cbc_sha,
- &s2n_dhe_rsa_with_aes_256_cbc_sha256,
-};
-
-const struct s2n_cipher_preferences cipher_preferences_20190214 = {
- .count = s2n_array_len(cipher_suites_20190214),
- .suites = cipher_suites_20190214,
-};
-
-struct s2n_cipher_suite *cipher_suites_null[] = {
- &s2n_null_cipher_suite
-};
-
-const struct s2n_cipher_preferences cipher_preferences_null = {
- .count = s2n_array_len(cipher_suites_null),
- .suites = cipher_suites_null,
-};
-
-/* Preferences optimized for interop. DHE and 3DES are added(at the lowest preference). */
-struct s2n_cipher_suite *cipher_suites_20170328[] = {
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &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_sha,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_256_cbc_sha256,
- &s2n_rsa_with_3des_ede_cbc_sha,
- &s2n_dhe_rsa_with_aes_128_cbc_sha,
- &s2n_dhe_rsa_with_aes_128_gcm_sha256,
- &s2n_dhe_rsa_with_aes_256_gcm_sha384,
- &s2n_dhe_rsa_with_aes_128_cbc_sha256,
- &s2n_dhe_rsa_with_aes_256_cbc_sha,
- &s2n_dhe_rsa_with_aes_256_cbc_sha256,
-};
-
-const struct s2n_cipher_preferences cipher_preferences_20170328 = {
- .count = s2n_array_len(cipher_suites_20170328),
- .suites = cipher_suites_20170328,
-};
-
-/* Preferences optimized for FIPS compatibility. */
-struct s2n_cipher_suite *cipher_suites_20170405[] = {
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_256_cbc_sha256,
- &s2n_rsa_with_3des_ede_cbc_sha,
-};
-
-const struct s2n_cipher_preferences cipher_preferences_20170405 = {
- .count = s2n_array_len(cipher_suites_20170405),
- .suites = cipher_suites_20170405,
-};
-
-/* Equivalent to cipher_suite_20160411 with 3DES removed.
- * Make a CBC cipher #1 to avoid negotiating GCM with buggy Java clients. */
-struct s2n_cipher_suite *cipher_suites_20170718[] = {
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &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_sha,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_256_cbc_sha256,
-};
-
-const struct s2n_cipher_preferences cipher_preferences_20170718 = {
- .count = s2n_array_len(cipher_suites_20170718),
- .suites = cipher_suites_20170718,
-};
-
-struct s2n_cipher_suite *cipher_suites_elb_security_policy_2015_04[] = {
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_256_cbc_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_3des_ede_cbc_sha,
-};
-
-const struct s2n_cipher_preferences elb_security_policy_2015_04 = {
- .count = s2n_array_len(cipher_suites_elb_security_policy_2015_04),
- .suites = cipher_suites_elb_security_policy_2015_04,
-};
-
-struct s2n_cipher_suite *cipher_suites_elb_security_policy_2016_08[] = {
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_256_cbc_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
-};
-
-const struct s2n_cipher_preferences elb_security_policy_2016_08 = {
- .count = s2n_array_len(cipher_suites_elb_security_policy_2016_08),
- .suites = cipher_suites_elb_security_policy_2016_08,
-};
-
-struct s2n_cipher_suite *cipher_suites_elb_security_policy_tls_1_2_2017_01[] = {
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_256_cbc_sha256,
-};
-
-const struct s2n_cipher_preferences elb_security_policy_tls_1_2_2017_01 = {
- .count = s2n_array_len(cipher_suites_elb_security_policy_tls_1_2_2017_01),
- .suites = cipher_suites_elb_security_policy_tls_1_2_2017_01,
-};
-
-struct s2n_cipher_suite *cipher_suites_elb_security_policy_tls_1_1_2017_01[] = {
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_256_cbc_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
-};
-
-const struct s2n_cipher_preferences elb_security_policy_tls_1_1_2017_01 = {
- .count = s2n_array_len(cipher_suites_elb_security_policy_tls_1_1_2017_01),
- .suites = cipher_suites_elb_security_policy_tls_1_1_2017_01,
-};
-
-struct s2n_cipher_suite *cipher_suites_elb_security_policy_tls_1_2_ext_2018_06[] = {
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_256_cbc_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
-};
-
-const struct s2n_cipher_preferences elb_security_policy_tls_1_2_ext_2018_06 = {
- .count = s2n_array_len(cipher_suites_elb_security_policy_tls_1_2_ext_2018_06),
- .suites = cipher_suites_elb_security_policy_tls_1_2_ext_2018_06,
-};
-
-struct s2n_cipher_suite *cipher_suites_elb_security_policy_fs_2018_06[] = {
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
-};
-
-const struct s2n_cipher_preferences elb_security_policy_fs_2018_06 = {
- .count = s2n_array_len(cipher_suites_elb_security_policy_fs_2018_06),
- .suites = cipher_suites_elb_security_policy_fs_2018_06,
-};
-
-struct s2n_cipher_suite *cipher_suites_elb_security_policy_fs_1_2_2019_08[] = {
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
-};
-
-const struct s2n_cipher_preferences elb_security_policy_fs_1_2_2019_08 = {
- .count = s2n_array_len(cipher_suites_elb_security_policy_fs_1_2_2019_08),
- .suites = cipher_suites_elb_security_policy_fs_1_2_2019_08,
-};
-
-struct s2n_cipher_suite *cipher_suites_elb_security_policy_fs_1_1_2019_08[] = {
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
-};
-
-const struct s2n_cipher_preferences elb_security_policy_fs_1_1_2019_08 = {
- .count = s2n_array_len(cipher_suites_elb_security_policy_fs_1_1_2019_08),
- .suites = cipher_suites_elb_security_policy_fs_1_1_2019_08,
-};
-
-struct s2n_cipher_suite *cipher_suites_elb_security_policy_fs_1_2_Res_2019_08[] = {
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
-};
-
-const struct s2n_cipher_preferences elb_security_policy_fs_1_2_Res_2019_08 = {
- .count = s2n_array_len(cipher_suites_elb_security_policy_fs_1_2_Res_2019_08),
- .suites = cipher_suites_elb_security_policy_fs_1_2_Res_2019_08,
-};
-
-struct s2n_cipher_suite *cipher_suites_cloudfront_upstream[] = {
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_3des_ede_cbc_sha,
- &s2n_rsa_with_rc4_128_md5
-};
-
-const struct s2n_cipher_preferences cipher_preferences_cloudfront_upstream = {
- .count = s2n_array_len(cipher_suites_cloudfront_upstream),
- .suites = cipher_suites_cloudfront_upstream,
-};
-
-/* CloudFront viewer facing (with TLS 1.3) */
-struct s2n_cipher_suite *cipher_suites_cloudfront_ssl_v_3[] = {
- S2N_TLS13_CLOUDFRONT_CIPHER_SUITES_20200716,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_3des_ede_cbc_sha,
- &s2n_rsa_with_rc4_128_md5
-};
-
-const struct s2n_cipher_preferences cipher_preferences_cloudfront_ssl_v_3 = {
- .count = s2n_array_len(cipher_suites_cloudfront_ssl_v_3),
- .suites = cipher_suites_cloudfront_ssl_v_3,
-};
-
-struct s2n_cipher_suite *cipher_suites_cloudfront_tls_1_0_2014[] = {
- S2N_TLS13_CLOUDFRONT_CIPHER_SUITES_20200716,
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256,
- &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_3des_ede_cbc_sha,
-};
-
-const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_0_2014 = {
- .count = s2n_array_len(cipher_suites_cloudfront_tls_1_0_2014),
- .suites = cipher_suites_cloudfront_tls_1_0_2014,
-};
-
-struct s2n_cipher_suite *cipher_suites_cloudfront_tls_1_0_2016[] = {
- S2N_TLS13_CLOUDFRONT_CIPHER_SUITES_20200716,
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256,
- &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_cbc_sha
-};
-
-const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_0_2016 = {
- .count = s2n_array_len(cipher_suites_cloudfront_tls_1_0_2016),
- .suites = cipher_suites_cloudfront_tls_1_0_2016,
-};
-
-struct s2n_cipher_suite *cipher_suites_cloudfront_tls_1_1_2016[] = {
- S2N_TLS13_CLOUDFRONT_CIPHER_SUITES_20200716,
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256,
- &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_cbc_sha
-};
-
-const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_1_2016 = {
- .count = s2n_array_len(cipher_suites_cloudfront_tls_1_1_2016),
- .suites = cipher_suites_cloudfront_tls_1_1_2016,
-};
-
-struct s2n_cipher_suite *cipher_suites_cloudfront_tls_1_2_2018[] = {
- S2N_TLS13_CLOUDFRONT_CIPHER_SUITES_20200716,
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256,
- &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_cbc_sha256
-};
-
-const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_2_2018 = {
- .count = s2n_array_len(cipher_suites_cloudfront_tls_1_2_2018),
- .suites = cipher_suites_cloudfront_tls_1_2_2018,
-};
-
-/* CloudFront viewer facing legacy TLS 1.2 policies */
-struct s2n_cipher_suite *cipher_suites_cloudfront_ssl_v_3_legacy[] = {
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_3des_ede_cbc_sha,
- &s2n_rsa_with_rc4_128_md5
-};
-
-const struct s2n_cipher_preferences cipher_preferences_cloudfront_ssl_v_3_legacy = {
- .count = s2n_array_len(cipher_suites_cloudfront_ssl_v_3_legacy),
- .suites = cipher_suites_cloudfront_ssl_v_3_legacy,
-};
-
-struct s2n_cipher_suite *cipher_suites_cloudfront_tls_1_0_2014_legacy[] = {
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_3des_ede_cbc_sha,
-};
-
-const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_0_2014_legacy = {
- .count = s2n_array_len(cipher_suites_cloudfront_tls_1_0_2014_legacy),
- .suites = cipher_suites_cloudfront_tls_1_0_2014_legacy,
-};
-
-struct s2n_cipher_suite *cipher_suites_cloudfront_tls_1_0_2016_legacy[] = {
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_cbc_sha
-};
-
-const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_0_2016_legacy = {
- .count = s2n_array_len(cipher_suites_cloudfront_tls_1_0_2016_legacy),
- .suites = cipher_suites_cloudfront_tls_1_0_2016_legacy,
-};
-
-struct s2n_cipher_suite *cipher_suites_cloudfront_tls_1_1_2016_legacy[] = {
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_cbc_sha
-};
-
-const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_1_2016_legacy = {
- .count = s2n_array_len(cipher_suites_cloudfront_tls_1_1_2016_legacy),
- .suites = cipher_suites_cloudfront_tls_1_1_2016_legacy,
-};
-
-struct s2n_cipher_suite *cipher_suites_cloudfront_tls_1_2_2018_legacy[] = {
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_cbc_sha256
-};
-
-const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_2_2018_legacy = {
- .count = s2n_array_len(cipher_suites_cloudfront_tls_1_2_2018_legacy),
- .suites = cipher_suites_cloudfront_tls_1_2_2018_legacy,
-};
-
-struct s2n_cipher_suite *cipher_suites_cloudfront_tls_1_2_2019_legacy[] = {
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256
-};
-
-const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_2_2019_legacy = {
- .count = s2n_array_len(cipher_suites_cloudfront_tls_1_2_2019_legacy),
- .suites = cipher_suites_cloudfront_tls_1_2_2019_legacy,
-};
-
-/* CloudFront upstream */
-struct s2n_cipher_suite *cipher_suites_cloudfront_upstream_tls10[] = {
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_3des_ede_cbc_sha,
- &s2n_rsa_with_rc4_128_md5
-};
-
-const struct s2n_cipher_preferences cipher_preferences_cloudfront_upstream_tls10 = {
- .count = s2n_array_len(cipher_suites_cloudfront_upstream_tls10),
- .suites = cipher_suites_cloudfront_upstream_tls10,
-};
-
-struct s2n_cipher_suite *cipher_suites_cloudfront_upstream_tls11[] = {
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_3des_ede_cbc_sha,
- &s2n_rsa_with_rc4_128_md5
-};
-
-const struct s2n_cipher_preferences cipher_preferences_cloudfront_upstream_tls11 = {
- .count = s2n_array_len(cipher_suites_cloudfront_upstream_tls11),
- .suites = cipher_suites_cloudfront_upstream_tls11,
-};
-
-struct s2n_cipher_suite *cipher_suites_cloudfront_upstream_tls12[] = {
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_aes_256_gcm_sha384,
- &s2n_rsa_with_aes_128_gcm_sha256,
- &s2n_rsa_with_aes_256_cbc_sha,
- &s2n_rsa_with_aes_128_cbc_sha256,
- &s2n_rsa_with_aes_128_cbc_sha,
- &s2n_rsa_with_3des_ede_cbc_sha,
- &s2n_rsa_with_rc4_128_md5
-};
-
-const struct s2n_cipher_preferences cipher_preferences_cloudfront_upstream_tls12 = {
- .count = s2n_array_len(cipher_suites_cloudfront_upstream_tls12),
- .suites = cipher_suites_cloudfront_upstream_tls12,
-};
-
-struct s2n_cipher_suite *cipher_suites_cloudfront_tls_1_2_2019[] = {
- S2N_TLS13_CLOUDFRONT_CIPHER_SUITES_20200716,
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256,
- &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256
-};
-
-const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_2_2019 = {
- .count = s2n_array_len(cipher_suites_cloudfront_tls_1_2_2019),
- .suites = cipher_suites_cloudfront_tls_1_2_2019,
-};
-
-struct s2n_cipher_suite *cipher_suites_kms_tls_1_0_2018_10[] = {
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_3des_ede_cbc_sha,
- &s2n_dhe_rsa_with_aes_256_cbc_sha256,
- &s2n_dhe_rsa_with_aes_128_cbc_sha256,
- &s2n_dhe_rsa_with_aes_256_cbc_sha,
- &s2n_dhe_rsa_with_aes_128_cbc_sha,
-};
-
-const struct s2n_cipher_preferences cipher_preferences_kms_tls_1_0_2018_10 = {
- .count = s2n_array_len(cipher_suites_kms_tls_1_0_2018_10),
- .suites = cipher_suites_kms_tls_1_0_2018_10,
-};
-
-#if !defined(S2N_NO_PQ)
-
-struct s2n_cipher_suite *cipher_suites_kms_pq_tls_1_0_2019_06[] = {
- &s2n_ecdhe_bike_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_sike_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_3des_ede_cbc_sha,
- &s2n_dhe_rsa_with_aes_256_cbc_sha256,
- &s2n_dhe_rsa_with_aes_128_cbc_sha256,
- &s2n_dhe_rsa_with_aes_256_cbc_sha,
- &s2n_dhe_rsa_with_aes_128_cbc_sha,
-};
-
-/* Includes only round 1 PQ KEM params */
-const struct s2n_cipher_preferences cipher_preferences_kms_pq_tls_1_0_2019_06 = {
- .count = s2n_array_len(cipher_suites_kms_pq_tls_1_0_2019_06),
- .suites = cipher_suites_kms_pq_tls_1_0_2019_06,
-};
-
-/* Includes round 1 and round 2 PQ KEM params. The cipher suite list is the same
- * as in cipher_preferences_kms_pq_tls_1_0_2019_06.*/
-const struct s2n_cipher_preferences cipher_preferences_kms_pq_tls_1_0_2020_02 = {
- .count = s2n_array_len(cipher_suites_kms_pq_tls_1_0_2019_06),
- .suites = cipher_suites_kms_pq_tls_1_0_2019_06,
-};
-
-struct s2n_cipher_suite *cipher_suites_pq_sike_test_tls_1_0_2019_11[] = {
- &s2n_ecdhe_sike_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_3des_ede_cbc_sha,
- &s2n_dhe_rsa_with_aes_256_cbc_sha256,
- &s2n_dhe_rsa_with_aes_128_cbc_sha256,
- &s2n_dhe_rsa_with_aes_256_cbc_sha,
- &s2n_dhe_rsa_with_aes_128_cbc_sha,
-};
-
-/* Includes only SIKE round 1 (for integration tests) */
-const struct s2n_cipher_preferences cipher_preferences_pq_sike_test_tls_1_0_2019_11 = {
- .count = s2n_array_len(cipher_suites_pq_sike_test_tls_1_0_2019_11),
- .suites = cipher_suites_pq_sike_test_tls_1_0_2019_11,
-};
-
-/* Includes only SIKE round 1 and round 2 (for integration tests). The cipher suite list
- * is the same as in cipher_preferences_pq_sike_test_tls_1_0_2019_11. */
-const struct s2n_cipher_preferences cipher_preferences_pq_sike_test_tls_1_0_2020_02 = {
- .count = s2n_array_len(cipher_suites_pq_sike_test_tls_1_0_2019_11),
- .suites = cipher_suites_pq_sike_test_tls_1_0_2019_11,
-};
-
-/* Includes Both Round 2 and Round 1 PQ Ciphers */
-struct s2n_cipher_suite *cipher_suites_kms_pq_tls_1_0_2020_07[] = {
- &s2n_ecdhe_kyber_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_bike_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_sike_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_3des_ede_cbc_sha,
- &s2n_dhe_rsa_with_aes_256_cbc_sha256,
- &s2n_dhe_rsa_with_aes_128_cbc_sha256,
- &s2n_dhe_rsa_with_aes_256_cbc_sha,
- &s2n_dhe_rsa_with_aes_128_cbc_sha,
-};
-
-const struct s2n_cipher_preferences cipher_preferences_kms_pq_tls_1_0_2020_07 = {
- .count = s2n_array_len(cipher_suites_kms_pq_tls_1_0_2020_07),
- .suites = cipher_suites_kms_pq_tls_1_0_2020_07,
-};
-
-struct s2n_cipher_suite *cipher_suites_pq_tls_1_0_2020_12[] = {
- S2N_TLS13_CIPHER_SUITES_20190801,
- &s2n_ecdhe_kyber_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_bike_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_sike_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_ecdhe_rsa_with_3des_ede_cbc_sha,
- &s2n_dhe_rsa_with_aes_256_cbc_sha256,
- &s2n_dhe_rsa_with_aes_128_cbc_sha256,
- &s2n_dhe_rsa_with_aes_256_cbc_sha,
- &s2n_dhe_rsa_with_aes_128_cbc_sha,
-};
-
-const struct s2n_cipher_preferences cipher_preferences_pq_tls_1_0_2020_12 = {
- .count = s2n_array_len(cipher_suites_pq_tls_1_0_2020_12),
- .suites = cipher_suites_pq_tls_1_0_2020_12,
-};
-
-#endif
-
-struct s2n_cipher_suite *cipher_suites_kms_fips_tls_1_2_2018_10[] = {
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
- &s2n_dhe_rsa_with_aes_256_cbc_sha256,
- &s2n_dhe_rsa_with_aes_128_cbc_sha256,
-};
-
-const struct s2n_cipher_preferences cipher_preferences_kms_fips_tls_1_2_2018_10 = {
- .count = s2n_array_len(cipher_suites_kms_fips_tls_1_2_2018_10),
- .suites = cipher_suites_kms_fips_tls_1_2_2018_10,
-};
-
-/* clang-format on */
+/*
+ * 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 "tls/s2n_cipher_preferences.h"
+#include <s2n.h>
+#include <stdint.h>
+#include <strings.h>
+#include "tls/s2n_config.h"
+#include "tls/s2n_kem.h"
+#include "tls/s2n_kex.h"
+
+#include "error/s2n_errno.h"
+#include "utils/s2n_safety.h"
+
+/* clang-format off */
+/* TLS 1.3 cipher suites, in order of preference.
+ * Can be added to other ciphers suite lists to enable
+ * TLS1.3 compatibility. */
+#define S2N_TLS13_CIPHER_SUITES_20190801 \
+ &s2n_tls13_aes_256_gcm_sha384, \
+ &s2n_tls13_aes_128_gcm_sha256, \
+ &s2n_tls13_chacha20_poly1305_sha256
+
+#define S2N_TLS13_CLOUDFRONT_CIPHER_SUITES_20200716 \
+ &s2n_tls13_aes_128_gcm_sha256, \
+ &s2n_tls13_aes_256_gcm_sha384, \
+ &s2n_tls13_chacha20_poly1305_sha256
+
+/* s2n's list of cipher suites, in order of preferences, as of 2019-08-01 */
+struct s2n_cipher_suite *cipher_suites_20190801[] = {
+ S2N_TLS13_CIPHER_SUITES_20190801,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha
+};
+
+const struct s2n_cipher_preferences cipher_preferences_20190801 = {
+ .count = s2n_array_len(cipher_suites_20190801),
+ .suites = cipher_suites_20190801,
+};
+
+/* 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,
+ &s2n_dhe_rsa_with_aes_128_cbc_sha,
+ &s2n_dhe_rsa_with_3des_ede_cbc_sha,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_3des_ede_cbc_sha,
+ &s2n_rsa_with_rc4_128_sha,
+ &s2n_rsa_with_rc4_128_md5
+};
+
+const struct s2n_cipher_preferences cipher_preferences_20140601 = {
+ .count = s2n_array_len(cipher_suites_20140601),
+ .suites = cipher_suites_20140601,
+};
+
+/* Disable SSLv3 due to POODLE */
+const struct s2n_cipher_preferences cipher_preferences_20141001 = {
+ .count = s2n_array_len(cipher_suites_20140601),
+ .suites = cipher_suites_20140601,
+};
+
+/* Disable RC4 */
+struct s2n_cipher_suite *cipher_suites_20150202[] = {
+ &s2n_dhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_dhe_rsa_with_aes_128_cbc_sha,
+ &s2n_dhe_rsa_with_3des_ede_cbc_sha,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_3des_ede_cbc_sha
+};
+
+const struct s2n_cipher_preferences cipher_preferences_20150202 = {
+ .count = s2n_array_len(cipher_suites_20150202),
+ .suites = cipher_suites_20150202,
+};
+
+/* Support AES-GCM modes */
+struct s2n_cipher_suite *cipher_suites_20150214[] = {
+ &s2n_dhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_dhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_dhe_rsa_with_aes_128_cbc_sha,
+ &s2n_dhe_rsa_with_3des_ede_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_3des_ede_cbc_sha
+};
+
+const struct s2n_cipher_preferences cipher_preferences_20150214 = {
+ .count = s2n_array_len(cipher_suites_20150214),
+ .suites = cipher_suites_20150214,
+};
+
+/* Make a CBC cipher #1 to avoid negotiating GCM with buggy Java clients */
+struct s2n_cipher_suite *cipher_suites_20160411[] = {
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &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_sha,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_256_cbc_sha256,
+ &s2n_rsa_with_3des_ede_cbc_sha,
+};
+
+const struct s2n_cipher_preferences cipher_preferences_20160411 = {
+ .count = s2n_array_len(cipher_suites_20160411),
+ .suites = cipher_suites_20160411,
+};
+
+/* Use ECDHE instead of plain DHE. Prioritize ECDHE in favour of non ECDHE; GCM in favour of CBC; AES128 in favour of AES256. */
+struct s2n_cipher_suite *cipher_suites_20150306[] = {
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_3des_ede_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_3des_ede_cbc_sha
+};
+
+const struct s2n_cipher_preferences cipher_preferences_20150306 = {
+ .count = s2n_array_len(cipher_suites_20150306),
+ .suites = cipher_suites_20150306,
+};
+
+struct s2n_cipher_suite *cipher_suites_20160804[] = {
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_256_cbc_sha256,
+ &s2n_rsa_with_3des_ede_cbc_sha
+};
+
+const struct s2n_cipher_preferences cipher_preferences_20160804 = {
+ .count = s2n_array_len(cipher_suites_20160804),
+ .suites = cipher_suites_20160804,
+};
+
+struct s2n_cipher_suite *cipher_suites_20160824[] = {
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha
+};
+
+const struct s2n_cipher_preferences cipher_preferences_20160824 = {
+ .count = s2n_array_len(cipher_suites_20160824),
+ .suites = cipher_suites_20160824,
+};
+
+/* Add ChaCha20 suite */
+struct s2n_cipher_suite *cipher_suites_20170210[] = {
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha
+};
+
+const struct s2n_cipher_preferences cipher_preferences_20170210 = {
+ .count = s2n_array_len(cipher_suites_20170210),
+ .suites = cipher_suites_20170210,
+};
+
+/* Same as 20160411, but with ChaCha20 added as 1st in Preference List */
+struct s2n_cipher_suite *cipher_suites_20190122[] = {
+ &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &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_sha,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_256_cbc_sha256,
+ &s2n_rsa_with_3des_ede_cbc_sha,
+};
+
+const struct s2n_cipher_preferences cipher_preferences_20190122 = {
+ .count = s2n_array_len(cipher_suites_20190122),
+ .suites = cipher_suites_20190122,
+};
+
+/* Same as 20160804, but with ChaCha20 added as 2nd in Preference List */
+struct s2n_cipher_suite *cipher_suites_20190121[] = {
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_256_cbc_sha256,
+ &s2n_rsa_with_3des_ede_cbc_sha
+};
+
+const struct s2n_cipher_preferences cipher_preferences_20190121 = {
+ .count = s2n_array_len(cipher_suites_20190121),
+ .suites = cipher_suites_20190121,
+};
+
+/* Same as 20160411, but with ChaCha20 in 3rd Place after CBC and GCM */
+struct s2n_cipher_suite *cipher_suites_20190120[] = {
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_256_cbc_sha256,
+ &s2n_rsa_with_3des_ede_cbc_sha,
+};
+
+const struct s2n_cipher_preferences cipher_preferences_20190120 = {
+ .count = s2n_array_len(cipher_suites_20190120),
+ .suites = cipher_suites_20190120,
+};
+
+/* Preferences optimized for interop, includes ECDSA priortitized. DHE and 3DES are added(at the lowest preference). */
+struct s2n_cipher_suite *cipher_suites_20190214[] = {
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_256_cbc_sha256,
+ &s2n_rsa_with_3des_ede_cbc_sha,
+ &s2n_dhe_rsa_with_aes_128_cbc_sha,
+ &s2n_dhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_dhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_dhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_dhe_rsa_with_aes_256_cbc_sha,
+ &s2n_dhe_rsa_with_aes_256_cbc_sha256,
+};
+
+const struct s2n_cipher_preferences cipher_preferences_20190214 = {
+ .count = s2n_array_len(cipher_suites_20190214),
+ .suites = cipher_suites_20190214,
+};
+
+struct s2n_cipher_suite *cipher_suites_null[] = {
+ &s2n_null_cipher_suite
+};
+
+const struct s2n_cipher_preferences cipher_preferences_null = {
+ .count = s2n_array_len(cipher_suites_null),
+ .suites = cipher_suites_null,
+};
+
+/* Preferences optimized for interop. DHE and 3DES are added(at the lowest preference). */
+struct s2n_cipher_suite *cipher_suites_20170328[] = {
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &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_sha,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_256_cbc_sha256,
+ &s2n_rsa_with_3des_ede_cbc_sha,
+ &s2n_dhe_rsa_with_aes_128_cbc_sha,
+ &s2n_dhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_dhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_dhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_dhe_rsa_with_aes_256_cbc_sha,
+ &s2n_dhe_rsa_with_aes_256_cbc_sha256,
+};
+
+const struct s2n_cipher_preferences cipher_preferences_20170328 = {
+ .count = s2n_array_len(cipher_suites_20170328),
+ .suites = cipher_suites_20170328,
+};
+
+/* Preferences optimized for FIPS compatibility. */
+struct s2n_cipher_suite *cipher_suites_20170405[] = {
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_256_cbc_sha256,
+ &s2n_rsa_with_3des_ede_cbc_sha,
+};
+
+const struct s2n_cipher_preferences cipher_preferences_20170405 = {
+ .count = s2n_array_len(cipher_suites_20170405),
+ .suites = cipher_suites_20170405,
+};
+
+/* Equivalent to cipher_suite_20160411 with 3DES removed.
+ * Make a CBC cipher #1 to avoid negotiating GCM with buggy Java clients. */
+struct s2n_cipher_suite *cipher_suites_20170718[] = {
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &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_sha,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_256_cbc_sha256,
+};
+
+const struct s2n_cipher_preferences cipher_preferences_20170718 = {
+ .count = s2n_array_len(cipher_suites_20170718),
+ .suites = cipher_suites_20170718,
+};
+
+struct s2n_cipher_suite *cipher_suites_elb_security_policy_2015_04[] = {
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_256_cbc_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_3des_ede_cbc_sha,
+};
+
+const struct s2n_cipher_preferences elb_security_policy_2015_04 = {
+ .count = s2n_array_len(cipher_suites_elb_security_policy_2015_04),
+ .suites = cipher_suites_elb_security_policy_2015_04,
+};
+
+struct s2n_cipher_suite *cipher_suites_elb_security_policy_2016_08[] = {
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_256_cbc_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+};
+
+const struct s2n_cipher_preferences elb_security_policy_2016_08 = {
+ .count = s2n_array_len(cipher_suites_elb_security_policy_2016_08),
+ .suites = cipher_suites_elb_security_policy_2016_08,
+};
+
+struct s2n_cipher_suite *cipher_suites_elb_security_policy_tls_1_2_2017_01[] = {
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_256_cbc_sha256,
+};
+
+const struct s2n_cipher_preferences elb_security_policy_tls_1_2_2017_01 = {
+ .count = s2n_array_len(cipher_suites_elb_security_policy_tls_1_2_2017_01),
+ .suites = cipher_suites_elb_security_policy_tls_1_2_2017_01,
+};
+
+struct s2n_cipher_suite *cipher_suites_elb_security_policy_tls_1_1_2017_01[] = {
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_256_cbc_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+};
+
+const struct s2n_cipher_preferences elb_security_policy_tls_1_1_2017_01 = {
+ .count = s2n_array_len(cipher_suites_elb_security_policy_tls_1_1_2017_01),
+ .suites = cipher_suites_elb_security_policy_tls_1_1_2017_01,
+};
+
+struct s2n_cipher_suite *cipher_suites_elb_security_policy_tls_1_2_ext_2018_06[] = {
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_256_cbc_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+};
+
+const struct s2n_cipher_preferences elb_security_policy_tls_1_2_ext_2018_06 = {
+ .count = s2n_array_len(cipher_suites_elb_security_policy_tls_1_2_ext_2018_06),
+ .suites = cipher_suites_elb_security_policy_tls_1_2_ext_2018_06,
+};
+
+struct s2n_cipher_suite *cipher_suites_elb_security_policy_fs_2018_06[] = {
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
+};
+
+const struct s2n_cipher_preferences elb_security_policy_fs_2018_06 = {
+ .count = s2n_array_len(cipher_suites_elb_security_policy_fs_2018_06),
+ .suites = cipher_suites_elb_security_policy_fs_2018_06,
+};
+
+struct s2n_cipher_suite *cipher_suites_elb_security_policy_fs_1_2_2019_08[] = {
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
+};
+
+const struct s2n_cipher_preferences elb_security_policy_fs_1_2_2019_08 = {
+ .count = s2n_array_len(cipher_suites_elb_security_policy_fs_1_2_2019_08),
+ .suites = cipher_suites_elb_security_policy_fs_1_2_2019_08,
+};
+
+struct s2n_cipher_suite *cipher_suites_elb_security_policy_fs_1_1_2019_08[] = {
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
+};
+
+const struct s2n_cipher_preferences elb_security_policy_fs_1_1_2019_08 = {
+ .count = s2n_array_len(cipher_suites_elb_security_policy_fs_1_1_2019_08),
+ .suites = cipher_suites_elb_security_policy_fs_1_1_2019_08,
+};
+
+struct s2n_cipher_suite *cipher_suites_elb_security_policy_fs_1_2_Res_2019_08[] = {
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+};
+
+const struct s2n_cipher_preferences elb_security_policy_fs_1_2_Res_2019_08 = {
+ .count = s2n_array_len(cipher_suites_elb_security_policy_fs_1_2_Res_2019_08),
+ .suites = cipher_suites_elb_security_policy_fs_1_2_Res_2019_08,
+};
+
+struct s2n_cipher_suite *cipher_suites_cloudfront_upstream[] = {
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_3des_ede_cbc_sha,
+ &s2n_rsa_with_rc4_128_md5
+};
+
+const struct s2n_cipher_preferences cipher_preferences_cloudfront_upstream = {
+ .count = s2n_array_len(cipher_suites_cloudfront_upstream),
+ .suites = cipher_suites_cloudfront_upstream,
+};
+
+/* CloudFront viewer facing (with TLS 1.3) */
+struct s2n_cipher_suite *cipher_suites_cloudfront_ssl_v_3[] = {
+ S2N_TLS13_CLOUDFRONT_CIPHER_SUITES_20200716,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_3des_ede_cbc_sha,
+ &s2n_rsa_with_rc4_128_md5
+};
+
+const struct s2n_cipher_preferences cipher_preferences_cloudfront_ssl_v_3 = {
+ .count = s2n_array_len(cipher_suites_cloudfront_ssl_v_3),
+ .suites = cipher_suites_cloudfront_ssl_v_3,
+};
+
+struct s2n_cipher_suite *cipher_suites_cloudfront_tls_1_0_2014[] = {
+ S2N_TLS13_CLOUDFRONT_CIPHER_SUITES_20200716,
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256,
+ &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_3des_ede_cbc_sha,
+};
+
+const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_0_2014 = {
+ .count = s2n_array_len(cipher_suites_cloudfront_tls_1_0_2014),
+ .suites = cipher_suites_cloudfront_tls_1_0_2014,
+};
+
+struct s2n_cipher_suite *cipher_suites_cloudfront_tls_1_0_2016[] = {
+ S2N_TLS13_CLOUDFRONT_CIPHER_SUITES_20200716,
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256,
+ &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_cbc_sha
+};
+
+const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_0_2016 = {
+ .count = s2n_array_len(cipher_suites_cloudfront_tls_1_0_2016),
+ .suites = cipher_suites_cloudfront_tls_1_0_2016,
+};
+
+struct s2n_cipher_suite *cipher_suites_cloudfront_tls_1_1_2016[] = {
+ S2N_TLS13_CLOUDFRONT_CIPHER_SUITES_20200716,
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256,
+ &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_cbc_sha
+};
+
+const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_1_2016 = {
+ .count = s2n_array_len(cipher_suites_cloudfront_tls_1_1_2016),
+ .suites = cipher_suites_cloudfront_tls_1_1_2016,
+};
+
+struct s2n_cipher_suite *cipher_suites_cloudfront_tls_1_2_2018[] = {
+ S2N_TLS13_CLOUDFRONT_CIPHER_SUITES_20200716,
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256,
+ &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha256
+};
+
+const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_2_2018 = {
+ .count = s2n_array_len(cipher_suites_cloudfront_tls_1_2_2018),
+ .suites = cipher_suites_cloudfront_tls_1_2_2018,
+};
+
+/* CloudFront viewer facing legacy TLS 1.2 policies */
+struct s2n_cipher_suite *cipher_suites_cloudfront_ssl_v_3_legacy[] = {
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_3des_ede_cbc_sha,
+ &s2n_rsa_with_rc4_128_md5
+};
+
+const struct s2n_cipher_preferences cipher_preferences_cloudfront_ssl_v_3_legacy = {
+ .count = s2n_array_len(cipher_suites_cloudfront_ssl_v_3_legacy),
+ .suites = cipher_suites_cloudfront_ssl_v_3_legacy,
+};
+
+struct s2n_cipher_suite *cipher_suites_cloudfront_tls_1_0_2014_legacy[] = {
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_3des_ede_cbc_sha,
+};
+
+const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_0_2014_legacy = {
+ .count = s2n_array_len(cipher_suites_cloudfront_tls_1_0_2014_legacy),
+ .suites = cipher_suites_cloudfront_tls_1_0_2014_legacy,
+};
+
+struct s2n_cipher_suite *cipher_suites_cloudfront_tls_1_0_2016_legacy[] = {
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_cbc_sha
+};
+
+const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_0_2016_legacy = {
+ .count = s2n_array_len(cipher_suites_cloudfront_tls_1_0_2016_legacy),
+ .suites = cipher_suites_cloudfront_tls_1_0_2016_legacy,
+};
+
+struct s2n_cipher_suite *cipher_suites_cloudfront_tls_1_1_2016_legacy[] = {
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_cbc_sha
+};
+
+const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_1_2016_legacy = {
+ .count = s2n_array_len(cipher_suites_cloudfront_tls_1_1_2016_legacy),
+ .suites = cipher_suites_cloudfront_tls_1_1_2016_legacy,
+};
+
+struct s2n_cipher_suite *cipher_suites_cloudfront_tls_1_2_2018_legacy[] = {
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_cbc_sha256
+};
+
+const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_2_2018_legacy = {
+ .count = s2n_array_len(cipher_suites_cloudfront_tls_1_2_2018_legacy),
+ .suites = cipher_suites_cloudfront_tls_1_2_2018_legacy,
+};
+
+struct s2n_cipher_suite *cipher_suites_cloudfront_tls_1_2_2019_legacy[] = {
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256
+};
+
+const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_2_2019_legacy = {
+ .count = s2n_array_len(cipher_suites_cloudfront_tls_1_2_2019_legacy),
+ .suites = cipher_suites_cloudfront_tls_1_2_2019_legacy,
+};
+
+/* CloudFront upstream */
+struct s2n_cipher_suite *cipher_suites_cloudfront_upstream_tls10[] = {
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_3des_ede_cbc_sha,
+ &s2n_rsa_with_rc4_128_md5
+};
+
+const struct s2n_cipher_preferences cipher_preferences_cloudfront_upstream_tls10 = {
+ .count = s2n_array_len(cipher_suites_cloudfront_upstream_tls10),
+ .suites = cipher_suites_cloudfront_upstream_tls10,
+};
+
+struct s2n_cipher_suite *cipher_suites_cloudfront_upstream_tls11[] = {
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_3des_ede_cbc_sha,
+ &s2n_rsa_with_rc4_128_md5
+};
+
+const struct s2n_cipher_preferences cipher_preferences_cloudfront_upstream_tls11 = {
+ .count = s2n_array_len(cipher_suites_cloudfront_upstream_tls11),
+ .suites = cipher_suites_cloudfront_upstream_tls11,
+};
+
+struct s2n_cipher_suite *cipher_suites_cloudfront_upstream_tls12[] = {
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_128_gcm_sha256,
+ &s2n_rsa_with_aes_256_cbc_sha,
+ &s2n_rsa_with_aes_128_cbc_sha256,
+ &s2n_rsa_with_aes_128_cbc_sha,
+ &s2n_rsa_with_3des_ede_cbc_sha,
+ &s2n_rsa_with_rc4_128_md5
+};
+
+const struct s2n_cipher_preferences cipher_preferences_cloudfront_upstream_tls12 = {
+ .count = s2n_array_len(cipher_suites_cloudfront_upstream_tls12),
+ .suites = cipher_suites_cloudfront_upstream_tls12,
+};
+
+struct s2n_cipher_suite *cipher_suites_cloudfront_tls_1_2_2019[] = {
+ S2N_TLS13_CLOUDFRONT_CIPHER_SUITES_20200716,
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256,
+ &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256,
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256
+};
+
+const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_2_2019 = {
+ .count = s2n_array_len(cipher_suites_cloudfront_tls_1_2_2019),
+ .suites = cipher_suites_cloudfront_tls_1_2_2019,
+};
+
+struct s2n_cipher_suite *cipher_suites_kms_tls_1_0_2018_10[] = {
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_3des_ede_cbc_sha,
+ &s2n_dhe_rsa_with_aes_256_cbc_sha256,
+ &s2n_dhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_dhe_rsa_with_aes_256_cbc_sha,
+ &s2n_dhe_rsa_with_aes_128_cbc_sha,
+};
+
+const struct s2n_cipher_preferences cipher_preferences_kms_tls_1_0_2018_10 = {
+ .count = s2n_array_len(cipher_suites_kms_tls_1_0_2018_10),
+ .suites = cipher_suites_kms_tls_1_0_2018_10,
+};
+
+#if !defined(S2N_NO_PQ)
+
+struct s2n_cipher_suite *cipher_suites_kms_pq_tls_1_0_2019_06[] = {
+ &s2n_ecdhe_bike_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_sike_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_3des_ede_cbc_sha,
+ &s2n_dhe_rsa_with_aes_256_cbc_sha256,
+ &s2n_dhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_dhe_rsa_with_aes_256_cbc_sha,
+ &s2n_dhe_rsa_with_aes_128_cbc_sha,
+};
+
+/* Includes only round 1 PQ KEM params */
+const struct s2n_cipher_preferences cipher_preferences_kms_pq_tls_1_0_2019_06 = {
+ .count = s2n_array_len(cipher_suites_kms_pq_tls_1_0_2019_06),
+ .suites = cipher_suites_kms_pq_tls_1_0_2019_06,
+};
+
+/* Includes round 1 and round 2 PQ KEM params. The cipher suite list is the same
+ * as in cipher_preferences_kms_pq_tls_1_0_2019_06.*/
+const struct s2n_cipher_preferences cipher_preferences_kms_pq_tls_1_0_2020_02 = {
+ .count = s2n_array_len(cipher_suites_kms_pq_tls_1_0_2019_06),
+ .suites = cipher_suites_kms_pq_tls_1_0_2019_06,
+};
+
+struct s2n_cipher_suite *cipher_suites_pq_sike_test_tls_1_0_2019_11[] = {
+ &s2n_ecdhe_sike_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_3des_ede_cbc_sha,
+ &s2n_dhe_rsa_with_aes_256_cbc_sha256,
+ &s2n_dhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_dhe_rsa_with_aes_256_cbc_sha,
+ &s2n_dhe_rsa_with_aes_128_cbc_sha,
+};
+
+/* Includes only SIKE round 1 (for integration tests) */
+const struct s2n_cipher_preferences cipher_preferences_pq_sike_test_tls_1_0_2019_11 = {
+ .count = s2n_array_len(cipher_suites_pq_sike_test_tls_1_0_2019_11),
+ .suites = cipher_suites_pq_sike_test_tls_1_0_2019_11,
+};
+
+/* Includes only SIKE round 1 and round 2 (for integration tests). The cipher suite list
+ * is the same as in cipher_preferences_pq_sike_test_tls_1_0_2019_11. */
+const struct s2n_cipher_preferences cipher_preferences_pq_sike_test_tls_1_0_2020_02 = {
+ .count = s2n_array_len(cipher_suites_pq_sike_test_tls_1_0_2019_11),
+ .suites = cipher_suites_pq_sike_test_tls_1_0_2019_11,
+};
+
+/* Includes Both Round 2 and Round 1 PQ Ciphers */
+struct s2n_cipher_suite *cipher_suites_kms_pq_tls_1_0_2020_07[] = {
+ &s2n_ecdhe_kyber_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_bike_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_sike_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_3des_ede_cbc_sha,
+ &s2n_dhe_rsa_with_aes_256_cbc_sha256,
+ &s2n_dhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_dhe_rsa_with_aes_256_cbc_sha,
+ &s2n_dhe_rsa_with_aes_128_cbc_sha,
+};
+
+const struct s2n_cipher_preferences cipher_preferences_kms_pq_tls_1_0_2020_07 = {
+ .count = s2n_array_len(cipher_suites_kms_pq_tls_1_0_2020_07),
+ .suites = cipher_suites_kms_pq_tls_1_0_2020_07,
+};
+
+struct s2n_cipher_suite *cipher_suites_pq_tls_1_0_2020_12[] = {
+ S2N_TLS13_CIPHER_SUITES_20190801,
+ &s2n_ecdhe_kyber_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_bike_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_sike_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_ecdhe_rsa_with_3des_ede_cbc_sha,
+ &s2n_dhe_rsa_with_aes_256_cbc_sha256,
+ &s2n_dhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_dhe_rsa_with_aes_256_cbc_sha,
+ &s2n_dhe_rsa_with_aes_128_cbc_sha,
+};
+
+const struct s2n_cipher_preferences cipher_preferences_pq_tls_1_0_2020_12 = {
+ .count = s2n_array_len(cipher_suites_pq_tls_1_0_2020_12),
+ .suites = cipher_suites_pq_tls_1_0_2020_12,
+};
+
+#endif
+
+struct s2n_cipher_suite *cipher_suites_kms_fips_tls_1_2_2018_10[] = {
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256,
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384,
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256,
+ &s2n_dhe_rsa_with_aes_256_cbc_sha256,
+ &s2n_dhe_rsa_with_aes_128_cbc_sha256,
+};
+
+const struct s2n_cipher_preferences cipher_preferences_kms_fips_tls_1_2_2018_10 = {
+ .count = s2n_array_len(cipher_suites_kms_fips_tls_1_2_2018_10),
+ .suites = cipher_suites_kms_fips_tls_1_2_2018_10,
+};
+
+/* clang-format on */
diff --git a/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.h b/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.h
index d48935608b..b70fa55922 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.h
@@ -1,103 +1,103 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <stdint.h>
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_kem.h"
-#include "tls/s2n_tls13.h"
-
-struct s2n_cipher_preferences {
- uint8_t count;
- struct s2n_cipher_suite **suites;
-};
-
-extern const struct s2n_cipher_preferences cipher_preferences_20140601;
-extern const struct s2n_cipher_preferences cipher_preferences_20141001;
-extern const struct s2n_cipher_preferences cipher_preferences_20150202;
-extern const struct s2n_cipher_preferences cipher_preferences_20150214;
-extern const struct s2n_cipher_preferences cipher_preferences_20150306;
-extern const struct s2n_cipher_preferences cipher_preferences_20160411;
-extern const struct s2n_cipher_preferences cipher_preferences_20160804;
-extern const struct s2n_cipher_preferences cipher_preferences_20160824;
-extern const struct s2n_cipher_preferences cipher_preferences_20170210;
-extern const struct s2n_cipher_preferences cipher_preferences_20170328;
-extern const struct s2n_cipher_preferences cipher_preferences_20170405;
-extern const struct s2n_cipher_preferences cipher_preferences_20170718;
-extern const struct s2n_cipher_preferences cipher_preferences_20190214;
-extern const struct s2n_cipher_preferences cipher_preferences_20190801;
-extern const struct s2n_cipher_preferences cipher_preferences_20190120;
-extern const struct s2n_cipher_preferences cipher_preferences_20190121;
-extern const struct s2n_cipher_preferences cipher_preferences_20190122;
-extern const struct s2n_cipher_preferences cipher_preferences_test_all;
-
-extern const struct s2n_cipher_preferences cipher_preferences_test_all_tls12;
-extern const struct s2n_cipher_preferences cipher_preferences_test_all_fips;
-extern const struct s2n_cipher_preferences cipher_preferences_test_all_ecdsa;
-extern const struct s2n_cipher_preferences cipher_preferences_test_ecdsa_priority;
-extern const struct s2n_cipher_preferences cipher_preferences_test_all_rsa_kex;
-extern const struct s2n_cipher_preferences cipher_preferences_test_all_tls13;
-
-/* See https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html */
-extern const struct s2n_cipher_preferences elb_security_policy_2015_04;
-extern const struct s2n_cipher_preferences elb_security_policy_2016_08;
-
-extern const struct s2n_cipher_preferences elb_security_policy_tls_1_1_2017_01;
-extern const struct s2n_cipher_preferences elb_security_policy_tls_1_2_2017_01;
-extern const struct s2n_cipher_preferences elb_security_policy_tls_1_2_ext_2018_06;
-
-extern const struct s2n_cipher_preferences elb_security_policy_fs_2018_06;
-extern const struct s2n_cipher_preferences elb_security_policy_fs_1_2_2019_08;
-extern const struct s2n_cipher_preferences elb_security_policy_fs_1_1_2019_08;
-extern const struct s2n_cipher_preferences elb_security_policy_fs_1_2_Res_2019_08;
-
-/* CloudFront upstream */
-extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_upstream;
-extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_upstream_tls10;
-extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_upstream_tls11;
-extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_upstream_tls12;
-/* CloudFront viewer facing */
-extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_ssl_v_3;
-extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_0_2014;
-extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_0_2016;
-extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_1_2016;
-extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_2_2018;
-extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_2_2019;
-
-/* CloudFront viewer facing legacy TLS 1.2 policies */
-extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_ssl_v_3_legacy;
-extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_0_2014_legacy;
-extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_0_2016_legacy;
-extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_1_2016_legacy;
-extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_2_2018_legacy;
-extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_2_2019_legacy;
-
-extern const struct s2n_cipher_preferences cipher_preferences_kms_tls_1_0_2018_10;
-
-#if !defined(S2N_NO_PQ)
-
-extern const struct s2n_cipher_preferences cipher_preferences_kms_pq_tls_1_0_2019_06;
-extern const struct s2n_cipher_preferences cipher_preferences_kms_pq_tls_1_0_2020_02;
-extern const struct s2n_cipher_preferences cipher_preferences_kms_pq_tls_1_0_2020_07;
-extern const struct s2n_cipher_preferences cipher_preferences_pq_sike_test_tls_1_0_2019_11;
-extern const struct s2n_cipher_preferences cipher_preferences_pq_sike_test_tls_1_0_2020_02;
-extern const struct s2n_cipher_preferences cipher_preferences_pq_tls_1_0_2020_12;
-
-#endif
-
-extern const struct s2n_cipher_preferences cipher_preferences_kms_fips_tls_1_2_2018_10;
-extern const struct s2n_cipher_preferences cipher_preferences_null;
-
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_kem.h"
+#include "tls/s2n_tls13.h"
+
+struct s2n_cipher_preferences {
+ uint8_t count;
+ struct s2n_cipher_suite **suites;
+};
+
+extern const struct s2n_cipher_preferences cipher_preferences_20140601;
+extern const struct s2n_cipher_preferences cipher_preferences_20141001;
+extern const struct s2n_cipher_preferences cipher_preferences_20150202;
+extern const struct s2n_cipher_preferences cipher_preferences_20150214;
+extern const struct s2n_cipher_preferences cipher_preferences_20150306;
+extern const struct s2n_cipher_preferences cipher_preferences_20160411;
+extern const struct s2n_cipher_preferences cipher_preferences_20160804;
+extern const struct s2n_cipher_preferences cipher_preferences_20160824;
+extern const struct s2n_cipher_preferences cipher_preferences_20170210;
+extern const struct s2n_cipher_preferences cipher_preferences_20170328;
+extern const struct s2n_cipher_preferences cipher_preferences_20170405;
+extern const struct s2n_cipher_preferences cipher_preferences_20170718;
+extern const struct s2n_cipher_preferences cipher_preferences_20190214;
+extern const struct s2n_cipher_preferences cipher_preferences_20190801;
+extern const struct s2n_cipher_preferences cipher_preferences_20190120;
+extern const struct s2n_cipher_preferences cipher_preferences_20190121;
+extern const struct s2n_cipher_preferences cipher_preferences_20190122;
+extern const struct s2n_cipher_preferences cipher_preferences_test_all;
+
+extern const struct s2n_cipher_preferences cipher_preferences_test_all_tls12;
+extern const struct s2n_cipher_preferences cipher_preferences_test_all_fips;
+extern const struct s2n_cipher_preferences cipher_preferences_test_all_ecdsa;
+extern const struct s2n_cipher_preferences cipher_preferences_test_ecdsa_priority;
+extern const struct s2n_cipher_preferences cipher_preferences_test_all_rsa_kex;
+extern const struct s2n_cipher_preferences cipher_preferences_test_all_tls13;
+
+/* See https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html */
+extern const struct s2n_cipher_preferences elb_security_policy_2015_04;
+extern const struct s2n_cipher_preferences elb_security_policy_2016_08;
+
+extern const struct s2n_cipher_preferences elb_security_policy_tls_1_1_2017_01;
+extern const struct s2n_cipher_preferences elb_security_policy_tls_1_2_2017_01;
+extern const struct s2n_cipher_preferences elb_security_policy_tls_1_2_ext_2018_06;
+
+extern const struct s2n_cipher_preferences elb_security_policy_fs_2018_06;
+extern const struct s2n_cipher_preferences elb_security_policy_fs_1_2_2019_08;
+extern const struct s2n_cipher_preferences elb_security_policy_fs_1_1_2019_08;
+extern const struct s2n_cipher_preferences elb_security_policy_fs_1_2_Res_2019_08;
+
+/* CloudFront upstream */
+extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_upstream;
+extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_upstream_tls10;
+extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_upstream_tls11;
+extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_upstream_tls12;
+/* CloudFront viewer facing */
+extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_ssl_v_3;
+extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_0_2014;
+extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_0_2016;
+extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_1_2016;
+extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_2_2018;
+extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_2_2019;
+
+/* CloudFront viewer facing legacy TLS 1.2 policies */
+extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_ssl_v_3_legacy;
+extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_0_2014_legacy;
+extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_0_2016_legacy;
+extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_1_2016_legacy;
+extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_2_2018_legacy;
+extern const struct s2n_cipher_preferences cipher_preferences_cloudfront_tls_1_2_2019_legacy;
+
+extern const struct s2n_cipher_preferences cipher_preferences_kms_tls_1_0_2018_10;
+
+#if !defined(S2N_NO_PQ)
+
+extern const struct s2n_cipher_preferences cipher_preferences_kms_pq_tls_1_0_2019_06;
+extern const struct s2n_cipher_preferences cipher_preferences_kms_pq_tls_1_0_2020_02;
+extern const struct s2n_cipher_preferences cipher_preferences_kms_pq_tls_1_0_2020_07;
+extern const struct s2n_cipher_preferences cipher_preferences_pq_sike_test_tls_1_0_2019_11;
+extern const struct s2n_cipher_preferences cipher_preferences_pq_sike_test_tls_1_0_2020_02;
+extern const struct s2n_cipher_preferences cipher_preferences_pq_tls_1_0_2020_12;
+
+#endif
+
+extern const struct s2n_cipher_preferences cipher_preferences_kms_fips_tls_1_2_2018_10;
+extern const struct s2n_cipher_preferences cipher_preferences_null;
+
diff --git a/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c b/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c
index 0c2fdaeab2..f3597ee3c2 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c
@@ -1,1265 +1,1265 @@
-/*
- * 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 <string.h>
-
-#include <openssl/crypto.h>
-
-#include "error/s2n_errno.h"
-
-#include "crypto/s2n_cipher.h"
-#include "crypto/s2n_openssl.h"
-
-#include "tls/s2n_auth_selection.h"
-#include "tls/s2n_kex.h"
-#include "tls/s2n_security_policies.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls13.h"
-#include "utils/s2n_safety.h"
-#include "tls/s2n_psk.h"
-
-/*************************
- * S2n Record Algorithms *
- *************************/
-const struct s2n_record_algorithm s2n_record_alg_null = {
- .cipher = &s2n_null_cipher,
- .hmac_alg = S2N_HMAC_NONE,
- .flags = 0,
- .encryption_limit = UINT64_MAX,
-};
-
-const struct s2n_record_algorithm s2n_record_alg_rc4_md5 = {
- .cipher = &s2n_rc4,
- .hmac_alg = S2N_HMAC_MD5,
- .flags = 0,
- .encryption_limit = UINT64_MAX,
-};
-
-const struct s2n_record_algorithm s2n_record_alg_rc4_sslv3_md5 = {
- .cipher = &s2n_rc4,
- .hmac_alg = S2N_HMAC_SSLv3_MD5,
- .flags = 0,
- .encryption_limit = UINT64_MAX,
-};
-
-const struct s2n_record_algorithm s2n_record_alg_rc4_sha = {
- .cipher = &s2n_rc4,
- .hmac_alg = S2N_HMAC_SHA1,
- .flags = 0,
- .encryption_limit = UINT64_MAX,
-};
-
-const struct s2n_record_algorithm s2n_record_alg_rc4_sslv3_sha = {
- .cipher = &s2n_rc4,
- .hmac_alg = S2N_HMAC_SSLv3_SHA1,
- .flags = 0,
- .encryption_limit = UINT64_MAX,
-};
-
-const struct s2n_record_algorithm s2n_record_alg_3des_sha = {
- .cipher = &s2n_3des,
- .hmac_alg = S2N_HMAC_SHA1,
- .flags = 0,
- .encryption_limit = UINT64_MAX,
-};
-
-const struct s2n_record_algorithm s2n_record_alg_3des_sslv3_sha = {
- .cipher = &s2n_3des,
- .hmac_alg = S2N_HMAC_SSLv3_SHA1,
- .flags = 0,
- .encryption_limit = UINT64_MAX,
-};
-
-const struct s2n_record_algorithm s2n_record_alg_aes128_sha = {
- .cipher = &s2n_aes128,
- .hmac_alg = S2N_HMAC_SHA1,
- .flags = 0,
- .encryption_limit = UINT64_MAX,
-};
-
-const struct s2n_record_algorithm s2n_record_alg_aes128_sslv3_sha = {
- .cipher = &s2n_aes128,
- .hmac_alg = S2N_HMAC_SSLv3_SHA1,
- .flags = 0,
- .encryption_limit = UINT64_MAX,
-};
-
-const struct s2n_record_algorithm s2n_record_alg_aes128_sha_composite = {
- .cipher = &s2n_aes128_sha,
- .hmac_alg = S2N_HMAC_NONE,
- .flags = 0,
- .encryption_limit = UINT64_MAX,
-};
-
-const struct s2n_record_algorithm s2n_record_alg_aes128_sha256 = {
- .cipher = &s2n_aes128,
- .hmac_alg = S2N_HMAC_SHA256,
- .flags = 0,
- .encryption_limit = UINT64_MAX,
-};
-
-const struct s2n_record_algorithm s2n_record_alg_aes128_sha256_composite = {
- .cipher = &s2n_aes128_sha256,
- .hmac_alg = S2N_HMAC_NONE,
- .encryption_limit = UINT64_MAX,
-};
-
-const struct s2n_record_algorithm s2n_record_alg_aes256_sha = {
- .cipher = &s2n_aes256,
- .hmac_alg = S2N_HMAC_SHA1,
- .flags = 0,
- .encryption_limit = UINT64_MAX,
-};
-
-const struct s2n_record_algorithm s2n_record_alg_aes256_sslv3_sha = {
- .cipher = &s2n_aes256,
- .hmac_alg = S2N_HMAC_SSLv3_SHA1,
- .flags = 0,
- .encryption_limit = UINT64_MAX,
-};
-
-const struct s2n_record_algorithm s2n_record_alg_aes256_sha_composite = {
- .cipher = &s2n_aes256_sha,
- .hmac_alg = S2N_HMAC_NONE,
- .flags = 0,
- .encryption_limit = UINT64_MAX,
-};
-
-const struct s2n_record_algorithm s2n_record_alg_aes256_sha256 = {
- .cipher = &s2n_aes256,
- .hmac_alg = S2N_HMAC_SHA256,
- .flags = 0,
- .encryption_limit = UINT64_MAX,
-};
-
-const struct s2n_record_algorithm s2n_record_alg_aes256_sha256_composite = {
- .cipher = &s2n_aes256_sha256,
- .hmac_alg = S2N_HMAC_NONE,
- .encryption_limit = UINT64_MAX,
-};
-
-const struct s2n_record_algorithm s2n_record_alg_aes256_sha384 = {
- .cipher = &s2n_aes256,
- .hmac_alg = S2N_HMAC_SHA384,
- .flags = 0,
- .encryption_limit = UINT64_MAX,
-};
-
-const struct s2n_record_algorithm s2n_record_alg_aes128_gcm = {
- .cipher = &s2n_aes128_gcm,
- .hmac_alg = S2N_HMAC_NONE,
- .flags = S2N_TLS12_AES_GCM_AEAD_NONCE,
- .encryption_limit = UINT64_MAX,
-};
-
-const struct s2n_record_algorithm s2n_record_alg_aes256_gcm = {
- .cipher = &s2n_aes256_gcm,
- .hmac_alg = S2N_HMAC_NONE,
- .flags = S2N_TLS12_AES_GCM_AEAD_NONCE,
- .encryption_limit = UINT64_MAX,
-};
-
-const struct s2n_record_algorithm s2n_record_alg_chacha20_poly1305 = {
- .cipher = &s2n_chacha20_poly1305,
- .hmac_alg = S2N_HMAC_NONE,
- /* Per RFC 7905, ChaCha20-Poly1305 will use a nonce construction expected to be used in TLS1.3.
- * Give it a distinct 1.2 nonce value in case this changes.
- */
- .flags = S2N_TLS12_CHACHA_POLY_AEAD_NONCE,
- .encryption_limit = UINT64_MAX,
-};
-
-/* TLS 1.3 Record Algorithms */
-const struct s2n_record_algorithm s2n_tls13_record_alg_aes128_gcm = {
- .cipher = &s2n_tls13_aes128_gcm,
- .hmac_alg = S2N_HMAC_NONE, /* previously used in 1.2 prf, we do not need this */
- .flags = S2N_TLS13_RECORD_AEAD_NONCE,
- .encryption_limit = S2N_TLS13_AES_GCM_MAXIMUM_RECORD_NUMBER,
-};
-
-const struct s2n_record_algorithm s2n_tls13_record_alg_aes256_gcm = {
- .cipher = &s2n_tls13_aes256_gcm,
- .hmac_alg = S2N_HMAC_NONE,
- .flags = S2N_TLS13_RECORD_AEAD_NONCE,
- .encryption_limit = S2N_TLS13_AES_GCM_MAXIMUM_RECORD_NUMBER,
-};
-
-const struct s2n_record_algorithm s2n_tls13_record_alg_chacha20_poly1305 = {
- .cipher = &s2n_chacha20_poly1305,
- .hmac_alg = S2N_HMAC_NONE,
- /* this mirrors s2n_record_alg_chacha20_poly1305 with the exception of TLS 1.3 nonce flag */
- .flags = S2N_TLS13_RECORD_AEAD_NONCE,
- .encryption_limit = UINT64_MAX,
-};
-
-/*********************
- * S2n Cipher Suites *
- *********************/
-
-/* This is the initial cipher suite, but is never negotiated */
-struct s2n_cipher_suite s2n_null_cipher_suite = {
- .available = 1,
- .name = "TLS_NULL_WITH_NULL_NULL",
- .iana_value = { TLS_NULL_WITH_NULL_NULL },
- .key_exchange_alg = &s2n_rsa,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = &s2n_record_alg_null,
-};
-
-struct s2n_cipher_suite s2n_rsa_with_rc4_128_md5 = /* 0x00,0x04 */ {
- .available = 0,
- .name = "RC4-MD5",
- .iana_value = { TLS_RSA_WITH_RC4_128_MD5 },
- .key_exchange_alg = &s2n_rsa,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_rc4_md5 },
- .num_record_algs = 1,
- .sslv3_record_alg = &s2n_record_alg_rc4_sslv3_md5,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_SSLv3,
-};
-
-struct s2n_cipher_suite s2n_rsa_with_rc4_128_sha = /* 0x00,0x05 */ {
- .available = 0,
- .name = "RC4-SHA",
- .iana_value = { TLS_RSA_WITH_RC4_128_SHA },
- .key_exchange_alg = &s2n_rsa,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_rc4_sha },
- .num_record_algs = 1,
- .sslv3_record_alg = &s2n_record_alg_rc4_sslv3_sha,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_SSLv3,
-};
-
-struct s2n_cipher_suite s2n_rsa_with_3des_ede_cbc_sha = /* 0x00,0x0A */ {
- .available = 0,
- .name = "DES-CBC3-SHA",
- .iana_value = { TLS_RSA_WITH_3DES_EDE_CBC_SHA },
- .key_exchange_alg = &s2n_rsa,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_3des_sha },
- .num_record_algs = 1,
- .sslv3_record_alg = &s2n_record_alg_3des_sslv3_sha,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_SSLv3,
-};
-
-struct s2n_cipher_suite s2n_dhe_rsa_with_3des_ede_cbc_sha = /* 0x00,0x16 */ {
- .available = 0,
- .name = "EDH-RSA-DES-CBC3-SHA",
- .iana_value = { TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA },
- .key_exchange_alg = &s2n_dhe,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_3des_sha },
- .num_record_algs = 1,
- .sslv3_record_alg = &s2n_record_alg_3des_sslv3_sha,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_SSLv3,
-};
-
-struct s2n_cipher_suite s2n_rsa_with_aes_128_cbc_sha = /* 0x00,0x2F */ {
- .available = 0,
- .name = "AES128-SHA",
- .iana_value = { TLS_RSA_WITH_AES_128_CBC_SHA },
- .key_exchange_alg = &s2n_rsa,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes128_sha_composite, &s2n_record_alg_aes128_sha },
- .num_record_algs = 2,
- .sslv3_record_alg = &s2n_record_alg_aes128_sslv3_sha,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_SSLv3,
-};
-
-struct s2n_cipher_suite s2n_dhe_rsa_with_aes_128_cbc_sha = /* 0x00,0x33 */ {
- .available = 0,
- .name = "DHE-RSA-AES128-SHA",
- .iana_value = { TLS_DHE_RSA_WITH_AES_128_CBC_SHA },
- .key_exchange_alg = &s2n_dhe,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes128_sha_composite, &s2n_record_alg_aes128_sha },
- .num_record_algs = 2,
- .sslv3_record_alg = &s2n_record_alg_aes128_sslv3_sha,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_SSLv3,
-};
-
-struct s2n_cipher_suite s2n_rsa_with_aes_256_cbc_sha = /* 0x00,0x35 */ {
- .available = 0,
- .name = "AES256-SHA",
- .iana_value = { TLS_RSA_WITH_AES_256_CBC_SHA },
- .key_exchange_alg = &s2n_rsa,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes256_sha_composite, &s2n_record_alg_aes256_sha },
- .num_record_algs = 2,
- .sslv3_record_alg = &s2n_record_alg_aes256_sslv3_sha,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_SSLv3,
-};
-
-struct s2n_cipher_suite s2n_dhe_rsa_with_aes_256_cbc_sha = /* 0x00,0x39 */ {
- .available = 0,
- .name = "DHE-RSA-AES256-SHA",
- .iana_value = { TLS_DHE_RSA_WITH_AES_256_CBC_SHA },
- .key_exchange_alg = &s2n_dhe,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes256_sha_composite, &s2n_record_alg_aes256_sha },
- .num_record_algs = 2,
- .sslv3_record_alg = &s2n_record_alg_aes256_sslv3_sha,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_SSLv3,
-};
-
-struct s2n_cipher_suite s2n_rsa_with_aes_128_cbc_sha256 = /* 0x00,0x3C */ {
- .available = 0,
- .name = "AES128-SHA256",
- .iana_value = { TLS_RSA_WITH_AES_128_CBC_SHA256 },
- .key_exchange_alg = &s2n_rsa,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes128_sha256_composite, &s2n_record_alg_aes128_sha256 },
- .num_record_algs = 2,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-struct s2n_cipher_suite s2n_rsa_with_aes_256_cbc_sha256 = /* 0x00,0x3D */ {
- .available = 0,
- .name = "AES256-SHA256",
- .iana_value = { TLS_RSA_WITH_AES_256_CBC_SHA256 },
- .key_exchange_alg = &s2n_rsa,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes256_sha256_composite, &s2n_record_alg_aes256_sha256 },
- .num_record_algs = 2,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-struct s2n_cipher_suite s2n_dhe_rsa_with_aes_128_cbc_sha256 = /* 0x00,0x67 */ {
- .available = 0,
- .name = "DHE-RSA-AES128-SHA256",
- .iana_value = { TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 },
- .key_exchange_alg = &s2n_dhe,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes128_sha256_composite, &s2n_record_alg_aes128_sha256 },
- .num_record_algs = 2,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-struct s2n_cipher_suite s2n_dhe_rsa_with_aes_256_cbc_sha256 = /* 0x00,0x6B */ {
- .available = 0,
- .name = "DHE-RSA-AES256-SHA256",
- .iana_value = { TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 },
- .key_exchange_alg = &s2n_dhe,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes256_sha256_composite, &s2n_record_alg_aes256_sha256 },
- .num_record_algs = 2,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-struct s2n_cipher_suite s2n_rsa_with_aes_128_gcm_sha256 = /* 0x00,0x9C */ {
- .available = 0,
- .name = "AES128-GCM-SHA256",
- .iana_value = { TLS_RSA_WITH_AES_128_GCM_SHA256 },
- .key_exchange_alg = &s2n_rsa,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes128_gcm },
- .num_record_algs = 1,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-struct s2n_cipher_suite s2n_rsa_with_aes_256_gcm_sha384 = /* 0x00,0x9D */ {
- .available = 0,
- .name = "AES256-GCM-SHA384",
- .iana_value = { TLS_RSA_WITH_AES_256_GCM_SHA384 },
- .key_exchange_alg = &s2n_rsa,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes256_gcm },
- .num_record_algs = 1,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA384,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-struct s2n_cipher_suite s2n_dhe_rsa_with_aes_128_gcm_sha256 = /* 0x00,0x9E */ {
- .available = 0,
- .name = "DHE-RSA-AES128-GCM-SHA256",
- .iana_value = { TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 },
- .key_exchange_alg = &s2n_dhe,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes128_gcm },
- .num_record_algs = 1,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-struct s2n_cipher_suite s2n_dhe_rsa_with_aes_256_gcm_sha384 = /* 0x00,0x9F */ {
- .available = 0,
- .name = "DHE-RSA-AES256-GCM-SHA384",
- .iana_value = { TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 },
- .key_exchange_alg = &s2n_dhe,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes256_gcm },
- .num_record_algs = 1,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA384,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_128_cbc_sha = /* 0xC0,0x09 */ {
- .available = 0,
- .name = "ECDHE-ECDSA-AES128-SHA",
- .iana_value = { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA },
- .key_exchange_alg = &s2n_ecdhe,
- .auth_method = S2N_AUTHENTICATION_ECDSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes128_sha_composite, &s2n_record_alg_aes128_sha },
- .num_record_algs = 2,
- .sslv3_record_alg = &s2n_record_alg_aes128_sslv3_sha,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_SSLv3,
-};
-
-struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_256_cbc_sha = /* 0xC0,0x0A */ {
- .available = 0,
- .name = "ECDHE-ECDSA-AES256-SHA",
- .iana_value = { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA },
- .key_exchange_alg = &s2n_ecdhe,
- .auth_method = S2N_AUTHENTICATION_ECDSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes256_sha_composite, &s2n_record_alg_aes256_sha },
- .num_record_algs = 2,
- .sslv3_record_alg = &s2n_record_alg_aes256_sslv3_sha,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_SSLv3,
-};
-
-struct s2n_cipher_suite s2n_ecdhe_rsa_with_rc4_128_sha = /* 0xC0,0x11 */ {
- .available = 0,
- .name = "ECDHE-RSA-RC4-SHA",
- .iana_value = { TLS_ECDHE_RSA_WITH_RC4_128_SHA },
- .key_exchange_alg = &s2n_ecdhe,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_rc4_sha },
- .num_record_algs = 1,
- .sslv3_record_alg = &s2n_record_alg_rc4_sslv3_sha,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_SSLv3,
-};
-
-struct s2n_cipher_suite s2n_ecdhe_rsa_with_3des_ede_cbc_sha = /* 0xC0,0x12 */ {
- .available = 0,
- .name = "ECDHE-RSA-DES-CBC3-SHA",
- .iana_value = { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA },
- .key_exchange_alg = &s2n_ecdhe,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_3des_sha },
- .num_record_algs = 1,
- .sslv3_record_alg = &s2n_record_alg_3des_sslv3_sha,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_SSLv3,
-};
-
-struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_128_cbc_sha = /* 0xC0,0x13 */ {
- .available = 0,
- .name = "ECDHE-RSA-AES128-SHA",
- .iana_value = { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA },
- .key_exchange_alg = &s2n_ecdhe,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes128_sha_composite, &s2n_record_alg_aes128_sha },
- .num_record_algs = 2,
- .sslv3_record_alg = &s2n_record_alg_aes128_sslv3_sha,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_SSLv3,
-};
-
-struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_256_cbc_sha = /* 0xC0,0x14 */ {
- .available = 0,
- .name = "ECDHE-RSA-AES256-SHA",
- .iana_value = { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA },
- .key_exchange_alg = &s2n_ecdhe,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes256_sha_composite, &s2n_record_alg_aes256_sha },
- .num_record_algs = 2,
- .sslv3_record_alg = &s2n_record_alg_aes256_sslv3_sha,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_SSLv3,
-};
-
-struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256 = /* 0xC0,0x23 */ {
- .available = 0,
- .name = "ECDHE-ECDSA-AES128-SHA256",
- .iana_value = { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 },
- .key_exchange_alg = &s2n_ecdhe,
- .auth_method = S2N_AUTHENTICATION_ECDSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes128_sha256_composite, &s2n_record_alg_aes128_sha256 },
- .num_record_algs = 2,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384 = /* 0xC0,0x24 */ {
- .available = 0,
- .name = "ECDHE-ECDSA-AES256-SHA384",
- .iana_value = { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 },
- .key_exchange_alg = &s2n_ecdhe,
- .auth_method = S2N_AUTHENTICATION_ECDSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes256_sha384 },
- .num_record_algs = 1,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA384,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_128_cbc_sha256 = /* 0xC0,0x27 */ {
- .available = 0,
- .name = "ECDHE-RSA-AES128-SHA256",
- .iana_value = { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 },
- .key_exchange_alg = &s2n_ecdhe,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes128_sha256_composite, &s2n_record_alg_aes128_sha256 },
- .num_record_algs = 2,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_256_cbc_sha384 = /* 0xC0,0x28 */ {
- .available = 0,
- .name = "ECDHE-RSA-AES256-SHA384",
- .iana_value = { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 },
- .key_exchange_alg = &s2n_ecdhe,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes256_sha384 },
- .num_record_algs = 1,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA384,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256 = /* 0xC0,0x2B */ {
- .available = 0,
- .name = "ECDHE-ECDSA-AES128-GCM-SHA256",
- .iana_value = { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 },
- .key_exchange_alg = &s2n_ecdhe,
- .auth_method = S2N_AUTHENTICATION_ECDSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes128_gcm },
- .num_record_algs = 1,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384 = /* 0xC0,0x2C */ {
- .available = 0,
- .name = "ECDHE-ECDSA-AES256-GCM-SHA384",
- .iana_value = { TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 },
- .key_exchange_alg = &s2n_ecdhe,
- .auth_method = S2N_AUTHENTICATION_ECDSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes256_gcm },
- .num_record_algs = 1,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA384,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_128_gcm_sha256 = /* 0xC0,0x2F */ {
- .available = 0,
- .name = "ECDHE-RSA-AES128-GCM-SHA256",
- .iana_value = { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 },
- .key_exchange_alg = &s2n_ecdhe,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes128_gcm },
- .num_record_algs = 1,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_256_gcm_sha384 = /* 0xC0,0x30 */ {
- .available = 0,
- .name = "ECDHE-RSA-AES256-GCM-SHA384",
- .iana_value = { TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 },
- .key_exchange_alg = &s2n_ecdhe,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes256_gcm },
- .num_record_algs = 1,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA384,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-struct s2n_cipher_suite s2n_ecdhe_rsa_with_chacha20_poly1305_sha256 = /* 0xCC,0xA8 */ {
- .available = 0,
- .name = "ECDHE-RSA-CHACHA20-POLY1305",
- .iana_value = { TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 },
- .key_exchange_alg = &s2n_ecdhe,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_chacha20_poly1305 },
- .num_record_algs = 1,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256 = /* 0xCC,0xA9 */ {
- .available = 0,
- .name = "ECDHE-ECDSA-CHACHA20-POLY1305",
- .iana_value = { TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 },
- .key_exchange_alg = &s2n_ecdhe,
- .auth_method = S2N_AUTHENTICATION_ECDSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_chacha20_poly1305 },
- .num_record_algs = 1,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-struct s2n_cipher_suite s2n_dhe_rsa_with_chacha20_poly1305_sha256 = /* 0xCC,0xAA */ {
- .available = 0,
- .name = "DHE-RSA-CHACHA20-POLY1305",
- .iana_value = { TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 },
- .key_exchange_alg = &s2n_dhe,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_chacha20_poly1305 },
- .num_record_algs = 1,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-/* From https://tools.ietf.org/html/draft-campagna-tls-bike-sike-hybrid */
-
-struct s2n_cipher_suite s2n_ecdhe_kyber_rsa_with_aes_256_gcm_sha384 = /* 0xFF, 0x0C */ {
- .available = 0,
- .name = "ECDHE-KYBER-RSA-AES256-GCM-SHA384",
- .iana_value = { TLS_ECDHE_KYBER_RSA_WITH_AES_256_GCM_SHA384 },
- .key_exchange_alg = &s2n_hybrid_ecdhe_kem,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes256_gcm },
- .num_record_algs = 1,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA384,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-struct s2n_cipher_suite s2n_ecdhe_bike_rsa_with_aes_256_gcm_sha384 = /* 0xFF, 0x04 */ {
- .available = 0,
- .name = "ECDHE-BIKE-RSA-AES256-GCM-SHA384",
- .iana_value = { TLS_ECDHE_BIKE_RSA_WITH_AES_256_GCM_SHA384 },
- .key_exchange_alg = &s2n_hybrid_ecdhe_kem,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes256_gcm },
- .num_record_algs = 1,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA384,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-struct s2n_cipher_suite s2n_ecdhe_sike_rsa_with_aes_256_gcm_sha384 = /* 0xFF, 0x08 */ {
- .available = 0,
- .name = "ECDHE-SIKE-RSA-AES256-GCM-SHA384",
- .iana_value = { TLS_ECDHE_SIKE_RSA_WITH_AES_256_GCM_SHA384 },
- .key_exchange_alg = &s2n_hybrid_ecdhe_kem,
- .auth_method = S2N_AUTHENTICATION_RSA,
- .record_alg = NULL,
- .all_record_algs = { &s2n_record_alg_aes256_gcm },
- .num_record_algs = 1,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA384,
- .minimum_required_tls_version = S2N_TLS12,
-};
-
-struct s2n_cipher_suite s2n_tls13_aes_128_gcm_sha256 = {
- .available = 0,
- .name = "TLS_AES_128_GCM_SHA256",
- .iana_value = { TLS_AES_128_GCM_SHA256 },
- .key_exchange_alg = NULL,
- .auth_method = S2N_AUTHENTICATION_METHOD_TLS13,
- .record_alg = NULL,
- .all_record_algs = { &s2n_tls13_record_alg_aes128_gcm },
- .num_record_algs = 1,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_TLS13,
-};
-
-struct s2n_cipher_suite s2n_tls13_aes_256_gcm_sha384 = {
- .available = 0,
- .name = "TLS_AES_256_GCM_SHA384",
- .iana_value = { TLS_AES_256_GCM_SHA384 },
- .key_exchange_alg = NULL,
- .auth_method = S2N_AUTHENTICATION_METHOD_TLS13,
- .record_alg = NULL,
- .all_record_algs = { &s2n_tls13_record_alg_aes256_gcm },
- .num_record_algs = 1,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA384,
- .minimum_required_tls_version = S2N_TLS13,
-};
-
-struct s2n_cipher_suite s2n_tls13_chacha20_poly1305_sha256 = {
- .available = 0,
- .name = "TLS_CHACHA20_POLY1305_SHA256",
- .iana_value = { TLS_CHACHA20_POLY1305_SHA256 },
- .key_exchange_alg = NULL,
- .auth_method = S2N_AUTHENTICATION_METHOD_TLS13,
- .record_alg = NULL,
- .all_record_algs = { &s2n_tls13_record_alg_chacha20_poly1305 },
- .num_record_algs = 1,
- .sslv3_record_alg = NULL,
- .prf_alg = S2N_HMAC_SHA256,
- .minimum_required_tls_version = S2N_TLS13,
-};
-
-/* All of the cipher suites that s2n negotiates in order of IANA value.
- * New cipher suites MUST be added here, IN ORDER, or they will not be
- * properly initialized.
- */
-static struct s2n_cipher_suite *s2n_all_cipher_suites[] = {
- &s2n_rsa_with_rc4_128_md5, /* 0x00,0x04 */
- &s2n_rsa_with_rc4_128_sha, /* 0x00,0x05 */
- &s2n_rsa_with_3des_ede_cbc_sha, /* 0x00,0x0A */
- &s2n_dhe_rsa_with_3des_ede_cbc_sha, /* 0x00,0x16 */
- &s2n_rsa_with_aes_128_cbc_sha, /* 0x00,0x2F */
- &s2n_dhe_rsa_with_aes_128_cbc_sha, /* 0x00,0x33 */
- &s2n_rsa_with_aes_256_cbc_sha, /* 0x00,0x35 */
- &s2n_dhe_rsa_with_aes_256_cbc_sha, /* 0x00,0x39 */
- &s2n_rsa_with_aes_128_cbc_sha256, /* 0x00,0x3C */
- &s2n_rsa_with_aes_256_cbc_sha256, /* 0x00,0x3D */
- &s2n_dhe_rsa_with_aes_128_cbc_sha256, /* 0x00,0x67 */
- &s2n_dhe_rsa_with_aes_256_cbc_sha256, /* 0x00,0x6B */
- &s2n_rsa_with_aes_128_gcm_sha256, /* 0x00,0x9C */
- &s2n_rsa_with_aes_256_gcm_sha384, /* 0x00,0x9D */
- &s2n_dhe_rsa_with_aes_128_gcm_sha256, /* 0x00,0x9E */
- &s2n_dhe_rsa_with_aes_256_gcm_sha384, /* 0x00,0x9F */
-
- &s2n_tls13_aes_128_gcm_sha256, /* 0x13,0x01 */
- &s2n_tls13_aes_256_gcm_sha384, /* 0x13,0x02 */
- &s2n_tls13_chacha20_poly1305_sha256, /* 0x13,0x03 */
-
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha, /* 0xC0,0x09 */
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha, /* 0xC0,0x0A */
- &s2n_ecdhe_rsa_with_rc4_128_sha, /* 0xC0,0x11 */
- &s2n_ecdhe_rsa_with_3des_ede_cbc_sha, /* 0xC0,0x12 */
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha, /* 0xC0,0x13 */
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha, /* 0xC0,0x14 */
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256, /* 0xC0,0x23 */
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384, /* 0xC0,0x24 */
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256, /* 0xC0,0x27 */
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384, /* 0xC0,0x28 */
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256, /* 0xC0,0x2B */
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384, /* 0xC0,0x2C */
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256, /* 0xC0,0x2F */
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384, /* 0xC0,0x30 */
- &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256, /* 0xCC,0xA8 */
- &s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256, /* 0xCC,0xA9 */
- &s2n_dhe_rsa_with_chacha20_poly1305_sha256, /* 0xCC,0xAA */
-#if !defined(S2N_NO_PQ)
- &s2n_ecdhe_bike_rsa_with_aes_256_gcm_sha384, /* 0xFF,0x04 */
- &s2n_ecdhe_sike_rsa_with_aes_256_gcm_sha384, /* 0xFF,0x08 */
- &s2n_ecdhe_kyber_rsa_with_aes_256_gcm_sha384, /* 0xFF,0x0C */
-#endif
-};
-
-/* All supported ciphers. Exposed for integration testing. */
-const struct s2n_cipher_preferences cipher_preferences_test_all = {
- .count = s2n_array_len(s2n_all_cipher_suites),
- .suites = s2n_all_cipher_suites,
-};
-
-/* All TLS12 Cipher Suites */
-
-static struct s2n_cipher_suite *s2n_all_tls12_cipher_suites[] = {
- &s2n_rsa_with_rc4_128_md5, /* 0x00,0x04 */
- &s2n_rsa_with_rc4_128_sha, /* 0x00,0x05 */
- &s2n_rsa_with_3des_ede_cbc_sha, /* 0x00,0x0A */
- &s2n_dhe_rsa_with_3des_ede_cbc_sha, /* 0x00,0x16 */
- &s2n_rsa_with_aes_128_cbc_sha, /* 0x00,0x2F */
- &s2n_dhe_rsa_with_aes_128_cbc_sha, /* 0x00,0x33 */
- &s2n_rsa_with_aes_256_cbc_sha, /* 0x00,0x35 */
- &s2n_dhe_rsa_with_aes_256_cbc_sha, /* 0x00,0x39 */
- &s2n_rsa_with_aes_128_cbc_sha256, /* 0x00,0x3C */
- &s2n_rsa_with_aes_256_cbc_sha256, /* 0x00,0x3D */
- &s2n_dhe_rsa_with_aes_128_cbc_sha256, /* 0x00,0x67 */
- &s2n_dhe_rsa_with_aes_256_cbc_sha256, /* 0x00,0x6B */
- &s2n_rsa_with_aes_128_gcm_sha256, /* 0x00,0x9C */
- &s2n_rsa_with_aes_256_gcm_sha384, /* 0x00,0x9D */
- &s2n_dhe_rsa_with_aes_128_gcm_sha256, /* 0x00,0x9E */
- &s2n_dhe_rsa_with_aes_256_gcm_sha384, /* 0x00,0x9F */
-
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha, /* 0xC0,0x09 */
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha, /* 0xC0,0x0A */
- &s2n_ecdhe_rsa_with_rc4_128_sha, /* 0xC0,0x11 */
- &s2n_ecdhe_rsa_with_3des_ede_cbc_sha, /* 0xC0,0x12 */
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha, /* 0xC0,0x13 */
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha, /* 0xC0,0x14 */
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256, /* 0xC0,0x23 */
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384, /* 0xC0,0x24 */
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256, /* 0xC0,0x27 */
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384, /* 0xC0,0x28 */
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256, /* 0xC0,0x2B */
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384, /* 0xC0,0x2C */
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256, /* 0xC0,0x2F */
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384, /* 0xC0,0x30 */
- &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256, /* 0xCC,0xA8 */
- &s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256, /* 0xCC,0xA9 */
- &s2n_dhe_rsa_with_chacha20_poly1305_sha256, /* 0xCC,0xAA */
-#if !defined(S2N_NO_PQ)
- &s2n_ecdhe_bike_rsa_with_aes_256_gcm_sha384, /* 0xFF,0x04 */
- &s2n_ecdhe_sike_rsa_with_aes_256_gcm_sha384, /* 0xFF,0x08 */
- &s2n_ecdhe_kyber_rsa_with_aes_256_gcm_sha384, /* 0xFF,0x0C */
-#endif
-};
-
-const struct s2n_cipher_preferences cipher_preferences_test_all_tls12 = {
- .count = s2n_array_len(s2n_all_tls12_cipher_suites),
- .suites = s2n_all_tls12_cipher_suites,
-};
-
-/* All of the cipher suites that s2n can negotiate when in FIPS mode,
- * in order of IANA value. Exposed for the "test_all_fips" cipher preference list.
- */
-static struct s2n_cipher_suite *s2n_all_fips_cipher_suites[] = {
- &s2n_rsa_with_3des_ede_cbc_sha, /* 0x00,0x0A */
- &s2n_rsa_with_aes_128_cbc_sha, /* 0x00,0x2F */
- &s2n_rsa_with_aes_256_cbc_sha, /* 0x00,0x35 */
- &s2n_rsa_with_aes_128_cbc_sha256, /* 0x00,0x3C */
- &s2n_rsa_with_aes_256_cbc_sha256, /* 0x00,0x3D */
- &s2n_dhe_rsa_with_aes_128_cbc_sha256, /* 0x00,0x67 */
- &s2n_dhe_rsa_with_aes_256_cbc_sha256, /* 0x00,0x6B */
- &s2n_rsa_with_aes_128_gcm_sha256, /* 0x00,0x9C */
- &s2n_rsa_with_aes_256_gcm_sha384, /* 0x00,0x9D */
- &s2n_dhe_rsa_with_aes_128_gcm_sha256, /* 0x00,0x9E */
- &s2n_dhe_rsa_with_aes_256_gcm_sha384, /* 0x00,0x9F */
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256, /* 0xC0,0x23 */
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384, /* 0xC0,0x24 */
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256, /* 0xC0,0x27 */
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384, /* 0xC0,0x28 */
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256, /* 0xC0,0x2B */
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384, /* 0xC0,0x2C */
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256, /* 0xC0,0x2F */
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384, /* 0xC0,0x30 */
-};
-
-/* All supported FIPS ciphers. Exposed for integration testing. */
-const struct s2n_cipher_preferences cipher_preferences_test_all_fips = {
- .count = s2n_array_len(s2n_all_fips_cipher_suites),
- .suites = s2n_all_fips_cipher_suites,
-};
-
-/* All of the ECDSA cipher suites that s2n can negotiate, in order of IANA
- * value. Exposed for the "test_all_ecdsa" cipher preference list.
- */
-static struct s2n_cipher_suite *s2n_all_ecdsa_cipher_suites[] = {
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha, /* 0xC0,0x09 */
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha, /* 0xC0,0x0A */
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256, /* 0xC0,0x23 */
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384, /* 0xC0,0x24 */
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256, /* 0xC0,0x2B */
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384, /* 0xC0,0x2C */
- &s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256, /* 0xCC,0xA9 */
-};
-
-/* All supported ECDSA cipher suites. Exposed for integration testing. */
-const struct s2n_cipher_preferences cipher_preferences_test_all_ecdsa = {
- .count = s2n_array_len(s2n_all_ecdsa_cipher_suites),
- .suites = s2n_all_ecdsa_cipher_suites,
-};
-
-/* All cipher suites that uses RSA key exchange. Exposed for unit or integration tests. */
-static struct s2n_cipher_suite *s2n_all_rsa_kex_cipher_suites[] = {
- &s2n_rsa_with_aes_128_cbc_sha, /* 0x00,0x2F */
- &s2n_rsa_with_rc4_128_md5, /* 0x00,0x04 */
- &s2n_rsa_with_rc4_128_sha, /* 0x00,0x05 */
- &s2n_rsa_with_3des_ede_cbc_sha, /* 0x00,0x0A */
- &s2n_rsa_with_aes_128_cbc_sha, /* 0x00,0x2F */
- &s2n_rsa_with_aes_256_cbc_sha, /* 0x00,0x35 */
- &s2n_rsa_with_aes_128_cbc_sha256, /* 0x00,0x3C */
- &s2n_rsa_with_aes_256_cbc_sha256, /* 0x00,0x3D */
- &s2n_rsa_with_aes_128_gcm_sha256, /* 0x00,0x9C */
- &s2n_rsa_with_aes_256_gcm_sha384, /* 0x00,0x9D */
-};
-
-/* Cipher preferences with rsa key exchange. Exposed for unit and integration tests. */
-const struct s2n_cipher_preferences cipher_preferences_test_all_rsa_kex = {
- .count = s2n_array_len(s2n_all_rsa_kex_cipher_suites),
- .suites = s2n_all_rsa_kex_cipher_suites,
-};
-
-/* All ECDSA cipher suites first, then the rest of the supported ciphers that s2n can negotiate.
- * Exposed for the "test_ecdsa_priority" cipher preference list.
- */
-static struct s2n_cipher_suite *s2n_ecdsa_priority_cipher_suites[] = {
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha, /* 0xC0,0x09 */
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha, /* 0xC0,0x0A */
- &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256, /* 0xC0,0x23 */
- &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384, /* 0xC0,0x24 */
- &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256, /* 0xC0,0x2B */
- &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384, /* 0xC0,0x2C */
- &s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256, /* 0xCC,0xA9 */
- &s2n_rsa_with_rc4_128_md5, /* 0x00,0x04 */
- &s2n_rsa_with_rc4_128_sha, /* 0x00,0x05 */
- &s2n_rsa_with_3des_ede_cbc_sha, /* 0x00,0x0A */
- &s2n_dhe_rsa_with_3des_ede_cbc_sha, /* 0x00,0x16 */
- &s2n_rsa_with_aes_128_cbc_sha, /* 0x00,0x2F */
- &s2n_dhe_rsa_with_aes_128_cbc_sha, /* 0x00,0x33 */
- &s2n_rsa_with_aes_256_cbc_sha, /* 0x00,0x35 */
- &s2n_dhe_rsa_with_aes_256_cbc_sha, /* 0x00,0x39 */
- &s2n_rsa_with_aes_128_cbc_sha256, /* 0x00,0x3C */
- &s2n_rsa_with_aes_256_cbc_sha256, /* 0x00,0x3D */
- &s2n_dhe_rsa_with_aes_128_cbc_sha256, /* 0x00,0x67 */
- &s2n_dhe_rsa_with_aes_256_cbc_sha256, /* 0x00,0x6B */
- &s2n_rsa_with_aes_128_gcm_sha256, /* 0x00,0x9C */
- &s2n_rsa_with_aes_256_gcm_sha384, /* 0x00,0x9D */
- &s2n_dhe_rsa_with_aes_128_gcm_sha256, /* 0x00,0x9E */
- &s2n_dhe_rsa_with_aes_256_gcm_sha384, /* 0x00,0x9F */
- &s2n_ecdhe_rsa_with_rc4_128_sha, /* 0xC0,0x11 */
- &s2n_ecdhe_rsa_with_3des_ede_cbc_sha, /* 0xC0,0x12 */
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha, /* 0xC0,0x13 */
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha, /* 0xC0,0x14 */
- &s2n_ecdhe_rsa_with_aes_128_cbc_sha256, /* 0xC0,0x27 */
- &s2n_ecdhe_rsa_with_aes_256_cbc_sha384, /* 0xC0,0x28 */
- &s2n_ecdhe_rsa_with_aes_128_gcm_sha256, /* 0xC0,0x2F */
- &s2n_ecdhe_rsa_with_aes_256_gcm_sha384, /* 0xC0,0x30 */
- &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256, /* 0xCC,0xA8 */
- &s2n_dhe_rsa_with_chacha20_poly1305_sha256, /* 0xCC,0xAA */
-};
-
-/* All cipher suites, but with ECDSA priority. Exposed for integration testing. */
-const struct s2n_cipher_preferences cipher_preferences_test_ecdsa_priority = {
- .count = s2n_array_len(s2n_ecdsa_priority_cipher_suites),
- .suites = s2n_ecdsa_priority_cipher_suites,
-};
-
-static struct s2n_cipher_suite *s2n_all_tls13_cipher_suites[] = {
- &s2n_tls13_aes_128_gcm_sha256, /* 0x13,0x01 */
- &s2n_tls13_aes_256_gcm_sha384, /* 0x13,0x02 */
- &s2n_tls13_chacha20_poly1305_sha256, /* 0x13,0x03 */
-};
-
-const struct s2n_cipher_preferences cipher_preferences_test_all_tls13 = {
- .count = s2n_array_len(s2n_all_tls13_cipher_suites),
- .suites = s2n_all_tls13_cipher_suites,
-};
-
-/* Determines cipher suite availability and selects record algorithms */
-int s2n_cipher_suites_init(void)
-{
- const int num_cipher_suites = s2n_array_len(s2n_all_cipher_suites);
- for (int i = 0; i < num_cipher_suites; i++) {
- struct s2n_cipher_suite *cur_suite = s2n_all_cipher_suites[i];
- cur_suite->available = 0;
- cur_suite->record_alg = NULL;
-
- /* Find the highest priority supported record algorithm */
- for (int j = 0; j < cur_suite->num_record_algs; j++) {
- /* Can we use the record algorithm's cipher? Won't be available if the system CPU architecture
- * doesn't support it or if the libcrypto lacks the feature. All hmac_algs are supported.
- */
- if (cur_suite->all_record_algs[j]->cipher->is_available()) {
- /* Found a supported record algorithm. Use it. */
- cur_suite->available = 1;
- cur_suite->record_alg = cur_suite->all_record_algs[j];
- break;
- }
- }
-
- /* Initialize SSLv3 cipher suite if SSLv3 utilizes a different record algorithm */
- if (cur_suite->sslv3_record_alg && cur_suite->sslv3_record_alg->cipher->is_available()) {
- struct s2n_blob cur_suite_mem = { .data = (uint8_t *) cur_suite, .size = sizeof(struct s2n_cipher_suite) };
- struct s2n_blob new_suite_mem = { 0 };
- GUARD(s2n_dup(&cur_suite_mem, &new_suite_mem));
-
- struct s2n_cipher_suite *new_suite = (struct s2n_cipher_suite *)(void *)new_suite_mem.data;
- new_suite->available = 1;
- new_suite->record_alg = cur_suite->sslv3_record_alg;
- cur_suite->sslv3_cipher_suite = new_suite;
- } else {
- cur_suite->sslv3_cipher_suite = cur_suite;
- }
- }
-
-#if !S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0)
- /*https://wiki.openssl.org/index.php/Manual:OpenSSL_add_all_algorithms(3)*/
- OpenSSL_add_all_algorithms();
-#else
- OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS | OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL);
-#endif
-
- return 0;
-}
-
-/* Reset any selected record algorithms */
-int s2n_cipher_suites_cleanup(void)
-{
- const int num_cipher_suites = sizeof(s2n_all_cipher_suites) / sizeof(struct s2n_cipher_suite *);
- for (int i = 0; i < num_cipher_suites; i++) {
- struct s2n_cipher_suite *cur_suite = s2n_all_cipher_suites[i];
- cur_suite->available = 0;
- cur_suite->record_alg = NULL;
-
- /* Release custom SSLv3 cipher suites */
- if (cur_suite->sslv3_cipher_suite != cur_suite) {
- GUARD(s2n_free_object((uint8_t **)&cur_suite->sslv3_cipher_suite, sizeof(struct s2n_cipher_suite)));
- }
- cur_suite->sslv3_cipher_suite = NULL;
- }
-
-#if !S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0)
- /*https://wiki.openssl.org/index.php/Manual:OpenSSL_add_all_algorithms(3)*/
- EVP_cleanup();
-
- /* per the reqs here https://www.openssl.org/docs/man1.1.0/crypto/OPENSSL_init_crypto.html we don't explicitly call
- * cleanup in later versions */
-#endif
-
- return 0;
-}
-
-struct s2n_cipher_suite *s2n_cipher_suite_from_wire(const uint8_t cipher_suite[S2N_TLS_CIPHER_SUITE_LEN])
-{
- int low = 0;
- int top = (sizeof(s2n_all_cipher_suites) / sizeof(struct s2n_cipher_suite *)) - 1;
- /* Perform a textbook binary search */
- while (low <= top) {
- /* Check in the middle */
- int mid = low + ((top - low) / 2);
- int m = memcmp(s2n_all_cipher_suites[mid]->iana_value, cipher_suite, 2);
-
- if (m == 0) {
- return s2n_all_cipher_suites[mid];
- } else if (m > 0) {
- top = mid - 1;
- } else if (m < 0) {
- low = mid + 1;
- }
- }
-
- return NULL;
-}
-
-int s2n_set_cipher_as_client(struct s2n_connection *conn, uint8_t wire[S2N_TLS_CIPHER_SUITE_LEN])
-{
- notnull_check(conn);
- notnull_check(conn->secure.cipher_suite);
- struct s2n_cipher_suite *cipher_suite;
-
- /* See if the cipher is one we support */
- cipher_suite = s2n_cipher_suite_from_wire(wire);
- ENSURE_POSIX(cipher_suite != NULL, S2N_ERR_CIPHER_NOT_SUPPORTED);
-
- /* Verify cipher suite sent in server hello is the same as sent in hello retry */
- if (s2n_is_hello_retry_handshake(conn) && !s2n_is_hello_retry_message(conn)) {
- ENSURE_POSIX(conn->secure.cipher_suite->iana_value == cipher_suite->iana_value, S2N_ERR_CIPHER_NOT_SUPPORTED);
- return S2N_SUCCESS;
- }
- conn->secure.cipher_suite = cipher_suite;
-
- /* Verify the cipher was part of the originally offered list */
- const struct s2n_cipher_preferences *cipher_prefs;
- GUARD(s2n_connection_get_cipher_preferences(conn, &cipher_prefs));
-
- uint8_t found = 0;
-
- for (int i = 0; i < cipher_prefs->count; i++ ) {
- /* The client sends all "available" ciphers in the preference list to the server.
- The server must pick one of the ciphers offered by the client. */
- if (cipher_prefs->suites[i]->available) {
- const uint8_t *server_iana_value = conn->secure.cipher_suite->iana_value;
- const uint8_t *client_iana_value = cipher_prefs->suites[i]->iana_value;
-
- if (memcmp(server_iana_value, client_iana_value, S2N_TLS_CIPHER_SUITE_LEN) == 0) {
- found = 1;
- break;
- }
- }
- }
-
- S2N_ERROR_IF(found != 1, S2N_ERR_CIPHER_NOT_SUPPORTED);
-
- /* For SSLv3 use SSLv3-specific ciphers */
- if (conn->actual_protocol_version == S2N_SSLv3) {
- conn->secure.cipher_suite = conn->secure.cipher_suite->sslv3_cipher_suite;
- notnull_check(conn->secure.cipher_suite);
- }
-
- return 0;
-}
-
-static int s2n_wire_ciphers_contain(const uint8_t *match, const uint8_t *wire, uint32_t count, uint32_t cipher_suite_len)
-{
- for (int i = 0; i < count; i++) {
- const uint8_t *theirs = wire + (i * cipher_suite_len) + (cipher_suite_len - S2N_TLS_CIPHER_SUITE_LEN);
-
- if (!memcmp(match, theirs, S2N_TLS_CIPHER_SUITE_LEN)) {
- return 1;
- }
- }
-
- return 0;
-}
-
-static int s2n_set_cipher_as_server(struct s2n_connection *conn, uint8_t *wire, uint32_t count, uint32_t cipher_suite_len)
-{
- uint8_t renegotiation_info_scsv[S2N_TLS_CIPHER_SUITE_LEN] = { TLS_EMPTY_RENEGOTIATION_INFO_SCSV };
- struct s2n_cipher_suite *higher_vers_match = NULL;
-
- /* RFC 7507 - If client is attempting to negotiate a TLS Version that is lower than the highest supported server
- * version, and the client cipher list contains TLS_FALLBACK_SCSV, then the server must abort the connection since
- * TLS_FALLBACK_SCSV should only be present when the client previously failed to negotiate a higher TLS version.
- */
- if (conn->client_protocol_version < conn->server_protocol_version) {
- uint8_t fallback_scsv[S2N_TLS_CIPHER_SUITE_LEN] = { TLS_FALLBACK_SCSV };
- if (s2n_wire_ciphers_contain(fallback_scsv, wire, count, cipher_suite_len)) {
- conn->closed = 1;
- S2N_ERROR(S2N_ERR_FALLBACK_DETECTED);
- }
- }
-
- /* RFC5746 Section 3.6: A server must check if TLS_EMPTY_RENEGOTIATION_INFO_SCSV is included */
- if (s2n_wire_ciphers_contain(renegotiation_info_scsv, wire, count, cipher_suite_len)) {
- conn->secure_renegotiation = 1;
- }
-
- const struct s2n_security_policy *security_policy;
- GUARD(s2n_connection_get_security_policy(conn, &security_policy));
-
- /* s2n supports only server order */
- for (int i = 0; i < security_policy->cipher_preferences->count; i++) {
- const uint8_t *ours = security_policy->cipher_preferences->suites[i]->iana_value;
-
- if (s2n_wire_ciphers_contain(ours, wire, count, cipher_suite_len)) {
- /* We have a match */
- struct s2n_cipher_suite *match = s2n_cipher_suite_from_wire(ours);
-
- /* Never use TLS1.3 ciphers on a pre-TLS1.3 connection, and vice versa */
- if ((conn->actual_protocol_version >= S2N_TLS13) != (match->minimum_required_tls_version >= S2N_TLS13)) {
- continue;
- }
-
- /* If connection is for SSLv3, use SSLv3 version of suites */
- if (conn->client_protocol_version == S2N_SSLv3) {
- match = match->sslv3_cipher_suite;
- }
-
- /* Skip the suite if we don't have an available implementation */
- if (!match->available) {
- continue;
- }
-
- /* Make sure the cipher is valid for available certs */
- if (s2n_is_cipher_suite_valid_for_auth(conn, match) != S2N_SUCCESS) {
- continue;
- }
-
- /* TLS 1.3 does not include key exchange in cipher suites */
- if (match->minimum_required_tls_version < S2N_TLS13) {
- /* If the kex is not supported continue to the next candidate */
- if (!s2n_kex_supported(match, conn)) {
- continue;
- }
-
- /* If the kex is not configured correctly continue to the next candidate */
- if (s2n_configure_kex(match, conn)) {
- continue;
- }
- }
-
- /* For TLS1.3 when PSKs are present, the server must consider the hash algorithm associated with the chosen PSK
- * when choosing a cipher suite. Server MUST reject any cipher suite without a matching hash algorithm and
- * continue to the next candidate.
- * */
- if (conn->actual_protocol_version >= S2N_TLS13 && conn->psk_params.chosen_psk != NULL) {
- s2n_hmac_algorithm chosen_psk_hmac_alg = { 0 };
- GUARD(s2n_hash_hmac_alg(conn->psk_params.chosen_psk->hash_alg, &chosen_psk_hmac_alg));
- if (match->prf_alg != chosen_psk_hmac_alg) {
- continue;
- }
- }
-
- /* Don't immediately choose a cipher the connection shouldn't be able to support */
- if (conn->actual_protocol_version < match->minimum_required_tls_version) {
- if (!higher_vers_match) {
- higher_vers_match = match;
- }
- continue;
- }
-
- conn->secure.cipher_suite = match;
- return S2N_SUCCESS;
- }
- }
-
- /* Settle for a cipher with a higher required proto version, if it was set */
- if (higher_vers_match) {
- conn->secure.cipher_suite = higher_vers_match;
- return S2N_SUCCESS;
- }
-
- S2N_ERROR(S2N_ERR_CIPHER_NOT_SUPPORTED);
-}
-
-int s2n_set_cipher_as_sslv2_server(struct s2n_connection *conn, uint8_t *wire, uint16_t count)
-{
- return s2n_set_cipher_as_server(conn, wire, count, S2N_SSLv2_CIPHER_SUITE_LEN);
-}
-
-int s2n_set_cipher_as_tls_server(struct s2n_connection *conn, uint8_t *wire, uint16_t count)
-{
- return s2n_set_cipher_as_server(conn, wire, count, S2N_TLS_CIPHER_SUITE_LEN);
-}
+/*
+ * 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 <string.h>
+
+#include <openssl/crypto.h>
+
+#include "error/s2n_errno.h"
+
+#include "crypto/s2n_cipher.h"
+#include "crypto/s2n_openssl.h"
+
+#include "tls/s2n_auth_selection.h"
+#include "tls/s2n_kex.h"
+#include "tls/s2n_security_policies.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls13.h"
+#include "utils/s2n_safety.h"
+#include "tls/s2n_psk.h"
+
+/*************************
+ * S2n Record Algorithms *
+ *************************/
+const struct s2n_record_algorithm s2n_record_alg_null = {
+ .cipher = &s2n_null_cipher,
+ .hmac_alg = S2N_HMAC_NONE,
+ .flags = 0,
+ .encryption_limit = UINT64_MAX,
+};
+
+const struct s2n_record_algorithm s2n_record_alg_rc4_md5 = {
+ .cipher = &s2n_rc4,
+ .hmac_alg = S2N_HMAC_MD5,
+ .flags = 0,
+ .encryption_limit = UINT64_MAX,
+};
+
+const struct s2n_record_algorithm s2n_record_alg_rc4_sslv3_md5 = {
+ .cipher = &s2n_rc4,
+ .hmac_alg = S2N_HMAC_SSLv3_MD5,
+ .flags = 0,
+ .encryption_limit = UINT64_MAX,
+};
+
+const struct s2n_record_algorithm s2n_record_alg_rc4_sha = {
+ .cipher = &s2n_rc4,
+ .hmac_alg = S2N_HMAC_SHA1,
+ .flags = 0,
+ .encryption_limit = UINT64_MAX,
+};
+
+const struct s2n_record_algorithm s2n_record_alg_rc4_sslv3_sha = {
+ .cipher = &s2n_rc4,
+ .hmac_alg = S2N_HMAC_SSLv3_SHA1,
+ .flags = 0,
+ .encryption_limit = UINT64_MAX,
+};
+
+const struct s2n_record_algorithm s2n_record_alg_3des_sha = {
+ .cipher = &s2n_3des,
+ .hmac_alg = S2N_HMAC_SHA1,
+ .flags = 0,
+ .encryption_limit = UINT64_MAX,
+};
+
+const struct s2n_record_algorithm s2n_record_alg_3des_sslv3_sha = {
+ .cipher = &s2n_3des,
+ .hmac_alg = S2N_HMAC_SSLv3_SHA1,
+ .flags = 0,
+ .encryption_limit = UINT64_MAX,
+};
+
+const struct s2n_record_algorithm s2n_record_alg_aes128_sha = {
+ .cipher = &s2n_aes128,
+ .hmac_alg = S2N_HMAC_SHA1,
+ .flags = 0,
+ .encryption_limit = UINT64_MAX,
+};
+
+const struct s2n_record_algorithm s2n_record_alg_aes128_sslv3_sha = {
+ .cipher = &s2n_aes128,
+ .hmac_alg = S2N_HMAC_SSLv3_SHA1,
+ .flags = 0,
+ .encryption_limit = UINT64_MAX,
+};
+
+const struct s2n_record_algorithm s2n_record_alg_aes128_sha_composite = {
+ .cipher = &s2n_aes128_sha,
+ .hmac_alg = S2N_HMAC_NONE,
+ .flags = 0,
+ .encryption_limit = UINT64_MAX,
+};
+
+const struct s2n_record_algorithm s2n_record_alg_aes128_sha256 = {
+ .cipher = &s2n_aes128,
+ .hmac_alg = S2N_HMAC_SHA256,
+ .flags = 0,
+ .encryption_limit = UINT64_MAX,
+};
+
+const struct s2n_record_algorithm s2n_record_alg_aes128_sha256_composite = {
+ .cipher = &s2n_aes128_sha256,
+ .hmac_alg = S2N_HMAC_NONE,
+ .encryption_limit = UINT64_MAX,
+};
+
+const struct s2n_record_algorithm s2n_record_alg_aes256_sha = {
+ .cipher = &s2n_aes256,
+ .hmac_alg = S2N_HMAC_SHA1,
+ .flags = 0,
+ .encryption_limit = UINT64_MAX,
+};
+
+const struct s2n_record_algorithm s2n_record_alg_aes256_sslv3_sha = {
+ .cipher = &s2n_aes256,
+ .hmac_alg = S2N_HMAC_SSLv3_SHA1,
+ .flags = 0,
+ .encryption_limit = UINT64_MAX,
+};
+
+const struct s2n_record_algorithm s2n_record_alg_aes256_sha_composite = {
+ .cipher = &s2n_aes256_sha,
+ .hmac_alg = S2N_HMAC_NONE,
+ .flags = 0,
+ .encryption_limit = UINT64_MAX,
+};
+
+const struct s2n_record_algorithm s2n_record_alg_aes256_sha256 = {
+ .cipher = &s2n_aes256,
+ .hmac_alg = S2N_HMAC_SHA256,
+ .flags = 0,
+ .encryption_limit = UINT64_MAX,
+};
+
+const struct s2n_record_algorithm s2n_record_alg_aes256_sha256_composite = {
+ .cipher = &s2n_aes256_sha256,
+ .hmac_alg = S2N_HMAC_NONE,
+ .encryption_limit = UINT64_MAX,
+};
+
+const struct s2n_record_algorithm s2n_record_alg_aes256_sha384 = {
+ .cipher = &s2n_aes256,
+ .hmac_alg = S2N_HMAC_SHA384,
+ .flags = 0,
+ .encryption_limit = UINT64_MAX,
+};
+
+const struct s2n_record_algorithm s2n_record_alg_aes128_gcm = {
+ .cipher = &s2n_aes128_gcm,
+ .hmac_alg = S2N_HMAC_NONE,
+ .flags = S2N_TLS12_AES_GCM_AEAD_NONCE,
+ .encryption_limit = UINT64_MAX,
+};
+
+const struct s2n_record_algorithm s2n_record_alg_aes256_gcm = {
+ .cipher = &s2n_aes256_gcm,
+ .hmac_alg = S2N_HMAC_NONE,
+ .flags = S2N_TLS12_AES_GCM_AEAD_NONCE,
+ .encryption_limit = UINT64_MAX,
+};
+
+const struct s2n_record_algorithm s2n_record_alg_chacha20_poly1305 = {
+ .cipher = &s2n_chacha20_poly1305,
+ .hmac_alg = S2N_HMAC_NONE,
+ /* Per RFC 7905, ChaCha20-Poly1305 will use a nonce construction expected to be used in TLS1.3.
+ * Give it a distinct 1.2 nonce value in case this changes.
+ */
+ .flags = S2N_TLS12_CHACHA_POLY_AEAD_NONCE,
+ .encryption_limit = UINT64_MAX,
+};
+
+/* TLS 1.3 Record Algorithms */
+const struct s2n_record_algorithm s2n_tls13_record_alg_aes128_gcm = {
+ .cipher = &s2n_tls13_aes128_gcm,
+ .hmac_alg = S2N_HMAC_NONE, /* previously used in 1.2 prf, we do not need this */
+ .flags = S2N_TLS13_RECORD_AEAD_NONCE,
+ .encryption_limit = S2N_TLS13_AES_GCM_MAXIMUM_RECORD_NUMBER,
+};
+
+const struct s2n_record_algorithm s2n_tls13_record_alg_aes256_gcm = {
+ .cipher = &s2n_tls13_aes256_gcm,
+ .hmac_alg = S2N_HMAC_NONE,
+ .flags = S2N_TLS13_RECORD_AEAD_NONCE,
+ .encryption_limit = S2N_TLS13_AES_GCM_MAXIMUM_RECORD_NUMBER,
+};
+
+const struct s2n_record_algorithm s2n_tls13_record_alg_chacha20_poly1305 = {
+ .cipher = &s2n_chacha20_poly1305,
+ .hmac_alg = S2N_HMAC_NONE,
+ /* this mirrors s2n_record_alg_chacha20_poly1305 with the exception of TLS 1.3 nonce flag */
+ .flags = S2N_TLS13_RECORD_AEAD_NONCE,
+ .encryption_limit = UINT64_MAX,
+};
+
+/*********************
+ * S2n Cipher Suites *
+ *********************/
+
+/* This is the initial cipher suite, but is never negotiated */
+struct s2n_cipher_suite s2n_null_cipher_suite = {
+ .available = 1,
+ .name = "TLS_NULL_WITH_NULL_NULL",
+ .iana_value = { TLS_NULL_WITH_NULL_NULL },
+ .key_exchange_alg = &s2n_rsa,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = &s2n_record_alg_null,
+};
+
+struct s2n_cipher_suite s2n_rsa_with_rc4_128_md5 = /* 0x00,0x04 */ {
+ .available = 0,
+ .name = "RC4-MD5",
+ .iana_value = { TLS_RSA_WITH_RC4_128_MD5 },
+ .key_exchange_alg = &s2n_rsa,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_rc4_md5 },
+ .num_record_algs = 1,
+ .sslv3_record_alg = &s2n_record_alg_rc4_sslv3_md5,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_SSLv3,
+};
+
+struct s2n_cipher_suite s2n_rsa_with_rc4_128_sha = /* 0x00,0x05 */ {
+ .available = 0,
+ .name = "RC4-SHA",
+ .iana_value = { TLS_RSA_WITH_RC4_128_SHA },
+ .key_exchange_alg = &s2n_rsa,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_rc4_sha },
+ .num_record_algs = 1,
+ .sslv3_record_alg = &s2n_record_alg_rc4_sslv3_sha,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_SSLv3,
+};
+
+struct s2n_cipher_suite s2n_rsa_with_3des_ede_cbc_sha = /* 0x00,0x0A */ {
+ .available = 0,
+ .name = "DES-CBC3-SHA",
+ .iana_value = { TLS_RSA_WITH_3DES_EDE_CBC_SHA },
+ .key_exchange_alg = &s2n_rsa,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_3des_sha },
+ .num_record_algs = 1,
+ .sslv3_record_alg = &s2n_record_alg_3des_sslv3_sha,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_SSLv3,
+};
+
+struct s2n_cipher_suite s2n_dhe_rsa_with_3des_ede_cbc_sha = /* 0x00,0x16 */ {
+ .available = 0,
+ .name = "EDH-RSA-DES-CBC3-SHA",
+ .iana_value = { TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA },
+ .key_exchange_alg = &s2n_dhe,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_3des_sha },
+ .num_record_algs = 1,
+ .sslv3_record_alg = &s2n_record_alg_3des_sslv3_sha,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_SSLv3,
+};
+
+struct s2n_cipher_suite s2n_rsa_with_aes_128_cbc_sha = /* 0x00,0x2F */ {
+ .available = 0,
+ .name = "AES128-SHA",
+ .iana_value = { TLS_RSA_WITH_AES_128_CBC_SHA },
+ .key_exchange_alg = &s2n_rsa,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes128_sha_composite, &s2n_record_alg_aes128_sha },
+ .num_record_algs = 2,
+ .sslv3_record_alg = &s2n_record_alg_aes128_sslv3_sha,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_SSLv3,
+};
+
+struct s2n_cipher_suite s2n_dhe_rsa_with_aes_128_cbc_sha = /* 0x00,0x33 */ {
+ .available = 0,
+ .name = "DHE-RSA-AES128-SHA",
+ .iana_value = { TLS_DHE_RSA_WITH_AES_128_CBC_SHA },
+ .key_exchange_alg = &s2n_dhe,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes128_sha_composite, &s2n_record_alg_aes128_sha },
+ .num_record_algs = 2,
+ .sslv3_record_alg = &s2n_record_alg_aes128_sslv3_sha,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_SSLv3,
+};
+
+struct s2n_cipher_suite s2n_rsa_with_aes_256_cbc_sha = /* 0x00,0x35 */ {
+ .available = 0,
+ .name = "AES256-SHA",
+ .iana_value = { TLS_RSA_WITH_AES_256_CBC_SHA },
+ .key_exchange_alg = &s2n_rsa,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes256_sha_composite, &s2n_record_alg_aes256_sha },
+ .num_record_algs = 2,
+ .sslv3_record_alg = &s2n_record_alg_aes256_sslv3_sha,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_SSLv3,
+};
+
+struct s2n_cipher_suite s2n_dhe_rsa_with_aes_256_cbc_sha = /* 0x00,0x39 */ {
+ .available = 0,
+ .name = "DHE-RSA-AES256-SHA",
+ .iana_value = { TLS_DHE_RSA_WITH_AES_256_CBC_SHA },
+ .key_exchange_alg = &s2n_dhe,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes256_sha_composite, &s2n_record_alg_aes256_sha },
+ .num_record_algs = 2,
+ .sslv3_record_alg = &s2n_record_alg_aes256_sslv3_sha,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_SSLv3,
+};
+
+struct s2n_cipher_suite s2n_rsa_with_aes_128_cbc_sha256 = /* 0x00,0x3C */ {
+ .available = 0,
+ .name = "AES128-SHA256",
+ .iana_value = { TLS_RSA_WITH_AES_128_CBC_SHA256 },
+ .key_exchange_alg = &s2n_rsa,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes128_sha256_composite, &s2n_record_alg_aes128_sha256 },
+ .num_record_algs = 2,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+struct s2n_cipher_suite s2n_rsa_with_aes_256_cbc_sha256 = /* 0x00,0x3D */ {
+ .available = 0,
+ .name = "AES256-SHA256",
+ .iana_value = { TLS_RSA_WITH_AES_256_CBC_SHA256 },
+ .key_exchange_alg = &s2n_rsa,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes256_sha256_composite, &s2n_record_alg_aes256_sha256 },
+ .num_record_algs = 2,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+struct s2n_cipher_suite s2n_dhe_rsa_with_aes_128_cbc_sha256 = /* 0x00,0x67 */ {
+ .available = 0,
+ .name = "DHE-RSA-AES128-SHA256",
+ .iana_value = { TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 },
+ .key_exchange_alg = &s2n_dhe,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes128_sha256_composite, &s2n_record_alg_aes128_sha256 },
+ .num_record_algs = 2,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+struct s2n_cipher_suite s2n_dhe_rsa_with_aes_256_cbc_sha256 = /* 0x00,0x6B */ {
+ .available = 0,
+ .name = "DHE-RSA-AES256-SHA256",
+ .iana_value = { TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 },
+ .key_exchange_alg = &s2n_dhe,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes256_sha256_composite, &s2n_record_alg_aes256_sha256 },
+ .num_record_algs = 2,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+struct s2n_cipher_suite s2n_rsa_with_aes_128_gcm_sha256 = /* 0x00,0x9C */ {
+ .available = 0,
+ .name = "AES128-GCM-SHA256",
+ .iana_value = { TLS_RSA_WITH_AES_128_GCM_SHA256 },
+ .key_exchange_alg = &s2n_rsa,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes128_gcm },
+ .num_record_algs = 1,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+struct s2n_cipher_suite s2n_rsa_with_aes_256_gcm_sha384 = /* 0x00,0x9D */ {
+ .available = 0,
+ .name = "AES256-GCM-SHA384",
+ .iana_value = { TLS_RSA_WITH_AES_256_GCM_SHA384 },
+ .key_exchange_alg = &s2n_rsa,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes256_gcm },
+ .num_record_algs = 1,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA384,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+struct s2n_cipher_suite s2n_dhe_rsa_with_aes_128_gcm_sha256 = /* 0x00,0x9E */ {
+ .available = 0,
+ .name = "DHE-RSA-AES128-GCM-SHA256",
+ .iana_value = { TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 },
+ .key_exchange_alg = &s2n_dhe,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes128_gcm },
+ .num_record_algs = 1,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+struct s2n_cipher_suite s2n_dhe_rsa_with_aes_256_gcm_sha384 = /* 0x00,0x9F */ {
+ .available = 0,
+ .name = "DHE-RSA-AES256-GCM-SHA384",
+ .iana_value = { TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 },
+ .key_exchange_alg = &s2n_dhe,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes256_gcm },
+ .num_record_algs = 1,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA384,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_128_cbc_sha = /* 0xC0,0x09 */ {
+ .available = 0,
+ .name = "ECDHE-ECDSA-AES128-SHA",
+ .iana_value = { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA },
+ .key_exchange_alg = &s2n_ecdhe,
+ .auth_method = S2N_AUTHENTICATION_ECDSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes128_sha_composite, &s2n_record_alg_aes128_sha },
+ .num_record_algs = 2,
+ .sslv3_record_alg = &s2n_record_alg_aes128_sslv3_sha,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_SSLv3,
+};
+
+struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_256_cbc_sha = /* 0xC0,0x0A */ {
+ .available = 0,
+ .name = "ECDHE-ECDSA-AES256-SHA",
+ .iana_value = { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA },
+ .key_exchange_alg = &s2n_ecdhe,
+ .auth_method = S2N_AUTHENTICATION_ECDSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes256_sha_composite, &s2n_record_alg_aes256_sha },
+ .num_record_algs = 2,
+ .sslv3_record_alg = &s2n_record_alg_aes256_sslv3_sha,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_SSLv3,
+};
+
+struct s2n_cipher_suite s2n_ecdhe_rsa_with_rc4_128_sha = /* 0xC0,0x11 */ {
+ .available = 0,
+ .name = "ECDHE-RSA-RC4-SHA",
+ .iana_value = { TLS_ECDHE_RSA_WITH_RC4_128_SHA },
+ .key_exchange_alg = &s2n_ecdhe,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_rc4_sha },
+ .num_record_algs = 1,
+ .sslv3_record_alg = &s2n_record_alg_rc4_sslv3_sha,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_SSLv3,
+};
+
+struct s2n_cipher_suite s2n_ecdhe_rsa_with_3des_ede_cbc_sha = /* 0xC0,0x12 */ {
+ .available = 0,
+ .name = "ECDHE-RSA-DES-CBC3-SHA",
+ .iana_value = { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA },
+ .key_exchange_alg = &s2n_ecdhe,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_3des_sha },
+ .num_record_algs = 1,
+ .sslv3_record_alg = &s2n_record_alg_3des_sslv3_sha,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_SSLv3,
+};
+
+struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_128_cbc_sha = /* 0xC0,0x13 */ {
+ .available = 0,
+ .name = "ECDHE-RSA-AES128-SHA",
+ .iana_value = { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA },
+ .key_exchange_alg = &s2n_ecdhe,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes128_sha_composite, &s2n_record_alg_aes128_sha },
+ .num_record_algs = 2,
+ .sslv3_record_alg = &s2n_record_alg_aes128_sslv3_sha,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_SSLv3,
+};
+
+struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_256_cbc_sha = /* 0xC0,0x14 */ {
+ .available = 0,
+ .name = "ECDHE-RSA-AES256-SHA",
+ .iana_value = { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA },
+ .key_exchange_alg = &s2n_ecdhe,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes256_sha_composite, &s2n_record_alg_aes256_sha },
+ .num_record_algs = 2,
+ .sslv3_record_alg = &s2n_record_alg_aes256_sslv3_sha,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_SSLv3,
+};
+
+struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256 = /* 0xC0,0x23 */ {
+ .available = 0,
+ .name = "ECDHE-ECDSA-AES128-SHA256",
+ .iana_value = { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 },
+ .key_exchange_alg = &s2n_ecdhe,
+ .auth_method = S2N_AUTHENTICATION_ECDSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes128_sha256_composite, &s2n_record_alg_aes128_sha256 },
+ .num_record_algs = 2,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384 = /* 0xC0,0x24 */ {
+ .available = 0,
+ .name = "ECDHE-ECDSA-AES256-SHA384",
+ .iana_value = { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 },
+ .key_exchange_alg = &s2n_ecdhe,
+ .auth_method = S2N_AUTHENTICATION_ECDSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes256_sha384 },
+ .num_record_algs = 1,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA384,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_128_cbc_sha256 = /* 0xC0,0x27 */ {
+ .available = 0,
+ .name = "ECDHE-RSA-AES128-SHA256",
+ .iana_value = { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 },
+ .key_exchange_alg = &s2n_ecdhe,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes128_sha256_composite, &s2n_record_alg_aes128_sha256 },
+ .num_record_algs = 2,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_256_cbc_sha384 = /* 0xC0,0x28 */ {
+ .available = 0,
+ .name = "ECDHE-RSA-AES256-SHA384",
+ .iana_value = { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 },
+ .key_exchange_alg = &s2n_ecdhe,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes256_sha384 },
+ .num_record_algs = 1,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA384,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256 = /* 0xC0,0x2B */ {
+ .available = 0,
+ .name = "ECDHE-ECDSA-AES128-GCM-SHA256",
+ .iana_value = { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 },
+ .key_exchange_alg = &s2n_ecdhe,
+ .auth_method = S2N_AUTHENTICATION_ECDSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes128_gcm },
+ .num_record_algs = 1,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384 = /* 0xC0,0x2C */ {
+ .available = 0,
+ .name = "ECDHE-ECDSA-AES256-GCM-SHA384",
+ .iana_value = { TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 },
+ .key_exchange_alg = &s2n_ecdhe,
+ .auth_method = S2N_AUTHENTICATION_ECDSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes256_gcm },
+ .num_record_algs = 1,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA384,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_128_gcm_sha256 = /* 0xC0,0x2F */ {
+ .available = 0,
+ .name = "ECDHE-RSA-AES128-GCM-SHA256",
+ .iana_value = { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 },
+ .key_exchange_alg = &s2n_ecdhe,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes128_gcm },
+ .num_record_algs = 1,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_256_gcm_sha384 = /* 0xC0,0x30 */ {
+ .available = 0,
+ .name = "ECDHE-RSA-AES256-GCM-SHA384",
+ .iana_value = { TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 },
+ .key_exchange_alg = &s2n_ecdhe,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes256_gcm },
+ .num_record_algs = 1,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA384,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+struct s2n_cipher_suite s2n_ecdhe_rsa_with_chacha20_poly1305_sha256 = /* 0xCC,0xA8 */ {
+ .available = 0,
+ .name = "ECDHE-RSA-CHACHA20-POLY1305",
+ .iana_value = { TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 },
+ .key_exchange_alg = &s2n_ecdhe,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_chacha20_poly1305 },
+ .num_record_algs = 1,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256 = /* 0xCC,0xA9 */ {
+ .available = 0,
+ .name = "ECDHE-ECDSA-CHACHA20-POLY1305",
+ .iana_value = { TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 },
+ .key_exchange_alg = &s2n_ecdhe,
+ .auth_method = S2N_AUTHENTICATION_ECDSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_chacha20_poly1305 },
+ .num_record_algs = 1,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+struct s2n_cipher_suite s2n_dhe_rsa_with_chacha20_poly1305_sha256 = /* 0xCC,0xAA */ {
+ .available = 0,
+ .name = "DHE-RSA-CHACHA20-POLY1305",
+ .iana_value = { TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 },
+ .key_exchange_alg = &s2n_dhe,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_chacha20_poly1305 },
+ .num_record_algs = 1,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+/* From https://tools.ietf.org/html/draft-campagna-tls-bike-sike-hybrid */
+
+struct s2n_cipher_suite s2n_ecdhe_kyber_rsa_with_aes_256_gcm_sha384 = /* 0xFF, 0x0C */ {
+ .available = 0,
+ .name = "ECDHE-KYBER-RSA-AES256-GCM-SHA384",
+ .iana_value = { TLS_ECDHE_KYBER_RSA_WITH_AES_256_GCM_SHA384 },
+ .key_exchange_alg = &s2n_hybrid_ecdhe_kem,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes256_gcm },
+ .num_record_algs = 1,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA384,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+struct s2n_cipher_suite s2n_ecdhe_bike_rsa_with_aes_256_gcm_sha384 = /* 0xFF, 0x04 */ {
+ .available = 0,
+ .name = "ECDHE-BIKE-RSA-AES256-GCM-SHA384",
+ .iana_value = { TLS_ECDHE_BIKE_RSA_WITH_AES_256_GCM_SHA384 },
+ .key_exchange_alg = &s2n_hybrid_ecdhe_kem,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes256_gcm },
+ .num_record_algs = 1,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA384,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+struct s2n_cipher_suite s2n_ecdhe_sike_rsa_with_aes_256_gcm_sha384 = /* 0xFF, 0x08 */ {
+ .available = 0,
+ .name = "ECDHE-SIKE-RSA-AES256-GCM-SHA384",
+ .iana_value = { TLS_ECDHE_SIKE_RSA_WITH_AES_256_GCM_SHA384 },
+ .key_exchange_alg = &s2n_hybrid_ecdhe_kem,
+ .auth_method = S2N_AUTHENTICATION_RSA,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_record_alg_aes256_gcm },
+ .num_record_algs = 1,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA384,
+ .minimum_required_tls_version = S2N_TLS12,
+};
+
+struct s2n_cipher_suite s2n_tls13_aes_128_gcm_sha256 = {
+ .available = 0,
+ .name = "TLS_AES_128_GCM_SHA256",
+ .iana_value = { TLS_AES_128_GCM_SHA256 },
+ .key_exchange_alg = NULL,
+ .auth_method = S2N_AUTHENTICATION_METHOD_TLS13,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_tls13_record_alg_aes128_gcm },
+ .num_record_algs = 1,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_TLS13,
+};
+
+struct s2n_cipher_suite s2n_tls13_aes_256_gcm_sha384 = {
+ .available = 0,
+ .name = "TLS_AES_256_GCM_SHA384",
+ .iana_value = { TLS_AES_256_GCM_SHA384 },
+ .key_exchange_alg = NULL,
+ .auth_method = S2N_AUTHENTICATION_METHOD_TLS13,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_tls13_record_alg_aes256_gcm },
+ .num_record_algs = 1,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA384,
+ .minimum_required_tls_version = S2N_TLS13,
+};
+
+struct s2n_cipher_suite s2n_tls13_chacha20_poly1305_sha256 = {
+ .available = 0,
+ .name = "TLS_CHACHA20_POLY1305_SHA256",
+ .iana_value = { TLS_CHACHA20_POLY1305_SHA256 },
+ .key_exchange_alg = NULL,
+ .auth_method = S2N_AUTHENTICATION_METHOD_TLS13,
+ .record_alg = NULL,
+ .all_record_algs = { &s2n_tls13_record_alg_chacha20_poly1305 },
+ .num_record_algs = 1,
+ .sslv3_record_alg = NULL,
+ .prf_alg = S2N_HMAC_SHA256,
+ .minimum_required_tls_version = S2N_TLS13,
+};
+
+/* All of the cipher suites that s2n negotiates in order of IANA value.
+ * New cipher suites MUST be added here, IN ORDER, or they will not be
+ * properly initialized.
+ */
+static struct s2n_cipher_suite *s2n_all_cipher_suites[] = {
+ &s2n_rsa_with_rc4_128_md5, /* 0x00,0x04 */
+ &s2n_rsa_with_rc4_128_sha, /* 0x00,0x05 */
+ &s2n_rsa_with_3des_ede_cbc_sha, /* 0x00,0x0A */
+ &s2n_dhe_rsa_with_3des_ede_cbc_sha, /* 0x00,0x16 */
+ &s2n_rsa_with_aes_128_cbc_sha, /* 0x00,0x2F */
+ &s2n_dhe_rsa_with_aes_128_cbc_sha, /* 0x00,0x33 */
+ &s2n_rsa_with_aes_256_cbc_sha, /* 0x00,0x35 */
+ &s2n_dhe_rsa_with_aes_256_cbc_sha, /* 0x00,0x39 */
+ &s2n_rsa_with_aes_128_cbc_sha256, /* 0x00,0x3C */
+ &s2n_rsa_with_aes_256_cbc_sha256, /* 0x00,0x3D */
+ &s2n_dhe_rsa_with_aes_128_cbc_sha256, /* 0x00,0x67 */
+ &s2n_dhe_rsa_with_aes_256_cbc_sha256, /* 0x00,0x6B */
+ &s2n_rsa_with_aes_128_gcm_sha256, /* 0x00,0x9C */
+ &s2n_rsa_with_aes_256_gcm_sha384, /* 0x00,0x9D */
+ &s2n_dhe_rsa_with_aes_128_gcm_sha256, /* 0x00,0x9E */
+ &s2n_dhe_rsa_with_aes_256_gcm_sha384, /* 0x00,0x9F */
+
+ &s2n_tls13_aes_128_gcm_sha256, /* 0x13,0x01 */
+ &s2n_tls13_aes_256_gcm_sha384, /* 0x13,0x02 */
+ &s2n_tls13_chacha20_poly1305_sha256, /* 0x13,0x03 */
+
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha, /* 0xC0,0x09 */
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha, /* 0xC0,0x0A */
+ &s2n_ecdhe_rsa_with_rc4_128_sha, /* 0xC0,0x11 */
+ &s2n_ecdhe_rsa_with_3des_ede_cbc_sha, /* 0xC0,0x12 */
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha, /* 0xC0,0x13 */
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha, /* 0xC0,0x14 */
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256, /* 0xC0,0x23 */
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384, /* 0xC0,0x24 */
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256, /* 0xC0,0x27 */
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384, /* 0xC0,0x28 */
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256, /* 0xC0,0x2B */
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384, /* 0xC0,0x2C */
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256, /* 0xC0,0x2F */
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384, /* 0xC0,0x30 */
+ &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256, /* 0xCC,0xA8 */
+ &s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256, /* 0xCC,0xA9 */
+ &s2n_dhe_rsa_with_chacha20_poly1305_sha256, /* 0xCC,0xAA */
+#if !defined(S2N_NO_PQ)
+ &s2n_ecdhe_bike_rsa_with_aes_256_gcm_sha384, /* 0xFF,0x04 */
+ &s2n_ecdhe_sike_rsa_with_aes_256_gcm_sha384, /* 0xFF,0x08 */
+ &s2n_ecdhe_kyber_rsa_with_aes_256_gcm_sha384, /* 0xFF,0x0C */
+#endif
+};
+
+/* All supported ciphers. Exposed for integration testing. */
+const struct s2n_cipher_preferences cipher_preferences_test_all = {
+ .count = s2n_array_len(s2n_all_cipher_suites),
+ .suites = s2n_all_cipher_suites,
+};
+
+/* All TLS12 Cipher Suites */
+
+static struct s2n_cipher_suite *s2n_all_tls12_cipher_suites[] = {
+ &s2n_rsa_with_rc4_128_md5, /* 0x00,0x04 */
+ &s2n_rsa_with_rc4_128_sha, /* 0x00,0x05 */
+ &s2n_rsa_with_3des_ede_cbc_sha, /* 0x00,0x0A */
+ &s2n_dhe_rsa_with_3des_ede_cbc_sha, /* 0x00,0x16 */
+ &s2n_rsa_with_aes_128_cbc_sha, /* 0x00,0x2F */
+ &s2n_dhe_rsa_with_aes_128_cbc_sha, /* 0x00,0x33 */
+ &s2n_rsa_with_aes_256_cbc_sha, /* 0x00,0x35 */
+ &s2n_dhe_rsa_with_aes_256_cbc_sha, /* 0x00,0x39 */
+ &s2n_rsa_with_aes_128_cbc_sha256, /* 0x00,0x3C */
+ &s2n_rsa_with_aes_256_cbc_sha256, /* 0x00,0x3D */
+ &s2n_dhe_rsa_with_aes_128_cbc_sha256, /* 0x00,0x67 */
+ &s2n_dhe_rsa_with_aes_256_cbc_sha256, /* 0x00,0x6B */
+ &s2n_rsa_with_aes_128_gcm_sha256, /* 0x00,0x9C */
+ &s2n_rsa_with_aes_256_gcm_sha384, /* 0x00,0x9D */
+ &s2n_dhe_rsa_with_aes_128_gcm_sha256, /* 0x00,0x9E */
+ &s2n_dhe_rsa_with_aes_256_gcm_sha384, /* 0x00,0x9F */
+
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha, /* 0xC0,0x09 */
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha, /* 0xC0,0x0A */
+ &s2n_ecdhe_rsa_with_rc4_128_sha, /* 0xC0,0x11 */
+ &s2n_ecdhe_rsa_with_3des_ede_cbc_sha, /* 0xC0,0x12 */
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha, /* 0xC0,0x13 */
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha, /* 0xC0,0x14 */
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256, /* 0xC0,0x23 */
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384, /* 0xC0,0x24 */
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256, /* 0xC0,0x27 */
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384, /* 0xC0,0x28 */
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256, /* 0xC0,0x2B */
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384, /* 0xC0,0x2C */
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256, /* 0xC0,0x2F */
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384, /* 0xC0,0x30 */
+ &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256, /* 0xCC,0xA8 */
+ &s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256, /* 0xCC,0xA9 */
+ &s2n_dhe_rsa_with_chacha20_poly1305_sha256, /* 0xCC,0xAA */
+#if !defined(S2N_NO_PQ)
+ &s2n_ecdhe_bike_rsa_with_aes_256_gcm_sha384, /* 0xFF,0x04 */
+ &s2n_ecdhe_sike_rsa_with_aes_256_gcm_sha384, /* 0xFF,0x08 */
+ &s2n_ecdhe_kyber_rsa_with_aes_256_gcm_sha384, /* 0xFF,0x0C */
+#endif
+};
+
+const struct s2n_cipher_preferences cipher_preferences_test_all_tls12 = {
+ .count = s2n_array_len(s2n_all_tls12_cipher_suites),
+ .suites = s2n_all_tls12_cipher_suites,
+};
+
+/* All of the cipher suites that s2n can negotiate when in FIPS mode,
+ * in order of IANA value. Exposed for the "test_all_fips" cipher preference list.
+ */
+static struct s2n_cipher_suite *s2n_all_fips_cipher_suites[] = {
+ &s2n_rsa_with_3des_ede_cbc_sha, /* 0x00,0x0A */
+ &s2n_rsa_with_aes_128_cbc_sha, /* 0x00,0x2F */
+ &s2n_rsa_with_aes_256_cbc_sha, /* 0x00,0x35 */
+ &s2n_rsa_with_aes_128_cbc_sha256, /* 0x00,0x3C */
+ &s2n_rsa_with_aes_256_cbc_sha256, /* 0x00,0x3D */
+ &s2n_dhe_rsa_with_aes_128_cbc_sha256, /* 0x00,0x67 */
+ &s2n_dhe_rsa_with_aes_256_cbc_sha256, /* 0x00,0x6B */
+ &s2n_rsa_with_aes_128_gcm_sha256, /* 0x00,0x9C */
+ &s2n_rsa_with_aes_256_gcm_sha384, /* 0x00,0x9D */
+ &s2n_dhe_rsa_with_aes_128_gcm_sha256, /* 0x00,0x9E */
+ &s2n_dhe_rsa_with_aes_256_gcm_sha384, /* 0x00,0x9F */
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256, /* 0xC0,0x23 */
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384, /* 0xC0,0x24 */
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256, /* 0xC0,0x27 */
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384, /* 0xC0,0x28 */
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256, /* 0xC0,0x2B */
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384, /* 0xC0,0x2C */
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256, /* 0xC0,0x2F */
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384, /* 0xC0,0x30 */
+};
+
+/* All supported FIPS ciphers. Exposed for integration testing. */
+const struct s2n_cipher_preferences cipher_preferences_test_all_fips = {
+ .count = s2n_array_len(s2n_all_fips_cipher_suites),
+ .suites = s2n_all_fips_cipher_suites,
+};
+
+/* All of the ECDSA cipher suites that s2n can negotiate, in order of IANA
+ * value. Exposed for the "test_all_ecdsa" cipher preference list.
+ */
+static struct s2n_cipher_suite *s2n_all_ecdsa_cipher_suites[] = {
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha, /* 0xC0,0x09 */
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha, /* 0xC0,0x0A */
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256, /* 0xC0,0x23 */
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384, /* 0xC0,0x24 */
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256, /* 0xC0,0x2B */
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384, /* 0xC0,0x2C */
+ &s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256, /* 0xCC,0xA9 */
+};
+
+/* All supported ECDSA cipher suites. Exposed for integration testing. */
+const struct s2n_cipher_preferences cipher_preferences_test_all_ecdsa = {
+ .count = s2n_array_len(s2n_all_ecdsa_cipher_suites),
+ .suites = s2n_all_ecdsa_cipher_suites,
+};
+
+/* All cipher suites that uses RSA key exchange. Exposed for unit or integration tests. */
+static struct s2n_cipher_suite *s2n_all_rsa_kex_cipher_suites[] = {
+ &s2n_rsa_with_aes_128_cbc_sha, /* 0x00,0x2F */
+ &s2n_rsa_with_rc4_128_md5, /* 0x00,0x04 */
+ &s2n_rsa_with_rc4_128_sha, /* 0x00,0x05 */
+ &s2n_rsa_with_3des_ede_cbc_sha, /* 0x00,0x0A */
+ &s2n_rsa_with_aes_128_cbc_sha, /* 0x00,0x2F */
+ &s2n_rsa_with_aes_256_cbc_sha, /* 0x00,0x35 */
+ &s2n_rsa_with_aes_128_cbc_sha256, /* 0x00,0x3C */
+ &s2n_rsa_with_aes_256_cbc_sha256, /* 0x00,0x3D */
+ &s2n_rsa_with_aes_128_gcm_sha256, /* 0x00,0x9C */
+ &s2n_rsa_with_aes_256_gcm_sha384, /* 0x00,0x9D */
+};
+
+/* Cipher preferences with rsa key exchange. Exposed for unit and integration tests. */
+const struct s2n_cipher_preferences cipher_preferences_test_all_rsa_kex = {
+ .count = s2n_array_len(s2n_all_rsa_kex_cipher_suites),
+ .suites = s2n_all_rsa_kex_cipher_suites,
+};
+
+/* All ECDSA cipher suites first, then the rest of the supported ciphers that s2n can negotiate.
+ * Exposed for the "test_ecdsa_priority" cipher preference list.
+ */
+static struct s2n_cipher_suite *s2n_ecdsa_priority_cipher_suites[] = {
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha, /* 0xC0,0x09 */
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha, /* 0xC0,0x0A */
+ &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256, /* 0xC0,0x23 */
+ &s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384, /* 0xC0,0x24 */
+ &s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256, /* 0xC0,0x2B */
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384, /* 0xC0,0x2C */
+ &s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256, /* 0xCC,0xA9 */
+ &s2n_rsa_with_rc4_128_md5, /* 0x00,0x04 */
+ &s2n_rsa_with_rc4_128_sha, /* 0x00,0x05 */
+ &s2n_rsa_with_3des_ede_cbc_sha, /* 0x00,0x0A */
+ &s2n_dhe_rsa_with_3des_ede_cbc_sha, /* 0x00,0x16 */
+ &s2n_rsa_with_aes_128_cbc_sha, /* 0x00,0x2F */
+ &s2n_dhe_rsa_with_aes_128_cbc_sha, /* 0x00,0x33 */
+ &s2n_rsa_with_aes_256_cbc_sha, /* 0x00,0x35 */
+ &s2n_dhe_rsa_with_aes_256_cbc_sha, /* 0x00,0x39 */
+ &s2n_rsa_with_aes_128_cbc_sha256, /* 0x00,0x3C */
+ &s2n_rsa_with_aes_256_cbc_sha256, /* 0x00,0x3D */
+ &s2n_dhe_rsa_with_aes_128_cbc_sha256, /* 0x00,0x67 */
+ &s2n_dhe_rsa_with_aes_256_cbc_sha256, /* 0x00,0x6B */
+ &s2n_rsa_with_aes_128_gcm_sha256, /* 0x00,0x9C */
+ &s2n_rsa_with_aes_256_gcm_sha384, /* 0x00,0x9D */
+ &s2n_dhe_rsa_with_aes_128_gcm_sha256, /* 0x00,0x9E */
+ &s2n_dhe_rsa_with_aes_256_gcm_sha384, /* 0x00,0x9F */
+ &s2n_ecdhe_rsa_with_rc4_128_sha, /* 0xC0,0x11 */
+ &s2n_ecdhe_rsa_with_3des_ede_cbc_sha, /* 0xC0,0x12 */
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha, /* 0xC0,0x13 */
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha, /* 0xC0,0x14 */
+ &s2n_ecdhe_rsa_with_aes_128_cbc_sha256, /* 0xC0,0x27 */
+ &s2n_ecdhe_rsa_with_aes_256_cbc_sha384, /* 0xC0,0x28 */
+ &s2n_ecdhe_rsa_with_aes_128_gcm_sha256, /* 0xC0,0x2F */
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384, /* 0xC0,0x30 */
+ &s2n_ecdhe_rsa_with_chacha20_poly1305_sha256, /* 0xCC,0xA8 */
+ &s2n_dhe_rsa_with_chacha20_poly1305_sha256, /* 0xCC,0xAA */
+};
+
+/* All cipher suites, but with ECDSA priority. Exposed for integration testing. */
+const struct s2n_cipher_preferences cipher_preferences_test_ecdsa_priority = {
+ .count = s2n_array_len(s2n_ecdsa_priority_cipher_suites),
+ .suites = s2n_ecdsa_priority_cipher_suites,
+};
+
+static struct s2n_cipher_suite *s2n_all_tls13_cipher_suites[] = {
+ &s2n_tls13_aes_128_gcm_sha256, /* 0x13,0x01 */
+ &s2n_tls13_aes_256_gcm_sha384, /* 0x13,0x02 */
+ &s2n_tls13_chacha20_poly1305_sha256, /* 0x13,0x03 */
+};
+
+const struct s2n_cipher_preferences cipher_preferences_test_all_tls13 = {
+ .count = s2n_array_len(s2n_all_tls13_cipher_suites),
+ .suites = s2n_all_tls13_cipher_suites,
+};
+
+/* Determines cipher suite availability and selects record algorithms */
+int s2n_cipher_suites_init(void)
+{
+ const int num_cipher_suites = s2n_array_len(s2n_all_cipher_suites);
+ for (int i = 0; i < num_cipher_suites; i++) {
+ struct s2n_cipher_suite *cur_suite = s2n_all_cipher_suites[i];
+ cur_suite->available = 0;
+ cur_suite->record_alg = NULL;
+
+ /* Find the highest priority supported record algorithm */
+ for (int j = 0; j < cur_suite->num_record_algs; j++) {
+ /* Can we use the record algorithm's cipher? Won't be available if the system CPU architecture
+ * doesn't support it or if the libcrypto lacks the feature. All hmac_algs are supported.
+ */
+ if (cur_suite->all_record_algs[j]->cipher->is_available()) {
+ /* Found a supported record algorithm. Use it. */
+ cur_suite->available = 1;
+ cur_suite->record_alg = cur_suite->all_record_algs[j];
+ break;
+ }
+ }
+
+ /* Initialize SSLv3 cipher suite if SSLv3 utilizes a different record algorithm */
+ if (cur_suite->sslv3_record_alg && cur_suite->sslv3_record_alg->cipher->is_available()) {
+ struct s2n_blob cur_suite_mem = { .data = (uint8_t *) cur_suite, .size = sizeof(struct s2n_cipher_suite) };
+ struct s2n_blob new_suite_mem = { 0 };
+ GUARD(s2n_dup(&cur_suite_mem, &new_suite_mem));
+
+ struct s2n_cipher_suite *new_suite = (struct s2n_cipher_suite *)(void *)new_suite_mem.data;
+ new_suite->available = 1;
+ new_suite->record_alg = cur_suite->sslv3_record_alg;
+ cur_suite->sslv3_cipher_suite = new_suite;
+ } else {
+ cur_suite->sslv3_cipher_suite = cur_suite;
+ }
+ }
+
+#if !S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0)
+ /*https://wiki.openssl.org/index.php/Manual:OpenSSL_add_all_algorithms(3)*/
+ OpenSSL_add_all_algorithms();
+#else
+ OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS | OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL);
+#endif
+
+ return 0;
+}
+
+/* Reset any selected record algorithms */
+int s2n_cipher_suites_cleanup(void)
+{
+ const int num_cipher_suites = sizeof(s2n_all_cipher_suites) / sizeof(struct s2n_cipher_suite *);
+ for (int i = 0; i < num_cipher_suites; i++) {
+ struct s2n_cipher_suite *cur_suite = s2n_all_cipher_suites[i];
+ cur_suite->available = 0;
+ cur_suite->record_alg = NULL;
+
+ /* Release custom SSLv3 cipher suites */
+ if (cur_suite->sslv3_cipher_suite != cur_suite) {
+ GUARD(s2n_free_object((uint8_t **)&cur_suite->sslv3_cipher_suite, sizeof(struct s2n_cipher_suite)));
+ }
+ cur_suite->sslv3_cipher_suite = NULL;
+ }
+
+#if !S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0)
+ /*https://wiki.openssl.org/index.php/Manual:OpenSSL_add_all_algorithms(3)*/
+ EVP_cleanup();
+
+ /* per the reqs here https://www.openssl.org/docs/man1.1.0/crypto/OPENSSL_init_crypto.html we don't explicitly call
+ * cleanup in later versions */
+#endif
+
+ return 0;
+}
+
+struct s2n_cipher_suite *s2n_cipher_suite_from_wire(const uint8_t cipher_suite[S2N_TLS_CIPHER_SUITE_LEN])
+{
+ int low = 0;
+ int top = (sizeof(s2n_all_cipher_suites) / sizeof(struct s2n_cipher_suite *)) - 1;
+ /* Perform a textbook binary search */
+ while (low <= top) {
+ /* Check in the middle */
+ int mid = low + ((top - low) / 2);
+ int m = memcmp(s2n_all_cipher_suites[mid]->iana_value, cipher_suite, 2);
+
+ if (m == 0) {
+ return s2n_all_cipher_suites[mid];
+ } else if (m > 0) {
+ top = mid - 1;
+ } else if (m < 0) {
+ low = mid + 1;
+ }
+ }
+
+ return NULL;
+}
+
+int s2n_set_cipher_as_client(struct s2n_connection *conn, uint8_t wire[S2N_TLS_CIPHER_SUITE_LEN])
+{
+ notnull_check(conn);
+ notnull_check(conn->secure.cipher_suite);
+ struct s2n_cipher_suite *cipher_suite;
+
+ /* See if the cipher is one we support */
+ cipher_suite = s2n_cipher_suite_from_wire(wire);
+ ENSURE_POSIX(cipher_suite != NULL, S2N_ERR_CIPHER_NOT_SUPPORTED);
+
+ /* Verify cipher suite sent in server hello is the same as sent in hello retry */
+ if (s2n_is_hello_retry_handshake(conn) && !s2n_is_hello_retry_message(conn)) {
+ ENSURE_POSIX(conn->secure.cipher_suite->iana_value == cipher_suite->iana_value, S2N_ERR_CIPHER_NOT_SUPPORTED);
+ return S2N_SUCCESS;
+ }
+ conn->secure.cipher_suite = cipher_suite;
+
+ /* Verify the cipher was part of the originally offered list */
+ const struct s2n_cipher_preferences *cipher_prefs;
+ GUARD(s2n_connection_get_cipher_preferences(conn, &cipher_prefs));
+
+ uint8_t found = 0;
+
+ for (int i = 0; i < cipher_prefs->count; i++ ) {
+ /* The client sends all "available" ciphers in the preference list to the server.
+ The server must pick one of the ciphers offered by the client. */
+ if (cipher_prefs->suites[i]->available) {
+ const uint8_t *server_iana_value = conn->secure.cipher_suite->iana_value;
+ const uint8_t *client_iana_value = cipher_prefs->suites[i]->iana_value;
+
+ if (memcmp(server_iana_value, client_iana_value, S2N_TLS_CIPHER_SUITE_LEN) == 0) {
+ found = 1;
+ break;
+ }
+ }
+ }
+
+ S2N_ERROR_IF(found != 1, S2N_ERR_CIPHER_NOT_SUPPORTED);
+
+ /* For SSLv3 use SSLv3-specific ciphers */
+ if (conn->actual_protocol_version == S2N_SSLv3) {
+ conn->secure.cipher_suite = conn->secure.cipher_suite->sslv3_cipher_suite;
+ notnull_check(conn->secure.cipher_suite);
+ }
+
+ return 0;
+}
+
+static int s2n_wire_ciphers_contain(const uint8_t *match, const uint8_t *wire, uint32_t count, uint32_t cipher_suite_len)
+{
+ for (int i = 0; i < count; i++) {
+ const uint8_t *theirs = wire + (i * cipher_suite_len) + (cipher_suite_len - S2N_TLS_CIPHER_SUITE_LEN);
+
+ if (!memcmp(match, theirs, S2N_TLS_CIPHER_SUITE_LEN)) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int s2n_set_cipher_as_server(struct s2n_connection *conn, uint8_t *wire, uint32_t count, uint32_t cipher_suite_len)
+{
+ uint8_t renegotiation_info_scsv[S2N_TLS_CIPHER_SUITE_LEN] = { TLS_EMPTY_RENEGOTIATION_INFO_SCSV };
+ struct s2n_cipher_suite *higher_vers_match = NULL;
+
+ /* RFC 7507 - If client is attempting to negotiate a TLS Version that is lower than the highest supported server
+ * version, and the client cipher list contains TLS_FALLBACK_SCSV, then the server must abort the connection since
+ * TLS_FALLBACK_SCSV should only be present when the client previously failed to negotiate a higher TLS version.
+ */
+ if (conn->client_protocol_version < conn->server_protocol_version) {
+ uint8_t fallback_scsv[S2N_TLS_CIPHER_SUITE_LEN] = { TLS_FALLBACK_SCSV };
+ if (s2n_wire_ciphers_contain(fallback_scsv, wire, count, cipher_suite_len)) {
+ conn->closed = 1;
+ S2N_ERROR(S2N_ERR_FALLBACK_DETECTED);
+ }
+ }
+
+ /* RFC5746 Section 3.6: A server must check if TLS_EMPTY_RENEGOTIATION_INFO_SCSV is included */
+ if (s2n_wire_ciphers_contain(renegotiation_info_scsv, wire, count, cipher_suite_len)) {
+ conn->secure_renegotiation = 1;
+ }
+
+ const struct s2n_security_policy *security_policy;
+ GUARD(s2n_connection_get_security_policy(conn, &security_policy));
+
+ /* s2n supports only server order */
+ for (int i = 0; i < security_policy->cipher_preferences->count; i++) {
+ const uint8_t *ours = security_policy->cipher_preferences->suites[i]->iana_value;
+
+ if (s2n_wire_ciphers_contain(ours, wire, count, cipher_suite_len)) {
+ /* We have a match */
+ struct s2n_cipher_suite *match = s2n_cipher_suite_from_wire(ours);
+
+ /* Never use TLS1.3 ciphers on a pre-TLS1.3 connection, and vice versa */
+ if ((conn->actual_protocol_version >= S2N_TLS13) != (match->minimum_required_tls_version >= S2N_TLS13)) {
+ continue;
+ }
+
+ /* If connection is for SSLv3, use SSLv3 version of suites */
+ if (conn->client_protocol_version == S2N_SSLv3) {
+ match = match->sslv3_cipher_suite;
+ }
+
+ /* Skip the suite if we don't have an available implementation */
+ if (!match->available) {
+ continue;
+ }
+
+ /* Make sure the cipher is valid for available certs */
+ if (s2n_is_cipher_suite_valid_for_auth(conn, match) != S2N_SUCCESS) {
+ continue;
+ }
+
+ /* TLS 1.3 does not include key exchange in cipher suites */
+ if (match->minimum_required_tls_version < S2N_TLS13) {
+ /* If the kex is not supported continue to the next candidate */
+ if (!s2n_kex_supported(match, conn)) {
+ continue;
+ }
+
+ /* If the kex is not configured correctly continue to the next candidate */
+ if (s2n_configure_kex(match, conn)) {
+ continue;
+ }
+ }
+
+ /* For TLS1.3 when PSKs are present, the server must consider the hash algorithm associated with the chosen PSK
+ * when choosing a cipher suite. Server MUST reject any cipher suite without a matching hash algorithm and
+ * continue to the next candidate.
+ * */
+ if (conn->actual_protocol_version >= S2N_TLS13 && conn->psk_params.chosen_psk != NULL) {
+ s2n_hmac_algorithm chosen_psk_hmac_alg = { 0 };
+ GUARD(s2n_hash_hmac_alg(conn->psk_params.chosen_psk->hash_alg, &chosen_psk_hmac_alg));
+ if (match->prf_alg != chosen_psk_hmac_alg) {
+ continue;
+ }
+ }
+
+ /* Don't immediately choose a cipher the connection shouldn't be able to support */
+ if (conn->actual_protocol_version < match->minimum_required_tls_version) {
+ if (!higher_vers_match) {
+ higher_vers_match = match;
+ }
+ continue;
+ }
+
+ conn->secure.cipher_suite = match;
+ return S2N_SUCCESS;
+ }
+ }
+
+ /* Settle for a cipher with a higher required proto version, if it was set */
+ if (higher_vers_match) {
+ conn->secure.cipher_suite = higher_vers_match;
+ return S2N_SUCCESS;
+ }
+
+ S2N_ERROR(S2N_ERR_CIPHER_NOT_SUPPORTED);
+}
+
+int s2n_set_cipher_as_sslv2_server(struct s2n_connection *conn, uint8_t *wire, uint16_t count)
+{
+ return s2n_set_cipher_as_server(conn, wire, count, S2N_SSLv2_CIPHER_SUITE_LEN);
+}
+
+int s2n_set_cipher_as_tls_server(struct s2n_connection *conn, uint8_t *wire, uint16_t count)
+{
+ return s2n_set_cipher_as_server(conn, wire, count, S2N_TLS_CIPHER_SUITE_LEN);
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.h b/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.h
index 2bd9bf0358..009f13471b 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.h
@@ -1,172 +1,172 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/s2n_tls_parameters.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_crypto.h"
-
-#include "crypto/s2n_certificate.h"
-#include "crypto/s2n_cipher.h"
-#include "crypto/s2n_hmac.h"
-
-#include <stdint.h>
-
-/* Key exchange flags that can be OR'ed */
-#define S2N_KEY_EXCHANGE_DH 0x01 /* Diffie-Hellman key exchange, including ephemeral */
-#define S2N_KEY_EXCHANGE_EPH 0x02 /* Ephemeral key exchange */
-#define S2N_KEY_EXCHANGE_ECC 0x04 /* Elliptic curve cryptography */
-
-#define S2N_MAX_POSSIBLE_RECORD_ALGS 2
-#if !defined(S2N_NO_PQ)
-#define S2N_PQ_CIPHER_SUITE_COUNT 3
-#else
-#define S2N_PQ_CIPHER_SUITE_COUNT 0
-#endif
-
-/* Kept up-to-date by s2n_cipher_suite_match_test */
-#define S2N_CIPHER_SUITE_COUNT (36 + S2N_PQ_CIPHER_SUITE_COUNT)
-
-
-/* Record algorithm flags that can be OR'ed */
-#define S2N_TLS12_AES_GCM_AEAD_NONCE 0x01
-#define S2N_TLS12_CHACHA_POLY_AEAD_NONCE 0x02
-#define S2N_TLS13_RECORD_AEAD_NONCE 0x04
-
-/* From RFC: https://tools.ietf.org/html/rfc8446#section-5.5
- * For AES-GCM, up to 2^24.5 full-size records (about 24 million) may be
- * encrypted on a given connection while keeping a safety margin of
- * approximately 2^-57 for Authenticated Encryption (AE) security.
- * S2N_TLS13_MAXIMUM_RECORD_NUMBER is 2^24.5 rounded down to the nearest whole number
- * minus 1 for the key update message.
- */
-#define S2N_TLS13_AES_GCM_MAXIMUM_RECORD_NUMBER ((uint64_t) 23726565)
-
-typedef enum {
- S2N_AUTHENTICATION_RSA = 0,
- S2N_AUTHENTICATION_ECDSA,
- S2N_AUTHENTICATION_METHOD_SENTINEL
-} s2n_authentication_method;
-
-/* Used by TLS 1.3 CipherSuites (Eg TLS_AES_128_GCM_SHA256 "0x1301") where the Auth method will be specified by the
- * SignatureScheme Extension, not the CipherSuite. */
-#define S2N_AUTHENTICATION_METHOD_TLS13 S2N_AUTHENTICATION_METHOD_SENTINEL
-
-struct s2n_record_algorithm {
- const struct s2n_cipher *cipher;
- s2n_hmac_algorithm hmac_alg;
- uint32_t flags;
- uint64_t encryption_limit;
-};
-
-/* Verbose names to avoid confusion with s2n_cipher. Exposed for unit tests */
-extern const struct s2n_record_algorithm s2n_record_alg_null;
-extern const struct s2n_record_algorithm s2n_record_alg_rc4_md5;
-extern const struct s2n_record_algorithm s2n_record_alg_rc4_sha;
-extern const struct s2n_record_algorithm s2n_record_alg_3des_sha;
-extern const struct s2n_record_algorithm s2n_record_alg_aes128_sha;
-extern const struct s2n_record_algorithm s2n_record_alg_aes128_sha_composite;
-extern const struct s2n_record_algorithm s2n_record_alg_aes128_sha256;
-extern const struct s2n_record_algorithm s2n_record_alg_aes128_sha256_composite;
-extern const struct s2n_record_algorithm s2n_record_alg_aes256_sha;
-extern const struct s2n_record_algorithm s2n_record_alg_aes256_sha_composite;
-extern const struct s2n_record_algorithm s2n_record_alg_aes256_sha256;
-extern const struct s2n_record_algorithm s2n_record_alg_aes256_sha256_composite;
-extern const struct s2n_record_algorithm s2n_record_alg_aes256_sha384;
-extern const struct s2n_record_algorithm s2n_record_alg_aes128_gcm;
-extern const struct s2n_record_algorithm s2n_record_alg_aes256_gcm;
-extern const struct s2n_record_algorithm s2n_record_alg_chacha20_poly1305;
-
-struct s2n_cipher_suite {
- /* Is there an implementation available? Set in s2n_cipher_suites_init() */
- unsigned int available:1;
-
- /* Cipher name in Openssl format */
- const char *name;
- const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN];
-
- const struct s2n_kex *key_exchange_alg;
-
- const s2n_authentication_method auth_method;
-
- /* Algorithms used for per-record security. Set in s2n_cipher_suites_init() */
- const struct s2n_record_algorithm *record_alg;
-
- /* List of all possible record alg implementations in descending priority */
- const struct s2n_record_algorithm *all_record_algs[S2N_MAX_POSSIBLE_RECORD_ALGS];
- const uint8_t num_record_algs;
-
- /* SSLv3 utilizes HMAC differently from TLS */
- const struct s2n_record_algorithm *sslv3_record_alg;
- struct s2n_cipher_suite *sslv3_cipher_suite;
-
- /* RFC 5426(TLS1.2) allows cipher suite defined PRFs. Cipher suites defined in and before TLS1.2 will use
- * P_hash with SHA256 when TLS1.2 is negotiated.
- */
- const s2n_hmac_algorithm prf_alg;
-
- const uint8_t minimum_required_tls_version;
-};
-
-/* Never negotiated */
-extern struct s2n_cipher_suite s2n_null_cipher_suite;
-
-extern struct s2n_cipher_suite s2n_rsa_with_rc4_128_md5;
-extern struct s2n_cipher_suite s2n_rsa_with_rc4_128_sha;
-extern struct s2n_cipher_suite s2n_rsa_with_3des_ede_cbc_sha;
-extern struct s2n_cipher_suite s2n_dhe_rsa_with_3des_ede_cbc_sha;
-extern struct s2n_cipher_suite s2n_rsa_with_aes_128_cbc_sha;
-extern struct s2n_cipher_suite s2n_dhe_rsa_with_aes_128_cbc_sha;
-extern struct s2n_cipher_suite s2n_rsa_with_aes_256_cbc_sha;
-extern struct s2n_cipher_suite s2n_dhe_rsa_with_aes_256_cbc_sha;
-extern struct s2n_cipher_suite s2n_rsa_with_aes_128_cbc_sha256;
-extern struct s2n_cipher_suite s2n_rsa_with_aes_256_cbc_sha256;
-extern struct s2n_cipher_suite s2n_dhe_rsa_with_aes_128_cbc_sha256;
-extern struct s2n_cipher_suite s2n_dhe_rsa_with_aes_256_cbc_sha256;
-extern struct s2n_cipher_suite s2n_rsa_with_aes_128_gcm_sha256;
-extern struct s2n_cipher_suite s2n_rsa_with_aes_256_gcm_sha384;
-extern struct s2n_cipher_suite s2n_dhe_rsa_with_aes_128_gcm_sha256;
-extern struct s2n_cipher_suite s2n_dhe_rsa_with_aes_256_gcm_sha384;
-extern struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_128_cbc_sha;
-extern struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_256_cbc_sha;
-extern struct s2n_cipher_suite s2n_ecdhe_rsa_with_3des_ede_cbc_sha;
-extern struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_128_cbc_sha;
-extern struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_256_cbc_sha;
-extern struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256;
-extern struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384;
-extern struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_128_cbc_sha256;
-extern struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_256_cbc_sha384;
-extern struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256;
-extern struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384;
-extern struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_128_gcm_sha256;
-extern struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_256_gcm_sha384;
-extern struct s2n_cipher_suite s2n_ecdhe_rsa_with_chacha20_poly1305_sha256;
-extern struct s2n_cipher_suite s2n_dhe_rsa_with_chacha20_poly1305_sha256;
-extern struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256;
-extern struct s2n_cipher_suite s2n_ecdhe_rsa_with_rc4_128_sha;
-extern struct s2n_cipher_suite s2n_ecdhe_kyber_rsa_with_aes_256_gcm_sha384;
-extern struct s2n_cipher_suite s2n_ecdhe_bike_rsa_with_aes_256_gcm_sha384;
-extern struct s2n_cipher_suite s2n_ecdhe_sike_rsa_with_aes_256_gcm_sha384;
-extern struct s2n_cipher_suite s2n_tls13_aes_256_gcm_sha384;
-extern struct s2n_cipher_suite s2n_tls13_aes_128_gcm_sha256;
-extern struct s2n_cipher_suite s2n_tls13_chacha20_poly1305_sha256;
-
-extern int s2n_cipher_suites_init(void);
-extern int s2n_cipher_suites_cleanup(void);
-extern struct s2n_cipher_suite *s2n_cipher_suite_from_wire(const uint8_t cipher_suite[S2N_TLS_CIPHER_SUITE_LEN]);
-extern int s2n_set_cipher_as_client(struct s2n_connection *conn, uint8_t wire[S2N_TLS_CIPHER_SUITE_LEN]);
-extern int s2n_set_cipher_as_sslv2_server(struct s2n_connection *conn, uint8_t * wire, uint16_t count);
-extern int s2n_set_cipher_as_tls_server(struct s2n_connection *conn, uint8_t * wire, uint16_t count);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/s2n_tls_parameters.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_crypto.h"
+
+#include "crypto/s2n_certificate.h"
+#include "crypto/s2n_cipher.h"
+#include "crypto/s2n_hmac.h"
+
+#include <stdint.h>
+
+/* Key exchange flags that can be OR'ed */
+#define S2N_KEY_EXCHANGE_DH 0x01 /* Diffie-Hellman key exchange, including ephemeral */
+#define S2N_KEY_EXCHANGE_EPH 0x02 /* Ephemeral key exchange */
+#define S2N_KEY_EXCHANGE_ECC 0x04 /* Elliptic curve cryptography */
+
+#define S2N_MAX_POSSIBLE_RECORD_ALGS 2
+#if !defined(S2N_NO_PQ)
+#define S2N_PQ_CIPHER_SUITE_COUNT 3
+#else
+#define S2N_PQ_CIPHER_SUITE_COUNT 0
+#endif
+
+/* Kept up-to-date by s2n_cipher_suite_match_test */
+#define S2N_CIPHER_SUITE_COUNT (36 + S2N_PQ_CIPHER_SUITE_COUNT)
+
+
+/* Record algorithm flags that can be OR'ed */
+#define S2N_TLS12_AES_GCM_AEAD_NONCE 0x01
+#define S2N_TLS12_CHACHA_POLY_AEAD_NONCE 0x02
+#define S2N_TLS13_RECORD_AEAD_NONCE 0x04
+
+/* From RFC: https://tools.ietf.org/html/rfc8446#section-5.5
+ * For AES-GCM, up to 2^24.5 full-size records (about 24 million) may be
+ * encrypted on a given connection while keeping a safety margin of
+ * approximately 2^-57 for Authenticated Encryption (AE) security.
+ * S2N_TLS13_MAXIMUM_RECORD_NUMBER is 2^24.5 rounded down to the nearest whole number
+ * minus 1 for the key update message.
+ */
+#define S2N_TLS13_AES_GCM_MAXIMUM_RECORD_NUMBER ((uint64_t) 23726565)
+
+typedef enum {
+ S2N_AUTHENTICATION_RSA = 0,
+ S2N_AUTHENTICATION_ECDSA,
+ S2N_AUTHENTICATION_METHOD_SENTINEL
+} s2n_authentication_method;
+
+/* Used by TLS 1.3 CipherSuites (Eg TLS_AES_128_GCM_SHA256 "0x1301") where the Auth method will be specified by the
+ * SignatureScheme Extension, not the CipherSuite. */
+#define S2N_AUTHENTICATION_METHOD_TLS13 S2N_AUTHENTICATION_METHOD_SENTINEL
+
+struct s2n_record_algorithm {
+ const struct s2n_cipher *cipher;
+ s2n_hmac_algorithm hmac_alg;
+ uint32_t flags;
+ uint64_t encryption_limit;
+};
+
+/* Verbose names to avoid confusion with s2n_cipher. Exposed for unit tests */
+extern const struct s2n_record_algorithm s2n_record_alg_null;
+extern const struct s2n_record_algorithm s2n_record_alg_rc4_md5;
+extern const struct s2n_record_algorithm s2n_record_alg_rc4_sha;
+extern const struct s2n_record_algorithm s2n_record_alg_3des_sha;
+extern const struct s2n_record_algorithm s2n_record_alg_aes128_sha;
+extern const struct s2n_record_algorithm s2n_record_alg_aes128_sha_composite;
+extern const struct s2n_record_algorithm s2n_record_alg_aes128_sha256;
+extern const struct s2n_record_algorithm s2n_record_alg_aes128_sha256_composite;
+extern const struct s2n_record_algorithm s2n_record_alg_aes256_sha;
+extern const struct s2n_record_algorithm s2n_record_alg_aes256_sha_composite;
+extern const struct s2n_record_algorithm s2n_record_alg_aes256_sha256;
+extern const struct s2n_record_algorithm s2n_record_alg_aes256_sha256_composite;
+extern const struct s2n_record_algorithm s2n_record_alg_aes256_sha384;
+extern const struct s2n_record_algorithm s2n_record_alg_aes128_gcm;
+extern const struct s2n_record_algorithm s2n_record_alg_aes256_gcm;
+extern const struct s2n_record_algorithm s2n_record_alg_chacha20_poly1305;
+
+struct s2n_cipher_suite {
+ /* Is there an implementation available? Set in s2n_cipher_suites_init() */
+ unsigned int available:1;
+
+ /* Cipher name in Openssl format */
+ const char *name;
+ const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN];
+
+ const struct s2n_kex *key_exchange_alg;
+
+ const s2n_authentication_method auth_method;
+
+ /* Algorithms used for per-record security. Set in s2n_cipher_suites_init() */
+ const struct s2n_record_algorithm *record_alg;
+
+ /* List of all possible record alg implementations in descending priority */
+ const struct s2n_record_algorithm *all_record_algs[S2N_MAX_POSSIBLE_RECORD_ALGS];
+ const uint8_t num_record_algs;
+
+ /* SSLv3 utilizes HMAC differently from TLS */
+ const struct s2n_record_algorithm *sslv3_record_alg;
+ struct s2n_cipher_suite *sslv3_cipher_suite;
+
+ /* RFC 5426(TLS1.2) allows cipher suite defined PRFs. Cipher suites defined in and before TLS1.2 will use
+ * P_hash with SHA256 when TLS1.2 is negotiated.
+ */
+ const s2n_hmac_algorithm prf_alg;
+
+ const uint8_t minimum_required_tls_version;
+};
+
+/* Never negotiated */
+extern struct s2n_cipher_suite s2n_null_cipher_suite;
+
+extern struct s2n_cipher_suite s2n_rsa_with_rc4_128_md5;
+extern struct s2n_cipher_suite s2n_rsa_with_rc4_128_sha;
+extern struct s2n_cipher_suite s2n_rsa_with_3des_ede_cbc_sha;
+extern struct s2n_cipher_suite s2n_dhe_rsa_with_3des_ede_cbc_sha;
+extern struct s2n_cipher_suite s2n_rsa_with_aes_128_cbc_sha;
+extern struct s2n_cipher_suite s2n_dhe_rsa_with_aes_128_cbc_sha;
+extern struct s2n_cipher_suite s2n_rsa_with_aes_256_cbc_sha;
+extern struct s2n_cipher_suite s2n_dhe_rsa_with_aes_256_cbc_sha;
+extern struct s2n_cipher_suite s2n_rsa_with_aes_128_cbc_sha256;
+extern struct s2n_cipher_suite s2n_rsa_with_aes_256_cbc_sha256;
+extern struct s2n_cipher_suite s2n_dhe_rsa_with_aes_128_cbc_sha256;
+extern struct s2n_cipher_suite s2n_dhe_rsa_with_aes_256_cbc_sha256;
+extern struct s2n_cipher_suite s2n_rsa_with_aes_128_gcm_sha256;
+extern struct s2n_cipher_suite s2n_rsa_with_aes_256_gcm_sha384;
+extern struct s2n_cipher_suite s2n_dhe_rsa_with_aes_128_gcm_sha256;
+extern struct s2n_cipher_suite s2n_dhe_rsa_with_aes_256_gcm_sha384;
+extern struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_128_cbc_sha;
+extern struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_256_cbc_sha;
+extern struct s2n_cipher_suite s2n_ecdhe_rsa_with_3des_ede_cbc_sha;
+extern struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_128_cbc_sha;
+extern struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_256_cbc_sha;
+extern struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_128_cbc_sha256;
+extern struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_256_cbc_sha384;
+extern struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_128_cbc_sha256;
+extern struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_256_cbc_sha384;
+extern struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_128_gcm_sha256;
+extern struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384;
+extern struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_128_gcm_sha256;
+extern struct s2n_cipher_suite s2n_ecdhe_rsa_with_aes_256_gcm_sha384;
+extern struct s2n_cipher_suite s2n_ecdhe_rsa_with_chacha20_poly1305_sha256;
+extern struct s2n_cipher_suite s2n_dhe_rsa_with_chacha20_poly1305_sha256;
+extern struct s2n_cipher_suite s2n_ecdhe_ecdsa_with_chacha20_poly1305_sha256;
+extern struct s2n_cipher_suite s2n_ecdhe_rsa_with_rc4_128_sha;
+extern struct s2n_cipher_suite s2n_ecdhe_kyber_rsa_with_aes_256_gcm_sha384;
+extern struct s2n_cipher_suite s2n_ecdhe_bike_rsa_with_aes_256_gcm_sha384;
+extern struct s2n_cipher_suite s2n_ecdhe_sike_rsa_with_aes_256_gcm_sha384;
+extern struct s2n_cipher_suite s2n_tls13_aes_256_gcm_sha384;
+extern struct s2n_cipher_suite s2n_tls13_aes_128_gcm_sha256;
+extern struct s2n_cipher_suite s2n_tls13_chacha20_poly1305_sha256;
+
+extern int s2n_cipher_suites_init(void);
+extern int s2n_cipher_suites_cleanup(void);
+extern struct s2n_cipher_suite *s2n_cipher_suite_from_wire(const uint8_t cipher_suite[S2N_TLS_CIPHER_SUITE_LEN]);
+extern int s2n_set_cipher_as_client(struct s2n_connection *conn, uint8_t wire[S2N_TLS_CIPHER_SUITE_LEN]);
+extern int s2n_set_cipher_as_sslv2_server(struct s2n_connection *conn, uint8_t * wire, uint16_t count);
+extern int s2n_set_cipher_as_tls_server(struct s2n_connection *conn, uint8_t * wire, uint16_t count);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_client_cert.c b/contrib/restricted/aws/s2n/tls/s2n_client_cert.c
index edec36255f..7dde226788 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_client_cert.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_client_cert.c
@@ -1,99 +1,99 @@
-/*
- * 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 <s2n.h>
-
-#include "crypto/s2n_certificate.h"
-#include "error/s2n_errno.h"
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_config.h"
-#include "tls/s2n_tls.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_blob.h"
-#include "utils/s2n_safety.h"
-
-
-int s2n_client_cert_recv(struct s2n_connection *conn)
-{
- if (conn->actual_protocol_version == S2N_TLS13) {
- uint8_t certificate_request_context_len;
- GUARD(s2n_stuffer_read_uint8(&conn->handshake.io, &certificate_request_context_len));
- S2N_ERROR_IF(certificate_request_context_len != 0,S2N_ERR_BAD_MESSAGE);
- }
-
- struct s2n_stuffer *in = &conn->handshake.io;
- struct s2n_blob client_cert_chain = {0};
-
- GUARD(s2n_stuffer_read_uint24(in, &client_cert_chain.size));
-
- S2N_ERROR_IF(client_cert_chain.size > s2n_stuffer_data_available(in), S2N_ERR_BAD_MESSAGE);
-
- if (client_cert_chain.size == 0) {
- GUARD(s2n_conn_set_handshake_no_client_cert(conn));
- return 0;
- }
-
- client_cert_chain.data = s2n_stuffer_raw_read(in, client_cert_chain.size);
- notnull_check(client_cert_chain.data);
-
- s2n_cert_public_key public_key;
- GUARD(s2n_pkey_zero_init(&public_key));
-
- s2n_pkey_type pkey_type;
-
- /* Determine the Cert Type, Verify the Cert, and extract the Public Key */
- S2N_ERROR_IF(s2n_x509_validator_validate_cert_chain(&conn->x509_validator, conn,
- client_cert_chain.data, client_cert_chain.size,
- &pkey_type, &public_key) != S2N_CERT_OK, S2N_ERR_CERT_UNTRUSTED);
-
- conn->secure.client_cert_pkey_type = pkey_type;
- GUARD(s2n_pkey_setup_for_type(&public_key, pkey_type));
-
- GUARD(s2n_pkey_check_key_exists(&public_key));
- GUARD(s2n_dup(&client_cert_chain, &conn->secure.client_cert_chain));
- conn->secure.client_public_key = public_key;
-
- return 0;
-}
-
-
-int s2n_client_cert_send(struct s2n_connection *conn)
-{
- struct s2n_cert_chain_and_key *chain_and_key = conn->handshake_params.our_chain_and_key;
-
- if (conn->actual_protocol_version == S2N_TLS13) {
- /* If this message is in response to a CertificateRequest, the value of
- * certificate_request_context in that message.
- * https://tools.ietf.org/html/rfc8446#section-4.4.2
- *
- * This field SHALL be zero length unless used for the post-handshake authentication
- * https://tools.ietf.org/html/rfc8446#section-4.3.2
- */
- uint8_t certificate_request_context_len = 0;
- GUARD(s2n_stuffer_write_uint8(&conn->handshake.io, certificate_request_context_len));
- }
-
- if (chain_and_key == NULL) {
- GUARD(s2n_conn_set_handshake_no_client_cert(conn));
- GUARD(s2n_send_empty_cert_chain(&conn->handshake.io));
- return 0;
- }
-
- GUARD(s2n_send_cert_chain(conn, &conn->handshake.io, chain_and_key));
- return 0;
-}
+/*
+ * 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 <s2n.h>
+
+#include "crypto/s2n_certificate.h"
+#include "error/s2n_errno.h"
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_config.h"
+#include "tls/s2n_tls.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_blob.h"
+#include "utils/s2n_safety.h"
+
+
+int s2n_client_cert_recv(struct s2n_connection *conn)
+{
+ if (conn->actual_protocol_version == S2N_TLS13) {
+ uint8_t certificate_request_context_len;
+ GUARD(s2n_stuffer_read_uint8(&conn->handshake.io, &certificate_request_context_len));
+ S2N_ERROR_IF(certificate_request_context_len != 0,S2N_ERR_BAD_MESSAGE);
+ }
+
+ struct s2n_stuffer *in = &conn->handshake.io;
+ struct s2n_blob client_cert_chain = {0};
+
+ GUARD(s2n_stuffer_read_uint24(in, &client_cert_chain.size));
+
+ S2N_ERROR_IF(client_cert_chain.size > s2n_stuffer_data_available(in), S2N_ERR_BAD_MESSAGE);
+
+ if (client_cert_chain.size == 0) {
+ GUARD(s2n_conn_set_handshake_no_client_cert(conn));
+ return 0;
+ }
+
+ client_cert_chain.data = s2n_stuffer_raw_read(in, client_cert_chain.size);
+ notnull_check(client_cert_chain.data);
+
+ s2n_cert_public_key public_key;
+ GUARD(s2n_pkey_zero_init(&public_key));
+
+ s2n_pkey_type pkey_type;
+
+ /* Determine the Cert Type, Verify the Cert, and extract the Public Key */
+ S2N_ERROR_IF(s2n_x509_validator_validate_cert_chain(&conn->x509_validator, conn,
+ client_cert_chain.data, client_cert_chain.size,
+ &pkey_type, &public_key) != S2N_CERT_OK, S2N_ERR_CERT_UNTRUSTED);
+
+ conn->secure.client_cert_pkey_type = pkey_type;
+ GUARD(s2n_pkey_setup_for_type(&public_key, pkey_type));
+
+ GUARD(s2n_pkey_check_key_exists(&public_key));
+ GUARD(s2n_dup(&client_cert_chain, &conn->secure.client_cert_chain));
+ conn->secure.client_public_key = public_key;
+
+ return 0;
+}
+
+
+int s2n_client_cert_send(struct s2n_connection *conn)
+{
+ struct s2n_cert_chain_and_key *chain_and_key = conn->handshake_params.our_chain_and_key;
+
+ if (conn->actual_protocol_version == S2N_TLS13) {
+ /* If this message is in response to a CertificateRequest, the value of
+ * certificate_request_context in that message.
+ * https://tools.ietf.org/html/rfc8446#section-4.4.2
+ *
+ * This field SHALL be zero length unless used for the post-handshake authentication
+ * https://tools.ietf.org/html/rfc8446#section-4.3.2
+ */
+ uint8_t certificate_request_context_len = 0;
+ GUARD(s2n_stuffer_write_uint8(&conn->handshake.io, certificate_request_context_len));
+ }
+
+ if (chain_and_key == NULL) {
+ GUARD(s2n_conn_set_handshake_no_client_cert(conn));
+ GUARD(s2n_send_empty_cert_chain(&conn->handshake.io));
+ return 0;
+ }
+
+ GUARD(s2n_send_cert_chain(conn, &conn->handshake.io, chain_and_key));
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_client_cert_verify.c b/contrib/restricted/aws/s2n/tls/s2n_client_cert_verify.c
index 5296762282..a218c13c18 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_client_cert_verify.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_client_cert_verify.c
@@ -1,91 +1,91 @@
-/*
- * 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 <s2n.h>
-
-#include "error/s2n_errno.h"
-
-#include "tls/s2n_connection.h"
-#include "tls/s2n_config.h"
-#include "tls/s2n_signature_algorithms.h"
-#include "tls/s2n_tls.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_safety.h"
-
-
-int s2n_client_cert_verify_recv(struct s2n_connection *conn)
-{
- struct s2n_stuffer *in = &conn->handshake.io;
- struct s2n_signature_scheme chosen_sig_scheme = s2n_rsa_pkcs1_md5_sha1;
-
- if(conn->actual_protocol_version >= S2N_TLS12){
- /* Verify the SigScheme picked by the Client was in the preference list we sent (or is the default SigScheme) */
- GUARD(s2n_get_and_validate_negotiated_signature_scheme(conn, in, &chosen_sig_scheme));
- }
- uint16_t signature_size;
- struct s2n_blob signature = {0};
- GUARD(s2n_stuffer_read_uint16(in, &signature_size));
- signature.size = signature_size;
- signature.data = s2n_stuffer_raw_read(in, signature.size);
- notnull_check(signature.data);
-
- /* Use a copy of the hash state since the verify digest computation may modify the running hash state we need later. */
- struct s2n_hash_state hash_state = {0};
- GUARD(s2n_handshake_get_hash_state(conn, chosen_sig_scheme.hash_alg, &hash_state));
- GUARD(s2n_hash_copy(&conn->handshake.ccv_hash_copy, &hash_state));
-
- /* Verify the signature */
- GUARD(s2n_pkey_verify(&conn->secure.client_public_key, chosen_sig_scheme.sig_alg, &conn->handshake.ccv_hash_copy, &signature));
-
- /* Client certificate has been verified. Minimize required handshake hash algs */
- GUARD(s2n_conn_update_required_handshake_hashes(conn));
-
- return 0;
-}
-
-int s2n_client_cert_verify_send(struct s2n_connection *conn)
-{
- struct s2n_stuffer *out = &conn->handshake.io;
-
- struct s2n_signature_scheme chosen_sig_scheme = s2n_rsa_pkcs1_md5_sha1;
-
- if (conn->actual_protocol_version >= S2N_TLS12) {
- chosen_sig_scheme = conn->secure.client_cert_sig_scheme;
- GUARD(s2n_stuffer_write_uint16(out, conn->secure.client_cert_sig_scheme.iana_value));
- }
-
- /* Use a copy of the hash state since the verify digest computation may modify the running hash state we need later. */
- struct s2n_hash_state hash_state = {0};
- GUARD(s2n_handshake_get_hash_state(conn, chosen_sig_scheme.hash_alg, &hash_state));
- GUARD(s2n_hash_copy(&conn->handshake.ccv_hash_copy, &hash_state));
-
- struct s2n_cert_chain_and_key *cert_chain_and_key = conn->handshake_params.our_chain_and_key;
-
- DEFER_CLEANUP(struct s2n_blob signature = {0}, s2n_free);
- uint32_t max_signature_size = s2n_pkey_size(cert_chain_and_key->private_key);
- GUARD(s2n_alloc(&signature, max_signature_size));
-
- GUARD(s2n_pkey_sign(cert_chain_and_key->private_key, chosen_sig_scheme.sig_alg, &conn->handshake.ccv_hash_copy, &signature));
-
- GUARD(s2n_stuffer_write_uint16(out, signature.size));
- GUARD(s2n_stuffer_write(out, &signature));
-
- /* Client certificate has been verified. Minimize required handshake hash algs */
- GUARD(s2n_conn_update_required_handshake_hashes(conn));
-
- return 0;
-}
+/*
+ * 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 <s2n.h>
+
+#include "error/s2n_errno.h"
+
+#include "tls/s2n_connection.h"
+#include "tls/s2n_config.h"
+#include "tls/s2n_signature_algorithms.h"
+#include "tls/s2n_tls.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_safety.h"
+
+
+int s2n_client_cert_verify_recv(struct s2n_connection *conn)
+{
+ struct s2n_stuffer *in = &conn->handshake.io;
+ struct s2n_signature_scheme chosen_sig_scheme = s2n_rsa_pkcs1_md5_sha1;
+
+ if(conn->actual_protocol_version >= S2N_TLS12){
+ /* Verify the SigScheme picked by the Client was in the preference list we sent (or is the default SigScheme) */
+ GUARD(s2n_get_and_validate_negotiated_signature_scheme(conn, in, &chosen_sig_scheme));
+ }
+ uint16_t signature_size;
+ struct s2n_blob signature = {0};
+ GUARD(s2n_stuffer_read_uint16(in, &signature_size));
+ signature.size = signature_size;
+ signature.data = s2n_stuffer_raw_read(in, signature.size);
+ notnull_check(signature.data);
+
+ /* Use a copy of the hash state since the verify digest computation may modify the running hash state we need later. */
+ struct s2n_hash_state hash_state = {0};
+ GUARD(s2n_handshake_get_hash_state(conn, chosen_sig_scheme.hash_alg, &hash_state));
+ GUARD(s2n_hash_copy(&conn->handshake.ccv_hash_copy, &hash_state));
+
+ /* Verify the signature */
+ GUARD(s2n_pkey_verify(&conn->secure.client_public_key, chosen_sig_scheme.sig_alg, &conn->handshake.ccv_hash_copy, &signature));
+
+ /* Client certificate has been verified. Minimize required handshake hash algs */
+ GUARD(s2n_conn_update_required_handshake_hashes(conn));
+
+ return 0;
+}
+
+int s2n_client_cert_verify_send(struct s2n_connection *conn)
+{
+ struct s2n_stuffer *out = &conn->handshake.io;
+
+ struct s2n_signature_scheme chosen_sig_scheme = s2n_rsa_pkcs1_md5_sha1;
+
+ if (conn->actual_protocol_version >= S2N_TLS12) {
+ chosen_sig_scheme = conn->secure.client_cert_sig_scheme;
+ GUARD(s2n_stuffer_write_uint16(out, conn->secure.client_cert_sig_scheme.iana_value));
+ }
+
+ /* Use a copy of the hash state since the verify digest computation may modify the running hash state we need later. */
+ struct s2n_hash_state hash_state = {0};
+ GUARD(s2n_handshake_get_hash_state(conn, chosen_sig_scheme.hash_alg, &hash_state));
+ GUARD(s2n_hash_copy(&conn->handshake.ccv_hash_copy, &hash_state));
+
+ struct s2n_cert_chain_and_key *cert_chain_and_key = conn->handshake_params.our_chain_and_key;
+
+ DEFER_CLEANUP(struct s2n_blob signature = {0}, s2n_free);
+ uint32_t max_signature_size = s2n_pkey_size(cert_chain_and_key->private_key);
+ GUARD(s2n_alloc(&signature, max_signature_size));
+
+ GUARD(s2n_pkey_sign(cert_chain_and_key->private_key, chosen_sig_scheme.sig_alg, &conn->handshake.ccv_hash_copy, &signature));
+
+ GUARD(s2n_stuffer_write_uint16(out, signature.size));
+ GUARD(s2n_stuffer_write(out, &signature));
+
+ /* Client certificate has been verified. Minimize required handshake hash algs */
+ GUARD(s2n_conn_update_required_handshake_hashes(conn));
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_client_finished.c b/contrib/restricted/aws/s2n/tls/s2n_client_finished.c
index d98da3452c..cc85970145 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_client_finished.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_client_finished.c
@@ -1,110 +1,110 @@
-/*
- * 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 <stdint.h>
-
-#include "error/s2n_errno.h"
-
-#include "tls/s2n_connection.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls13_handshake.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_safety.h"
-
-int s2n_client_finished_recv(struct s2n_connection *conn)
-{
- uint8_t *our_version;
- our_version = conn->handshake.client_finished;
- uint8_t *their_version = s2n_stuffer_raw_read(&conn->handshake.io, S2N_TLS_FINISHED_LEN);
- notnull_check(their_version);
-
- S2N_ERROR_IF(!s2n_constant_time_equals(our_version, their_version, S2N_TLS_FINISHED_LEN) || conn->handshake.rsa_failed, S2N_ERR_BAD_MESSAGE);
-
- return 0;
-}
-
-int s2n_client_finished_send(struct s2n_connection *conn)
-{
- uint8_t *our_version;
- GUARD(s2n_prf_client_finished(conn));
-
- struct s2n_blob seq = {.data = conn->secure.client_sequence_number,.size = sizeof(conn->secure.client_sequence_number) };
- GUARD(s2n_blob_zero(&seq));
- our_version = conn->handshake.client_finished;
-
- /* Update the server to use the cipher suite */
- conn->client = &conn->secure;
-
- if (conn->actual_protocol_version == S2N_SSLv3) {
- GUARD(s2n_stuffer_write_bytes(&conn->handshake.io, our_version, S2N_SSL_FINISHED_LEN));
- } else {
- GUARD(s2n_stuffer_write_bytes(&conn->handshake.io, our_version, S2N_TLS_FINISHED_LEN));
- }
- return 0;
-}
-
-int s2n_tls13_client_finished_recv(struct s2n_connection *conn) {
- eq_check(conn->actual_protocol_version, S2N_TLS13);
-
- uint8_t length = s2n_stuffer_data_available(&conn->handshake.io);
- S2N_ERROR_IF(length == 0, S2N_ERR_BAD_MESSAGE);
-
- /* read finished mac from handshake */
- struct s2n_blob wire_finished_mac = {0};
- s2n_blob_init(&wire_finished_mac, s2n_stuffer_raw_read(&conn->handshake.io, length), length);
-
- /* get tls13 keys */
- s2n_tls13_connection_keys(keys, conn);
-
- /* get transcript hash */
- struct s2n_hash_state hash_state = {0};
- GUARD(s2n_handshake_get_hash_state(conn, keys.hash_algorithm, &hash_state));
-
- struct s2n_blob finished_key = {0};
- GUARD(s2n_blob_init(&finished_key, conn->handshake.client_finished, keys.size));
-
- s2n_tls13_key_blob(client_finished_mac, keys.size);
- GUARD(s2n_tls13_calculate_finished_mac(&keys, &finished_key, &hash_state, &client_finished_mac));
-
- GUARD(s2n_tls13_mac_verify(&keys, &client_finished_mac, &wire_finished_mac));
-
- return 0;
-}
-
-int s2n_tls13_client_finished_send(struct s2n_connection *conn) {
- eq_check(conn->actual_protocol_version, S2N_TLS13);
-
- /* get tls13 keys */
- s2n_tls13_connection_keys(keys, conn);
-
- /* get transcript hash */
- struct s2n_hash_state hash_state = {0};
- GUARD(s2n_handshake_get_hash_state(conn, keys.hash_algorithm, &hash_state));
-
- /* look up finished secret key */
- struct s2n_blob finished_key = {0};
- GUARD(s2n_blob_init(&finished_key, conn->handshake.client_finished, keys.size));
-
- /* generate the hashed message authenticated code */
- s2n_stack_blob(client_finished_mac, keys.size, S2N_TLS13_SECRET_MAX_LEN);
- GUARD(s2n_tls13_calculate_finished_mac(&keys, &finished_key, &hash_state, &client_finished_mac));
-
- /* write to handshake io */
- GUARD(s2n_stuffer_write(&conn->handshake.io, &client_finished_mac));
-
- return 0;
-}
+/*
+ * 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 <stdint.h>
+
+#include "error/s2n_errno.h"
+
+#include "tls/s2n_connection.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls13_handshake.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_safety.h"
+
+int s2n_client_finished_recv(struct s2n_connection *conn)
+{
+ uint8_t *our_version;
+ our_version = conn->handshake.client_finished;
+ uint8_t *their_version = s2n_stuffer_raw_read(&conn->handshake.io, S2N_TLS_FINISHED_LEN);
+ notnull_check(their_version);
+
+ S2N_ERROR_IF(!s2n_constant_time_equals(our_version, their_version, S2N_TLS_FINISHED_LEN) || conn->handshake.rsa_failed, S2N_ERR_BAD_MESSAGE);
+
+ return 0;
+}
+
+int s2n_client_finished_send(struct s2n_connection *conn)
+{
+ uint8_t *our_version;
+ GUARD(s2n_prf_client_finished(conn));
+
+ struct s2n_blob seq = {.data = conn->secure.client_sequence_number,.size = sizeof(conn->secure.client_sequence_number) };
+ GUARD(s2n_blob_zero(&seq));
+ our_version = conn->handshake.client_finished;
+
+ /* Update the server to use the cipher suite */
+ conn->client = &conn->secure;
+
+ if (conn->actual_protocol_version == S2N_SSLv3) {
+ GUARD(s2n_stuffer_write_bytes(&conn->handshake.io, our_version, S2N_SSL_FINISHED_LEN));
+ } else {
+ GUARD(s2n_stuffer_write_bytes(&conn->handshake.io, our_version, S2N_TLS_FINISHED_LEN));
+ }
+ return 0;
+}
+
+int s2n_tls13_client_finished_recv(struct s2n_connection *conn) {
+ eq_check(conn->actual_protocol_version, S2N_TLS13);
+
+ uint8_t length = s2n_stuffer_data_available(&conn->handshake.io);
+ S2N_ERROR_IF(length == 0, S2N_ERR_BAD_MESSAGE);
+
+ /* read finished mac from handshake */
+ struct s2n_blob wire_finished_mac = {0};
+ s2n_blob_init(&wire_finished_mac, s2n_stuffer_raw_read(&conn->handshake.io, length), length);
+
+ /* get tls13 keys */
+ s2n_tls13_connection_keys(keys, conn);
+
+ /* get transcript hash */
+ struct s2n_hash_state hash_state = {0};
+ GUARD(s2n_handshake_get_hash_state(conn, keys.hash_algorithm, &hash_state));
+
+ struct s2n_blob finished_key = {0};
+ GUARD(s2n_blob_init(&finished_key, conn->handshake.client_finished, keys.size));
+
+ s2n_tls13_key_blob(client_finished_mac, keys.size);
+ GUARD(s2n_tls13_calculate_finished_mac(&keys, &finished_key, &hash_state, &client_finished_mac));
+
+ GUARD(s2n_tls13_mac_verify(&keys, &client_finished_mac, &wire_finished_mac));
+
+ return 0;
+}
+
+int s2n_tls13_client_finished_send(struct s2n_connection *conn) {
+ eq_check(conn->actual_protocol_version, S2N_TLS13);
+
+ /* get tls13 keys */
+ s2n_tls13_connection_keys(keys, conn);
+
+ /* get transcript hash */
+ struct s2n_hash_state hash_state = {0};
+ GUARD(s2n_handshake_get_hash_state(conn, keys.hash_algorithm, &hash_state));
+
+ /* look up finished secret key */
+ struct s2n_blob finished_key = {0};
+ GUARD(s2n_blob_init(&finished_key, conn->handshake.client_finished, keys.size));
+
+ /* generate the hashed message authenticated code */
+ s2n_stack_blob(client_finished_mac, keys.size, S2N_TLS13_SECRET_MAX_LEN);
+ GUARD(s2n_tls13_calculate_finished_mac(&keys, &finished_key, &hash_state, &client_finished_mac));
+
+ /* write to handshake io */
+ GUARD(s2n_stuffer_write(&conn->handshake.io, &client_finished_mac));
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_client_hello.c b/contrib/restricted/aws/s2n/tls/s2n_client_hello.c
index 95b1277e96..15bf12c525 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_client_hello.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_client_hello.c
@@ -1,510 +1,510 @@
-/*
- * 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 <sys/param.h>
-#include <time.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "crypto/s2n_fips.h"
-
-#include "error/s2n_errno.h"
-
-#include "crypto/s2n_hash.h"
-
-#include "tls/extensions/s2n_extension_list.h"
-#include "tls/extensions/s2n_server_key_share.h"
-#include "tls/s2n_auth_selection.h"
-#include "tls/s2n_cipher_preferences.h"
-#include "tls/s2n_security_policies.h"
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_client_hello.h"
-#include "tls/s2n_alerts.h"
-#include "tls/s2n_signature_algorithms.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls_digest_preferences.h"
-#include "tls/s2n_security_policies.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_bitmap.h"
-#include "utils/s2n_random.h"
-#include "utils/s2n_safety.h"
-
-struct s2n_client_hello *s2n_connection_get_client_hello(struct s2n_connection *conn) {
- if (conn->client_hello.parsed != 1) {
- return NULL;
- }
-
- return &conn->client_hello;
-}
-
-static uint32_t min_size(struct s2n_blob *blob, uint32_t max_length) {
- return blob->size < max_length ? blob->size : max_length;
-}
-
-static S2N_RESULT s2n_generate_client_session_id(struct s2n_connection *conn)
-{
- ENSURE_REF(conn);
- ENSURE_REF(conn->config);
-
- /* Session id already generated - no-op */
- if (conn->session_id_len) {
- return S2N_RESULT_OK;
- }
-
- /* Only generate the session id for pre-TLS1.3 if using tickets */
- if (conn->client_protocol_version < S2N_TLS13 && !conn->config->use_tickets) {
- return S2N_RESULT_OK;
- }
-
- /* Generate the session id for TLS1.3 if in middlebox compatibility mode.
- * For now, we default to middlebox compatibility mode unless using QUIC. */
- if (conn->config->quic_enabled) {
- return S2N_RESULT_OK;
- }
-
- struct s2n_blob session_id = {0};
- GUARD_AS_RESULT(s2n_blob_init(&session_id, conn->session_id, S2N_TLS_SESSION_ID_MAX_LEN));
- GUARD_RESULT(s2n_get_public_random_data(&session_id));
- conn->session_id_len = S2N_TLS_SESSION_ID_MAX_LEN;
-
- return S2N_RESULT_OK;
-}
-
-ssize_t s2n_client_hello_get_raw_message_length(struct s2n_client_hello *ch) {
- notnull_check(ch);
-
- return ch->raw_message.blob.size;
-}
-
-ssize_t s2n_client_hello_get_raw_message(struct s2n_client_hello *ch, uint8_t *out, uint32_t max_length)
-{
- notnull_check(ch);
- notnull_check(out);
-
- uint32_t len = min_size(&ch->raw_message.blob, max_length);
-
- struct s2n_stuffer *raw_message = &ch->raw_message;
- GUARD(s2n_stuffer_reread(raw_message));
- GUARD(s2n_stuffer_read_bytes(raw_message, out, len));
-
- return len;
-}
-
-ssize_t s2n_client_hello_get_cipher_suites_length(struct s2n_client_hello *ch) {
- notnull_check(ch);
-
- return ch->cipher_suites.size;
-}
-
-ssize_t s2n_client_hello_get_cipher_suites(struct s2n_client_hello *ch, uint8_t *out, uint32_t max_length)
-{
- notnull_check(ch);
- notnull_check(out);
- notnull_check(ch->cipher_suites.data);
-
- uint32_t len = min_size(&ch->cipher_suites, max_length);
-
- memcpy_check(out, &ch->cipher_suites.data, len);
-
- return len;
-}
-
-ssize_t s2n_client_hello_get_extensions_length(struct s2n_client_hello *ch) {
- notnull_check(ch);
-
- return ch->extensions.raw.size;
-}
-
-ssize_t s2n_client_hello_get_extensions(struct s2n_client_hello *ch, uint8_t *out, uint32_t max_length)
-{
- notnull_check(ch);
- notnull_check(out);
- notnull_check(ch->extensions.raw.data);
-
- uint32_t len = min_size(&ch->extensions.raw, max_length);
-
- memcpy_check(out, &ch->extensions.raw.data, len);
-
- return len;
-}
-
-int s2n_client_hello_free(struct s2n_client_hello *client_hello)
-{
- notnull_check(client_hello);
-
- GUARD(s2n_stuffer_free(&client_hello->raw_message));
-
- /* These point to data in the raw_message stuffer,
- so we don't need to free them */
- client_hello->cipher_suites.data = NULL;
- client_hello->extensions.raw.data = NULL;
-
- return 0;
-}
-
-int s2n_collect_client_hello(struct s2n_connection *conn, struct s2n_stuffer *source)
-{
- notnull_check(conn);
- notnull_check(source);
-
- uint32_t size = s2n_stuffer_data_available(source);
- S2N_ERROR_IF(size == 0, S2N_ERR_BAD_MESSAGE);
-
- struct s2n_client_hello *ch = &conn->client_hello;
-
- GUARD(s2n_stuffer_resize(&ch->raw_message, size));
- GUARD(s2n_stuffer_copy(source, &ch->raw_message, size));
-
- return 0;
-}
-
-static int s2n_parse_client_hello(struct s2n_connection *conn)
-{
- notnull_check(conn);
- GUARD(s2n_collect_client_hello(conn, &conn->handshake.io));
-
- if (conn->client_hello_version == S2N_SSLv2) {
- GUARD(s2n_sslv2_client_hello_recv(conn));
- return S2N_SUCCESS;
- }
-
- /* Going forward, we parse the collected client hello */
- struct s2n_client_hello *client_hello = &conn->client_hello;
- struct s2n_stuffer *in = &client_hello->raw_message;
-
- uint8_t client_protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN];
-
- GUARD(s2n_stuffer_read_bytes(in, client_protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
- GUARD(s2n_stuffer_erase_and_read_bytes(in, conn->secure.client_random, S2N_TLS_RANDOM_DATA_LEN));
-
- /* Protocol version in the ClientHello is fixed at 0x0303(TLS 1.2) for
- * future versions of TLS. Therefore, we will negotiate down if a client sends
- * an unexpected value above 0x0303.
- */
- conn->client_protocol_version = MIN((client_protocol_version[0] * 10) + client_protocol_version[1], S2N_TLS12);
- conn->client_hello_version = conn->client_protocol_version;
-
- GUARD(s2n_stuffer_read_uint8(in, &conn->session_id_len));
- S2N_ERROR_IF(conn->session_id_len > S2N_TLS_SESSION_ID_MAX_LEN || conn->session_id_len > s2n_stuffer_data_available(in), S2N_ERR_BAD_MESSAGE);
-
- GUARD(s2n_stuffer_read_bytes(in, conn->session_id, conn->session_id_len));
-
- uint16_t cipher_suites_length = 0;
- GUARD(s2n_stuffer_read_uint16(in, &cipher_suites_length));
- ENSURE_POSIX(cipher_suites_length > 0, S2N_ERR_BAD_MESSAGE);
- ENSURE_POSIX(cipher_suites_length % S2N_TLS_CIPHER_SUITE_LEN == 0, S2N_ERR_BAD_MESSAGE);
-
- client_hello->cipher_suites.size = cipher_suites_length;
- client_hello->cipher_suites.data = s2n_stuffer_raw_read(in, cipher_suites_length);
- notnull_check(client_hello->cipher_suites.data);
-
- /* Don't choose the cipher yet, read the extensions first */
- uint8_t num_compression_methods = 0;
- GUARD(s2n_stuffer_read_uint8(in, &num_compression_methods));
- GUARD(s2n_stuffer_skip_read(in, num_compression_methods));
-
- const struct s2n_ecc_preferences *ecc_pref = NULL;
- GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
- notnull_check(ecc_pref);
-
- /* This is going to be our fallback if the client has no preference. */
- /* A TLS-compliant application MUST support key exchange with secp256r1 (NIST P-256) */
- /* and SHOULD support key exchange with X25519 [RFC7748]. */
- /* - https://tools.ietf.org/html/rfc8446#section-9.1 */
- conn->secure.server_ecc_evp_params.negotiated_curve = &s2n_ecc_curve_secp256r1;
-
- GUARD(s2n_extension_list_parse(in, &conn->client_hello.extensions));
-
- return S2N_SUCCESS;
-}
-
-int s2n_process_client_hello(struct s2n_connection *conn)
-{
- /* Client hello is parsed and config is finalized.
- * Negotiate protocol version, cipher suite, ALPN, select a cert, etc. */
- struct s2n_client_hello *client_hello = &conn->client_hello;
-
- const struct s2n_security_policy *security_policy;
- GUARD(s2n_connection_get_security_policy(conn, &security_policy));
-
- /* Ensure that highest supported version is set correctly */
- if (!s2n_security_policy_supports_tls13(security_policy)) {
- conn->server_protocol_version = MIN(conn->server_protocol_version, S2N_TLS12);
- conn->actual_protocol_version = MIN(conn->server_protocol_version, S2N_TLS12);
- }
-
- /* s2n_extension_list_process clears the parsed extensions as it processes them.
- * To keep the version in client_hello intact for the extension retrieval APIs, process a copy instead.
- */
- s2n_parsed_extensions_list copy_of_parsed_extensions = conn->client_hello.extensions;
- GUARD(s2n_extension_list_process(S2N_EXTENSION_LIST_CLIENT_HELLO, conn, &copy_of_parsed_extensions));
-
- /* After parsing extensions, select a curve and corresponding keyshare to use */
- if (conn->actual_protocol_version >= S2N_TLS13) {
- GUARD(s2n_extensions_server_key_share_select(conn));
- }
-
- /* for pre TLS 1.3 connections, protocol selection is not done in supported_versions extensions, so do it here */
- if (conn->actual_protocol_version < S2N_TLS13) {
- conn->actual_protocol_version = MIN(conn->server_protocol_version, conn->client_protocol_version);
- }
-
- if (conn->client_protocol_version < security_policy->minimum_protocol_version) {
- GUARD(s2n_queue_reader_unsupported_protocol_version_alert(conn));
- S2N_ERROR(S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED);
- }
-
- if (conn->config->quic_enabled) {
- ENSURE_POSIX(conn->actual_protocol_version >= S2N_TLS13, S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED);
-
- /* In TLS1.3, legacy_session_id is only set to indicate middlebox compatability mode.
- * When running with QUIC, S2N does not support middlebox compatability mode.
- * https://tools.ietf.org/html/draft-ietf-quic-tls-32#section-8.4
- */
- ENSURE_POSIX(conn->session_id_len == 0, S2N_ERR_BAD_MESSAGE);
- }
-
- /* Find potential certificate matches before we choose the cipher. */
- GUARD(s2n_conn_find_name_matching_certs(conn));
-
- /* Now choose the ciphers we have certs for. */
- GUARD(s2n_set_cipher_as_tls_server(conn, client_hello->cipher_suites.data, client_hello->cipher_suites.size / 2));
-
- /* And set the signature and hash algorithm used for key exchange signatures */
- GUARD(s2n_choose_sig_scheme_from_peer_preference_list(conn,
- &conn->handshake_params.client_sig_hash_algs,
- &conn->secure.conn_sig_scheme));
-
- /* And finally, set the certs specified by the final auth + sig_alg combo. */
- GUARD(s2n_select_certs_for_server_auth(conn, &conn->handshake_params.our_chain_and_key));
-
- return 0;
-}
-
-int s2n_client_hello_recv(struct s2n_connection *conn)
-{
- /* Parse client hello */
- GUARD(s2n_parse_client_hello(conn));
-
- /* If the CLIENT_HELLO has already been parsed, then we should not call
- * the client_hello_cb a second time. */
- if (conn->client_hello.parsed == 0) {
- /* Mark the collected client hello as available when parsing is done and before the client hello callback */
- conn->client_hello.parsed = 1;
-
- /* Call client_hello_cb if exists, letting application to modify s2n_connection or swap s2n_config */
- if (conn->config->client_hello_cb) {
- int rc = conn->config->client_hello_cb(conn, conn->config->client_hello_cb_ctx);
- if (rc < 0) {
- GUARD(s2n_queue_reader_handshake_failure_alert(conn));
- S2N_ERROR(S2N_ERR_CANCELLED);
- }
- if (rc) {
- conn->server_name_used = 1;
- }
- }
- }
-
- if (conn->client_hello_version != S2N_SSLv2) {
- GUARD(s2n_process_client_hello(conn));
- }
-
- return 0;
-}
-
-int s2n_client_hello_send(struct s2n_connection *conn)
-{
- const struct s2n_security_policy *security_policy;
- GUARD(s2n_connection_get_security_policy(conn, &security_policy));
-
- const struct s2n_cipher_preferences *cipher_preferences = security_policy->cipher_preferences;
- notnull_check(cipher_preferences);
-
- /* Check whether cipher preference supports TLS 1.3. If it doesn't,
- our highest supported version is S2N_TLS12 */
- if (!s2n_security_policy_supports_tls13(security_policy)) {
- conn->client_protocol_version = MIN(conn->client_protocol_version, S2N_TLS12);
- conn->actual_protocol_version = MIN(conn->actual_protocol_version, S2N_TLS12);
- }
-
- struct s2n_stuffer *out = &conn->handshake.io;
- struct s2n_stuffer client_random = {0};
- uint8_t client_protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN] = {0};
-
- struct s2n_blob b = {0};
- GUARD(s2n_blob_init(&b, conn->secure.client_random, S2N_TLS_RANDOM_DATA_LEN));
- /* Create the client random data */
- GUARD(s2n_stuffer_init(&client_random, &b));
-
- struct s2n_blob r = {0};
- GUARD(s2n_blob_init(&r, s2n_stuffer_raw_write(&client_random, S2N_TLS_RANDOM_DATA_LEN), S2N_TLS_RANDOM_DATA_LEN));
- notnull_check(r.data);
- GUARD_AS_POSIX(s2n_get_public_random_data(&r));
-
- uint8_t reported_protocol_version = MIN(conn->client_protocol_version, S2N_TLS12);
- client_protocol_version[0] = reported_protocol_version / 10;
- client_protocol_version[1] = reported_protocol_version % 10;
- conn->client_hello_version = reported_protocol_version;
-
- GUARD(s2n_stuffer_write_bytes(out, client_protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
- GUARD(s2n_stuffer_copy(&client_random, out, S2N_TLS_RANDOM_DATA_LEN));
-
- GUARD_AS_POSIX(s2n_generate_client_session_id(conn));
- GUARD(s2n_stuffer_write_uint8(out, conn->session_id_len));
- if (conn->session_id_len > 0) {
- GUARD(s2n_stuffer_write_bytes(out, conn->session_id, conn->session_id_len));
- }
-
- /* Reserve space for size of the list of available ciphers */
- struct s2n_stuffer_reservation available_cipher_suites_size;
- GUARD(s2n_stuffer_reserve_uint16(out, &available_cipher_suites_size));
-
- /* Now, write the IANA values of every available cipher suite in our list */
- for (int i = 0; i < security_policy->cipher_preferences->count; i++ ) {
- if (cipher_preferences->suites[i]->available &&
- cipher_preferences->suites[i]->minimum_required_tls_version <= conn->client_protocol_version) {
- GUARD(s2n_stuffer_write_bytes(out, security_policy->cipher_preferences->suites[i]->iana_value, S2N_TLS_CIPHER_SUITE_LEN));
- }
- }
-
- /* Lastly, write TLS_EMPTY_RENEGOTIATION_INFO_SCSV so that server knows it's an initial handshake (RFC5746 Section 3.4) */
- uint8_t renegotiation_info_scsv[S2N_TLS_CIPHER_SUITE_LEN] = { TLS_EMPTY_RENEGOTIATION_INFO_SCSV };
- GUARD(s2n_stuffer_write_bytes(out, renegotiation_info_scsv, S2N_TLS_CIPHER_SUITE_LEN));
-
- /* Write size of the list of available ciphers */
- GUARD(s2n_stuffer_write_vector_size(&available_cipher_suites_size));
-
- /* Zero compression methods */
- GUARD(s2n_stuffer_write_uint8(out, 1));
- GUARD(s2n_stuffer_write_uint8(out, 0));
-
- /* Write the extensions */
- GUARD(s2n_extension_list_send(S2N_EXTENSION_LIST_CLIENT_HELLO, conn, out));
-
- /* Once the message is complete, finish calculating the PSK binders.
- *
- * The PSK binders require all the sizes in the ClientHello to be written correctly,
- * including the extension size and extension list size, and therefore have
- * to be calculated AFTER we finish writing the entire extension list. */
- GUARD_AS_POSIX(s2n_finish_psk_extension(conn));
-
- return S2N_SUCCESS;
-}
-
-/* See http://www-archive.mozilla.org/projects/security/pki/nss/ssl/draft02.html 2.5 */
-int s2n_sslv2_client_hello_recv(struct s2n_connection *conn)
-{
- struct s2n_client_hello *client_hello = &conn->client_hello;
- struct s2n_stuffer *in = &client_hello->raw_message;
-
- const struct s2n_security_policy *security_policy;
- GUARD(s2n_connection_get_security_policy(conn, &security_policy));
-
- if (conn->client_protocol_version < security_policy->minimum_protocol_version) {
- GUARD(s2n_queue_reader_unsupported_protocol_version_alert(conn));
- S2N_ERROR(S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED);
- }
- conn->actual_protocol_version = MIN(conn->client_protocol_version, conn->server_protocol_version);
-
- /* We start 5 bytes into the record */
- uint16_t cipher_suites_length;
- GUARD(s2n_stuffer_read_uint16(in, &cipher_suites_length));
- ENSURE_POSIX(cipher_suites_length > 0, S2N_ERR_BAD_MESSAGE);
- ENSURE_POSIX(cipher_suites_length % S2N_SSLv2_CIPHER_SUITE_LEN == 0, S2N_ERR_BAD_MESSAGE);
-
- uint16_t session_id_length;
- GUARD(s2n_stuffer_read_uint16(in, &session_id_length));
-
- uint16_t challenge_length;
- GUARD(s2n_stuffer_read_uint16(in, &challenge_length));
-
- S2N_ERROR_IF(challenge_length > S2N_TLS_RANDOM_DATA_LEN, S2N_ERR_BAD_MESSAGE);
-
- client_hello->cipher_suites.size = cipher_suites_length;
- client_hello->cipher_suites.data = s2n_stuffer_raw_read(in, cipher_suites_length);
- notnull_check(client_hello->cipher_suites.data);
-
- /* Find potential certificate matches before we choose the cipher. */
- GUARD(s2n_conn_find_name_matching_certs(conn));
-
- GUARD(s2n_set_cipher_as_sslv2_server(conn, client_hello->cipher_suites.data, client_hello->cipher_suites.size / S2N_SSLv2_CIPHER_SUITE_LEN));
- GUARD(s2n_choose_default_sig_scheme(conn, &conn->secure.conn_sig_scheme));
- GUARD(s2n_select_certs_for_server_auth(conn, &conn->handshake_params.our_chain_and_key));
-
- S2N_ERROR_IF(session_id_length > s2n_stuffer_data_available(in), S2N_ERR_BAD_MESSAGE);
- if (session_id_length > 0 && session_id_length <= S2N_TLS_SESSION_ID_MAX_LEN) {
- GUARD(s2n_stuffer_read_bytes(in, conn->session_id, session_id_length));
- conn->session_id_len = (uint8_t) session_id_length;
- } else {
- GUARD(s2n_stuffer_skip_read(in, session_id_length));
- }
-
- struct s2n_blob b = {0};
- GUARD(s2n_blob_init(&b, conn->secure.client_random, S2N_TLS_RANDOM_DATA_LEN));
-
- b.data += S2N_TLS_RANDOM_DATA_LEN - challenge_length;
- b.size -= S2N_TLS_RANDOM_DATA_LEN - challenge_length;
-
- GUARD(s2n_stuffer_read(in, &b));
-
- return 0;
-}
-
-static int s2n_client_hello_get_parsed_extension(s2n_tls_extension_type extension_type,
- s2n_parsed_extensions_list *parsed_extension_list, s2n_parsed_extension **parsed_extension)
-{
- notnull_check(parsed_extension_list);
- notnull_check(parsed_extension);
-
- s2n_extension_type_id extension_type_id;
- GUARD(s2n_extension_supported_iana_value_to_id(extension_type, &extension_type_id));
-
- s2n_parsed_extension *found_parsed_extension = &parsed_extension_list->parsed_extensions[extension_type_id];
- notnull_check(found_parsed_extension->extension.data);
- ENSURE_POSIX(found_parsed_extension->extension_type == extension_type, S2N_ERR_INVALID_PARSED_EXTENSIONS);
-
- *parsed_extension = found_parsed_extension;
- return S2N_SUCCESS;
-}
-
-ssize_t s2n_client_hello_get_extension_length(struct s2n_client_hello *ch, s2n_tls_extension_type extension_type)
-{
- notnull_check(ch);
-
- s2n_parsed_extension *parsed_extension = NULL;
- if (s2n_client_hello_get_parsed_extension(extension_type, &ch->extensions, &parsed_extension) != S2N_SUCCESS) {
- return 0;
- }
-
- return parsed_extension->extension.size;
-}
-
-ssize_t s2n_client_hello_get_extension_by_id(struct s2n_client_hello *ch, s2n_tls_extension_type extension_type, uint8_t *out, uint32_t max_length)
-{
- notnull_check(ch);
- notnull_check(out);
-
- s2n_parsed_extension *parsed_extension = NULL;
- if (s2n_client_hello_get_parsed_extension(extension_type, &ch->extensions, &parsed_extension) != S2N_SUCCESS) {
- return 0;
- }
-
- uint32_t len = min_size(&parsed_extension->extension, max_length);
- memcpy_check(out, parsed_extension->extension.data, len);
- return len;
-}
+/*
+ * 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 <sys/param.h>
+#include <time.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "crypto/s2n_fips.h"
+
+#include "error/s2n_errno.h"
+
+#include "crypto/s2n_hash.h"
+
+#include "tls/extensions/s2n_extension_list.h"
+#include "tls/extensions/s2n_server_key_share.h"
+#include "tls/s2n_auth_selection.h"
+#include "tls/s2n_cipher_preferences.h"
+#include "tls/s2n_security_policies.h"
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_client_hello.h"
+#include "tls/s2n_alerts.h"
+#include "tls/s2n_signature_algorithms.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls_digest_preferences.h"
+#include "tls/s2n_security_policies.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_bitmap.h"
+#include "utils/s2n_random.h"
+#include "utils/s2n_safety.h"
+
+struct s2n_client_hello *s2n_connection_get_client_hello(struct s2n_connection *conn) {
+ if (conn->client_hello.parsed != 1) {
+ return NULL;
+ }
+
+ return &conn->client_hello;
+}
+
+static uint32_t min_size(struct s2n_blob *blob, uint32_t max_length) {
+ return blob->size < max_length ? blob->size : max_length;
+}
+
+static S2N_RESULT s2n_generate_client_session_id(struct s2n_connection *conn)
+{
+ ENSURE_REF(conn);
+ ENSURE_REF(conn->config);
+
+ /* Session id already generated - no-op */
+ if (conn->session_id_len) {
+ return S2N_RESULT_OK;
+ }
+
+ /* Only generate the session id for pre-TLS1.3 if using tickets */
+ if (conn->client_protocol_version < S2N_TLS13 && !conn->config->use_tickets) {
+ return S2N_RESULT_OK;
+ }
+
+ /* Generate the session id for TLS1.3 if in middlebox compatibility mode.
+ * For now, we default to middlebox compatibility mode unless using QUIC. */
+ if (conn->config->quic_enabled) {
+ return S2N_RESULT_OK;
+ }
+
+ struct s2n_blob session_id = {0};
+ GUARD_AS_RESULT(s2n_blob_init(&session_id, conn->session_id, S2N_TLS_SESSION_ID_MAX_LEN));
+ GUARD_RESULT(s2n_get_public_random_data(&session_id));
+ conn->session_id_len = S2N_TLS_SESSION_ID_MAX_LEN;
+
+ return S2N_RESULT_OK;
+}
+
+ssize_t s2n_client_hello_get_raw_message_length(struct s2n_client_hello *ch) {
+ notnull_check(ch);
+
+ return ch->raw_message.blob.size;
+}
+
+ssize_t s2n_client_hello_get_raw_message(struct s2n_client_hello *ch, uint8_t *out, uint32_t max_length)
+{
+ notnull_check(ch);
+ notnull_check(out);
+
+ uint32_t len = min_size(&ch->raw_message.blob, max_length);
+
+ struct s2n_stuffer *raw_message = &ch->raw_message;
+ GUARD(s2n_stuffer_reread(raw_message));
+ GUARD(s2n_stuffer_read_bytes(raw_message, out, len));
+
+ return len;
+}
+
+ssize_t s2n_client_hello_get_cipher_suites_length(struct s2n_client_hello *ch) {
+ notnull_check(ch);
+
+ return ch->cipher_suites.size;
+}
+
+ssize_t s2n_client_hello_get_cipher_suites(struct s2n_client_hello *ch, uint8_t *out, uint32_t max_length)
+{
+ notnull_check(ch);
+ notnull_check(out);
+ notnull_check(ch->cipher_suites.data);
+
+ uint32_t len = min_size(&ch->cipher_suites, max_length);
+
+ memcpy_check(out, &ch->cipher_suites.data, len);
+
+ return len;
+}
+
+ssize_t s2n_client_hello_get_extensions_length(struct s2n_client_hello *ch) {
+ notnull_check(ch);
+
+ return ch->extensions.raw.size;
+}
+
+ssize_t s2n_client_hello_get_extensions(struct s2n_client_hello *ch, uint8_t *out, uint32_t max_length)
+{
+ notnull_check(ch);
+ notnull_check(out);
+ notnull_check(ch->extensions.raw.data);
+
+ uint32_t len = min_size(&ch->extensions.raw, max_length);
+
+ memcpy_check(out, &ch->extensions.raw.data, len);
+
+ return len;
+}
+
+int s2n_client_hello_free(struct s2n_client_hello *client_hello)
+{
+ notnull_check(client_hello);
+
+ GUARD(s2n_stuffer_free(&client_hello->raw_message));
+
+ /* These point to data in the raw_message stuffer,
+ so we don't need to free them */
+ client_hello->cipher_suites.data = NULL;
+ client_hello->extensions.raw.data = NULL;
+
+ return 0;
+}
+
+int s2n_collect_client_hello(struct s2n_connection *conn, struct s2n_stuffer *source)
+{
+ notnull_check(conn);
+ notnull_check(source);
+
+ uint32_t size = s2n_stuffer_data_available(source);
+ S2N_ERROR_IF(size == 0, S2N_ERR_BAD_MESSAGE);
+
+ struct s2n_client_hello *ch = &conn->client_hello;
+
+ GUARD(s2n_stuffer_resize(&ch->raw_message, size));
+ GUARD(s2n_stuffer_copy(source, &ch->raw_message, size));
+
+ return 0;
+}
+
+static int s2n_parse_client_hello(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+ GUARD(s2n_collect_client_hello(conn, &conn->handshake.io));
+
+ if (conn->client_hello_version == S2N_SSLv2) {
+ GUARD(s2n_sslv2_client_hello_recv(conn));
+ return S2N_SUCCESS;
+ }
+
+ /* Going forward, we parse the collected client hello */
+ struct s2n_client_hello *client_hello = &conn->client_hello;
+ struct s2n_stuffer *in = &client_hello->raw_message;
+
+ uint8_t client_protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN];
+
+ GUARD(s2n_stuffer_read_bytes(in, client_protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
+ GUARD(s2n_stuffer_erase_and_read_bytes(in, conn->secure.client_random, S2N_TLS_RANDOM_DATA_LEN));
+
+ /* Protocol version in the ClientHello is fixed at 0x0303(TLS 1.2) for
+ * future versions of TLS. Therefore, we will negotiate down if a client sends
+ * an unexpected value above 0x0303.
+ */
+ conn->client_protocol_version = MIN((client_protocol_version[0] * 10) + client_protocol_version[1], S2N_TLS12);
+ conn->client_hello_version = conn->client_protocol_version;
+
+ GUARD(s2n_stuffer_read_uint8(in, &conn->session_id_len));
+ S2N_ERROR_IF(conn->session_id_len > S2N_TLS_SESSION_ID_MAX_LEN || conn->session_id_len > s2n_stuffer_data_available(in), S2N_ERR_BAD_MESSAGE);
+
+ GUARD(s2n_stuffer_read_bytes(in, conn->session_id, conn->session_id_len));
+
+ uint16_t cipher_suites_length = 0;
+ GUARD(s2n_stuffer_read_uint16(in, &cipher_suites_length));
+ ENSURE_POSIX(cipher_suites_length > 0, S2N_ERR_BAD_MESSAGE);
+ ENSURE_POSIX(cipher_suites_length % S2N_TLS_CIPHER_SUITE_LEN == 0, S2N_ERR_BAD_MESSAGE);
+
+ client_hello->cipher_suites.size = cipher_suites_length;
+ client_hello->cipher_suites.data = s2n_stuffer_raw_read(in, cipher_suites_length);
+ notnull_check(client_hello->cipher_suites.data);
+
+ /* Don't choose the cipher yet, read the extensions first */
+ uint8_t num_compression_methods = 0;
+ GUARD(s2n_stuffer_read_uint8(in, &num_compression_methods));
+ GUARD(s2n_stuffer_skip_read(in, num_compression_methods));
+
+ const struct s2n_ecc_preferences *ecc_pref = NULL;
+ GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
+ notnull_check(ecc_pref);
+
+ /* This is going to be our fallback if the client has no preference. */
+ /* A TLS-compliant application MUST support key exchange with secp256r1 (NIST P-256) */
+ /* and SHOULD support key exchange with X25519 [RFC7748]. */
+ /* - https://tools.ietf.org/html/rfc8446#section-9.1 */
+ conn->secure.server_ecc_evp_params.negotiated_curve = &s2n_ecc_curve_secp256r1;
+
+ GUARD(s2n_extension_list_parse(in, &conn->client_hello.extensions));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_process_client_hello(struct s2n_connection *conn)
+{
+ /* Client hello is parsed and config is finalized.
+ * Negotiate protocol version, cipher suite, ALPN, select a cert, etc. */
+ struct s2n_client_hello *client_hello = &conn->client_hello;
+
+ const struct s2n_security_policy *security_policy;
+ GUARD(s2n_connection_get_security_policy(conn, &security_policy));
+
+ /* Ensure that highest supported version is set correctly */
+ if (!s2n_security_policy_supports_tls13(security_policy)) {
+ conn->server_protocol_version = MIN(conn->server_protocol_version, S2N_TLS12);
+ conn->actual_protocol_version = MIN(conn->server_protocol_version, S2N_TLS12);
+ }
+
+ /* s2n_extension_list_process clears the parsed extensions as it processes them.
+ * To keep the version in client_hello intact for the extension retrieval APIs, process a copy instead.
+ */
+ s2n_parsed_extensions_list copy_of_parsed_extensions = conn->client_hello.extensions;
+ GUARD(s2n_extension_list_process(S2N_EXTENSION_LIST_CLIENT_HELLO, conn, &copy_of_parsed_extensions));
+
+ /* After parsing extensions, select a curve and corresponding keyshare to use */
+ if (conn->actual_protocol_version >= S2N_TLS13) {
+ GUARD(s2n_extensions_server_key_share_select(conn));
+ }
+
+ /* for pre TLS 1.3 connections, protocol selection is not done in supported_versions extensions, so do it here */
+ if (conn->actual_protocol_version < S2N_TLS13) {
+ conn->actual_protocol_version = MIN(conn->server_protocol_version, conn->client_protocol_version);
+ }
+
+ if (conn->client_protocol_version < security_policy->minimum_protocol_version) {
+ GUARD(s2n_queue_reader_unsupported_protocol_version_alert(conn));
+ S2N_ERROR(S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED);
+ }
+
+ if (conn->config->quic_enabled) {
+ ENSURE_POSIX(conn->actual_protocol_version >= S2N_TLS13, S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED);
+
+ /* In TLS1.3, legacy_session_id is only set to indicate middlebox compatability mode.
+ * When running with QUIC, S2N does not support middlebox compatability mode.
+ * https://tools.ietf.org/html/draft-ietf-quic-tls-32#section-8.4
+ */
+ ENSURE_POSIX(conn->session_id_len == 0, S2N_ERR_BAD_MESSAGE);
+ }
+
+ /* Find potential certificate matches before we choose the cipher. */
+ GUARD(s2n_conn_find_name_matching_certs(conn));
+
+ /* Now choose the ciphers we have certs for. */
+ GUARD(s2n_set_cipher_as_tls_server(conn, client_hello->cipher_suites.data, client_hello->cipher_suites.size / 2));
+
+ /* And set the signature and hash algorithm used for key exchange signatures */
+ GUARD(s2n_choose_sig_scheme_from_peer_preference_list(conn,
+ &conn->handshake_params.client_sig_hash_algs,
+ &conn->secure.conn_sig_scheme));
+
+ /* And finally, set the certs specified by the final auth + sig_alg combo. */
+ GUARD(s2n_select_certs_for_server_auth(conn, &conn->handshake_params.our_chain_and_key));
+
+ return 0;
+}
+
+int s2n_client_hello_recv(struct s2n_connection *conn)
+{
+ /* Parse client hello */
+ GUARD(s2n_parse_client_hello(conn));
+
+ /* If the CLIENT_HELLO has already been parsed, then we should not call
+ * the client_hello_cb a second time. */
+ if (conn->client_hello.parsed == 0) {
+ /* Mark the collected client hello as available when parsing is done and before the client hello callback */
+ conn->client_hello.parsed = 1;
+
+ /* Call client_hello_cb if exists, letting application to modify s2n_connection or swap s2n_config */
+ if (conn->config->client_hello_cb) {
+ int rc = conn->config->client_hello_cb(conn, conn->config->client_hello_cb_ctx);
+ if (rc < 0) {
+ GUARD(s2n_queue_reader_handshake_failure_alert(conn));
+ S2N_ERROR(S2N_ERR_CANCELLED);
+ }
+ if (rc) {
+ conn->server_name_used = 1;
+ }
+ }
+ }
+
+ if (conn->client_hello_version != S2N_SSLv2) {
+ GUARD(s2n_process_client_hello(conn));
+ }
+
+ return 0;
+}
+
+int s2n_client_hello_send(struct s2n_connection *conn)
+{
+ const struct s2n_security_policy *security_policy;
+ GUARD(s2n_connection_get_security_policy(conn, &security_policy));
+
+ const struct s2n_cipher_preferences *cipher_preferences = security_policy->cipher_preferences;
+ notnull_check(cipher_preferences);
+
+ /* Check whether cipher preference supports TLS 1.3. If it doesn't,
+ our highest supported version is S2N_TLS12 */
+ if (!s2n_security_policy_supports_tls13(security_policy)) {
+ conn->client_protocol_version = MIN(conn->client_protocol_version, S2N_TLS12);
+ conn->actual_protocol_version = MIN(conn->actual_protocol_version, S2N_TLS12);
+ }
+
+ struct s2n_stuffer *out = &conn->handshake.io;
+ struct s2n_stuffer client_random = {0};
+ uint8_t client_protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN] = {0};
+
+ struct s2n_blob b = {0};
+ GUARD(s2n_blob_init(&b, conn->secure.client_random, S2N_TLS_RANDOM_DATA_LEN));
+ /* Create the client random data */
+ GUARD(s2n_stuffer_init(&client_random, &b));
+
+ struct s2n_blob r = {0};
+ GUARD(s2n_blob_init(&r, s2n_stuffer_raw_write(&client_random, S2N_TLS_RANDOM_DATA_LEN), S2N_TLS_RANDOM_DATA_LEN));
+ notnull_check(r.data);
+ GUARD_AS_POSIX(s2n_get_public_random_data(&r));
+
+ uint8_t reported_protocol_version = MIN(conn->client_protocol_version, S2N_TLS12);
+ client_protocol_version[0] = reported_protocol_version / 10;
+ client_protocol_version[1] = reported_protocol_version % 10;
+ conn->client_hello_version = reported_protocol_version;
+
+ GUARD(s2n_stuffer_write_bytes(out, client_protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
+ GUARD(s2n_stuffer_copy(&client_random, out, S2N_TLS_RANDOM_DATA_LEN));
+
+ GUARD_AS_POSIX(s2n_generate_client_session_id(conn));
+ GUARD(s2n_stuffer_write_uint8(out, conn->session_id_len));
+ if (conn->session_id_len > 0) {
+ GUARD(s2n_stuffer_write_bytes(out, conn->session_id, conn->session_id_len));
+ }
+
+ /* Reserve space for size of the list of available ciphers */
+ struct s2n_stuffer_reservation available_cipher_suites_size;
+ GUARD(s2n_stuffer_reserve_uint16(out, &available_cipher_suites_size));
+
+ /* Now, write the IANA values of every available cipher suite in our list */
+ for (int i = 0; i < security_policy->cipher_preferences->count; i++ ) {
+ if (cipher_preferences->suites[i]->available &&
+ cipher_preferences->suites[i]->minimum_required_tls_version <= conn->client_protocol_version) {
+ GUARD(s2n_stuffer_write_bytes(out, security_policy->cipher_preferences->suites[i]->iana_value, S2N_TLS_CIPHER_SUITE_LEN));
+ }
+ }
+
+ /* Lastly, write TLS_EMPTY_RENEGOTIATION_INFO_SCSV so that server knows it's an initial handshake (RFC5746 Section 3.4) */
+ uint8_t renegotiation_info_scsv[S2N_TLS_CIPHER_SUITE_LEN] = { TLS_EMPTY_RENEGOTIATION_INFO_SCSV };
+ GUARD(s2n_stuffer_write_bytes(out, renegotiation_info_scsv, S2N_TLS_CIPHER_SUITE_LEN));
+
+ /* Write size of the list of available ciphers */
+ GUARD(s2n_stuffer_write_vector_size(&available_cipher_suites_size));
+
+ /* Zero compression methods */
+ GUARD(s2n_stuffer_write_uint8(out, 1));
+ GUARD(s2n_stuffer_write_uint8(out, 0));
+
+ /* Write the extensions */
+ GUARD(s2n_extension_list_send(S2N_EXTENSION_LIST_CLIENT_HELLO, conn, out));
+
+ /* Once the message is complete, finish calculating the PSK binders.
+ *
+ * The PSK binders require all the sizes in the ClientHello to be written correctly,
+ * including the extension size and extension list size, and therefore have
+ * to be calculated AFTER we finish writing the entire extension list. */
+ GUARD_AS_POSIX(s2n_finish_psk_extension(conn));
+
+ return S2N_SUCCESS;
+}
+
+/* See http://www-archive.mozilla.org/projects/security/pki/nss/ssl/draft02.html 2.5 */
+int s2n_sslv2_client_hello_recv(struct s2n_connection *conn)
+{
+ struct s2n_client_hello *client_hello = &conn->client_hello;
+ struct s2n_stuffer *in = &client_hello->raw_message;
+
+ const struct s2n_security_policy *security_policy;
+ GUARD(s2n_connection_get_security_policy(conn, &security_policy));
+
+ if (conn->client_protocol_version < security_policy->minimum_protocol_version) {
+ GUARD(s2n_queue_reader_unsupported_protocol_version_alert(conn));
+ S2N_ERROR(S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED);
+ }
+ conn->actual_protocol_version = MIN(conn->client_protocol_version, conn->server_protocol_version);
+
+ /* We start 5 bytes into the record */
+ uint16_t cipher_suites_length;
+ GUARD(s2n_stuffer_read_uint16(in, &cipher_suites_length));
+ ENSURE_POSIX(cipher_suites_length > 0, S2N_ERR_BAD_MESSAGE);
+ ENSURE_POSIX(cipher_suites_length % S2N_SSLv2_CIPHER_SUITE_LEN == 0, S2N_ERR_BAD_MESSAGE);
+
+ uint16_t session_id_length;
+ GUARD(s2n_stuffer_read_uint16(in, &session_id_length));
+
+ uint16_t challenge_length;
+ GUARD(s2n_stuffer_read_uint16(in, &challenge_length));
+
+ S2N_ERROR_IF(challenge_length > S2N_TLS_RANDOM_DATA_LEN, S2N_ERR_BAD_MESSAGE);
+
+ client_hello->cipher_suites.size = cipher_suites_length;
+ client_hello->cipher_suites.data = s2n_stuffer_raw_read(in, cipher_suites_length);
+ notnull_check(client_hello->cipher_suites.data);
+
+ /* Find potential certificate matches before we choose the cipher. */
+ GUARD(s2n_conn_find_name_matching_certs(conn));
+
+ GUARD(s2n_set_cipher_as_sslv2_server(conn, client_hello->cipher_suites.data, client_hello->cipher_suites.size / S2N_SSLv2_CIPHER_SUITE_LEN));
+ GUARD(s2n_choose_default_sig_scheme(conn, &conn->secure.conn_sig_scheme));
+ GUARD(s2n_select_certs_for_server_auth(conn, &conn->handshake_params.our_chain_and_key));
+
+ S2N_ERROR_IF(session_id_length > s2n_stuffer_data_available(in), S2N_ERR_BAD_MESSAGE);
+ if (session_id_length > 0 && session_id_length <= S2N_TLS_SESSION_ID_MAX_LEN) {
+ GUARD(s2n_stuffer_read_bytes(in, conn->session_id, session_id_length));
+ conn->session_id_len = (uint8_t) session_id_length;
+ } else {
+ GUARD(s2n_stuffer_skip_read(in, session_id_length));
+ }
+
+ struct s2n_blob b = {0};
+ GUARD(s2n_blob_init(&b, conn->secure.client_random, S2N_TLS_RANDOM_DATA_LEN));
+
+ b.data += S2N_TLS_RANDOM_DATA_LEN - challenge_length;
+ b.size -= S2N_TLS_RANDOM_DATA_LEN - challenge_length;
+
+ GUARD(s2n_stuffer_read(in, &b));
+
+ return 0;
+}
+
+static int s2n_client_hello_get_parsed_extension(s2n_tls_extension_type extension_type,
+ s2n_parsed_extensions_list *parsed_extension_list, s2n_parsed_extension **parsed_extension)
+{
+ notnull_check(parsed_extension_list);
+ notnull_check(parsed_extension);
+
+ s2n_extension_type_id extension_type_id;
+ GUARD(s2n_extension_supported_iana_value_to_id(extension_type, &extension_type_id));
+
+ s2n_parsed_extension *found_parsed_extension = &parsed_extension_list->parsed_extensions[extension_type_id];
+ notnull_check(found_parsed_extension->extension.data);
+ ENSURE_POSIX(found_parsed_extension->extension_type == extension_type, S2N_ERR_INVALID_PARSED_EXTENSIONS);
+
+ *parsed_extension = found_parsed_extension;
+ return S2N_SUCCESS;
+}
+
+ssize_t s2n_client_hello_get_extension_length(struct s2n_client_hello *ch, s2n_tls_extension_type extension_type)
+{
+ notnull_check(ch);
+
+ s2n_parsed_extension *parsed_extension = NULL;
+ if (s2n_client_hello_get_parsed_extension(extension_type, &ch->extensions, &parsed_extension) != S2N_SUCCESS) {
+ return 0;
+ }
+
+ return parsed_extension->extension.size;
+}
+
+ssize_t s2n_client_hello_get_extension_by_id(struct s2n_client_hello *ch, s2n_tls_extension_type extension_type, uint8_t *out, uint32_t max_length)
+{
+ notnull_check(ch);
+ notnull_check(out);
+
+ s2n_parsed_extension *parsed_extension = NULL;
+ if (s2n_client_hello_get_parsed_extension(extension_type, &ch->extensions, &parsed_extension) != S2N_SUCCESS) {
+ return 0;
+ }
+
+ uint32_t len = min_size(&parsed_extension->extension, max_length);
+ memcpy_check(out, parsed_extension->extension.data, len);
+ return len;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_client_hello.h b/contrib/restricted/aws/s2n/tls/s2n_client_hello.h
index f8e8c8c999..59eb0b12c7 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_client_hello.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_client_hello.h
@@ -1,49 +1,49 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <stdint.h>
-#include <s2n.h>
-
-#include "stuffer/s2n_stuffer.h"
-#include "tls/extensions/s2n_extension_list.h"
-
-#include "utils/s2n_array.h"
-/*
- * the 'data' pointers in the below blobs
- * point to data in the raw_message stuffer
- */
-struct s2n_client_hello {
- struct s2n_stuffer raw_message;
-
- s2n_parsed_extensions_list extensions;
- struct s2n_blob cipher_suites;
-
- unsigned int parsed:1;
-};
-
-int s2n_client_hello_free(struct s2n_client_hello *client_hello);
-
-extern struct s2n_client_hello *s2n_connection_get_client_hello(struct s2n_connection *conn);
-
-extern ssize_t s2n_client_hello_get_raw_message_length(struct s2n_client_hello *ch);
-extern ssize_t s2n_client_hello_get_raw_message(struct s2n_client_hello *ch, uint8_t *out, uint32_t max_length);
-
-extern ssize_t s2n_client_hello_get_cipher_suites_length(struct s2n_client_hello *ch);
-extern ssize_t s2n_client_hello_get_cipher_suites(struct s2n_client_hello *ch, uint8_t *out, uint32_t max_length);
-
-extern ssize_t s2n_client_hello_get_extensions_length(struct s2n_client_hello *ch);
-extern ssize_t s2n_client_hello_get_extensions(struct s2n_client_hello *ch, uint8_t *out, uint32_t max_length);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <s2n.h>
+
+#include "stuffer/s2n_stuffer.h"
+#include "tls/extensions/s2n_extension_list.h"
+
+#include "utils/s2n_array.h"
+/*
+ * the 'data' pointers in the below blobs
+ * point to data in the raw_message stuffer
+ */
+struct s2n_client_hello {
+ struct s2n_stuffer raw_message;
+
+ s2n_parsed_extensions_list extensions;
+ struct s2n_blob cipher_suites;
+
+ unsigned int parsed:1;
+};
+
+int s2n_client_hello_free(struct s2n_client_hello *client_hello);
+
+extern struct s2n_client_hello *s2n_connection_get_client_hello(struct s2n_connection *conn);
+
+extern ssize_t s2n_client_hello_get_raw_message_length(struct s2n_client_hello *ch);
+extern ssize_t s2n_client_hello_get_raw_message(struct s2n_client_hello *ch, uint8_t *out, uint32_t max_length);
+
+extern ssize_t s2n_client_hello_get_cipher_suites_length(struct s2n_client_hello *ch);
+extern ssize_t s2n_client_hello_get_cipher_suites(struct s2n_client_hello *ch, uint8_t *out, uint32_t max_length);
+
+extern ssize_t s2n_client_hello_get_extensions_length(struct s2n_client_hello *ch);
+extern ssize_t s2n_client_hello_get_extensions(struct s2n_client_hello *ch, uint8_t *out, uint32_t max_length);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.c b/contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.c
index 7e07867d31..99510d8628 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.c
@@ -1,318 +1,318 @@
-/*
- * 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 <sys/param.h>
-#include <s2n.h>
-
-#include "error/s2n_errno.h"
-
-#include "tls/s2n_async_pkey.h"
-#include "tls/s2n_handshake.h"
-#include "tls/s2n_kem.h"
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_kex.h"
-#include "tls/s2n_resume.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "crypto/s2n_dhe.h"
-#include "crypto/s2n_rsa.h"
-#include "crypto/s2n_pkey.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_random.h"
-
-#define get_client_hello_protocol_version(conn) (conn->client_hello_version == S2N_SSLv2 ? conn->client_protocol_version : conn->client_hello_version)
-
-typedef int s2n_kex_client_key_method(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *shared_key);
-typedef void *s2n_stuffer_action(struct s2n_stuffer *stuffer, uint32_t data_len);
-
-static int s2n_rsa_client_key_recv_complete(struct s2n_connection *conn, bool rsa_failed, struct s2n_blob *shared_key);
-
-static int s2n_hybrid_client_action(struct s2n_connection *conn, struct s2n_blob *combined_shared_key,
- s2n_kex_client_key_method kex_method, uint32_t *cursor, s2n_stuffer_action stuffer_action)
-{
- notnull_check(kex_method);
- notnull_check(stuffer_action);
- struct s2n_stuffer *io = &conn->handshake.io;
- const struct s2n_kex *hybrid_kex_0 = conn->secure.cipher_suite->key_exchange_alg->hybrid[0];
- const struct s2n_kex *hybrid_kex_1 = conn->secure.cipher_suite->key_exchange_alg->hybrid[1];
-
- /* Keep a copy to the start of the entire hybrid client key exchange message for the hybrid PRF */
- struct s2n_blob *client_key_exchange_message = &conn->secure.client_key_exchange_message;
- client_key_exchange_message->data = stuffer_action(io, 0);
- notnull_check(client_key_exchange_message->data);
- const uint32_t start_cursor = *cursor;
-
- DEFER_CLEANUP(struct s2n_blob shared_key_0 = {0}, s2n_free);
- GUARD(kex_method(hybrid_kex_0, conn, &shared_key_0));
-
- struct s2n_blob *shared_key_1 = &(conn->secure.kem_params.shared_secret);
- GUARD(kex_method(hybrid_kex_1, conn, shared_key_1));
-
- const uint32_t end_cursor = *cursor;
- gte_check(end_cursor, start_cursor);
- client_key_exchange_message->size = end_cursor - start_cursor;
-
- GUARD(s2n_alloc(combined_shared_key, shared_key_0.size + shared_key_1->size));
- struct s2n_stuffer stuffer_combiner = {0};
- GUARD(s2n_stuffer_init(&stuffer_combiner, combined_shared_key));
- GUARD(s2n_stuffer_write(&stuffer_combiner, &shared_key_0));
- GUARD(s2n_stuffer_write(&stuffer_combiner, shared_key_1));
-
- GUARD(s2n_kem_free(&conn->secure.kem_params));
-
- return 0;
-}
-
-static int s2n_calculate_keys(struct s2n_connection *conn, struct s2n_blob *shared_key)
-{
- /* Turn the pre-master secret into a master secret */
- GUARD(s2n_kex_tls_prf(conn->secure.cipher_suite->key_exchange_alg, conn, shared_key));
- /* Erase the pre-master secret */
- GUARD(s2n_blob_zero(shared_key));
- if (shared_key->allocated) {
- GUARD(s2n_free(shared_key));
- }
- /* Expand the keys */
- GUARD(s2n_prf_key_expansion(conn));
- /* Save the master secret in the cache */
- if (s2n_allowed_to_cache_connection(conn)) {
- GUARD(s2n_store_to_cache(conn));
- }
- return 0;
-}
-
-int s2n_rsa_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key)
-{
- /* Set shared_key before async guard to pass the proper shared_key to the caller upon async completion */
- notnull_check(shared_key);
- shared_key->data = conn->secure.rsa_premaster_secret;
- shared_key->size = S2N_TLS_SECRET_LEN;
-
- S2N_ASYNC_PKEY_GUARD(conn);
-
- struct s2n_stuffer *in = &conn->handshake.io;
- uint8_t client_hello_protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN];
- uint16_t length;
-
- if (conn->actual_protocol_version == S2N_SSLv3) {
- length = s2n_stuffer_data_available(in);
- } else {
- GUARD(s2n_stuffer_read_uint16(in, &length));
- }
-
- S2N_ERROR_IF(length > s2n_stuffer_data_available(in), S2N_ERR_BAD_MESSAGE);
-
- /* Keep a copy of the client hello version in wire format, which should be
- * either the protocol version supported by client if the supported version is <= TLS1.2,
- * or TLS1.2 (the legacy version) if client supported version is TLS1.3
- */
- uint8_t legacy_client_hello_protocol_version = get_client_hello_protocol_version(conn);
- client_hello_protocol_version[0] = legacy_client_hello_protocol_version / 10;
- client_hello_protocol_version[1] = legacy_client_hello_protocol_version % 10;
-
- /* Decrypt the pre-master secret */
- struct s2n_blob encrypted = {.size = length, .data = s2n_stuffer_raw_read(in, length)};
- notnull_check(encrypted.data);
- gt_check(encrypted.size, 0);
-
- /* First: use a random pre-master secret */
- GUARD_AS_POSIX(s2n_get_private_random_data(shared_key));
- conn->secure.rsa_premaster_secret[0] = client_hello_protocol_version[0];
- conn->secure.rsa_premaster_secret[1] = client_hello_protocol_version[1];
-
- S2N_ASYNC_PKEY_DECRYPT(conn, &encrypted, shared_key, s2n_rsa_client_key_recv_complete);
-}
-
-int s2n_rsa_client_key_recv_complete(struct s2n_connection *conn, bool rsa_failed, struct s2n_blob *decrypted)
-{
- S2N_ERROR_IF(decrypted->size != S2N_TLS_SECRET_LEN, S2N_ERR_SIZE_MISMATCH);
-
- /* Avoid copying the same buffer for the case where async pkey is not used */
- if (conn->secure.rsa_premaster_secret != decrypted->data) {
- /* Copy (maybe) decrypted data into shared key */
- memcpy_check(conn->secure.rsa_premaster_secret, decrypted->data, S2N_TLS_SECRET_LEN);
- }
-
- /* Get client hello protocol version for comparison with decrypted data */
- uint8_t legacy_client_hello_protocol_version = get_client_hello_protocol_version(conn);
- uint8_t client_hello_protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN];
- client_hello_protocol_version[0] = legacy_client_hello_protocol_version / 10;
- client_hello_protocol_version[1] = legacy_client_hello_protocol_version % 10;
-
- conn->handshake.rsa_failed = rsa_failed;
-
- /* Set rsa_failed to true, if it isn't already, if the protocol version isn't what we expect */
- conn->handshake.rsa_failed |= !s2n_constant_time_equals(client_hello_protocol_version,
- conn->secure.rsa_premaster_secret, S2N_TLS_PROTOCOL_VERSION_LEN);
-
- return 0;
-}
-
-int s2n_dhe_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key)
-{
- struct s2n_stuffer *in = &conn->handshake.io;
-
- /* Get the shared key */
- GUARD(s2n_dh_compute_shared_secret_as_server(&conn->secure.server_dh_params, in, shared_key));
- /* We don't need the server params any more */
- GUARD(s2n_dh_params_free(&conn->secure.server_dh_params));
- return 0;
-}
-
-int s2n_ecdhe_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key)
-{
- struct s2n_stuffer *in = &conn->handshake.io;
-
- /* Get the shared key */
- GUARD(s2n_ecc_evp_compute_shared_secret_as_server(&conn->secure.server_ecc_evp_params, in, shared_key));
- /* We don't need the server params any more */
- GUARD(s2n_ecc_evp_params_free(&conn->secure.server_ecc_evp_params));
- return 0;
-}
-
-int s2n_kem_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key)
-{
- /* s2n_kem_recv_ciphertext() writes the KEM shared secret directly to
- * conn->secure.kem_params. However, the calling function
- * likely expects *shared_key to point to the shared secret. We
- * can't reassign *shared_key to point to kem_params.shared_secret,
- * because that would require us to take struct s2n_blob **shared_key
- * as the argument, but we can't (easily) change the function signature
- * because it has to be consistent with what is defined in s2n_kex.
- *
- * So, we assert that the caller already has *shared_key pointing
- * to kem_params.shared_secret. */
- notnull_check(shared_key);
- S2N_ERROR_IF(shared_key != &(conn->secure.kem_params.shared_secret), S2N_ERR_SAFETY);
-
- GUARD(s2n_kem_recv_ciphertext(&(conn->handshake.io), &(conn->secure.kem_params)));
-
- return 0;
-}
-
-int s2n_hybrid_client_key_recv(struct s2n_connection *conn, struct s2n_blob *combined_shared_key)
-{
- return s2n_hybrid_client_action(conn, combined_shared_key, &s2n_kex_client_key_recv, &conn->handshake.io.read_cursor,
- &s2n_stuffer_raw_read);
-}
-
-int s2n_client_key_recv(struct s2n_connection *conn)
-{
- const struct s2n_kex *key_exchange = conn->secure.cipher_suite->key_exchange_alg;
- struct s2n_blob shared_key = {0};
-
- GUARD(s2n_kex_client_key_recv(key_exchange, conn, &shared_key));
-
- GUARD(s2n_calculate_keys(conn, &shared_key));
- return 0;
-}
-
-int s2n_dhe_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key)
-{
- struct s2n_stuffer *out = &conn->handshake.io;
- GUARD(s2n_dh_compute_shared_secret_as_client(&conn->secure.server_dh_params, out, shared_key));
-
- /* We don't need the server params any more */
- GUARD(s2n_dh_params_free(&conn->secure.server_dh_params));
- return 0;
-}
-
-int s2n_ecdhe_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key)
-{
- struct s2n_stuffer *out = &conn->handshake.io;
- GUARD(s2n_ecc_evp_compute_shared_secret_as_client(&conn->secure.server_ecc_evp_params, out, shared_key));
-
- /* We don't need the server params any more */
- GUARD(s2n_ecc_evp_params_free(&conn->secure.server_ecc_evp_params));
- return 0;
-}
-
-int s2n_rsa_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key)
-{
- uint8_t client_hello_protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN];
- uint8_t legacy_client_hello_protocol_version = get_client_hello_protocol_version(conn);
- client_hello_protocol_version[0] = legacy_client_hello_protocol_version / 10;
- client_hello_protocol_version[1] = legacy_client_hello_protocol_version % 10;
-
- shared_key->data = conn->secure.rsa_premaster_secret;
- shared_key->size = S2N_TLS_SECRET_LEN;
-
- GUARD_AS_POSIX(s2n_get_private_random_data(shared_key));
-
- /* Over-write the first two bytes with the client hello version, per RFC2246/RFC4346/RFC5246 7.4.7.1.
- * The latest version supported by client (as seen from the the client hello version) are <= TLS1.2
- * for all clients, because TLS 1.3 clients freezes the TLS1.2 legacy version in client hello.
- */
- memcpy_check(conn->secure.rsa_premaster_secret, client_hello_protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN);
-
- int encrypted_size = s2n_pkey_size(&conn->secure.server_public_key);
- S2N_ERROR_IF(encrypted_size < 0 || encrypted_size > 0xffff, S2N_ERR_SIZE_MISMATCH);
-
- if (conn->actual_protocol_version > S2N_SSLv3) {
- GUARD(s2n_stuffer_write_uint16(&conn->handshake.io, encrypted_size));
- }
-
- struct s2n_blob encrypted = {0};
- encrypted.data = s2n_stuffer_raw_write(&conn->handshake.io, encrypted_size);
- encrypted.size = encrypted_size;
- notnull_check(encrypted.data);
-
- /* Encrypt the secret and send it on */
- GUARD(s2n_pkey_encrypt(&conn->secure.server_public_key, shared_key, &encrypted));
-
- /* We don't need the key any more, so free it */
- GUARD(s2n_pkey_free(&conn->secure.server_public_key));
- return 0;
-}
-
-int s2n_kem_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key)
-{
- /* s2n_kem_send_ciphertext() writes the KEM shared secret directly to
- * conn->secure.kem_params. However, the calling function
+/*
+ * 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 <sys/param.h>
+#include <s2n.h>
+
+#include "error/s2n_errno.h"
+
+#include "tls/s2n_async_pkey.h"
+#include "tls/s2n_handshake.h"
+#include "tls/s2n_kem.h"
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_kex.h"
+#include "tls/s2n_resume.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "crypto/s2n_dhe.h"
+#include "crypto/s2n_rsa.h"
+#include "crypto/s2n_pkey.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_random.h"
+
+#define get_client_hello_protocol_version(conn) (conn->client_hello_version == S2N_SSLv2 ? conn->client_protocol_version : conn->client_hello_version)
+
+typedef int s2n_kex_client_key_method(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *shared_key);
+typedef void *s2n_stuffer_action(struct s2n_stuffer *stuffer, uint32_t data_len);
+
+static int s2n_rsa_client_key_recv_complete(struct s2n_connection *conn, bool rsa_failed, struct s2n_blob *shared_key);
+
+static int s2n_hybrid_client_action(struct s2n_connection *conn, struct s2n_blob *combined_shared_key,
+ s2n_kex_client_key_method kex_method, uint32_t *cursor, s2n_stuffer_action stuffer_action)
+{
+ notnull_check(kex_method);
+ notnull_check(stuffer_action);
+ struct s2n_stuffer *io = &conn->handshake.io;
+ const struct s2n_kex *hybrid_kex_0 = conn->secure.cipher_suite->key_exchange_alg->hybrid[0];
+ const struct s2n_kex *hybrid_kex_1 = conn->secure.cipher_suite->key_exchange_alg->hybrid[1];
+
+ /* Keep a copy to the start of the entire hybrid client key exchange message for the hybrid PRF */
+ struct s2n_blob *client_key_exchange_message = &conn->secure.client_key_exchange_message;
+ client_key_exchange_message->data = stuffer_action(io, 0);
+ notnull_check(client_key_exchange_message->data);
+ const uint32_t start_cursor = *cursor;
+
+ DEFER_CLEANUP(struct s2n_blob shared_key_0 = {0}, s2n_free);
+ GUARD(kex_method(hybrid_kex_0, conn, &shared_key_0));
+
+ struct s2n_blob *shared_key_1 = &(conn->secure.kem_params.shared_secret);
+ GUARD(kex_method(hybrid_kex_1, conn, shared_key_1));
+
+ const uint32_t end_cursor = *cursor;
+ gte_check(end_cursor, start_cursor);
+ client_key_exchange_message->size = end_cursor - start_cursor;
+
+ GUARD(s2n_alloc(combined_shared_key, shared_key_0.size + shared_key_1->size));
+ struct s2n_stuffer stuffer_combiner = {0};
+ GUARD(s2n_stuffer_init(&stuffer_combiner, combined_shared_key));
+ GUARD(s2n_stuffer_write(&stuffer_combiner, &shared_key_0));
+ GUARD(s2n_stuffer_write(&stuffer_combiner, shared_key_1));
+
+ GUARD(s2n_kem_free(&conn->secure.kem_params));
+
+ return 0;
+}
+
+static int s2n_calculate_keys(struct s2n_connection *conn, struct s2n_blob *shared_key)
+{
+ /* Turn the pre-master secret into a master secret */
+ GUARD(s2n_kex_tls_prf(conn->secure.cipher_suite->key_exchange_alg, conn, shared_key));
+ /* Erase the pre-master secret */
+ GUARD(s2n_blob_zero(shared_key));
+ if (shared_key->allocated) {
+ GUARD(s2n_free(shared_key));
+ }
+ /* Expand the keys */
+ GUARD(s2n_prf_key_expansion(conn));
+ /* Save the master secret in the cache */
+ if (s2n_allowed_to_cache_connection(conn)) {
+ GUARD(s2n_store_to_cache(conn));
+ }
+ return 0;
+}
+
+int s2n_rsa_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key)
+{
+ /* Set shared_key before async guard to pass the proper shared_key to the caller upon async completion */
+ notnull_check(shared_key);
+ shared_key->data = conn->secure.rsa_premaster_secret;
+ shared_key->size = S2N_TLS_SECRET_LEN;
+
+ S2N_ASYNC_PKEY_GUARD(conn);
+
+ struct s2n_stuffer *in = &conn->handshake.io;
+ uint8_t client_hello_protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN];
+ uint16_t length;
+
+ if (conn->actual_protocol_version == S2N_SSLv3) {
+ length = s2n_stuffer_data_available(in);
+ } else {
+ GUARD(s2n_stuffer_read_uint16(in, &length));
+ }
+
+ S2N_ERROR_IF(length > s2n_stuffer_data_available(in), S2N_ERR_BAD_MESSAGE);
+
+ /* Keep a copy of the client hello version in wire format, which should be
+ * either the protocol version supported by client if the supported version is <= TLS1.2,
+ * or TLS1.2 (the legacy version) if client supported version is TLS1.3
+ */
+ uint8_t legacy_client_hello_protocol_version = get_client_hello_protocol_version(conn);
+ client_hello_protocol_version[0] = legacy_client_hello_protocol_version / 10;
+ client_hello_protocol_version[1] = legacy_client_hello_protocol_version % 10;
+
+ /* Decrypt the pre-master secret */
+ struct s2n_blob encrypted = {.size = length, .data = s2n_stuffer_raw_read(in, length)};
+ notnull_check(encrypted.data);
+ gt_check(encrypted.size, 0);
+
+ /* First: use a random pre-master secret */
+ GUARD_AS_POSIX(s2n_get_private_random_data(shared_key));
+ conn->secure.rsa_premaster_secret[0] = client_hello_protocol_version[0];
+ conn->secure.rsa_premaster_secret[1] = client_hello_protocol_version[1];
+
+ S2N_ASYNC_PKEY_DECRYPT(conn, &encrypted, shared_key, s2n_rsa_client_key_recv_complete);
+}
+
+int s2n_rsa_client_key_recv_complete(struct s2n_connection *conn, bool rsa_failed, struct s2n_blob *decrypted)
+{
+ S2N_ERROR_IF(decrypted->size != S2N_TLS_SECRET_LEN, S2N_ERR_SIZE_MISMATCH);
+
+ /* Avoid copying the same buffer for the case where async pkey is not used */
+ if (conn->secure.rsa_premaster_secret != decrypted->data) {
+ /* Copy (maybe) decrypted data into shared key */
+ memcpy_check(conn->secure.rsa_premaster_secret, decrypted->data, S2N_TLS_SECRET_LEN);
+ }
+
+ /* Get client hello protocol version for comparison with decrypted data */
+ uint8_t legacy_client_hello_protocol_version = get_client_hello_protocol_version(conn);
+ uint8_t client_hello_protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN];
+ client_hello_protocol_version[0] = legacy_client_hello_protocol_version / 10;
+ client_hello_protocol_version[1] = legacy_client_hello_protocol_version % 10;
+
+ conn->handshake.rsa_failed = rsa_failed;
+
+ /* Set rsa_failed to true, if it isn't already, if the protocol version isn't what we expect */
+ conn->handshake.rsa_failed |= !s2n_constant_time_equals(client_hello_protocol_version,
+ conn->secure.rsa_premaster_secret, S2N_TLS_PROTOCOL_VERSION_LEN);
+
+ return 0;
+}
+
+int s2n_dhe_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key)
+{
+ struct s2n_stuffer *in = &conn->handshake.io;
+
+ /* Get the shared key */
+ GUARD(s2n_dh_compute_shared_secret_as_server(&conn->secure.server_dh_params, in, shared_key));
+ /* We don't need the server params any more */
+ GUARD(s2n_dh_params_free(&conn->secure.server_dh_params));
+ return 0;
+}
+
+int s2n_ecdhe_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key)
+{
+ struct s2n_stuffer *in = &conn->handshake.io;
+
+ /* Get the shared key */
+ GUARD(s2n_ecc_evp_compute_shared_secret_as_server(&conn->secure.server_ecc_evp_params, in, shared_key));
+ /* We don't need the server params any more */
+ GUARD(s2n_ecc_evp_params_free(&conn->secure.server_ecc_evp_params));
+ return 0;
+}
+
+int s2n_kem_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key)
+{
+ /* s2n_kem_recv_ciphertext() writes the KEM shared secret directly to
+ * conn->secure.kem_params. However, the calling function
* likely expects *shared_key to point to the shared secret. We
- * can't reassign *shared_key to point to kem_params.shared_secret,
- * because that would require us to take struct s2n_blob **shared_key
- * as the argument, but we can't (easily) change the function signature
- * because it has to be consistent with what is defined in s2n_kex.
- *
- * So, we assert that the caller already has *shared_key pointing
- * to kem_params.shared_secret. */
- notnull_check(shared_key);
- S2N_ERROR_IF(shared_key != &(conn->secure.kem_params.shared_secret), S2N_ERR_SAFETY);
-
- GUARD(s2n_kem_send_ciphertext(&(conn->handshake.io), &(conn->secure.kem_params)));
-
- return 0;
-}
-
-int s2n_hybrid_client_key_send(struct s2n_connection *conn, struct s2n_blob *combined_shared_key)
-{
- return s2n_hybrid_client_action(conn, combined_shared_key, &s2n_kex_client_key_send, &conn->handshake.io.write_cursor,
- s2n_stuffer_raw_write);
-}
-
-int s2n_client_key_send(struct s2n_connection *conn)
-{
- const struct s2n_kex *key_exchange = conn->secure.cipher_suite->key_exchange_alg;
- struct s2n_blob shared_key = {0};
-
- GUARD(s2n_kex_client_key_send(key_exchange, conn, &shared_key));
-
- GUARD(s2n_calculate_keys(conn, &shared_key));
- return 0;
-}
+ * can't reassign *shared_key to point to kem_params.shared_secret,
+ * because that would require us to take struct s2n_blob **shared_key
+ * as the argument, but we can't (easily) change the function signature
+ * because it has to be consistent with what is defined in s2n_kex.
+ *
+ * So, we assert that the caller already has *shared_key pointing
+ * to kem_params.shared_secret. */
+ notnull_check(shared_key);
+ S2N_ERROR_IF(shared_key != &(conn->secure.kem_params.shared_secret), S2N_ERR_SAFETY);
+
+ GUARD(s2n_kem_recv_ciphertext(&(conn->handshake.io), &(conn->secure.kem_params)));
+
+ return 0;
+}
+
+int s2n_hybrid_client_key_recv(struct s2n_connection *conn, struct s2n_blob *combined_shared_key)
+{
+ return s2n_hybrid_client_action(conn, combined_shared_key, &s2n_kex_client_key_recv, &conn->handshake.io.read_cursor,
+ &s2n_stuffer_raw_read);
+}
+
+int s2n_client_key_recv(struct s2n_connection *conn)
+{
+ const struct s2n_kex *key_exchange = conn->secure.cipher_suite->key_exchange_alg;
+ struct s2n_blob shared_key = {0};
+
+ GUARD(s2n_kex_client_key_recv(key_exchange, conn, &shared_key));
+
+ GUARD(s2n_calculate_keys(conn, &shared_key));
+ return 0;
+}
+
+int s2n_dhe_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key)
+{
+ struct s2n_stuffer *out = &conn->handshake.io;
+ GUARD(s2n_dh_compute_shared_secret_as_client(&conn->secure.server_dh_params, out, shared_key));
+
+ /* We don't need the server params any more */
+ GUARD(s2n_dh_params_free(&conn->secure.server_dh_params));
+ return 0;
+}
+
+int s2n_ecdhe_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key)
+{
+ struct s2n_stuffer *out = &conn->handshake.io;
+ GUARD(s2n_ecc_evp_compute_shared_secret_as_client(&conn->secure.server_ecc_evp_params, out, shared_key));
+
+ /* We don't need the server params any more */
+ GUARD(s2n_ecc_evp_params_free(&conn->secure.server_ecc_evp_params));
+ return 0;
+}
+
+int s2n_rsa_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key)
+{
+ uint8_t client_hello_protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN];
+ uint8_t legacy_client_hello_protocol_version = get_client_hello_protocol_version(conn);
+ client_hello_protocol_version[0] = legacy_client_hello_protocol_version / 10;
+ client_hello_protocol_version[1] = legacy_client_hello_protocol_version % 10;
+
+ shared_key->data = conn->secure.rsa_premaster_secret;
+ shared_key->size = S2N_TLS_SECRET_LEN;
+
+ GUARD_AS_POSIX(s2n_get_private_random_data(shared_key));
+
+ /* Over-write the first two bytes with the client hello version, per RFC2246/RFC4346/RFC5246 7.4.7.1.
+ * The latest version supported by client (as seen from the the client hello version) are <= TLS1.2
+ * for all clients, because TLS 1.3 clients freezes the TLS1.2 legacy version in client hello.
+ */
+ memcpy_check(conn->secure.rsa_premaster_secret, client_hello_protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN);
+
+ int encrypted_size = s2n_pkey_size(&conn->secure.server_public_key);
+ S2N_ERROR_IF(encrypted_size < 0 || encrypted_size > 0xffff, S2N_ERR_SIZE_MISMATCH);
+
+ if (conn->actual_protocol_version > S2N_SSLv3) {
+ GUARD(s2n_stuffer_write_uint16(&conn->handshake.io, encrypted_size));
+ }
+
+ struct s2n_blob encrypted = {0};
+ encrypted.data = s2n_stuffer_raw_write(&conn->handshake.io, encrypted_size);
+ encrypted.size = encrypted_size;
+ notnull_check(encrypted.data);
+
+ /* Encrypt the secret and send it on */
+ GUARD(s2n_pkey_encrypt(&conn->secure.server_public_key, shared_key, &encrypted));
+
+ /* We don't need the key any more, so free it */
+ GUARD(s2n_pkey_free(&conn->secure.server_public_key));
+ return 0;
+}
+
+int s2n_kem_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key)
+{
+ /* s2n_kem_send_ciphertext() writes the KEM shared secret directly to
+ * conn->secure.kem_params. However, the calling function
+ * likely expects *shared_key to point to the shared secret. We
+ * can't reassign *shared_key to point to kem_params.shared_secret,
+ * because that would require us to take struct s2n_blob **shared_key
+ * as the argument, but we can't (easily) change the function signature
+ * because it has to be consistent with what is defined in s2n_kex.
+ *
+ * So, we assert that the caller already has *shared_key pointing
+ * to kem_params.shared_secret. */
+ notnull_check(shared_key);
+ S2N_ERROR_IF(shared_key != &(conn->secure.kem_params.shared_secret), S2N_ERR_SAFETY);
+
+ GUARD(s2n_kem_send_ciphertext(&(conn->handshake.io), &(conn->secure.kem_params)));
+
+ return 0;
+}
+
+int s2n_hybrid_client_key_send(struct s2n_connection *conn, struct s2n_blob *combined_shared_key)
+{
+ return s2n_hybrid_client_action(conn, combined_shared_key, &s2n_kex_client_key_send, &conn->handshake.io.write_cursor,
+ s2n_stuffer_raw_write);
+}
+
+int s2n_client_key_send(struct s2n_connection *conn)
+{
+ const struct s2n_kex *key_exchange = conn->secure.cipher_suite->key_exchange_alg;
+ struct s2n_blob shared_key = {0};
+
+ GUARD(s2n_kex_client_key_send(key_exchange, conn, &shared_key));
+
+ GUARD(s2n_calculate_keys(conn, &shared_key));
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.h b/contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.h
index ee37cb4a8f..5389988dcc 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.h
@@ -1,35 +1,35 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/s2n_connection.h"
-#include "utils/s2n_blob.h"
-
-int s2n_dhe_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key);
-int s2n_ecdhe_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key);
-int s2n_rsa_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key);
-int s2n_kem_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key);
-int s2n_hybrid_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key);
-
-int s2n_dhe_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key);
-int s2n_ecdhe_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key);
-int s2n_rsa_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key);
-int s2n_kem_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key);
-int s2n_hybrid_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key);
-
-int s2n_dhe_client_key_external(struct s2n_connection * conn, struct s2n_blob* shared_key);
-int s2n_ecdhe_client_key_external(struct s2n_connection * conn, struct s2n_blob* shared_key);
-int s2n_rsa_client_key_external(struct s2n_connection *conn, struct s2n_blob *shared_key);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/s2n_connection.h"
+#include "utils/s2n_blob.h"
+
+int s2n_dhe_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key);
+int s2n_ecdhe_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key);
+int s2n_rsa_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key);
+int s2n_kem_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key);
+int s2n_hybrid_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key);
+
+int s2n_dhe_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key);
+int s2n_ecdhe_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key);
+int s2n_rsa_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key);
+int s2n_kem_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key);
+int s2n_hybrid_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key);
+
+int s2n_dhe_client_key_external(struct s2n_connection * conn, struct s2n_blob* shared_key);
+int s2n_ecdhe_client_key_external(struct s2n_connection * conn, struct s2n_blob* shared_key);
+int s2n_rsa_client_key_external(struct s2n_connection *conn, struct s2n_blob *shared_key);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_config.c b/contrib/restricted/aws/s2n/tls/s2n_config.c
index dc674d2803..51a974f8c7 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_config.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_config.c
@@ -1,860 +1,860 @@
-/*
- * 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 <strings.h>
-#include <time.h>
-
-#include "error/s2n_errno.h"
-
-#include "crypto/s2n_certificate.h"
-#include "crypto/s2n_fips.h"
-
-#include "tls/s2n_cipher_preferences.h"
-#include "tls/s2n_security_policies.h"
-#include "tls/s2n_tls13.h"
-#include "utils/s2n_safety.h"
-#include "crypto/s2n_hkdf.h"
-#include "utils/s2n_map.h"
-#include "utils/s2n_blob.h"
-
-#if defined(CLOCK_MONOTONIC_RAW)
-#define S2N_CLOCK_HW CLOCK_MONOTONIC_RAW
-#else
-#define S2N_CLOCK_HW CLOCK_MONOTONIC
-#endif
-
-#define S2N_CLOCK_SYS CLOCK_REALTIME
-
-static int monotonic_clock(void *data, uint64_t *nanoseconds)
-{
- struct timespec current_time = {0};
-
- GUARD(clock_gettime(S2N_CLOCK_HW, &current_time));
-
- *nanoseconds = (uint64_t)current_time.tv_sec * 1000000000ull;
- *nanoseconds += current_time.tv_nsec;
-
- return 0;
-}
-
-static int wall_clock(void *data, uint64_t *nanoseconds)
-{
- struct timespec current_time = {0};
-
- GUARD(clock_gettime(S2N_CLOCK_SYS, &current_time));
-
- *nanoseconds = (uint64_t)current_time.tv_sec * 1000000000ull;
- *nanoseconds += current_time.tv_nsec;
-
- return 0;
-}
-
-static struct s2n_config s2n_default_config = {0};
-static struct s2n_config s2n_default_fips_config = {0};
-static struct s2n_config s2n_default_tls13_config = {0};
-
-static int s2n_config_setup_default(struct s2n_config *config)
-{
- GUARD(s2n_config_set_cipher_preferences(config, "default"));
- return S2N_SUCCESS;
-}
-
-static int s2n_config_setup_tls13(struct s2n_config *config)
-{
- GUARD(s2n_config_set_cipher_preferences(config, "default_tls13"));
- return S2N_SUCCESS;
-}
-
-static int s2n_config_setup_fips(struct s2n_config *config)
-{
- GUARD(s2n_config_set_cipher_preferences(config, "default_fips"));
- return S2N_SUCCESS;
-}
-
-static int s2n_config_init(struct s2n_config *config)
-{
- config->cert_allocated = 0;
- config->dhparams = NULL;
- memset(&config->application_protocols, 0, sizeof(config->application_protocols));
- config->status_request_type = S2N_STATUS_REQUEST_NONE;
- config->wall_clock = wall_clock;
- config->monotonic_clock = monotonic_clock;
- config->verify_host = NULL;
- config->data_for_verify_host = NULL;
- config->client_hello_cb = NULL;
- config->client_hello_cb_ctx = NULL;
- config->cache_store = NULL;
- config->cache_store_data = NULL;
- config->cache_retrieve = NULL;
- config->cache_retrieve_data = NULL;
- config->cache_delete = NULL;
- config->cache_delete_data = NULL;
- config->ct_type = S2N_CT_SUPPORT_NONE;
- config->mfl_code = S2N_TLS_MAX_FRAG_LEN_EXT_NONE;
- config->alert_behavior = S2N_ALERT_FAIL_ON_WARNINGS;
- config->accept_mfl = 0;
- config->session_state_lifetime_in_nanos = S2N_STATE_LIFETIME_IN_NANOS;
- config->use_tickets = 0;
- config->use_session_cache = 0;
- config->ticket_keys = NULL;
- config->ticket_key_hashes = NULL;
- config->encrypt_decrypt_key_lifetime_in_nanos = S2N_TICKET_ENCRYPT_DECRYPT_KEY_LIFETIME_IN_NANOS;
- config->decrypt_key_lifetime_in_nanos = S2N_TICKET_DECRYPT_KEY_LIFETIME_IN_NANOS;
- config->quic_enabled = 0;
-
- /* By default, only the client will authenticate the Server's Certificate. The Server does not request or
- * authenticate any client certificates. */
- config->client_cert_auth_type = S2N_CERT_AUTH_NONE;
- config->check_ocsp = 1;
- config->disable_x509_validation = 0;
- config->max_verify_cert_chain_depth = 0;
- config->max_verify_cert_chain_depth_set = 0;
- config->cert_tiebreak_cb = NULL;
- config->async_pkey_cb = NULL;
- config->cert_req_dss_legacy_compat_enabled = 0;
-
- GUARD(s2n_config_setup_default(config));
- if (s2n_use_default_tls13_config()) {
- GUARD(s2n_config_setup_tls13(config));
- } else if (s2n_is_in_fips_mode()) {
- GUARD(s2n_config_setup_fips(config));
- }
-
- notnull_check(config->domain_name_to_cert_map = s2n_map_new_with_initial_capacity(1));
- GUARD_AS_POSIX(s2n_map_complete(config->domain_name_to_cert_map));
- memset(&config->default_certs_by_type, 0, sizeof(struct certs_by_type));
- config->default_certs_are_explicit = 0;
-
- s2n_x509_trust_store_init_empty(&config->trust_store);
- s2n_x509_trust_store_from_system_defaults(&config->trust_store);
-
- return 0;
-}
-
-static int s2n_config_cleanup(struct s2n_config *config)
-{
- s2n_x509_trust_store_wipe(&config->trust_store);
- config->check_ocsp = 0;
-
- GUARD(s2n_config_free_session_ticket_keys(config));
- GUARD(s2n_config_free_cert_chain_and_key(config));
- GUARD(s2n_config_free_dhparams(config));
- GUARD(s2n_free(&config->application_protocols));
- GUARD_AS_POSIX(s2n_map_free(config->domain_name_to_cert_map));
-
- return 0;
-}
-
-static int s2n_config_update_domain_name_to_cert_map(struct s2n_config *config,
- struct s2n_blob *name,
- struct s2n_cert_chain_and_key *cert_key_pair)
-{
- notnull_check(config);
- notnull_check(name);
-
- struct s2n_map *domain_name_to_cert_map = config->domain_name_to_cert_map;
- /* s2n_map does not allow zero-size key */
- if (name->size == 0) {
- return 0;
- }
- s2n_pkey_type cert_type = s2n_cert_chain_and_key_get_pkey_type(cert_key_pair);
- struct s2n_blob s2n_map_value = { 0 };
- bool key_found = false;
- GUARD_AS_POSIX(s2n_map_lookup(domain_name_to_cert_map, name, &s2n_map_value, &key_found));
- if (!key_found) {
- struct certs_by_type value = {{ 0 }};
- value.certs[cert_type] = cert_key_pair;
- s2n_map_value.data = (uint8_t *) &value;
- s2n_map_value.size = sizeof(struct certs_by_type);
-
- GUARD_AS_POSIX(s2n_map_unlock(domain_name_to_cert_map));
- GUARD_AS_POSIX(s2n_map_add(domain_name_to_cert_map, name, &s2n_map_value));
- GUARD_AS_POSIX(s2n_map_complete(domain_name_to_cert_map));
- } else {
- struct certs_by_type *value = (void *) s2n_map_value.data;;
- if (value->certs[cert_type] == NULL) {
- value->certs[cert_type] = cert_key_pair;
- } else if (config->cert_tiebreak_cb) {
- /* There's an existing certificate for this (domain_name, auth_method).
- * Run the application's tiebreaking callback to decide which cert should be used.
- * An application may have some context specific logic to resolve ties that are based
- * on factors like trust, expiry, etc.
- */
- struct s2n_cert_chain_and_key *winner = config->cert_tiebreak_cb(
- value->certs[cert_type],
- cert_key_pair,
- name->data,
- name->size);
- if (winner) {
- value->certs[cert_type] = winner;
- }
- }
- }
-
- return 0;
-}
-
-static int s2n_config_build_domain_name_to_cert_map(struct s2n_config *config, struct s2n_cert_chain_and_key *cert_key_pair)
-{
-
- uint32_t cn_len = 0;
- GUARD_AS_POSIX(s2n_array_num_elements(cert_key_pair->cn_names, &cn_len));
- uint32_t san_len = 0;
- GUARD_AS_POSIX(s2n_array_num_elements(cert_key_pair->san_names, &san_len));
-
- if (san_len == 0) {
- for (uint32_t i = 0; i < cn_len; i++) {
- struct s2n_blob *cn_name = NULL;
- GUARD_AS_POSIX(s2n_array_get(cert_key_pair->cn_names, i, (void **)&cn_name));
- GUARD(s2n_config_update_domain_name_to_cert_map(config, cn_name, cert_key_pair));
- }
- } else {
- for (uint32_t i = 0; i < san_len; i++) {
- struct s2n_blob *san_name = NULL;
- GUARD_AS_POSIX(s2n_array_get(cert_key_pair->san_names, i, (void **)&san_name));
- GUARD(s2n_config_update_domain_name_to_cert_map(config, san_name, cert_key_pair));
- }
- }
-
- return 0;
-}
-
-struct s2n_config *s2n_fetch_default_config(void)
-{
- if (s2n_use_default_tls13_config()) {
- return &s2n_default_tls13_config;
- }
- if (s2n_is_in_fips_mode()) {
- return &s2n_default_fips_config;
- }
- return &s2n_default_config;
-}
-
-int s2n_config_set_unsafe_for_testing(struct s2n_config *config)
-{
- S2N_ERROR_IF(!S2N_IN_TEST, S2N_ERR_NOT_IN_UNIT_TEST);
- config->client_cert_auth_type = S2N_CERT_AUTH_NONE;
- config->check_ocsp = 0;
- config->disable_x509_validation = 1;
-
- return S2N_SUCCESS;
-}
-
-int s2n_config_defaults_init(void)
-{
- /* Set up default */
- GUARD(s2n_config_init(&s2n_default_config));
- GUARD(s2n_config_setup_default(&s2n_default_config));
-
- /* Set up fips defaults */
- GUARD(s2n_config_init(&s2n_default_fips_config));
- GUARD(s2n_config_setup_fips(&s2n_default_fips_config));
-
- /* Set up TLS 1.3 defaults */
- GUARD(s2n_config_init(&s2n_default_tls13_config));
- GUARD(s2n_config_setup_tls13(&s2n_default_tls13_config));
-
- return S2N_SUCCESS;
-}
-
-void s2n_wipe_static_configs(void)
-{
- s2n_config_cleanup(&s2n_default_config);
- s2n_config_cleanup(&s2n_default_fips_config);
- s2n_config_cleanup(&s2n_default_tls13_config);
-}
-
-struct s2n_config *s2n_config_new(void)
-{
- struct s2n_blob allocator = {0};
- struct s2n_config *new_config;
-
- GUARD_PTR(s2n_alloc(&allocator, sizeof(struct s2n_config)));
-
- new_config = (struct s2n_config *)(void *)allocator.data;
- if (s2n_config_init(new_config) != S2N_SUCCESS) {
- s2n_free(&allocator);
- return NULL;
- }
-
- return new_config;
-}
-
-static int s2n_config_store_ticket_key_comparator(const void *a, const void *b)
-{
- if (((const struct s2n_ticket_key *) a)->intro_timestamp >= ((const struct s2n_ticket_key *) b)->intro_timestamp) {
- return S2N_GREATER_OR_EQUAL;
- } else {
- return S2N_LESS_THAN;
- }
-}
-
-static int s2n_verify_unique_ticket_key_comparator(const void *a, const void *b)
-{
- return memcmp(a, b, SHA_DIGEST_LENGTH);
-}
-
-int s2n_config_init_session_ticket_keys(struct s2n_config *config)
-{
- if (config->ticket_keys == NULL) {
- notnull_check(config->ticket_keys = s2n_set_new(sizeof(struct s2n_ticket_key), s2n_config_store_ticket_key_comparator));
- }
-
- if (config->ticket_key_hashes == NULL) {
- notnull_check(config->ticket_key_hashes = s2n_set_new(SHA_DIGEST_LENGTH, s2n_verify_unique_ticket_key_comparator));
- }
-
- return 0;
-}
-
-int s2n_config_free_session_ticket_keys(struct s2n_config *config)
-{
- if (config->ticket_keys != NULL) {
- GUARD_AS_POSIX(s2n_set_free_p(&config->ticket_keys));
- }
-
- if (config->ticket_key_hashes != NULL) {
- GUARD_AS_POSIX(s2n_set_free_p(&config->ticket_key_hashes));
- }
-
- return 0;
-}
-
-int s2n_config_free_cert_chain_and_key(struct s2n_config *config)
-{
- /* Free the cert_chain_and_key since the application has no reference
- * to it. This is necessary until s2n_config_add_cert_chain_and_key is deprecated. */
- if (config->cert_allocated) {
- for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) {
- s2n_cert_chain_and_key_free(config->default_certs_by_type.certs[i]);
- }
- }
-
- return 0;
-}
-
-int s2n_config_free_dhparams(struct s2n_config *config)
-{
- if (config->dhparams) {
- GUARD(s2n_dh_params_free(config->dhparams));
- }
-
- GUARD(s2n_free_object((uint8_t **)&config->dhparams, sizeof(struct s2n_dh_params)));
- return 0;
-}
-
-int s2n_config_free(struct s2n_config *config)
-{
- s2n_config_cleanup(config);
-
- GUARD(s2n_free_object((uint8_t **)&config, sizeof(struct s2n_config)));
- return 0;
-}
-
-int s2n_config_get_client_auth_type(struct s2n_config *config, s2n_cert_auth_type *client_auth_type)
-{
- notnull_check(config);
- notnull_check(client_auth_type);
- *client_auth_type = config->client_cert_auth_type;
- return 0;
-}
-
-int s2n_config_set_client_auth_type(struct s2n_config *config, s2n_cert_auth_type client_auth_type)
-{
- notnull_check(config);
- config->client_cert_auth_type = client_auth_type;
- return 0;
-}
-
-int s2n_config_set_ct_support_level(struct s2n_config *config, s2n_ct_support_level type)
-{
- notnull_check(config);
- config->ct_type = type;
-
- return 0;
-}
-
-int s2n_config_set_alert_behavior(struct s2n_config *config, s2n_alert_behavior alert_behavior)
-{
- notnull_check(config);
-
- switch (alert_behavior) {
- case S2N_ALERT_FAIL_ON_WARNINGS:
- case S2N_ALERT_IGNORE_WARNINGS:
- config->alert_behavior = alert_behavior;
- break;
- default:
- S2N_ERROR(S2N_ERR_INVALID_ARGUMENT);
- }
-
- return 0;
-}
-
-int s2n_config_set_verify_host_callback(struct s2n_config *config, s2n_verify_host_fn verify_host_fn, void *data)
-{
- notnull_check(config);
- config->verify_host = verify_host_fn;
- config->data_for_verify_host = data;
- return 0;
-}
-
-int s2n_config_set_check_stapled_ocsp_response(struct s2n_config *config, uint8_t check_ocsp)
-{
- notnull_check(config);
- S2N_ERROR_IF(check_ocsp && !s2n_x509_ocsp_stapling_supported(), S2N_ERR_OCSP_NOT_SUPPORTED);
- config->check_ocsp = check_ocsp;
- return 0;
-}
-
-int s2n_config_disable_x509_verification(struct s2n_config *config)
-{
- notnull_check(config);
- s2n_x509_trust_store_wipe(&config->trust_store);
- config->disable_x509_validation = 1;
- return 0;
-}
-
-int s2n_config_set_max_cert_chain_depth(struct s2n_config *config, uint16_t max_depth)
-{
- notnull_check(config);
- S2N_ERROR_IF(max_depth == 0, S2N_ERR_INVALID_ARGUMENT);
-
- config->max_verify_cert_chain_depth = max_depth;
- config->max_verify_cert_chain_depth_set = 1;
- return 0;
-}
-
-
-int s2n_config_set_status_request_type(struct s2n_config *config, s2n_status_request_type type)
-{
- S2N_ERROR_IF(type == S2N_STATUS_REQUEST_OCSP && !s2n_x509_ocsp_stapling_supported(), S2N_ERR_OCSP_NOT_SUPPORTED);
-
- notnull_check(config);
- config->status_request_type = type;
-
- return 0;
-}
-
-int s2n_config_add_pem_to_trust_store(struct s2n_config *config, const char *pem)
-{
- notnull_check(config);
- notnull_check(pem);
-
- GUARD(s2n_x509_trust_store_add_pem(&config->trust_store, pem));
-
- return 0;
-}
-
-int s2n_config_set_verification_ca_location(struct s2n_config *config, const char *ca_pem_filename, const char *ca_dir)
-{
- notnull_check(config);
- int err_code = s2n_x509_trust_store_from_ca_file(&config->trust_store, ca_pem_filename, ca_dir);
-
- if (!err_code) {
- config->status_request_type = s2n_x509_ocsp_stapling_supported() ? S2N_STATUS_REQUEST_OCSP : S2N_STATUS_REQUEST_NONE;
- }
-
- return err_code;
-}
-
-/* Deprecated. Superseded by s2n_config_add_cert_chain_and_key_to_store */
-int s2n_config_add_cert_chain_and_key(struct s2n_config *config, const char *cert_chain_pem, const char *private_key_pem)
-{
- struct s2n_cert_chain_and_key *chain_and_key;
- notnull_check(chain_and_key = s2n_cert_chain_and_key_new());
- GUARD(s2n_cert_chain_and_key_load_pem(chain_and_key, cert_chain_pem, private_key_pem));
- GUARD(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key));
- config->cert_allocated = 1;
-
- return 0;
-}
-
-int s2n_config_add_cert_chain_and_key_to_store(struct s2n_config *config, struct s2n_cert_chain_and_key *cert_key_pair)
-{
- notnull_check(config->domain_name_to_cert_map);
- notnull_check(cert_key_pair);
-
- GUARD(s2n_config_build_domain_name_to_cert_map(config, cert_key_pair));
-
- if (!config->default_certs_are_explicit) {
- /* Attempt to auto set default based on ordering. ie: first RSA cert is the default, first ECDSA cert is the
- * default, etc. */
- s2n_pkey_type cert_type = s2n_cert_chain_and_key_get_pkey_type(cert_key_pair);
- if (config->default_certs_by_type.certs[cert_type] == NULL) {
- config->default_certs_by_type.certs[cert_type] = cert_key_pair;
- }
- }
-
- return 0;
-}
-
-int s2n_config_set_async_pkey_callback(struct s2n_config *config, s2n_async_pkey_fn fn)
-{
- notnull_check(config);
-
- config->async_pkey_cb = fn;
-
- return S2N_SUCCESS;
-}
-
-int s2n_config_clear_default_certificates(struct s2n_config *config)
-{
- notnull_check(config);
- for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) {
- config->default_certs_by_type.certs[i] = NULL;
- }
- return 0;
-}
-
-int s2n_config_set_cert_chain_and_key_defaults(struct s2n_config *config,
- struct s2n_cert_chain_and_key **cert_key_pairs,
- uint32_t num_cert_key_pairs)
-{
- notnull_check(config);
- notnull_check(cert_key_pairs);
- S2N_ERROR_IF(num_cert_key_pairs < 1 || num_cert_key_pairs > S2N_CERT_TYPE_COUNT,
- S2N_ERR_NUM_DEFAULT_CERTIFICATES);
-
- /* Validate certs being set before clearing auto-chosen defaults or previously set defaults */
- struct certs_by_type new_defaults = {{ 0 }};
- for (int i = 0; i < num_cert_key_pairs; i++) {
- notnull_check(cert_key_pairs[i]);
- s2n_pkey_type cert_type = s2n_cert_chain_and_key_get_pkey_type(cert_key_pairs[i]);
- S2N_ERROR_IF(new_defaults.certs[cert_type] != NULL, S2N_ERR_MULTIPLE_DEFAULT_CERTIFICATES_PER_AUTH_TYPE);
- new_defaults.certs[cert_type] = cert_key_pairs[i];
- }
-
- GUARD(s2n_config_clear_default_certificates(config));
- for (int i = 0; i < num_cert_key_pairs; i++) {
- s2n_pkey_type cert_type = s2n_cert_chain_and_key_get_pkey_type(cert_key_pairs[i]);
- config->default_certs_by_type.certs[cert_type] = cert_key_pairs[i];
- }
-
- config->default_certs_are_explicit = 1;
- return 0;
-}
-
-int s2n_config_add_dhparams(struct s2n_config *config, const char *dhparams_pem)
-{
- DEFER_CLEANUP(struct s2n_stuffer dhparams_in_stuffer = {0}, s2n_stuffer_free);
- DEFER_CLEANUP(struct s2n_stuffer dhparams_out_stuffer = {0}, s2n_stuffer_free);
- struct s2n_blob dhparams_blob = {0};
- struct s2n_blob mem = {0};
-
- /* Allocate the memory for the chain and key struct */
- GUARD(s2n_alloc(&mem, sizeof(struct s2n_dh_params)));
- config->dhparams = (struct s2n_dh_params *)(void *)mem.data;
-
- if (s2n_stuffer_alloc_ro_from_string(&dhparams_in_stuffer, dhparams_pem) != S2N_SUCCESS) {
- s2n_free(&mem);
- S2N_ERROR_PRESERVE_ERRNO();
- }
- if (s2n_stuffer_growable_alloc(&dhparams_out_stuffer, strlen(dhparams_pem)) != S2N_SUCCESS) {
- s2n_free(&mem);
- S2N_ERROR_PRESERVE_ERRNO();
- }
-
- /* Convert pem to asn1 and asn1 to the private key */
- GUARD(s2n_stuffer_dhparams_from_pem(&dhparams_in_stuffer, &dhparams_out_stuffer));
-
- dhparams_blob.size = s2n_stuffer_data_available(&dhparams_out_stuffer);
- dhparams_blob.data = s2n_stuffer_raw_read(&dhparams_out_stuffer, dhparams_blob.size);
- notnull_check(dhparams_blob.data);
-
- GUARD(s2n_pkcs3_to_dh_params(config->dhparams, &dhparams_blob));
-
- return 0;
-}
-
-extern int s2n_config_set_wall_clock(struct s2n_config *config, s2n_clock_time_nanoseconds clock_fn, void *ctx)
-{
- notnull_check(clock_fn);
-
- config->wall_clock = clock_fn;
- config->sys_clock_ctx = ctx;
-
- return 0;
-}
-
-extern int s2n_config_set_monotonic_clock(struct s2n_config *config, s2n_clock_time_nanoseconds clock_fn, void *ctx)
-{
- notnull_check(clock_fn);
-
- config->monotonic_clock = clock_fn;
- config->monotonic_clock_ctx = ctx;
-
- return 0;
-}
-
-int s2n_config_set_cache_store_callback(struct s2n_config *config, s2n_cache_store_callback cache_store_callback, void *data)
-{
- notnull_check(cache_store_callback);
-
- config->cache_store = cache_store_callback;
- config->cache_store_data = data;
-
- return 0;
-}
-
-int s2n_config_set_cache_retrieve_callback(struct s2n_config *config, s2n_cache_retrieve_callback cache_retrieve_callback, void *data)
-{
- notnull_check(cache_retrieve_callback);
-
- config->cache_retrieve = cache_retrieve_callback;
- config->cache_retrieve_data = data;
-
- return 0;
-}
-
-int s2n_config_set_cache_delete_callback(struct s2n_config *config, s2n_cache_delete_callback cache_delete_callback, void *data)
-{
- notnull_check(cache_delete_callback);
-
- config->cache_delete = cache_delete_callback;
- config->cache_delete_data = data;
-
- return 0;
-}
-
-int s2n_config_set_extension_data(struct s2n_config *config, s2n_tls_extension_type type, const uint8_t *data, uint32_t length)
-{
- notnull_check(config);
-
- if (s2n_config_get_num_default_certs(config) == 0) {
- S2N_ERROR(S2N_ERR_UPDATING_EXTENSION);
- }
- struct s2n_cert_chain_and_key *config_chain_and_key = s2n_config_get_single_default_cert(config);
- notnull_check(config_chain_and_key);
-
- switch (type) {
- case S2N_EXTENSION_CERTIFICATE_TRANSPARENCY:
- {
- GUARD(s2n_cert_chain_and_key_set_sct_list(config_chain_and_key, data, length));
- } break;
- case S2N_EXTENSION_OCSP_STAPLING:
- {
- GUARD(s2n_cert_chain_and_key_set_ocsp_data(config_chain_and_key, data, length));
- } break;
- default:
- S2N_ERROR(S2N_ERR_UNRECOGNIZED_EXTENSION);
- }
-
- return 0;
-}
-
-int s2n_config_set_client_hello_cb(struct s2n_config *config, s2n_client_hello_fn client_hello_cb, void *ctx)
-{
- config->client_hello_cb = client_hello_cb;
- config->client_hello_cb_ctx = ctx;
-
- return 0;
-}
-
-int s2n_config_send_max_fragment_length(struct s2n_config *config, s2n_max_frag_len mfl_code)
-{
- notnull_check(config);
-
- S2N_ERROR_IF(mfl_code > S2N_TLS_MAX_FRAG_LEN_4096, S2N_ERR_INVALID_MAX_FRAG_LEN);
-
- config->mfl_code = mfl_code;
-
- return 0;
-}
-
-int s2n_config_accept_max_fragment_length(struct s2n_config *config)
-{
- notnull_check(config);
-
- config->accept_mfl = 1;
-
- return 0;
-}
-
-int s2n_config_set_session_state_lifetime(struct s2n_config *config,
- uint64_t lifetime_in_secs)
-{
- notnull_check(config);
-
- config->session_state_lifetime_in_nanos = (lifetime_in_secs * ONE_SEC_IN_NANOS);
- return 0;
-}
-
-int s2n_config_set_session_tickets_onoff(struct s2n_config *config, uint8_t enabled)
-{
- notnull_check(config);
-
- if (config->use_tickets == enabled) {
- return 0;
- }
-
- config->use_tickets = enabled;
-
- /* session ticket || session id is enabled */
- if (enabled) {
- GUARD(s2n_config_init_session_ticket_keys(config));
- } else if (!config->use_session_cache) {
- GUARD(s2n_config_free_session_ticket_keys(config));
- }
-
- return 0;
-}
-
-int s2n_config_set_session_cache_onoff(struct s2n_config *config, uint8_t enabled)
-{
- notnull_check(config);
- if (enabled && config->cache_store && config->cache_retrieve && config->cache_delete) {
- GUARD(s2n_config_init_session_ticket_keys(config));
- config->use_session_cache = 1;
- }
- else {
- if (!config->use_tickets) {
- GUARD(s2n_config_free_session_ticket_keys(config));
- }
- config->use_session_cache = 0;
- }
- return 0;
-}
-
-int s2n_config_set_ticket_encrypt_decrypt_key_lifetime(struct s2n_config *config,
- uint64_t lifetime_in_secs)
-{
- notnull_check(config);
-
- config->encrypt_decrypt_key_lifetime_in_nanos = (lifetime_in_secs * ONE_SEC_IN_NANOS);
- return 0;
-}
-
-int s2n_config_set_ticket_decrypt_key_lifetime(struct s2n_config *config,
- uint64_t lifetime_in_secs)
-{
- notnull_check(config);
-
- config->decrypt_key_lifetime_in_nanos = (lifetime_in_secs * ONE_SEC_IN_NANOS);
- return 0;
-}
-
-int s2n_config_add_ticket_crypto_key(struct s2n_config *config,
- const uint8_t *name, uint32_t name_len,
- uint8_t *key, uint32_t key_len,
- uint64_t intro_time_in_seconds_from_epoch)
-{
- notnull_check(config);
- notnull_check(name);
- notnull_check(key);
-
- /* both session ticket and session cache encryption/decryption can use the same key mechanism */
- if (!config->use_tickets && !config->use_session_cache) {
- return 0;
- }
-
- GUARD(s2n_config_wipe_expired_ticket_crypto_keys(config, -1));
-
- S2N_ERROR_IF(key_len == 0, S2N_ERR_INVALID_TICKET_KEY_LENGTH);
-
- uint32_t ticket_keys_len = 0;
- GUARD_AS_POSIX(s2n_set_len(config->ticket_keys, &ticket_keys_len));
- S2N_ERROR_IF(ticket_keys_len >= S2N_MAX_TICKET_KEYS, S2N_ERR_TICKET_KEY_LIMIT);
-
- S2N_ERROR_IF(name_len == 0 || name_len > S2N_TICKET_KEY_NAME_LEN || s2n_find_ticket_key(config, name), S2N_ERR_INVALID_TICKET_KEY_NAME_OR_NAME_LENGTH);
-
- uint8_t output_pad[S2N_AES256_KEY_LEN + S2N_TICKET_AAD_IMPLICIT_LEN];
- struct s2n_blob out_key = { .data = output_pad, .size = sizeof(output_pad) };
- struct s2n_blob in_key = { .data = key, .size = key_len };
- struct s2n_blob salt = { .size = 0 };
- struct s2n_blob info = { .size = 0 };
-
- struct s2n_ticket_key *session_ticket_key;
- DEFER_CLEANUP(struct s2n_blob allocator = {0}, s2n_free);
- GUARD(s2n_alloc(&allocator, sizeof(struct s2n_ticket_key)));
- session_ticket_key = (struct s2n_ticket_key *) (void *) allocator.data;
-
- DEFER_CLEANUP(struct s2n_hmac_state hmac = {0}, s2n_hmac_free);
-
- GUARD(s2n_hmac_new(&hmac));
- GUARD(s2n_hkdf(&hmac, S2N_HMAC_SHA256, &salt, &in_key, &info, &out_key));
-
- DEFER_CLEANUP(struct s2n_hash_state hash = {0}, s2n_hash_free);
- uint8_t hash_output[SHA_DIGEST_LENGTH];
-
- GUARD(s2n_hash_new(&hash));
- GUARD(s2n_hash_init(&hash, S2N_HASH_SHA1));
- GUARD(s2n_hash_update(&hash, out_key.data, out_key.size));
- GUARD(s2n_hash_digest(&hash, hash_output, SHA_DIGEST_LENGTH));
-
- GUARD_AS_POSIX(s2n_set_len(config->ticket_keys, &ticket_keys_len));
- if (ticket_keys_len >= S2N_MAX_TICKET_KEY_HASHES) {
- GUARD_AS_POSIX(s2n_set_free_p(&config->ticket_key_hashes));
- notnull_check(config->ticket_key_hashes = s2n_set_new(SHA_DIGEST_LENGTH, s2n_verify_unique_ticket_key_comparator));
- }
-
- /* Insert hash key into a sorted array at known index */
- GUARD_AS_POSIX(s2n_set_add(config->ticket_key_hashes, hash_output));
-
- memcpy_check(session_ticket_key->key_name, name, S2N_TICKET_KEY_NAME_LEN);
- memcpy_check(session_ticket_key->aes_key, out_key.data, S2N_AES256_KEY_LEN);
- out_key.data = output_pad + S2N_AES256_KEY_LEN;
- memcpy_check(session_ticket_key->implicit_aad, out_key.data, S2N_TICKET_AAD_IMPLICIT_LEN);
-
- if (intro_time_in_seconds_from_epoch == 0) {
- uint64_t now;
- GUARD(config->wall_clock(config->sys_clock_ctx, &now));
- session_ticket_key->intro_timestamp = now;
- } else {
- session_ticket_key->intro_timestamp = (intro_time_in_seconds_from_epoch * ONE_SEC_IN_NANOS);
- }
-
- GUARD(s2n_config_store_ticket_key(config, session_ticket_key));
-
- return 0;
-}
-
-int s2n_config_set_cert_tiebreak_callback(struct s2n_config *config, s2n_cert_tiebreak_callback cert_tiebreak_cb)
-{
- config->cert_tiebreak_cb = cert_tiebreak_cb;
- return 0;
-}
-
-struct s2n_cert_chain_and_key *s2n_config_get_single_default_cert(struct s2n_config *config)
-{
- notnull_check_ptr(config);
- struct s2n_cert_chain_and_key *cert = NULL;
-
- for (int i = S2N_CERT_TYPE_COUNT - 1; i >= 0; i--) {
- if (config->default_certs_by_type.certs[i] != NULL) {
- cert = config->default_certs_by_type.certs[i];
- }
- }
- return cert;
-}
-
-int s2n_config_get_num_default_certs(struct s2n_config *config)
-{
- notnull_check(config);
- int num_certs = 0;
- for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) {
- if (config->default_certs_by_type.certs[i] != NULL) {
- num_certs++;
- }
- }
-
- return num_certs;
-}
-
-int s2n_config_enable_cert_req_dss_legacy_compat(struct s2n_config *config)
-{
- notnull_check(config);
- config->cert_req_dss_legacy_compat_enabled = 1;
- return S2N_SUCCESS;
-}
+/*
+ * 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 <strings.h>
+#include <time.h>
+
+#include "error/s2n_errno.h"
+
+#include "crypto/s2n_certificate.h"
+#include "crypto/s2n_fips.h"
+
+#include "tls/s2n_cipher_preferences.h"
+#include "tls/s2n_security_policies.h"
+#include "tls/s2n_tls13.h"
+#include "utils/s2n_safety.h"
+#include "crypto/s2n_hkdf.h"
+#include "utils/s2n_map.h"
+#include "utils/s2n_blob.h"
+
+#if defined(CLOCK_MONOTONIC_RAW)
+#define S2N_CLOCK_HW CLOCK_MONOTONIC_RAW
+#else
+#define S2N_CLOCK_HW CLOCK_MONOTONIC
+#endif
+
+#define S2N_CLOCK_SYS CLOCK_REALTIME
+
+static int monotonic_clock(void *data, uint64_t *nanoseconds)
+{
+ struct timespec current_time = {0};
+
+ GUARD(clock_gettime(S2N_CLOCK_HW, &current_time));
+
+ *nanoseconds = (uint64_t)current_time.tv_sec * 1000000000ull;
+ *nanoseconds += current_time.tv_nsec;
+
+ return 0;
+}
+
+static int wall_clock(void *data, uint64_t *nanoseconds)
+{
+ struct timespec current_time = {0};
+
+ GUARD(clock_gettime(S2N_CLOCK_SYS, &current_time));
+
+ *nanoseconds = (uint64_t)current_time.tv_sec * 1000000000ull;
+ *nanoseconds += current_time.tv_nsec;
+
+ return 0;
+}
+
+static struct s2n_config s2n_default_config = {0};
+static struct s2n_config s2n_default_fips_config = {0};
+static struct s2n_config s2n_default_tls13_config = {0};
+
+static int s2n_config_setup_default(struct s2n_config *config)
+{
+ GUARD(s2n_config_set_cipher_preferences(config, "default"));
+ return S2N_SUCCESS;
+}
+
+static int s2n_config_setup_tls13(struct s2n_config *config)
+{
+ GUARD(s2n_config_set_cipher_preferences(config, "default_tls13"));
+ return S2N_SUCCESS;
+}
+
+static int s2n_config_setup_fips(struct s2n_config *config)
+{
+ GUARD(s2n_config_set_cipher_preferences(config, "default_fips"));
+ return S2N_SUCCESS;
+}
+
+static int s2n_config_init(struct s2n_config *config)
+{
+ config->cert_allocated = 0;
+ config->dhparams = NULL;
+ memset(&config->application_protocols, 0, sizeof(config->application_protocols));
+ config->status_request_type = S2N_STATUS_REQUEST_NONE;
+ config->wall_clock = wall_clock;
+ config->monotonic_clock = monotonic_clock;
+ config->verify_host = NULL;
+ config->data_for_verify_host = NULL;
+ config->client_hello_cb = NULL;
+ config->client_hello_cb_ctx = NULL;
+ config->cache_store = NULL;
+ config->cache_store_data = NULL;
+ config->cache_retrieve = NULL;
+ config->cache_retrieve_data = NULL;
+ config->cache_delete = NULL;
+ config->cache_delete_data = NULL;
+ config->ct_type = S2N_CT_SUPPORT_NONE;
+ config->mfl_code = S2N_TLS_MAX_FRAG_LEN_EXT_NONE;
+ config->alert_behavior = S2N_ALERT_FAIL_ON_WARNINGS;
+ config->accept_mfl = 0;
+ config->session_state_lifetime_in_nanos = S2N_STATE_LIFETIME_IN_NANOS;
+ config->use_tickets = 0;
+ config->use_session_cache = 0;
+ config->ticket_keys = NULL;
+ config->ticket_key_hashes = NULL;
+ config->encrypt_decrypt_key_lifetime_in_nanos = S2N_TICKET_ENCRYPT_DECRYPT_KEY_LIFETIME_IN_NANOS;
+ config->decrypt_key_lifetime_in_nanos = S2N_TICKET_DECRYPT_KEY_LIFETIME_IN_NANOS;
+ config->quic_enabled = 0;
+
+ /* By default, only the client will authenticate the Server's Certificate. The Server does not request or
+ * authenticate any client certificates. */
+ config->client_cert_auth_type = S2N_CERT_AUTH_NONE;
+ config->check_ocsp = 1;
+ config->disable_x509_validation = 0;
+ config->max_verify_cert_chain_depth = 0;
+ config->max_verify_cert_chain_depth_set = 0;
+ config->cert_tiebreak_cb = NULL;
+ config->async_pkey_cb = NULL;
+ config->cert_req_dss_legacy_compat_enabled = 0;
+
+ GUARD(s2n_config_setup_default(config));
+ if (s2n_use_default_tls13_config()) {
+ GUARD(s2n_config_setup_tls13(config));
+ } else if (s2n_is_in_fips_mode()) {
+ GUARD(s2n_config_setup_fips(config));
+ }
+
+ notnull_check(config->domain_name_to_cert_map = s2n_map_new_with_initial_capacity(1));
+ GUARD_AS_POSIX(s2n_map_complete(config->domain_name_to_cert_map));
+ memset(&config->default_certs_by_type, 0, sizeof(struct certs_by_type));
+ config->default_certs_are_explicit = 0;
+
+ s2n_x509_trust_store_init_empty(&config->trust_store);
+ s2n_x509_trust_store_from_system_defaults(&config->trust_store);
+
+ return 0;
+}
+
+static int s2n_config_cleanup(struct s2n_config *config)
+{
+ s2n_x509_trust_store_wipe(&config->trust_store);
+ config->check_ocsp = 0;
+
+ GUARD(s2n_config_free_session_ticket_keys(config));
+ GUARD(s2n_config_free_cert_chain_and_key(config));
+ GUARD(s2n_config_free_dhparams(config));
+ GUARD(s2n_free(&config->application_protocols));
+ GUARD_AS_POSIX(s2n_map_free(config->domain_name_to_cert_map));
+
+ return 0;
+}
+
+static int s2n_config_update_domain_name_to_cert_map(struct s2n_config *config,
+ struct s2n_blob *name,
+ struct s2n_cert_chain_and_key *cert_key_pair)
+{
+ notnull_check(config);
+ notnull_check(name);
+
+ struct s2n_map *domain_name_to_cert_map = config->domain_name_to_cert_map;
+ /* s2n_map does not allow zero-size key */
+ if (name->size == 0) {
+ return 0;
+ }
+ s2n_pkey_type cert_type = s2n_cert_chain_and_key_get_pkey_type(cert_key_pair);
+ struct s2n_blob s2n_map_value = { 0 };
+ bool key_found = false;
+ GUARD_AS_POSIX(s2n_map_lookup(domain_name_to_cert_map, name, &s2n_map_value, &key_found));
+ if (!key_found) {
+ struct certs_by_type value = {{ 0 }};
+ value.certs[cert_type] = cert_key_pair;
+ s2n_map_value.data = (uint8_t *) &value;
+ s2n_map_value.size = sizeof(struct certs_by_type);
+
+ GUARD_AS_POSIX(s2n_map_unlock(domain_name_to_cert_map));
+ GUARD_AS_POSIX(s2n_map_add(domain_name_to_cert_map, name, &s2n_map_value));
+ GUARD_AS_POSIX(s2n_map_complete(domain_name_to_cert_map));
+ } else {
+ struct certs_by_type *value = (void *) s2n_map_value.data;;
+ if (value->certs[cert_type] == NULL) {
+ value->certs[cert_type] = cert_key_pair;
+ } else if (config->cert_tiebreak_cb) {
+ /* There's an existing certificate for this (domain_name, auth_method).
+ * Run the application's tiebreaking callback to decide which cert should be used.
+ * An application may have some context specific logic to resolve ties that are based
+ * on factors like trust, expiry, etc.
+ */
+ struct s2n_cert_chain_and_key *winner = config->cert_tiebreak_cb(
+ value->certs[cert_type],
+ cert_key_pair,
+ name->data,
+ name->size);
+ if (winner) {
+ value->certs[cert_type] = winner;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int s2n_config_build_domain_name_to_cert_map(struct s2n_config *config, struct s2n_cert_chain_and_key *cert_key_pair)
+{
+
+ uint32_t cn_len = 0;
+ GUARD_AS_POSIX(s2n_array_num_elements(cert_key_pair->cn_names, &cn_len));
+ uint32_t san_len = 0;
+ GUARD_AS_POSIX(s2n_array_num_elements(cert_key_pair->san_names, &san_len));
+
+ if (san_len == 0) {
+ for (uint32_t i = 0; i < cn_len; i++) {
+ struct s2n_blob *cn_name = NULL;
+ GUARD_AS_POSIX(s2n_array_get(cert_key_pair->cn_names, i, (void **)&cn_name));
+ GUARD(s2n_config_update_domain_name_to_cert_map(config, cn_name, cert_key_pair));
+ }
+ } else {
+ for (uint32_t i = 0; i < san_len; i++) {
+ struct s2n_blob *san_name = NULL;
+ GUARD_AS_POSIX(s2n_array_get(cert_key_pair->san_names, i, (void **)&san_name));
+ GUARD(s2n_config_update_domain_name_to_cert_map(config, san_name, cert_key_pair));
+ }
+ }
+
+ return 0;
+}
+
+struct s2n_config *s2n_fetch_default_config(void)
+{
+ if (s2n_use_default_tls13_config()) {
+ return &s2n_default_tls13_config;
+ }
+ if (s2n_is_in_fips_mode()) {
+ return &s2n_default_fips_config;
+ }
+ return &s2n_default_config;
+}
+
+int s2n_config_set_unsafe_for_testing(struct s2n_config *config)
+{
+ S2N_ERROR_IF(!S2N_IN_TEST, S2N_ERR_NOT_IN_UNIT_TEST);
+ config->client_cert_auth_type = S2N_CERT_AUTH_NONE;
+ config->check_ocsp = 0;
+ config->disable_x509_validation = 1;
+
+ return S2N_SUCCESS;
+}
+
+int s2n_config_defaults_init(void)
+{
+ /* Set up default */
+ GUARD(s2n_config_init(&s2n_default_config));
+ GUARD(s2n_config_setup_default(&s2n_default_config));
+
+ /* Set up fips defaults */
+ GUARD(s2n_config_init(&s2n_default_fips_config));
+ GUARD(s2n_config_setup_fips(&s2n_default_fips_config));
+
+ /* Set up TLS 1.3 defaults */
+ GUARD(s2n_config_init(&s2n_default_tls13_config));
+ GUARD(s2n_config_setup_tls13(&s2n_default_tls13_config));
+
+ return S2N_SUCCESS;
+}
+
+void s2n_wipe_static_configs(void)
+{
+ s2n_config_cleanup(&s2n_default_config);
+ s2n_config_cleanup(&s2n_default_fips_config);
+ s2n_config_cleanup(&s2n_default_tls13_config);
+}
+
+struct s2n_config *s2n_config_new(void)
+{
+ struct s2n_blob allocator = {0};
+ struct s2n_config *new_config;
+
+ GUARD_PTR(s2n_alloc(&allocator, sizeof(struct s2n_config)));
+
+ new_config = (struct s2n_config *)(void *)allocator.data;
+ if (s2n_config_init(new_config) != S2N_SUCCESS) {
+ s2n_free(&allocator);
+ return NULL;
+ }
+
+ return new_config;
+}
+
+static int s2n_config_store_ticket_key_comparator(const void *a, const void *b)
+{
+ if (((const struct s2n_ticket_key *) a)->intro_timestamp >= ((const struct s2n_ticket_key *) b)->intro_timestamp) {
+ return S2N_GREATER_OR_EQUAL;
+ } else {
+ return S2N_LESS_THAN;
+ }
+}
+
+static int s2n_verify_unique_ticket_key_comparator(const void *a, const void *b)
+{
+ return memcmp(a, b, SHA_DIGEST_LENGTH);
+}
+
+int s2n_config_init_session_ticket_keys(struct s2n_config *config)
+{
+ if (config->ticket_keys == NULL) {
+ notnull_check(config->ticket_keys = s2n_set_new(sizeof(struct s2n_ticket_key), s2n_config_store_ticket_key_comparator));
+ }
+
+ if (config->ticket_key_hashes == NULL) {
+ notnull_check(config->ticket_key_hashes = s2n_set_new(SHA_DIGEST_LENGTH, s2n_verify_unique_ticket_key_comparator));
+ }
+
+ return 0;
+}
+
+int s2n_config_free_session_ticket_keys(struct s2n_config *config)
+{
+ if (config->ticket_keys != NULL) {
+ GUARD_AS_POSIX(s2n_set_free_p(&config->ticket_keys));
+ }
+
+ if (config->ticket_key_hashes != NULL) {
+ GUARD_AS_POSIX(s2n_set_free_p(&config->ticket_key_hashes));
+ }
+
+ return 0;
+}
+
+int s2n_config_free_cert_chain_and_key(struct s2n_config *config)
+{
+ /* Free the cert_chain_and_key since the application has no reference
+ * to it. This is necessary until s2n_config_add_cert_chain_and_key is deprecated. */
+ if (config->cert_allocated) {
+ for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) {
+ s2n_cert_chain_and_key_free(config->default_certs_by_type.certs[i]);
+ }
+ }
+
+ return 0;
+}
+
+int s2n_config_free_dhparams(struct s2n_config *config)
+{
+ if (config->dhparams) {
+ GUARD(s2n_dh_params_free(config->dhparams));
+ }
+
+ GUARD(s2n_free_object((uint8_t **)&config->dhparams, sizeof(struct s2n_dh_params)));
+ return 0;
+}
+
+int s2n_config_free(struct s2n_config *config)
+{
+ s2n_config_cleanup(config);
+
+ GUARD(s2n_free_object((uint8_t **)&config, sizeof(struct s2n_config)));
+ return 0;
+}
+
+int s2n_config_get_client_auth_type(struct s2n_config *config, s2n_cert_auth_type *client_auth_type)
+{
+ notnull_check(config);
+ notnull_check(client_auth_type);
+ *client_auth_type = config->client_cert_auth_type;
+ return 0;
+}
+
+int s2n_config_set_client_auth_type(struct s2n_config *config, s2n_cert_auth_type client_auth_type)
+{
+ notnull_check(config);
+ config->client_cert_auth_type = client_auth_type;
+ return 0;
+}
+
+int s2n_config_set_ct_support_level(struct s2n_config *config, s2n_ct_support_level type)
+{
+ notnull_check(config);
+ config->ct_type = type;
+
+ return 0;
+}
+
+int s2n_config_set_alert_behavior(struct s2n_config *config, s2n_alert_behavior alert_behavior)
+{
+ notnull_check(config);
+
+ switch (alert_behavior) {
+ case S2N_ALERT_FAIL_ON_WARNINGS:
+ case S2N_ALERT_IGNORE_WARNINGS:
+ config->alert_behavior = alert_behavior;
+ break;
+ default:
+ S2N_ERROR(S2N_ERR_INVALID_ARGUMENT);
+ }
+
+ return 0;
+}
+
+int s2n_config_set_verify_host_callback(struct s2n_config *config, s2n_verify_host_fn verify_host_fn, void *data)
+{
+ notnull_check(config);
+ config->verify_host = verify_host_fn;
+ config->data_for_verify_host = data;
+ return 0;
+}
+
+int s2n_config_set_check_stapled_ocsp_response(struct s2n_config *config, uint8_t check_ocsp)
+{
+ notnull_check(config);
+ S2N_ERROR_IF(check_ocsp && !s2n_x509_ocsp_stapling_supported(), S2N_ERR_OCSP_NOT_SUPPORTED);
+ config->check_ocsp = check_ocsp;
+ return 0;
+}
+
+int s2n_config_disable_x509_verification(struct s2n_config *config)
+{
+ notnull_check(config);
+ s2n_x509_trust_store_wipe(&config->trust_store);
+ config->disable_x509_validation = 1;
+ return 0;
+}
+
+int s2n_config_set_max_cert_chain_depth(struct s2n_config *config, uint16_t max_depth)
+{
+ notnull_check(config);
+ S2N_ERROR_IF(max_depth == 0, S2N_ERR_INVALID_ARGUMENT);
+
+ config->max_verify_cert_chain_depth = max_depth;
+ config->max_verify_cert_chain_depth_set = 1;
+ return 0;
+}
+
+
+int s2n_config_set_status_request_type(struct s2n_config *config, s2n_status_request_type type)
+{
+ S2N_ERROR_IF(type == S2N_STATUS_REQUEST_OCSP && !s2n_x509_ocsp_stapling_supported(), S2N_ERR_OCSP_NOT_SUPPORTED);
+
+ notnull_check(config);
+ config->status_request_type = type;
+
+ return 0;
+}
+
+int s2n_config_add_pem_to_trust_store(struct s2n_config *config, const char *pem)
+{
+ notnull_check(config);
+ notnull_check(pem);
+
+ GUARD(s2n_x509_trust_store_add_pem(&config->trust_store, pem));
+
+ return 0;
+}
+
+int s2n_config_set_verification_ca_location(struct s2n_config *config, const char *ca_pem_filename, const char *ca_dir)
+{
+ notnull_check(config);
+ int err_code = s2n_x509_trust_store_from_ca_file(&config->trust_store, ca_pem_filename, ca_dir);
+
+ if (!err_code) {
+ config->status_request_type = s2n_x509_ocsp_stapling_supported() ? S2N_STATUS_REQUEST_OCSP : S2N_STATUS_REQUEST_NONE;
+ }
+
+ return err_code;
+}
+
+/* Deprecated. Superseded by s2n_config_add_cert_chain_and_key_to_store */
+int s2n_config_add_cert_chain_and_key(struct s2n_config *config, const char *cert_chain_pem, const char *private_key_pem)
+{
+ struct s2n_cert_chain_and_key *chain_and_key;
+ notnull_check(chain_and_key = s2n_cert_chain_and_key_new());
+ GUARD(s2n_cert_chain_and_key_load_pem(chain_and_key, cert_chain_pem, private_key_pem));
+ GUARD(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key));
+ config->cert_allocated = 1;
+
+ return 0;
+}
+
+int s2n_config_add_cert_chain_and_key_to_store(struct s2n_config *config, struct s2n_cert_chain_and_key *cert_key_pair)
+{
+ notnull_check(config->domain_name_to_cert_map);
+ notnull_check(cert_key_pair);
+
+ GUARD(s2n_config_build_domain_name_to_cert_map(config, cert_key_pair));
+
+ if (!config->default_certs_are_explicit) {
+ /* Attempt to auto set default based on ordering. ie: first RSA cert is the default, first ECDSA cert is the
+ * default, etc. */
+ s2n_pkey_type cert_type = s2n_cert_chain_and_key_get_pkey_type(cert_key_pair);
+ if (config->default_certs_by_type.certs[cert_type] == NULL) {
+ config->default_certs_by_type.certs[cert_type] = cert_key_pair;
+ }
+ }
+
+ return 0;
+}
+
+int s2n_config_set_async_pkey_callback(struct s2n_config *config, s2n_async_pkey_fn fn)
+{
+ notnull_check(config);
+
+ config->async_pkey_cb = fn;
+
+ return S2N_SUCCESS;
+}
+
+int s2n_config_clear_default_certificates(struct s2n_config *config)
+{
+ notnull_check(config);
+ for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) {
+ config->default_certs_by_type.certs[i] = NULL;
+ }
+ return 0;
+}
+
+int s2n_config_set_cert_chain_and_key_defaults(struct s2n_config *config,
+ struct s2n_cert_chain_and_key **cert_key_pairs,
+ uint32_t num_cert_key_pairs)
+{
+ notnull_check(config);
+ notnull_check(cert_key_pairs);
+ S2N_ERROR_IF(num_cert_key_pairs < 1 || num_cert_key_pairs > S2N_CERT_TYPE_COUNT,
+ S2N_ERR_NUM_DEFAULT_CERTIFICATES);
+
+ /* Validate certs being set before clearing auto-chosen defaults or previously set defaults */
+ struct certs_by_type new_defaults = {{ 0 }};
+ for (int i = 0; i < num_cert_key_pairs; i++) {
+ notnull_check(cert_key_pairs[i]);
+ s2n_pkey_type cert_type = s2n_cert_chain_and_key_get_pkey_type(cert_key_pairs[i]);
+ S2N_ERROR_IF(new_defaults.certs[cert_type] != NULL, S2N_ERR_MULTIPLE_DEFAULT_CERTIFICATES_PER_AUTH_TYPE);
+ new_defaults.certs[cert_type] = cert_key_pairs[i];
+ }
+
+ GUARD(s2n_config_clear_default_certificates(config));
+ for (int i = 0; i < num_cert_key_pairs; i++) {
+ s2n_pkey_type cert_type = s2n_cert_chain_and_key_get_pkey_type(cert_key_pairs[i]);
+ config->default_certs_by_type.certs[cert_type] = cert_key_pairs[i];
+ }
+
+ config->default_certs_are_explicit = 1;
+ return 0;
+}
+
+int s2n_config_add_dhparams(struct s2n_config *config, const char *dhparams_pem)
+{
+ DEFER_CLEANUP(struct s2n_stuffer dhparams_in_stuffer = {0}, s2n_stuffer_free);
+ DEFER_CLEANUP(struct s2n_stuffer dhparams_out_stuffer = {0}, s2n_stuffer_free);
+ struct s2n_blob dhparams_blob = {0};
+ struct s2n_blob mem = {0};
+
+ /* Allocate the memory for the chain and key struct */
+ GUARD(s2n_alloc(&mem, sizeof(struct s2n_dh_params)));
+ config->dhparams = (struct s2n_dh_params *)(void *)mem.data;
+
+ if (s2n_stuffer_alloc_ro_from_string(&dhparams_in_stuffer, dhparams_pem) != S2N_SUCCESS) {
+ s2n_free(&mem);
+ S2N_ERROR_PRESERVE_ERRNO();
+ }
+ if (s2n_stuffer_growable_alloc(&dhparams_out_stuffer, strlen(dhparams_pem)) != S2N_SUCCESS) {
+ s2n_free(&mem);
+ S2N_ERROR_PRESERVE_ERRNO();
+ }
+
+ /* Convert pem to asn1 and asn1 to the private key */
+ GUARD(s2n_stuffer_dhparams_from_pem(&dhparams_in_stuffer, &dhparams_out_stuffer));
+
+ dhparams_blob.size = s2n_stuffer_data_available(&dhparams_out_stuffer);
+ dhparams_blob.data = s2n_stuffer_raw_read(&dhparams_out_stuffer, dhparams_blob.size);
+ notnull_check(dhparams_blob.data);
+
+ GUARD(s2n_pkcs3_to_dh_params(config->dhparams, &dhparams_blob));
+
+ return 0;
+}
+
+extern int s2n_config_set_wall_clock(struct s2n_config *config, s2n_clock_time_nanoseconds clock_fn, void *ctx)
+{
+ notnull_check(clock_fn);
+
+ config->wall_clock = clock_fn;
+ config->sys_clock_ctx = ctx;
+
+ return 0;
+}
+
+extern int s2n_config_set_monotonic_clock(struct s2n_config *config, s2n_clock_time_nanoseconds clock_fn, void *ctx)
+{
+ notnull_check(clock_fn);
+
+ config->monotonic_clock = clock_fn;
+ config->monotonic_clock_ctx = ctx;
+
+ return 0;
+}
+
+int s2n_config_set_cache_store_callback(struct s2n_config *config, s2n_cache_store_callback cache_store_callback, void *data)
+{
+ notnull_check(cache_store_callback);
+
+ config->cache_store = cache_store_callback;
+ config->cache_store_data = data;
+
+ return 0;
+}
+
+int s2n_config_set_cache_retrieve_callback(struct s2n_config *config, s2n_cache_retrieve_callback cache_retrieve_callback, void *data)
+{
+ notnull_check(cache_retrieve_callback);
+
+ config->cache_retrieve = cache_retrieve_callback;
+ config->cache_retrieve_data = data;
+
+ return 0;
+}
+
+int s2n_config_set_cache_delete_callback(struct s2n_config *config, s2n_cache_delete_callback cache_delete_callback, void *data)
+{
+ notnull_check(cache_delete_callback);
+
+ config->cache_delete = cache_delete_callback;
+ config->cache_delete_data = data;
+
+ return 0;
+}
+
+int s2n_config_set_extension_data(struct s2n_config *config, s2n_tls_extension_type type, const uint8_t *data, uint32_t length)
+{
+ notnull_check(config);
+
+ if (s2n_config_get_num_default_certs(config) == 0) {
+ S2N_ERROR(S2N_ERR_UPDATING_EXTENSION);
+ }
+ struct s2n_cert_chain_and_key *config_chain_and_key = s2n_config_get_single_default_cert(config);
+ notnull_check(config_chain_and_key);
+
+ switch (type) {
+ case S2N_EXTENSION_CERTIFICATE_TRANSPARENCY:
+ {
+ GUARD(s2n_cert_chain_and_key_set_sct_list(config_chain_and_key, data, length));
+ } break;
+ case S2N_EXTENSION_OCSP_STAPLING:
+ {
+ GUARD(s2n_cert_chain_and_key_set_ocsp_data(config_chain_and_key, data, length));
+ } break;
+ default:
+ S2N_ERROR(S2N_ERR_UNRECOGNIZED_EXTENSION);
+ }
+
+ return 0;
+}
+
+int s2n_config_set_client_hello_cb(struct s2n_config *config, s2n_client_hello_fn client_hello_cb, void *ctx)
+{
+ config->client_hello_cb = client_hello_cb;
+ config->client_hello_cb_ctx = ctx;
+
+ return 0;
+}
+
+int s2n_config_send_max_fragment_length(struct s2n_config *config, s2n_max_frag_len mfl_code)
+{
+ notnull_check(config);
+
+ S2N_ERROR_IF(mfl_code > S2N_TLS_MAX_FRAG_LEN_4096, S2N_ERR_INVALID_MAX_FRAG_LEN);
+
+ config->mfl_code = mfl_code;
+
+ return 0;
+}
+
+int s2n_config_accept_max_fragment_length(struct s2n_config *config)
+{
+ notnull_check(config);
+
+ config->accept_mfl = 1;
+
+ return 0;
+}
+
+int s2n_config_set_session_state_lifetime(struct s2n_config *config,
+ uint64_t lifetime_in_secs)
+{
+ notnull_check(config);
+
+ config->session_state_lifetime_in_nanos = (lifetime_in_secs * ONE_SEC_IN_NANOS);
+ return 0;
+}
+
+int s2n_config_set_session_tickets_onoff(struct s2n_config *config, uint8_t enabled)
+{
+ notnull_check(config);
+
+ if (config->use_tickets == enabled) {
+ return 0;
+ }
+
+ config->use_tickets = enabled;
+
+ /* session ticket || session id is enabled */
+ if (enabled) {
+ GUARD(s2n_config_init_session_ticket_keys(config));
+ } else if (!config->use_session_cache) {
+ GUARD(s2n_config_free_session_ticket_keys(config));
+ }
+
+ return 0;
+}
+
+int s2n_config_set_session_cache_onoff(struct s2n_config *config, uint8_t enabled)
+{
+ notnull_check(config);
+ if (enabled && config->cache_store && config->cache_retrieve && config->cache_delete) {
+ GUARD(s2n_config_init_session_ticket_keys(config));
+ config->use_session_cache = 1;
+ }
+ else {
+ if (!config->use_tickets) {
+ GUARD(s2n_config_free_session_ticket_keys(config));
+ }
+ config->use_session_cache = 0;
+ }
+ return 0;
+}
+
+int s2n_config_set_ticket_encrypt_decrypt_key_lifetime(struct s2n_config *config,
+ uint64_t lifetime_in_secs)
+{
+ notnull_check(config);
+
+ config->encrypt_decrypt_key_lifetime_in_nanos = (lifetime_in_secs * ONE_SEC_IN_NANOS);
+ return 0;
+}
+
+int s2n_config_set_ticket_decrypt_key_lifetime(struct s2n_config *config,
+ uint64_t lifetime_in_secs)
+{
+ notnull_check(config);
+
+ config->decrypt_key_lifetime_in_nanos = (lifetime_in_secs * ONE_SEC_IN_NANOS);
+ return 0;
+}
+
+int s2n_config_add_ticket_crypto_key(struct s2n_config *config,
+ const uint8_t *name, uint32_t name_len,
+ uint8_t *key, uint32_t key_len,
+ uint64_t intro_time_in_seconds_from_epoch)
+{
+ notnull_check(config);
+ notnull_check(name);
+ notnull_check(key);
+
+ /* both session ticket and session cache encryption/decryption can use the same key mechanism */
+ if (!config->use_tickets && !config->use_session_cache) {
+ return 0;
+ }
+
+ GUARD(s2n_config_wipe_expired_ticket_crypto_keys(config, -1));
+
+ S2N_ERROR_IF(key_len == 0, S2N_ERR_INVALID_TICKET_KEY_LENGTH);
+
+ uint32_t ticket_keys_len = 0;
+ GUARD_AS_POSIX(s2n_set_len(config->ticket_keys, &ticket_keys_len));
+ S2N_ERROR_IF(ticket_keys_len >= S2N_MAX_TICKET_KEYS, S2N_ERR_TICKET_KEY_LIMIT);
+
+ S2N_ERROR_IF(name_len == 0 || name_len > S2N_TICKET_KEY_NAME_LEN || s2n_find_ticket_key(config, name), S2N_ERR_INVALID_TICKET_KEY_NAME_OR_NAME_LENGTH);
+
+ uint8_t output_pad[S2N_AES256_KEY_LEN + S2N_TICKET_AAD_IMPLICIT_LEN];
+ struct s2n_blob out_key = { .data = output_pad, .size = sizeof(output_pad) };
+ struct s2n_blob in_key = { .data = key, .size = key_len };
+ struct s2n_blob salt = { .size = 0 };
+ struct s2n_blob info = { .size = 0 };
+
+ struct s2n_ticket_key *session_ticket_key;
+ DEFER_CLEANUP(struct s2n_blob allocator = {0}, s2n_free);
+ GUARD(s2n_alloc(&allocator, sizeof(struct s2n_ticket_key)));
+ session_ticket_key = (struct s2n_ticket_key *) (void *) allocator.data;
+
+ DEFER_CLEANUP(struct s2n_hmac_state hmac = {0}, s2n_hmac_free);
+
+ GUARD(s2n_hmac_new(&hmac));
+ GUARD(s2n_hkdf(&hmac, S2N_HMAC_SHA256, &salt, &in_key, &info, &out_key));
+
+ DEFER_CLEANUP(struct s2n_hash_state hash = {0}, s2n_hash_free);
+ uint8_t hash_output[SHA_DIGEST_LENGTH];
+
+ GUARD(s2n_hash_new(&hash));
+ GUARD(s2n_hash_init(&hash, S2N_HASH_SHA1));
+ GUARD(s2n_hash_update(&hash, out_key.data, out_key.size));
+ GUARD(s2n_hash_digest(&hash, hash_output, SHA_DIGEST_LENGTH));
+
+ GUARD_AS_POSIX(s2n_set_len(config->ticket_keys, &ticket_keys_len));
+ if (ticket_keys_len >= S2N_MAX_TICKET_KEY_HASHES) {
+ GUARD_AS_POSIX(s2n_set_free_p(&config->ticket_key_hashes));
+ notnull_check(config->ticket_key_hashes = s2n_set_new(SHA_DIGEST_LENGTH, s2n_verify_unique_ticket_key_comparator));
+ }
+
+ /* Insert hash key into a sorted array at known index */
+ GUARD_AS_POSIX(s2n_set_add(config->ticket_key_hashes, hash_output));
+
+ memcpy_check(session_ticket_key->key_name, name, S2N_TICKET_KEY_NAME_LEN);
+ memcpy_check(session_ticket_key->aes_key, out_key.data, S2N_AES256_KEY_LEN);
+ out_key.data = output_pad + S2N_AES256_KEY_LEN;
+ memcpy_check(session_ticket_key->implicit_aad, out_key.data, S2N_TICKET_AAD_IMPLICIT_LEN);
+
+ if (intro_time_in_seconds_from_epoch == 0) {
+ uint64_t now;
+ GUARD(config->wall_clock(config->sys_clock_ctx, &now));
+ session_ticket_key->intro_timestamp = now;
+ } else {
+ session_ticket_key->intro_timestamp = (intro_time_in_seconds_from_epoch * ONE_SEC_IN_NANOS);
+ }
+
+ GUARD(s2n_config_store_ticket_key(config, session_ticket_key));
+
+ return 0;
+}
+
+int s2n_config_set_cert_tiebreak_callback(struct s2n_config *config, s2n_cert_tiebreak_callback cert_tiebreak_cb)
+{
+ config->cert_tiebreak_cb = cert_tiebreak_cb;
+ return 0;
+}
+
+struct s2n_cert_chain_and_key *s2n_config_get_single_default_cert(struct s2n_config *config)
+{
+ notnull_check_ptr(config);
+ struct s2n_cert_chain_and_key *cert = NULL;
+
+ for (int i = S2N_CERT_TYPE_COUNT - 1; i >= 0; i--) {
+ if (config->default_certs_by_type.certs[i] != NULL) {
+ cert = config->default_certs_by_type.certs[i];
+ }
+ }
+ return cert;
+}
+
+int s2n_config_get_num_default_certs(struct s2n_config *config)
+{
+ notnull_check(config);
+ int num_certs = 0;
+ for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) {
+ if (config->default_certs_by_type.certs[i] != NULL) {
+ num_certs++;
+ }
+ }
+
+ return num_certs;
+}
+
+int s2n_config_enable_cert_req_dss_legacy_compat(struct s2n_config *config)
+{
+ notnull_check(config);
+ config->cert_req_dss_legacy_compat_enabled = 1;
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_config.h b/contrib/restricted/aws/s2n/tls/s2n_config.h
index 83985dc7e8..be8baf1da1 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_config.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_config.h
@@ -1,115 +1,115 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "api/s2n.h"
-#include "crypto/s2n_certificate.h"
-#include "crypto/s2n_dhe.h"
-#include "tls/s2n_resume.h"
-#include "tls/s2n_x509_validator.h"
-#include "utils/s2n_blob.h"
-#include "utils/s2n_set.h"
-
-#define S2N_MAX_TICKET_KEYS 48
-#define S2N_MAX_TICKET_KEY_HASHES 500 /* 10KB */
-
-struct s2n_cipher_preferences;
-
-struct s2n_config {
- unsigned cert_allocated:1;
- unsigned default_certs_are_explicit:1;
- unsigned use_tickets:1;
- unsigned use_session_cache:1;
- /* if this is FALSE, server will ignore client's Maximum Fragment Length request */
- unsigned accept_mfl:1;
- unsigned check_ocsp:1;
- unsigned disable_x509_validation:1;
- unsigned max_verify_cert_chain_depth_set:1;
- /* Whether a connection can be used by a QUIC implementation.
- * See s2n_quic_support.h */
- unsigned quic_enabled:1;
- /* Whether to add dss cert type during a server certificate request.
- * See https://github.com/awslabs/s2n/blob/main/docs/USAGE-GUIDE.md */
- unsigned cert_req_dss_legacy_compat_enabled:1;
-
- struct s2n_dh_params *dhparams;
- /* Needed until we can deprecate s2n_config_add_cert_chain_and_key. This is
- * used to release memory allocated only in the deprecated API that the application
- * does not have a reference to. */
- struct s2n_map *domain_name_to_cert_map;
- struct certs_by_type default_certs_by_type;
- struct s2n_blob application_protocols;
- s2n_status_request_type status_request_type;
- s2n_clock_time_nanoseconds wall_clock;
- s2n_clock_time_nanoseconds monotonic_clock;
-
- const struct s2n_security_policy *security_policy;
-
- void *sys_clock_ctx;
- void *monotonic_clock_ctx;
-
- s2n_client_hello_fn *client_hello_cb;
- void *client_hello_cb_ctx;
-
- uint64_t session_state_lifetime_in_nanos;
-
- struct s2n_set *ticket_keys;
- struct s2n_set *ticket_key_hashes;
- uint64_t encrypt_decrypt_key_lifetime_in_nanos;
- uint64_t decrypt_key_lifetime_in_nanos;
-
- /* If session cache is being used, these must all be set */
- s2n_cache_store_callback cache_store;
- void *cache_store_data;
-
- s2n_cache_retrieve_callback cache_retrieve;
- void *cache_retrieve_data;
-
- s2n_cache_delete_callback cache_delete;
- void *cache_delete_data;
-
- s2n_ct_support_level ct_type;
-
- s2n_cert_auth_type client_cert_auth_type;
-
- s2n_alert_behavior alert_behavior;
-
- /* Return TRUE if the host should be trusted, If FALSE this will likely be called again for every host/alternative name
- * in the certificate. If any respond TRUE. If none return TRUE, the cert will be considered untrusted. */
- uint8_t (*verify_host)(const char *host_name, size_t host_name_len, void *data);
- void *data_for_verify_host;
-
- /* Application supplied callback to resolve domain name conflicts when loading certs. */
- s2n_cert_tiebreak_callback cert_tiebreak_cb;
-
- uint8_t mfl_code;
-
- struct s2n_x509_trust_store trust_store;
- uint16_t max_verify_cert_chain_depth;
-
- s2n_async_pkey_fn async_pkey_cb;
-};
-
-int s2n_config_defaults_init(void);
-extern struct s2n_config *s2n_fetch_default_config(void);
-int s2n_config_set_unsafe_for_testing(struct s2n_config *config);
-
-int s2n_config_init_session_ticket_keys(struct s2n_config *config);
-int s2n_config_free_session_ticket_keys(struct s2n_config *config);
-
-void s2n_wipe_static_configs(void);
-extern struct s2n_cert_chain_and_key *s2n_config_get_single_default_cert(struct s2n_config *config);
-int s2n_config_get_num_default_certs(struct s2n_config *config);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "api/s2n.h"
+#include "crypto/s2n_certificate.h"
+#include "crypto/s2n_dhe.h"
+#include "tls/s2n_resume.h"
+#include "tls/s2n_x509_validator.h"
+#include "utils/s2n_blob.h"
+#include "utils/s2n_set.h"
+
+#define S2N_MAX_TICKET_KEYS 48
+#define S2N_MAX_TICKET_KEY_HASHES 500 /* 10KB */
+
+struct s2n_cipher_preferences;
+
+struct s2n_config {
+ unsigned cert_allocated:1;
+ unsigned default_certs_are_explicit:1;
+ unsigned use_tickets:1;
+ unsigned use_session_cache:1;
+ /* if this is FALSE, server will ignore client's Maximum Fragment Length request */
+ unsigned accept_mfl:1;
+ unsigned check_ocsp:1;
+ unsigned disable_x509_validation:1;
+ unsigned max_verify_cert_chain_depth_set:1;
+ /* Whether a connection can be used by a QUIC implementation.
+ * See s2n_quic_support.h */
+ unsigned quic_enabled:1;
+ /* Whether to add dss cert type during a server certificate request.
+ * See https://github.com/awslabs/s2n/blob/main/docs/USAGE-GUIDE.md */
+ unsigned cert_req_dss_legacy_compat_enabled:1;
+
+ struct s2n_dh_params *dhparams;
+ /* Needed until we can deprecate s2n_config_add_cert_chain_and_key. This is
+ * used to release memory allocated only in the deprecated API that the application
+ * does not have a reference to. */
+ struct s2n_map *domain_name_to_cert_map;
+ struct certs_by_type default_certs_by_type;
+ struct s2n_blob application_protocols;
+ s2n_status_request_type status_request_type;
+ s2n_clock_time_nanoseconds wall_clock;
+ s2n_clock_time_nanoseconds monotonic_clock;
+
+ const struct s2n_security_policy *security_policy;
+
+ void *sys_clock_ctx;
+ void *monotonic_clock_ctx;
+
+ s2n_client_hello_fn *client_hello_cb;
+ void *client_hello_cb_ctx;
+
+ uint64_t session_state_lifetime_in_nanos;
+
+ struct s2n_set *ticket_keys;
+ struct s2n_set *ticket_key_hashes;
+ uint64_t encrypt_decrypt_key_lifetime_in_nanos;
+ uint64_t decrypt_key_lifetime_in_nanos;
+
+ /* If session cache is being used, these must all be set */
+ s2n_cache_store_callback cache_store;
+ void *cache_store_data;
+
+ s2n_cache_retrieve_callback cache_retrieve;
+ void *cache_retrieve_data;
+
+ s2n_cache_delete_callback cache_delete;
+ void *cache_delete_data;
+
+ s2n_ct_support_level ct_type;
+
+ s2n_cert_auth_type client_cert_auth_type;
+
+ s2n_alert_behavior alert_behavior;
+
+ /* Return TRUE if the host should be trusted, If FALSE this will likely be called again for every host/alternative name
+ * in the certificate. If any respond TRUE. If none return TRUE, the cert will be considered untrusted. */
+ uint8_t (*verify_host)(const char *host_name, size_t host_name_len, void *data);
+ void *data_for_verify_host;
+
+ /* Application supplied callback to resolve domain name conflicts when loading certs. */
+ s2n_cert_tiebreak_callback cert_tiebreak_cb;
+
+ uint8_t mfl_code;
+
+ struct s2n_x509_trust_store trust_store;
+ uint16_t max_verify_cert_chain_depth;
+
+ s2n_async_pkey_fn async_pkey_cb;
+};
+
+int s2n_config_defaults_init(void);
+extern struct s2n_config *s2n_fetch_default_config(void);
+int s2n_config_set_unsafe_for_testing(struct s2n_config *config);
+
+int s2n_config_init_session_ticket_keys(struct s2n_config *config);
+int s2n_config_free_session_ticket_keys(struct s2n_config *config);
+
+void s2n_wipe_static_configs(void);
+extern struct s2n_cert_chain_and_key *s2n_config_get_single_default_cert(struct s2n_config *config);
+int s2n_config_get_num_default_certs(struct s2n_config *config);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_connection.c b/contrib/restricted/aws/s2n/tls/s2n_connection.c
index 89aa144750..ae23da2439 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_connection.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_connection.c
@@ -1,1354 +1,1354 @@
-/*
- * 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 <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <s2n.h>
-#include <stdbool.h>
-
-#include "crypto/s2n_fips.h"
-
-#include "error/s2n_errno.h"
-
-#include "tls/extensions/s2n_client_server_name.h"
-#include "tls/s2n_alerts.h"
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_connection_evp_digests.h"
-#include "tls/s2n_handshake.h"
-#include "tls/s2n_kem.h"
-#include "tls/s2n_prf.h"
-#include "tls/s2n_record.h"
-#include "tls/s2n_resume.h"
-#include "tls/s2n_security_policies.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls_parameters.h"
-
-#include "crypto/s2n_certificate.h"
-#include "crypto/s2n_cipher.h"
-
-#include "utils/s2n_blob.h"
-#include "utils/s2n_compiler.h"
-#include "utils/s2n_mem.h"
-#include "utils/s2n_random.h"
-#include "utils/s2n_safety.h"
-#include "utils/s2n_socket.h"
-#include "utils/s2n_timer.h"
-
-#define S2N_SET_KEY_SHARE_LIST_EMPTY(keyshares) (keyshares |= 1)
-#define S2N_SET_KEY_SHARE_REQUEST(keyshares, i) (keyshares |= ( 1 << ( i + 1 )))
-
-static int s2n_connection_new_hashes(struct s2n_connection *conn)
-{
- /* Allocate long-term memory for the Connection's hash states */
- GUARD(s2n_hash_new(&conn->handshake.md5));
- GUARD(s2n_hash_new(&conn->handshake.sha1));
- GUARD(s2n_hash_new(&conn->handshake.sha224));
- GUARD(s2n_hash_new(&conn->handshake.sha256));
- GUARD(s2n_hash_new(&conn->handshake.sha384));
- GUARD(s2n_hash_new(&conn->handshake.sha512));
- GUARD(s2n_hash_new(&conn->handshake.md5_sha1));
- GUARD(s2n_hash_new(&conn->handshake.ccv_hash_copy));
- GUARD(s2n_hash_new(&conn->handshake.prf_md5_hash_copy));
- GUARD(s2n_hash_new(&conn->handshake.prf_sha1_hash_copy));
- GUARD(s2n_hash_new(&conn->handshake.prf_tls12_hash_copy));
- GUARD(s2n_hash_new(&conn->handshake.server_finished_copy));
- GUARD(s2n_hash_new(&conn->prf_space.ssl3.md5));
- GUARD(s2n_hash_new(&conn->prf_space.ssl3.sha1));
- GUARD(s2n_hash_new(&conn->initial.signature_hash));
- GUARD(s2n_hash_new(&conn->secure.signature_hash));
-
- return 0;
-}
-
-static int s2n_connection_init_hashes(struct s2n_connection *conn)
-{
- /* Initialize all of the Connection's hash states */
-
- if (s2n_hash_is_available(S2N_HASH_MD5)) {
- /* Only initialize hashes that use MD5 if available. */
- GUARD(s2n_hash_init(&conn->prf_space.ssl3.md5, S2N_HASH_MD5));
- }
-
-
- /* Allow MD5 for hash states that are used by the PRF. This is required
- * to comply with the TLS 1.0 and 1.1 RFCs and is approved as per
- * NIST Special Publication 800-52 Revision 1.
- */
- if (s2n_is_in_fips_mode()) {
- GUARD(s2n_hash_allow_md5_for_fips(&conn->handshake.md5));
- GUARD(s2n_hash_allow_md5_for_fips(&conn->handshake.prf_md5_hash_copy));
-
- /* Do not check s2n_hash_is_available before initialization. Allow MD5 and
- * SHA-1 for both fips and non-fips mode. This is required to perform the
- * signature checks in the CertificateVerify message in TLS 1.0 and TLS 1.1.
- * This is approved per Nist SP 800-52r1.*/
- GUARD(s2n_hash_allow_md5_for_fips(&conn->handshake.md5_sha1));
- }
-
- GUARD(s2n_hash_init(&conn->handshake.md5, S2N_HASH_MD5));
- GUARD(s2n_hash_init(&conn->handshake.prf_md5_hash_copy, S2N_HASH_MD5));
- GUARD(s2n_hash_init(&conn->handshake.md5_sha1, S2N_HASH_MD5_SHA1));
-
- GUARD(s2n_hash_init(&conn->handshake.sha1, S2N_HASH_SHA1));
- GUARD(s2n_hash_init(&conn->handshake.sha224, S2N_HASH_SHA224));
- GUARD(s2n_hash_init(&conn->handshake.sha256, S2N_HASH_SHA256));
- GUARD(s2n_hash_init(&conn->handshake.sha384, S2N_HASH_SHA384));
- GUARD(s2n_hash_init(&conn->handshake.sha512, S2N_HASH_SHA512));
- GUARD(s2n_hash_init(&conn->handshake.ccv_hash_copy, S2N_HASH_NONE));
- GUARD(s2n_hash_init(&conn->handshake.prf_tls12_hash_copy, S2N_HASH_NONE));
- GUARD(s2n_hash_init(&conn->handshake.server_finished_copy, S2N_HASH_NONE));
- GUARD(s2n_hash_init(&conn->handshake.prf_sha1_hash_copy, S2N_HASH_SHA1));
- GUARD(s2n_hash_init(&conn->prf_space.ssl3.sha1, S2N_HASH_SHA1));
- GUARD(s2n_hash_init(&conn->initial.signature_hash, S2N_HASH_NONE));
- GUARD(s2n_hash_init(&conn->secure.signature_hash, S2N_HASH_NONE));
-
- return 0;
-}
-
-static int s2n_connection_new_hmacs(struct s2n_connection *conn)
-{
- /* Allocate long-term memory for the Connection's HMAC states */
- GUARD(s2n_hmac_new(&conn->initial.client_record_mac));
- GUARD(s2n_hmac_new(&conn->initial.server_record_mac));
- GUARD(s2n_hmac_new(&conn->initial.record_mac_copy_workspace));
- GUARD(s2n_hmac_new(&conn->secure.client_record_mac));
- GUARD(s2n_hmac_new(&conn->secure.server_record_mac));
- GUARD(s2n_hmac_new(&conn->secure.record_mac_copy_workspace));
-
- return 0;
-}
-
-static int s2n_connection_init_hmacs(struct s2n_connection *conn)
-{
- /* Initialize all of the Connection's HMAC states */
- GUARD(s2n_hmac_init(&conn->initial.client_record_mac, S2N_HMAC_NONE, NULL, 0));
- GUARD(s2n_hmac_init(&conn->initial.server_record_mac, S2N_HMAC_NONE, NULL, 0));
- GUARD(s2n_hmac_init(&conn->initial.record_mac_copy_workspace, S2N_HMAC_NONE, NULL, 0));
- GUARD(s2n_hmac_init(&conn->secure.client_record_mac, S2N_HMAC_NONE, NULL, 0));
- GUARD(s2n_hmac_init(&conn->secure.server_record_mac, S2N_HMAC_NONE, NULL, 0));
- GUARD(s2n_hmac_init(&conn->secure.record_mac_copy_workspace, S2N_HMAC_NONE, NULL, 0));
-
- return 0;
-}
-
-struct s2n_connection *s2n_connection_new(s2n_mode mode)
-{
- struct s2n_blob blob = {0};
- GUARD_PTR(s2n_alloc(&blob, sizeof(struct s2n_connection)));
- GUARD_PTR(s2n_blob_zero(&blob));
-
- /* Cast 'through' void to acknowledge that we are changing alignment,
- * which is ok, as blob.data is always aligned.
- */
- struct s2n_connection* conn = (struct s2n_connection *)(void *)blob.data;
-
- GUARD_PTR(s2n_connection_set_config(conn, s2n_fetch_default_config()));
-
- conn->mode = mode;
- conn->blinding = S2N_BUILT_IN_BLINDING;
- conn->close_notify_queued = 0;
- conn->client_session_resumed = 0;
- conn->session_id_len = 0;
- conn->verify_host_fn = NULL;
- conn->data_for_verify_host = NULL;
- conn->verify_host_fn_overridden = 0;
- conn->data_for_verify_host = NULL;
- conn->send = NULL;
- conn->recv = NULL;
- conn->send_io_context = NULL;
- conn->recv_io_context = NULL;
- conn->managed_io = 0;
- conn->corked_io = 0;
- conn->context = NULL;
- conn->security_policy_override = NULL;
- conn->ticket_lifetime_hint = 0;
- conn->session_ticket_status = S2N_NO_TICKET;
-
- /* Allocate the fixed-size stuffers */
- blob = (struct s2n_blob) {0};
- GUARD_PTR(s2n_blob_init(&blob, conn->alert_in_data, S2N_ALERT_LENGTH));
- GUARD_PTR(s2n_stuffer_init(&conn->alert_in, &blob));
-
- blob = (struct s2n_blob) {0};
- GUARD_PTR(s2n_blob_init(&blob, conn->reader_alert_out_data, S2N_ALERT_LENGTH));
- GUARD_PTR(s2n_stuffer_init(&conn->reader_alert_out, &blob));
-
- blob = (struct s2n_blob) {0};
- GUARD_PTR(s2n_blob_init(&blob, conn->writer_alert_out_data, S2N_ALERT_LENGTH));
- GUARD_PTR(s2n_stuffer_init(&conn->writer_alert_out, &blob));
-
- blob = (struct s2n_blob) {0};
- GUARD_PTR(s2n_blob_init(&blob, conn->ticket_ext_data, S2N_TICKET_SIZE_IN_BYTES));
- GUARD_PTR(s2n_stuffer_init(&conn->client_ticket_to_decrypt, &blob));
-
- /* Allocate long term key memory */
- GUARD_PTR(s2n_session_key_alloc(&conn->secure.client_key));
- GUARD_PTR(s2n_session_key_alloc(&conn->secure.server_key));
- GUARD_PTR(s2n_session_key_alloc(&conn->initial.client_key));
- GUARD_PTR(s2n_session_key_alloc(&conn->initial.server_key));
-
- /* Allocate long term hash and HMAC memory */
- GUARD_PTR(s2n_prf_new(conn));
-
- GUARD_PTR(s2n_connection_new_hashes(conn));
- GUARD_PTR(s2n_connection_init_hashes(conn));
-
- GUARD_PTR(s2n_connection_new_hmacs(conn));
- GUARD_PTR(s2n_connection_init_hmacs(conn));
-
- /* Initialize the growable stuffers. Zero length at first, but the resize
- * in _wipe will fix that
- */
- blob = (struct s2n_blob) {0};
- GUARD_PTR(s2n_blob_init(&blob, conn->header_in_data, S2N_TLS_RECORD_HEADER_LENGTH));
- GUARD_PTR(s2n_stuffer_init(&conn->header_in, &blob));
- GUARD_PTR(s2n_stuffer_growable_alloc(&conn->out, 0));
- GUARD_PTR(s2n_stuffer_growable_alloc(&conn->in, 0));
- GUARD_PTR(s2n_stuffer_growable_alloc(&conn->handshake.io, 0));
- GUARD_PTR(s2n_stuffer_growable_alloc(&conn->client_hello.raw_message, 0));
- GUARD_PTR(s2n_connection_wipe(conn));
- GUARD_RESULT_PTR(s2n_timer_start(conn->config, &conn->write_timer));
-
- /* Initialize the cookie stuffer with zero length. If a cookie extension
- * is received, the stuffer will be resized according to the cookie length */
- GUARD_PTR(s2n_stuffer_growable_alloc(&conn->cookie_stuffer, 0));
-
- return conn;
-}
-
-static int s2n_connection_free_keys(struct s2n_connection *conn)
-{
- GUARD(s2n_session_key_free(&conn->secure.client_key));
- GUARD(s2n_session_key_free(&conn->secure.server_key));
- GUARD(s2n_session_key_free(&conn->initial.client_key));
- GUARD(s2n_session_key_free(&conn->initial.server_key));
-
- return 0;
-}
-
-static int s2n_connection_zero(struct s2n_connection *conn, int mode, struct s2n_config *config)
-{
- /* Zero the whole connection structure */
- memset_check(conn, 0, sizeof(struct s2n_connection));
-
- conn->send = NULL;
- conn->recv = NULL;
- conn->send_io_context = NULL;
- conn->recv_io_context = NULL;
- conn->mode = mode;
- conn->close_notify_queued = 0;
- conn->client_session_resumed = 0;
- conn->current_user_data_consumed = 0;
- conn->initial.cipher_suite = &s2n_null_cipher_suite;
- conn->secure.cipher_suite = &s2n_null_cipher_suite;
- conn->initial.kem_params.kem = NULL;
- conn->secure.kem_params.kem = NULL;
- conn->server = &conn->initial;
- conn->client = &conn->initial;
- conn->max_outgoing_fragment_length = S2N_DEFAULT_FRAGMENT_LENGTH;
- conn->mfl_code = S2N_TLS_MAX_FRAG_LEN_EXT_NONE;
- conn->handshake.handshake_type = INITIAL;
- conn->handshake.message_number = 0;
- conn->handshake.paused = 0;
- conn->verify_host_fn = NULL;
- conn->verify_host_fn_overridden = 0;
- conn->data_for_verify_host = NULL;
- s2n_connection_set_config(conn, config);
-
- return 0;
-}
-
-static int s2n_connection_wipe_keys(struct s2n_connection *conn)
-{
- /* Destroy any keys - we call destroy on the object as that is where
- * keys are allocated. */
- if (conn->secure.cipher_suite
- && conn->secure.cipher_suite->record_alg
- && conn->secure.cipher_suite->record_alg->cipher
- && conn->secure.cipher_suite->record_alg->cipher->destroy_key) {
- GUARD(conn->secure.cipher_suite->record_alg->cipher->destroy_key(&conn->secure.client_key));
- GUARD(conn->secure.cipher_suite->record_alg->cipher->destroy_key(&conn->secure.server_key));
- }
-
- /* Free any server key received (we may not have completed a
- * handshake, so this may not have been free'd yet) */
- GUARD(s2n_pkey_free(&conn->secure.server_public_key));
- GUARD(s2n_pkey_zero_init(&conn->secure.server_public_key));
- GUARD(s2n_pkey_free(&conn->secure.client_public_key));
- GUARD(s2n_pkey_zero_init(&conn->secure.client_public_key));
- s2n_x509_validator_wipe(&conn->x509_validator);
- GUARD(s2n_dh_params_free(&conn->secure.server_dh_params));
- GUARD(s2n_ecc_evp_params_free(&conn->secure.server_ecc_evp_params));
- for (int i=0; i < S2N_ECC_EVP_SUPPORTED_CURVES_COUNT; i++) {
- GUARD(s2n_ecc_evp_params_free(&conn->secure.client_ecc_evp_params[i]));
- }
- GUARD(s2n_kem_group_free(&conn->secure.server_kem_group_params));
- for (int i = 0; i < S2N_SUPPORTED_KEM_GROUPS_COUNT; i++) {
- GUARD(s2n_kem_group_free(&conn->secure.client_kem_group_params[i]));
- }
- GUARD(s2n_kem_free(&conn->secure.kem_params));
- GUARD(s2n_free(&conn->secure.client_cert_chain));
- GUARD(s2n_free(&conn->ct_response));
-
- return 0;
-}
-
-static int s2n_connection_reset_hashes(struct s2n_connection *conn)
-{
- /* Reset all of the Connection's hash states */
- GUARD(s2n_hash_reset(&conn->handshake.md5));
- GUARD(s2n_hash_reset(&conn->handshake.sha1));
- GUARD(s2n_hash_reset(&conn->handshake.sha224));
- GUARD(s2n_hash_reset(&conn->handshake.sha256));
- GUARD(s2n_hash_reset(&conn->handshake.sha384));
- GUARD(s2n_hash_reset(&conn->handshake.sha512));
- GUARD(s2n_hash_reset(&conn->handshake.md5_sha1));
- GUARD(s2n_hash_reset(&conn->handshake.ccv_hash_copy));
- GUARD(s2n_hash_reset(&conn->handshake.prf_md5_hash_copy));
- GUARD(s2n_hash_reset(&conn->handshake.prf_sha1_hash_copy));
- GUARD(s2n_hash_reset(&conn->handshake.prf_tls12_hash_copy));
- GUARD(s2n_hash_reset(&conn->handshake.server_finished_copy));
- GUARD(s2n_hash_reset(&conn->prf_space.ssl3.md5));
- GUARD(s2n_hash_reset(&conn->prf_space.ssl3.sha1));
- GUARD(s2n_hash_reset(&conn->initial.signature_hash));
- GUARD(s2n_hash_reset(&conn->secure.signature_hash));
-
- return 0;
-}
-
-static int s2n_connection_reset_hmacs(struct s2n_connection *conn)
-{
- /* Reset all of the Connection's HMAC states */
- GUARD(s2n_hmac_reset(&conn->initial.client_record_mac));
- GUARD(s2n_hmac_reset(&conn->initial.server_record_mac));
- GUARD(s2n_hmac_reset(&conn->initial.record_mac_copy_workspace));
- GUARD(s2n_hmac_reset(&conn->secure.client_record_mac));
- GUARD(s2n_hmac_reset(&conn->secure.server_record_mac));
- GUARD(s2n_hmac_reset(&conn->secure.record_mac_copy_workspace));
-
- return 0;
-}
-
-static int s2n_connection_free_io_contexts(struct s2n_connection *conn)
-{
- /* Free the I/O context if it was allocated by s2n. Don't touch user-controlled contexts. */
- if (!conn->managed_io) {
- return 0;
- }
-
- GUARD(s2n_free_object((uint8_t **)&conn->send_io_context, sizeof(struct s2n_socket_write_io_context)));
- GUARD(s2n_free_object((uint8_t **)&conn->recv_io_context, sizeof(struct s2n_socket_read_io_context)));
-
- return 0;
-}
-
-static int s2n_connection_wipe_io(struct s2n_connection *conn)
-{
- if (s2n_connection_is_managed_corked(conn) && conn->recv){
- GUARD(s2n_socket_read_restore(conn));
- }
- if (s2n_connection_is_managed_corked(conn) && conn->send){
- GUARD(s2n_socket_write_restore(conn));
- }
-
- /* Remove all I/O-related members */
- GUARD(s2n_connection_free_io_contexts(conn));
- conn->managed_io = 0;
- conn->send = NULL;
- conn->recv = NULL;
-
- return 0;
-}
-
-static int s2n_connection_free_hashes(struct s2n_connection *conn)
-{
- /* Free all of the Connection's hash states */
- GUARD(s2n_hash_free(&conn->handshake.md5));
- GUARD(s2n_hash_free(&conn->handshake.sha1));
- GUARD(s2n_hash_free(&conn->handshake.sha224));
- GUARD(s2n_hash_free(&conn->handshake.sha256));
- GUARD(s2n_hash_free(&conn->handshake.sha384));
- GUARD(s2n_hash_free(&conn->handshake.sha512));
- GUARD(s2n_hash_free(&conn->handshake.md5_sha1));
- GUARD(s2n_hash_free(&conn->handshake.ccv_hash_copy));
- GUARD(s2n_hash_free(&conn->handshake.prf_md5_hash_copy));
- GUARD(s2n_hash_free(&conn->handshake.prf_sha1_hash_copy));
- GUARD(s2n_hash_free(&conn->handshake.prf_tls12_hash_copy));
- GUARD(s2n_hash_free(&conn->handshake.server_finished_copy));
- GUARD(s2n_hash_free(&conn->prf_space.ssl3.md5));
- GUARD(s2n_hash_free(&conn->prf_space.ssl3.sha1));
- GUARD(s2n_hash_free(&conn->initial.signature_hash));
- GUARD(s2n_hash_free(&conn->secure.signature_hash));
-
- return 0;
-}
-
-static int s2n_connection_free_hmacs(struct s2n_connection *conn)
-{
- /* Free all of the Connection's HMAC states */
- GUARD(s2n_hmac_free(&conn->initial.client_record_mac));
- GUARD(s2n_hmac_free(&conn->initial.server_record_mac));
- GUARD(s2n_hmac_free(&conn->initial.record_mac_copy_workspace));
- GUARD(s2n_hmac_free(&conn->secure.client_record_mac));
- GUARD(s2n_hmac_free(&conn->secure.server_record_mac));
- GUARD(s2n_hmac_free(&conn->secure.record_mac_copy_workspace));
-
- return 0;
-}
-
-static uint8_t s2n_default_verify_host(const char *host_name, size_t len, void *data)
-{
- /* if present, match server_name of the connection using rules
- * outlined in RFC6125 6.4. */
-
- struct s2n_connection *conn = data;
-
- if (conn->server_name[0] == '\0') {
- return 0;
- }
-
- /* complete match */
- if (strlen(conn->server_name) == len &&
- strncasecmp(conn->server_name, host_name, len) == 0) {
- return 1;
- }
-
- /* match 1 level of wildcard */
- if (len > 2 && host_name[0] == '*' && host_name[1] == '.') {
- const char *suffix = strchr(conn->server_name, '.');
-
- if (suffix == NULL) {
- return 0;
- }
-
- if (strlen(suffix) == len - 1 &&
- strncasecmp(suffix, host_name + 1, len - 1) == 0) {
- return 1;
- }
- }
-
- return 0;
-}
-
-int s2n_connection_free(struct s2n_connection *conn)
-{
- GUARD(s2n_connection_wipe_keys(conn));
- GUARD(s2n_connection_free_keys(conn));
- GUARD(s2n_psk_parameters_free(&conn->psk_params));
-
- GUARD(s2n_prf_free(conn));
-
- GUARD(s2n_connection_reset_hashes(conn));
- GUARD(s2n_connection_free_hashes(conn));
-
- GUARD(s2n_connection_reset_hmacs(conn));
- GUARD(s2n_connection_free_hmacs(conn));
-
- GUARD(s2n_connection_free_io_contexts(conn));
-
- GUARD(s2n_free(&conn->client_ticket));
- GUARD(s2n_free(&conn->status_response));
- GUARD(s2n_free(&conn->our_quic_transport_parameters));
- GUARD(s2n_free(&conn->peer_quic_transport_parameters));
- GUARD(s2n_stuffer_free(&conn->in));
- GUARD(s2n_stuffer_free(&conn->out));
- GUARD(s2n_stuffer_free(&conn->handshake.io));
- s2n_x509_validator_wipe(&conn->x509_validator);
- GUARD(s2n_client_hello_free(&conn->client_hello));
- GUARD(s2n_free(&conn->application_protocols_overridden));
- GUARD(s2n_stuffer_free(&conn->cookie_stuffer));
- GUARD(s2n_free_object((uint8_t **)&conn, sizeof(struct s2n_connection)));
-
- return 0;
-}
-
-int s2n_connection_set_config(struct s2n_connection *conn, struct s2n_config *config)
-{
- notnull_check(conn);
- notnull_check(config);
-
- if (conn->config == config) {
- return 0;
- }
-
- /* We only support one client certificate */
- if (s2n_config_get_num_default_certs(config) > 1 && conn->mode == S2N_CLIENT) {
- S2N_ERROR(S2N_ERR_TOO_MANY_CERTIFICATES);
- }
-
- s2n_x509_validator_wipe(&conn->x509_validator);
-
- s2n_cert_auth_type auth_type = config->client_cert_auth_type;
-
- if (conn->client_cert_auth_type_overridden) {
- auth_type = conn->client_cert_auth_type;
- }
-
- int8_t dont_need_x509_validation = (conn->mode == S2N_SERVER) && (auth_type == S2N_CERT_AUTH_NONE);
-
- if (config->disable_x509_validation || dont_need_x509_validation) {
- GUARD(s2n_x509_validator_init_no_x509_validation(&conn->x509_validator));
- }
- else {
- GUARD(s2n_x509_validator_init(&conn->x509_validator, &config->trust_store, config->check_ocsp));
- if (!conn->verify_host_fn_overridden) {
- if (config->verify_host != NULL) {
- conn->verify_host_fn = config->verify_host;
- conn->data_for_verify_host = config->data_for_verify_host;
- } else {
- conn->verify_host_fn = s2n_default_verify_host;
- conn->data_for_verify_host = conn;
- }
- }
-
- if (config->max_verify_cert_chain_depth_set) {
- GUARD(s2n_x509_validator_set_max_chain_depth(&conn->x509_validator, config->max_verify_cert_chain_depth));
- }
- }
-
- conn->config = config;
- return 0;
-}
-
-int s2n_connection_set_ctx(struct s2n_connection *conn, void *ctx)
-{
- conn->context = ctx;
- return 0;
-}
-
-void *s2n_connection_get_ctx(struct s2n_connection *conn)
-{
- return conn->context;
-}
-
-int s2n_connection_release_buffers(struct s2n_connection *conn)
-{
- notnull_check(conn);
- PRECONDITION_POSIX(s2n_stuffer_validate(&conn->out));
- PRECONDITION_POSIX(s2n_stuffer_validate(&conn->in));
-
- ENSURE_POSIX(s2n_stuffer_is_consumed(&conn->out), S2N_ERR_STUFFER_HAS_UNPROCESSED_DATA);
- GUARD(s2n_stuffer_resize(&conn->out, 0));
-
- ENSURE_POSIX(s2n_stuffer_is_consumed(&conn->in), S2N_ERR_STUFFER_HAS_UNPROCESSED_DATA);
- GUARD(s2n_stuffer_resize(&conn->in, 0));
-
- POSTCONDITION_POSIX(s2n_stuffer_validate(&conn->out));
- POSTCONDITION_POSIX(s2n_stuffer_validate(&conn->in));
- return S2N_SUCCESS;
-}
-
-int s2n_connection_free_handshake(struct s2n_connection *conn)
-{
- /* We are done with the handshake */
- GUARD(s2n_hash_reset(&conn->handshake.md5));
- GUARD(s2n_hash_reset(&conn->handshake.sha1));
- GUARD(s2n_hash_reset(&conn->handshake.sha224));
- GUARD(s2n_hash_reset(&conn->handshake.sha256));
- GUARD(s2n_hash_reset(&conn->handshake.sha384));
- GUARD(s2n_hash_reset(&conn->handshake.sha512));
- GUARD(s2n_hash_reset(&conn->handshake.md5_sha1));
- GUARD(s2n_hash_reset(&conn->handshake.ccv_hash_copy));
- GUARD(s2n_hash_reset(&conn->handshake.prf_md5_hash_copy));
- GUARD(s2n_hash_reset(&conn->handshake.prf_sha1_hash_copy));
- GUARD(s2n_hash_reset(&conn->handshake.prf_tls12_hash_copy));
- GUARD(s2n_hash_reset(&conn->handshake.server_finished_copy));
-
- /* Wipe the buffers we are going to free */
- GUARD(s2n_stuffer_wipe(&conn->handshake.io));
- GUARD(s2n_stuffer_wipe(&conn->client_hello.raw_message));
-
- /* Truncate buffers to save memory, we are done with the handshake */
- GUARD(s2n_stuffer_resize(&conn->handshake.io, 0));
- GUARD(s2n_stuffer_resize(&conn->client_hello.raw_message, 0));
-
- /* We can free extension data we no longer need */
- GUARD(s2n_free(&conn->client_ticket));
- GUARD(s2n_free(&conn->status_response));
- GUARD(s2n_free(&conn->our_quic_transport_parameters));
- GUARD(s2n_free(&conn->application_protocols_overridden));
- GUARD(s2n_stuffer_free(&conn->cookie_stuffer));
-
- return 0;
-}
-
-int s2n_connection_wipe(struct s2n_connection *conn)
-{
- /* First make a copy of everything we'd like to save, which isn't very much. */
- int mode = conn->mode;
- struct s2n_config *config = conn->config;
- struct s2n_stuffer alert_in = {0};
- struct s2n_stuffer reader_alert_out = {0};
- struct s2n_stuffer writer_alert_out = {0};
- struct s2n_stuffer client_ticket_to_decrypt = {0};
- struct s2n_stuffer handshake_io = {0};
- struct s2n_stuffer client_hello_raw_message = {0};
- struct s2n_stuffer header_in = {0};
- struct s2n_stuffer in = {0};
- struct s2n_stuffer out = {0};
- /* Session keys will be wiped. Preserve structs to avoid reallocation */
- struct s2n_session_key initial_client_key = {0};
- struct s2n_session_key initial_server_key = {0};
- struct s2n_session_key secure_client_key = {0};
- struct s2n_session_key secure_server_key = {0};
- /* Parts of the PRF working space, hash states, and hmac states will be wiped. Preserve structs to avoid reallocation */
- struct s2n_connection_prf_handles prf_handles = {0};
- struct s2n_connection_hash_handles hash_handles = {0};
- struct s2n_connection_hmac_handles hmac_handles = {0};
-
- /* Wipe all of the sensitive stuff */
- GUARD(s2n_connection_wipe_keys(conn));
- GUARD(s2n_connection_reset_hashes(conn));
- GUARD(s2n_connection_reset_hmacs(conn));
- GUARD(s2n_stuffer_wipe(&conn->alert_in));
- GUARD(s2n_stuffer_wipe(&conn->reader_alert_out));
- GUARD(s2n_stuffer_wipe(&conn->writer_alert_out));
- GUARD(s2n_stuffer_wipe(&conn->client_ticket_to_decrypt));
- GUARD(s2n_stuffer_wipe(&conn->handshake.io));
- GUARD(s2n_stuffer_wipe(&conn->client_hello.raw_message));
- GUARD(s2n_stuffer_wipe(&conn->header_in));
- GUARD(s2n_stuffer_wipe(&conn->in));
- GUARD(s2n_stuffer_wipe(&conn->out));
-
- GUARD_AS_POSIX(s2n_psk_parameters_wipe(&conn->psk_params));
-
- /* Wipe the I/O-related info and restore the original socket if necessary */
- GUARD(s2n_connection_wipe_io(conn));
-
- GUARD(s2n_free(&conn->client_ticket));
- GUARD(s2n_free(&conn->status_response));
- GUARD(s2n_free(&conn->application_protocols_overridden));
- GUARD(s2n_free(&conn->our_quic_transport_parameters));
- GUARD(s2n_free(&conn->peer_quic_transport_parameters));
-
- /* Allocate memory for handling handshakes */
- GUARD(s2n_stuffer_resize(&conn->handshake.io, S2N_LARGE_RECORD_LENGTH));
-
- /* Truncate the message buffers to save memory, we will dynamically resize it as needed */
- GUARD(s2n_stuffer_resize(&conn->client_hello.raw_message, 0));
- GUARD(s2n_stuffer_resize(&conn->in, 0));
- GUARD(s2n_stuffer_resize(&conn->out, 0));
-
- /* Remove context associated with connection */
- conn->context = NULL;
- conn->verify_host_fn_overridden = 0;
- conn->verify_host_fn = NULL;
- conn->data_for_verify_host = NULL;
-
- /* Clone the stuffers */
- /* ignore gcc 4.7 address warnings because dest is allocated on the stack */
- /* pragma gcc diagnostic was added in gcc 4.6 */
-#if S2N_GCC_VERSION_AT_LEAST(4,6,0)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Waddress"
-#endif
- memcpy_check(&alert_in, &conn->alert_in, sizeof(struct s2n_stuffer));
- memcpy_check(&reader_alert_out, &conn->reader_alert_out, sizeof(struct s2n_stuffer));
- memcpy_check(&writer_alert_out, &conn->writer_alert_out, sizeof(struct s2n_stuffer));
- memcpy_check(&client_ticket_to_decrypt, &conn->client_ticket_to_decrypt, sizeof(struct s2n_stuffer));
- memcpy_check(&handshake_io, &conn->handshake.io, sizeof(struct s2n_stuffer));
- memcpy_check(&client_hello_raw_message, &conn->client_hello.raw_message, sizeof(struct s2n_stuffer));
- memcpy_check(&header_in, &conn->header_in, sizeof(struct s2n_stuffer));
- memcpy_check(&in, &conn->in, sizeof(struct s2n_stuffer));
- memcpy_check(&out, &conn->out, sizeof(struct s2n_stuffer));
- memcpy_check(&initial_client_key, &conn->initial.client_key, sizeof(struct s2n_session_key));
- memcpy_check(&initial_server_key, &conn->initial.server_key, sizeof(struct s2n_session_key));
- memcpy_check(&secure_client_key, &conn->secure.client_key, sizeof(struct s2n_session_key));
- memcpy_check(&secure_server_key, &conn->secure.server_key, sizeof(struct s2n_session_key));
- GUARD(s2n_connection_save_prf_state(&prf_handles, conn));
- GUARD(s2n_connection_save_hash_state(&hash_handles, conn));
- GUARD(s2n_connection_save_hmac_state(&hmac_handles, conn));
-#if S2N_GCC_VERSION_AT_LEAST(4,6,0)
-#pragma GCC diagnostic pop
-#endif
-
- GUARD(s2n_connection_zero(conn, mode, config));
-
- memcpy_check(&conn->alert_in, &alert_in, sizeof(struct s2n_stuffer));
- memcpy_check(&conn->reader_alert_out, &reader_alert_out, sizeof(struct s2n_stuffer));
- memcpy_check(&conn->writer_alert_out, &writer_alert_out, sizeof(struct s2n_stuffer));
- memcpy_check(&conn->client_ticket_to_decrypt, &client_ticket_to_decrypt, sizeof(struct s2n_stuffer));
- memcpy_check(&conn->handshake.io, &handshake_io, sizeof(struct s2n_stuffer));
- memcpy_check(&conn->client_hello.raw_message, &client_hello_raw_message, sizeof(struct s2n_stuffer));
- memcpy_check(&conn->header_in, &header_in, sizeof(struct s2n_stuffer));
- memcpy_check(&conn->in, &in, sizeof(struct s2n_stuffer));
- memcpy_check(&conn->out, &out, sizeof(struct s2n_stuffer));
- memcpy_check(&conn->initial.client_key, &initial_client_key, sizeof(struct s2n_session_key));
- memcpy_check(&conn->initial.server_key, &initial_server_key, sizeof(struct s2n_session_key));
- memcpy_check(&conn->secure.client_key, &secure_client_key, sizeof(struct s2n_session_key));
- memcpy_check(&conn->secure.server_key, &secure_server_key, sizeof(struct s2n_session_key));
- GUARD(s2n_connection_restore_prf_state(conn, &prf_handles));
- GUARD(s2n_connection_restore_hash_state(conn, &hash_handles));
- GUARD(s2n_connection_restore_hmac_state(conn, &hmac_handles));
-
- /* Re-initialize hash and hmac states */
- GUARD(s2n_connection_init_hashes(conn));
- GUARD(s2n_connection_init_hmacs(conn));
-
- GUARD_AS_POSIX(s2n_psk_parameters_init(&conn->psk_params));
-
- /* Require all handshakes hashes. This set can be reduced as the handshake progresses. */
- GUARD(s2n_handshake_require_all_hashes(&conn->handshake));
-
- if (conn->mode == S2N_SERVER) {
- /* Start with the highest protocol version so that the highest common protocol version can be selected */
- /* during handshake. */
- conn->server_protocol_version = s2n_highest_protocol_version;
- conn->client_protocol_version = s2n_unknown_protocol_version;
- conn->actual_protocol_version = s2n_unknown_protocol_version;
- }
- else {
- /* For clients, also set actual_protocol_version. Record generation uses that value for the initial */
- /* ClientHello record version. Not all servers ignore the record version in ClientHello. */
- conn->server_protocol_version = s2n_unknown_protocol_version;
- conn->client_protocol_version = s2n_highest_protocol_version;
- conn->actual_protocol_version = s2n_highest_protocol_version;
- }
-
- return 0;
-}
-
-int s2n_connection_set_recv_ctx(struct s2n_connection *conn, void *ctx)
-{
- conn->recv_io_context = ctx;
- return 0;
-}
-
-int s2n_connection_set_send_ctx(struct s2n_connection *conn, void *ctx)
-{
- conn->send_io_context = ctx;
- return 0;
-}
-
-int s2n_connection_set_recv_cb(struct s2n_connection *conn, s2n_recv_fn recv)
-{
- conn->recv = recv;
- return 0;
-}
-
-int s2n_connection_set_send_cb(struct s2n_connection *conn, s2n_send_fn send)
-{
- conn->send = send;
- return 0;
-}
-
-int s2n_connection_get_client_cert_chain(struct s2n_connection *conn, uint8_t **der_cert_chain_out, uint32_t *cert_chain_len)
-{
- notnull_check(conn);
- notnull_check(der_cert_chain_out);
- notnull_check(cert_chain_len);
- notnull_check(conn->secure.client_cert_chain.data);
-
- *der_cert_chain_out = conn->secure.client_cert_chain.data;
- *cert_chain_len = conn->secure.client_cert_chain.size;
-
- return 0;
-}
-
-int s2n_connection_get_cipher_preferences(struct s2n_connection *conn, const struct s2n_cipher_preferences **cipher_preferences)
-{
- notnull_check(conn);
- notnull_check(conn->config);
- notnull_check(cipher_preferences);
-
- if (conn->security_policy_override != NULL) {
- *cipher_preferences = conn->security_policy_override->cipher_preferences;
- } else if (conn->config->security_policy != NULL) {
- *cipher_preferences = conn->config->security_policy->cipher_preferences;
- } else {
- S2N_ERROR(S2N_ERR_INVALID_CIPHER_PREFERENCES);
- }
-
- notnull_check(*cipher_preferences);
- return 0;
-}
-
-int s2n_connection_get_security_policy(struct s2n_connection *conn, const struct s2n_security_policy **security_policy)
-{
- notnull_check(conn);
- notnull_check(conn->config);
- notnull_check(security_policy);
-
- if (conn->security_policy_override != NULL) {
- *security_policy = conn->security_policy_override;
- } else if (conn->config->security_policy != NULL) {
- *security_policy = conn->config->security_policy;
- } else {
- S2N_ERROR(S2N_ERR_INVALID_SECURITY_POLICY);
- }
-
- notnull_check(*security_policy);
- return 0;
-}
-
-int s2n_connection_get_kem_preferences(struct s2n_connection *conn, const struct s2n_kem_preferences **kem_preferences)
-{
- notnull_check(conn);
- notnull_check(conn->config);
- notnull_check(kem_preferences);
-
- if (conn->security_policy_override != NULL) {
- *kem_preferences = conn->security_policy_override->kem_preferences;
- } else if (conn->config->security_policy != NULL) {
- *kem_preferences = conn->config->security_policy->kem_preferences;
- } else {
- S2N_ERROR(S2N_ERR_INVALID_KEM_PREFERENCES);
- }
-
- notnull_check(*kem_preferences);
- return 0;
-}
-
-int s2n_connection_get_signature_preferences(struct s2n_connection *conn, const struct s2n_signature_preferences **signature_preferences)
-{
- notnull_check(conn);
- notnull_check(conn->config);
- notnull_check(signature_preferences);
-
- if (conn->security_policy_override != NULL) {
- *signature_preferences = conn->security_policy_override->signature_preferences;
- } else if (conn->config->security_policy != NULL) {
- *signature_preferences = conn->config->security_policy->signature_preferences;
- } else {
- S2N_ERROR(S2N_ERR_INVALID_SIGNATURE_ALGORITHMS_PREFERENCES);
- }
-
- notnull_check(*signature_preferences);
- return 0;
-
-}
-
-int s2n_connection_get_ecc_preferences(struct s2n_connection *conn, const struct s2n_ecc_preferences **ecc_preferences)
-{
- notnull_check(conn);
- notnull_check(conn->config);
- notnull_check(ecc_preferences);
-
- if (conn->security_policy_override != NULL) {
- *ecc_preferences = conn->security_policy_override->ecc_preferences;
- } else if (conn->config->security_policy != NULL) {
- *ecc_preferences = conn->config->security_policy->ecc_preferences;
- } else {
- S2N_ERROR(S2N_ERR_INVALID_ECC_PREFERENCES);
- }
-
- notnull_check(*ecc_preferences);
- return 0;
-
-}
-
-int s2n_connection_get_protocol_preferences(struct s2n_connection *conn, struct s2n_blob **protocol_preferences)
-{
- notnull_check(conn);
- notnull_check(protocol_preferences);
-
- *protocol_preferences = NULL;
- if (conn->application_protocols_overridden.size > 0) {
- *protocol_preferences = &conn->application_protocols_overridden;
- } else {
- *protocol_preferences = &conn->config->application_protocols;
- }
-
- notnull_check(*protocol_preferences);
- return 0;
-}
-
-int s2n_connection_get_client_auth_type(struct s2n_connection *conn, s2n_cert_auth_type *client_cert_auth_type)
-{
- notnull_check(conn);
- notnull_check(client_cert_auth_type);
-
- if (conn->client_cert_auth_type_overridden) {
- *client_cert_auth_type = conn->client_cert_auth_type;
- } else {
- *client_cert_auth_type = conn->config->client_cert_auth_type;
- }
-
- return 0;
-}
-
-int s2n_connection_set_client_auth_type(struct s2n_connection *conn, s2n_cert_auth_type client_cert_auth_type)
-{
- conn->client_cert_auth_type_overridden = 1;
- conn->client_cert_auth_type = client_cert_auth_type;
- return 0;
-}
-
-int s2n_connection_set_read_fd(struct s2n_connection *conn, int rfd)
-{
- struct s2n_blob ctx_mem = {0};
- struct s2n_socket_read_io_context *peer_socket_ctx;
-
- GUARD(s2n_alloc(&ctx_mem, sizeof(struct s2n_socket_read_io_context)));
- GUARD(s2n_blob_zero(&ctx_mem));
-
- peer_socket_ctx = (struct s2n_socket_read_io_context *)(void *)ctx_mem.data;
- peer_socket_ctx->fd = rfd;
-
- s2n_connection_set_recv_cb(conn, s2n_socket_read);
- s2n_connection_set_recv_ctx(conn, peer_socket_ctx);
- conn->managed_io = 1;
-
- /* This is only needed if the user is using corked io.
- * Take the snapshot in case optimized io is enabled after setting the fd.
- */
- GUARD(s2n_socket_read_snapshot(conn));
-
- return 0;
-}
-
-int s2n_connection_set_write_fd(struct s2n_connection *conn, int wfd)
-{
- struct s2n_blob ctx_mem = {0};
- struct s2n_socket_write_io_context *peer_socket_ctx;
-
- GUARD(s2n_alloc(&ctx_mem, sizeof(struct s2n_socket_write_io_context)));
-
- peer_socket_ctx = (struct s2n_socket_write_io_context *)(void *)ctx_mem.data;
- peer_socket_ctx->fd = wfd;
-
- s2n_connection_set_send_cb(conn, s2n_socket_write);
- s2n_connection_set_send_ctx(conn, peer_socket_ctx);
- conn->managed_io = 1;
-
- /* This is only needed if the user is using corked io.
- * Take the snapshot in case optimized io is enabled after setting the fd.
- */
- GUARD(s2n_socket_write_snapshot(conn));
-
- uint8_t ipv6;
- if (0 == s2n_socket_is_ipv6(wfd, &ipv6)) {
- conn->ipv6 = (ipv6 ? 1 : 0);
- }
-
- conn->write_fd_broken = 0;
-
- return 0;
-}
-
-int s2n_connection_set_fd(struct s2n_connection *conn, int fd)
-{
- GUARD(s2n_connection_set_read_fd(conn, fd));
- GUARD(s2n_connection_set_write_fd(conn, fd));
- return 0;
-}
-
-int s2n_connection_use_corked_io(struct s2n_connection *conn)
-{
- if (!conn->managed_io) {
- /* Caller shouldn't be trying to set s2n IO corked on non-s2n-managed IO */
- S2N_ERROR(S2N_ERR_CORK_SET_ON_UNMANAGED);
- }
- conn->corked_io = 1;
-
- return 0;
-}
-
-uint64_t s2n_connection_get_wire_bytes_in(struct s2n_connection *conn)
-{
- return conn->wire_bytes_in;
-}
-
-uint64_t s2n_connection_get_wire_bytes_out(struct s2n_connection *conn)
-{
- return conn->wire_bytes_out;
-}
-
-const char *s2n_connection_get_cipher(struct s2n_connection *conn)
-{
- notnull_check_ptr(conn);
- notnull_check_ptr(conn->secure.cipher_suite);
-
- return conn->secure.cipher_suite->name;
-}
-
-const char *s2n_connection_get_curve(struct s2n_connection *conn)
-{
- notnull_check_ptr(conn);
-
- if (!conn->secure.server_ecc_evp_params.negotiated_curve) {
- return "NONE";
- }
-
- return conn->secure.server_ecc_evp_params.negotiated_curve->name;
-}
-
-const char *s2n_connection_get_kem_name(struct s2n_connection *conn)
-{
- notnull_check_ptr(conn);
-
- if (!conn->secure.kem_params.kem) {
- return "NONE";
- }
-
- return conn->secure.kem_params.kem->name;
-}
-
-const char *s2n_connection_get_kem_group_name(struct s2n_connection *conn)
-{
- notnull_check_ptr(conn);
-
- if (!conn->secure.chosen_client_kem_group_params || !conn->secure.chosen_client_kem_group_params->kem_group) {
- return "NONE";
- }
-
- return conn->secure.chosen_client_kem_group_params->kem_group->name;
-}
-
-int s2n_connection_get_client_protocol_version(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- return conn->client_protocol_version;
-}
-
-int s2n_connection_get_server_protocol_version(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- return conn->server_protocol_version;
-}
-
-int s2n_connection_get_actual_protocol_version(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- return conn->actual_protocol_version;
-}
-
-int s2n_connection_get_client_hello_version(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- return conn->client_hello_version;
-}
-
-int s2n_connection_client_cert_used(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- if ((conn->handshake.handshake_type & CLIENT_AUTH) && is_handshake_complete(conn)) {
- if (conn->handshake.handshake_type & NO_CLIENT_CERT) {
- return 0;
- }
- return 1;
- }
- return 0;
-}
-
-int s2n_connection_get_alert(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- S2N_ERROR_IF(s2n_stuffer_data_available(&conn->alert_in) != 2, S2N_ERR_NO_ALERT);
-
- uint8_t alert_code = 0;
- GUARD(s2n_stuffer_read_uint8(&conn->alert_in, &alert_code));
- GUARD(s2n_stuffer_read_uint8(&conn->alert_in, &alert_code));
-
- return alert_code;
-}
-
-int s2n_set_server_name(struct s2n_connection *conn, const char *server_name)
-{
- notnull_check(conn);
- notnull_check(server_name);
-
- S2N_ERROR_IF(conn->mode != S2N_CLIENT, S2N_ERR_CLIENT_MODE);
-
- int len = strlen(server_name);
- S2N_ERROR_IF(len > S2N_MAX_SERVER_NAME, S2N_ERR_SERVER_NAME_TOO_LONG);
-
- memcpy_check(conn->server_name, server_name, len);
-
- return 0;
-}
-
-const char *s2n_get_server_name(struct s2n_connection *conn)
-{
- notnull_check_ptr(conn);
-
- if (conn->server_name[0]) {
- return conn->server_name;
- }
-
- GUARD_PTR(s2n_extension_process(&s2n_client_server_name_extension, conn, &conn->client_hello.extensions));
-
- if (!conn->server_name[0]) {
- return NULL;
- }
-
- return conn->server_name;
-}
-
-const char *s2n_get_application_protocol(struct s2n_connection *conn)
-{
- notnull_check_ptr(conn);
-
- if (strlen(conn->application_protocol) == 0) {
- return NULL;
- }
-
- return conn->application_protocol;
-}
-
-int s2n_connection_get_session_id_length(struct s2n_connection *conn)
-{
- notnull_check(conn);
- return conn->session_id_len;
-}
-
-int s2n_connection_get_session_id(struct s2n_connection *conn, uint8_t *session_id, size_t max_length)
-{
- notnull_check(conn);
- notnull_check(session_id);
-
- int session_id_len = s2n_connection_get_session_id_length(conn);
-
- S2N_ERROR_IF(session_id_len > max_length, S2N_ERR_SESSION_ID_TOO_LONG);
-
- memcpy_check(session_id, conn->session_id, session_id_len);
-
- return session_id_len;
-}
-
-int s2n_connection_set_blinding(struct s2n_connection *conn, s2n_blinding blinding)
-{
- notnull_check(conn);
- conn->blinding = blinding;
-
- return 0;
-}
-
-#define ONE_S INT64_C(1000000000)
-#define TEN_S INT64_C(10000000000)
-
-uint64_t s2n_connection_get_delay(struct s2n_connection *conn)
-{
- if (!conn->delay) {
- return 0;
- }
-
- uint64_t elapsed;
- /* This will cast -1 to max uint64_t */
- GUARD_AS_POSIX(s2n_timer_elapsed(conn->config, &conn->write_timer, &elapsed));
-
- if (elapsed > conn->delay) {
- return 0;
- }
-
- return conn->delay - elapsed;
-}
-
-int s2n_connection_kill(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- conn->closed = 1;
-
- /* Delay between 10 and 30 seconds in nanoseconds */
- int64_t min = TEN_S, max = 3 * TEN_S;
-
- /* Keep track of the delay so that it can be enforced */
- uint64_t rand_delay = 0;
- GUARD_AS_POSIX(s2n_public_random(max - min, &rand_delay));
-
- conn->delay = min + rand_delay;
-
- /* Restart the write timer */
- GUARD_AS_POSIX(s2n_timer_start(conn->config, &conn->write_timer));
-
- if (conn->blinding == S2N_BUILT_IN_BLINDING) {
- struct timespec sleep_time = {.tv_sec = conn->delay / ONE_S,.tv_nsec = conn->delay % ONE_S };
- int r;
-
- do {
- r = nanosleep(&sleep_time, &sleep_time);
- }
- while (r != 0);
- }
-
- return 0;
-}
-
-const uint8_t *s2n_connection_get_ocsp_response(struct s2n_connection *conn, uint32_t * length)
-{
- notnull_check_ptr(conn);
- notnull_check_ptr(length);
-
- *length = conn->status_response.size;
- return conn->status_response.data;
-}
-
-int s2n_connection_prefer_throughput(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- if (!conn->mfl_code) {
- conn->max_outgoing_fragment_length = S2N_LARGE_FRAGMENT_LENGTH;
- }
-
- return 0;
-}
-
-int s2n_connection_prefer_low_latency(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- if (!conn->mfl_code) {
- conn->max_outgoing_fragment_length = S2N_SMALL_FRAGMENT_LENGTH;
- }
-
- return 0;
-}
-
-int s2n_connection_set_dynamic_record_threshold(struct s2n_connection *conn, uint32_t resize_threshold, uint16_t timeout_threshold)
-{
- notnull_check(conn);
- S2N_ERROR_IF(resize_threshold > S2N_TLS_MAX_RESIZE_THRESHOLD, S2N_ERR_INVALID_DYNAMIC_THRESHOLD);
-
- conn->dynamic_record_resize_threshold = resize_threshold;
- conn->dynamic_record_timeout_threshold = timeout_threshold;
- return 0;
-}
-
-int s2n_connection_set_verify_host_callback(struct s2n_connection *conn, s2n_verify_host_fn verify_host_fn, void *data) {
- notnull_check(conn);
-
- conn->verify_host_fn = verify_host_fn;
- conn->data_for_verify_host = data;
- conn->verify_host_fn_overridden = 1;
-
- return 0;
-}
-
-int s2n_connection_recv_stuffer(struct s2n_stuffer *stuffer, struct s2n_connection *conn, uint32_t len)
-{
- notnull_check(conn->recv);
- /* Make sure we have enough space to write */
- GUARD(s2n_stuffer_reserve_space(stuffer, len));
-
- int r = 0;
- do {
- errno = 0;
- r = conn->recv(conn->recv_io_context, stuffer->blob.data + stuffer->write_cursor, len);
- S2N_ERROR_IF(r < 0 && errno != EINTR, S2N_ERR_RECV_STUFFER_FROM_CONN);
- } while (r < 0);
-
- /* Record just how many bytes we have written */
- GUARD(s2n_stuffer_skip_write(stuffer, r));
- return r;
-}
-
-int s2n_connection_send_stuffer(struct s2n_stuffer *stuffer, struct s2n_connection *conn, uint32_t len)
-{
- notnull_check(conn);
- notnull_check(conn->send);
- if (conn->write_fd_broken) {
- S2N_ERROR(S2N_ERR_SEND_STUFFER_TO_CONN);
- }
- /* Make sure we even have the data */
- S2N_ERROR_IF(s2n_stuffer_data_available(stuffer) < len, S2N_ERR_STUFFER_OUT_OF_DATA);
-
- int w = 0;
- do {
- errno = 0;
- w = conn->send(conn->send_io_context, stuffer->blob.data + stuffer->read_cursor, len);
- if (w < 0 && errno == EPIPE) {
- conn->write_fd_broken = 1;
- }
- S2N_ERROR_IF(w < 0 && errno != EINTR, S2N_ERR_SEND_STUFFER_TO_CONN);
- } while (w < 0);
-
- GUARD(s2n_stuffer_skip_read(stuffer, w));
- return w;
-}
-
-int s2n_connection_is_managed_corked(const struct s2n_connection *s2n_connection)
-{
- notnull_check(s2n_connection);
-
- return (s2n_connection->managed_io && s2n_connection->corked_io);
-}
-
-const uint8_t *s2n_connection_get_sct_list(struct s2n_connection *conn, uint32_t *length)
-{
- if (!length) {
- return NULL;
- }
-
- *length = conn->ct_response.size;
- return conn->ct_response.data;
-}
-
-int s2n_connection_is_client_auth_enabled(struct s2n_connection *s2n_connection)
-{
- s2n_cert_auth_type auth_type;
- GUARD(s2n_connection_get_client_auth_type(s2n_connection, &auth_type));
-
- return (auth_type != S2N_CERT_AUTH_NONE);
-}
-
-struct s2n_cert_chain_and_key *s2n_connection_get_selected_cert(struct s2n_connection *conn)
-{
- notnull_check_ptr(conn);
- return conn->handshake_params.our_chain_and_key;
-}
-
-uint8_t s2n_connection_get_protocol_version(const struct s2n_connection *conn)
-{
- if (conn == NULL) {
- return S2N_UNKNOWN_PROTOCOL_VERSION;
- }
-
- if (conn->actual_protocol_version != S2N_UNKNOWN_PROTOCOL_VERSION) {
- return conn->actual_protocol_version;
- }
-
- if (conn->mode == S2N_CLIENT) {
- return conn->client_protocol_version;
- }
- return conn->server_protocol_version;
-}
-
-int s2n_connection_set_keyshare_by_name_for_testing(struct s2n_connection *conn, const char* curve_name)
-{
- ENSURE_POSIX(S2N_IN_TEST, S2N_ERR_NOT_IN_TEST);
- notnull_check(conn);
-
- if (!strcmp(curve_name, "none")) {
- S2N_SET_KEY_SHARE_LIST_EMPTY(conn->preferred_key_shares);
- return S2N_SUCCESS;
- }
-
- const struct s2n_ecc_preferences *ecc_pref = NULL;
- GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
- notnull_check(ecc_pref);
-
- for (size_t i = 0; i < ecc_pref->count; i++) {
- if (!strcmp(ecc_pref->ecc_curves[i]->name, curve_name)) {
- S2N_SET_KEY_SHARE_REQUEST(conn->preferred_key_shares, i);
- return S2N_SUCCESS;
- }
- }
-
- S2N_ERROR(S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
-}
+/*
+ * 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 <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <s2n.h>
+#include <stdbool.h>
+
+#include "crypto/s2n_fips.h"
+
+#include "error/s2n_errno.h"
+
+#include "tls/extensions/s2n_client_server_name.h"
+#include "tls/s2n_alerts.h"
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_connection_evp_digests.h"
+#include "tls/s2n_handshake.h"
+#include "tls/s2n_kem.h"
+#include "tls/s2n_prf.h"
+#include "tls/s2n_record.h"
+#include "tls/s2n_resume.h"
+#include "tls/s2n_security_policies.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls_parameters.h"
+
+#include "crypto/s2n_certificate.h"
+#include "crypto/s2n_cipher.h"
+
+#include "utils/s2n_blob.h"
+#include "utils/s2n_compiler.h"
+#include "utils/s2n_mem.h"
+#include "utils/s2n_random.h"
+#include "utils/s2n_safety.h"
+#include "utils/s2n_socket.h"
+#include "utils/s2n_timer.h"
+
+#define S2N_SET_KEY_SHARE_LIST_EMPTY(keyshares) (keyshares |= 1)
+#define S2N_SET_KEY_SHARE_REQUEST(keyshares, i) (keyshares |= ( 1 << ( i + 1 )))
+
+static int s2n_connection_new_hashes(struct s2n_connection *conn)
+{
+ /* Allocate long-term memory for the Connection's hash states */
+ GUARD(s2n_hash_new(&conn->handshake.md5));
+ GUARD(s2n_hash_new(&conn->handshake.sha1));
+ GUARD(s2n_hash_new(&conn->handshake.sha224));
+ GUARD(s2n_hash_new(&conn->handshake.sha256));
+ GUARD(s2n_hash_new(&conn->handshake.sha384));
+ GUARD(s2n_hash_new(&conn->handshake.sha512));
+ GUARD(s2n_hash_new(&conn->handshake.md5_sha1));
+ GUARD(s2n_hash_new(&conn->handshake.ccv_hash_copy));
+ GUARD(s2n_hash_new(&conn->handshake.prf_md5_hash_copy));
+ GUARD(s2n_hash_new(&conn->handshake.prf_sha1_hash_copy));
+ GUARD(s2n_hash_new(&conn->handshake.prf_tls12_hash_copy));
+ GUARD(s2n_hash_new(&conn->handshake.server_finished_copy));
+ GUARD(s2n_hash_new(&conn->prf_space.ssl3.md5));
+ GUARD(s2n_hash_new(&conn->prf_space.ssl3.sha1));
+ GUARD(s2n_hash_new(&conn->initial.signature_hash));
+ GUARD(s2n_hash_new(&conn->secure.signature_hash));
+
+ return 0;
+}
+
+static int s2n_connection_init_hashes(struct s2n_connection *conn)
+{
+ /* Initialize all of the Connection's hash states */
+
+ if (s2n_hash_is_available(S2N_HASH_MD5)) {
+ /* Only initialize hashes that use MD5 if available. */
+ GUARD(s2n_hash_init(&conn->prf_space.ssl3.md5, S2N_HASH_MD5));
+ }
+
+
+ /* Allow MD5 for hash states that are used by the PRF. This is required
+ * to comply with the TLS 1.0 and 1.1 RFCs and is approved as per
+ * NIST Special Publication 800-52 Revision 1.
+ */
+ if (s2n_is_in_fips_mode()) {
+ GUARD(s2n_hash_allow_md5_for_fips(&conn->handshake.md5));
+ GUARD(s2n_hash_allow_md5_for_fips(&conn->handshake.prf_md5_hash_copy));
+
+ /* Do not check s2n_hash_is_available before initialization. Allow MD5 and
+ * SHA-1 for both fips and non-fips mode. This is required to perform the
+ * signature checks in the CertificateVerify message in TLS 1.0 and TLS 1.1.
+ * This is approved per Nist SP 800-52r1.*/
+ GUARD(s2n_hash_allow_md5_for_fips(&conn->handshake.md5_sha1));
+ }
+
+ GUARD(s2n_hash_init(&conn->handshake.md5, S2N_HASH_MD5));
+ GUARD(s2n_hash_init(&conn->handshake.prf_md5_hash_copy, S2N_HASH_MD5));
+ GUARD(s2n_hash_init(&conn->handshake.md5_sha1, S2N_HASH_MD5_SHA1));
+
+ GUARD(s2n_hash_init(&conn->handshake.sha1, S2N_HASH_SHA1));
+ GUARD(s2n_hash_init(&conn->handshake.sha224, S2N_HASH_SHA224));
+ GUARD(s2n_hash_init(&conn->handshake.sha256, S2N_HASH_SHA256));
+ GUARD(s2n_hash_init(&conn->handshake.sha384, S2N_HASH_SHA384));
+ GUARD(s2n_hash_init(&conn->handshake.sha512, S2N_HASH_SHA512));
+ GUARD(s2n_hash_init(&conn->handshake.ccv_hash_copy, S2N_HASH_NONE));
+ GUARD(s2n_hash_init(&conn->handshake.prf_tls12_hash_copy, S2N_HASH_NONE));
+ GUARD(s2n_hash_init(&conn->handshake.server_finished_copy, S2N_HASH_NONE));
+ GUARD(s2n_hash_init(&conn->handshake.prf_sha1_hash_copy, S2N_HASH_SHA1));
+ GUARD(s2n_hash_init(&conn->prf_space.ssl3.sha1, S2N_HASH_SHA1));
+ GUARD(s2n_hash_init(&conn->initial.signature_hash, S2N_HASH_NONE));
+ GUARD(s2n_hash_init(&conn->secure.signature_hash, S2N_HASH_NONE));
+
+ return 0;
+}
+
+static int s2n_connection_new_hmacs(struct s2n_connection *conn)
+{
+ /* Allocate long-term memory for the Connection's HMAC states */
+ GUARD(s2n_hmac_new(&conn->initial.client_record_mac));
+ GUARD(s2n_hmac_new(&conn->initial.server_record_mac));
+ GUARD(s2n_hmac_new(&conn->initial.record_mac_copy_workspace));
+ GUARD(s2n_hmac_new(&conn->secure.client_record_mac));
+ GUARD(s2n_hmac_new(&conn->secure.server_record_mac));
+ GUARD(s2n_hmac_new(&conn->secure.record_mac_copy_workspace));
+
+ return 0;
+}
+
+static int s2n_connection_init_hmacs(struct s2n_connection *conn)
+{
+ /* Initialize all of the Connection's HMAC states */
+ GUARD(s2n_hmac_init(&conn->initial.client_record_mac, S2N_HMAC_NONE, NULL, 0));
+ GUARD(s2n_hmac_init(&conn->initial.server_record_mac, S2N_HMAC_NONE, NULL, 0));
+ GUARD(s2n_hmac_init(&conn->initial.record_mac_copy_workspace, S2N_HMAC_NONE, NULL, 0));
+ GUARD(s2n_hmac_init(&conn->secure.client_record_mac, S2N_HMAC_NONE, NULL, 0));
+ GUARD(s2n_hmac_init(&conn->secure.server_record_mac, S2N_HMAC_NONE, NULL, 0));
+ GUARD(s2n_hmac_init(&conn->secure.record_mac_copy_workspace, S2N_HMAC_NONE, NULL, 0));
+
+ return 0;
+}
+
+struct s2n_connection *s2n_connection_new(s2n_mode mode)
+{
+ struct s2n_blob blob = {0};
+ GUARD_PTR(s2n_alloc(&blob, sizeof(struct s2n_connection)));
+ GUARD_PTR(s2n_blob_zero(&blob));
+
+ /* Cast 'through' void to acknowledge that we are changing alignment,
+ * which is ok, as blob.data is always aligned.
+ */
+ struct s2n_connection* conn = (struct s2n_connection *)(void *)blob.data;
+
+ GUARD_PTR(s2n_connection_set_config(conn, s2n_fetch_default_config()));
+
+ conn->mode = mode;
+ conn->blinding = S2N_BUILT_IN_BLINDING;
+ conn->close_notify_queued = 0;
+ conn->client_session_resumed = 0;
+ conn->session_id_len = 0;
+ conn->verify_host_fn = NULL;
+ conn->data_for_verify_host = NULL;
+ conn->verify_host_fn_overridden = 0;
+ conn->data_for_verify_host = NULL;
+ conn->send = NULL;
+ conn->recv = NULL;
+ conn->send_io_context = NULL;
+ conn->recv_io_context = NULL;
+ conn->managed_io = 0;
+ conn->corked_io = 0;
+ conn->context = NULL;
+ conn->security_policy_override = NULL;
+ conn->ticket_lifetime_hint = 0;
+ conn->session_ticket_status = S2N_NO_TICKET;
+
+ /* Allocate the fixed-size stuffers */
+ blob = (struct s2n_blob) {0};
+ GUARD_PTR(s2n_blob_init(&blob, conn->alert_in_data, S2N_ALERT_LENGTH));
+ GUARD_PTR(s2n_stuffer_init(&conn->alert_in, &blob));
+
+ blob = (struct s2n_blob) {0};
+ GUARD_PTR(s2n_blob_init(&blob, conn->reader_alert_out_data, S2N_ALERT_LENGTH));
+ GUARD_PTR(s2n_stuffer_init(&conn->reader_alert_out, &blob));
+
+ blob = (struct s2n_blob) {0};
+ GUARD_PTR(s2n_blob_init(&blob, conn->writer_alert_out_data, S2N_ALERT_LENGTH));
+ GUARD_PTR(s2n_stuffer_init(&conn->writer_alert_out, &blob));
+
+ blob = (struct s2n_blob) {0};
+ GUARD_PTR(s2n_blob_init(&blob, conn->ticket_ext_data, S2N_TICKET_SIZE_IN_BYTES));
+ GUARD_PTR(s2n_stuffer_init(&conn->client_ticket_to_decrypt, &blob));
+
+ /* Allocate long term key memory */
+ GUARD_PTR(s2n_session_key_alloc(&conn->secure.client_key));
+ GUARD_PTR(s2n_session_key_alloc(&conn->secure.server_key));
+ GUARD_PTR(s2n_session_key_alloc(&conn->initial.client_key));
+ GUARD_PTR(s2n_session_key_alloc(&conn->initial.server_key));
+
+ /* Allocate long term hash and HMAC memory */
+ GUARD_PTR(s2n_prf_new(conn));
+
+ GUARD_PTR(s2n_connection_new_hashes(conn));
+ GUARD_PTR(s2n_connection_init_hashes(conn));
+
+ GUARD_PTR(s2n_connection_new_hmacs(conn));
+ GUARD_PTR(s2n_connection_init_hmacs(conn));
+
+ /* Initialize the growable stuffers. Zero length at first, but the resize
+ * in _wipe will fix that
+ */
+ blob = (struct s2n_blob) {0};
+ GUARD_PTR(s2n_blob_init(&blob, conn->header_in_data, S2N_TLS_RECORD_HEADER_LENGTH));
+ GUARD_PTR(s2n_stuffer_init(&conn->header_in, &blob));
+ GUARD_PTR(s2n_stuffer_growable_alloc(&conn->out, 0));
+ GUARD_PTR(s2n_stuffer_growable_alloc(&conn->in, 0));
+ GUARD_PTR(s2n_stuffer_growable_alloc(&conn->handshake.io, 0));
+ GUARD_PTR(s2n_stuffer_growable_alloc(&conn->client_hello.raw_message, 0));
+ GUARD_PTR(s2n_connection_wipe(conn));
+ GUARD_RESULT_PTR(s2n_timer_start(conn->config, &conn->write_timer));
+
+ /* Initialize the cookie stuffer with zero length. If a cookie extension
+ * is received, the stuffer will be resized according to the cookie length */
+ GUARD_PTR(s2n_stuffer_growable_alloc(&conn->cookie_stuffer, 0));
+
+ return conn;
+}
+
+static int s2n_connection_free_keys(struct s2n_connection *conn)
+{
+ GUARD(s2n_session_key_free(&conn->secure.client_key));
+ GUARD(s2n_session_key_free(&conn->secure.server_key));
+ GUARD(s2n_session_key_free(&conn->initial.client_key));
+ GUARD(s2n_session_key_free(&conn->initial.server_key));
+
+ return 0;
+}
+
+static int s2n_connection_zero(struct s2n_connection *conn, int mode, struct s2n_config *config)
+{
+ /* Zero the whole connection structure */
+ memset_check(conn, 0, sizeof(struct s2n_connection));
+
+ conn->send = NULL;
+ conn->recv = NULL;
+ conn->send_io_context = NULL;
+ conn->recv_io_context = NULL;
+ conn->mode = mode;
+ conn->close_notify_queued = 0;
+ conn->client_session_resumed = 0;
+ conn->current_user_data_consumed = 0;
+ conn->initial.cipher_suite = &s2n_null_cipher_suite;
+ conn->secure.cipher_suite = &s2n_null_cipher_suite;
+ conn->initial.kem_params.kem = NULL;
+ conn->secure.kem_params.kem = NULL;
+ conn->server = &conn->initial;
+ conn->client = &conn->initial;
+ conn->max_outgoing_fragment_length = S2N_DEFAULT_FRAGMENT_LENGTH;
+ conn->mfl_code = S2N_TLS_MAX_FRAG_LEN_EXT_NONE;
+ conn->handshake.handshake_type = INITIAL;
+ conn->handshake.message_number = 0;
+ conn->handshake.paused = 0;
+ conn->verify_host_fn = NULL;
+ conn->verify_host_fn_overridden = 0;
+ conn->data_for_verify_host = NULL;
+ s2n_connection_set_config(conn, config);
+
+ return 0;
+}
+
+static int s2n_connection_wipe_keys(struct s2n_connection *conn)
+{
+ /* Destroy any keys - we call destroy on the object as that is where
+ * keys are allocated. */
+ if (conn->secure.cipher_suite
+ && conn->secure.cipher_suite->record_alg
+ && conn->secure.cipher_suite->record_alg->cipher
+ && conn->secure.cipher_suite->record_alg->cipher->destroy_key) {
+ GUARD(conn->secure.cipher_suite->record_alg->cipher->destroy_key(&conn->secure.client_key));
+ GUARD(conn->secure.cipher_suite->record_alg->cipher->destroy_key(&conn->secure.server_key));
+ }
+
+ /* Free any server key received (we may not have completed a
+ * handshake, so this may not have been free'd yet) */
+ GUARD(s2n_pkey_free(&conn->secure.server_public_key));
+ GUARD(s2n_pkey_zero_init(&conn->secure.server_public_key));
+ GUARD(s2n_pkey_free(&conn->secure.client_public_key));
+ GUARD(s2n_pkey_zero_init(&conn->secure.client_public_key));
+ s2n_x509_validator_wipe(&conn->x509_validator);
+ GUARD(s2n_dh_params_free(&conn->secure.server_dh_params));
+ GUARD(s2n_ecc_evp_params_free(&conn->secure.server_ecc_evp_params));
+ for (int i=0; i < S2N_ECC_EVP_SUPPORTED_CURVES_COUNT; i++) {
+ GUARD(s2n_ecc_evp_params_free(&conn->secure.client_ecc_evp_params[i]));
+ }
+ GUARD(s2n_kem_group_free(&conn->secure.server_kem_group_params));
+ for (int i = 0; i < S2N_SUPPORTED_KEM_GROUPS_COUNT; i++) {
+ GUARD(s2n_kem_group_free(&conn->secure.client_kem_group_params[i]));
+ }
+ GUARD(s2n_kem_free(&conn->secure.kem_params));
+ GUARD(s2n_free(&conn->secure.client_cert_chain));
+ GUARD(s2n_free(&conn->ct_response));
+
+ return 0;
+}
+
+static int s2n_connection_reset_hashes(struct s2n_connection *conn)
+{
+ /* Reset all of the Connection's hash states */
+ GUARD(s2n_hash_reset(&conn->handshake.md5));
+ GUARD(s2n_hash_reset(&conn->handshake.sha1));
+ GUARD(s2n_hash_reset(&conn->handshake.sha224));
+ GUARD(s2n_hash_reset(&conn->handshake.sha256));
+ GUARD(s2n_hash_reset(&conn->handshake.sha384));
+ GUARD(s2n_hash_reset(&conn->handshake.sha512));
+ GUARD(s2n_hash_reset(&conn->handshake.md5_sha1));
+ GUARD(s2n_hash_reset(&conn->handshake.ccv_hash_copy));
+ GUARD(s2n_hash_reset(&conn->handshake.prf_md5_hash_copy));
+ GUARD(s2n_hash_reset(&conn->handshake.prf_sha1_hash_copy));
+ GUARD(s2n_hash_reset(&conn->handshake.prf_tls12_hash_copy));
+ GUARD(s2n_hash_reset(&conn->handshake.server_finished_copy));
+ GUARD(s2n_hash_reset(&conn->prf_space.ssl3.md5));
+ GUARD(s2n_hash_reset(&conn->prf_space.ssl3.sha1));
+ GUARD(s2n_hash_reset(&conn->initial.signature_hash));
+ GUARD(s2n_hash_reset(&conn->secure.signature_hash));
+
+ return 0;
+}
+
+static int s2n_connection_reset_hmacs(struct s2n_connection *conn)
+{
+ /* Reset all of the Connection's HMAC states */
+ GUARD(s2n_hmac_reset(&conn->initial.client_record_mac));
+ GUARD(s2n_hmac_reset(&conn->initial.server_record_mac));
+ GUARD(s2n_hmac_reset(&conn->initial.record_mac_copy_workspace));
+ GUARD(s2n_hmac_reset(&conn->secure.client_record_mac));
+ GUARD(s2n_hmac_reset(&conn->secure.server_record_mac));
+ GUARD(s2n_hmac_reset(&conn->secure.record_mac_copy_workspace));
+
+ return 0;
+}
+
+static int s2n_connection_free_io_contexts(struct s2n_connection *conn)
+{
+ /* Free the I/O context if it was allocated by s2n. Don't touch user-controlled contexts. */
+ if (!conn->managed_io) {
+ return 0;
+ }
+
+ GUARD(s2n_free_object((uint8_t **)&conn->send_io_context, sizeof(struct s2n_socket_write_io_context)));
+ GUARD(s2n_free_object((uint8_t **)&conn->recv_io_context, sizeof(struct s2n_socket_read_io_context)));
+
+ return 0;
+}
+
+static int s2n_connection_wipe_io(struct s2n_connection *conn)
+{
+ if (s2n_connection_is_managed_corked(conn) && conn->recv){
+ GUARD(s2n_socket_read_restore(conn));
+ }
+ if (s2n_connection_is_managed_corked(conn) && conn->send){
+ GUARD(s2n_socket_write_restore(conn));
+ }
+
+ /* Remove all I/O-related members */
+ GUARD(s2n_connection_free_io_contexts(conn));
+ conn->managed_io = 0;
+ conn->send = NULL;
+ conn->recv = NULL;
+
+ return 0;
+}
+
+static int s2n_connection_free_hashes(struct s2n_connection *conn)
+{
+ /* Free all of the Connection's hash states */
+ GUARD(s2n_hash_free(&conn->handshake.md5));
+ GUARD(s2n_hash_free(&conn->handshake.sha1));
+ GUARD(s2n_hash_free(&conn->handshake.sha224));
+ GUARD(s2n_hash_free(&conn->handshake.sha256));
+ GUARD(s2n_hash_free(&conn->handshake.sha384));
+ GUARD(s2n_hash_free(&conn->handshake.sha512));
+ GUARD(s2n_hash_free(&conn->handshake.md5_sha1));
+ GUARD(s2n_hash_free(&conn->handshake.ccv_hash_copy));
+ GUARD(s2n_hash_free(&conn->handshake.prf_md5_hash_copy));
+ GUARD(s2n_hash_free(&conn->handshake.prf_sha1_hash_copy));
+ GUARD(s2n_hash_free(&conn->handshake.prf_tls12_hash_copy));
+ GUARD(s2n_hash_free(&conn->handshake.server_finished_copy));
+ GUARD(s2n_hash_free(&conn->prf_space.ssl3.md5));
+ GUARD(s2n_hash_free(&conn->prf_space.ssl3.sha1));
+ GUARD(s2n_hash_free(&conn->initial.signature_hash));
+ GUARD(s2n_hash_free(&conn->secure.signature_hash));
+
+ return 0;
+}
+
+static int s2n_connection_free_hmacs(struct s2n_connection *conn)
+{
+ /* Free all of the Connection's HMAC states */
+ GUARD(s2n_hmac_free(&conn->initial.client_record_mac));
+ GUARD(s2n_hmac_free(&conn->initial.server_record_mac));
+ GUARD(s2n_hmac_free(&conn->initial.record_mac_copy_workspace));
+ GUARD(s2n_hmac_free(&conn->secure.client_record_mac));
+ GUARD(s2n_hmac_free(&conn->secure.server_record_mac));
+ GUARD(s2n_hmac_free(&conn->secure.record_mac_copy_workspace));
+
+ return 0;
+}
+
+static uint8_t s2n_default_verify_host(const char *host_name, size_t len, void *data)
+{
+ /* if present, match server_name of the connection using rules
+ * outlined in RFC6125 6.4. */
+
+ struct s2n_connection *conn = data;
+
+ if (conn->server_name[0] == '\0') {
+ return 0;
+ }
+
+ /* complete match */
+ if (strlen(conn->server_name) == len &&
+ strncasecmp(conn->server_name, host_name, len) == 0) {
+ return 1;
+ }
+
+ /* match 1 level of wildcard */
+ if (len > 2 && host_name[0] == '*' && host_name[1] == '.') {
+ const char *suffix = strchr(conn->server_name, '.');
+
+ if (suffix == NULL) {
+ return 0;
+ }
+
+ if (strlen(suffix) == len - 1 &&
+ strncasecmp(suffix, host_name + 1, len - 1) == 0) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int s2n_connection_free(struct s2n_connection *conn)
+{
+ GUARD(s2n_connection_wipe_keys(conn));
+ GUARD(s2n_connection_free_keys(conn));
+ GUARD(s2n_psk_parameters_free(&conn->psk_params));
+
+ GUARD(s2n_prf_free(conn));
+
+ GUARD(s2n_connection_reset_hashes(conn));
+ GUARD(s2n_connection_free_hashes(conn));
+
+ GUARD(s2n_connection_reset_hmacs(conn));
+ GUARD(s2n_connection_free_hmacs(conn));
+
+ GUARD(s2n_connection_free_io_contexts(conn));
+
+ GUARD(s2n_free(&conn->client_ticket));
+ GUARD(s2n_free(&conn->status_response));
+ GUARD(s2n_free(&conn->our_quic_transport_parameters));
+ GUARD(s2n_free(&conn->peer_quic_transport_parameters));
+ GUARD(s2n_stuffer_free(&conn->in));
+ GUARD(s2n_stuffer_free(&conn->out));
+ GUARD(s2n_stuffer_free(&conn->handshake.io));
+ s2n_x509_validator_wipe(&conn->x509_validator);
+ GUARD(s2n_client_hello_free(&conn->client_hello));
+ GUARD(s2n_free(&conn->application_protocols_overridden));
+ GUARD(s2n_stuffer_free(&conn->cookie_stuffer));
+ GUARD(s2n_free_object((uint8_t **)&conn, sizeof(struct s2n_connection)));
+
+ return 0;
+}
+
+int s2n_connection_set_config(struct s2n_connection *conn, struct s2n_config *config)
+{
+ notnull_check(conn);
+ notnull_check(config);
+
+ if (conn->config == config) {
+ return 0;
+ }
+
+ /* We only support one client certificate */
+ if (s2n_config_get_num_default_certs(config) > 1 && conn->mode == S2N_CLIENT) {
+ S2N_ERROR(S2N_ERR_TOO_MANY_CERTIFICATES);
+ }
+
+ s2n_x509_validator_wipe(&conn->x509_validator);
+
+ s2n_cert_auth_type auth_type = config->client_cert_auth_type;
+
+ if (conn->client_cert_auth_type_overridden) {
+ auth_type = conn->client_cert_auth_type;
+ }
+
+ int8_t dont_need_x509_validation = (conn->mode == S2N_SERVER) && (auth_type == S2N_CERT_AUTH_NONE);
+
+ if (config->disable_x509_validation || dont_need_x509_validation) {
+ GUARD(s2n_x509_validator_init_no_x509_validation(&conn->x509_validator));
+ }
+ else {
+ GUARD(s2n_x509_validator_init(&conn->x509_validator, &config->trust_store, config->check_ocsp));
+ if (!conn->verify_host_fn_overridden) {
+ if (config->verify_host != NULL) {
+ conn->verify_host_fn = config->verify_host;
+ conn->data_for_verify_host = config->data_for_verify_host;
+ } else {
+ conn->verify_host_fn = s2n_default_verify_host;
+ conn->data_for_verify_host = conn;
+ }
+ }
+
+ if (config->max_verify_cert_chain_depth_set) {
+ GUARD(s2n_x509_validator_set_max_chain_depth(&conn->x509_validator, config->max_verify_cert_chain_depth));
+ }
+ }
+
+ conn->config = config;
+ return 0;
+}
+
+int s2n_connection_set_ctx(struct s2n_connection *conn, void *ctx)
+{
+ conn->context = ctx;
+ return 0;
+}
+
+void *s2n_connection_get_ctx(struct s2n_connection *conn)
+{
+ return conn->context;
+}
+
+int s2n_connection_release_buffers(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+ PRECONDITION_POSIX(s2n_stuffer_validate(&conn->out));
+ PRECONDITION_POSIX(s2n_stuffer_validate(&conn->in));
+
+ ENSURE_POSIX(s2n_stuffer_is_consumed(&conn->out), S2N_ERR_STUFFER_HAS_UNPROCESSED_DATA);
+ GUARD(s2n_stuffer_resize(&conn->out, 0));
+
+ ENSURE_POSIX(s2n_stuffer_is_consumed(&conn->in), S2N_ERR_STUFFER_HAS_UNPROCESSED_DATA);
+ GUARD(s2n_stuffer_resize(&conn->in, 0));
+
+ POSTCONDITION_POSIX(s2n_stuffer_validate(&conn->out));
+ POSTCONDITION_POSIX(s2n_stuffer_validate(&conn->in));
+ return S2N_SUCCESS;
+}
+
+int s2n_connection_free_handshake(struct s2n_connection *conn)
+{
+ /* We are done with the handshake */
+ GUARD(s2n_hash_reset(&conn->handshake.md5));
+ GUARD(s2n_hash_reset(&conn->handshake.sha1));
+ GUARD(s2n_hash_reset(&conn->handshake.sha224));
+ GUARD(s2n_hash_reset(&conn->handshake.sha256));
+ GUARD(s2n_hash_reset(&conn->handshake.sha384));
+ GUARD(s2n_hash_reset(&conn->handshake.sha512));
+ GUARD(s2n_hash_reset(&conn->handshake.md5_sha1));
+ GUARD(s2n_hash_reset(&conn->handshake.ccv_hash_copy));
+ GUARD(s2n_hash_reset(&conn->handshake.prf_md5_hash_copy));
+ GUARD(s2n_hash_reset(&conn->handshake.prf_sha1_hash_copy));
+ GUARD(s2n_hash_reset(&conn->handshake.prf_tls12_hash_copy));
+ GUARD(s2n_hash_reset(&conn->handshake.server_finished_copy));
+
+ /* Wipe the buffers we are going to free */
+ GUARD(s2n_stuffer_wipe(&conn->handshake.io));
+ GUARD(s2n_stuffer_wipe(&conn->client_hello.raw_message));
+
+ /* Truncate buffers to save memory, we are done with the handshake */
+ GUARD(s2n_stuffer_resize(&conn->handshake.io, 0));
+ GUARD(s2n_stuffer_resize(&conn->client_hello.raw_message, 0));
+
+ /* We can free extension data we no longer need */
+ GUARD(s2n_free(&conn->client_ticket));
+ GUARD(s2n_free(&conn->status_response));
+ GUARD(s2n_free(&conn->our_quic_transport_parameters));
+ GUARD(s2n_free(&conn->application_protocols_overridden));
+ GUARD(s2n_stuffer_free(&conn->cookie_stuffer));
+
+ return 0;
+}
+
+int s2n_connection_wipe(struct s2n_connection *conn)
+{
+ /* First make a copy of everything we'd like to save, which isn't very much. */
+ int mode = conn->mode;
+ struct s2n_config *config = conn->config;
+ struct s2n_stuffer alert_in = {0};
+ struct s2n_stuffer reader_alert_out = {0};
+ struct s2n_stuffer writer_alert_out = {0};
+ struct s2n_stuffer client_ticket_to_decrypt = {0};
+ struct s2n_stuffer handshake_io = {0};
+ struct s2n_stuffer client_hello_raw_message = {0};
+ struct s2n_stuffer header_in = {0};
+ struct s2n_stuffer in = {0};
+ struct s2n_stuffer out = {0};
+ /* Session keys will be wiped. Preserve structs to avoid reallocation */
+ struct s2n_session_key initial_client_key = {0};
+ struct s2n_session_key initial_server_key = {0};
+ struct s2n_session_key secure_client_key = {0};
+ struct s2n_session_key secure_server_key = {0};
+ /* Parts of the PRF working space, hash states, and hmac states will be wiped. Preserve structs to avoid reallocation */
+ struct s2n_connection_prf_handles prf_handles = {0};
+ struct s2n_connection_hash_handles hash_handles = {0};
+ struct s2n_connection_hmac_handles hmac_handles = {0};
+
+ /* Wipe all of the sensitive stuff */
+ GUARD(s2n_connection_wipe_keys(conn));
+ GUARD(s2n_connection_reset_hashes(conn));
+ GUARD(s2n_connection_reset_hmacs(conn));
+ GUARD(s2n_stuffer_wipe(&conn->alert_in));
+ GUARD(s2n_stuffer_wipe(&conn->reader_alert_out));
+ GUARD(s2n_stuffer_wipe(&conn->writer_alert_out));
+ GUARD(s2n_stuffer_wipe(&conn->client_ticket_to_decrypt));
+ GUARD(s2n_stuffer_wipe(&conn->handshake.io));
+ GUARD(s2n_stuffer_wipe(&conn->client_hello.raw_message));
+ GUARD(s2n_stuffer_wipe(&conn->header_in));
+ GUARD(s2n_stuffer_wipe(&conn->in));
+ GUARD(s2n_stuffer_wipe(&conn->out));
+
+ GUARD_AS_POSIX(s2n_psk_parameters_wipe(&conn->psk_params));
+
+ /* Wipe the I/O-related info and restore the original socket if necessary */
+ GUARD(s2n_connection_wipe_io(conn));
+
+ GUARD(s2n_free(&conn->client_ticket));
+ GUARD(s2n_free(&conn->status_response));
+ GUARD(s2n_free(&conn->application_protocols_overridden));
+ GUARD(s2n_free(&conn->our_quic_transport_parameters));
+ GUARD(s2n_free(&conn->peer_quic_transport_parameters));
+
+ /* Allocate memory for handling handshakes */
+ GUARD(s2n_stuffer_resize(&conn->handshake.io, S2N_LARGE_RECORD_LENGTH));
+
+ /* Truncate the message buffers to save memory, we will dynamically resize it as needed */
+ GUARD(s2n_stuffer_resize(&conn->client_hello.raw_message, 0));
+ GUARD(s2n_stuffer_resize(&conn->in, 0));
+ GUARD(s2n_stuffer_resize(&conn->out, 0));
+
+ /* Remove context associated with connection */
+ conn->context = NULL;
+ conn->verify_host_fn_overridden = 0;
+ conn->verify_host_fn = NULL;
+ conn->data_for_verify_host = NULL;
+
+ /* Clone the stuffers */
+ /* ignore gcc 4.7 address warnings because dest is allocated on the stack */
+ /* pragma gcc diagnostic was added in gcc 4.6 */
+#if S2N_GCC_VERSION_AT_LEAST(4,6,0)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Waddress"
+#endif
+ memcpy_check(&alert_in, &conn->alert_in, sizeof(struct s2n_stuffer));
+ memcpy_check(&reader_alert_out, &conn->reader_alert_out, sizeof(struct s2n_stuffer));
+ memcpy_check(&writer_alert_out, &conn->writer_alert_out, sizeof(struct s2n_stuffer));
+ memcpy_check(&client_ticket_to_decrypt, &conn->client_ticket_to_decrypt, sizeof(struct s2n_stuffer));
+ memcpy_check(&handshake_io, &conn->handshake.io, sizeof(struct s2n_stuffer));
+ memcpy_check(&client_hello_raw_message, &conn->client_hello.raw_message, sizeof(struct s2n_stuffer));
+ memcpy_check(&header_in, &conn->header_in, sizeof(struct s2n_stuffer));
+ memcpy_check(&in, &conn->in, sizeof(struct s2n_stuffer));
+ memcpy_check(&out, &conn->out, sizeof(struct s2n_stuffer));
+ memcpy_check(&initial_client_key, &conn->initial.client_key, sizeof(struct s2n_session_key));
+ memcpy_check(&initial_server_key, &conn->initial.server_key, sizeof(struct s2n_session_key));
+ memcpy_check(&secure_client_key, &conn->secure.client_key, sizeof(struct s2n_session_key));
+ memcpy_check(&secure_server_key, &conn->secure.server_key, sizeof(struct s2n_session_key));
+ GUARD(s2n_connection_save_prf_state(&prf_handles, conn));
+ GUARD(s2n_connection_save_hash_state(&hash_handles, conn));
+ GUARD(s2n_connection_save_hmac_state(&hmac_handles, conn));
+#if S2N_GCC_VERSION_AT_LEAST(4,6,0)
+#pragma GCC diagnostic pop
+#endif
+
+ GUARD(s2n_connection_zero(conn, mode, config));
+
+ memcpy_check(&conn->alert_in, &alert_in, sizeof(struct s2n_stuffer));
+ memcpy_check(&conn->reader_alert_out, &reader_alert_out, sizeof(struct s2n_stuffer));
+ memcpy_check(&conn->writer_alert_out, &writer_alert_out, sizeof(struct s2n_stuffer));
+ memcpy_check(&conn->client_ticket_to_decrypt, &client_ticket_to_decrypt, sizeof(struct s2n_stuffer));
+ memcpy_check(&conn->handshake.io, &handshake_io, sizeof(struct s2n_stuffer));
+ memcpy_check(&conn->client_hello.raw_message, &client_hello_raw_message, sizeof(struct s2n_stuffer));
+ memcpy_check(&conn->header_in, &header_in, sizeof(struct s2n_stuffer));
+ memcpy_check(&conn->in, &in, sizeof(struct s2n_stuffer));
+ memcpy_check(&conn->out, &out, sizeof(struct s2n_stuffer));
+ memcpy_check(&conn->initial.client_key, &initial_client_key, sizeof(struct s2n_session_key));
+ memcpy_check(&conn->initial.server_key, &initial_server_key, sizeof(struct s2n_session_key));
+ memcpy_check(&conn->secure.client_key, &secure_client_key, sizeof(struct s2n_session_key));
+ memcpy_check(&conn->secure.server_key, &secure_server_key, sizeof(struct s2n_session_key));
+ GUARD(s2n_connection_restore_prf_state(conn, &prf_handles));
+ GUARD(s2n_connection_restore_hash_state(conn, &hash_handles));
+ GUARD(s2n_connection_restore_hmac_state(conn, &hmac_handles));
+
+ /* Re-initialize hash and hmac states */
+ GUARD(s2n_connection_init_hashes(conn));
+ GUARD(s2n_connection_init_hmacs(conn));
+
+ GUARD_AS_POSIX(s2n_psk_parameters_init(&conn->psk_params));
+
+ /* Require all handshakes hashes. This set can be reduced as the handshake progresses. */
+ GUARD(s2n_handshake_require_all_hashes(&conn->handshake));
+
+ if (conn->mode == S2N_SERVER) {
+ /* Start with the highest protocol version so that the highest common protocol version can be selected */
+ /* during handshake. */
+ conn->server_protocol_version = s2n_highest_protocol_version;
+ conn->client_protocol_version = s2n_unknown_protocol_version;
+ conn->actual_protocol_version = s2n_unknown_protocol_version;
+ }
+ else {
+ /* For clients, also set actual_protocol_version. Record generation uses that value for the initial */
+ /* ClientHello record version. Not all servers ignore the record version in ClientHello. */
+ conn->server_protocol_version = s2n_unknown_protocol_version;
+ conn->client_protocol_version = s2n_highest_protocol_version;
+ conn->actual_protocol_version = s2n_highest_protocol_version;
+ }
+
+ return 0;
+}
+
+int s2n_connection_set_recv_ctx(struct s2n_connection *conn, void *ctx)
+{
+ conn->recv_io_context = ctx;
+ return 0;
+}
+
+int s2n_connection_set_send_ctx(struct s2n_connection *conn, void *ctx)
+{
+ conn->send_io_context = ctx;
+ return 0;
+}
+
+int s2n_connection_set_recv_cb(struct s2n_connection *conn, s2n_recv_fn recv)
+{
+ conn->recv = recv;
+ return 0;
+}
+
+int s2n_connection_set_send_cb(struct s2n_connection *conn, s2n_send_fn send)
+{
+ conn->send = send;
+ return 0;
+}
+
+int s2n_connection_get_client_cert_chain(struct s2n_connection *conn, uint8_t **der_cert_chain_out, uint32_t *cert_chain_len)
+{
+ notnull_check(conn);
+ notnull_check(der_cert_chain_out);
+ notnull_check(cert_chain_len);
+ notnull_check(conn->secure.client_cert_chain.data);
+
+ *der_cert_chain_out = conn->secure.client_cert_chain.data;
+ *cert_chain_len = conn->secure.client_cert_chain.size;
+
+ return 0;
+}
+
+int s2n_connection_get_cipher_preferences(struct s2n_connection *conn, const struct s2n_cipher_preferences **cipher_preferences)
+{
+ notnull_check(conn);
+ notnull_check(conn->config);
+ notnull_check(cipher_preferences);
+
+ if (conn->security_policy_override != NULL) {
+ *cipher_preferences = conn->security_policy_override->cipher_preferences;
+ } else if (conn->config->security_policy != NULL) {
+ *cipher_preferences = conn->config->security_policy->cipher_preferences;
+ } else {
+ S2N_ERROR(S2N_ERR_INVALID_CIPHER_PREFERENCES);
+ }
+
+ notnull_check(*cipher_preferences);
+ return 0;
+}
+
+int s2n_connection_get_security_policy(struct s2n_connection *conn, const struct s2n_security_policy **security_policy)
+{
+ notnull_check(conn);
+ notnull_check(conn->config);
+ notnull_check(security_policy);
+
+ if (conn->security_policy_override != NULL) {
+ *security_policy = conn->security_policy_override;
+ } else if (conn->config->security_policy != NULL) {
+ *security_policy = conn->config->security_policy;
+ } else {
+ S2N_ERROR(S2N_ERR_INVALID_SECURITY_POLICY);
+ }
+
+ notnull_check(*security_policy);
+ return 0;
+}
+
+int s2n_connection_get_kem_preferences(struct s2n_connection *conn, const struct s2n_kem_preferences **kem_preferences)
+{
+ notnull_check(conn);
+ notnull_check(conn->config);
+ notnull_check(kem_preferences);
+
+ if (conn->security_policy_override != NULL) {
+ *kem_preferences = conn->security_policy_override->kem_preferences;
+ } else if (conn->config->security_policy != NULL) {
+ *kem_preferences = conn->config->security_policy->kem_preferences;
+ } else {
+ S2N_ERROR(S2N_ERR_INVALID_KEM_PREFERENCES);
+ }
+
+ notnull_check(*kem_preferences);
+ return 0;
+}
+
+int s2n_connection_get_signature_preferences(struct s2n_connection *conn, const struct s2n_signature_preferences **signature_preferences)
+{
+ notnull_check(conn);
+ notnull_check(conn->config);
+ notnull_check(signature_preferences);
+
+ if (conn->security_policy_override != NULL) {
+ *signature_preferences = conn->security_policy_override->signature_preferences;
+ } else if (conn->config->security_policy != NULL) {
+ *signature_preferences = conn->config->security_policy->signature_preferences;
+ } else {
+ S2N_ERROR(S2N_ERR_INVALID_SIGNATURE_ALGORITHMS_PREFERENCES);
+ }
+
+ notnull_check(*signature_preferences);
+ return 0;
+
+}
+
+int s2n_connection_get_ecc_preferences(struct s2n_connection *conn, const struct s2n_ecc_preferences **ecc_preferences)
+{
+ notnull_check(conn);
+ notnull_check(conn->config);
+ notnull_check(ecc_preferences);
+
+ if (conn->security_policy_override != NULL) {
+ *ecc_preferences = conn->security_policy_override->ecc_preferences;
+ } else if (conn->config->security_policy != NULL) {
+ *ecc_preferences = conn->config->security_policy->ecc_preferences;
+ } else {
+ S2N_ERROR(S2N_ERR_INVALID_ECC_PREFERENCES);
+ }
+
+ notnull_check(*ecc_preferences);
+ return 0;
+
+}
+
+int s2n_connection_get_protocol_preferences(struct s2n_connection *conn, struct s2n_blob **protocol_preferences)
+{
+ notnull_check(conn);
+ notnull_check(protocol_preferences);
+
+ *protocol_preferences = NULL;
+ if (conn->application_protocols_overridden.size > 0) {
+ *protocol_preferences = &conn->application_protocols_overridden;
+ } else {
+ *protocol_preferences = &conn->config->application_protocols;
+ }
+
+ notnull_check(*protocol_preferences);
+ return 0;
+}
+
+int s2n_connection_get_client_auth_type(struct s2n_connection *conn, s2n_cert_auth_type *client_cert_auth_type)
+{
+ notnull_check(conn);
+ notnull_check(client_cert_auth_type);
+
+ if (conn->client_cert_auth_type_overridden) {
+ *client_cert_auth_type = conn->client_cert_auth_type;
+ } else {
+ *client_cert_auth_type = conn->config->client_cert_auth_type;
+ }
+
+ return 0;
+}
+
+int s2n_connection_set_client_auth_type(struct s2n_connection *conn, s2n_cert_auth_type client_cert_auth_type)
+{
+ conn->client_cert_auth_type_overridden = 1;
+ conn->client_cert_auth_type = client_cert_auth_type;
+ return 0;
+}
+
+int s2n_connection_set_read_fd(struct s2n_connection *conn, int rfd)
+{
+ struct s2n_blob ctx_mem = {0};
+ struct s2n_socket_read_io_context *peer_socket_ctx;
+
+ GUARD(s2n_alloc(&ctx_mem, sizeof(struct s2n_socket_read_io_context)));
+ GUARD(s2n_blob_zero(&ctx_mem));
+
+ peer_socket_ctx = (struct s2n_socket_read_io_context *)(void *)ctx_mem.data;
+ peer_socket_ctx->fd = rfd;
+
+ s2n_connection_set_recv_cb(conn, s2n_socket_read);
+ s2n_connection_set_recv_ctx(conn, peer_socket_ctx);
+ conn->managed_io = 1;
+
+ /* This is only needed if the user is using corked io.
+ * Take the snapshot in case optimized io is enabled after setting the fd.
+ */
+ GUARD(s2n_socket_read_snapshot(conn));
+
+ return 0;
+}
+
+int s2n_connection_set_write_fd(struct s2n_connection *conn, int wfd)
+{
+ struct s2n_blob ctx_mem = {0};
+ struct s2n_socket_write_io_context *peer_socket_ctx;
+
+ GUARD(s2n_alloc(&ctx_mem, sizeof(struct s2n_socket_write_io_context)));
+
+ peer_socket_ctx = (struct s2n_socket_write_io_context *)(void *)ctx_mem.data;
+ peer_socket_ctx->fd = wfd;
+
+ s2n_connection_set_send_cb(conn, s2n_socket_write);
+ s2n_connection_set_send_ctx(conn, peer_socket_ctx);
+ conn->managed_io = 1;
+
+ /* This is only needed if the user is using corked io.
+ * Take the snapshot in case optimized io is enabled after setting the fd.
+ */
+ GUARD(s2n_socket_write_snapshot(conn));
+
+ uint8_t ipv6;
+ if (0 == s2n_socket_is_ipv6(wfd, &ipv6)) {
+ conn->ipv6 = (ipv6 ? 1 : 0);
+ }
+
+ conn->write_fd_broken = 0;
+
+ return 0;
+}
+
+int s2n_connection_set_fd(struct s2n_connection *conn, int fd)
+{
+ GUARD(s2n_connection_set_read_fd(conn, fd));
+ GUARD(s2n_connection_set_write_fd(conn, fd));
+ return 0;
+}
+
+int s2n_connection_use_corked_io(struct s2n_connection *conn)
+{
+ if (!conn->managed_io) {
+ /* Caller shouldn't be trying to set s2n IO corked on non-s2n-managed IO */
+ S2N_ERROR(S2N_ERR_CORK_SET_ON_UNMANAGED);
+ }
+ conn->corked_io = 1;
+
+ return 0;
+}
+
+uint64_t s2n_connection_get_wire_bytes_in(struct s2n_connection *conn)
+{
+ return conn->wire_bytes_in;
+}
+
+uint64_t s2n_connection_get_wire_bytes_out(struct s2n_connection *conn)
+{
+ return conn->wire_bytes_out;
+}
+
+const char *s2n_connection_get_cipher(struct s2n_connection *conn)
+{
+ notnull_check_ptr(conn);
+ notnull_check_ptr(conn->secure.cipher_suite);
+
+ return conn->secure.cipher_suite->name;
+}
+
+const char *s2n_connection_get_curve(struct s2n_connection *conn)
+{
+ notnull_check_ptr(conn);
+
+ if (!conn->secure.server_ecc_evp_params.negotiated_curve) {
+ return "NONE";
+ }
+
+ return conn->secure.server_ecc_evp_params.negotiated_curve->name;
+}
+
+const char *s2n_connection_get_kem_name(struct s2n_connection *conn)
+{
+ notnull_check_ptr(conn);
+
+ if (!conn->secure.kem_params.kem) {
+ return "NONE";
+ }
+
+ return conn->secure.kem_params.kem->name;
+}
+
+const char *s2n_connection_get_kem_group_name(struct s2n_connection *conn)
+{
+ notnull_check_ptr(conn);
+
+ if (!conn->secure.chosen_client_kem_group_params || !conn->secure.chosen_client_kem_group_params->kem_group) {
+ return "NONE";
+ }
+
+ return conn->secure.chosen_client_kem_group_params->kem_group->name;
+}
+
+int s2n_connection_get_client_protocol_version(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ return conn->client_protocol_version;
+}
+
+int s2n_connection_get_server_protocol_version(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ return conn->server_protocol_version;
+}
+
+int s2n_connection_get_actual_protocol_version(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ return conn->actual_protocol_version;
+}
+
+int s2n_connection_get_client_hello_version(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ return conn->client_hello_version;
+}
+
+int s2n_connection_client_cert_used(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ if ((conn->handshake.handshake_type & CLIENT_AUTH) && is_handshake_complete(conn)) {
+ if (conn->handshake.handshake_type & NO_CLIENT_CERT) {
+ return 0;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+int s2n_connection_get_alert(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ S2N_ERROR_IF(s2n_stuffer_data_available(&conn->alert_in) != 2, S2N_ERR_NO_ALERT);
+
+ uint8_t alert_code = 0;
+ GUARD(s2n_stuffer_read_uint8(&conn->alert_in, &alert_code));
+ GUARD(s2n_stuffer_read_uint8(&conn->alert_in, &alert_code));
+
+ return alert_code;
+}
+
+int s2n_set_server_name(struct s2n_connection *conn, const char *server_name)
+{
+ notnull_check(conn);
+ notnull_check(server_name);
+
+ S2N_ERROR_IF(conn->mode != S2N_CLIENT, S2N_ERR_CLIENT_MODE);
+
+ int len = strlen(server_name);
+ S2N_ERROR_IF(len > S2N_MAX_SERVER_NAME, S2N_ERR_SERVER_NAME_TOO_LONG);
+
+ memcpy_check(conn->server_name, server_name, len);
+
+ return 0;
+}
+
+const char *s2n_get_server_name(struct s2n_connection *conn)
+{
+ notnull_check_ptr(conn);
+
+ if (conn->server_name[0]) {
+ return conn->server_name;
+ }
+
+ GUARD_PTR(s2n_extension_process(&s2n_client_server_name_extension, conn, &conn->client_hello.extensions));
+
+ if (!conn->server_name[0]) {
+ return NULL;
+ }
+
+ return conn->server_name;
+}
+
+const char *s2n_get_application_protocol(struct s2n_connection *conn)
+{
+ notnull_check_ptr(conn);
+
+ if (strlen(conn->application_protocol) == 0) {
+ return NULL;
+ }
+
+ return conn->application_protocol;
+}
+
+int s2n_connection_get_session_id_length(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+ return conn->session_id_len;
+}
+
+int s2n_connection_get_session_id(struct s2n_connection *conn, uint8_t *session_id, size_t max_length)
+{
+ notnull_check(conn);
+ notnull_check(session_id);
+
+ int session_id_len = s2n_connection_get_session_id_length(conn);
+
+ S2N_ERROR_IF(session_id_len > max_length, S2N_ERR_SESSION_ID_TOO_LONG);
+
+ memcpy_check(session_id, conn->session_id, session_id_len);
+
+ return session_id_len;
+}
+
+int s2n_connection_set_blinding(struct s2n_connection *conn, s2n_blinding blinding)
+{
+ notnull_check(conn);
+ conn->blinding = blinding;
+
+ return 0;
+}
+
+#define ONE_S INT64_C(1000000000)
+#define TEN_S INT64_C(10000000000)
+
+uint64_t s2n_connection_get_delay(struct s2n_connection *conn)
+{
+ if (!conn->delay) {
+ return 0;
+ }
+
+ uint64_t elapsed;
+ /* This will cast -1 to max uint64_t */
+ GUARD_AS_POSIX(s2n_timer_elapsed(conn->config, &conn->write_timer, &elapsed));
+
+ if (elapsed > conn->delay) {
+ return 0;
+ }
+
+ return conn->delay - elapsed;
+}
+
+int s2n_connection_kill(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ conn->closed = 1;
+
+ /* Delay between 10 and 30 seconds in nanoseconds */
+ int64_t min = TEN_S, max = 3 * TEN_S;
+
+ /* Keep track of the delay so that it can be enforced */
+ uint64_t rand_delay = 0;
+ GUARD_AS_POSIX(s2n_public_random(max - min, &rand_delay));
+
+ conn->delay = min + rand_delay;
+
+ /* Restart the write timer */
+ GUARD_AS_POSIX(s2n_timer_start(conn->config, &conn->write_timer));
+
+ if (conn->blinding == S2N_BUILT_IN_BLINDING) {
+ struct timespec sleep_time = {.tv_sec = conn->delay / ONE_S,.tv_nsec = conn->delay % ONE_S };
+ int r;
+
+ do {
+ r = nanosleep(&sleep_time, &sleep_time);
+ }
+ while (r != 0);
+ }
+
+ return 0;
+}
+
+const uint8_t *s2n_connection_get_ocsp_response(struct s2n_connection *conn, uint32_t * length)
+{
+ notnull_check_ptr(conn);
+ notnull_check_ptr(length);
+
+ *length = conn->status_response.size;
+ return conn->status_response.data;
+}
+
+int s2n_connection_prefer_throughput(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ if (!conn->mfl_code) {
+ conn->max_outgoing_fragment_length = S2N_LARGE_FRAGMENT_LENGTH;
+ }
+
+ return 0;
+}
+
+int s2n_connection_prefer_low_latency(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ if (!conn->mfl_code) {
+ conn->max_outgoing_fragment_length = S2N_SMALL_FRAGMENT_LENGTH;
+ }
+
+ return 0;
+}
+
+int s2n_connection_set_dynamic_record_threshold(struct s2n_connection *conn, uint32_t resize_threshold, uint16_t timeout_threshold)
+{
+ notnull_check(conn);
+ S2N_ERROR_IF(resize_threshold > S2N_TLS_MAX_RESIZE_THRESHOLD, S2N_ERR_INVALID_DYNAMIC_THRESHOLD);
+
+ conn->dynamic_record_resize_threshold = resize_threshold;
+ conn->dynamic_record_timeout_threshold = timeout_threshold;
+ return 0;
+}
+
+int s2n_connection_set_verify_host_callback(struct s2n_connection *conn, s2n_verify_host_fn verify_host_fn, void *data) {
+ notnull_check(conn);
+
+ conn->verify_host_fn = verify_host_fn;
+ conn->data_for_verify_host = data;
+ conn->verify_host_fn_overridden = 1;
+
+ return 0;
+}
+
+int s2n_connection_recv_stuffer(struct s2n_stuffer *stuffer, struct s2n_connection *conn, uint32_t len)
+{
+ notnull_check(conn->recv);
+ /* Make sure we have enough space to write */
+ GUARD(s2n_stuffer_reserve_space(stuffer, len));
+
+ int r = 0;
+ do {
+ errno = 0;
+ r = conn->recv(conn->recv_io_context, stuffer->blob.data + stuffer->write_cursor, len);
+ S2N_ERROR_IF(r < 0 && errno != EINTR, S2N_ERR_RECV_STUFFER_FROM_CONN);
+ } while (r < 0);
+
+ /* Record just how many bytes we have written */
+ GUARD(s2n_stuffer_skip_write(stuffer, r));
+ return r;
+}
+
+int s2n_connection_send_stuffer(struct s2n_stuffer *stuffer, struct s2n_connection *conn, uint32_t len)
+{
+ notnull_check(conn);
+ notnull_check(conn->send);
+ if (conn->write_fd_broken) {
+ S2N_ERROR(S2N_ERR_SEND_STUFFER_TO_CONN);
+ }
+ /* Make sure we even have the data */
+ S2N_ERROR_IF(s2n_stuffer_data_available(stuffer) < len, S2N_ERR_STUFFER_OUT_OF_DATA);
+
+ int w = 0;
+ do {
+ errno = 0;
+ w = conn->send(conn->send_io_context, stuffer->blob.data + stuffer->read_cursor, len);
+ if (w < 0 && errno == EPIPE) {
+ conn->write_fd_broken = 1;
+ }
+ S2N_ERROR_IF(w < 0 && errno != EINTR, S2N_ERR_SEND_STUFFER_TO_CONN);
+ } while (w < 0);
+
+ GUARD(s2n_stuffer_skip_read(stuffer, w));
+ return w;
+}
+
+int s2n_connection_is_managed_corked(const struct s2n_connection *s2n_connection)
+{
+ notnull_check(s2n_connection);
+
+ return (s2n_connection->managed_io && s2n_connection->corked_io);
+}
+
+const uint8_t *s2n_connection_get_sct_list(struct s2n_connection *conn, uint32_t *length)
+{
+ if (!length) {
+ return NULL;
+ }
+
+ *length = conn->ct_response.size;
+ return conn->ct_response.data;
+}
+
+int s2n_connection_is_client_auth_enabled(struct s2n_connection *s2n_connection)
+{
+ s2n_cert_auth_type auth_type;
+ GUARD(s2n_connection_get_client_auth_type(s2n_connection, &auth_type));
+
+ return (auth_type != S2N_CERT_AUTH_NONE);
+}
+
+struct s2n_cert_chain_and_key *s2n_connection_get_selected_cert(struct s2n_connection *conn)
+{
+ notnull_check_ptr(conn);
+ return conn->handshake_params.our_chain_and_key;
+}
+
+uint8_t s2n_connection_get_protocol_version(const struct s2n_connection *conn)
+{
+ if (conn == NULL) {
+ return S2N_UNKNOWN_PROTOCOL_VERSION;
+ }
+
+ if (conn->actual_protocol_version != S2N_UNKNOWN_PROTOCOL_VERSION) {
+ return conn->actual_protocol_version;
+ }
+
+ if (conn->mode == S2N_CLIENT) {
+ return conn->client_protocol_version;
+ }
+ return conn->server_protocol_version;
+}
+
+int s2n_connection_set_keyshare_by_name_for_testing(struct s2n_connection *conn, const char* curve_name)
+{
+ ENSURE_POSIX(S2N_IN_TEST, S2N_ERR_NOT_IN_TEST);
+ notnull_check(conn);
+
+ if (!strcmp(curve_name, "none")) {
+ S2N_SET_KEY_SHARE_LIST_EMPTY(conn->preferred_key_shares);
+ return S2N_SUCCESS;
+ }
+
+ const struct s2n_ecc_preferences *ecc_pref = NULL;
+ GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
+ notnull_check(ecc_pref);
+
+ for (size_t i = 0; i < ecc_pref->count; i++) {
+ if (!strcmp(ecc_pref->ecc_curves[i]->name, curve_name)) {
+ S2N_SET_KEY_SHARE_REQUEST(conn->preferred_key_shares, i);
+ return S2N_SUCCESS;
+ }
+ }
+
+ S2N_ERROR(S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_connection.h b/contrib/restricted/aws/s2n/tls/s2n_connection.h
index 9dac38db8a..5ba5667fc2 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_connection.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_connection.h
@@ -1,349 +1,349 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <errno.h>
-#include <s2n.h>
-#include <signal.h>
-#include <stdint.h>
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "tls/s2n_client_hello.h"
-#include "tls/s2n_config.h"
-#include "tls/s2n_crypto.h"
-#include "tls/s2n_handshake.h"
-#include "tls/s2n_prf.h"
-#include "tls/s2n_quic_support.h"
-#include "tls/s2n_tls_parameters.h"
-#include "tls/s2n_x509_validator.h"
-#include "tls/s2n_key_update.h"
-#include "tls/s2n_kem_preferences.h"
-#include "tls/s2n_ecc_preferences.h"
-#include "tls/s2n_security_policies.h"
-
-#include "crypto/s2n_hash.h"
-#include "crypto/s2n_hmac.h"
-
-#include "utils/s2n_mem.h"
-#include "utils/s2n_timer.h"
-
-#define S2N_TLS_PROTOCOL_VERSION_LEN 2
-
-#define is_handshake_complete(conn) (APPLICATION_DATA == s2n_conn_get_current_message_type(conn))
-
-typedef enum {
- S2N_NO_TICKET = 0,
- S2N_DECRYPT_TICKET,
- S2N_NEW_TICKET
-} s2n_session_ticket_status;
-
-struct s2n_connection {
- /* The configuration (cert, key .. etc ) */
- struct s2n_config *config;
-
- /* Overrides Security Policy in config if non-null */
- const struct s2n_security_policy *security_policy_override;
-
- /* The user defined context associated with connection */
- void *context;
-
- /* The user defined secret callback and context */
- s2n_secret_cb secret_cb;
- void *secret_cb_context;
-
- /* The send and receive callbacks don't have to be the same (e.g. two pipes) */
- s2n_send_fn *send;
- s2n_recv_fn *recv;
-
- /* The context passed to the I/O callbacks */
- void *send_io_context;
- void *recv_io_context;
-
- /* Has the user set their own I/O callbacks or is this connection using the
- * default socket-based I/O set by s2n */
- uint8_t managed_io;
-
- /* Is this connection using CORK/SO_RCVLOWAT optimizations? Only valid when the connection is using
- * managed_io
- */
- unsigned corked_io:1;
-
- /* Session resumption indicator on client side */
- unsigned client_session_resumed:1;
-
- /* Determines if we're currently sending or receiving in s2n_shutdown */
- unsigned close_notify_queued:1;
-
- /* s2n does not support renegotiation.
- * RFC5746 Section 4.3 suggests servers implement a minimal version of the
- * renegotiation_info extension even if renegotiation is not supported.
- * Some clients may fail the handshake if a corresponding renegotiation_info
- * extension is not sent back by the server.
- */
- unsigned secure_renegotiation:1;
- /* Was the EC point formats sent by the client */
- unsigned ec_point_formats:1;
-
- /* whether the connection address is ipv6 or not */
- unsigned ipv6:1;
-
- /* Whether server_name extension was used to make a decision on cert selection.
- * RFC6066 Section 3 states that server which used server_name to make a decision
- * on certificate or security settings has to send an empty server_name.
- */
- unsigned server_name_used:1;
-
- /* If write fd is broken */
- unsigned write_fd_broken:1;
-
- /* Track request 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
- * be requested by the client, the server, or both.
- */
- s2n_extension_bitfield extension_requests_sent;
- s2n_extension_bitfield extension_requests_received;
-
- /* Is this connection a client or a server connection */
- s2n_mode mode;
-
- /* Does s2n handle the blinding, or does the application */
- s2n_blinding blinding;
-
- /* A timer to measure the time between record writes */
- struct s2n_timer write_timer;
-
- /* last written time */
- uint64_t last_write_elapsed;
-
- /* When fatal errors occurs, s2n imposes a pause before
- * the connection is closed. If non-zero, this value tracks
- * how many nanoseconds to pause - which will be relative to
- * the write_timer value. */
- uint64_t delay;
-
- /* The session id */
- uint8_t session_id[S2N_TLS_SESSION_ID_MAX_LEN];
- uint8_t session_id_len;
-
- /* The version advertised by the client, by the
- * server, and the actual version we are currently
- * speaking. */
- uint8_t client_hello_version;
- uint8_t client_protocol_version;
- uint8_t server_protocol_version;
- uint8_t actual_protocol_version;
-
- /* Flag indicating whether a protocol version has been
- * negotiated yet. */
- uint8_t actual_protocol_version_established;
-
- /* Our crypto parameters */
- struct s2n_crypto_parameters initial;
- struct s2n_crypto_parameters secure;
-
- /* Which set is the client/server actually using? */
- struct s2n_crypto_parameters *client;
- struct s2n_crypto_parameters *server;
-
- /* Contains parameters needed during the handshake phase */
- struct s2n_handshake_parameters handshake_params;
-
- /* Our PSK parameters */
- struct s2n_psk_parameters psk_params;
-
- /* The PRF needs some storage elements to work with */
- struct s2n_prf_working_space prf_space;
-
- /* Whether to use client_cert_auth_type stored in s2n_config or in this s2n_connection.
- *
- * By default the s2n_connection will defer to s2n_config->client_cert_auth_type on whether or not to use Client Auth.
- * But users can override Client Auth at the connection level using s2n_connection_set_client_auth_type() without mutating
- * s2n_config since s2n_config can be shared between multiple s2n_connections. */
- uint8_t client_cert_auth_type_overridden;
-
- /* Whether or not the s2n_connection should require the Client to authenticate itself to the server. Only used if
- * client_cert_auth_type_overridden is non-zero. */
- s2n_cert_auth_type client_cert_auth_type;
-
- /* Our workhorse stuffers, used for buffering the plaintext
- * and encrypted data in both directions.
- */
- uint8_t header_in_data[S2N_TLS_RECORD_HEADER_LENGTH];
- struct s2n_stuffer header_in;
- struct s2n_stuffer in;
- struct s2n_stuffer out;
- enum { ENCRYPTED, PLAINTEXT } in_status;
-
- /* How much of the current user buffer have we already
- * encrypted and sent or have pending for the wire but have
- * not acknowledged to the user.
- */
- ssize_t current_user_data_consumed;
-
- /* An alert may be fragmented across multiple records,
- * this stuffer is used to re-assemble.
- */
- uint8_t alert_in_data[S2N_ALERT_LENGTH];
- struct s2n_stuffer alert_in;
-
- /* An alert may be partially written in the outbound
- * direction, so we keep this as a small 2 byte queue.
- *
- * We keep separate queues for alerts generated by
- * readers (a response to an alert from a peer) and writers (an
- * intentional shutdown) so that the s2n reader and writer
- * can be separate duplex I/O threads.
- */
- uint8_t reader_alert_out_data[S2N_ALERT_LENGTH];
- uint8_t writer_alert_out_data[S2N_ALERT_LENGTH];
- struct s2n_stuffer reader_alert_out;
- struct s2n_stuffer writer_alert_out;
-
- /* Our handshake state machine */
- struct s2n_handshake handshake;
-
- /* Maximum outgoing fragment size for this connection. Does not limit
- * incoming record size.
- *
- * This value is updated when:
- * 1. s2n_connection_prefer_low_latency is set
- * 2. s2n_connection_prefer_throughput is set
- * 3. TLS Maximum Fragment Length extension is negotiated
- *
- * Default value: S2N_DEFAULT_FRAGMENT_LENGTH
- */
- uint16_t max_outgoing_fragment_length;
-
- /* The number of bytes to send before changing the record size.
- * If this value > 0 then dynamic TLS record size is enabled. Otherwise, the feature is disabled (default).
- */
- uint32_t dynamic_record_resize_threshold;
-
- /* Reset record size back to a single segment after threshold seconds of inactivity */
- uint16_t dynamic_record_timeout_threshold;
-
- /* number of bytes consumed during application activity */
- uint64_t active_application_bytes_consumed;
-
- /* Negotiated TLS extension Maximum Fragment Length code */
- uint8_t mfl_code;
-
- /* Keep some accounting on each connection */
- uint64_t wire_bytes_in;
- uint64_t wire_bytes_out;
-
- /* Is the connection open or closed ? We use C's only
- * atomic type as both the reader and the writer threads
- * may declare a connection closed.
- *
- * A connection can be gracefully closed or hard-closed.
- * When gracefully closed the reader or the writer mark
- * the connection as closing, and then the writer will
- * send an alert message before closing the connection
- * and marking it as closed.
- *
- * A hard-close goes straight to closed with no alert
- * message being sent.
- */
- sig_atomic_t closing;
- sig_atomic_t closed;
-
- /* TLS extension data */
- char server_name[S2N_MAX_SERVER_NAME + 1];
-
- /* The application protocol decided upon during the client hello.
- * If ALPN is being used, then:
- * In server mode, this will be set by the time client_hello_cb is invoked.
- * In client mode, this will be set after is_handshake_complete(connection) is true.
- */
- char application_protocol[256];
-
- /* OCSP stapling response data */
- s2n_status_request_type status_type;
- struct s2n_blob status_response;
-
- /* Certificate Transparency response data */
- s2n_ct_support_level ct_level_requested;
- struct s2n_blob ct_response;
-
- /* QUIC transport parameters data: https://tools.ietf.org/html/draft-ietf-quic-tls-29#section-8.2 */
- struct s2n_blob our_quic_transport_parameters;
- struct s2n_blob peer_quic_transport_parameters;
-
- struct s2n_client_hello client_hello;
-
- struct s2n_x509_validator x509_validator;
-
- /* After a connection is created this is the verification function that should always be used. At init time,
- * the config should be checked for a verify callback and each connection should default to that. However,
- * from the user's perspective, it's sometimes simpler to manage state by attaching each validation function/data
- * to the connection, instead of globally to a single config.*/
- s2n_verify_host_fn verify_host_fn;
- void *data_for_verify_host;
- uint8_t verify_host_fn_overridden;
-
- /* Session ticket data */
- s2n_session_ticket_status session_ticket_status;
- struct s2n_blob client_ticket;
- uint32_t ticket_lifetime_hint;
-
- /* Session ticket extension from client to attempt to decrypt as the server. */
- uint8_t ticket_ext_data[S2N_TICKET_SIZE_IN_BYTES];
- struct s2n_stuffer client_ticket_to_decrypt;
-
- /* application protocols overridden */
- struct s2n_blob application_protocols_overridden;
-
- /* Cookie extension data */
- struct s2n_stuffer cookie_stuffer;
-
- /* Key update data */
- unsigned key_update_pending:1;
-
- /* Bitmap to represent preferred list of keyshare for client to generate and send keyshares in the ClientHello message.
- * The least significant bit (lsb), if set, indicates that the client must send an empty keyshare list.
- * Each bit value in the bitmap indiciates the corresponding curve in the ecc_preferences list for which a key share needs to be generated.
- * The order of the curves represented in the bitmap is obtained from the security_policy->ecc_preferences.
- * Setting and manipulating this value requires security_policy to be configured prior.
- * */
- uint8_t preferred_key_shares;
-};
-
-int s2n_connection_is_managed_corked(const struct s2n_connection *s2n_connection);
-int s2n_connection_is_client_auth_enabled(struct s2n_connection *s2n_connection);
-
-/* Kill a bad connection */
-int s2n_connection_kill(struct s2n_connection *conn);
-
-/* Send/recv a stuffer to/from a connection */
-int s2n_connection_send_stuffer(struct s2n_stuffer *stuffer, struct s2n_connection *conn, uint32_t len);
-int s2n_connection_recv_stuffer(struct s2n_stuffer *stuffer, struct s2n_connection *conn, uint32_t len);
-
-int s2n_connection_get_cipher_preferences(struct s2n_connection *conn, const struct s2n_cipher_preferences **cipher_preferences);
-int s2n_connection_get_security_policy(struct s2n_connection *conn, const struct s2n_security_policy **security_policy);
-int s2n_connection_get_kem_preferences(struct s2n_connection *conn, const struct s2n_kem_preferences **kem_preferences);
-int s2n_connection_get_signature_preferences(struct s2n_connection *conn, const struct s2n_signature_preferences **signature_preferences);
-int s2n_connection_get_ecc_preferences(struct s2n_connection *conn, const struct s2n_ecc_preferences **ecc_preferences);
-int s2n_connection_get_protocol_preferences(struct s2n_connection *conn, struct s2n_blob **protocol_preferences);
-int s2n_connection_set_client_auth_type(struct s2n_connection *conn, s2n_cert_auth_type cert_auth_type);
-int s2n_connection_get_client_auth_type(struct s2n_connection *conn, s2n_cert_auth_type *client_cert_auth_type);
-int s2n_connection_get_client_cert_chain(struct s2n_connection *conn, uint8_t **der_cert_chain_out, uint32_t *cert_chain_len);
-uint8_t s2n_connection_get_protocol_version(const struct s2n_connection *conn);
-/* `none` keyword represents a list of empty keyshares */
-int s2n_connection_set_keyshare_by_name_for_testing(struct s2n_connection *conn, const char* curve_name);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <errno.h>
+#include <s2n.h>
+#include <signal.h>
+#include <stdint.h>
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "tls/s2n_client_hello.h"
+#include "tls/s2n_config.h"
+#include "tls/s2n_crypto.h"
+#include "tls/s2n_handshake.h"
+#include "tls/s2n_prf.h"
+#include "tls/s2n_quic_support.h"
+#include "tls/s2n_tls_parameters.h"
+#include "tls/s2n_x509_validator.h"
+#include "tls/s2n_key_update.h"
+#include "tls/s2n_kem_preferences.h"
+#include "tls/s2n_ecc_preferences.h"
+#include "tls/s2n_security_policies.h"
+
+#include "crypto/s2n_hash.h"
+#include "crypto/s2n_hmac.h"
+
+#include "utils/s2n_mem.h"
+#include "utils/s2n_timer.h"
+
+#define S2N_TLS_PROTOCOL_VERSION_LEN 2
+
+#define is_handshake_complete(conn) (APPLICATION_DATA == s2n_conn_get_current_message_type(conn))
+
+typedef enum {
+ S2N_NO_TICKET = 0,
+ S2N_DECRYPT_TICKET,
+ S2N_NEW_TICKET
+} s2n_session_ticket_status;
+
+struct s2n_connection {
+ /* The configuration (cert, key .. etc ) */
+ struct s2n_config *config;
+
+ /* Overrides Security Policy in config if non-null */
+ const struct s2n_security_policy *security_policy_override;
+
+ /* The user defined context associated with connection */
+ void *context;
+
+ /* The user defined secret callback and context */
+ s2n_secret_cb secret_cb;
+ void *secret_cb_context;
+
+ /* The send and receive callbacks don't have to be the same (e.g. two pipes) */
+ s2n_send_fn *send;
+ s2n_recv_fn *recv;
+
+ /* The context passed to the I/O callbacks */
+ void *send_io_context;
+ void *recv_io_context;
+
+ /* Has the user set their own I/O callbacks or is this connection using the
+ * default socket-based I/O set by s2n */
+ uint8_t managed_io;
+
+ /* Is this connection using CORK/SO_RCVLOWAT optimizations? Only valid when the connection is using
+ * managed_io
+ */
+ unsigned corked_io:1;
+
+ /* Session resumption indicator on client side */
+ unsigned client_session_resumed:1;
+
+ /* Determines if we're currently sending or receiving in s2n_shutdown */
+ unsigned close_notify_queued:1;
+
+ /* s2n does not support renegotiation.
+ * RFC5746 Section 4.3 suggests servers implement a minimal version of the
+ * renegotiation_info extension even if renegotiation is not supported.
+ * Some clients may fail the handshake if a corresponding renegotiation_info
+ * extension is not sent back by the server.
+ */
+ unsigned secure_renegotiation:1;
+ /* Was the EC point formats sent by the client */
+ unsigned ec_point_formats:1;
+
+ /* whether the connection address is ipv6 or not */
+ unsigned ipv6:1;
+
+ /* Whether server_name extension was used to make a decision on cert selection.
+ * RFC6066 Section 3 states that server which used server_name to make a decision
+ * on certificate or security settings has to send an empty server_name.
+ */
+ unsigned server_name_used:1;
+
+ /* If write fd is broken */
+ unsigned write_fd_broken:1;
+
+ /* Track request 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
+ * be requested by the client, the server, or both.
+ */
+ s2n_extension_bitfield extension_requests_sent;
+ s2n_extension_bitfield extension_requests_received;
+
+ /* Is this connection a client or a server connection */
+ s2n_mode mode;
+
+ /* Does s2n handle the blinding, or does the application */
+ s2n_blinding blinding;
+
+ /* A timer to measure the time between record writes */
+ struct s2n_timer write_timer;
+
+ /* last written time */
+ uint64_t last_write_elapsed;
+
+ /* When fatal errors occurs, s2n imposes a pause before
+ * the connection is closed. If non-zero, this value tracks
+ * how many nanoseconds to pause - which will be relative to
+ * the write_timer value. */
+ uint64_t delay;
+
+ /* The session id */
+ uint8_t session_id[S2N_TLS_SESSION_ID_MAX_LEN];
+ uint8_t session_id_len;
+
+ /* The version advertised by the client, by the
+ * server, and the actual version we are currently
+ * speaking. */
+ uint8_t client_hello_version;
+ uint8_t client_protocol_version;
+ uint8_t server_protocol_version;
+ uint8_t actual_protocol_version;
+
+ /* Flag indicating whether a protocol version has been
+ * negotiated yet. */
+ uint8_t actual_protocol_version_established;
+
+ /* Our crypto parameters */
+ struct s2n_crypto_parameters initial;
+ struct s2n_crypto_parameters secure;
+
+ /* Which set is the client/server actually using? */
+ struct s2n_crypto_parameters *client;
+ struct s2n_crypto_parameters *server;
+
+ /* Contains parameters needed during the handshake phase */
+ struct s2n_handshake_parameters handshake_params;
+
+ /* Our PSK parameters */
+ struct s2n_psk_parameters psk_params;
+
+ /* The PRF needs some storage elements to work with */
+ struct s2n_prf_working_space prf_space;
+
+ /* Whether to use client_cert_auth_type stored in s2n_config or in this s2n_connection.
+ *
+ * By default the s2n_connection will defer to s2n_config->client_cert_auth_type on whether or not to use Client Auth.
+ * But users can override Client Auth at the connection level using s2n_connection_set_client_auth_type() without mutating
+ * s2n_config since s2n_config can be shared between multiple s2n_connections. */
+ uint8_t client_cert_auth_type_overridden;
+
+ /* Whether or not the s2n_connection should require the Client to authenticate itself to the server. Only used if
+ * client_cert_auth_type_overridden is non-zero. */
+ s2n_cert_auth_type client_cert_auth_type;
+
+ /* Our workhorse stuffers, used for buffering the plaintext
+ * and encrypted data in both directions.
+ */
+ uint8_t header_in_data[S2N_TLS_RECORD_HEADER_LENGTH];
+ struct s2n_stuffer header_in;
+ struct s2n_stuffer in;
+ struct s2n_stuffer out;
+ enum { ENCRYPTED, PLAINTEXT } in_status;
+
+ /* How much of the current user buffer have we already
+ * encrypted and sent or have pending for the wire but have
+ * not acknowledged to the user.
+ */
+ ssize_t current_user_data_consumed;
+
+ /* An alert may be fragmented across multiple records,
+ * this stuffer is used to re-assemble.
+ */
+ uint8_t alert_in_data[S2N_ALERT_LENGTH];
+ struct s2n_stuffer alert_in;
+
+ /* An alert may be partially written in the outbound
+ * direction, so we keep this as a small 2 byte queue.
+ *
+ * We keep separate queues for alerts generated by
+ * readers (a response to an alert from a peer) and writers (an
+ * intentional shutdown) so that the s2n reader and writer
+ * can be separate duplex I/O threads.
+ */
+ uint8_t reader_alert_out_data[S2N_ALERT_LENGTH];
+ uint8_t writer_alert_out_data[S2N_ALERT_LENGTH];
+ struct s2n_stuffer reader_alert_out;
+ struct s2n_stuffer writer_alert_out;
+
+ /* Our handshake state machine */
+ struct s2n_handshake handshake;
+
+ /* Maximum outgoing fragment size for this connection. Does not limit
+ * incoming record size.
+ *
+ * This value is updated when:
+ * 1. s2n_connection_prefer_low_latency is set
+ * 2. s2n_connection_prefer_throughput is set
+ * 3. TLS Maximum Fragment Length extension is negotiated
+ *
+ * Default value: S2N_DEFAULT_FRAGMENT_LENGTH
+ */
+ uint16_t max_outgoing_fragment_length;
+
+ /* The number of bytes to send before changing the record size.
+ * If this value > 0 then dynamic TLS record size is enabled. Otherwise, the feature is disabled (default).
+ */
+ uint32_t dynamic_record_resize_threshold;
+
+ /* Reset record size back to a single segment after threshold seconds of inactivity */
+ uint16_t dynamic_record_timeout_threshold;
+
+ /* number of bytes consumed during application activity */
+ uint64_t active_application_bytes_consumed;
+
+ /* Negotiated TLS extension Maximum Fragment Length code */
+ uint8_t mfl_code;
+
+ /* Keep some accounting on each connection */
+ uint64_t wire_bytes_in;
+ uint64_t wire_bytes_out;
+
+ /* Is the connection open or closed ? We use C's only
+ * atomic type as both the reader and the writer threads
+ * may declare a connection closed.
+ *
+ * A connection can be gracefully closed or hard-closed.
+ * When gracefully closed the reader or the writer mark
+ * the connection as closing, and then the writer will
+ * send an alert message before closing the connection
+ * and marking it as closed.
+ *
+ * A hard-close goes straight to closed with no alert
+ * message being sent.
+ */
+ sig_atomic_t closing;
+ sig_atomic_t closed;
+
+ /* TLS extension data */
+ char server_name[S2N_MAX_SERVER_NAME + 1];
+
+ /* The application protocol decided upon during the client hello.
+ * If ALPN is being used, then:
+ * In server mode, this will be set by the time client_hello_cb is invoked.
+ * In client mode, this will be set after is_handshake_complete(connection) is true.
+ */
+ char application_protocol[256];
+
+ /* OCSP stapling response data */
+ s2n_status_request_type status_type;
+ struct s2n_blob status_response;
+
+ /* Certificate Transparency response data */
+ s2n_ct_support_level ct_level_requested;
+ struct s2n_blob ct_response;
+
+ /* QUIC transport parameters data: https://tools.ietf.org/html/draft-ietf-quic-tls-29#section-8.2 */
+ struct s2n_blob our_quic_transport_parameters;
+ struct s2n_blob peer_quic_transport_parameters;
+
+ struct s2n_client_hello client_hello;
+
+ struct s2n_x509_validator x509_validator;
+
+ /* After a connection is created this is the verification function that should always be used. At init time,
+ * the config should be checked for a verify callback and each connection should default to that. However,
+ * from the user's perspective, it's sometimes simpler to manage state by attaching each validation function/data
+ * to the connection, instead of globally to a single config.*/
+ s2n_verify_host_fn verify_host_fn;
+ void *data_for_verify_host;
+ uint8_t verify_host_fn_overridden;
+
+ /* Session ticket data */
+ s2n_session_ticket_status session_ticket_status;
+ struct s2n_blob client_ticket;
+ uint32_t ticket_lifetime_hint;
+
+ /* Session ticket extension from client to attempt to decrypt as the server. */
+ uint8_t ticket_ext_data[S2N_TICKET_SIZE_IN_BYTES];
+ struct s2n_stuffer client_ticket_to_decrypt;
+
+ /* application protocols overridden */
+ struct s2n_blob application_protocols_overridden;
+
+ /* Cookie extension data */
+ struct s2n_stuffer cookie_stuffer;
+
+ /* Key update data */
+ unsigned key_update_pending:1;
+
+ /* Bitmap to represent preferred list of keyshare for client to generate and send keyshares in the ClientHello message.
+ * The least significant bit (lsb), if set, indicates that the client must send an empty keyshare list.
+ * Each bit value in the bitmap indiciates the corresponding curve in the ecc_preferences list for which a key share needs to be generated.
+ * The order of the curves represented in the bitmap is obtained from the security_policy->ecc_preferences.
+ * Setting and manipulating this value requires security_policy to be configured prior.
+ * */
+ uint8_t preferred_key_shares;
+};
+
+int s2n_connection_is_managed_corked(const struct s2n_connection *s2n_connection);
+int s2n_connection_is_client_auth_enabled(struct s2n_connection *s2n_connection);
+
+/* Kill a bad connection */
+int s2n_connection_kill(struct s2n_connection *conn);
+
+/* Send/recv a stuffer to/from a connection */
+int s2n_connection_send_stuffer(struct s2n_stuffer *stuffer, struct s2n_connection *conn, uint32_t len);
+int s2n_connection_recv_stuffer(struct s2n_stuffer *stuffer, struct s2n_connection *conn, uint32_t len);
+
+int s2n_connection_get_cipher_preferences(struct s2n_connection *conn, const struct s2n_cipher_preferences **cipher_preferences);
+int s2n_connection_get_security_policy(struct s2n_connection *conn, const struct s2n_security_policy **security_policy);
+int s2n_connection_get_kem_preferences(struct s2n_connection *conn, const struct s2n_kem_preferences **kem_preferences);
+int s2n_connection_get_signature_preferences(struct s2n_connection *conn, const struct s2n_signature_preferences **signature_preferences);
+int s2n_connection_get_ecc_preferences(struct s2n_connection *conn, const struct s2n_ecc_preferences **ecc_preferences);
+int s2n_connection_get_protocol_preferences(struct s2n_connection *conn, struct s2n_blob **protocol_preferences);
+int s2n_connection_set_client_auth_type(struct s2n_connection *conn, s2n_cert_auth_type cert_auth_type);
+int s2n_connection_get_client_auth_type(struct s2n_connection *conn, s2n_cert_auth_type *client_cert_auth_type);
+int s2n_connection_get_client_cert_chain(struct s2n_connection *conn, uint8_t **der_cert_chain_out, uint32_t *cert_chain_len);
+uint8_t s2n_connection_get_protocol_version(const struct s2n_connection *conn);
+/* `none` keyword represents a list of empty keyshares */
+int s2n_connection_set_keyshare_by_name_for_testing(struct s2n_connection *conn, const char* curve_name);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_connection_evp_digests.c b/contrib/restricted/aws/s2n/tls/s2n_connection_evp_digests.c
index 895dc39dc4..f7c08dc594 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_connection_evp_digests.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_connection_evp_digests.c
@@ -1,140 +1,140 @@
-/*
- * 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 "tls/s2n_connection_evp_digests.h"
-
-#include "utils/s2n_safety.h"
-
-/* On s2n_connection_wipe, save all pointers to OpenSSL EVP digest structs in a temporary
- * s2n_connection_prf_handles struct to avoid re-allocation after zeroing the connection struct.
- * Do not store any additional hash/HMAC state as it is unnecessary and excessive copying would impact performance.
- */
-int s2n_connection_save_prf_state(struct s2n_connection_prf_handles *prf_handles, struct s2n_connection *conn)
-{
- /* Preserve only the handlers for TLS PRF p_hash pointers to avoid re-allocation */
- GUARD(s2n_hmac_save_evp_hash_state(&prf_handles->p_hash_s2n_hmac, &conn->prf_space.tls.p_hash.s2n_hmac));
- prf_handles->p_hash_evp_hmac = conn->prf_space.tls.p_hash.evp_hmac;
-
- return 0;
-}
-
-/* On s2n_connection_wipe, save all pointers to OpenSSL EVP digest structs in a temporary
- * s2n_connection_hash_handles struct to avoid re-allocation after zeroing the connection struct.
- * Do not store any additional hash state as it is unnecessary and excessive copying would impact performance.
- */
-int s2n_connection_save_hash_state(struct s2n_connection_hash_handles *hash_handles, struct s2n_connection *conn)
-{
- /* Preserve only the handlers for handshake hash state pointers to avoid re-allocation */
- hash_handles->md5 = conn->handshake.md5.digest.high_level;
- hash_handles->sha1 = conn->handshake.sha1.digest.high_level;
- hash_handles->sha224 = conn->handshake.sha224.digest.high_level;
- hash_handles->sha256 = conn->handshake.sha256.digest.high_level;
- hash_handles->sha384 = conn->handshake.sha384.digest.high_level;
- hash_handles->sha512 = conn->handshake.sha512.digest.high_level;
- hash_handles->md5_sha1 = conn->handshake.md5_sha1.digest.high_level;
- hash_handles->ccv_hash_copy = conn->handshake.ccv_hash_copy.digest.high_level;
- hash_handles->prf_md5_hash_copy = conn->handshake.prf_md5_hash_copy.digest.high_level;
- hash_handles->prf_sha1_hash_copy = conn->handshake.prf_sha1_hash_copy.digest.high_level;
- hash_handles->prf_tls12_hash_copy = conn->handshake.prf_tls12_hash_copy.digest.high_level;
- hash_handles->server_finished_copy = conn->handshake.server_finished_copy.digest.high_level;
-
- /* Preserve only the handlers for SSLv3 PRF hash state pointers to avoid re-allocation */
- hash_handles->prf_md5 = conn->prf_space.ssl3.md5.digest.high_level;
- hash_handles->prf_sha1 = conn->prf_space.ssl3.sha1.digest.high_level;
-
- /* Preserve only the handlers for initial signature hash state pointers to avoid re-allocation */
- hash_handles->initial_signature_hash = conn->initial.signature_hash.digest.high_level;
-
- /* Preserve only the handlers for secure signature hash state pointers to avoid re-allocation */
- hash_handles->secure_signature_hash = conn->secure.signature_hash.digest.high_level;
-
- return 0;
-}
-
-/* On s2n_connection_wipe, save all pointers to OpenSSL EVP digest structs in a temporary
- * s2n_connection_hmac_handles struct to avoid re-allocation after zeroing the connection struct.
- * Do not store any additional HMAC state as it is unnecessary and excessive copying would impact performance.
- */
-int s2n_connection_save_hmac_state(struct s2n_connection_hmac_handles *hmac_handles, struct s2n_connection *conn)
-{
- GUARD(s2n_hmac_save_evp_hash_state(&hmac_handles->initial_client, &conn->initial.client_record_mac));
- GUARD(s2n_hmac_save_evp_hash_state(&hmac_handles->initial_server, &conn->initial.server_record_mac));
- GUARD(s2n_hmac_save_evp_hash_state(&hmac_handles->initial_client_copy, &conn->initial.record_mac_copy_workspace));
- GUARD(s2n_hmac_save_evp_hash_state(&hmac_handles->secure_client, &conn->secure.client_record_mac));
- GUARD(s2n_hmac_save_evp_hash_state(&hmac_handles->secure_server, &conn->secure.server_record_mac));
- GUARD(s2n_hmac_save_evp_hash_state(&hmac_handles->secure_client_copy, &conn->secure.record_mac_copy_workspace));
- return 0;
-}
-
-/* On s2n_connection_wipe, restore all pointers to OpenSSL EVP digest structs after zeroing the connection struct
- * to avoid re-allocation. Do not store any additional hash/HMAC state as it is unnecessary and excessive copying
- * would impact performance.
- */
-int s2n_connection_restore_prf_state(struct s2n_connection *conn, struct s2n_connection_prf_handles *prf_handles)
-{
- /* Restore s2n_connection handlers for TLS PRF p_hash */
- GUARD(s2n_hmac_restore_evp_hash_state(&prf_handles->p_hash_s2n_hmac, &conn->prf_space.tls.p_hash.s2n_hmac));
- conn->prf_space.tls.p_hash.evp_hmac = prf_handles->p_hash_evp_hmac;
-
- return 0;
-}
-
-/* On s2n_connection_wipe, restore all pointers to OpenSSL EVP digest structs after zeroing the connection struct
- * to avoid re-allocation. Do not store any additional hash state as it is unnecessary and excessive copying
- * would impact performance.
- */
-int s2n_connection_restore_hash_state(struct s2n_connection *conn, struct s2n_connection_hash_handles *hash_handles)
-{
- /* Restore s2n_connection handlers for handshake hash states */
- conn->handshake.md5.digest.high_level = hash_handles->md5;
- conn->handshake.sha1.digest.high_level = hash_handles->sha1;
- conn->handshake.sha224.digest.high_level = hash_handles->sha224;
- conn->handshake.sha256.digest.high_level = hash_handles->sha256;
- conn->handshake.sha384.digest.high_level = hash_handles->sha384;
- conn->handshake.sha512.digest.high_level = hash_handles->sha512;
- conn->handshake.md5_sha1.digest.high_level = hash_handles->md5_sha1;
- conn->handshake.ccv_hash_copy.digest.high_level = hash_handles->ccv_hash_copy;
- conn->handshake.prf_md5_hash_copy.digest.high_level = hash_handles->prf_md5_hash_copy;
- conn->handshake.prf_sha1_hash_copy.digest.high_level = hash_handles->prf_sha1_hash_copy;
- conn->handshake.prf_tls12_hash_copy.digest.high_level = hash_handles->prf_tls12_hash_copy;
- conn->handshake.server_finished_copy.digest.high_level = hash_handles->server_finished_copy;
-
- /* Restore s2n_connection handlers for SSLv3 PRF hash states */
- conn->prf_space.ssl3.md5.digest.high_level = hash_handles->prf_md5;
- conn->prf_space.ssl3.sha1.digest.high_level = hash_handles->prf_sha1;
-
- /* Restore s2n_connection handlers for initial signature hash states */
- conn->initial.signature_hash.digest.high_level = hash_handles->initial_signature_hash;
-
- /* Restore s2n_connection handlers for secure signature hash states */
- conn->secure.signature_hash.digest.high_level = hash_handles->secure_signature_hash;
-
- return 0;
-}
-
-/* On s2n_connection_wipe, restore all pointers to OpenSSL EVP digest structs after zeroing the connection struct
- * to avoid re-allocation. Do not store any additional HMAC state as it is unnecessary and excessive copying
- * would impact performance.
- */
-int s2n_connection_restore_hmac_state(struct s2n_connection *conn, struct s2n_connection_hmac_handles *hmac_handles)
-{
- GUARD(s2n_hmac_restore_evp_hash_state(&hmac_handles->initial_client, &conn->initial.client_record_mac));
- GUARD(s2n_hmac_restore_evp_hash_state(&hmac_handles->initial_server, &conn->initial.server_record_mac));
- GUARD(s2n_hmac_restore_evp_hash_state(&hmac_handles->initial_client_copy, &conn->initial.record_mac_copy_workspace));
- GUARD(s2n_hmac_restore_evp_hash_state(&hmac_handles->secure_client, &conn->secure.client_record_mac));
- GUARD(s2n_hmac_restore_evp_hash_state(&hmac_handles->secure_server, &conn->secure.server_record_mac));
- GUARD(s2n_hmac_restore_evp_hash_state(&hmac_handles->secure_client_copy, &conn->secure.record_mac_copy_workspace));
- return 0;
-}
+/*
+ * 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 "tls/s2n_connection_evp_digests.h"
+
+#include "utils/s2n_safety.h"
+
+/* On s2n_connection_wipe, save all pointers to OpenSSL EVP digest structs in a temporary
+ * s2n_connection_prf_handles struct to avoid re-allocation after zeroing the connection struct.
+ * Do not store any additional hash/HMAC state as it is unnecessary and excessive copying would impact performance.
+ */
+int s2n_connection_save_prf_state(struct s2n_connection_prf_handles *prf_handles, struct s2n_connection *conn)
+{
+ /* Preserve only the handlers for TLS PRF p_hash pointers to avoid re-allocation */
+ GUARD(s2n_hmac_save_evp_hash_state(&prf_handles->p_hash_s2n_hmac, &conn->prf_space.tls.p_hash.s2n_hmac));
+ prf_handles->p_hash_evp_hmac = conn->prf_space.tls.p_hash.evp_hmac;
+
+ return 0;
+}
+
+/* On s2n_connection_wipe, save all pointers to OpenSSL EVP digest structs in a temporary
+ * s2n_connection_hash_handles struct to avoid re-allocation after zeroing the connection struct.
+ * Do not store any additional hash state as it is unnecessary and excessive copying would impact performance.
+ */
+int s2n_connection_save_hash_state(struct s2n_connection_hash_handles *hash_handles, struct s2n_connection *conn)
+{
+ /* Preserve only the handlers for handshake hash state pointers to avoid re-allocation */
+ hash_handles->md5 = conn->handshake.md5.digest.high_level;
+ hash_handles->sha1 = conn->handshake.sha1.digest.high_level;
+ hash_handles->sha224 = conn->handshake.sha224.digest.high_level;
+ hash_handles->sha256 = conn->handshake.sha256.digest.high_level;
+ hash_handles->sha384 = conn->handshake.sha384.digest.high_level;
+ hash_handles->sha512 = conn->handshake.sha512.digest.high_level;
+ hash_handles->md5_sha1 = conn->handshake.md5_sha1.digest.high_level;
+ hash_handles->ccv_hash_copy = conn->handshake.ccv_hash_copy.digest.high_level;
+ hash_handles->prf_md5_hash_copy = conn->handshake.prf_md5_hash_copy.digest.high_level;
+ hash_handles->prf_sha1_hash_copy = conn->handshake.prf_sha1_hash_copy.digest.high_level;
+ hash_handles->prf_tls12_hash_copy = conn->handshake.prf_tls12_hash_copy.digest.high_level;
+ hash_handles->server_finished_copy = conn->handshake.server_finished_copy.digest.high_level;
+
+ /* Preserve only the handlers for SSLv3 PRF hash state pointers to avoid re-allocation */
+ hash_handles->prf_md5 = conn->prf_space.ssl3.md5.digest.high_level;
+ hash_handles->prf_sha1 = conn->prf_space.ssl3.sha1.digest.high_level;
+
+ /* Preserve only the handlers for initial signature hash state pointers to avoid re-allocation */
+ hash_handles->initial_signature_hash = conn->initial.signature_hash.digest.high_level;
+
+ /* Preserve only the handlers for secure signature hash state pointers to avoid re-allocation */
+ hash_handles->secure_signature_hash = conn->secure.signature_hash.digest.high_level;
+
+ return 0;
+}
+
+/* On s2n_connection_wipe, save all pointers to OpenSSL EVP digest structs in a temporary
+ * s2n_connection_hmac_handles struct to avoid re-allocation after zeroing the connection struct.
+ * Do not store any additional HMAC state as it is unnecessary and excessive copying would impact performance.
+ */
+int s2n_connection_save_hmac_state(struct s2n_connection_hmac_handles *hmac_handles, struct s2n_connection *conn)
+{
+ GUARD(s2n_hmac_save_evp_hash_state(&hmac_handles->initial_client, &conn->initial.client_record_mac));
+ GUARD(s2n_hmac_save_evp_hash_state(&hmac_handles->initial_server, &conn->initial.server_record_mac));
+ GUARD(s2n_hmac_save_evp_hash_state(&hmac_handles->initial_client_copy, &conn->initial.record_mac_copy_workspace));
+ GUARD(s2n_hmac_save_evp_hash_state(&hmac_handles->secure_client, &conn->secure.client_record_mac));
+ GUARD(s2n_hmac_save_evp_hash_state(&hmac_handles->secure_server, &conn->secure.server_record_mac));
+ GUARD(s2n_hmac_save_evp_hash_state(&hmac_handles->secure_client_copy, &conn->secure.record_mac_copy_workspace));
+ return 0;
+}
+
+/* On s2n_connection_wipe, restore all pointers to OpenSSL EVP digest structs after zeroing the connection struct
+ * to avoid re-allocation. Do not store any additional hash/HMAC state as it is unnecessary and excessive copying
+ * would impact performance.
+ */
+int s2n_connection_restore_prf_state(struct s2n_connection *conn, struct s2n_connection_prf_handles *prf_handles)
+{
+ /* Restore s2n_connection handlers for TLS PRF p_hash */
+ GUARD(s2n_hmac_restore_evp_hash_state(&prf_handles->p_hash_s2n_hmac, &conn->prf_space.tls.p_hash.s2n_hmac));
+ conn->prf_space.tls.p_hash.evp_hmac = prf_handles->p_hash_evp_hmac;
+
+ return 0;
+}
+
+/* On s2n_connection_wipe, restore all pointers to OpenSSL EVP digest structs after zeroing the connection struct
+ * to avoid re-allocation. Do not store any additional hash state as it is unnecessary and excessive copying
+ * would impact performance.
+ */
+int s2n_connection_restore_hash_state(struct s2n_connection *conn, struct s2n_connection_hash_handles *hash_handles)
+{
+ /* Restore s2n_connection handlers for handshake hash states */
+ conn->handshake.md5.digest.high_level = hash_handles->md5;
+ conn->handshake.sha1.digest.high_level = hash_handles->sha1;
+ conn->handshake.sha224.digest.high_level = hash_handles->sha224;
+ conn->handshake.sha256.digest.high_level = hash_handles->sha256;
+ conn->handshake.sha384.digest.high_level = hash_handles->sha384;
+ conn->handshake.sha512.digest.high_level = hash_handles->sha512;
+ conn->handshake.md5_sha1.digest.high_level = hash_handles->md5_sha1;
+ conn->handshake.ccv_hash_copy.digest.high_level = hash_handles->ccv_hash_copy;
+ conn->handshake.prf_md5_hash_copy.digest.high_level = hash_handles->prf_md5_hash_copy;
+ conn->handshake.prf_sha1_hash_copy.digest.high_level = hash_handles->prf_sha1_hash_copy;
+ conn->handshake.prf_tls12_hash_copy.digest.high_level = hash_handles->prf_tls12_hash_copy;
+ conn->handshake.server_finished_copy.digest.high_level = hash_handles->server_finished_copy;
+
+ /* Restore s2n_connection handlers for SSLv3 PRF hash states */
+ conn->prf_space.ssl3.md5.digest.high_level = hash_handles->prf_md5;
+ conn->prf_space.ssl3.sha1.digest.high_level = hash_handles->prf_sha1;
+
+ /* Restore s2n_connection handlers for initial signature hash states */
+ conn->initial.signature_hash.digest.high_level = hash_handles->initial_signature_hash;
+
+ /* Restore s2n_connection handlers for secure signature hash states */
+ conn->secure.signature_hash.digest.high_level = hash_handles->secure_signature_hash;
+
+ return 0;
+}
+
+/* On s2n_connection_wipe, restore all pointers to OpenSSL EVP digest structs after zeroing the connection struct
+ * to avoid re-allocation. Do not store any additional HMAC state as it is unnecessary and excessive copying
+ * would impact performance.
+ */
+int s2n_connection_restore_hmac_state(struct s2n_connection *conn, struct s2n_connection_hmac_handles *hmac_handles)
+{
+ GUARD(s2n_hmac_restore_evp_hash_state(&hmac_handles->initial_client, &conn->initial.client_record_mac));
+ GUARD(s2n_hmac_restore_evp_hash_state(&hmac_handles->initial_server, &conn->initial.server_record_mac));
+ GUARD(s2n_hmac_restore_evp_hash_state(&hmac_handles->initial_client_copy, &conn->initial.record_mac_copy_workspace));
+ GUARD(s2n_hmac_restore_evp_hash_state(&hmac_handles->secure_client, &conn->secure.client_record_mac));
+ GUARD(s2n_hmac_restore_evp_hash_state(&hmac_handles->secure_server, &conn->secure.server_record_mac));
+ GUARD(s2n_hmac_restore_evp_hash_state(&hmac_handles->secure_client_copy, &conn->secure.record_mac_copy_workspace));
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_connection_evp_digests.h b/contrib/restricted/aws/s2n/tls/s2n_connection_evp_digests.h
index 135b8d9b3c..80e16823ba 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_connection_evp_digests.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_connection_evp_digests.h
@@ -1,70 +1,70 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/s2n_connection.h"
-#include "tls/s2n_prf.h"
-
-#include "crypto/s2n_hash.h"
-
-struct s2n_connection_prf_handles {
- /* TLS PRF HMAC p_hash */
- struct s2n_hmac_evp_backup p_hash_s2n_hmac;
-
- /* TLS PRF EVP p_hash */
- struct s2n_evp_hmac_state p_hash_evp_hmac;
-};
-
-struct s2n_connection_hash_handles {
- /* Handshake hash states */
- struct s2n_hash_evp_digest md5;
- struct s2n_hash_evp_digest sha1;
- struct s2n_hash_evp_digest sha224;
- struct s2n_hash_evp_digest sha256;
- struct s2n_hash_evp_digest sha384;
- struct s2n_hash_evp_digest sha512;
- struct s2n_hash_evp_digest md5_sha1;
- struct s2n_hash_evp_digest ccv_hash_copy;
- struct s2n_hash_evp_digest prf_md5_hash_copy;
- struct s2n_hash_evp_digest prf_sha1_hash_copy;
- struct s2n_hash_evp_digest prf_tls12_hash_copy;
- struct s2n_hash_evp_digest server_finished_copy;
- struct s2n_hash_evp_digest prf_md5;
-
- /* SSLv3 PRF hash states */
- struct s2n_hash_evp_digest prf_sha1;
-
- /* Initial signature hash states */
- struct s2n_hash_evp_digest initial_signature_hash;
- struct s2n_hash_evp_digest secure_signature_hash;
-};
-
-/* Allocationg new EVP structs is expensive, so we back them up here and reuse them */
-struct s2n_connection_hmac_handles {
- struct s2n_hmac_evp_backup initial_client;
- struct s2n_hmac_evp_backup initial_client_copy;
- struct s2n_hmac_evp_backup initial_server;
- struct s2n_hmac_evp_backup secure_client;
- struct s2n_hmac_evp_backup secure_client_copy;
- struct s2n_hmac_evp_backup secure_server;
-};
-
-extern int s2n_connection_save_prf_state(struct s2n_connection_prf_handles *prf_handles, struct s2n_connection *conn);
-extern int s2n_connection_save_hash_state(struct s2n_connection_hash_handles *hash_handles, struct s2n_connection *conn);
-extern int s2n_connection_save_hmac_state(struct s2n_connection_hmac_handles *hmac_handles, struct s2n_connection *conn);
-extern int s2n_connection_restore_prf_state(struct s2n_connection *conn, struct s2n_connection_prf_handles *prf_handles);
-extern int s2n_connection_restore_hash_state(struct s2n_connection *conn, struct s2n_connection_hash_handles *hash_handles);
-extern int s2n_connection_restore_hmac_state(struct s2n_connection *conn, struct s2n_connection_hmac_handles *hmac_handles);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/s2n_connection.h"
+#include "tls/s2n_prf.h"
+
+#include "crypto/s2n_hash.h"
+
+struct s2n_connection_prf_handles {
+ /* TLS PRF HMAC p_hash */
+ struct s2n_hmac_evp_backup p_hash_s2n_hmac;
+
+ /* TLS PRF EVP p_hash */
+ struct s2n_evp_hmac_state p_hash_evp_hmac;
+};
+
+struct s2n_connection_hash_handles {
+ /* Handshake hash states */
+ struct s2n_hash_evp_digest md5;
+ struct s2n_hash_evp_digest sha1;
+ struct s2n_hash_evp_digest sha224;
+ struct s2n_hash_evp_digest sha256;
+ struct s2n_hash_evp_digest sha384;
+ struct s2n_hash_evp_digest sha512;
+ struct s2n_hash_evp_digest md5_sha1;
+ struct s2n_hash_evp_digest ccv_hash_copy;
+ struct s2n_hash_evp_digest prf_md5_hash_copy;
+ struct s2n_hash_evp_digest prf_sha1_hash_copy;
+ struct s2n_hash_evp_digest prf_tls12_hash_copy;
+ struct s2n_hash_evp_digest server_finished_copy;
+ struct s2n_hash_evp_digest prf_md5;
+
+ /* SSLv3 PRF hash states */
+ struct s2n_hash_evp_digest prf_sha1;
+
+ /* Initial signature hash states */
+ struct s2n_hash_evp_digest initial_signature_hash;
+ struct s2n_hash_evp_digest secure_signature_hash;
+};
+
+/* Allocationg new EVP structs is expensive, so we back them up here and reuse them */
+struct s2n_connection_hmac_handles {
+ struct s2n_hmac_evp_backup initial_client;
+ struct s2n_hmac_evp_backup initial_client_copy;
+ struct s2n_hmac_evp_backup initial_server;
+ struct s2n_hmac_evp_backup secure_client;
+ struct s2n_hmac_evp_backup secure_client_copy;
+ struct s2n_hmac_evp_backup secure_server;
+};
+
+extern int s2n_connection_save_prf_state(struct s2n_connection_prf_handles *prf_handles, struct s2n_connection *conn);
+extern int s2n_connection_save_hash_state(struct s2n_connection_hash_handles *hash_handles, struct s2n_connection *conn);
+extern int s2n_connection_save_hmac_state(struct s2n_connection_hmac_handles *hmac_handles, struct s2n_connection *conn);
+extern int s2n_connection_restore_prf_state(struct s2n_connection *conn, struct s2n_connection_prf_handles *prf_handles);
+extern int s2n_connection_restore_hash_state(struct s2n_connection *conn, struct s2n_connection_hash_handles *hash_handles);
+extern int s2n_connection_restore_hmac_state(struct s2n_connection *conn, struct s2n_connection_hmac_handles *hmac_handles);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_crypto.h b/contrib/restricted/aws/s2n/tls/s2n_crypto.h
index 8b1289d8db..515165c09d 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_crypto.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_crypto.h
@@ -1,73 +1,73 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/s2n_config.h"
-#include "tls/s2n_signature_scheme.h"
-#include "tls/s2n_crypto_constants.h"
-#include "tls/s2n_kem.h"
-
-#include "crypto/s2n_certificate.h"
-#include "crypto/s2n_cipher.h"
-#include "crypto/s2n_hmac.h"
-#include "crypto/s2n_hash.h"
-#include "crypto/s2n_pkey.h"
-#include "crypto/s2n_signature.h"
-#include "crypto/s2n_tls13_keys.h"
-#include "crypto/s2n_dhe.h"
-#include "crypto/s2n_ecc_evp.h"
-
-struct s2n_crypto_parameters {
- struct s2n_pkey server_public_key;
- struct s2n_pkey client_public_key;
- struct s2n_dh_params server_dh_params;
- struct s2n_ecc_evp_params server_ecc_evp_params;
- const struct s2n_ecc_named_curve *mutually_supported_curves[S2N_ECC_EVP_SUPPORTED_CURVES_COUNT];
- struct s2n_ecc_evp_params client_ecc_evp_params[S2N_ECC_EVP_SUPPORTED_CURVES_COUNT];
- struct s2n_kem_group_params server_kem_group_params;
- struct s2n_kem_group_params *chosen_client_kem_group_params;
- struct s2n_kem_group_params client_kem_group_params[S2N_SUPPORTED_KEM_GROUPS_COUNT];
- const struct s2n_kem_group *mutually_supported_kem_groups[S2N_SUPPORTED_KEM_GROUPS_COUNT];
- struct s2n_kem_params kem_params;
- struct s2n_blob client_key_exchange_message;
- struct s2n_blob client_pq_kem_extension;
-
- struct s2n_signature_scheme conn_sig_scheme;
-
- struct s2n_blob client_cert_chain;
- s2n_pkey_type client_cert_pkey_type;
-
- struct s2n_signature_scheme client_cert_sig_scheme;
-
- struct s2n_cipher_suite *cipher_suite;
- struct s2n_session_key client_key;
- struct s2n_session_key server_key;
-
- uint8_t rsa_premaster_secret[S2N_TLS_SECRET_LEN];
- uint8_t master_secret[S2N_TLS_SECRET_LEN];
- uint8_t client_random[S2N_TLS_RANDOM_DATA_LEN];
- uint8_t server_random[S2N_TLS_RANDOM_DATA_LEN];
- uint8_t client_implicit_iv[S2N_TLS_MAX_IV_LEN];
- uint8_t server_implicit_iv[S2N_TLS_MAX_IV_LEN];
- uint8_t client_app_secret[S2N_TLS13_SECRET_MAX_LEN];
- uint8_t server_app_secret[S2N_TLS13_SECRET_MAX_LEN];
- struct s2n_hash_state signature_hash;
- struct s2n_hmac_state client_record_mac;
- struct s2n_hmac_state server_record_mac;
- struct s2n_hmac_state record_mac_copy_workspace;
- uint8_t client_sequence_number[S2N_TLS_SEQUENCE_NUM_LEN];
- uint8_t server_sequence_number[S2N_TLS_SEQUENCE_NUM_LEN];
-};
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/s2n_config.h"
+#include "tls/s2n_signature_scheme.h"
+#include "tls/s2n_crypto_constants.h"
+#include "tls/s2n_kem.h"
+
+#include "crypto/s2n_certificate.h"
+#include "crypto/s2n_cipher.h"
+#include "crypto/s2n_hmac.h"
+#include "crypto/s2n_hash.h"
+#include "crypto/s2n_pkey.h"
+#include "crypto/s2n_signature.h"
+#include "crypto/s2n_tls13_keys.h"
+#include "crypto/s2n_dhe.h"
+#include "crypto/s2n_ecc_evp.h"
+
+struct s2n_crypto_parameters {
+ struct s2n_pkey server_public_key;
+ struct s2n_pkey client_public_key;
+ struct s2n_dh_params server_dh_params;
+ struct s2n_ecc_evp_params server_ecc_evp_params;
+ const struct s2n_ecc_named_curve *mutually_supported_curves[S2N_ECC_EVP_SUPPORTED_CURVES_COUNT];
+ struct s2n_ecc_evp_params client_ecc_evp_params[S2N_ECC_EVP_SUPPORTED_CURVES_COUNT];
+ struct s2n_kem_group_params server_kem_group_params;
+ struct s2n_kem_group_params *chosen_client_kem_group_params;
+ struct s2n_kem_group_params client_kem_group_params[S2N_SUPPORTED_KEM_GROUPS_COUNT];
+ const struct s2n_kem_group *mutually_supported_kem_groups[S2N_SUPPORTED_KEM_GROUPS_COUNT];
+ struct s2n_kem_params kem_params;
+ struct s2n_blob client_key_exchange_message;
+ struct s2n_blob client_pq_kem_extension;
+
+ struct s2n_signature_scheme conn_sig_scheme;
+
+ struct s2n_blob client_cert_chain;
+ s2n_pkey_type client_cert_pkey_type;
+
+ struct s2n_signature_scheme client_cert_sig_scheme;
+
+ struct s2n_cipher_suite *cipher_suite;
+ struct s2n_session_key client_key;
+ struct s2n_session_key server_key;
+
+ uint8_t rsa_premaster_secret[S2N_TLS_SECRET_LEN];
+ uint8_t master_secret[S2N_TLS_SECRET_LEN];
+ uint8_t client_random[S2N_TLS_RANDOM_DATA_LEN];
+ uint8_t server_random[S2N_TLS_RANDOM_DATA_LEN];
+ uint8_t client_implicit_iv[S2N_TLS_MAX_IV_LEN];
+ uint8_t server_implicit_iv[S2N_TLS_MAX_IV_LEN];
+ uint8_t client_app_secret[S2N_TLS13_SECRET_MAX_LEN];
+ uint8_t server_app_secret[S2N_TLS13_SECRET_MAX_LEN];
+ struct s2n_hash_state signature_hash;
+ struct s2n_hmac_state client_record_mac;
+ struct s2n_hmac_state server_record_mac;
+ struct s2n_hmac_state record_mac_copy_workspace;
+ uint8_t client_sequence_number[S2N_TLS_SEQUENCE_NUM_LEN];
+ uint8_t server_sequence_number[S2N_TLS_SEQUENCE_NUM_LEN];
+};
diff --git a/contrib/restricted/aws/s2n/tls/s2n_crypto_constants.h b/contrib/restricted/aws/s2n/tls/s2n_crypto_constants.h
index 9b3753ec92..52316e256e 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_crypto_constants.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_crypto_constants.h
@@ -1,50 +1,50 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#define S2N_TLS_SECRET_LEN 48
-#define S2N_TLS_RANDOM_DATA_LEN 32
-#define S2N_TLS_SEQUENCE_NUM_LEN 8
-#define S2N_TLS_CIPHER_SUITE_LEN 2
-#define S2N_SSLv2_CIPHER_SUITE_LEN 3
-#define S2N_TLS_FINISHED_LEN 12
-#define S2N_SSL_FINISHED_LEN 36
-#define S2N_TLS_MAX_IV_LEN 16
-
-/* From RFC 5246 6.2.3.3 */
-#define S2N_TLS12_AAD_LEN 13
-#define S2N_TLS_MAX_AAD_LEN S2N_TLS12_AAD_LEN
-#define S2N_TLS_GCM_FIXED_IV_LEN 4
-#define S2N_TLS_GCM_EXPLICIT_IV_LEN 8
-#define S2N_TLS_GCM_IV_LEN (S2N_TLS_GCM_FIXED_IV_LEN + S2N_TLS_GCM_EXPLICIT_IV_LEN)
-#define S2N_TLS_GCM_TAG_LEN 16
-#define S2N_TLS_AES_128_GCM_KEY_LEN 16
-#define S2N_TLS_AES_256_GCM_KEY_LEN 32
-
-/* TLS 1.3 uses only implicit IVs - RFC 8446 5.3 */
-#define S2N_TLS13_AAD_LEN 5
-#define S2N_TLS13_RECORD_IV_LEN 0
-#define S2N_TLS13_FIXED_IV_LEN 12
-
-/* From RFC 7905 */
-#define S2N_TLS_CHACHA20_POLY1305_FIXED_IV_LEN 12
-#define S2N_TLS_CHACHA20_POLY1305_EXPLICIT_IV_LEN 0
-#define S2N_TLS_CHACHA20_POLY1305_IV_LEN 12
-#define S2N_TLS_CHACHA20_POLY1305_KEY_LEN 32
-#define S2N_TLS_CHACHA20_POLY1305_TAG_LEN 16
-
-/* RFC 5246 7.4.1.2 */
-#define S2N_TLS_SESSION_ID_MAX_LEN 32
+/*
+ * 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.
+ */
+
+#pragma once
+
+#define S2N_TLS_SECRET_LEN 48
+#define S2N_TLS_RANDOM_DATA_LEN 32
+#define S2N_TLS_SEQUENCE_NUM_LEN 8
+#define S2N_TLS_CIPHER_SUITE_LEN 2
+#define S2N_SSLv2_CIPHER_SUITE_LEN 3
+#define S2N_TLS_FINISHED_LEN 12
+#define S2N_SSL_FINISHED_LEN 36
+#define S2N_TLS_MAX_IV_LEN 16
+
+/* From RFC 5246 6.2.3.3 */
+#define S2N_TLS12_AAD_LEN 13
+#define S2N_TLS_MAX_AAD_LEN S2N_TLS12_AAD_LEN
+#define S2N_TLS_GCM_FIXED_IV_LEN 4
+#define S2N_TLS_GCM_EXPLICIT_IV_LEN 8
+#define S2N_TLS_GCM_IV_LEN (S2N_TLS_GCM_FIXED_IV_LEN + S2N_TLS_GCM_EXPLICIT_IV_LEN)
+#define S2N_TLS_GCM_TAG_LEN 16
+#define S2N_TLS_AES_128_GCM_KEY_LEN 16
+#define S2N_TLS_AES_256_GCM_KEY_LEN 32
+
+/* TLS 1.3 uses only implicit IVs - RFC 8446 5.3 */
+#define S2N_TLS13_AAD_LEN 5
+#define S2N_TLS13_RECORD_IV_LEN 0
+#define S2N_TLS13_FIXED_IV_LEN 12
+
+/* From RFC 7905 */
+#define S2N_TLS_CHACHA20_POLY1305_FIXED_IV_LEN 12
+#define S2N_TLS_CHACHA20_POLY1305_EXPLICIT_IV_LEN 0
+#define S2N_TLS_CHACHA20_POLY1305_IV_LEN 12
+#define S2N_TLS_CHACHA20_POLY1305_KEY_LEN 32
+#define S2N_TLS_CHACHA20_POLY1305_TAG_LEN 16
+
+/* RFC 5246 7.4.1.2 */
+#define S2N_TLS_SESSION_ID_MAX_LEN 32
diff --git a/contrib/restricted/aws/s2n/tls/s2n_ecc_preferences.c b/contrib/restricted/aws/s2n/tls/s2n_ecc_preferences.c
index 0568c39589..12db371abb 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_ecc_preferences.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_ecc_preferences.c
@@ -1,111 +1,111 @@
-/*
- * 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 <s2n.h>
-
-#include "tls/s2n_ecc_preferences.h"
-#include "tls/s2n_connection.h"
-#include "crypto/s2n_ecc_evp.h"
-#include "utils/s2n_safety.h"
-
-const struct s2n_ecc_named_curve *const s2n_ecc_pref_list_20140601[] = {
- &s2n_ecc_curve_secp256r1,
- &s2n_ecc_curve_secp384r1,
-};
-
-const struct s2n_ecc_named_curve *const s2n_ecc_pref_list_20200310[] = {
-#if EVP_APIS_SUPPORTED
- &s2n_ecc_curve_x25519,
-#endif
- &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,
- &s2n_ecc_curve_secp521r1,
-};
-
-const struct s2n_ecc_named_curve *const s2n_ecc_pref_list_test_all[] = {
-#if EVP_APIS_SUPPORTED
- &s2n_ecc_curve_x25519,
-#endif
- &s2n_ecc_curve_secp256r1,
- &s2n_ecc_curve_secp384r1,
- &s2n_ecc_curve_secp521r1,
-};
-
-const struct s2n_ecc_preferences s2n_ecc_preferences_20140601 = {
- .count = s2n_array_len(s2n_ecc_pref_list_20140601),
- .ecc_curves = s2n_ecc_pref_list_20140601,
-};
-
-const struct s2n_ecc_preferences s2n_ecc_preferences_20200310 = {
- .count = s2n_array_len(s2n_ecc_pref_list_20200310),
- .ecc_curves = s2n_ecc_pref_list_20200310,
-};
-
-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,
-};
-
-const struct s2n_ecc_preferences s2n_ecc_preferences_test_all = {
- .count = s2n_array_len(s2n_ecc_pref_list_test_all),
- .ecc_curves = s2n_ecc_pref_list_test_all,
-};
-
-const struct s2n_ecc_preferences s2n_ecc_preferences_null = {
- .count = 0,
- .ecc_curves = NULL,
-};
-
-/* Checks if the ecc_curves present in s2n_ecc_preferences list is a subset of s2n_all_supported_curves_list
- * maintained in s2n_ecc_evp.c */
-int s2n_check_ecc_preferences_curves_list(const struct s2n_ecc_preferences *ecc_preferences) {
- int check = 1;
- for (int i = 0; i < ecc_preferences->count; i++) {
- const struct s2n_ecc_named_curve *named_curve = ecc_preferences->ecc_curves[i];
- int curve_found = 0;
- for (int 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;
- }
- }
- check *= curve_found;
- if (check == 0) {
- S2N_ERROR(S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
- }
- }
- return S2N_SUCCESS;
-}
-
-/* Determines if query_iana_id corresponds to a curve for these ECC preferences. */
-bool s2n_ecc_preferences_includes_curve(const struct s2n_ecc_preferences *ecc_preferences, uint16_t query_iana_id) {
- if (ecc_preferences == NULL) {
- return false;
- }
-
- for (size_t i = 0; i < ecc_preferences->count; i++) {
- if (query_iana_id == ecc_preferences->ecc_curves[i]->iana_id) {
- return true;
- }
- }
-
- return false;
-}
-
+/*
+ * 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 <s2n.h>
+
+#include "tls/s2n_ecc_preferences.h"
+#include "tls/s2n_connection.h"
+#include "crypto/s2n_ecc_evp.h"
+#include "utils/s2n_safety.h"
+
+const struct s2n_ecc_named_curve *const s2n_ecc_pref_list_20140601[] = {
+ &s2n_ecc_curve_secp256r1,
+ &s2n_ecc_curve_secp384r1,
+};
+
+const struct s2n_ecc_named_curve *const s2n_ecc_pref_list_20200310[] = {
+#if EVP_APIS_SUPPORTED
+ &s2n_ecc_curve_x25519,
+#endif
+ &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,
+ &s2n_ecc_curve_secp521r1,
+};
+
+const struct s2n_ecc_named_curve *const s2n_ecc_pref_list_test_all[] = {
+#if EVP_APIS_SUPPORTED
+ &s2n_ecc_curve_x25519,
+#endif
+ &s2n_ecc_curve_secp256r1,
+ &s2n_ecc_curve_secp384r1,
+ &s2n_ecc_curve_secp521r1,
+};
+
+const struct s2n_ecc_preferences s2n_ecc_preferences_20140601 = {
+ .count = s2n_array_len(s2n_ecc_pref_list_20140601),
+ .ecc_curves = s2n_ecc_pref_list_20140601,
+};
+
+const struct s2n_ecc_preferences s2n_ecc_preferences_20200310 = {
+ .count = s2n_array_len(s2n_ecc_pref_list_20200310),
+ .ecc_curves = s2n_ecc_pref_list_20200310,
+};
+
+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,
+};
+
+const struct s2n_ecc_preferences s2n_ecc_preferences_test_all = {
+ .count = s2n_array_len(s2n_ecc_pref_list_test_all),
+ .ecc_curves = s2n_ecc_pref_list_test_all,
+};
+
+const struct s2n_ecc_preferences s2n_ecc_preferences_null = {
+ .count = 0,
+ .ecc_curves = NULL,
+};
+
+/* Checks if the ecc_curves present in s2n_ecc_preferences list is a subset of s2n_all_supported_curves_list
+ * maintained in s2n_ecc_evp.c */
+int s2n_check_ecc_preferences_curves_list(const struct s2n_ecc_preferences *ecc_preferences) {
+ int check = 1;
+ for (int i = 0; i < ecc_preferences->count; i++) {
+ const struct s2n_ecc_named_curve *named_curve = ecc_preferences->ecc_curves[i];
+ int curve_found = 0;
+ for (int 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;
+ }
+ }
+ check *= curve_found;
+ if (check == 0) {
+ S2N_ERROR(S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
+ }
+ }
+ return S2N_SUCCESS;
+}
+
+/* Determines if query_iana_id corresponds to a curve for these ECC preferences. */
+bool s2n_ecc_preferences_includes_curve(const struct s2n_ecc_preferences *ecc_preferences, uint16_t query_iana_id) {
+ if (ecc_preferences == NULL) {
+ return false;
+ }
+
+ for (size_t i = 0; i < ecc_preferences->count; i++) {
+ if (query_iana_id == ecc_preferences->ecc_curves[i]->iana_id) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
diff --git a/contrib/restricted/aws/s2n/tls/s2n_ecc_preferences.h b/contrib/restricted/aws/s2n/tls/s2n_ecc_preferences.h
index 8a78398b85..96afa8051a 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_ecc_preferences.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_ecc_preferences.h
@@ -1,35 +1,35 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <s2n.h>
-#include <strings.h>
-#include <stdbool.h>
-
-#include "crypto/s2n_ecc_evp.h"
-
-struct s2n_ecc_preferences {
- uint8_t count;
- const struct s2n_ecc_named_curve *const *ecc_curves;
-};
-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_20201021;
-extern const struct s2n_ecc_preferences s2n_ecc_preferences_test_all;
-extern const struct s2n_ecc_preferences s2n_ecc_preferences_null;
-
-int s2n_check_ecc_preferences_curves_list(const struct s2n_ecc_preferences *ecc_preferences);
-bool s2n_ecc_preferences_includes_curve(const struct s2n_ecc_preferences *ecc_preferences, uint16_t query_iana_id);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <s2n.h>
+#include <strings.h>
+#include <stdbool.h>
+
+#include "crypto/s2n_ecc_evp.h"
+
+struct s2n_ecc_preferences {
+ uint8_t count;
+ const struct s2n_ecc_named_curve *const *ecc_curves;
+};
+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_20201021;
+extern const struct s2n_ecc_preferences s2n_ecc_preferences_test_all;
+extern const struct s2n_ecc_preferences s2n_ecc_preferences_null;
+
+int s2n_check_ecc_preferences_curves_list(const struct s2n_ecc_preferences *ecc_preferences);
+bool s2n_ecc_preferences_includes_curve(const struct s2n_ecc_preferences *ecc_preferences, uint16_t query_iana_id);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_encrypted_extensions.c b/contrib/restricted/aws/s2n/tls/s2n_encrypted_extensions.c
index f0d2b94dd8..d61d7c1b2d 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_encrypted_extensions.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_encrypted_extensions.c
@@ -1,55 +1,55 @@
-/*
- * 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 "error/s2n_errno.h"
-#include "utils/s2n_safety.h"
-#include "stuffer/s2n_stuffer.h"
-
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls13.h"
-
-#include "tls/extensions/s2n_extension_list.h"
-
-/**
- * Specified in https://tools.ietf.org/html/rfc8446#section-4.3.1
- *
- * In all handshakes, the server MUST send the EncryptedExtensions
- * message immediately after the ServerHello message.
- *
- * The EncryptedExtensions message contains extensions that can be
- * protected, i.e., any which are not needed to establish the
- * cryptographic context but which are not associated with individual
- * certificates.
- **/
-
-int s2n_encrypted_extensions_send(struct s2n_connection *conn)
-{
- notnull_check(conn);
- ENSURE_POSIX(conn->actual_protocol_version >= S2N_TLS13, S2N_ERR_BAD_MESSAGE);
-
- struct s2n_stuffer *out = &conn->handshake.io;
- GUARD(s2n_extension_list_send(S2N_EXTENSION_LIST_ENCRYPTED_EXTENSIONS, conn, out));
- return S2N_SUCCESS;
-}
-
-int s2n_encrypted_extensions_recv(struct s2n_connection *conn)
-{
- notnull_check(conn);
- ENSURE_POSIX(conn->actual_protocol_version >= S2N_TLS13, S2N_ERR_BAD_MESSAGE);
-
- struct s2n_stuffer *in = &conn->handshake.io;
- GUARD(s2n_extension_list_recv(S2N_EXTENSION_LIST_ENCRYPTED_EXTENSIONS, conn, in));
- return S2N_SUCCESS;
-}
+/*
+ * 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 "error/s2n_errno.h"
+#include "utils/s2n_safety.h"
+#include "stuffer/s2n_stuffer.h"
+
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls13.h"
+
+#include "tls/extensions/s2n_extension_list.h"
+
+/**
+ * Specified in https://tools.ietf.org/html/rfc8446#section-4.3.1
+ *
+ * In all handshakes, the server MUST send the EncryptedExtensions
+ * message immediately after the ServerHello message.
+ *
+ * The EncryptedExtensions message contains extensions that can be
+ * protected, i.e., any which are not needed to establish the
+ * cryptographic context but which are not associated with individual
+ * certificates.
+ **/
+
+int s2n_encrypted_extensions_send(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+ ENSURE_POSIX(conn->actual_protocol_version >= S2N_TLS13, S2N_ERR_BAD_MESSAGE);
+
+ struct s2n_stuffer *out = &conn->handshake.io;
+ GUARD(s2n_extension_list_send(S2N_EXTENSION_LIST_ENCRYPTED_EXTENSIONS, conn, out));
+ return S2N_SUCCESS;
+}
+
+int s2n_encrypted_extensions_recv(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+ ENSURE_POSIX(conn->actual_protocol_version >= S2N_TLS13, S2N_ERR_BAD_MESSAGE);
+
+ struct s2n_stuffer *in = &conn->handshake.io;
+ GUARD(s2n_extension_list_recv(S2N_EXTENSION_LIST_ENCRYPTED_EXTENSIONS, conn, in));
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_establish_session.c b/contrib/restricted/aws/s2n/tls/s2n_establish_session.c
index 95c0df5283..e61b9f2850 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_establish_session.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_establish_session.c
@@ -1,55 +1,55 @@
-/*
- * Copyright 2020 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 <stdint.h>
-#include <s2n.h>
-
-#include "error/s2n_errno.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "tls/s2n_connection.h"
-#include "tls/s2n_tls.h"
-
-#include "utils/s2n_array.h"
-
-
-/* Establishing a session requires reading the CLIENT_HELLO message and then generating security parameters.
- *
- * S2N supports resuming sessions under TLS1.2 if the client sends a session ID. The server can lookup a
- * provided session ID in its cache. */
-int s2n_establish_session(struct s2n_connection *conn)
-{
- GUARD(s2n_conn_set_handshake_read_block(conn));
-
- /* Start by receiving and processing the entire CLIENT_HELLO message */
- if (!conn->handshake.client_hello_received) {
- GUARD(s2n_client_hello_recv(conn));
- conn->handshake.client_hello_received = 1;
- }
-
- GUARD(s2n_conn_set_handshake_type(conn));
-
- if (conn->client_hello_version != S2N_SSLv2)
- {
- /* We've selected the parameters for the handshake, update the required hashes for this connection */
- GUARD(s2n_conn_update_required_handshake_hashes(conn));
- }
-
- GUARD(s2n_conn_clear_handshake_read_block(conn));
-
- return 0;
-}
-
+/*
+ * Copyright 2020 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 <stdint.h>
+#include <s2n.h>
+
+#include "error/s2n_errno.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "tls/s2n_connection.h"
+#include "tls/s2n_tls.h"
+
+#include "utils/s2n_array.h"
+
+
+/* Establishing a session requires reading the CLIENT_HELLO message and then generating security parameters.
+ *
+ * S2N supports resuming sessions under TLS1.2 if the client sends a session ID. The server can lookup a
+ * provided session ID in its cache. */
+int s2n_establish_session(struct s2n_connection *conn)
+{
+ GUARD(s2n_conn_set_handshake_read_block(conn));
+
+ /* Start by receiving and processing the entire CLIENT_HELLO message */
+ if (!conn->handshake.client_hello_received) {
+ GUARD(s2n_client_hello_recv(conn));
+ conn->handshake.client_hello_received = 1;
+ }
+
+ GUARD(s2n_conn_set_handshake_type(conn));
+
+ if (conn->client_hello_version != S2N_SSLv2)
+ {
+ /* We've selected the parameters for the handshake, update the required hashes for this connection */
+ GUARD(s2n_conn_update_required_handshake_hashes(conn));
+ }
+
+ GUARD(s2n_conn_clear_handshake_read_block(conn));
+
+ return 0;
+}
+
diff --git a/contrib/restricted/aws/s2n/tls/s2n_handshake.c b/contrib/restricted/aws/s2n/tls/s2n_handshake.c
index 9e667acaa3..922cd67c2b 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_handshake.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_handshake.c
@@ -1,331 +1,331 @@
-/*
- * 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 <stdint.h>
-
-#include "error/s2n_errno.h"
-
-#include "tls/s2n_connection.h"
-#include "tls/s2n_record.h"
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_tls.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_map.h"
-
-int s2n_handshake_write_header(struct s2n_stuffer *out, uint8_t message_type)
-{
- S2N_ERROR_IF(s2n_stuffer_data_available(out), S2N_ERR_HANDSHAKE_STATE);
-
- /* Write the message header */
- GUARD(s2n_stuffer_write_uint8(out, message_type));
-
- /* Leave the length blank for now */
- uint16_t length = 0;
- GUARD(s2n_stuffer_write_uint24(out, length));
-
- return 0;
-}
-
-int s2n_handshake_finish_header(struct s2n_stuffer *out)
-{
- uint16_t length = s2n_stuffer_data_available(out);
- S2N_ERROR_IF(length < TLS_HANDSHAKE_HEADER_LENGTH, S2N_ERR_SIZE_MISMATCH);
-
- uint16_t payload = length - TLS_HANDSHAKE_HEADER_LENGTH;
-
- /* Write the message header */
- GUARD(s2n_stuffer_rewrite(out));
- GUARD(s2n_stuffer_skip_write(out, 1));
- GUARD(s2n_stuffer_write_uint24(out, payload));
- GUARD(s2n_stuffer_skip_write(out, payload));
-
- return 0;
-}
-
-int s2n_handshake_parse_header(struct s2n_connection *conn, uint8_t * message_type, uint32_t * length)
-{
- S2N_ERROR_IF(s2n_stuffer_data_available(&conn->handshake.io) < TLS_HANDSHAKE_HEADER_LENGTH, S2N_ERR_SIZE_MISMATCH);
-
- /* read the message header */
- GUARD(s2n_stuffer_read_uint8(&conn->handshake.io, message_type));
- GUARD(s2n_stuffer_read_uint24(&conn->handshake.io, length));
-
- return 0;
-}
-
-static int s2n_handshake_get_hash_state_ptr(struct s2n_connection *conn, s2n_hash_algorithm hash_alg, struct s2n_hash_state **hash_state)
-{
- notnull_check(conn);
-
- switch (hash_alg) {
- case S2N_HASH_MD5:
- *hash_state = &conn->handshake.md5;
- break;
- case S2N_HASH_SHA1:
- *hash_state = &conn->handshake.sha1;
- break;
- case S2N_HASH_SHA224:
- *hash_state = &conn->handshake.sha224;
- break;
- case S2N_HASH_SHA256:
- *hash_state = &conn->handshake.sha256;
- break;
- case S2N_HASH_SHA384:
- *hash_state = &conn->handshake.sha384;
- break;
- case S2N_HASH_SHA512:
- *hash_state = &conn->handshake.sha512;
- break;
- case S2N_HASH_MD5_SHA1:
- *hash_state = &conn->handshake.md5_sha1;
- break;
- default:
- S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
- break;
- }
-
- return 0;
-}
-
-int s2n_handshake_reset_hash_state(struct s2n_connection *conn, s2n_hash_algorithm hash_alg)
-{
- struct s2n_hash_state *hash_state_ptr = NULL;
- GUARD(s2n_handshake_get_hash_state_ptr(conn, hash_alg, &hash_state_ptr));
-
- GUARD(s2n_hash_reset(hash_state_ptr));
-
- return 0;
-}
-
-/* Copy the current hash state into the caller supplied pointer.
- * NOTE: If the underlying digest implementation is using the EVP API
- * then a pointer to the EVP ctx and md is copied. So you are actually
- * taking a reference, not a value.
- * Before using the hash_state returned by this function you must
- * use s2n_hash_copy() to avoid modifying the underlying value.
- */
-int s2n_handshake_get_hash_state(struct s2n_connection *conn, s2n_hash_algorithm hash_alg, struct s2n_hash_state *hash_state)
-{
- notnull_check(hash_state);
-
- struct s2n_hash_state *hash_state_ptr = NULL;
- GUARD(s2n_handshake_get_hash_state_ptr(conn, hash_alg, &hash_state_ptr));
-
- *hash_state = *hash_state_ptr;
-
- return 0;
-}
-
-int s2n_handshake_require_all_hashes(struct s2n_handshake *handshake)
-{
- memset(handshake->required_hash_algs, 1, sizeof(handshake->required_hash_algs));
- return 0;
-}
-
-static int s2n_handshake_require_hash(struct s2n_handshake *handshake, s2n_hash_algorithm hash_alg)
-{
- handshake->required_hash_algs[hash_alg] = 1;
- return 0;
-}
-
-uint8_t s2n_handshake_is_hash_required(struct s2n_handshake *handshake, s2n_hash_algorithm hash_alg)
-{
- return handshake->required_hash_algs[hash_alg];
-}
-
-/* Update the required handshake hash algs depending on current handshake session state.
- * This function must called at the end of a handshake message handler. Additionally it must be called after the
- * ClientHello or ServerHello is processed in client and server mode respectively. The relevant handshake parameters
- * are not available until those messages are processed.
- */
-int s2n_conn_update_required_handshake_hashes(struct s2n_connection *conn)
-{
- /* Clear all of the required hashes */
- memset(conn->handshake.required_hash_algs, 0, sizeof(conn->handshake.required_hash_algs));
-
- message_type_t handshake_message = s2n_conn_get_current_message_type(conn);
- const uint8_t client_cert_verify_done = (handshake_message >= CLIENT_CERT_VERIFY) ? 1 : 0;
- s2n_cert_auth_type client_cert_auth_type;
- GUARD(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
-
- /* If client authentication is possible, all hashes are needed until we're past CLIENT_CERT_VERIFY. */
- if ((client_cert_auth_type != S2N_CERT_AUTH_NONE) && !client_cert_verify_done) {
- GUARD(s2n_handshake_require_all_hashes(&conn->handshake));
- return 0;
- }
-
- /* We don't need all of the hashes. Set the hash alg(s) required for the PRF */
- switch (conn->actual_protocol_version) {
- case S2N_SSLv3:
- case S2N_TLS10:
- case S2N_TLS11:
- GUARD(s2n_handshake_require_hash(&conn->handshake, S2N_HASH_MD5));
- GUARD(s2n_handshake_require_hash(&conn->handshake, S2N_HASH_SHA1));
- break;
- case S2N_TLS12:
- /* fall through */
- case S2N_TLS13:
- {
- /* For TLS 1.2 and TLS 1.3, the cipher suite defines the PRF hash alg */
- s2n_hmac_algorithm prf_alg = conn->secure.cipher_suite->prf_alg;
- s2n_hash_algorithm hash_alg;
- GUARD(s2n_hmac_hash_alg(prf_alg, &hash_alg));
- GUARD(s2n_handshake_require_hash(&conn->handshake, hash_alg));
- break;
- }
- }
-
- return 0;
-}
-
-/*
- * Take a hostname and return a single "simple" wildcard domain name that matches it.
- * The output wildcard representation is meant to be compared directly against a wildcard domain in a certificate.
- * We take a restrictive definition of wildcard here to achieve a single unique wildcard representation
- * given any input hostname.
- * No embedded or trailing wildcards are supported. Additionally, we only support one level of wildcard matching.
- * Thus the output should be a single wildcard character in the first(left-most) DNS label.
- *
- * Example:
- * - my.domain.name -> *.domain.name
- *
- * Not supported:
- * - my.domain.name -> m*.domain.name
- * - my.domain.name -> my.*.name
- * etc.
- *
- * The motivation for using a constrained definition of wildcard:
- * - Support for issuing non-simple wildcard certificates is insignificant.
- * - Certificate selection can be implemented with a constant number of lookups(two).
- */
-int s2n_create_wildcard_hostname(struct s2n_stuffer *hostname_stuffer, struct s2n_stuffer *output)
-{
- /* Find the end of the first label */
- GUARD(s2n_stuffer_skip_to_char(hostname_stuffer, '.'));
-
- /* No first label found */
- if (s2n_stuffer_data_available(hostname_stuffer) == 0) {
- return 0;
- }
-
- /* Slap a single wildcard character to be the first label in output */
- GUARD(s2n_stuffer_write_uint8(output, '*'));
-
- /* Simply copy the rest of the input to the output. */
- GUARD(s2n_stuffer_copy(hostname_stuffer, output, s2n_stuffer_data_available(hostname_stuffer)));
-
- return 0;
-}
-
-static int s2n_find_cert_matches(struct s2n_map *domain_name_to_cert_map,
- struct s2n_blob *dns_name,
- struct s2n_cert_chain_and_key *matches[S2N_CERT_TYPE_COUNT],
- uint8_t *match_exists)
-{
- struct s2n_blob map_value;
- bool key_found = false;
- GUARD_AS_POSIX(s2n_map_lookup(domain_name_to_cert_map, dns_name, &map_value, &key_found));
- if (key_found) {
- struct certs_by_type *value = (void *) map_value.data;
- for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) {
- matches[i] = value->certs[i];
- }
- *match_exists = 1;
- }
-
- return 0;
-}
-
-/* Find certificates that match the ServerName TLS extension sent by the client.
- * For a given ServerName there can be multiple matching certificates based on the
- * type of key in the certificate.
- *
- * A match is determined using s2n_map lookup by DNS name.
- * Wildcards that have a single * in the left most label are supported.
- */
-int s2n_conn_find_name_matching_certs(struct s2n_connection *conn)
-{
- if (!s2n_server_received_server_name(conn)) {
- return 0;
- }
- const char *name = conn->server_name;
- struct s2n_blob hostname_blob = { .data = (uint8_t *) (uintptr_t) name, .size = strlen(name) };
- lte_check(hostname_blob.size, S2N_MAX_SERVER_NAME);
- char normalized_hostname[S2N_MAX_SERVER_NAME + 1] = { 0 };
- memcpy_check(normalized_hostname, hostname_blob.data, hostname_blob.size);
- struct s2n_blob normalized_name = { .data = (uint8_t *) normalized_hostname, .size = hostname_blob.size };
- GUARD(s2n_blob_char_to_lower(&normalized_name));
- struct s2n_stuffer normalized_hostname_stuffer;
- GUARD(s2n_stuffer_init(&normalized_hostname_stuffer, &normalized_name));
- GUARD(s2n_stuffer_skip_write(&normalized_hostname_stuffer, normalized_name.size));
-
- /* Find the exact matches for the ServerName */
- GUARD(s2n_find_cert_matches(conn->config->domain_name_to_cert_map,
- &normalized_name,
- conn->handshake_params.exact_sni_matches,
- &(conn->handshake_params.exact_sni_match_exists)));
-
- if (!conn->handshake_params.exact_sni_match_exists) {
- /* We have not yet found an exact domain match. Try to find wildcard matches. */
- char wildcard_hostname[S2N_MAX_SERVER_NAME + 1] = { 0 };
- struct s2n_blob wildcard_blob = { .data = (uint8_t *) wildcard_hostname, .size = sizeof(wildcard_hostname) };
- struct s2n_stuffer wildcard_stuffer;
- GUARD(s2n_stuffer_init(&wildcard_stuffer, &wildcard_blob));
- GUARD(s2n_create_wildcard_hostname(&normalized_hostname_stuffer, &wildcard_stuffer));
- const uint32_t wildcard_len = s2n_stuffer_data_available(&wildcard_stuffer);
-
- /* Couldn't create a valid wildcard from the input */
- if (wildcard_len == 0) {
- return 0;
- }
-
- /* The client's SNI is wildcardified, do an exact match against the set of server certs. */
- wildcard_blob.size = wildcard_len;
- GUARD(s2n_find_cert_matches(conn->config->domain_name_to_cert_map,
- &wildcard_blob,
- conn->handshake_params.wc_sni_matches,
- &(conn->handshake_params.wc_sni_match_exists)));
- }
-
- /* If we found a suitable cert, we should send back the ServerName extension.
- * Note that this may have already been set by the client hello callback, so we won't override its value
- */
- conn->server_name_used = conn->server_name_used
- || conn->handshake_params.exact_sni_match_exists
- || conn->handshake_params.wc_sni_match_exists;
-
- return 0;
-}
-
-/* Find the optimal certificate of a specific type.
- * The priority of set of certificates to choose from:
- * 1. Certificates that match the client's ServerName extension.
- * 2. Default certificates
- */
-struct s2n_cert_chain_and_key *s2n_get_compatible_cert_chain_and_key(struct s2n_connection *conn, const s2n_pkey_type cert_type)
-{
- if (conn->handshake_params.exact_sni_match_exists) {
- /* This may return NULL if there was an SNI match, but not a match the cipher_suite's authentication type. */
- return conn->handshake_params.exact_sni_matches[cert_type];
- } if (conn->handshake_params.wc_sni_match_exists) {
- return conn->handshake_params.wc_sni_matches[cert_type];
- } else {
- /* We don't have any name matches. Use the default certificate that works with the key type. */
- return conn->config->default_certs_by_type.certs[cert_type];
- }
-}
+/*
+ * 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 <stdint.h>
+
+#include "error/s2n_errno.h"
+
+#include "tls/s2n_connection.h"
+#include "tls/s2n_record.h"
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_tls.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_map.h"
+
+int s2n_handshake_write_header(struct s2n_stuffer *out, uint8_t message_type)
+{
+ S2N_ERROR_IF(s2n_stuffer_data_available(out), S2N_ERR_HANDSHAKE_STATE);
+
+ /* Write the message header */
+ GUARD(s2n_stuffer_write_uint8(out, message_type));
+
+ /* Leave the length blank for now */
+ uint16_t length = 0;
+ GUARD(s2n_stuffer_write_uint24(out, length));
+
+ return 0;
+}
+
+int s2n_handshake_finish_header(struct s2n_stuffer *out)
+{
+ uint16_t length = s2n_stuffer_data_available(out);
+ S2N_ERROR_IF(length < TLS_HANDSHAKE_HEADER_LENGTH, S2N_ERR_SIZE_MISMATCH);
+
+ uint16_t payload = length - TLS_HANDSHAKE_HEADER_LENGTH;
+
+ /* Write the message header */
+ GUARD(s2n_stuffer_rewrite(out));
+ GUARD(s2n_stuffer_skip_write(out, 1));
+ GUARD(s2n_stuffer_write_uint24(out, payload));
+ GUARD(s2n_stuffer_skip_write(out, payload));
+
+ return 0;
+}
+
+int s2n_handshake_parse_header(struct s2n_connection *conn, uint8_t * message_type, uint32_t * length)
+{
+ S2N_ERROR_IF(s2n_stuffer_data_available(&conn->handshake.io) < TLS_HANDSHAKE_HEADER_LENGTH, S2N_ERR_SIZE_MISMATCH);
+
+ /* read the message header */
+ GUARD(s2n_stuffer_read_uint8(&conn->handshake.io, message_type));
+ GUARD(s2n_stuffer_read_uint24(&conn->handshake.io, length));
+
+ return 0;
+}
+
+static int s2n_handshake_get_hash_state_ptr(struct s2n_connection *conn, s2n_hash_algorithm hash_alg, struct s2n_hash_state **hash_state)
+{
+ notnull_check(conn);
+
+ switch (hash_alg) {
+ case S2N_HASH_MD5:
+ *hash_state = &conn->handshake.md5;
+ break;
+ case S2N_HASH_SHA1:
+ *hash_state = &conn->handshake.sha1;
+ break;
+ case S2N_HASH_SHA224:
+ *hash_state = &conn->handshake.sha224;
+ break;
+ case S2N_HASH_SHA256:
+ *hash_state = &conn->handshake.sha256;
+ break;
+ case S2N_HASH_SHA384:
+ *hash_state = &conn->handshake.sha384;
+ break;
+ case S2N_HASH_SHA512:
+ *hash_state = &conn->handshake.sha512;
+ break;
+ case S2N_HASH_MD5_SHA1:
+ *hash_state = &conn->handshake.md5_sha1;
+ break;
+ default:
+ S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
+ break;
+ }
+
+ return 0;
+}
+
+int s2n_handshake_reset_hash_state(struct s2n_connection *conn, s2n_hash_algorithm hash_alg)
+{
+ struct s2n_hash_state *hash_state_ptr = NULL;
+ GUARD(s2n_handshake_get_hash_state_ptr(conn, hash_alg, &hash_state_ptr));
+
+ GUARD(s2n_hash_reset(hash_state_ptr));
+
+ return 0;
+}
+
+/* Copy the current hash state into the caller supplied pointer.
+ * NOTE: If the underlying digest implementation is using the EVP API
+ * then a pointer to the EVP ctx and md is copied. So you are actually
+ * taking a reference, not a value.
+ * Before using the hash_state returned by this function you must
+ * use s2n_hash_copy() to avoid modifying the underlying value.
+ */
+int s2n_handshake_get_hash_state(struct s2n_connection *conn, s2n_hash_algorithm hash_alg, struct s2n_hash_state *hash_state)
+{
+ notnull_check(hash_state);
+
+ struct s2n_hash_state *hash_state_ptr = NULL;
+ GUARD(s2n_handshake_get_hash_state_ptr(conn, hash_alg, &hash_state_ptr));
+
+ *hash_state = *hash_state_ptr;
+
+ return 0;
+}
+
+int s2n_handshake_require_all_hashes(struct s2n_handshake *handshake)
+{
+ memset(handshake->required_hash_algs, 1, sizeof(handshake->required_hash_algs));
+ return 0;
+}
+
+static int s2n_handshake_require_hash(struct s2n_handshake *handshake, s2n_hash_algorithm hash_alg)
+{
+ handshake->required_hash_algs[hash_alg] = 1;
+ return 0;
+}
+
+uint8_t s2n_handshake_is_hash_required(struct s2n_handshake *handshake, s2n_hash_algorithm hash_alg)
+{
+ return handshake->required_hash_algs[hash_alg];
+}
+
+/* Update the required handshake hash algs depending on current handshake session state.
+ * This function must called at the end of a handshake message handler. Additionally it must be called after the
+ * ClientHello or ServerHello is processed in client and server mode respectively. The relevant handshake parameters
+ * are not available until those messages are processed.
+ */
+int s2n_conn_update_required_handshake_hashes(struct s2n_connection *conn)
+{
+ /* Clear all of the required hashes */
+ memset(conn->handshake.required_hash_algs, 0, sizeof(conn->handshake.required_hash_algs));
+
+ message_type_t handshake_message = s2n_conn_get_current_message_type(conn);
+ const uint8_t client_cert_verify_done = (handshake_message >= CLIENT_CERT_VERIFY) ? 1 : 0;
+ s2n_cert_auth_type client_cert_auth_type;
+ GUARD(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
+
+ /* If client authentication is possible, all hashes are needed until we're past CLIENT_CERT_VERIFY. */
+ if ((client_cert_auth_type != S2N_CERT_AUTH_NONE) && !client_cert_verify_done) {
+ GUARD(s2n_handshake_require_all_hashes(&conn->handshake));
+ return 0;
+ }
+
+ /* We don't need all of the hashes. Set the hash alg(s) required for the PRF */
+ switch (conn->actual_protocol_version) {
+ case S2N_SSLv3:
+ case S2N_TLS10:
+ case S2N_TLS11:
+ GUARD(s2n_handshake_require_hash(&conn->handshake, S2N_HASH_MD5));
+ GUARD(s2n_handshake_require_hash(&conn->handshake, S2N_HASH_SHA1));
+ break;
+ case S2N_TLS12:
+ /* fall through */
+ case S2N_TLS13:
+ {
+ /* For TLS 1.2 and TLS 1.3, the cipher suite defines the PRF hash alg */
+ s2n_hmac_algorithm prf_alg = conn->secure.cipher_suite->prf_alg;
+ s2n_hash_algorithm hash_alg;
+ GUARD(s2n_hmac_hash_alg(prf_alg, &hash_alg));
+ GUARD(s2n_handshake_require_hash(&conn->handshake, hash_alg));
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Take a hostname and return a single "simple" wildcard domain name that matches it.
+ * The output wildcard representation is meant to be compared directly against a wildcard domain in a certificate.
+ * We take a restrictive definition of wildcard here to achieve a single unique wildcard representation
+ * given any input hostname.
+ * No embedded or trailing wildcards are supported. Additionally, we only support one level of wildcard matching.
+ * Thus the output should be a single wildcard character in the first(left-most) DNS label.
+ *
+ * Example:
+ * - my.domain.name -> *.domain.name
+ *
+ * Not supported:
+ * - my.domain.name -> m*.domain.name
+ * - my.domain.name -> my.*.name
+ * etc.
+ *
+ * The motivation for using a constrained definition of wildcard:
+ * - Support for issuing non-simple wildcard certificates is insignificant.
+ * - Certificate selection can be implemented with a constant number of lookups(two).
+ */
+int s2n_create_wildcard_hostname(struct s2n_stuffer *hostname_stuffer, struct s2n_stuffer *output)
+{
+ /* Find the end of the first label */
+ GUARD(s2n_stuffer_skip_to_char(hostname_stuffer, '.'));
+
+ /* No first label found */
+ if (s2n_stuffer_data_available(hostname_stuffer) == 0) {
+ return 0;
+ }
+
+ /* Slap a single wildcard character to be the first label in output */
+ GUARD(s2n_stuffer_write_uint8(output, '*'));
+
+ /* Simply copy the rest of the input to the output. */
+ GUARD(s2n_stuffer_copy(hostname_stuffer, output, s2n_stuffer_data_available(hostname_stuffer)));
+
+ return 0;
+}
+
+static int s2n_find_cert_matches(struct s2n_map *domain_name_to_cert_map,
+ struct s2n_blob *dns_name,
+ struct s2n_cert_chain_and_key *matches[S2N_CERT_TYPE_COUNT],
+ uint8_t *match_exists)
+{
+ struct s2n_blob map_value;
+ bool key_found = false;
+ GUARD_AS_POSIX(s2n_map_lookup(domain_name_to_cert_map, dns_name, &map_value, &key_found));
+ if (key_found) {
+ struct certs_by_type *value = (void *) map_value.data;
+ for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) {
+ matches[i] = value->certs[i];
+ }
+ *match_exists = 1;
+ }
+
+ return 0;
+}
+
+/* Find certificates that match the ServerName TLS extension sent by the client.
+ * For a given ServerName there can be multiple matching certificates based on the
+ * type of key in the certificate.
+ *
+ * A match is determined using s2n_map lookup by DNS name.
+ * Wildcards that have a single * in the left most label are supported.
+ */
+int s2n_conn_find_name_matching_certs(struct s2n_connection *conn)
+{
+ if (!s2n_server_received_server_name(conn)) {
+ return 0;
+ }
+ const char *name = conn->server_name;
+ struct s2n_blob hostname_blob = { .data = (uint8_t *) (uintptr_t) name, .size = strlen(name) };
+ lte_check(hostname_blob.size, S2N_MAX_SERVER_NAME);
+ char normalized_hostname[S2N_MAX_SERVER_NAME + 1] = { 0 };
+ memcpy_check(normalized_hostname, hostname_blob.data, hostname_blob.size);
+ struct s2n_blob normalized_name = { .data = (uint8_t *) normalized_hostname, .size = hostname_blob.size };
+ GUARD(s2n_blob_char_to_lower(&normalized_name));
+ struct s2n_stuffer normalized_hostname_stuffer;
+ GUARD(s2n_stuffer_init(&normalized_hostname_stuffer, &normalized_name));
+ GUARD(s2n_stuffer_skip_write(&normalized_hostname_stuffer, normalized_name.size));
+
+ /* Find the exact matches for the ServerName */
+ GUARD(s2n_find_cert_matches(conn->config->domain_name_to_cert_map,
+ &normalized_name,
+ conn->handshake_params.exact_sni_matches,
+ &(conn->handshake_params.exact_sni_match_exists)));
+
+ if (!conn->handshake_params.exact_sni_match_exists) {
+ /* We have not yet found an exact domain match. Try to find wildcard matches. */
+ char wildcard_hostname[S2N_MAX_SERVER_NAME + 1] = { 0 };
+ struct s2n_blob wildcard_blob = { .data = (uint8_t *) wildcard_hostname, .size = sizeof(wildcard_hostname) };
+ struct s2n_stuffer wildcard_stuffer;
+ GUARD(s2n_stuffer_init(&wildcard_stuffer, &wildcard_blob));
+ GUARD(s2n_create_wildcard_hostname(&normalized_hostname_stuffer, &wildcard_stuffer));
+ const uint32_t wildcard_len = s2n_stuffer_data_available(&wildcard_stuffer);
+
+ /* Couldn't create a valid wildcard from the input */
+ if (wildcard_len == 0) {
+ return 0;
+ }
+
+ /* The client's SNI is wildcardified, do an exact match against the set of server certs. */
+ wildcard_blob.size = wildcard_len;
+ GUARD(s2n_find_cert_matches(conn->config->domain_name_to_cert_map,
+ &wildcard_blob,
+ conn->handshake_params.wc_sni_matches,
+ &(conn->handshake_params.wc_sni_match_exists)));
+ }
+
+ /* If we found a suitable cert, we should send back the ServerName extension.
+ * Note that this may have already been set by the client hello callback, so we won't override its value
+ */
+ conn->server_name_used = conn->server_name_used
+ || conn->handshake_params.exact_sni_match_exists
+ || conn->handshake_params.wc_sni_match_exists;
+
+ return 0;
+}
+
+/* Find the optimal certificate of a specific type.
+ * The priority of set of certificates to choose from:
+ * 1. Certificates that match the client's ServerName extension.
+ * 2. Default certificates
+ */
+struct s2n_cert_chain_and_key *s2n_get_compatible_cert_chain_and_key(struct s2n_connection *conn, const s2n_pkey_type cert_type)
+{
+ if (conn->handshake_params.exact_sni_match_exists) {
+ /* This may return NULL if there was an SNI match, but not a match the cipher_suite's authentication type. */
+ return conn->handshake_params.exact_sni_matches[cert_type];
+ } if (conn->handshake_params.wc_sni_match_exists) {
+ return conn->handshake_params.wc_sni_matches[cert_type];
+ } else {
+ /* We don't have any name matches. Use the default certificate that works with the key type. */
+ return conn->config->default_certs_by_type.certs[cert_type];
+ }
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_handshake.h b/contrib/restricted/aws/s2n/tls/s2n_handshake.h
index a0fde5f3af..cb871889e4 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_handshake.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_handshake.h
@@ -1,220 +1,220 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <stdint.h>
-#include <s2n.h>
-
-#include "tls/s2n_crypto.h"
-#include "tls/s2n_signature_algorithms.h"
-#include "tls/s2n_tls_parameters.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "crypto/s2n_certificate.h"
-#include "crypto/s2n_hash.h"
-
-/* From RFC 8446: https://tools.ietf.org/html/rfc8446#appendix-B.3 */
-#define TLS_HELLO_REQUEST 0
-#define TLS_CLIENT_HELLO 1
-#define TLS_SERVER_HELLO 2
-#define TLS_SERVER_NEW_SESSION_TICKET 4
-#define TLS_ENCRYPTED_EXTENSIONS 8
-#define TLS_CERTIFICATE 11
-#define TLS_SERVER_KEY 12
-#define TLS_CERT_REQ 13
-#define TLS_SERVER_HELLO_DONE 14
-#define TLS_CERT_VERIFY 15
-#define TLS_CLIENT_KEY 16
-#define TLS_FINISHED 20
-#define TLS_SERVER_CERT_STATUS 22
-#define TLS_SERVER_SESSION_LOOKUP 23
-#define TLS_KEY_UPDATE 24
-#define TLS_MESSAGE_HASH 254
-
-/* This is the list of message types that we support */
-typedef enum {
- CLIENT_HELLO=0,
- SERVER_HELLO,
- SERVER_CERT,
- SERVER_NEW_SESSION_TICKET,
- SERVER_CERT_STATUS,
- SERVER_KEY,
- SERVER_CERT_REQ,
- SERVER_HELLO_DONE,
- CLIENT_CERT,
- CLIENT_KEY,
- CLIENT_CERT_VERIFY,
- CLIENT_CHANGE_CIPHER_SPEC,
- CLIENT_FINISHED,
- SERVER_CHANGE_CIPHER_SPEC,
- SERVER_FINISHED,
-
- /* TLS1.3 message types. Defined: https://tools.ietf.org/html/rfc8446#appendix-B.3 */
- ENCRYPTED_EXTENSIONS,
- SERVER_CERT_VERIFY,
- HELLO_RETRY_MSG,
-
- APPLICATION_DATA,
-} message_type_t;
-
-typedef enum {
- S2N_ASYNC_NOT_INVOKED = 0,
- S2N_ASYNC_INVOKING_CALLBACK,
- S2N_ASYNC_INVOKED_WAITING,
- S2N_ASYNC_INVOKED_COMPLETE,
-} s2n_async_state;
-
-struct s2n_handshake_parameters {
- /* Signature/hash algorithm pairs offered by the client in the signature_algorithms extension */
- struct s2n_sig_scheme_list client_sig_hash_algs;
-
- /* Signature/hash algorithm pairs offered by the server in the certificate request */
- struct s2n_sig_scheme_list server_sig_hash_algs;
-
- /* The cert chain we will send the peer. */
- struct s2n_cert_chain_and_key *our_chain_and_key;
-
- /* The subset of certificates that match the server_name presented in the ClientHello.
- * In the case of multiple certificates matching a server_name, s2n will prefer certificates
- * in FIFO order based on calls to s2n_config_add_cert_chain_and_key_to_store
- *
- * Note that in addition to domain matching, the key type for the certificate must also be
- * suitable for a negotiation in order to be selected. The set of matching certs here are indexed
- * by s2n_authentication_method.
- *
- * Example:
- * - Assume certA is added to s2n_config via s2n_config_add_cert_chain_and_key_to_store
- * - Next certB is added.
- * - if certA matches www.foo.com and certB matches www.foo.com, s2n will prefer certA
- *
- * Note that in addition to domain matching, the key type for the certificate must also be
- * suitable for a negotiation in order to be selected.
- *
- * Example:
- * - Assume certA and certB match server_name www.foo.com
- * - certA is ECDSA and certB is RSA.
- * - Client only supports RSA ciphers
- * - certB will be selected.
- */
- struct s2n_cert_chain_and_key *exact_sni_matches[S2N_CERT_TYPE_COUNT];
- struct s2n_cert_chain_and_key *wc_sni_matches[S2N_CERT_TYPE_COUNT];
- uint8_t exact_sni_match_exists;
- uint8_t wc_sni_match_exists;
-};
-
-struct s2n_handshake {
- struct s2n_stuffer io;
-
- struct s2n_hash_state md5;
- struct s2n_hash_state sha1;
- struct s2n_hash_state sha224;
- struct s2n_hash_state sha256;
- struct s2n_hash_state sha384;
- struct s2n_hash_state sha512;
- struct s2n_hash_state md5_sha1;
-
- /* A copy of the handshake messages hash used to validate the CertificateVerify message */
- struct s2n_hash_state ccv_hash_copy;
-
- /* Used for SSLv3, TLS 1.0, and TLS 1.1 PRFs */
- struct s2n_hash_state prf_md5_hash_copy;
- struct s2n_hash_state prf_sha1_hash_copy;
- /*Used for TLS 1.2 PRF */
- struct s2n_hash_state prf_tls12_hash_copy;
- struct s2n_hash_state server_finished_copy;
-
- /* Hash algorithms required for this handshake. The set of required hashes can be reduced as session parameters are
- * negotiated, i.e. cipher suite and protocol version.
- */
- uint8_t required_hash_algs[S2N_HASH_SENTINEL];
-
- uint8_t server_finished[S2N_TLS_SECRET_LEN];
- uint8_t client_finished[S2N_TLS_SECRET_LEN];
-
- /* Handshake type is a bitset, with the following
- bit positions */
- uint32_t handshake_type;
-
-/* Has the handshake been negotiated yet? */
-#define INITIAL 0x00
-#define NEGOTIATED 0x01
-#define IS_NEGOTIATED( type ) ( (type) & NEGOTIATED )
-
-/* Handshake is a full handshake */
-#define FULL_HANDSHAKE 0x02
-#define IS_FULL_HANDSHAKE( type ) ( (type) & FULL_HANDSHAKE )
-#define IS_RESUMPTION_HANDSHAKE( type ) ( !IS_FULL_HANDSHAKE( (type) ) && IS_NEGOTIATED ( (type) ) )
-
-/* Handshake uses perfect forward secrecy */
-#define TLS12_PERFECT_FORWARD_SECRECY 0x04
-
-/* Handshake needs OCSP status message */
-#define OCSP_STATUS 0x08
-#define IS_OCSP_STAPLED( type ) ( ( (type) & OCSP_STATUS ) != 0 )
-
-/* Handshake should request a Client Certificate */
-#define CLIENT_AUTH 0x10
-#define IS_CLIENT_AUTH_HANDSHAKE( type ) ( (type) & CLIENT_AUTH )
-
-/* Session Resumption via session-tickets */
-#define WITH_SESSION_TICKET 0x20
-#define IS_ISSUING_NEW_SESSION_TICKET( type ) ( (type) & WITH_SESSION_TICKET )
-
-/* Handshake requested a Client Certificate but did not get one */
-#define NO_CLIENT_CERT 0x40
-#define IS_CLIENT_AUTH_NO_CERT( type ) ( IS_CLIENT_AUTH_HANDSHAKE( (type) ) && ( (type) & NO_CLIENT_CERT) )
-
-/* A HelloRetryRequest was needed to proceed with the handshake */
-#define HELLO_RETRY_REQUEST 0x80
-
-/* Disguise a TLS1.3 handshake as a TLS1.2 handshake for backwards compatibility
- * with some middleboxes: https://tools.ietf.org/html/rfc8446#appendix-D.4 */
-#define MIDDLEBOX_COMPAT 0x100
-#define IS_MIDDLEBOX_COMPAT_MODE( type ) ( (type) & MIDDLEBOX_COMPAT )
-
- /* Which handshake message number are we processing */
- int message_number;
-
- /* State of the async pkey operation during handshake */
- s2n_async_state async_state;
-
- /* Indicates the CLIENT_HELLO message has been completely received */
- unsigned client_hello_received:1;
-
- /* Indicates the handshake blocked while trying to read or write data, and has been paused */
- unsigned paused:1;
-
- /* Set to 1 if the RSA verification failed */
- unsigned rsa_failed:1;
-};
-
-extern message_type_t s2n_conn_get_current_message_type(struct s2n_connection *conn);
-extern int s2n_conn_set_handshake_type(struct s2n_connection *conn);
-extern int s2n_conn_set_handshake_no_client_cert(struct s2n_connection *conn);
-extern int s2n_conn_set_handshake_read_block(struct s2n_connection *conn);
-extern int s2n_conn_clear_handshake_read_block(struct s2n_connection *conn);
-extern int s2n_handshake_require_all_hashes(struct s2n_handshake *handshake);
-extern uint8_t s2n_handshake_is_hash_required(struct s2n_handshake *handshake, s2n_hash_algorithm hash_alg);
-extern int s2n_conn_update_required_handshake_hashes(struct s2n_connection *conn);
-extern int s2n_handshake_get_hash_state(struct s2n_connection *conn, s2n_hash_algorithm hash_alg, struct s2n_hash_state *hash_state);
-extern int s2n_handshake_reset_hash_state(struct s2n_connection *conn, s2n_hash_algorithm hash_alg);
-extern int s2n_conn_find_name_matching_certs(struct s2n_connection *conn);
-extern int s2n_create_wildcard_hostname(struct s2n_stuffer *hostname, struct s2n_stuffer *output);
-struct s2n_cert_chain_and_key *s2n_get_compatible_cert_chain_and_key(struct s2n_connection *conn, const s2n_pkey_type cert_type);
-int s2n_conn_update_handshake_hashes(struct s2n_connection *conn, struct s2n_blob *data);
-S2N_RESULT s2n_quic_read_handshake_message(struct s2n_connection *conn, uint8_t *message_type);
-S2N_RESULT s2n_quic_write_handshake_message(struct s2n_connection *conn, struct s2n_blob *in);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <s2n.h>
+
+#include "tls/s2n_crypto.h"
+#include "tls/s2n_signature_algorithms.h"
+#include "tls/s2n_tls_parameters.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "crypto/s2n_certificate.h"
+#include "crypto/s2n_hash.h"
+
+/* From RFC 8446: https://tools.ietf.org/html/rfc8446#appendix-B.3 */
+#define TLS_HELLO_REQUEST 0
+#define TLS_CLIENT_HELLO 1
+#define TLS_SERVER_HELLO 2
+#define TLS_SERVER_NEW_SESSION_TICKET 4
+#define TLS_ENCRYPTED_EXTENSIONS 8
+#define TLS_CERTIFICATE 11
+#define TLS_SERVER_KEY 12
+#define TLS_CERT_REQ 13
+#define TLS_SERVER_HELLO_DONE 14
+#define TLS_CERT_VERIFY 15
+#define TLS_CLIENT_KEY 16
+#define TLS_FINISHED 20
+#define TLS_SERVER_CERT_STATUS 22
+#define TLS_SERVER_SESSION_LOOKUP 23
+#define TLS_KEY_UPDATE 24
+#define TLS_MESSAGE_HASH 254
+
+/* This is the list of message types that we support */
+typedef enum {
+ CLIENT_HELLO=0,
+ SERVER_HELLO,
+ SERVER_CERT,
+ SERVER_NEW_SESSION_TICKET,
+ SERVER_CERT_STATUS,
+ SERVER_KEY,
+ SERVER_CERT_REQ,
+ SERVER_HELLO_DONE,
+ CLIENT_CERT,
+ CLIENT_KEY,
+ CLIENT_CERT_VERIFY,
+ CLIENT_CHANGE_CIPHER_SPEC,
+ CLIENT_FINISHED,
+ SERVER_CHANGE_CIPHER_SPEC,
+ SERVER_FINISHED,
+
+ /* TLS1.3 message types. Defined: https://tools.ietf.org/html/rfc8446#appendix-B.3 */
+ ENCRYPTED_EXTENSIONS,
+ SERVER_CERT_VERIFY,
+ HELLO_RETRY_MSG,
+
+ APPLICATION_DATA,
+} message_type_t;
+
+typedef enum {
+ S2N_ASYNC_NOT_INVOKED = 0,
+ S2N_ASYNC_INVOKING_CALLBACK,
+ S2N_ASYNC_INVOKED_WAITING,
+ S2N_ASYNC_INVOKED_COMPLETE,
+} s2n_async_state;
+
+struct s2n_handshake_parameters {
+ /* Signature/hash algorithm pairs offered by the client in the signature_algorithms extension */
+ struct s2n_sig_scheme_list client_sig_hash_algs;
+
+ /* Signature/hash algorithm pairs offered by the server in the certificate request */
+ struct s2n_sig_scheme_list server_sig_hash_algs;
+
+ /* The cert chain we will send the peer. */
+ struct s2n_cert_chain_and_key *our_chain_and_key;
+
+ /* The subset of certificates that match the server_name presented in the ClientHello.
+ * In the case of multiple certificates matching a server_name, s2n will prefer certificates
+ * in FIFO order based on calls to s2n_config_add_cert_chain_and_key_to_store
+ *
+ * Note that in addition to domain matching, the key type for the certificate must also be
+ * suitable for a negotiation in order to be selected. The set of matching certs here are indexed
+ * by s2n_authentication_method.
+ *
+ * Example:
+ * - Assume certA is added to s2n_config via s2n_config_add_cert_chain_and_key_to_store
+ * - Next certB is added.
+ * - if certA matches www.foo.com and certB matches www.foo.com, s2n will prefer certA
+ *
+ * Note that in addition to domain matching, the key type for the certificate must also be
+ * suitable for a negotiation in order to be selected.
+ *
+ * Example:
+ * - Assume certA and certB match server_name www.foo.com
+ * - certA is ECDSA and certB is RSA.
+ * - Client only supports RSA ciphers
+ * - certB will be selected.
+ */
+ struct s2n_cert_chain_and_key *exact_sni_matches[S2N_CERT_TYPE_COUNT];
+ struct s2n_cert_chain_and_key *wc_sni_matches[S2N_CERT_TYPE_COUNT];
+ uint8_t exact_sni_match_exists;
+ uint8_t wc_sni_match_exists;
+};
+
+struct s2n_handshake {
+ struct s2n_stuffer io;
+
+ struct s2n_hash_state md5;
+ struct s2n_hash_state sha1;
+ struct s2n_hash_state sha224;
+ struct s2n_hash_state sha256;
+ struct s2n_hash_state sha384;
+ struct s2n_hash_state sha512;
+ struct s2n_hash_state md5_sha1;
+
+ /* A copy of the handshake messages hash used to validate the CertificateVerify message */
+ struct s2n_hash_state ccv_hash_copy;
+
+ /* Used for SSLv3, TLS 1.0, and TLS 1.1 PRFs */
+ struct s2n_hash_state prf_md5_hash_copy;
+ struct s2n_hash_state prf_sha1_hash_copy;
+ /*Used for TLS 1.2 PRF */
+ struct s2n_hash_state prf_tls12_hash_copy;
+ struct s2n_hash_state server_finished_copy;
+
+ /* Hash algorithms required for this handshake. The set of required hashes can be reduced as session parameters are
+ * negotiated, i.e. cipher suite and protocol version.
+ */
+ uint8_t required_hash_algs[S2N_HASH_SENTINEL];
+
+ uint8_t server_finished[S2N_TLS_SECRET_LEN];
+ uint8_t client_finished[S2N_TLS_SECRET_LEN];
+
+ /* Handshake type is a bitset, with the following
+ bit positions */
+ uint32_t handshake_type;
+
+/* Has the handshake been negotiated yet? */
+#define INITIAL 0x00
+#define NEGOTIATED 0x01
+#define IS_NEGOTIATED( type ) ( (type) & NEGOTIATED )
+
+/* Handshake is a full handshake */
+#define FULL_HANDSHAKE 0x02
+#define IS_FULL_HANDSHAKE( type ) ( (type) & FULL_HANDSHAKE )
+#define IS_RESUMPTION_HANDSHAKE( type ) ( !IS_FULL_HANDSHAKE( (type) ) && IS_NEGOTIATED ( (type) ) )
+
+/* Handshake uses perfect forward secrecy */
+#define TLS12_PERFECT_FORWARD_SECRECY 0x04
+
+/* Handshake needs OCSP status message */
+#define OCSP_STATUS 0x08
+#define IS_OCSP_STAPLED( type ) ( ( (type) & OCSP_STATUS ) != 0 )
+
+/* Handshake should request a Client Certificate */
+#define CLIENT_AUTH 0x10
+#define IS_CLIENT_AUTH_HANDSHAKE( type ) ( (type) & CLIENT_AUTH )
+
+/* Session Resumption via session-tickets */
+#define WITH_SESSION_TICKET 0x20
+#define IS_ISSUING_NEW_SESSION_TICKET( type ) ( (type) & WITH_SESSION_TICKET )
+
+/* Handshake requested a Client Certificate but did not get one */
+#define NO_CLIENT_CERT 0x40
+#define IS_CLIENT_AUTH_NO_CERT( type ) ( IS_CLIENT_AUTH_HANDSHAKE( (type) ) && ( (type) & NO_CLIENT_CERT) )
+
+/* A HelloRetryRequest was needed to proceed with the handshake */
+#define HELLO_RETRY_REQUEST 0x80
+
+/* Disguise a TLS1.3 handshake as a TLS1.2 handshake for backwards compatibility
+ * with some middleboxes: https://tools.ietf.org/html/rfc8446#appendix-D.4 */
+#define MIDDLEBOX_COMPAT 0x100
+#define IS_MIDDLEBOX_COMPAT_MODE( type ) ( (type) & MIDDLEBOX_COMPAT )
+
+ /* Which handshake message number are we processing */
+ int message_number;
+
+ /* State of the async pkey operation during handshake */
+ s2n_async_state async_state;
+
+ /* Indicates the CLIENT_HELLO message has been completely received */
+ unsigned client_hello_received:1;
+
+ /* Indicates the handshake blocked while trying to read or write data, and has been paused */
+ unsigned paused:1;
+
+ /* Set to 1 if the RSA verification failed */
+ unsigned rsa_failed:1;
+};
+
+extern message_type_t s2n_conn_get_current_message_type(struct s2n_connection *conn);
+extern int s2n_conn_set_handshake_type(struct s2n_connection *conn);
+extern int s2n_conn_set_handshake_no_client_cert(struct s2n_connection *conn);
+extern int s2n_conn_set_handshake_read_block(struct s2n_connection *conn);
+extern int s2n_conn_clear_handshake_read_block(struct s2n_connection *conn);
+extern int s2n_handshake_require_all_hashes(struct s2n_handshake *handshake);
+extern uint8_t s2n_handshake_is_hash_required(struct s2n_handshake *handshake, s2n_hash_algorithm hash_alg);
+extern int s2n_conn_update_required_handshake_hashes(struct s2n_connection *conn);
+extern int s2n_handshake_get_hash_state(struct s2n_connection *conn, s2n_hash_algorithm hash_alg, struct s2n_hash_state *hash_state);
+extern int s2n_handshake_reset_hash_state(struct s2n_connection *conn, s2n_hash_algorithm hash_alg);
+extern int s2n_conn_find_name_matching_certs(struct s2n_connection *conn);
+extern int s2n_create_wildcard_hostname(struct s2n_stuffer *hostname, struct s2n_stuffer *output);
+struct s2n_cert_chain_and_key *s2n_get_compatible_cert_chain_and_key(struct s2n_connection *conn, const s2n_pkey_type cert_type);
+int s2n_conn_update_handshake_hashes(struct s2n_connection *conn, struct s2n_blob *data);
+S2N_RESULT s2n_quic_read_handshake_message(struct s2n_connection *conn, uint8_t *message_type);
+S2N_RESULT s2n_quic_write_handshake_message(struct s2n_connection *conn, struct s2n_blob *in);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c b/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c
index 356bfa2201..ad53a33938 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c
@@ -1,1215 +1,1215 @@
-/*
- * 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 <sys/param.h>
-
-#include <errno.h>
-#include <s2n.h>
-
-#include "error/s2n_errno.h"
-
-#include "crypto/s2n_fips.h"
-
-#include "tls/s2n_async_pkey.h"
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_record.h"
-#include "tls/s2n_resume.h"
-#include "tls/s2n_alerts.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls13.h"
-#include "tls/s2n_tls13_handshake.h"
-#include "tls/s2n_kex.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_socket.h"
-#include "utils/s2n_random.h"
-#include "utils/s2n_str.h"
-
-/* clang-format off */
-struct s2n_handshake_action {
- uint8_t record_type;
- uint8_t message_type;
- char writer; /* 'S' or 'C' for server or client, 'B' for both */
- int (*handler[2]) (struct s2n_connection * conn);
-};
-
-static int s2n_always_fail_send(struct s2n_connection *conn)
-{
- /* This state should never be sending a handshake message. */
- S2N_ERROR(S2N_ERR_HANDSHAKE_UNREACHABLE);
-}
-
-static int s2n_always_fail_recv(struct s2n_connection *conn)
-{
- /* This state should never have an incoming handshake message. */
- S2N_ERROR(S2N_ERR_HANDSHAKE_UNREACHABLE);
-}
-
-/* Client and Server handlers for each message type we support.
- * See http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-7 for the list of handshake message types
- */
-static struct s2n_handshake_action state_machine[] = {
- /* message_type_t = {Record type Message type Writer S2N_SERVER S2N_CLIENT } */
- [CLIENT_HELLO] = {TLS_HANDSHAKE, TLS_CLIENT_HELLO, 'C', {s2n_establish_session, s2n_client_hello_send}},
- [SERVER_HELLO] = {TLS_HANDSHAKE, TLS_SERVER_HELLO, 'S', {s2n_server_hello_send, s2n_server_hello_recv}},
- [SERVER_NEW_SESSION_TICKET] = {TLS_HANDSHAKE, TLS_SERVER_NEW_SESSION_TICKET,'S', {s2n_server_nst_send, s2n_server_nst_recv}},
- [SERVER_CERT] = {TLS_HANDSHAKE, TLS_CERTIFICATE, 'S', {s2n_server_cert_send, s2n_server_cert_recv}},
- [SERVER_CERT_STATUS] = {TLS_HANDSHAKE, TLS_SERVER_CERT_STATUS, 'S', {s2n_server_status_send, s2n_server_status_recv}},
- [SERVER_KEY] = {TLS_HANDSHAKE, TLS_SERVER_KEY, 'S', {s2n_server_key_send, s2n_server_key_recv}},
- [SERVER_CERT_REQ] = {TLS_HANDSHAKE, TLS_CERT_REQ, 'S', {s2n_cert_req_send, s2n_cert_req_recv}},
- [SERVER_HELLO_DONE] = {TLS_HANDSHAKE, TLS_SERVER_HELLO_DONE, 'S', {s2n_server_done_send, s2n_server_done_recv}},
- [CLIENT_CERT] = {TLS_HANDSHAKE, TLS_CERTIFICATE, 'C', {s2n_client_cert_recv, s2n_client_cert_send}},
- [CLIENT_KEY] = {TLS_HANDSHAKE, TLS_CLIENT_KEY, 'C', {s2n_client_key_recv, s2n_client_key_send}},
- [CLIENT_CERT_VERIFY] = {TLS_HANDSHAKE, TLS_CERT_VERIFY, 'C', {s2n_client_cert_verify_recv, s2n_client_cert_verify_send}},
- [CLIENT_CHANGE_CIPHER_SPEC] = {TLS_CHANGE_CIPHER_SPEC, 0, 'C', {s2n_client_ccs_recv, s2n_ccs_send}},
- [CLIENT_FINISHED] = {TLS_HANDSHAKE, TLS_FINISHED, 'C', {s2n_client_finished_recv, s2n_client_finished_send}},
- [SERVER_CHANGE_CIPHER_SPEC] = {TLS_CHANGE_CIPHER_SPEC, 0, 'S', {s2n_ccs_send, s2n_server_ccs_recv}},
- [SERVER_FINISHED] = {TLS_HANDSHAKE, TLS_FINISHED, 'S', {s2n_server_finished_send, s2n_server_finished_recv}},
- [APPLICATION_DATA] = {TLS_APPLICATION_DATA, 0, 'B', {s2n_always_fail_send, s2n_always_fail_recv}}
-};
-
-/*
- * Client and Server handlers for TLS1.3.
- */
-static struct s2n_handshake_action tls13_state_machine[] = {
- /* message_type_t = {Record type, Message type, Writer, {Server handler, client handler} } */
- [CLIENT_HELLO] = {TLS_HANDSHAKE, TLS_CLIENT_HELLO, 'C', {s2n_establish_session, s2n_client_hello_send}},
- [SERVER_HELLO] = {TLS_HANDSHAKE, TLS_SERVER_HELLO, 'S', {s2n_server_hello_send, s2n_server_hello_recv}},
- [HELLO_RETRY_MSG] = {TLS_HANDSHAKE, TLS_SERVER_HELLO, 'S', {s2n_server_hello_retry_send, s2n_server_hello_retry_recv}},
- [ENCRYPTED_EXTENSIONS] = {TLS_HANDSHAKE, TLS_ENCRYPTED_EXTENSIONS, 'S', {s2n_encrypted_extensions_send, s2n_encrypted_extensions_recv}},
- [SERVER_CERT_REQ] = {TLS_HANDSHAKE, TLS_CERT_REQ, 'S', {s2n_tls13_cert_req_send, s2n_tls13_cert_req_recv}},
- [SERVER_CERT] = {TLS_HANDSHAKE, TLS_CERTIFICATE, 'S', {s2n_server_cert_send, s2n_server_cert_recv}},
- [SERVER_CERT_VERIFY] = {TLS_HANDSHAKE, TLS_CERT_VERIFY, 'S', {s2n_tls13_cert_verify_send, s2n_tls13_cert_verify_recv}},
- [SERVER_FINISHED] = {TLS_HANDSHAKE, TLS_FINISHED, 'S', {s2n_tls13_server_finished_send, s2n_tls13_server_finished_recv}},
-
- [CLIENT_CERT] = {TLS_HANDSHAKE, TLS_CERTIFICATE, 'C', {s2n_client_cert_recv, s2n_client_cert_send}},
- [CLIENT_CERT_VERIFY] = {TLS_HANDSHAKE, TLS_CERT_VERIFY, 'C', {s2n_tls13_cert_verify_recv, s2n_tls13_cert_verify_send}},
- [CLIENT_FINISHED] = {TLS_HANDSHAKE, TLS_FINISHED, 'C', {s2n_tls13_client_finished_recv, s2n_tls13_client_finished_send}},
-
- /* Not used by TLS1.3, except to maintain middlebox compatibility */
- [CLIENT_CHANGE_CIPHER_SPEC] = {TLS_CHANGE_CIPHER_SPEC, 0, 'C', {s2n_basic_ccs_recv, s2n_ccs_send}},
- [SERVER_CHANGE_CIPHER_SPEC] = {TLS_CHANGE_CIPHER_SPEC, 0, 'S', {s2n_ccs_send, s2n_basic_ccs_recv}},
-
- [APPLICATION_DATA] = {TLS_APPLICATION_DATA, 0, 'B', {s2n_always_fail_send, s2n_always_fail_recv}},
-};
-
-#define MESSAGE_NAME_ENTRY(msg) [msg] = #msg
-
-static const char *message_names[] = {
- MESSAGE_NAME_ENTRY(CLIENT_HELLO),
- MESSAGE_NAME_ENTRY(SERVER_HELLO),
- MESSAGE_NAME_ENTRY(ENCRYPTED_EXTENSIONS),
- MESSAGE_NAME_ENTRY(SERVER_NEW_SESSION_TICKET),
- MESSAGE_NAME_ENTRY(SERVER_CERT),
- MESSAGE_NAME_ENTRY(SERVER_CERT_STATUS),
- MESSAGE_NAME_ENTRY(SERVER_CERT_VERIFY),
- MESSAGE_NAME_ENTRY(SERVER_KEY),
- MESSAGE_NAME_ENTRY(SERVER_CERT_REQ),
- MESSAGE_NAME_ENTRY(SERVER_HELLO_DONE),
- MESSAGE_NAME_ENTRY(CLIENT_CERT),
- MESSAGE_NAME_ENTRY(CLIENT_KEY),
- MESSAGE_NAME_ENTRY(CLIENT_CERT_VERIFY),
- MESSAGE_NAME_ENTRY(CLIENT_CHANGE_CIPHER_SPEC),
- MESSAGE_NAME_ENTRY(CLIENT_FINISHED),
- MESSAGE_NAME_ENTRY(SERVER_CHANGE_CIPHER_SPEC),
- MESSAGE_NAME_ENTRY(SERVER_FINISHED),
- MESSAGE_NAME_ENTRY(HELLO_RETRY_MSG),
- MESSAGE_NAME_ENTRY(APPLICATION_DATA),
-};
-
-/* Maximum number of valid handshakes */
-#define S2N_HANDSHAKES_COUNT 512
-
-/* Maximum number of messages in a handshake */
-#define S2N_MAX_HANDSHAKE_LENGTH 32
-
-/* We support different ordering of TLS Handshake messages, depending on what is being negotiated. There's also a dummy "INITIAL" handshake
- * that everything starts out as until we know better.
- */
-
-static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] = {
- [INITIAL] = {
- CLIENT_HELLO,
- SERVER_HELLO
- },
-
- [NEGOTIATED] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | WITH_SESSION_TICKET ] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- APPLICATION_DATA},
-
- [NEGOTIATED | FULL_HANDSHAKE ] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_HELLO_DONE,
- CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | WITH_SESSION_TICKET ] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_HELLO_DONE,
- CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY ] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_HELLO_DONE,
- CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | WITH_SESSION_TICKET ] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_HELLO_DONE,
- CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS ] ={
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_HELLO_DONE,
- CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | WITH_SESSION_TICKET ] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_HELLO_DONE,
- CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS ] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_HELLO_DONE,
- CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | WITH_SESSION_TICKET ] ={
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_HELLO_DONE,
- CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
- CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT ] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
- CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | WITH_SESSION_TICKET] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
- CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET ] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
- CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
- CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | NO_CLIENT_CERT ] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
- CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | WITH_SESSION_TICKET] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
- CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET ] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
- CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
- CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT ] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
- CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | WITH_SESSION_TICKET] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
- CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET ] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
- CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH ] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
- CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT ] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
- CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | WITH_SESSION_TICKET ] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
- CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET ] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
- CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
- APPLICATION_DATA
- },
-};
-
-/*
- * This selection of handshakes resembles the standard set, but with changes made to support tls1.3.
- *
- * These are just the basic handshakes. At the moment hello retries, session resumption, and early data are not supported.
- *
- * The CHANGE_CIPHER_SPEC messages are included only for middlebox compatibility.
- * See https://tools.ietf.org/html/rfc8446#appendix-D.4
- */
-static message_type_t tls13_handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] = {
- [INITIAL] = {
- CLIENT_HELLO,
- SERVER_HELLO
- },
-
- [INITIAL | HELLO_RETRY_REQUEST] = {
- CLIENT_HELLO,
- HELLO_RETRY_MSG
- },
-
- [NEGOTIATED | FULL_HANDSHAKE] = {
- CLIENT_HELLO,
- SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
- CLIENT_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | MIDDLEBOX_COMPAT] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
- CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST] = {
- CLIENT_HELLO,
- HELLO_RETRY_MSG,
- CLIENT_HELLO,
- SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
- CLIENT_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | MIDDLEBOX_COMPAT] = {
- CLIENT_HELLO,
- HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
- CLIENT_CHANGE_CIPHER_SPEC, CLIENT_HELLO,
- SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
- CLIENT_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | CLIENT_AUTH] = {
- CLIENT_HELLO,
- HELLO_RETRY_MSG,
- CLIENT_HELLO,
- SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
- CLIENT_CERT, CLIENT_CERT_VERIFY, CLIENT_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | CLIENT_AUTH | MIDDLEBOX_COMPAT] = {
- CLIENT_HELLO,
- HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
- CLIENT_CHANGE_CIPHER_SPEC, CLIENT_HELLO,
- SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
- CLIENT_CERT, CLIENT_CERT_VERIFY, CLIENT_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | CLIENT_AUTH | NO_CLIENT_CERT] = {
- CLIENT_HELLO,
- HELLO_RETRY_MSG,
- CLIENT_HELLO,
- SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
- CLIENT_CERT, CLIENT_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | CLIENT_AUTH | NO_CLIENT_CERT | MIDDLEBOX_COMPAT] = {
- CLIENT_HELLO,
- HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
- CLIENT_CHANGE_CIPHER_SPEC, CLIENT_HELLO,
- SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
- CLIENT_CERT, CLIENT_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH] = {
- CLIENT_HELLO,
- SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
- CLIENT_CERT, CLIENT_CERT_VERIFY, CLIENT_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | MIDDLEBOX_COMPAT] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
- CLIENT_CHANGE_CIPHER_SPEC, CLIENT_CERT, CLIENT_CERT_VERIFY, CLIENT_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT] = {
- CLIENT_HELLO,
- SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
- CLIENT_CERT, CLIENT_FINISHED,
- APPLICATION_DATA
- },
-
- [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT | MIDDLEBOX_COMPAT] = {
- CLIENT_HELLO,
- SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
- CLIENT_CHANGE_CIPHER_SPEC, CLIENT_CERT, CLIENT_FINISHED,
- APPLICATION_DATA
- },
-};
-/* clang-format on */
-
-#define MAX_HANDSHAKE_TYPE_LEN 152
-static char handshake_type_str[S2N_HANDSHAKES_COUNT][MAX_HANDSHAKE_TYPE_LEN] = {0};
-
-static const char* handshake_type_names[] = {
- "NEGOTIATED|",
- "FULL_HANDSHAKE|",
- "TLS12_PERFECT_FORWARD_SECRECY|",
- "OCSP_STATUS|",
- "CLIENT_AUTH|",
- "WITH_SESSION_TICKET|",
- "NO_CLIENT_CERT|",
- "HELLO_RETRY_REQUEST|",
- "MIDDLEBOX_COMPAT|",
-};
-
-#define IS_TLS13_HANDSHAKE( conn ) ((conn)->actual_protocol_version == S2N_TLS13)
-
-#define ACTIVE_STATE_MACHINE( conn ) (IS_TLS13_HANDSHAKE(conn) ? tls13_state_machine : state_machine)
-#define ACTIVE_HANDSHAKES( conn ) (IS_TLS13_HANDSHAKE(conn) ? tls13_handshakes : handshakes)
-
-#define ACTIVE_MESSAGE( conn ) ACTIVE_HANDSHAKES(conn)[ (conn)->handshake.handshake_type ][ (conn)->handshake.message_number ]
-
-#define ACTIVE_STATE( conn ) ACTIVE_STATE_MACHINE(conn)[ ACTIVE_MESSAGE( (conn) ) ]
-#define CCS_STATE( conn ) (((conn)->mode == S2N_CLIENT) ? ACTIVE_STATE_MACHINE(conn)[SERVER_CHANGE_CIPHER_SPEC] \
- : ACTIVE_STATE_MACHINE(conn)[CLIENT_CHANGE_CIPHER_SPEC] )
-
-#define EXPECTED_RECORD_TYPE( conn ) ACTIVE_STATE( conn ).record_type
-#define EXPECTED_MESSAGE_TYPE( conn ) ACTIVE_STATE( conn ).message_type
-
-#define CONNECTION_WRITER( conn ) (conn->mode == S2N_CLIENT ? 'C' : 'S')
-#define CONNECTION_IS_WRITER( conn ) (ACTIVE_STATE(conn).writer == CONNECTION_WRITER(conn))
-
-/* Used in our test cases */
-message_type_t s2n_conn_get_current_message_type(struct s2n_connection *conn)
-{
- return ACTIVE_MESSAGE(conn);
-}
-
-static int s2n_advance_message(struct s2n_connection *conn)
-{
- /* Get the mode: 'C'lient or 'S'erver */
- char previous_writer = ACTIVE_STATE(conn).writer;
- char this_mode = CONNECTION_WRITER(conn);
-
- /* Actually advance the message number */
- conn->handshake.message_number++;
-
- /* When reading and using TLS1.3, skip optional change_cipher_spec states. */
- if (ACTIVE_STATE(conn).writer != this_mode &&
- EXPECTED_RECORD_TYPE(conn) == TLS_CHANGE_CIPHER_SPEC &&
- IS_TLS13_HANDSHAKE(conn)) {
- conn->handshake.message_number++;
- }
-
- /* Set TCP_QUICKACK to avoid artificial delay during the handshake */
- GUARD(s2n_socket_quickack(conn));
-
- /* If optimized io hasn't been enabled or if the caller started out with a corked socket,
- * we don't mess with it
- */
- if (!conn->corked_io || s2n_socket_was_corked(conn)) {
- return 0;
- }
-
- /* Are we changing I/O directions */
- if (ACTIVE_STATE(conn).writer == previous_writer || ACTIVE_STATE(conn).writer == 'A') {
- return 0;
- }
-
- /* We're the new writer */
- if (ACTIVE_STATE(conn).writer == this_mode) {
- if (s2n_connection_is_managed_corked(conn)) {
- /* Set TCP_CORK/NOPUSH */
- GUARD(s2n_socket_write_cork(conn));
- }
-
- return 0;
- }
-
- /* We're the new reader, or we reached the "B" writer stage indicating that
- we're at the application data stage - uncork the data */
- if (s2n_connection_is_managed_corked(conn)) {
- GUARD(s2n_socket_write_uncork(conn));
- }
-
- return 0;
-}
-
-int s2n_generate_new_client_session_id(struct s2n_connection *conn)
-{
- if (conn->mode == S2N_SERVER) {
- struct s2n_blob session_id = { .data = conn->session_id, .size = S2N_TLS_SESSION_ID_MAX_LEN };
-
- /* Generate a new session id */
- GUARD_AS_POSIX(s2n_get_public_random_data(&session_id));
- conn->session_id_len = S2N_TLS_SESSION_ID_MAX_LEN;
- }
-
- return 0;
-}
-
-/* Lets the server flag whether a HelloRetryRequest is needed while processing extensions */
-int s2n_set_hello_retry_required(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- ENSURE_POSIX(conn->actual_protocol_version >= S2N_TLS13, S2N_ERR_INVALID_HELLO_RETRY);
- conn->handshake.handshake_type |= HELLO_RETRY_REQUEST;
-
- return S2N_SUCCESS;
-}
-
-bool s2n_is_hello_retry_message(struct s2n_connection *conn)
-{
- return (ACTIVE_MESSAGE(conn) == HELLO_RETRY_MSG);
-}
-
-bool s2n_is_hello_retry_handshake(struct s2n_connection *conn)
-{
- return conn->handshake.handshake_type & HELLO_RETRY_REQUEST;
-}
-
-int s2n_conn_set_handshake_type(struct s2n_connection *conn)
-{
- if (conn->handshake.handshake_type & HELLO_RETRY_REQUEST) {
- ENSURE_POSIX(conn->actual_protocol_version >= S2N_TLS13, S2N_ERR_INVALID_HELLO_RETRY);
- conn->handshake.handshake_type = HELLO_RETRY_REQUEST;
- } else {
- conn->handshake.handshake_type = INITIAL;
- }
-
- /* A handshake type has been negotiated */
- conn->handshake.handshake_type |= NEGOTIATED;
-
- s2n_cert_auth_type client_cert_auth_type;
- GUARD(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
-
- if (conn->mode == S2N_CLIENT && client_cert_auth_type == S2N_CERT_AUTH_REQUIRED) {
- /* If we're a client, and Client Auth is REQUIRED, then the Client must expect the CLIENT_CERT_REQ Message */
- conn->handshake.handshake_type |= CLIENT_AUTH;
- } else if (conn->mode == S2N_SERVER && client_cert_auth_type != S2N_CERT_AUTH_NONE) {
- /* If we're a server, and Client Auth is REQUIRED or OPTIONAL, then the server must send the CLIENT_CERT_REQ Message*/
- conn->handshake.handshake_type |= CLIENT_AUTH;
- }
-
- if (IS_TLS13_HANDSHAKE(conn)) {
- /* Use middlebox compatibility mode for TLS1.3 by default.
- * For now, only disable it when QUIC support is enabled. */
- if (!conn->config->quic_enabled) {
- conn->handshake.handshake_type |= MIDDLEBOX_COMPAT;
- }
- conn->handshake.handshake_type |= FULL_HANDSHAKE;
-
- return 0;
- }
-
- if (conn->config->use_tickets) {
- if (conn->session_ticket_status == S2N_DECRYPT_TICKET) {
- if (!s2n_decrypt_session_ticket(conn)) {
- return 0;
- }
-
- if (s2n_config_is_encrypt_decrypt_key_available(conn->config) == 1) {
- conn->session_ticket_status = S2N_NEW_TICKET;
- conn->handshake.handshake_type |= WITH_SESSION_TICKET;
- }
-
- /* If a session ticket is presented by the client, then skip lookup in Session ID server cache */
- goto skip_cache_lookup;
- }
-
- if (conn->session_ticket_status == S2N_NEW_TICKET) {
- conn->handshake.handshake_type |= WITH_SESSION_TICKET;
- }
- }
-
- /* If a TLS session is resumed, the Server should respond in its ServerHello with the same SessionId the
- * Client sent in the ClientHello. */
- if (conn->actual_protocol_version <= S2N_TLS12 && conn->mode == S2N_SERVER && s2n_allowed_to_cache_connection(conn)) {
- int r = s2n_resume_from_cache(conn);
- if (r == S2N_SUCCESS || (r < 0 && S2N_ERROR_IS_BLOCKING(s2n_errno))) {
- return r;
- }
- }
-
-skip_cache_lookup:
- if (conn->mode == S2N_CLIENT && conn->client_session_resumed == 1) {
- return 0;
- }
-
- /* If we're doing full handshake, generate a new session id. */
- GUARD(s2n_generate_new_client_session_id(conn));
-
- /* If we get this far, it's a full handshake */
- conn->handshake.handshake_type |= FULL_HANDSHAKE;
-
- if (s2n_kex_is_ephemeral(conn->secure.cipher_suite->key_exchange_alg)) {
- conn->handshake.handshake_type |= TLS12_PERFECT_FORWARD_SECRECY;
- }
-
- if (s2n_server_can_send_ocsp(conn) || s2n_server_sent_ocsp(conn)) {
- conn->handshake.handshake_type |= OCSP_STATUS;
- }
-
- return 0;
-}
-
-int s2n_conn_set_handshake_no_client_cert(struct s2n_connection *conn)
-{
- s2n_cert_auth_type client_cert_auth_type;
- GUARD(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
- S2N_ERROR_IF(client_cert_auth_type != S2N_CERT_AUTH_OPTIONAL, S2N_ERR_BAD_MESSAGE);
-
- conn->handshake.handshake_type |= NO_CLIENT_CERT;
-
- return 0;
-}
-
-int s2n_conn_set_handshake_read_block(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- conn->handshake.paused = 1;
-
- return 0;
-}
-
-int s2n_conn_clear_handshake_read_block(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- conn->handshake.paused = 0;
-
- return 0;
-}
-
-const char *s2n_connection_get_last_message_name(struct s2n_connection *conn)
-{
- notnull_check_ptr(conn);
-
- return message_names[ACTIVE_MESSAGE(conn)];
-}
-
-const char *s2n_connection_get_handshake_type_name(struct s2n_connection *conn)
-{
- notnull_check_ptr(conn);
-
- int handshake_type = conn->handshake.handshake_type;
-
- if (handshake_type == INITIAL) {
- return "INITIAL";
- }
-
- if (handshake_type_str[handshake_type][0] != '\0') {
- return handshake_type_str[handshake_type];
- }
-
- /* Compute handshake_type_str[handshake_type] */
- char *p = handshake_type_str[handshake_type];
- char *end = p + sizeof(handshake_type_str[0]);
-
- for (int i = 0; i < s2n_array_len(handshake_type_names); ++i) {
- if (handshake_type & (1 << i)) {
- p = s2n_strcpy(p, end, handshake_type_names[i]);
- }
- }
-
- if (p != handshake_type_str[handshake_type] && '|' == *(p - 1)) {
- *(p - 1) = '\0';
- }
-
- return handshake_type_str[handshake_type];
-}
-
-/* Writing is relatively straight forward, simply write each message out as a record,
- * we may fragment a message across multiple records, but we never coalesce multiple
- * messages into single records.
- * Precondition: secure outbound I/O has already been flushed
- */
-static int s2n_handshake_write_io(struct s2n_connection *conn)
-{
- uint8_t record_type = EXPECTED_RECORD_TYPE(conn);
- s2n_blocked_status blocked = S2N_NOT_BLOCKED;
-
- /* Populate handshake.io with header/payload for the current state, once.
- * Check wiped instead of s2n_stuffer_data_available to differentiate between the initial call
- * to s2n_handshake_write_io and a repeated call after an EWOULDBLOCK.
- */
- if (s2n_stuffer_is_wiped(&conn->handshake.io)) {
- if (record_type == TLS_HANDSHAKE) {
- GUARD(s2n_handshake_write_header(&conn->handshake.io, ACTIVE_STATE(conn).message_type));
- }
- GUARD(ACTIVE_STATE(conn).handler[conn->mode] (conn));
- if (record_type == TLS_HANDSHAKE) {
- GUARD(s2n_handshake_finish_header(&conn->handshake.io));
- }
- }
-
- /* Write the handshake data to records in fragment sized chunks */
- struct s2n_blob out = {0};
- while (s2n_stuffer_data_available(&conn->handshake.io) > 0) {
- uint16_t max_payload_size = 0;
- GUARD_AS_POSIX(s2n_record_max_write_payload_size(conn, &max_payload_size));
- out.size = MIN(s2n_stuffer_data_available(&conn->handshake.io), max_payload_size);
-
- out.data = s2n_stuffer_raw_read(&conn->handshake.io, out.size);
- notnull_check(out.data);
-
- if (conn->config->quic_enabled) {
- GUARD_AS_POSIX(s2n_quic_write_handshake_message(conn, &out));
- } else {
- GUARD(s2n_record_write(conn, record_type, &out));
- }
-
- /* MD5 and SHA sum the handshake data too */
- if (record_type == TLS_HANDSHAKE) {
- GUARD(s2n_conn_update_handshake_hashes(conn, &out));
- }
-
- /* Actually send the record. We could block here. Assume the caller will call flush before coming back. */
- GUARD(s2n_flush(conn, &blocked));
- }
-
- /* We're done sending the last record, reset everything */
- GUARD(s2n_stuffer_wipe(&conn->out));
- GUARD(s2n_stuffer_wipe(&conn->handshake.io));
-
- /* Update the secrets, if necessary */
- GUARD(s2n_tls13_handle_secrets(conn));
-
- /* Advance the state machine */
- GUARD(s2n_advance_message(conn));
-
- return 0;
-}
-
-/*
- * Returns:
- * 1 - more data is needed to complete the handshake message.
- * 0 - we read the whole handshake message.
- * -1 - error processing the handshake message.
- */
-static int s2n_read_full_handshake_message(struct s2n_connection *conn, uint8_t *message_type)
-{
- uint32_t current_handshake_data = s2n_stuffer_data_available(&conn->handshake.io);
- if (current_handshake_data < TLS_HANDSHAKE_HEADER_LENGTH) {
- /* The message may be so badly fragmented that we don't even read the full header, take
- * what we can and then continue to the next record read iteration.
- */
- if (s2n_stuffer_data_available(&conn->in) < (TLS_HANDSHAKE_HEADER_LENGTH - current_handshake_data)) {
- GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, s2n_stuffer_data_available(&conn->in)));
- return 1;
- }
-
- /* Get the remainder of the header */
- GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, (TLS_HANDSHAKE_HEADER_LENGTH - current_handshake_data)));
- }
-
- uint32_t handshake_message_length;
- GUARD(s2n_handshake_parse_header(conn, message_type, &handshake_message_length));
-
- S2N_ERROR_IF(handshake_message_length > S2N_MAXIMUM_HANDSHAKE_MESSAGE_LENGTH, S2N_ERR_BAD_MESSAGE);
-
- uint32_t bytes_to_take = handshake_message_length - s2n_stuffer_data_available(&conn->handshake.io);
- bytes_to_take = MIN(bytes_to_take, s2n_stuffer_data_available(&conn->in));
-
- /* If the record is handshake data, add it to the handshake buffer */
- GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, bytes_to_take));
-
- /* If we have the whole handshake message, then success */
- if (s2n_stuffer_data_available(&conn->handshake.io) == handshake_message_length) {
- return 0;
- }
-
- /* We don't have the whole message, so we'll need to go again */
- GUARD(s2n_stuffer_reread(&conn->handshake.io));
-
- return 1;
-}
-
-static int s2n_handshake_conn_update_hashes(struct s2n_connection *conn)
-{
- uint8_t message_type;
- uint32_t handshake_message_length;
-
- GUARD(s2n_stuffer_reread(&conn->handshake.io));
- GUARD(s2n_handshake_parse_header(conn, &message_type, &handshake_message_length));
-
- struct s2n_blob handshake_record = {0};
- handshake_record.data = conn->handshake.io.blob.data;
- handshake_record.size = TLS_HANDSHAKE_HEADER_LENGTH + handshake_message_length;
- notnull_check(handshake_record.data);
-
- /* MD5 and SHA sum the handshake data too */
- GUARD(s2n_conn_update_handshake_hashes(conn, &handshake_record));
-
- return 0;
-}
-
-static int s2n_handshake_handle_sslv2(struct s2n_connection *conn)
-{
- S2N_ERROR_IF(ACTIVE_MESSAGE(conn) != CLIENT_HELLO, S2N_ERR_BAD_MESSAGE);
-
- /* Add the message to our handshake hashes */
- struct s2n_blob hashed = {.data = conn->header_in.blob.data + 2,.size = 3 };
- GUARD(s2n_conn_update_handshake_hashes(conn, &hashed));
-
- hashed.data = conn->in.blob.data;
- hashed.size = s2n_stuffer_data_available(&conn->in);
- GUARD(s2n_conn_update_handshake_hashes(conn, &hashed));
-
- /* Handle an SSLv2 client hello */
- GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, s2n_stuffer_data_available(&conn->in)));
- /* Set the client hello version */
- conn->client_hello_version = S2N_SSLv2;
- /* Execute the state machine handler */
- int r = ACTIVE_STATE(conn).handler[conn->mode](conn);
- GUARD(s2n_stuffer_wipe(&conn->handshake.io));
-
- /* We're done with the record, wipe it */
- GUARD(s2n_stuffer_wipe(&conn->header_in));
- GUARD(s2n_stuffer_wipe(&conn->in));
- if (r < 0) {
- /* Don't invoke blinding on some of the common errors */
- switch (s2n_errno) {
- case S2N_ERR_CANCELLED:
- case S2N_ERR_CIPHER_NOT_SUPPORTED:
- case S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED:
- conn->closed = 1;
- break;
- case S2N_ERR_IO_BLOCKED:
- case S2N_ERR_ASYNC_BLOCKED:
- /* A blocking condition is retryable, so we should return without killing the connection. */
- S2N_ERROR_PRESERVE_ERRNO();
- break;
- default:
- GUARD(s2n_connection_kill(conn));
- }
-
- return r;
- }
-
- conn->in_status = ENCRYPTED;
-
- /* Advance the state machine */
- GUARD(s2n_advance_message(conn));
-
- return 0;
-}
-
-static int s2n_try_delete_session_cache(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- if (s2n_allowed_to_cache_connection(conn) > 0) {
- conn->config->cache_delete(conn, conn->config->cache_delete_data, conn->session_id, conn->session_id_len);
- }
-
- return 0;
-}
-
-/* Reading is a little more complicated than writing as the TLS RFCs allow content
- * types to be interleaved at the record layer. We may get an alert message
- * during the handshake phase, or messages of types that we don't support (e.g.
- * HEARTBEAT messages), or during renegotiations we may even get application
- * data messages that need to be handled by the application. The latter is punted
- * for now (s2n does not support renegotiations).
- */
-static int s2n_handshake_read_io(struct s2n_connection *conn)
-{
- uint8_t record_type;
- uint8_t message_type;
- int isSSLv2 = 0;
-
- /* Fill conn->in stuffer necessary for the handshake.
- * If using TCP, read a record. If using QUIC, read a message. */
- if (conn->config->quic_enabled) {
- record_type = TLS_HANDSHAKE;
- GUARD_AS_POSIX(s2n_quic_read_handshake_message(conn, &message_type));
- } else {
- GUARD(s2n_read_full_record(conn, &record_type, &isSSLv2));
- }
-
- if (isSSLv2) {
- S2N_ERROR_IF(record_type != SSLv2_CLIENT_HELLO, S2N_ERR_BAD_MESSAGE);
- GUARD(s2n_handshake_handle_sslv2(conn));
- }
-
- /* Now we have a record, but it could be a partial fragment of a message, or it might
- * contain several messages.
- */
- S2N_ERROR_IF(record_type == TLS_APPLICATION_DATA, S2N_ERR_BAD_MESSAGE);
- if (record_type == TLS_CHANGE_CIPHER_SPEC) {
- /* TLS1.3 can receive unexpected CCS messages at any point in the handshake
- * due to a peer operating in middlebox compatibility mode.
- * However, when operating in QUIC mode, S2N should not accept ANY CCS messages,
- * including these unexpected ones.*/
- if (!IS_TLS13_HANDSHAKE(conn) || conn->config->quic_enabled) {
- ENSURE_POSIX(EXPECTED_RECORD_TYPE(conn) == TLS_CHANGE_CIPHER_SPEC, S2N_ERR_BAD_MESSAGE);
- ENSURE_POSIX(!CONNECTION_IS_WRITER(conn), S2N_ERR_BAD_MESSAGE);
- }
-
- S2N_ERROR_IF(s2n_stuffer_data_available(&conn->in) != 1, S2N_ERR_BAD_MESSAGE);
-
- GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, s2n_stuffer_data_available(&conn->in)));
- GUARD(CCS_STATE(conn).handler[conn->mode] (conn));
- GUARD(s2n_stuffer_wipe(&conn->handshake.io));
-
- /* We're done with the record, wipe it */
- GUARD(s2n_stuffer_wipe(&conn->header_in));
- GUARD(s2n_stuffer_wipe(&conn->in));
- conn->in_status = ENCRYPTED;
-
- /* Advance the state machine if this was an expected message */
- if (EXPECTED_RECORD_TYPE(conn) == TLS_CHANGE_CIPHER_SPEC && !CONNECTION_IS_WRITER(conn)) {
- GUARD(s2n_advance_message(conn));
- }
-
- return 0;
- } else if (record_type != TLS_HANDSHAKE) {
- if (record_type == TLS_ALERT) {
- GUARD(s2n_process_alert_fragment(conn));
- }
-
- /* Ignore record types that we don't support */
-
- /* We're done with the record, wipe it */
- GUARD(s2n_stuffer_wipe(&conn->header_in));
- GUARD(s2n_stuffer_wipe(&conn->in));
- conn->in_status = ENCRYPTED;
- return 0;
- }
-
- /* Record is a handshake message */
- S2N_ERROR_IF(s2n_stuffer_data_available(&conn->in) == 0, S2N_ERR_BAD_MESSAGE);
-
- while (s2n_stuffer_data_available(&conn->in)) {
- /* We're done with negotiating but we have trailing data in this record. Bail on the handshake. */
- S2N_ERROR_IF(EXPECTED_RECORD_TYPE(conn) == TLS_APPLICATION_DATA, S2N_ERR_BAD_MESSAGE);
- int r;
- GUARD((r = s2n_read_full_handshake_message(conn, &message_type)));
-
- /* Do we need more data? This happens for message fragmentation */
- if (r == 1) {
- /* Break out of this inner loop, but since we're not changing the state, the
- * outer loop in s2n_handshake_io() will read another record.
- */
- GUARD(s2n_stuffer_wipe(&conn->header_in));
- GUARD(s2n_stuffer_wipe(&conn->in));
- conn->in_status = ENCRYPTED;
- return 0;
- }
-
- s2n_cert_auth_type client_cert_auth_type;
- GUARD(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
-
- /* If we're a Client, and received a ClientCertRequest message, and ClientAuth
- * is set to optional, then switch the State Machine that we're using to expect the ClientCertRequest. */
- if (conn->mode == S2N_CLIENT
- && client_cert_auth_type == S2N_CERT_AUTH_OPTIONAL
- && message_type == TLS_CERT_REQ) {
- conn->handshake.handshake_type |= CLIENT_AUTH;
- }
-
- /* According to rfc6066 section 8, server may choose not to send "CertificateStatus" message even if it has
- * sent "status_request" extension in the ServerHello message. */
- if (conn->mode == S2N_CLIENT
- && EXPECTED_MESSAGE_TYPE(conn) == TLS_SERVER_CERT_STATUS
- && message_type != TLS_SERVER_CERT_STATUS) {
- conn->handshake.handshake_type &= ~OCSP_STATUS;
- }
-
- ENSURE_POSIX(record_type == EXPECTED_RECORD_TYPE(conn), S2N_ERR_BAD_MESSAGE);
- ENSURE_POSIX(message_type == EXPECTED_MESSAGE_TYPE(conn), S2N_ERR_BAD_MESSAGE);
- ENSURE_POSIX(!CONNECTION_IS_WRITER(conn), S2N_ERR_BAD_MESSAGE);
-
- /* Call the relevant handler */
- r = ACTIVE_STATE(conn).handler[conn->mode] (conn);
-
- /* Don't update handshake hashes until after the handler has executed since some handlers need to read the
- * hash values before they are updated. */
- GUARD(s2n_handshake_conn_update_hashes(conn));
-
- GUARD(s2n_stuffer_wipe(&conn->handshake.io));
-
- if (r < 0) {
- /* Don't invoke blinding on some of the common errors */
- switch (s2n_errno) {
- case S2N_ERR_CANCELLED:
- case S2N_ERR_CIPHER_NOT_SUPPORTED:
- case S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED:
- conn->closed = 1;
- break;
- case S2N_ERR_IO_BLOCKED:
- case S2N_ERR_ASYNC_BLOCKED:
- /* A blocking condition is retryable, so we should return without killing the connection. */
- S2N_ERROR_PRESERVE_ERRNO();
- break;
- default:
- GUARD(s2n_connection_kill(conn));
- }
-
- return r;
- }
-
- /* Update the secrets, if necessary */
- GUARD(s2n_tls13_handle_secrets(conn));
-
- /* Advance the state machine */
- GUARD(s2n_advance_message(conn));
- }
-
- /* We're done with the record, wipe it */
- GUARD(s2n_stuffer_wipe(&conn->header_in));
- GUARD(s2n_stuffer_wipe(&conn->in));
- conn->in_status = ENCRYPTED;
-
- return 0;
-}
-
-static int s2n_handle_retry_state(struct s2n_connection *conn)
-{
- /* If we were blocked reading or writing a record, then the handler is waiting on
- * external data. The handler will know how to continue, so we should call the
- * handler right away. We aren't going to read more handshake data yet or proceed
- * to the next handler because the current message has not finished processing. */
- s2n_errno = S2N_ERR_OK;
- const int r = ACTIVE_STATE(conn).handler[conn->mode] (conn);
-
- if (r < 0 && S2N_ERROR_IS_BLOCKING(s2n_errno)) {
- /* If the handler is still waiting for data, return control to the caller. */
- S2N_ERROR_PRESERVE_ERRNO();
- }
-
- if (!CONNECTION_IS_WRITER(conn)) {
- /* We're done parsing the record, reset everything */
- GUARD(s2n_stuffer_wipe(&conn->header_in));
- GUARD(s2n_stuffer_wipe(&conn->in));
- conn->in_status = ENCRYPTED;
- }
-
- if (r < 0) {
- /* There is some other problem and we should kill the connection. */
- if (conn->session_id_len) {
- s2n_try_delete_session_cache(conn);
- }
-
- GUARD(s2n_connection_kill(conn));
- S2N_ERROR_PRESERVE_ERRNO();
- }
-
- if (CONNECTION_IS_WRITER(conn)) {
- /* If we're the writer and handler just finished, update the record header if
- * needed and let the s2n_handshake_write_io write the data to the socket */
- if (EXPECTED_RECORD_TYPE(conn) == TLS_HANDSHAKE) {
- GUARD(s2n_handshake_finish_header(&conn->handshake.io));
- }
- } else {
- /* The read handler processed the record successfully, we are done with this
- * record. Advance the state machine. */
- GUARD(s2n_advance_message(conn));
- }
-
- return 0;
-}
-
-int s2n_negotiate(struct s2n_connection *conn, s2n_blocked_status *blocked)
-{
- notnull_check(conn);
- notnull_check(blocked);
-
- while (ACTIVE_STATE(conn).writer != 'B') {
- errno = 0;
- s2n_errno = S2N_ERR_OK;
-
- /* Flush any pending I/O or alert messages */
- GUARD(s2n_flush(conn, blocked));
-
- /* If the handshake was paused, retry the current message */
- if (conn->handshake.paused) {
- *blocked = S2N_BLOCKED_ON_APPLICATION_INPUT;
- GUARD(s2n_handle_retry_state(conn));
- }
-
- if (CONNECTION_IS_WRITER(conn)) {
- *blocked = S2N_BLOCKED_ON_WRITE;
- const int write_result = s2n_handshake_write_io(conn);
-
- if (write_result < 0) {
- if (!S2N_ERROR_IS_BLOCKING(s2n_errno)) {
- /* Non-retryable write error. The peer might have sent an alert. Try and read it. */
- const int write_errno = errno;
- const int write_s2n_errno = s2n_errno;
- const char *write_s2n_debug_str = s2n_debug_str;
-
- if (s2n_handshake_read_io(conn) < 0 && s2n_errno == S2N_ERR_ALERT) {
- /* s2n_handshake_read_io has set s2n_errno */
- S2N_ERROR_PRESERVE_ERRNO();
- } else {
- /* Let the write error take precedence if we didn't read an alert. */
- errno = write_errno;
- s2n_errno = write_s2n_errno;
- s2n_debug_str = write_s2n_debug_str;
- S2N_ERROR_PRESERVE_ERRNO();
- }
- }
-
- if (s2n_errno == S2N_ERR_ASYNC_BLOCKED) {
- *blocked = S2N_BLOCKED_ON_APPLICATION_INPUT;
- }
-
- S2N_ERROR_PRESERVE_ERRNO();
- }
- } else {
- *blocked = S2N_BLOCKED_ON_READ;
- const int read_result = s2n_handshake_read_io(conn);
-
- if (read_result < 0) {
- /* One blocking condition is waiting on the session resumption cache. */
- /* So we don't want to delete anything if we are blocked. */
- if (!S2N_ERROR_IS_BLOCKING(s2n_errno) && conn->session_id_len) {
- s2n_try_delete_session_cache(conn);
- }
-
- if (s2n_errno == S2N_ERR_ASYNC_BLOCKED) {
- *blocked = S2N_BLOCKED_ON_APPLICATION_INPUT;
- }
-
- S2N_ERROR_PRESERVE_ERRNO();
- }
- }
-
- /* If the handshake has just ended, free up memory */
- if (ACTIVE_STATE(conn).writer == 'B') {
- GUARD(s2n_stuffer_resize(&conn->handshake.io, 0));
- }
- }
-
- *blocked = S2N_NOT_BLOCKED;
-
- return 0;
-}
+/*
+ * 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 <sys/param.h>
+
+#include <errno.h>
+#include <s2n.h>
+
+#include "error/s2n_errno.h"
+
+#include "crypto/s2n_fips.h"
+
+#include "tls/s2n_async_pkey.h"
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_record.h"
+#include "tls/s2n_resume.h"
+#include "tls/s2n_alerts.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls13.h"
+#include "tls/s2n_tls13_handshake.h"
+#include "tls/s2n_kex.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_socket.h"
+#include "utils/s2n_random.h"
+#include "utils/s2n_str.h"
+
+/* clang-format off */
+struct s2n_handshake_action {
+ uint8_t record_type;
+ uint8_t message_type;
+ char writer; /* 'S' or 'C' for server or client, 'B' for both */
+ int (*handler[2]) (struct s2n_connection * conn);
+};
+
+static int s2n_always_fail_send(struct s2n_connection *conn)
+{
+ /* This state should never be sending a handshake message. */
+ S2N_ERROR(S2N_ERR_HANDSHAKE_UNREACHABLE);
+}
+
+static int s2n_always_fail_recv(struct s2n_connection *conn)
+{
+ /* This state should never have an incoming handshake message. */
+ S2N_ERROR(S2N_ERR_HANDSHAKE_UNREACHABLE);
+}
+
+/* Client and Server handlers for each message type we support.
+ * See http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-7 for the list of handshake message types
+ */
+static struct s2n_handshake_action state_machine[] = {
+ /* message_type_t = {Record type Message type Writer S2N_SERVER S2N_CLIENT } */
+ [CLIENT_HELLO] = {TLS_HANDSHAKE, TLS_CLIENT_HELLO, 'C', {s2n_establish_session, s2n_client_hello_send}},
+ [SERVER_HELLO] = {TLS_HANDSHAKE, TLS_SERVER_HELLO, 'S', {s2n_server_hello_send, s2n_server_hello_recv}},
+ [SERVER_NEW_SESSION_TICKET] = {TLS_HANDSHAKE, TLS_SERVER_NEW_SESSION_TICKET,'S', {s2n_server_nst_send, s2n_server_nst_recv}},
+ [SERVER_CERT] = {TLS_HANDSHAKE, TLS_CERTIFICATE, 'S', {s2n_server_cert_send, s2n_server_cert_recv}},
+ [SERVER_CERT_STATUS] = {TLS_HANDSHAKE, TLS_SERVER_CERT_STATUS, 'S', {s2n_server_status_send, s2n_server_status_recv}},
+ [SERVER_KEY] = {TLS_HANDSHAKE, TLS_SERVER_KEY, 'S', {s2n_server_key_send, s2n_server_key_recv}},
+ [SERVER_CERT_REQ] = {TLS_HANDSHAKE, TLS_CERT_REQ, 'S', {s2n_cert_req_send, s2n_cert_req_recv}},
+ [SERVER_HELLO_DONE] = {TLS_HANDSHAKE, TLS_SERVER_HELLO_DONE, 'S', {s2n_server_done_send, s2n_server_done_recv}},
+ [CLIENT_CERT] = {TLS_HANDSHAKE, TLS_CERTIFICATE, 'C', {s2n_client_cert_recv, s2n_client_cert_send}},
+ [CLIENT_KEY] = {TLS_HANDSHAKE, TLS_CLIENT_KEY, 'C', {s2n_client_key_recv, s2n_client_key_send}},
+ [CLIENT_CERT_VERIFY] = {TLS_HANDSHAKE, TLS_CERT_VERIFY, 'C', {s2n_client_cert_verify_recv, s2n_client_cert_verify_send}},
+ [CLIENT_CHANGE_CIPHER_SPEC] = {TLS_CHANGE_CIPHER_SPEC, 0, 'C', {s2n_client_ccs_recv, s2n_ccs_send}},
+ [CLIENT_FINISHED] = {TLS_HANDSHAKE, TLS_FINISHED, 'C', {s2n_client_finished_recv, s2n_client_finished_send}},
+ [SERVER_CHANGE_CIPHER_SPEC] = {TLS_CHANGE_CIPHER_SPEC, 0, 'S', {s2n_ccs_send, s2n_server_ccs_recv}},
+ [SERVER_FINISHED] = {TLS_HANDSHAKE, TLS_FINISHED, 'S', {s2n_server_finished_send, s2n_server_finished_recv}},
+ [APPLICATION_DATA] = {TLS_APPLICATION_DATA, 0, 'B', {s2n_always_fail_send, s2n_always_fail_recv}}
+};
+
+/*
+ * Client and Server handlers for TLS1.3.
+ */
+static struct s2n_handshake_action tls13_state_machine[] = {
+ /* message_type_t = {Record type, Message type, Writer, {Server handler, client handler} } */
+ [CLIENT_HELLO] = {TLS_HANDSHAKE, TLS_CLIENT_HELLO, 'C', {s2n_establish_session, s2n_client_hello_send}},
+ [SERVER_HELLO] = {TLS_HANDSHAKE, TLS_SERVER_HELLO, 'S', {s2n_server_hello_send, s2n_server_hello_recv}},
+ [HELLO_RETRY_MSG] = {TLS_HANDSHAKE, TLS_SERVER_HELLO, 'S', {s2n_server_hello_retry_send, s2n_server_hello_retry_recv}},
+ [ENCRYPTED_EXTENSIONS] = {TLS_HANDSHAKE, TLS_ENCRYPTED_EXTENSIONS, 'S', {s2n_encrypted_extensions_send, s2n_encrypted_extensions_recv}},
+ [SERVER_CERT_REQ] = {TLS_HANDSHAKE, TLS_CERT_REQ, 'S', {s2n_tls13_cert_req_send, s2n_tls13_cert_req_recv}},
+ [SERVER_CERT] = {TLS_HANDSHAKE, TLS_CERTIFICATE, 'S', {s2n_server_cert_send, s2n_server_cert_recv}},
+ [SERVER_CERT_VERIFY] = {TLS_HANDSHAKE, TLS_CERT_VERIFY, 'S', {s2n_tls13_cert_verify_send, s2n_tls13_cert_verify_recv}},
+ [SERVER_FINISHED] = {TLS_HANDSHAKE, TLS_FINISHED, 'S', {s2n_tls13_server_finished_send, s2n_tls13_server_finished_recv}},
+
+ [CLIENT_CERT] = {TLS_HANDSHAKE, TLS_CERTIFICATE, 'C', {s2n_client_cert_recv, s2n_client_cert_send}},
+ [CLIENT_CERT_VERIFY] = {TLS_HANDSHAKE, TLS_CERT_VERIFY, 'C', {s2n_tls13_cert_verify_recv, s2n_tls13_cert_verify_send}},
+ [CLIENT_FINISHED] = {TLS_HANDSHAKE, TLS_FINISHED, 'C', {s2n_tls13_client_finished_recv, s2n_tls13_client_finished_send}},
+
+ /* Not used by TLS1.3, except to maintain middlebox compatibility */
+ [CLIENT_CHANGE_CIPHER_SPEC] = {TLS_CHANGE_CIPHER_SPEC, 0, 'C', {s2n_basic_ccs_recv, s2n_ccs_send}},
+ [SERVER_CHANGE_CIPHER_SPEC] = {TLS_CHANGE_CIPHER_SPEC, 0, 'S', {s2n_ccs_send, s2n_basic_ccs_recv}},
+
+ [APPLICATION_DATA] = {TLS_APPLICATION_DATA, 0, 'B', {s2n_always_fail_send, s2n_always_fail_recv}},
+};
+
+#define MESSAGE_NAME_ENTRY(msg) [msg] = #msg
+
+static const char *message_names[] = {
+ MESSAGE_NAME_ENTRY(CLIENT_HELLO),
+ MESSAGE_NAME_ENTRY(SERVER_HELLO),
+ MESSAGE_NAME_ENTRY(ENCRYPTED_EXTENSIONS),
+ MESSAGE_NAME_ENTRY(SERVER_NEW_SESSION_TICKET),
+ MESSAGE_NAME_ENTRY(SERVER_CERT),
+ MESSAGE_NAME_ENTRY(SERVER_CERT_STATUS),
+ MESSAGE_NAME_ENTRY(SERVER_CERT_VERIFY),
+ MESSAGE_NAME_ENTRY(SERVER_KEY),
+ MESSAGE_NAME_ENTRY(SERVER_CERT_REQ),
+ MESSAGE_NAME_ENTRY(SERVER_HELLO_DONE),
+ MESSAGE_NAME_ENTRY(CLIENT_CERT),
+ MESSAGE_NAME_ENTRY(CLIENT_KEY),
+ MESSAGE_NAME_ENTRY(CLIENT_CERT_VERIFY),
+ MESSAGE_NAME_ENTRY(CLIENT_CHANGE_CIPHER_SPEC),
+ MESSAGE_NAME_ENTRY(CLIENT_FINISHED),
+ MESSAGE_NAME_ENTRY(SERVER_CHANGE_CIPHER_SPEC),
+ MESSAGE_NAME_ENTRY(SERVER_FINISHED),
+ MESSAGE_NAME_ENTRY(HELLO_RETRY_MSG),
+ MESSAGE_NAME_ENTRY(APPLICATION_DATA),
+};
+
+/* Maximum number of valid handshakes */
+#define S2N_HANDSHAKES_COUNT 512
+
+/* Maximum number of messages in a handshake */
+#define S2N_MAX_HANDSHAKE_LENGTH 32
+
+/* We support different ordering of TLS Handshake messages, depending on what is being negotiated. There's also a dummy "INITIAL" handshake
+ * that everything starts out as until we know better.
+ */
+
+static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] = {
+ [INITIAL] = {
+ CLIENT_HELLO,
+ SERVER_HELLO
+ },
+
+ [NEGOTIATED] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | WITH_SESSION_TICKET ] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ APPLICATION_DATA},
+
+ [NEGOTIATED | FULL_HANDSHAKE ] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_HELLO_DONE,
+ CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | WITH_SESSION_TICKET ] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_HELLO_DONE,
+ CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY ] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_HELLO_DONE,
+ CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | WITH_SESSION_TICKET ] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_HELLO_DONE,
+ CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS ] ={
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_HELLO_DONE,
+ CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | WITH_SESSION_TICKET ] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_HELLO_DONE,
+ CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS ] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_HELLO_DONE,
+ CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | WITH_SESSION_TICKET ] ={
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_HELLO_DONE,
+ CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
+ CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT ] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
+ CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | WITH_SESSION_TICKET] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
+ CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET ] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
+ CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
+ CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | NO_CLIENT_CERT ] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
+ CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | WITH_SESSION_TICKET] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
+ CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET ] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
+ CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
+ CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT ] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
+ CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | WITH_SESSION_TICKET] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
+ CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET ] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
+ CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH ] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
+ CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT ] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
+ CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | WITH_SESSION_TICKET ] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
+ CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET ] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
+ CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
+ APPLICATION_DATA
+ },
+};
+
+/*
+ * This selection of handshakes resembles the standard set, but with changes made to support tls1.3.
+ *
+ * These are just the basic handshakes. At the moment hello retries, session resumption, and early data are not supported.
+ *
+ * The CHANGE_CIPHER_SPEC messages are included only for middlebox compatibility.
+ * See https://tools.ietf.org/html/rfc8446#appendix-D.4
+ */
+static message_type_t tls13_handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] = {
+ [INITIAL] = {
+ CLIENT_HELLO,
+ SERVER_HELLO
+ },
+
+ [INITIAL | HELLO_RETRY_REQUEST] = {
+ CLIENT_HELLO,
+ HELLO_RETRY_MSG
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
+ CLIENT_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | MIDDLEBOX_COMPAT] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
+ CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST] = {
+ CLIENT_HELLO,
+ HELLO_RETRY_MSG,
+ CLIENT_HELLO,
+ SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
+ CLIENT_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | MIDDLEBOX_COMPAT] = {
+ CLIENT_HELLO,
+ HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
+ CLIENT_CHANGE_CIPHER_SPEC, CLIENT_HELLO,
+ SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
+ CLIENT_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | CLIENT_AUTH] = {
+ CLIENT_HELLO,
+ HELLO_RETRY_MSG,
+ CLIENT_HELLO,
+ SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
+ CLIENT_CERT, CLIENT_CERT_VERIFY, CLIENT_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | CLIENT_AUTH | MIDDLEBOX_COMPAT] = {
+ CLIENT_HELLO,
+ HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
+ CLIENT_CHANGE_CIPHER_SPEC, CLIENT_HELLO,
+ SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
+ CLIENT_CERT, CLIENT_CERT_VERIFY, CLIENT_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | CLIENT_AUTH | NO_CLIENT_CERT] = {
+ CLIENT_HELLO,
+ HELLO_RETRY_MSG,
+ CLIENT_HELLO,
+ SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
+ CLIENT_CERT, CLIENT_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | CLIENT_AUTH | NO_CLIENT_CERT | MIDDLEBOX_COMPAT] = {
+ CLIENT_HELLO,
+ HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
+ CLIENT_CHANGE_CIPHER_SPEC, CLIENT_HELLO,
+ SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
+ CLIENT_CERT, CLIENT_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
+ CLIENT_CERT, CLIENT_CERT_VERIFY, CLIENT_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | MIDDLEBOX_COMPAT] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
+ CLIENT_CHANGE_CIPHER_SPEC, CLIENT_CERT, CLIENT_CERT_VERIFY, CLIENT_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
+ CLIENT_CERT, CLIENT_FINISHED,
+ APPLICATION_DATA
+ },
+
+ [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT | MIDDLEBOX_COMPAT] = {
+ CLIENT_HELLO,
+ SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
+ CLIENT_CHANGE_CIPHER_SPEC, CLIENT_CERT, CLIENT_FINISHED,
+ APPLICATION_DATA
+ },
+};
+/* clang-format on */
+
+#define MAX_HANDSHAKE_TYPE_LEN 152
+static char handshake_type_str[S2N_HANDSHAKES_COUNT][MAX_HANDSHAKE_TYPE_LEN] = {0};
+
+static const char* handshake_type_names[] = {
+ "NEGOTIATED|",
+ "FULL_HANDSHAKE|",
+ "TLS12_PERFECT_FORWARD_SECRECY|",
+ "OCSP_STATUS|",
+ "CLIENT_AUTH|",
+ "WITH_SESSION_TICKET|",
+ "NO_CLIENT_CERT|",
+ "HELLO_RETRY_REQUEST|",
+ "MIDDLEBOX_COMPAT|",
+};
+
+#define IS_TLS13_HANDSHAKE( conn ) ((conn)->actual_protocol_version == S2N_TLS13)
+
+#define ACTIVE_STATE_MACHINE( conn ) (IS_TLS13_HANDSHAKE(conn) ? tls13_state_machine : state_machine)
+#define ACTIVE_HANDSHAKES( conn ) (IS_TLS13_HANDSHAKE(conn) ? tls13_handshakes : handshakes)
+
+#define ACTIVE_MESSAGE( conn ) ACTIVE_HANDSHAKES(conn)[ (conn)->handshake.handshake_type ][ (conn)->handshake.message_number ]
+
+#define ACTIVE_STATE( conn ) ACTIVE_STATE_MACHINE(conn)[ ACTIVE_MESSAGE( (conn) ) ]
+#define CCS_STATE( conn ) (((conn)->mode == S2N_CLIENT) ? ACTIVE_STATE_MACHINE(conn)[SERVER_CHANGE_CIPHER_SPEC] \
+ : ACTIVE_STATE_MACHINE(conn)[CLIENT_CHANGE_CIPHER_SPEC] )
+
+#define EXPECTED_RECORD_TYPE( conn ) ACTIVE_STATE( conn ).record_type
+#define EXPECTED_MESSAGE_TYPE( conn ) ACTIVE_STATE( conn ).message_type
+
+#define CONNECTION_WRITER( conn ) (conn->mode == S2N_CLIENT ? 'C' : 'S')
+#define CONNECTION_IS_WRITER( conn ) (ACTIVE_STATE(conn).writer == CONNECTION_WRITER(conn))
+
+/* Used in our test cases */
+message_type_t s2n_conn_get_current_message_type(struct s2n_connection *conn)
+{
+ return ACTIVE_MESSAGE(conn);
+}
+
+static int s2n_advance_message(struct s2n_connection *conn)
+{
+ /* Get the mode: 'C'lient or 'S'erver */
+ char previous_writer = ACTIVE_STATE(conn).writer;
+ char this_mode = CONNECTION_WRITER(conn);
+
+ /* Actually advance the message number */
+ conn->handshake.message_number++;
+
+ /* When reading and using TLS1.3, skip optional change_cipher_spec states. */
+ if (ACTIVE_STATE(conn).writer != this_mode &&
+ EXPECTED_RECORD_TYPE(conn) == TLS_CHANGE_CIPHER_SPEC &&
+ IS_TLS13_HANDSHAKE(conn)) {
+ conn->handshake.message_number++;
+ }
+
+ /* Set TCP_QUICKACK to avoid artificial delay during the handshake */
+ GUARD(s2n_socket_quickack(conn));
+
+ /* If optimized io hasn't been enabled or if the caller started out with a corked socket,
+ * we don't mess with it
+ */
+ if (!conn->corked_io || s2n_socket_was_corked(conn)) {
+ return 0;
+ }
+
+ /* Are we changing I/O directions */
+ if (ACTIVE_STATE(conn).writer == previous_writer || ACTIVE_STATE(conn).writer == 'A') {
+ return 0;
+ }
+
+ /* We're the new writer */
+ if (ACTIVE_STATE(conn).writer == this_mode) {
+ if (s2n_connection_is_managed_corked(conn)) {
+ /* Set TCP_CORK/NOPUSH */
+ GUARD(s2n_socket_write_cork(conn));
+ }
+
+ return 0;
+ }
+
+ /* We're the new reader, or we reached the "B" writer stage indicating that
+ we're at the application data stage - uncork the data */
+ if (s2n_connection_is_managed_corked(conn)) {
+ GUARD(s2n_socket_write_uncork(conn));
+ }
+
+ return 0;
+}
+
+int s2n_generate_new_client_session_id(struct s2n_connection *conn)
+{
+ if (conn->mode == S2N_SERVER) {
+ struct s2n_blob session_id = { .data = conn->session_id, .size = S2N_TLS_SESSION_ID_MAX_LEN };
+
+ /* Generate a new session id */
+ GUARD_AS_POSIX(s2n_get_public_random_data(&session_id));
+ conn->session_id_len = S2N_TLS_SESSION_ID_MAX_LEN;
+ }
+
+ return 0;
+}
+
+/* Lets the server flag whether a HelloRetryRequest is needed while processing extensions */
+int s2n_set_hello_retry_required(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ ENSURE_POSIX(conn->actual_protocol_version >= S2N_TLS13, S2N_ERR_INVALID_HELLO_RETRY);
+ conn->handshake.handshake_type |= HELLO_RETRY_REQUEST;
+
+ return S2N_SUCCESS;
+}
+
+bool s2n_is_hello_retry_message(struct s2n_connection *conn)
+{
+ return (ACTIVE_MESSAGE(conn) == HELLO_RETRY_MSG);
+}
+
+bool s2n_is_hello_retry_handshake(struct s2n_connection *conn)
+{
+ return conn->handshake.handshake_type & HELLO_RETRY_REQUEST;
+}
+
+int s2n_conn_set_handshake_type(struct s2n_connection *conn)
+{
+ if (conn->handshake.handshake_type & HELLO_RETRY_REQUEST) {
+ ENSURE_POSIX(conn->actual_protocol_version >= S2N_TLS13, S2N_ERR_INVALID_HELLO_RETRY);
+ conn->handshake.handshake_type = HELLO_RETRY_REQUEST;
+ } else {
+ conn->handshake.handshake_type = INITIAL;
+ }
+
+ /* A handshake type has been negotiated */
+ conn->handshake.handshake_type |= NEGOTIATED;
+
+ s2n_cert_auth_type client_cert_auth_type;
+ GUARD(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
+
+ if (conn->mode == S2N_CLIENT && client_cert_auth_type == S2N_CERT_AUTH_REQUIRED) {
+ /* If we're a client, and Client Auth is REQUIRED, then the Client must expect the CLIENT_CERT_REQ Message */
+ conn->handshake.handshake_type |= CLIENT_AUTH;
+ } else if (conn->mode == S2N_SERVER && client_cert_auth_type != S2N_CERT_AUTH_NONE) {
+ /* If we're a server, and Client Auth is REQUIRED or OPTIONAL, then the server must send the CLIENT_CERT_REQ Message*/
+ conn->handshake.handshake_type |= CLIENT_AUTH;
+ }
+
+ if (IS_TLS13_HANDSHAKE(conn)) {
+ /* Use middlebox compatibility mode for TLS1.3 by default.
+ * For now, only disable it when QUIC support is enabled. */
+ if (!conn->config->quic_enabled) {
+ conn->handshake.handshake_type |= MIDDLEBOX_COMPAT;
+ }
+ conn->handshake.handshake_type |= FULL_HANDSHAKE;
+
+ return 0;
+ }
+
+ if (conn->config->use_tickets) {
+ if (conn->session_ticket_status == S2N_DECRYPT_TICKET) {
+ if (!s2n_decrypt_session_ticket(conn)) {
+ return 0;
+ }
+
+ if (s2n_config_is_encrypt_decrypt_key_available(conn->config) == 1) {
+ conn->session_ticket_status = S2N_NEW_TICKET;
+ conn->handshake.handshake_type |= WITH_SESSION_TICKET;
+ }
+
+ /* If a session ticket is presented by the client, then skip lookup in Session ID server cache */
+ goto skip_cache_lookup;
+ }
+
+ if (conn->session_ticket_status == S2N_NEW_TICKET) {
+ conn->handshake.handshake_type |= WITH_SESSION_TICKET;
+ }
+ }
+
+ /* If a TLS session is resumed, the Server should respond in its ServerHello with the same SessionId the
+ * Client sent in the ClientHello. */
+ if (conn->actual_protocol_version <= S2N_TLS12 && conn->mode == S2N_SERVER && s2n_allowed_to_cache_connection(conn)) {
+ int r = s2n_resume_from_cache(conn);
+ if (r == S2N_SUCCESS || (r < 0 && S2N_ERROR_IS_BLOCKING(s2n_errno))) {
+ return r;
+ }
+ }
+
+skip_cache_lookup:
+ if (conn->mode == S2N_CLIENT && conn->client_session_resumed == 1) {
+ return 0;
+ }
+
+ /* If we're doing full handshake, generate a new session id. */
+ GUARD(s2n_generate_new_client_session_id(conn));
+
+ /* If we get this far, it's a full handshake */
+ conn->handshake.handshake_type |= FULL_HANDSHAKE;
+
+ if (s2n_kex_is_ephemeral(conn->secure.cipher_suite->key_exchange_alg)) {
+ conn->handshake.handshake_type |= TLS12_PERFECT_FORWARD_SECRECY;
+ }
+
+ if (s2n_server_can_send_ocsp(conn) || s2n_server_sent_ocsp(conn)) {
+ conn->handshake.handshake_type |= OCSP_STATUS;
+ }
+
+ return 0;
+}
+
+int s2n_conn_set_handshake_no_client_cert(struct s2n_connection *conn)
+{
+ s2n_cert_auth_type client_cert_auth_type;
+ GUARD(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
+ S2N_ERROR_IF(client_cert_auth_type != S2N_CERT_AUTH_OPTIONAL, S2N_ERR_BAD_MESSAGE);
+
+ conn->handshake.handshake_type |= NO_CLIENT_CERT;
+
+ return 0;
+}
+
+int s2n_conn_set_handshake_read_block(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ conn->handshake.paused = 1;
+
+ return 0;
+}
+
+int s2n_conn_clear_handshake_read_block(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ conn->handshake.paused = 0;
+
+ return 0;
+}
+
+const char *s2n_connection_get_last_message_name(struct s2n_connection *conn)
+{
+ notnull_check_ptr(conn);
+
+ return message_names[ACTIVE_MESSAGE(conn)];
+}
+
+const char *s2n_connection_get_handshake_type_name(struct s2n_connection *conn)
+{
+ notnull_check_ptr(conn);
+
+ int handshake_type = conn->handshake.handshake_type;
+
+ if (handshake_type == INITIAL) {
+ return "INITIAL";
+ }
+
+ if (handshake_type_str[handshake_type][0] != '\0') {
+ return handshake_type_str[handshake_type];
+ }
+
+ /* Compute handshake_type_str[handshake_type] */
+ char *p = handshake_type_str[handshake_type];
+ char *end = p + sizeof(handshake_type_str[0]);
+
+ for (int i = 0; i < s2n_array_len(handshake_type_names); ++i) {
+ if (handshake_type & (1 << i)) {
+ p = s2n_strcpy(p, end, handshake_type_names[i]);
+ }
+ }
+
+ if (p != handshake_type_str[handshake_type] && '|' == *(p - 1)) {
+ *(p - 1) = '\0';
+ }
+
+ return handshake_type_str[handshake_type];
+}
+
+/* Writing is relatively straight forward, simply write each message out as a record,
+ * we may fragment a message across multiple records, but we never coalesce multiple
+ * messages into single records.
+ * Precondition: secure outbound I/O has already been flushed
+ */
+static int s2n_handshake_write_io(struct s2n_connection *conn)
+{
+ uint8_t record_type = EXPECTED_RECORD_TYPE(conn);
+ s2n_blocked_status blocked = S2N_NOT_BLOCKED;
+
+ /* Populate handshake.io with header/payload for the current state, once.
+ * Check wiped instead of s2n_stuffer_data_available to differentiate between the initial call
+ * to s2n_handshake_write_io and a repeated call after an EWOULDBLOCK.
+ */
+ if (s2n_stuffer_is_wiped(&conn->handshake.io)) {
+ if (record_type == TLS_HANDSHAKE) {
+ GUARD(s2n_handshake_write_header(&conn->handshake.io, ACTIVE_STATE(conn).message_type));
+ }
+ GUARD(ACTIVE_STATE(conn).handler[conn->mode] (conn));
+ if (record_type == TLS_HANDSHAKE) {
+ GUARD(s2n_handshake_finish_header(&conn->handshake.io));
+ }
+ }
+
+ /* Write the handshake data to records in fragment sized chunks */
+ struct s2n_blob out = {0};
+ while (s2n_stuffer_data_available(&conn->handshake.io) > 0) {
+ uint16_t max_payload_size = 0;
+ GUARD_AS_POSIX(s2n_record_max_write_payload_size(conn, &max_payload_size));
+ out.size = MIN(s2n_stuffer_data_available(&conn->handshake.io), max_payload_size);
+
+ out.data = s2n_stuffer_raw_read(&conn->handshake.io, out.size);
+ notnull_check(out.data);
+
+ if (conn->config->quic_enabled) {
+ GUARD_AS_POSIX(s2n_quic_write_handshake_message(conn, &out));
+ } else {
+ GUARD(s2n_record_write(conn, record_type, &out));
+ }
+
+ /* MD5 and SHA sum the handshake data too */
+ if (record_type == TLS_HANDSHAKE) {
+ GUARD(s2n_conn_update_handshake_hashes(conn, &out));
+ }
+
+ /* Actually send the record. We could block here. Assume the caller will call flush before coming back. */
+ GUARD(s2n_flush(conn, &blocked));
+ }
+
+ /* We're done sending the last record, reset everything */
+ GUARD(s2n_stuffer_wipe(&conn->out));
+ GUARD(s2n_stuffer_wipe(&conn->handshake.io));
+
+ /* Update the secrets, if necessary */
+ GUARD(s2n_tls13_handle_secrets(conn));
+
+ /* Advance the state machine */
+ GUARD(s2n_advance_message(conn));
+
+ return 0;
+}
+
+/*
+ * Returns:
+ * 1 - more data is needed to complete the handshake message.
+ * 0 - we read the whole handshake message.
+ * -1 - error processing the handshake message.
+ */
+static int s2n_read_full_handshake_message(struct s2n_connection *conn, uint8_t *message_type)
+{
+ uint32_t current_handshake_data = s2n_stuffer_data_available(&conn->handshake.io);
+ if (current_handshake_data < TLS_HANDSHAKE_HEADER_LENGTH) {
+ /* The message may be so badly fragmented that we don't even read the full header, take
+ * what we can and then continue to the next record read iteration.
+ */
+ if (s2n_stuffer_data_available(&conn->in) < (TLS_HANDSHAKE_HEADER_LENGTH - current_handshake_data)) {
+ GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, s2n_stuffer_data_available(&conn->in)));
+ return 1;
+ }
+
+ /* Get the remainder of the header */
+ GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, (TLS_HANDSHAKE_HEADER_LENGTH - current_handshake_data)));
+ }
+
+ uint32_t handshake_message_length;
+ GUARD(s2n_handshake_parse_header(conn, message_type, &handshake_message_length));
+
+ S2N_ERROR_IF(handshake_message_length > S2N_MAXIMUM_HANDSHAKE_MESSAGE_LENGTH, S2N_ERR_BAD_MESSAGE);
+
+ uint32_t bytes_to_take = handshake_message_length - s2n_stuffer_data_available(&conn->handshake.io);
+ bytes_to_take = MIN(bytes_to_take, s2n_stuffer_data_available(&conn->in));
+
+ /* If the record is handshake data, add it to the handshake buffer */
+ GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, bytes_to_take));
+
+ /* If we have the whole handshake message, then success */
+ if (s2n_stuffer_data_available(&conn->handshake.io) == handshake_message_length) {
+ return 0;
+ }
+
+ /* We don't have the whole message, so we'll need to go again */
+ GUARD(s2n_stuffer_reread(&conn->handshake.io));
+
+ return 1;
+}
+
+static int s2n_handshake_conn_update_hashes(struct s2n_connection *conn)
+{
+ uint8_t message_type;
+ uint32_t handshake_message_length;
+
+ GUARD(s2n_stuffer_reread(&conn->handshake.io));
+ GUARD(s2n_handshake_parse_header(conn, &message_type, &handshake_message_length));
+
+ struct s2n_blob handshake_record = {0};
+ handshake_record.data = conn->handshake.io.blob.data;
+ handshake_record.size = TLS_HANDSHAKE_HEADER_LENGTH + handshake_message_length;
+ notnull_check(handshake_record.data);
+
+ /* MD5 and SHA sum the handshake data too */
+ GUARD(s2n_conn_update_handshake_hashes(conn, &handshake_record));
+
+ return 0;
+}
+
+static int s2n_handshake_handle_sslv2(struct s2n_connection *conn)
+{
+ S2N_ERROR_IF(ACTIVE_MESSAGE(conn) != CLIENT_HELLO, S2N_ERR_BAD_MESSAGE);
+
+ /* Add the message to our handshake hashes */
+ struct s2n_blob hashed = {.data = conn->header_in.blob.data + 2,.size = 3 };
+ GUARD(s2n_conn_update_handshake_hashes(conn, &hashed));
+
+ hashed.data = conn->in.blob.data;
+ hashed.size = s2n_stuffer_data_available(&conn->in);
+ GUARD(s2n_conn_update_handshake_hashes(conn, &hashed));
+
+ /* Handle an SSLv2 client hello */
+ GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, s2n_stuffer_data_available(&conn->in)));
+ /* Set the client hello version */
+ conn->client_hello_version = S2N_SSLv2;
+ /* Execute the state machine handler */
+ int r = ACTIVE_STATE(conn).handler[conn->mode](conn);
+ GUARD(s2n_stuffer_wipe(&conn->handshake.io));
+
+ /* We're done with the record, wipe it */
+ GUARD(s2n_stuffer_wipe(&conn->header_in));
+ GUARD(s2n_stuffer_wipe(&conn->in));
+ if (r < 0) {
+ /* Don't invoke blinding on some of the common errors */
+ switch (s2n_errno) {
+ case S2N_ERR_CANCELLED:
+ case S2N_ERR_CIPHER_NOT_SUPPORTED:
+ case S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED:
+ conn->closed = 1;
+ break;
+ case S2N_ERR_IO_BLOCKED:
+ case S2N_ERR_ASYNC_BLOCKED:
+ /* A blocking condition is retryable, so we should return without killing the connection. */
+ S2N_ERROR_PRESERVE_ERRNO();
+ break;
+ default:
+ GUARD(s2n_connection_kill(conn));
+ }
+
+ return r;
+ }
+
+ conn->in_status = ENCRYPTED;
+
+ /* Advance the state machine */
+ GUARD(s2n_advance_message(conn));
+
+ return 0;
+}
+
+static int s2n_try_delete_session_cache(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ if (s2n_allowed_to_cache_connection(conn) > 0) {
+ conn->config->cache_delete(conn, conn->config->cache_delete_data, conn->session_id, conn->session_id_len);
+ }
+
+ return 0;
+}
+
+/* Reading is a little more complicated than writing as the TLS RFCs allow content
+ * types to be interleaved at the record layer. We may get an alert message
+ * during the handshake phase, or messages of types that we don't support (e.g.
+ * HEARTBEAT messages), or during renegotiations we may even get application
+ * data messages that need to be handled by the application. The latter is punted
+ * for now (s2n does not support renegotiations).
+ */
+static int s2n_handshake_read_io(struct s2n_connection *conn)
+{
+ uint8_t record_type;
+ uint8_t message_type;
+ int isSSLv2 = 0;
+
+ /* Fill conn->in stuffer necessary for the handshake.
+ * If using TCP, read a record. If using QUIC, read a message. */
+ if (conn->config->quic_enabled) {
+ record_type = TLS_HANDSHAKE;
+ GUARD_AS_POSIX(s2n_quic_read_handshake_message(conn, &message_type));
+ } else {
+ GUARD(s2n_read_full_record(conn, &record_type, &isSSLv2));
+ }
+
+ if (isSSLv2) {
+ S2N_ERROR_IF(record_type != SSLv2_CLIENT_HELLO, S2N_ERR_BAD_MESSAGE);
+ GUARD(s2n_handshake_handle_sslv2(conn));
+ }
+
+ /* Now we have a record, but it could be a partial fragment of a message, or it might
+ * contain several messages.
+ */
+ S2N_ERROR_IF(record_type == TLS_APPLICATION_DATA, S2N_ERR_BAD_MESSAGE);
+ if (record_type == TLS_CHANGE_CIPHER_SPEC) {
+ /* TLS1.3 can receive unexpected CCS messages at any point in the handshake
+ * due to a peer operating in middlebox compatibility mode.
+ * However, when operating in QUIC mode, S2N should not accept ANY CCS messages,
+ * including these unexpected ones.*/
+ if (!IS_TLS13_HANDSHAKE(conn) || conn->config->quic_enabled) {
+ ENSURE_POSIX(EXPECTED_RECORD_TYPE(conn) == TLS_CHANGE_CIPHER_SPEC, S2N_ERR_BAD_MESSAGE);
+ ENSURE_POSIX(!CONNECTION_IS_WRITER(conn), S2N_ERR_BAD_MESSAGE);
+ }
+
+ S2N_ERROR_IF(s2n_stuffer_data_available(&conn->in) != 1, S2N_ERR_BAD_MESSAGE);
+
+ GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, s2n_stuffer_data_available(&conn->in)));
+ GUARD(CCS_STATE(conn).handler[conn->mode] (conn));
+ GUARD(s2n_stuffer_wipe(&conn->handshake.io));
+
+ /* We're done with the record, wipe it */
+ GUARD(s2n_stuffer_wipe(&conn->header_in));
+ GUARD(s2n_stuffer_wipe(&conn->in));
+ conn->in_status = ENCRYPTED;
+
+ /* Advance the state machine if this was an expected message */
+ if (EXPECTED_RECORD_TYPE(conn) == TLS_CHANGE_CIPHER_SPEC && !CONNECTION_IS_WRITER(conn)) {
+ GUARD(s2n_advance_message(conn));
+ }
+
+ return 0;
+ } else if (record_type != TLS_HANDSHAKE) {
+ if (record_type == TLS_ALERT) {
+ GUARD(s2n_process_alert_fragment(conn));
+ }
+
+ /* Ignore record types that we don't support */
+
+ /* We're done with the record, wipe it */
+ GUARD(s2n_stuffer_wipe(&conn->header_in));
+ GUARD(s2n_stuffer_wipe(&conn->in));
+ conn->in_status = ENCRYPTED;
+ return 0;
+ }
+
+ /* Record is a handshake message */
+ S2N_ERROR_IF(s2n_stuffer_data_available(&conn->in) == 0, S2N_ERR_BAD_MESSAGE);
+
+ while (s2n_stuffer_data_available(&conn->in)) {
+ /* We're done with negotiating but we have trailing data in this record. Bail on the handshake. */
+ S2N_ERROR_IF(EXPECTED_RECORD_TYPE(conn) == TLS_APPLICATION_DATA, S2N_ERR_BAD_MESSAGE);
+ int r;
+ GUARD((r = s2n_read_full_handshake_message(conn, &message_type)));
+
+ /* Do we need more data? This happens for message fragmentation */
+ if (r == 1) {
+ /* Break out of this inner loop, but since we're not changing the state, the
+ * outer loop in s2n_handshake_io() will read another record.
+ */
+ GUARD(s2n_stuffer_wipe(&conn->header_in));
+ GUARD(s2n_stuffer_wipe(&conn->in));
+ conn->in_status = ENCRYPTED;
+ return 0;
+ }
+
+ s2n_cert_auth_type client_cert_auth_type;
+ GUARD(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
+
+ /* If we're a Client, and received a ClientCertRequest message, and ClientAuth
+ * is set to optional, then switch the State Machine that we're using to expect the ClientCertRequest. */
+ if (conn->mode == S2N_CLIENT
+ && client_cert_auth_type == S2N_CERT_AUTH_OPTIONAL
+ && message_type == TLS_CERT_REQ) {
+ conn->handshake.handshake_type |= CLIENT_AUTH;
+ }
+
+ /* According to rfc6066 section 8, server may choose not to send "CertificateStatus" message even if it has
+ * sent "status_request" extension in the ServerHello message. */
+ if (conn->mode == S2N_CLIENT
+ && EXPECTED_MESSAGE_TYPE(conn) == TLS_SERVER_CERT_STATUS
+ && message_type != TLS_SERVER_CERT_STATUS) {
+ conn->handshake.handshake_type &= ~OCSP_STATUS;
+ }
+
+ ENSURE_POSIX(record_type == EXPECTED_RECORD_TYPE(conn), S2N_ERR_BAD_MESSAGE);
+ ENSURE_POSIX(message_type == EXPECTED_MESSAGE_TYPE(conn), S2N_ERR_BAD_MESSAGE);
+ ENSURE_POSIX(!CONNECTION_IS_WRITER(conn), S2N_ERR_BAD_MESSAGE);
+
+ /* Call the relevant handler */
+ r = ACTIVE_STATE(conn).handler[conn->mode] (conn);
+
+ /* Don't update handshake hashes until after the handler has executed since some handlers need to read the
+ * hash values before they are updated. */
+ GUARD(s2n_handshake_conn_update_hashes(conn));
+
+ GUARD(s2n_stuffer_wipe(&conn->handshake.io));
+
+ if (r < 0) {
+ /* Don't invoke blinding on some of the common errors */
+ switch (s2n_errno) {
+ case S2N_ERR_CANCELLED:
+ case S2N_ERR_CIPHER_NOT_SUPPORTED:
+ case S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED:
+ conn->closed = 1;
+ break;
+ case S2N_ERR_IO_BLOCKED:
+ case S2N_ERR_ASYNC_BLOCKED:
+ /* A blocking condition is retryable, so we should return without killing the connection. */
+ S2N_ERROR_PRESERVE_ERRNO();
+ break;
+ default:
+ GUARD(s2n_connection_kill(conn));
+ }
+
+ return r;
+ }
+
+ /* Update the secrets, if necessary */
+ GUARD(s2n_tls13_handle_secrets(conn));
+
+ /* Advance the state machine */
+ GUARD(s2n_advance_message(conn));
+ }
+
+ /* We're done with the record, wipe it */
+ GUARD(s2n_stuffer_wipe(&conn->header_in));
+ GUARD(s2n_stuffer_wipe(&conn->in));
+ conn->in_status = ENCRYPTED;
+
+ return 0;
+}
+
+static int s2n_handle_retry_state(struct s2n_connection *conn)
+{
+ /* If we were blocked reading or writing a record, then the handler is waiting on
+ * external data. The handler will know how to continue, so we should call the
+ * handler right away. We aren't going to read more handshake data yet or proceed
+ * to the next handler because the current message has not finished processing. */
+ s2n_errno = S2N_ERR_OK;
+ const int r = ACTIVE_STATE(conn).handler[conn->mode] (conn);
+
+ if (r < 0 && S2N_ERROR_IS_BLOCKING(s2n_errno)) {
+ /* If the handler is still waiting for data, return control to the caller. */
+ S2N_ERROR_PRESERVE_ERRNO();
+ }
+
+ if (!CONNECTION_IS_WRITER(conn)) {
+ /* We're done parsing the record, reset everything */
+ GUARD(s2n_stuffer_wipe(&conn->header_in));
+ GUARD(s2n_stuffer_wipe(&conn->in));
+ conn->in_status = ENCRYPTED;
+ }
+
+ if (r < 0) {
+ /* There is some other problem and we should kill the connection. */
+ if (conn->session_id_len) {
+ s2n_try_delete_session_cache(conn);
+ }
+
+ GUARD(s2n_connection_kill(conn));
+ S2N_ERROR_PRESERVE_ERRNO();
+ }
+
+ if (CONNECTION_IS_WRITER(conn)) {
+ /* If we're the writer and handler just finished, update the record header if
+ * needed and let the s2n_handshake_write_io write the data to the socket */
+ if (EXPECTED_RECORD_TYPE(conn) == TLS_HANDSHAKE) {
+ GUARD(s2n_handshake_finish_header(&conn->handshake.io));
+ }
+ } else {
+ /* The read handler processed the record successfully, we are done with this
+ * record. Advance the state machine. */
+ GUARD(s2n_advance_message(conn));
+ }
+
+ return 0;
+}
+
+int s2n_negotiate(struct s2n_connection *conn, s2n_blocked_status *blocked)
+{
+ notnull_check(conn);
+ notnull_check(blocked);
+
+ while (ACTIVE_STATE(conn).writer != 'B') {
+ errno = 0;
+ s2n_errno = S2N_ERR_OK;
+
+ /* Flush any pending I/O or alert messages */
+ GUARD(s2n_flush(conn, blocked));
+
+ /* If the handshake was paused, retry the current message */
+ if (conn->handshake.paused) {
+ *blocked = S2N_BLOCKED_ON_APPLICATION_INPUT;
+ GUARD(s2n_handle_retry_state(conn));
+ }
+
+ if (CONNECTION_IS_WRITER(conn)) {
+ *blocked = S2N_BLOCKED_ON_WRITE;
+ const int write_result = s2n_handshake_write_io(conn);
+
+ if (write_result < 0) {
+ if (!S2N_ERROR_IS_BLOCKING(s2n_errno)) {
+ /* Non-retryable write error. The peer might have sent an alert. Try and read it. */
+ const int write_errno = errno;
+ const int write_s2n_errno = s2n_errno;
+ const char *write_s2n_debug_str = s2n_debug_str;
+
+ if (s2n_handshake_read_io(conn) < 0 && s2n_errno == S2N_ERR_ALERT) {
+ /* s2n_handshake_read_io has set s2n_errno */
+ S2N_ERROR_PRESERVE_ERRNO();
+ } else {
+ /* Let the write error take precedence if we didn't read an alert. */
+ errno = write_errno;
+ s2n_errno = write_s2n_errno;
+ s2n_debug_str = write_s2n_debug_str;
+ S2N_ERROR_PRESERVE_ERRNO();
+ }
+ }
+
+ if (s2n_errno == S2N_ERR_ASYNC_BLOCKED) {
+ *blocked = S2N_BLOCKED_ON_APPLICATION_INPUT;
+ }
+
+ S2N_ERROR_PRESERVE_ERRNO();
+ }
+ } else {
+ *blocked = S2N_BLOCKED_ON_READ;
+ const int read_result = s2n_handshake_read_io(conn);
+
+ if (read_result < 0) {
+ /* One blocking condition is waiting on the session resumption cache. */
+ /* So we don't want to delete anything if we are blocked. */
+ if (!S2N_ERROR_IS_BLOCKING(s2n_errno) && conn->session_id_len) {
+ s2n_try_delete_session_cache(conn);
+ }
+
+ if (s2n_errno == S2N_ERR_ASYNC_BLOCKED) {
+ *blocked = S2N_BLOCKED_ON_APPLICATION_INPUT;
+ }
+
+ S2N_ERROR_PRESERVE_ERRNO();
+ }
+ }
+
+ /* If the handshake has just ended, free up memory */
+ if (ACTIVE_STATE(conn).writer == 'B') {
+ GUARD(s2n_stuffer_resize(&conn->handshake.io, 0));
+ }
+ }
+
+ *blocked = S2N_NOT_BLOCKED;
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_handshake_transcript.c b/contrib/restricted/aws/s2n/tls/s2n_handshake_transcript.c
index 7023d78e59..7c6c3dffb6 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_handshake_transcript.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_handshake_transcript.c
@@ -1,136 +1,136 @@
-/*
- * 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 "tls/s2n_connection.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls13_handshake.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_blob.h"
-
-/* Length of the synthetic message header */
-#define MESSAGE_HASH_HEADER_LENGTH 4
-
-static int s2n_tls13_conn_copy_server_finished_hash(struct s2n_connection *conn) {
- notnull_check(conn);
- s2n_tls13_connection_keys(keys, conn);
- struct s2n_hash_state hash_state = {0};
-
- GUARD(s2n_handshake_get_hash_state(conn, keys.hash_algorithm, &hash_state));
- GUARD(s2n_hash_copy(&conn->handshake.server_finished_copy, &hash_state));
-
- return 0;
-}
-
-int s2n_conn_update_handshake_hashes(struct s2n_connection *conn, struct s2n_blob *data)
-{
- notnull_check(conn);
- notnull_check(data);
-
- if (s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_MD5)) {
- /* The handshake MD5 hash state will fail the s2n_hash_is_available() check
- * since MD5 is not permitted in FIPS mode. This check will not be used as
- * the handshake MD5 hash state is specifically used by the TLS 1.0 and TLS 1.1
- * PRF, which is required to comply with the TLS 1.0 and 1.1 RFCs and is approved
- * as per NIST Special Publication 800-52 Revision 1.
- */
- GUARD(s2n_hash_update(&conn->handshake.md5, data->data, data->size));
- }
-
- if (s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_SHA1)) {
- GUARD(s2n_hash_update(&conn->handshake.sha1, data->data, data->size));
- }
-
- const uint8_t md5_sha1_required = (s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_MD5) &&
- s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_SHA1));
-
- if (md5_sha1_required) {
- /* The MD5_SHA1 hash can still be used for TLS 1.0 and 1.1 in FIPS mode for
- * the handshake hashes. This will only be used for the signature check in the
- * CertificateVerify message and the PRF. NIST SP 800-52r1 approves use
- * of MD5_SHA1 for these use cases (see footnotes 15 and 20, and section
- * 3.3.2) */
- GUARD(s2n_hash_update(&conn->handshake.md5_sha1, data->data, data->size));
- }
-
- if (s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_SHA224)) {
- GUARD(s2n_hash_update(&conn->handshake.sha224, data->data, data->size));
- }
-
- if (s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_SHA256)) {
- GUARD(s2n_hash_update(&conn->handshake.sha256, data->data, data->size));
- }
-
- if (s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_SHA384)) {
- GUARD(s2n_hash_update(&conn->handshake.sha384, data->data, data->size));
- }
-
- if (s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_SHA512)) {
- GUARD(s2n_hash_update(&conn->handshake.sha512, data->data, data->size));
- }
-
- /* Copy the CLIENT_HELLO -> SERVER_FINISHED hash.
- * TLS1.3 will need it later to calculate the application secrets. */
- if (s2n_connection_get_protocol_version(conn) >= S2N_TLS13 &&
- s2n_conn_get_current_message_type(conn) == SERVER_FINISHED) {
- GUARD(s2n_tls13_conn_copy_server_finished_hash(conn));
- }
-
- return 0;
-}
-
-/* When a HelloRetryRequest message is used, the hash transcript needs to be recreated.
- * This is done with a synthetic message header, and the hash of ClientHello1.
- *
- * https://tools.ietf.org/html/rfc8446#section-4.4.1
- */
-int s2n_server_hello_retry_recreate_transcript(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- s2n_tls13_connection_keys(keys, conn);
- uint8_t hash_digest_length = keys.size;
-
- /* Create the MessageHash (our synthetic message) */
- uint8_t msghdr[MESSAGE_HASH_HEADER_LENGTH] = {0};
- msghdr[0] = TLS_MESSAGE_HASH;
- msghdr[MESSAGE_HASH_HEADER_LENGTH - 1] = hash_digest_length;
-
- /* Grab the current transcript hash to use as the ClientHello1 value. */
- struct s2n_hash_state hash_state, client_hello1_hash;
- uint8_t client_hello1_digest_out[S2N_MAX_DIGEST_LEN];
- GUARD(s2n_handshake_get_hash_state(conn, keys.hash_algorithm, &hash_state));
-
- GUARD(s2n_hash_new(&client_hello1_hash));
- GUARD(s2n_hash_copy(&client_hello1_hash, &hash_state));
- GUARD(s2n_hash_digest(&client_hello1_hash, client_hello1_digest_out, hash_digest_length));
- GUARD(s2n_hash_free(&client_hello1_hash));
-
- /* Step 1: Reset the hash state */
- GUARD(s2n_handshake_reset_hash_state(conn, keys.hash_algorithm));
-
- /* Step 2: Update the transcript with the synthetic message */
- struct s2n_blob msg_blob = {0};
- GUARD(s2n_blob_init(&msg_blob, msghdr, MESSAGE_HASH_HEADER_LENGTH));
- GUARD(s2n_conn_update_handshake_hashes(conn, &msg_blob));
-
- /* Step 3: Update the transcript with the ClientHello1 hash */
- GUARD(s2n_blob_init(&msg_blob, client_hello1_digest_out, hash_digest_length));
- GUARD(s2n_conn_update_handshake_hashes(conn, &msg_blob));
-
- return 0;
-}
-
+/*
+ * 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 "tls/s2n_connection.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls13_handshake.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_blob.h"
+
+/* Length of the synthetic message header */
+#define MESSAGE_HASH_HEADER_LENGTH 4
+
+static int s2n_tls13_conn_copy_server_finished_hash(struct s2n_connection *conn) {
+ notnull_check(conn);
+ s2n_tls13_connection_keys(keys, conn);
+ struct s2n_hash_state hash_state = {0};
+
+ GUARD(s2n_handshake_get_hash_state(conn, keys.hash_algorithm, &hash_state));
+ GUARD(s2n_hash_copy(&conn->handshake.server_finished_copy, &hash_state));
+
+ return 0;
+}
+
+int s2n_conn_update_handshake_hashes(struct s2n_connection *conn, struct s2n_blob *data)
+{
+ notnull_check(conn);
+ notnull_check(data);
+
+ if (s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_MD5)) {
+ /* The handshake MD5 hash state will fail the s2n_hash_is_available() check
+ * since MD5 is not permitted in FIPS mode. This check will not be used as
+ * the handshake MD5 hash state is specifically used by the TLS 1.0 and TLS 1.1
+ * PRF, which is required to comply with the TLS 1.0 and 1.1 RFCs and is approved
+ * as per NIST Special Publication 800-52 Revision 1.
+ */
+ GUARD(s2n_hash_update(&conn->handshake.md5, data->data, data->size));
+ }
+
+ if (s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_SHA1)) {
+ GUARD(s2n_hash_update(&conn->handshake.sha1, data->data, data->size));
+ }
+
+ const uint8_t md5_sha1_required = (s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_MD5) &&
+ s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_SHA1));
+
+ if (md5_sha1_required) {
+ /* The MD5_SHA1 hash can still be used for TLS 1.0 and 1.1 in FIPS mode for
+ * the handshake hashes. This will only be used for the signature check in the
+ * CertificateVerify message and the PRF. NIST SP 800-52r1 approves use
+ * of MD5_SHA1 for these use cases (see footnotes 15 and 20, and section
+ * 3.3.2) */
+ GUARD(s2n_hash_update(&conn->handshake.md5_sha1, data->data, data->size));
+ }
+
+ if (s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_SHA224)) {
+ GUARD(s2n_hash_update(&conn->handshake.sha224, data->data, data->size));
+ }
+
+ if (s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_SHA256)) {
+ GUARD(s2n_hash_update(&conn->handshake.sha256, data->data, data->size));
+ }
+
+ if (s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_SHA384)) {
+ GUARD(s2n_hash_update(&conn->handshake.sha384, data->data, data->size));
+ }
+
+ if (s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_SHA512)) {
+ GUARD(s2n_hash_update(&conn->handshake.sha512, data->data, data->size));
+ }
+
+ /* Copy the CLIENT_HELLO -> SERVER_FINISHED hash.
+ * TLS1.3 will need it later to calculate the application secrets. */
+ if (s2n_connection_get_protocol_version(conn) >= S2N_TLS13 &&
+ s2n_conn_get_current_message_type(conn) == SERVER_FINISHED) {
+ GUARD(s2n_tls13_conn_copy_server_finished_hash(conn));
+ }
+
+ return 0;
+}
+
+/* When a HelloRetryRequest message is used, the hash transcript needs to be recreated.
+ * This is done with a synthetic message header, and the hash of ClientHello1.
+ *
+ * https://tools.ietf.org/html/rfc8446#section-4.4.1
+ */
+int s2n_server_hello_retry_recreate_transcript(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ s2n_tls13_connection_keys(keys, conn);
+ uint8_t hash_digest_length = keys.size;
+
+ /* Create the MessageHash (our synthetic message) */
+ uint8_t msghdr[MESSAGE_HASH_HEADER_LENGTH] = {0};
+ msghdr[0] = TLS_MESSAGE_HASH;
+ msghdr[MESSAGE_HASH_HEADER_LENGTH - 1] = hash_digest_length;
+
+ /* Grab the current transcript hash to use as the ClientHello1 value. */
+ struct s2n_hash_state hash_state, client_hello1_hash;
+ uint8_t client_hello1_digest_out[S2N_MAX_DIGEST_LEN];
+ GUARD(s2n_handshake_get_hash_state(conn, keys.hash_algorithm, &hash_state));
+
+ GUARD(s2n_hash_new(&client_hello1_hash));
+ GUARD(s2n_hash_copy(&client_hello1_hash, &hash_state));
+ GUARD(s2n_hash_digest(&client_hello1_hash, client_hello1_digest_out, hash_digest_length));
+ GUARD(s2n_hash_free(&client_hello1_hash));
+
+ /* Step 1: Reset the hash state */
+ GUARD(s2n_handshake_reset_hash_state(conn, keys.hash_algorithm));
+
+ /* Step 2: Update the transcript with the synthetic message */
+ struct s2n_blob msg_blob = {0};
+ GUARD(s2n_blob_init(&msg_blob, msghdr, MESSAGE_HASH_HEADER_LENGTH));
+ GUARD(s2n_conn_update_handshake_hashes(conn, &msg_blob));
+
+ /* Step 3: Update the transcript with the ClientHello1 hash */
+ GUARD(s2n_blob_init(&msg_blob, client_hello1_digest_out, hash_digest_length));
+ GUARD(s2n_conn_update_handshake_hashes(conn, &msg_blob));
+
+ return 0;
+}
+
diff --git a/contrib/restricted/aws/s2n/tls/s2n_kem.c b/contrib/restricted/aws/s2n/tls/s2n_kem.c
index e1b413cfe2..4ddbbc8683 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_kem.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_kem.c
@@ -1,509 +1,509 @@
-/*
- * 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 "stuffer/s2n_stuffer.h"
-#include "tls/s2n_tls_parameters.h"
-#include "tls/s2n_kem.h"
-#include "tls/extensions/s2n_key_share.h"
-#include "utils/s2n_mem.h"
-#include "utils/s2n_safety.h"
-#include "pq-crypto/s2n_pq.h"
-
-/* The KEM IDs and names come from https://tools.ietf.org/html/draft-campagna-tls-bike-sike-hybrid */
-const struct s2n_kem s2n_bike1_l1_r1 = {
- .name = "BIKE1r1-Level1",
- .kem_extension_id = TLS_PQ_KEM_EXTENSION_ID_BIKE1_L1_R1,
- .public_key_length = BIKE1_L1_R1_PUBLIC_KEY_BYTES,
- .private_key_length = BIKE1_L1_R1_SECRET_KEY_BYTES,
- .shared_secret_key_length = BIKE1_L1_R1_SHARED_SECRET_BYTES,
- .ciphertext_length = BIKE1_L1_R1_CIPHERTEXT_BYTES,
- .generate_keypair = &BIKE1_L1_R1_crypto_kem_keypair,
- .encapsulate = &BIKE1_L1_R1_crypto_kem_enc,
- .decapsulate = &BIKE1_L1_R1_crypto_kem_dec,
-};
-
-const struct s2n_kem s2n_bike1_l1_r2 = {
- .name = "BIKE1r2-Level1",
- .kem_extension_id = TLS_PQ_KEM_EXTENSION_ID_BIKE1_L1_R2,
- .public_key_length = BIKE1_L1_R2_PUBLIC_KEY_BYTES,
- .private_key_length = BIKE1_L1_R2_SECRET_KEY_BYTES,
- .shared_secret_key_length = BIKE1_L1_R2_SHARED_SECRET_BYTES,
- .ciphertext_length = BIKE1_L1_R2_CIPHERTEXT_BYTES,
- .generate_keypair = &BIKE1_L1_R2_crypto_kem_keypair,
- .encapsulate = &BIKE1_L1_R2_crypto_kem_enc,
- .decapsulate = &BIKE1_L1_R2_crypto_kem_dec,
-};
-
-const struct s2n_kem s2n_sike_p503_r1 = {
- .name = "SIKEp503r1-KEM",
- .kem_extension_id = TLS_PQ_KEM_EXTENSION_ID_SIKE_P503_R1,
- .public_key_length = SIKE_P503_R1_PUBLIC_KEY_BYTES,
- .private_key_length = SIKE_P503_R1_SECRET_KEY_BYTES,
- .shared_secret_key_length = SIKE_P503_R1_SHARED_SECRET_BYTES,
- .ciphertext_length = SIKE_P503_R1_CIPHERTEXT_BYTES,
- .generate_keypair = &SIKE_P503_r1_crypto_kem_keypair,
- .encapsulate = &SIKE_P503_r1_crypto_kem_enc,
- .decapsulate = &SIKE_P503_r1_crypto_kem_dec,
-};
-
-const struct s2n_kem s2n_sike_p434_r2 = {
- .name = "SIKEp434r2-KEM",
- .kem_extension_id = TLS_PQ_KEM_EXTENSION_ID_SIKE_P434_R2,
- .public_key_length = SIKE_P434_R2_PUBLIC_KEY_BYTES,
- .private_key_length = SIKE_P434_R2_SECRET_KEY_BYTES,
- .shared_secret_key_length = SIKE_P434_R2_SHARED_SECRET_BYTES,
- .ciphertext_length = SIKE_P434_R2_CIPHERTEXT_BYTES,
- .generate_keypair = &SIKE_P434_r2_crypto_kem_keypair,
- .encapsulate = &SIKE_P434_r2_crypto_kem_enc,
- .decapsulate = &SIKE_P434_r2_crypto_kem_dec,
-};
-
-const struct s2n_kem s2n_kyber_512_r2 = {
- .name = "kyber512r2",
- .kem_extension_id = TLS_PQ_KEM_EXTENSION_ID_KYBER_512_R2,
- .public_key_length = KYBER_512_R2_PUBLIC_KEY_BYTES,
- .private_key_length = KYBER_512_R2_SECRET_KEY_BYTES,
- .shared_secret_key_length = KYBER_512_R2_SHARED_SECRET_BYTES,
- .ciphertext_length = KYBER_512_R2_CIPHERTEXT_BYTES,
- .generate_keypair = &kyber_512_r2_crypto_kem_keypair,
- .encapsulate = &kyber_512_r2_crypto_kem_enc,
- .decapsulate = &kyber_512_r2_crypto_kem_dec,
-};
-
-const struct s2n_kem s2n_kyber_512_90s_r2 = {
- .name = "kyber51290sr2",
- .kem_extension_id = TLS_PQ_KEM_EXTENSION_ID_KYBER_512_90S_R2,
- .public_key_length = KYBER_512_R2_PUBLIC_KEY_BYTES,
- .private_key_length = KYBER_512_R2_SECRET_KEY_BYTES,
- .shared_secret_key_length = KYBER_512_R2_SHARED_SECRET_BYTES,
- .ciphertext_length = KYBER_512_R2_CIPHERTEXT_BYTES,
- .generate_keypair = &kyber_512_90s_r2_crypto_kem_keypair,
- .encapsulate = &kyber_512_90s_r2_crypto_kem_enc,
- .decapsulate = &kyber_512_90s_r2_crypto_kem_dec,
-};
-
-/* These lists should be kept up to date with the above KEMs. Order in the lists
- * does not matter. Adding a KEM to these lists will not automatically enable
- * support for the KEM extension - that must be added via the KEM preferences &
- * security policies. These lists are applicable only to PQ-TLS 1.2. */
-const struct s2n_kem *bike_kems[] = {
- &s2n_bike1_l1_r1,
- &s2n_bike1_l1_r2
-};
-
-const struct s2n_kem *sike_kems[] = {
- &s2n_sike_p503_r1,
- &s2n_sike_p434_r2,
-};
-
-const struct s2n_kem *kyber_kems[] = {
- &s2n_kyber_512_r2,
- &s2n_kyber_512_90s_r2,
-};
-
-const struct s2n_iana_to_kem kem_mapping[3] = {
- {
- .iana_value = { TLS_ECDHE_BIKE_RSA_WITH_AES_256_GCM_SHA384 },
- .kems = bike_kems,
- .kem_count = s2n_array_len(bike_kems),
- },
- {
- .iana_value = { TLS_ECDHE_SIKE_RSA_WITH_AES_256_GCM_SHA384 },
- .kems = sike_kems,
- .kem_count = s2n_array_len(sike_kems),
- },
- {
- .iana_value = { TLS_ECDHE_KYBER_RSA_WITH_AES_256_GCM_SHA384 },
- .kems = kyber_kems,
- .kem_count = s2n_array_len(kyber_kems),
- }
-};
-
-/* Specific assignments of KEM group IDs and names have not yet been
- * published in an RFC (or draft). There is consensus in the
- * community to use values in the proposed reserved range defined in
- * https://tools.ietf.org/html/draft-stebila-tls-hybrid-design.
- * Values for interoperability are defined in
- * https://docs.google.com/spreadsheets/d/12YarzaNv3XQNLnvDsWLlRKwtZFhRrDdWf36YlzwrPeg/edit#gid=0.
- *
- * The structure of the hybrid share is:
- * size of ECC key share (2 bytes)
- * || ECC key share (variable bytes)
- * || size of PQ key share (2 bytes)
- * || PQ key share (variable bytes) */
-const struct s2n_kem_group s2n_secp256r1_sike_p434_r2 = {
- .name = "secp256r1_sike-p434-r2",
- .iana_id = TLS_PQ_KEM_GROUP_ID_SECP256R1_SIKE_P434_R2,
- .client_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + SECP256R1_SHARE_SIZE) +
- (S2N_SIZE_OF_KEY_SHARE_SIZE + SIKE_P434_R2_PUBLIC_KEY_BYTES),
- .server_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + SECP256R1_SHARE_SIZE) +
- (S2N_SIZE_OF_KEY_SHARE_SIZE + SIKE_P434_R2_CIPHERTEXT_BYTES),
- .curve = &s2n_ecc_curve_secp256r1,
- .kem = &s2n_sike_p434_r2,
-};
-
-const struct s2n_kem_group s2n_secp256r1_bike1_l1_r2 = {
- /* The name string follows the convention in the above google doc */
- .name = "secp256r1_bike-1l1fo-r2",
- .iana_id = TLS_PQ_KEM_GROUP_ID_SECP256R1_BIKE1_L1_R2,
- .client_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + SECP256R1_SHARE_SIZE) +
- (S2N_SIZE_OF_KEY_SHARE_SIZE + BIKE1_L1_R2_PUBLIC_KEY_BYTES),
- .server_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + SECP256R1_SHARE_SIZE) +
- (S2N_SIZE_OF_KEY_SHARE_SIZE + BIKE1_L1_R2_CIPHERTEXT_BYTES),
- .curve = &s2n_ecc_curve_secp256r1,
- .kem = &s2n_bike1_l1_r2,
-};
-
-const struct s2n_kem_group s2n_secp256r1_kyber_512_r2 = {
- .name = "secp256r1_kyber-512-r2",
- .iana_id = TLS_PQ_KEM_GROUP_ID_SECP256R1_KYBER_512_R2,
- .client_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + SECP256R1_SHARE_SIZE) +
- (S2N_SIZE_OF_KEY_SHARE_SIZE + KYBER_512_R2_PUBLIC_KEY_BYTES),
- .server_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + SECP256R1_SHARE_SIZE) +
- (S2N_SIZE_OF_KEY_SHARE_SIZE + KYBER_512_R2_CIPHERTEXT_BYTES),
- .curve = &s2n_ecc_curve_secp256r1,
- .kem = &s2n_kyber_512_r2,
-};
-
-#if EVP_APIS_SUPPORTED
-const struct s2n_kem_group s2n_x25519_sike_p434_r2 = {
- .name = "x25519_sike-p434-r2",
- .iana_id = TLS_PQ_KEM_GROUP_ID_X25519_SIKE_P434_R2,
- .client_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + X25519_SHARE_SIZE) +
- (S2N_SIZE_OF_KEY_SHARE_SIZE + SIKE_P434_R2_PUBLIC_KEY_BYTES),
- .server_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + X25519_SHARE_SIZE) +
- (S2N_SIZE_OF_KEY_SHARE_SIZE + SIKE_P434_R2_CIPHERTEXT_BYTES),
- .curve = &s2n_ecc_curve_x25519,
- .kem = &s2n_sike_p434_r2,
-};
-
-const struct s2n_kem_group s2n_x25519_bike1_l1_r2 = {
- /* The name string follows the convention in the above google doc */
- .name = "x25519_bike-1l1fo-r2",
- .iana_id = TLS_PQ_KEM_GROUP_ID_X25519_BIKE1_L1_R2,
- .client_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + X25519_SHARE_SIZE) +
- (S2N_SIZE_OF_KEY_SHARE_SIZE + BIKE1_L1_R2_PUBLIC_KEY_BYTES),
- .server_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + X25519_SHARE_SIZE) +
- (S2N_SIZE_OF_KEY_SHARE_SIZE + BIKE1_L1_R2_CIPHERTEXT_BYTES),
- .curve = &s2n_ecc_curve_x25519,
- .kem = &s2n_bike1_l1_r2,
-};
-
-const struct s2n_kem_group s2n_x25519_kyber_512_r2 = {
- .name = "x25519_kyber-512-r2",
- .iana_id = TLS_PQ_KEM_GROUP_ID_X25519_KYBER_512_R2,
- .client_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + X25519_SHARE_SIZE) +
- (S2N_SIZE_OF_KEY_SHARE_SIZE + KYBER_512_R2_PUBLIC_KEY_BYTES),
- .server_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + X25519_SHARE_SIZE) +
- (S2N_SIZE_OF_KEY_SHARE_SIZE + KYBER_512_R2_CIPHERTEXT_BYTES),
- .curve = &s2n_ecc_curve_x25519,
- .kem = &s2n_kyber_512_r2,
-};
-#else
-const struct s2n_kem_group s2n_x25519_sike_p434_r2 = { 0 };
-const struct s2n_kem_group s2n_x25519_bike1_l1_r2 = { 0 };
-const struct s2n_kem_group s2n_x25519_kyber_512_r2 = { 0 };
-#endif
-
-/* Helper safety macro to call the NIST PQ KEM functions. The NIST
- * functions may return any non-zero value to indicate failure. */
-#define GUARD_PQ_AS_RESULT(x) ENSURE((x) == 0, S2N_ERR_PQ_CRYPTO)
-
-S2N_RESULT s2n_kem_generate_keypair(struct s2n_kem_params *kem_params)
-{
- ENSURE_REF(kem_params);
- ENSURE_REF(kem_params->kem);
- const struct s2n_kem *kem = kem_params->kem;
- ENSURE_REF(kem->generate_keypair);
-
- ENSURE_REF(kem_params->public_key.data);
- ENSURE(kem_params->public_key.size == kem->public_key_length, S2N_ERR_SAFETY);
-
- /* Need to save the private key for decapsulation */
- GUARD_AS_RESULT(s2n_alloc(&kem_params->private_key, kem->private_key_length));
-
- GUARD_PQ_AS_RESULT(kem->generate_keypair(kem_params->public_key.data, kem_params->private_key.data));
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_kem_encapsulate(struct s2n_kem_params *kem_params, struct s2n_blob *ciphertext)
-{
- ENSURE_REF(kem_params);
- ENSURE_REF(kem_params->kem);
- const struct s2n_kem *kem = kem_params->kem;
- ENSURE_REF(kem->encapsulate);
-
- ENSURE(kem_params->public_key.size == kem->public_key_length, S2N_ERR_SAFETY);
- ENSURE_REF(kem_params->public_key.data);
-
- ENSURE_REF(ciphertext);
- ENSURE_REF(ciphertext->data);
- ENSURE(ciphertext->size == kem->ciphertext_length, S2N_ERR_SAFETY);
-
- /* Need to save the shared secret for key derivation */
- GUARD_AS_RESULT(s2n_alloc(&(kem_params->shared_secret), kem->shared_secret_key_length));
-
- GUARD_PQ_AS_RESULT(kem->encapsulate(ciphertext->data, kem_params->shared_secret.data, kem_params->public_key.data));
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_kem_decapsulate(struct s2n_kem_params *kem_params, const struct s2n_blob *ciphertext)
-{
- ENSURE_REF(kem_params);
- ENSURE_REF(kem_params->kem);
- const struct s2n_kem *kem = kem_params->kem;
- ENSURE_REF(kem->decapsulate);
-
- ENSURE(kem_params->private_key.size == kem->private_key_length, S2N_ERR_SAFETY);
- ENSURE_REF(kem_params->private_key.data);
-
- ENSURE_REF(ciphertext);
- ENSURE_REF(ciphertext->data);
- ENSURE(ciphertext->size == kem->ciphertext_length, S2N_ERR_SAFETY);
-
- /* Need to save the shared secret for key derivation */
- GUARD_AS_RESULT(s2n_alloc(&(kem_params->shared_secret), kem->shared_secret_key_length));
-
- GUARD_PQ_AS_RESULT(kem->decapsulate(kem_params->shared_secret.data, ciphertext->data, kem_params->private_key.data));
- return S2N_RESULT_OK;
-}
-
-static int s2n_kem_check_kem_compatibility(const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN], const struct s2n_kem *candidate_kem,
- uint8_t *kem_is_compatible) {
- const struct s2n_iana_to_kem *compatible_kems = NULL;
- GUARD(s2n_cipher_suite_to_kem(iana_value, &compatible_kems));
-
- for (uint8_t i = 0; i < compatible_kems->kem_count; i++) {
- if (candidate_kem->kem_extension_id == compatible_kems->kems[i]->kem_extension_id) {
- *kem_is_compatible = 1;
- return S2N_SUCCESS;
- }
- }
-
- *kem_is_compatible = 0;
- return S2N_SUCCESS;
-}
-
-int s2n_choose_kem_with_peer_pref_list(const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN], struct s2n_blob *client_kem_ids,
- const struct s2n_kem *server_kem_pref_list[], const uint8_t num_server_supported_kems, const struct s2n_kem **chosen_kem) {
- struct s2n_stuffer client_kem_ids_stuffer = {0};
- GUARD(s2n_stuffer_init(&client_kem_ids_stuffer, client_kem_ids));
- GUARD(s2n_stuffer_write(&client_kem_ids_stuffer, client_kem_ids));
-
- /* Each KEM ID is 2 bytes */
- uint8_t num_client_candidate_kems = client_kem_ids->size / 2;
-
- for (uint8_t i = 0; i < num_server_supported_kems; i++) {
- const struct s2n_kem *candidate_server_kem = (server_kem_pref_list[i]);
-
- uint8_t server_kem_is_compatible = 0;
- GUARD(s2n_kem_check_kem_compatibility(iana_value, candidate_server_kem, &server_kem_is_compatible));
-
- if (!server_kem_is_compatible) {
- continue;
- }
-
- for (uint8_t j = 0; j < num_client_candidate_kems; j++) {
- kem_extension_size candidate_client_kem_id;
- GUARD(s2n_stuffer_read_uint16(&client_kem_ids_stuffer, &candidate_client_kem_id));
-
- if (candidate_server_kem->kem_extension_id == candidate_client_kem_id) {
- *chosen_kem = candidate_server_kem;
- return S2N_SUCCESS;
- }
- }
- GUARD(s2n_stuffer_reread(&client_kem_ids_stuffer));
- }
-
- /* Client and server did not propose any mutually supported KEMs compatible with the ciphersuite */
- S2N_ERROR(S2N_ERR_KEM_UNSUPPORTED_PARAMS);
-}
-
-int s2n_choose_kem_without_peer_pref_list(const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN], const struct s2n_kem *server_kem_pref_list[],
- const uint8_t num_server_supported_kems, const struct s2n_kem **chosen_kem) {
- for (uint8_t i = 0; i < num_server_supported_kems; i++) {
- uint8_t kem_is_compatible = 0;
- GUARD(s2n_kem_check_kem_compatibility(iana_value, server_kem_pref_list[i], &kem_is_compatible));
- if (kem_is_compatible) {
- *chosen_kem = server_kem_pref_list[i];
- return S2N_SUCCESS;
- }
- }
-
- /* The server preference list did not contain any KEM extensions compatible with the ciphersuite */
- S2N_ERROR(S2N_ERR_KEM_UNSUPPORTED_PARAMS);
-}
-
-int s2n_kem_free(struct s2n_kem_params *kem_params)
-{
- if (kem_params != NULL) {
- GUARD(s2n_blob_zeroize_free(&kem_params->private_key));
- GUARD(s2n_blob_zeroize_free(&kem_params->public_key));
- GUARD(s2n_blob_zeroize_free(&kem_params->shared_secret));
- }
- return S2N_SUCCESS;
-}
-
-int s2n_kem_group_free(struct s2n_kem_group_params *kem_group_params) {
- if (kem_group_params != NULL) {
- GUARD(s2n_kem_free(&kem_group_params->kem_params));
- GUARD(s2n_ecc_evp_params_free(&kem_group_params->ecc_params));
- }
- return S2N_SUCCESS;
-}
-
-int s2n_cipher_suite_to_kem(const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN], const struct s2n_iana_to_kem **compatible_params) {
- for (int i = 0; i < s2n_array_len(kem_mapping); i++) {
- const struct s2n_iana_to_kem *candidate = &kem_mapping[i];
- if (memcmp(iana_value, candidate->iana_value, S2N_TLS_CIPHER_SUITE_LEN) == 0) {
- *compatible_params = candidate;
- return S2N_SUCCESS;
- }
- }
- S2N_ERROR(S2N_ERR_KEM_UNSUPPORTED_PARAMS);
-}
-
-int s2n_get_kem_from_extension_id(kem_extension_size kem_id, const struct s2n_kem **kem) {
- for (int i = 0; i < s2n_array_len(kem_mapping); i++) {
- const struct s2n_iana_to_kem *iana_to_kem = &kem_mapping[i];
-
- for (int j = 0; j < iana_to_kem->kem_count; j++) {
- const struct s2n_kem *candidate_kem = iana_to_kem->kems[j];
- if (candidate_kem->kem_extension_id == kem_id) {
- *kem = candidate_kem;
- return S2N_SUCCESS;
- }
- }
- }
-
- S2N_ERROR(S2N_ERR_KEM_UNSUPPORTED_PARAMS);
-}
-
-int s2n_kem_send_public_key(struct s2n_stuffer *out, struct s2n_kem_params *kem_params) {
- notnull_check(out);
- notnull_check(kem_params);
- notnull_check(kem_params->kem);
-
- const struct s2n_kem *kem = kem_params->kem;
-
- GUARD(s2n_stuffer_write_uint16(out, kem->public_key_length));
-
- /* We don't need to store the public key after sending it.
- * We write it directly to *out. */
- kem_params->public_key.data = s2n_stuffer_raw_write(out, kem->public_key_length);
- notnull_check(kem_params->public_key.data);
- kem_params->public_key.size = kem->public_key_length;
-
- /* Saves the private key in kem_params */
- GUARD_AS_POSIX(s2n_kem_generate_keypair(kem_params));
-
- /* After using s2n_stuffer_raw_write() above to write the public
- * key to the stuffer, we want to ensure that kem_params->public_key.data
- * does not continue to point at *out, else we may unexpectedly
- * overwrite part of the stuffer when s2n_kem_free() is called. */
- kem_params->public_key.data = NULL;
- kem_params->public_key.size = 0;
-
- return S2N_SUCCESS;
-}
-
-int s2n_kem_recv_public_key(struct s2n_stuffer *in, struct s2n_kem_params *kem_params) {
- notnull_check(in);
- notnull_check(kem_params);
- notnull_check(kem_params->kem);
-
- const struct s2n_kem *kem = kem_params->kem;
- kem_public_key_size public_key_length;
-
- GUARD(s2n_stuffer_read_uint16(in, &public_key_length));
- S2N_ERROR_IF(public_key_length != kem->public_key_length, S2N_ERR_BAD_MESSAGE);
-
- /* Alloc memory for the public key; the peer receiving it will need it
- * later during the handshake to encapsulate the shared secret. */
- GUARD(s2n_alloc(&(kem_params->public_key), public_key_length));
- GUARD(s2n_stuffer_read_bytes(in, kem_params->public_key.data, public_key_length));
-
- return S2N_SUCCESS;
-}
-
-int s2n_kem_send_ciphertext(struct s2n_stuffer *out, struct s2n_kem_params *kem_params) {
- notnull_check(out);
- notnull_check(kem_params);
- notnull_check(kem_params->kem);
- notnull_check(kem_params->public_key.data);
-
- const struct s2n_kem *kem = kem_params->kem;
-
- GUARD(s2n_stuffer_write_uint16(out, kem->ciphertext_length));
-
- /* Ciphertext will get written to *out */
- struct s2n_blob ciphertext = {.data = s2n_stuffer_raw_write(out, kem->ciphertext_length), .size = kem->ciphertext_length};
- notnull_check(ciphertext.data);
-
- /* Saves the shared secret in kem_params */
- GUARD_AS_POSIX(s2n_kem_encapsulate(kem_params, &ciphertext));
-
- return S2N_SUCCESS;
-}
-
-int s2n_kem_recv_ciphertext(struct s2n_stuffer *in, struct s2n_kem_params *kem_params) {
- notnull_check(in);
- notnull_check(kem_params);
- notnull_check(kem_params->kem);
- notnull_check(kem_params->private_key.data);
-
- const struct s2n_kem *kem = kem_params->kem;
- kem_ciphertext_key_size ciphertext_length;
-
- GUARD(s2n_stuffer_read_uint16(in, &ciphertext_length));
- S2N_ERROR_IF(ciphertext_length != kem->ciphertext_length, S2N_ERR_BAD_MESSAGE);
-
- const struct s2n_blob ciphertext = {.data = s2n_stuffer_raw_read(in, ciphertext_length), .size = ciphertext_length};
- notnull_check(ciphertext.data);
-
- /* Saves the shared secret in kem_params */
- GUARD_AS_POSIX(s2n_kem_decapsulate(kem_params, &ciphertext));
-
- return S2N_SUCCESS;
-}
-
-#if defined(S2N_NO_PQ)
-/* IF S2N_NO_PQ was defined at compile time, the PQ KEM code will have been entirely excluded
- * from compilation. We define stubs of these functions here to error if they are called. */
-/* sikep503r1 */
-int SIKE_P503_r1_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
-int SIKE_P503_r1_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
-int SIKE_P503_r1_crypto_kem_dec(OUT unsigned char *ss, IN const unsigned char *ct, IN const unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
-/* sikep434r2 */
-int SIKE_P434_r2_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
-int SIKE_P434_r2_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
-int SIKE_P434_r2_crypto_kem_dec(OUT unsigned char *ss, IN const unsigned char *ct, IN const unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
-/* bike1l1r1 */
-int BIKE1_L1_R1_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
-int BIKE1_L1_R1_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
-int BIKE1_L1_R1_crypto_kem_dec(OUT unsigned char *ss, IN const unsigned char *ct, IN const unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
-/* bike1l1r2*/
-int BIKE1_L1_R2_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
-int BIKE1_L1_R2_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
-int BIKE1_L1_R2_crypto_kem_dec(OUT unsigned char * ss, IN const unsigned char *ct, IN const unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
-/* kyber512r2 */
-int kyber_512_r2_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
-int kyber_512_r2_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
-int kyber_512_r2_crypto_kem_dec(OUT unsigned char *ss, IN const unsigned char *ct, IN const unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
-/* kyber512r2 90's version*/
-int kyber_512_90s_r2_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
-int kyber_512_90s_r2_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
-int kyber_512_90s_r2_crypto_kem_dec(OUT unsigned char *ss, IN const unsigned char *ct, IN const unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
-#endif
+/*
+ * 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 "stuffer/s2n_stuffer.h"
+#include "tls/s2n_tls_parameters.h"
+#include "tls/s2n_kem.h"
+#include "tls/extensions/s2n_key_share.h"
+#include "utils/s2n_mem.h"
+#include "utils/s2n_safety.h"
+#include "pq-crypto/s2n_pq.h"
+
+/* The KEM IDs and names come from https://tools.ietf.org/html/draft-campagna-tls-bike-sike-hybrid */
+const struct s2n_kem s2n_bike1_l1_r1 = {
+ .name = "BIKE1r1-Level1",
+ .kem_extension_id = TLS_PQ_KEM_EXTENSION_ID_BIKE1_L1_R1,
+ .public_key_length = BIKE1_L1_R1_PUBLIC_KEY_BYTES,
+ .private_key_length = BIKE1_L1_R1_SECRET_KEY_BYTES,
+ .shared_secret_key_length = BIKE1_L1_R1_SHARED_SECRET_BYTES,
+ .ciphertext_length = BIKE1_L1_R1_CIPHERTEXT_BYTES,
+ .generate_keypair = &BIKE1_L1_R1_crypto_kem_keypair,
+ .encapsulate = &BIKE1_L1_R1_crypto_kem_enc,
+ .decapsulate = &BIKE1_L1_R1_crypto_kem_dec,
+};
+
+const struct s2n_kem s2n_bike1_l1_r2 = {
+ .name = "BIKE1r2-Level1",
+ .kem_extension_id = TLS_PQ_KEM_EXTENSION_ID_BIKE1_L1_R2,
+ .public_key_length = BIKE1_L1_R2_PUBLIC_KEY_BYTES,
+ .private_key_length = BIKE1_L1_R2_SECRET_KEY_BYTES,
+ .shared_secret_key_length = BIKE1_L1_R2_SHARED_SECRET_BYTES,
+ .ciphertext_length = BIKE1_L1_R2_CIPHERTEXT_BYTES,
+ .generate_keypair = &BIKE1_L1_R2_crypto_kem_keypair,
+ .encapsulate = &BIKE1_L1_R2_crypto_kem_enc,
+ .decapsulate = &BIKE1_L1_R2_crypto_kem_dec,
+};
+
+const struct s2n_kem s2n_sike_p503_r1 = {
+ .name = "SIKEp503r1-KEM",
+ .kem_extension_id = TLS_PQ_KEM_EXTENSION_ID_SIKE_P503_R1,
+ .public_key_length = SIKE_P503_R1_PUBLIC_KEY_BYTES,
+ .private_key_length = SIKE_P503_R1_SECRET_KEY_BYTES,
+ .shared_secret_key_length = SIKE_P503_R1_SHARED_SECRET_BYTES,
+ .ciphertext_length = SIKE_P503_R1_CIPHERTEXT_BYTES,
+ .generate_keypair = &SIKE_P503_r1_crypto_kem_keypair,
+ .encapsulate = &SIKE_P503_r1_crypto_kem_enc,
+ .decapsulate = &SIKE_P503_r1_crypto_kem_dec,
+};
+
+const struct s2n_kem s2n_sike_p434_r2 = {
+ .name = "SIKEp434r2-KEM",
+ .kem_extension_id = TLS_PQ_KEM_EXTENSION_ID_SIKE_P434_R2,
+ .public_key_length = SIKE_P434_R2_PUBLIC_KEY_BYTES,
+ .private_key_length = SIKE_P434_R2_SECRET_KEY_BYTES,
+ .shared_secret_key_length = SIKE_P434_R2_SHARED_SECRET_BYTES,
+ .ciphertext_length = SIKE_P434_R2_CIPHERTEXT_BYTES,
+ .generate_keypair = &SIKE_P434_r2_crypto_kem_keypair,
+ .encapsulate = &SIKE_P434_r2_crypto_kem_enc,
+ .decapsulate = &SIKE_P434_r2_crypto_kem_dec,
+};
+
+const struct s2n_kem s2n_kyber_512_r2 = {
+ .name = "kyber512r2",
+ .kem_extension_id = TLS_PQ_KEM_EXTENSION_ID_KYBER_512_R2,
+ .public_key_length = KYBER_512_R2_PUBLIC_KEY_BYTES,
+ .private_key_length = KYBER_512_R2_SECRET_KEY_BYTES,
+ .shared_secret_key_length = KYBER_512_R2_SHARED_SECRET_BYTES,
+ .ciphertext_length = KYBER_512_R2_CIPHERTEXT_BYTES,
+ .generate_keypair = &kyber_512_r2_crypto_kem_keypair,
+ .encapsulate = &kyber_512_r2_crypto_kem_enc,
+ .decapsulate = &kyber_512_r2_crypto_kem_dec,
+};
+
+const struct s2n_kem s2n_kyber_512_90s_r2 = {
+ .name = "kyber51290sr2",
+ .kem_extension_id = TLS_PQ_KEM_EXTENSION_ID_KYBER_512_90S_R2,
+ .public_key_length = KYBER_512_R2_PUBLIC_KEY_BYTES,
+ .private_key_length = KYBER_512_R2_SECRET_KEY_BYTES,
+ .shared_secret_key_length = KYBER_512_R2_SHARED_SECRET_BYTES,
+ .ciphertext_length = KYBER_512_R2_CIPHERTEXT_BYTES,
+ .generate_keypair = &kyber_512_90s_r2_crypto_kem_keypair,
+ .encapsulate = &kyber_512_90s_r2_crypto_kem_enc,
+ .decapsulate = &kyber_512_90s_r2_crypto_kem_dec,
+};
+
+/* These lists should be kept up to date with the above KEMs. Order in the lists
+ * does not matter. Adding a KEM to these lists will not automatically enable
+ * support for the KEM extension - that must be added via the KEM preferences &
+ * security policies. These lists are applicable only to PQ-TLS 1.2. */
+const struct s2n_kem *bike_kems[] = {
+ &s2n_bike1_l1_r1,
+ &s2n_bike1_l1_r2
+};
+
+const struct s2n_kem *sike_kems[] = {
+ &s2n_sike_p503_r1,
+ &s2n_sike_p434_r2,
+};
+
+const struct s2n_kem *kyber_kems[] = {
+ &s2n_kyber_512_r2,
+ &s2n_kyber_512_90s_r2,
+};
+
+const struct s2n_iana_to_kem kem_mapping[3] = {
+ {
+ .iana_value = { TLS_ECDHE_BIKE_RSA_WITH_AES_256_GCM_SHA384 },
+ .kems = bike_kems,
+ .kem_count = s2n_array_len(bike_kems),
+ },
+ {
+ .iana_value = { TLS_ECDHE_SIKE_RSA_WITH_AES_256_GCM_SHA384 },
+ .kems = sike_kems,
+ .kem_count = s2n_array_len(sike_kems),
+ },
+ {
+ .iana_value = { TLS_ECDHE_KYBER_RSA_WITH_AES_256_GCM_SHA384 },
+ .kems = kyber_kems,
+ .kem_count = s2n_array_len(kyber_kems),
+ }
+};
+
+/* Specific assignments of KEM group IDs and names have not yet been
+ * published in an RFC (or draft). There is consensus in the
+ * community to use values in the proposed reserved range defined in
+ * https://tools.ietf.org/html/draft-stebila-tls-hybrid-design.
+ * Values for interoperability are defined in
+ * https://docs.google.com/spreadsheets/d/12YarzaNv3XQNLnvDsWLlRKwtZFhRrDdWf36YlzwrPeg/edit#gid=0.
+ *
+ * The structure of the hybrid share is:
+ * size of ECC key share (2 bytes)
+ * || ECC key share (variable bytes)
+ * || size of PQ key share (2 bytes)
+ * || PQ key share (variable bytes) */
+const struct s2n_kem_group s2n_secp256r1_sike_p434_r2 = {
+ .name = "secp256r1_sike-p434-r2",
+ .iana_id = TLS_PQ_KEM_GROUP_ID_SECP256R1_SIKE_P434_R2,
+ .client_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + SECP256R1_SHARE_SIZE) +
+ (S2N_SIZE_OF_KEY_SHARE_SIZE + SIKE_P434_R2_PUBLIC_KEY_BYTES),
+ .server_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + SECP256R1_SHARE_SIZE) +
+ (S2N_SIZE_OF_KEY_SHARE_SIZE + SIKE_P434_R2_CIPHERTEXT_BYTES),
+ .curve = &s2n_ecc_curve_secp256r1,
+ .kem = &s2n_sike_p434_r2,
+};
+
+const struct s2n_kem_group s2n_secp256r1_bike1_l1_r2 = {
+ /* The name string follows the convention in the above google doc */
+ .name = "secp256r1_bike-1l1fo-r2",
+ .iana_id = TLS_PQ_KEM_GROUP_ID_SECP256R1_BIKE1_L1_R2,
+ .client_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + SECP256R1_SHARE_SIZE) +
+ (S2N_SIZE_OF_KEY_SHARE_SIZE + BIKE1_L1_R2_PUBLIC_KEY_BYTES),
+ .server_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + SECP256R1_SHARE_SIZE) +
+ (S2N_SIZE_OF_KEY_SHARE_SIZE + BIKE1_L1_R2_CIPHERTEXT_BYTES),
+ .curve = &s2n_ecc_curve_secp256r1,
+ .kem = &s2n_bike1_l1_r2,
+};
+
+const struct s2n_kem_group s2n_secp256r1_kyber_512_r2 = {
+ .name = "secp256r1_kyber-512-r2",
+ .iana_id = TLS_PQ_KEM_GROUP_ID_SECP256R1_KYBER_512_R2,
+ .client_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + SECP256R1_SHARE_SIZE) +
+ (S2N_SIZE_OF_KEY_SHARE_SIZE + KYBER_512_R2_PUBLIC_KEY_BYTES),
+ .server_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + SECP256R1_SHARE_SIZE) +
+ (S2N_SIZE_OF_KEY_SHARE_SIZE + KYBER_512_R2_CIPHERTEXT_BYTES),
+ .curve = &s2n_ecc_curve_secp256r1,
+ .kem = &s2n_kyber_512_r2,
+};
+
+#if EVP_APIS_SUPPORTED
+const struct s2n_kem_group s2n_x25519_sike_p434_r2 = {
+ .name = "x25519_sike-p434-r2",
+ .iana_id = TLS_PQ_KEM_GROUP_ID_X25519_SIKE_P434_R2,
+ .client_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + X25519_SHARE_SIZE) +
+ (S2N_SIZE_OF_KEY_SHARE_SIZE + SIKE_P434_R2_PUBLIC_KEY_BYTES),
+ .server_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + X25519_SHARE_SIZE) +
+ (S2N_SIZE_OF_KEY_SHARE_SIZE + SIKE_P434_R2_CIPHERTEXT_BYTES),
+ .curve = &s2n_ecc_curve_x25519,
+ .kem = &s2n_sike_p434_r2,
+};
+
+const struct s2n_kem_group s2n_x25519_bike1_l1_r2 = {
+ /* The name string follows the convention in the above google doc */
+ .name = "x25519_bike-1l1fo-r2",
+ .iana_id = TLS_PQ_KEM_GROUP_ID_X25519_BIKE1_L1_R2,
+ .client_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + X25519_SHARE_SIZE) +
+ (S2N_SIZE_OF_KEY_SHARE_SIZE + BIKE1_L1_R2_PUBLIC_KEY_BYTES),
+ .server_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + X25519_SHARE_SIZE) +
+ (S2N_SIZE_OF_KEY_SHARE_SIZE + BIKE1_L1_R2_CIPHERTEXT_BYTES),
+ .curve = &s2n_ecc_curve_x25519,
+ .kem = &s2n_bike1_l1_r2,
+};
+
+const struct s2n_kem_group s2n_x25519_kyber_512_r2 = {
+ .name = "x25519_kyber-512-r2",
+ .iana_id = TLS_PQ_KEM_GROUP_ID_X25519_KYBER_512_R2,
+ .client_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + X25519_SHARE_SIZE) +
+ (S2N_SIZE_OF_KEY_SHARE_SIZE + KYBER_512_R2_PUBLIC_KEY_BYTES),
+ .server_share_size = (S2N_SIZE_OF_KEY_SHARE_SIZE + X25519_SHARE_SIZE) +
+ (S2N_SIZE_OF_KEY_SHARE_SIZE + KYBER_512_R2_CIPHERTEXT_BYTES),
+ .curve = &s2n_ecc_curve_x25519,
+ .kem = &s2n_kyber_512_r2,
+};
+#else
+const struct s2n_kem_group s2n_x25519_sike_p434_r2 = { 0 };
+const struct s2n_kem_group s2n_x25519_bike1_l1_r2 = { 0 };
+const struct s2n_kem_group s2n_x25519_kyber_512_r2 = { 0 };
+#endif
+
+/* Helper safety macro to call the NIST PQ KEM functions. The NIST
+ * functions may return any non-zero value to indicate failure. */
+#define GUARD_PQ_AS_RESULT(x) ENSURE((x) == 0, S2N_ERR_PQ_CRYPTO)
+
+S2N_RESULT s2n_kem_generate_keypair(struct s2n_kem_params *kem_params)
+{
+ ENSURE_REF(kem_params);
+ ENSURE_REF(kem_params->kem);
+ const struct s2n_kem *kem = kem_params->kem;
+ ENSURE_REF(kem->generate_keypair);
+
+ ENSURE_REF(kem_params->public_key.data);
+ ENSURE(kem_params->public_key.size == kem->public_key_length, S2N_ERR_SAFETY);
+
+ /* Need to save the private key for decapsulation */
+ GUARD_AS_RESULT(s2n_alloc(&kem_params->private_key, kem->private_key_length));
+
+ GUARD_PQ_AS_RESULT(kem->generate_keypair(kem_params->public_key.data, kem_params->private_key.data));
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_kem_encapsulate(struct s2n_kem_params *kem_params, struct s2n_blob *ciphertext)
+{
+ ENSURE_REF(kem_params);
+ ENSURE_REF(kem_params->kem);
+ const struct s2n_kem *kem = kem_params->kem;
+ ENSURE_REF(kem->encapsulate);
+
+ ENSURE(kem_params->public_key.size == kem->public_key_length, S2N_ERR_SAFETY);
+ ENSURE_REF(kem_params->public_key.data);
+
+ ENSURE_REF(ciphertext);
+ ENSURE_REF(ciphertext->data);
+ ENSURE(ciphertext->size == kem->ciphertext_length, S2N_ERR_SAFETY);
+
+ /* Need to save the shared secret for key derivation */
+ GUARD_AS_RESULT(s2n_alloc(&(kem_params->shared_secret), kem->shared_secret_key_length));
+
+ GUARD_PQ_AS_RESULT(kem->encapsulate(ciphertext->data, kem_params->shared_secret.data, kem_params->public_key.data));
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_kem_decapsulate(struct s2n_kem_params *kem_params, const struct s2n_blob *ciphertext)
+{
+ ENSURE_REF(kem_params);
+ ENSURE_REF(kem_params->kem);
+ const struct s2n_kem *kem = kem_params->kem;
+ ENSURE_REF(kem->decapsulate);
+
+ ENSURE(kem_params->private_key.size == kem->private_key_length, S2N_ERR_SAFETY);
+ ENSURE_REF(kem_params->private_key.data);
+
+ ENSURE_REF(ciphertext);
+ ENSURE_REF(ciphertext->data);
+ ENSURE(ciphertext->size == kem->ciphertext_length, S2N_ERR_SAFETY);
+
+ /* Need to save the shared secret for key derivation */
+ GUARD_AS_RESULT(s2n_alloc(&(kem_params->shared_secret), kem->shared_secret_key_length));
+
+ GUARD_PQ_AS_RESULT(kem->decapsulate(kem_params->shared_secret.data, ciphertext->data, kem_params->private_key.data));
+ return S2N_RESULT_OK;
+}
+
+static int s2n_kem_check_kem_compatibility(const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN], const struct s2n_kem *candidate_kem,
+ uint8_t *kem_is_compatible) {
+ const struct s2n_iana_to_kem *compatible_kems = NULL;
+ GUARD(s2n_cipher_suite_to_kem(iana_value, &compatible_kems));
+
+ for (uint8_t i = 0; i < compatible_kems->kem_count; i++) {
+ if (candidate_kem->kem_extension_id == compatible_kems->kems[i]->kem_extension_id) {
+ *kem_is_compatible = 1;
+ return S2N_SUCCESS;
+ }
+ }
+
+ *kem_is_compatible = 0;
+ return S2N_SUCCESS;
+}
+
+int s2n_choose_kem_with_peer_pref_list(const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN], struct s2n_blob *client_kem_ids,
+ const struct s2n_kem *server_kem_pref_list[], const uint8_t num_server_supported_kems, const struct s2n_kem **chosen_kem) {
+ struct s2n_stuffer client_kem_ids_stuffer = {0};
+ GUARD(s2n_stuffer_init(&client_kem_ids_stuffer, client_kem_ids));
+ GUARD(s2n_stuffer_write(&client_kem_ids_stuffer, client_kem_ids));
+
+ /* Each KEM ID is 2 bytes */
+ uint8_t num_client_candidate_kems = client_kem_ids->size / 2;
+
+ for (uint8_t i = 0; i < num_server_supported_kems; i++) {
+ const struct s2n_kem *candidate_server_kem = (server_kem_pref_list[i]);
+
+ uint8_t server_kem_is_compatible = 0;
+ GUARD(s2n_kem_check_kem_compatibility(iana_value, candidate_server_kem, &server_kem_is_compatible));
+
+ if (!server_kem_is_compatible) {
+ continue;
+ }
+
+ for (uint8_t j = 0; j < num_client_candidate_kems; j++) {
+ kem_extension_size candidate_client_kem_id;
+ GUARD(s2n_stuffer_read_uint16(&client_kem_ids_stuffer, &candidate_client_kem_id));
+
+ if (candidate_server_kem->kem_extension_id == candidate_client_kem_id) {
+ *chosen_kem = candidate_server_kem;
+ return S2N_SUCCESS;
+ }
+ }
+ GUARD(s2n_stuffer_reread(&client_kem_ids_stuffer));
+ }
+
+ /* Client and server did not propose any mutually supported KEMs compatible with the ciphersuite */
+ S2N_ERROR(S2N_ERR_KEM_UNSUPPORTED_PARAMS);
+}
+
+int s2n_choose_kem_without_peer_pref_list(const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN], const struct s2n_kem *server_kem_pref_list[],
+ const uint8_t num_server_supported_kems, const struct s2n_kem **chosen_kem) {
+ for (uint8_t i = 0; i < num_server_supported_kems; i++) {
+ uint8_t kem_is_compatible = 0;
+ GUARD(s2n_kem_check_kem_compatibility(iana_value, server_kem_pref_list[i], &kem_is_compatible));
+ if (kem_is_compatible) {
+ *chosen_kem = server_kem_pref_list[i];
+ return S2N_SUCCESS;
+ }
+ }
+
+ /* The server preference list did not contain any KEM extensions compatible with the ciphersuite */
+ S2N_ERROR(S2N_ERR_KEM_UNSUPPORTED_PARAMS);
+}
+
+int s2n_kem_free(struct s2n_kem_params *kem_params)
+{
+ if (kem_params != NULL) {
+ GUARD(s2n_blob_zeroize_free(&kem_params->private_key));
+ GUARD(s2n_blob_zeroize_free(&kem_params->public_key));
+ GUARD(s2n_blob_zeroize_free(&kem_params->shared_secret));
+ }
+ return S2N_SUCCESS;
+}
+
+int s2n_kem_group_free(struct s2n_kem_group_params *kem_group_params) {
+ if (kem_group_params != NULL) {
+ GUARD(s2n_kem_free(&kem_group_params->kem_params));
+ GUARD(s2n_ecc_evp_params_free(&kem_group_params->ecc_params));
+ }
+ return S2N_SUCCESS;
+}
+
+int s2n_cipher_suite_to_kem(const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN], const struct s2n_iana_to_kem **compatible_params) {
+ for (int i = 0; i < s2n_array_len(kem_mapping); i++) {
+ const struct s2n_iana_to_kem *candidate = &kem_mapping[i];
+ if (memcmp(iana_value, candidate->iana_value, S2N_TLS_CIPHER_SUITE_LEN) == 0) {
+ *compatible_params = candidate;
+ return S2N_SUCCESS;
+ }
+ }
+ S2N_ERROR(S2N_ERR_KEM_UNSUPPORTED_PARAMS);
+}
+
+int s2n_get_kem_from_extension_id(kem_extension_size kem_id, const struct s2n_kem **kem) {
+ for (int i = 0; i < s2n_array_len(kem_mapping); i++) {
+ const struct s2n_iana_to_kem *iana_to_kem = &kem_mapping[i];
+
+ for (int j = 0; j < iana_to_kem->kem_count; j++) {
+ const struct s2n_kem *candidate_kem = iana_to_kem->kems[j];
+ if (candidate_kem->kem_extension_id == kem_id) {
+ *kem = candidate_kem;
+ return S2N_SUCCESS;
+ }
+ }
+ }
+
+ S2N_ERROR(S2N_ERR_KEM_UNSUPPORTED_PARAMS);
+}
+
+int s2n_kem_send_public_key(struct s2n_stuffer *out, struct s2n_kem_params *kem_params) {
+ notnull_check(out);
+ notnull_check(kem_params);
+ notnull_check(kem_params->kem);
+
+ const struct s2n_kem *kem = kem_params->kem;
+
+ GUARD(s2n_stuffer_write_uint16(out, kem->public_key_length));
+
+ /* We don't need to store the public key after sending it.
+ * We write it directly to *out. */
+ kem_params->public_key.data = s2n_stuffer_raw_write(out, kem->public_key_length);
+ notnull_check(kem_params->public_key.data);
+ kem_params->public_key.size = kem->public_key_length;
+
+ /* Saves the private key in kem_params */
+ GUARD_AS_POSIX(s2n_kem_generate_keypair(kem_params));
+
+ /* After using s2n_stuffer_raw_write() above to write the public
+ * key to the stuffer, we want to ensure that kem_params->public_key.data
+ * does not continue to point at *out, else we may unexpectedly
+ * overwrite part of the stuffer when s2n_kem_free() is called. */
+ kem_params->public_key.data = NULL;
+ kem_params->public_key.size = 0;
+
+ return S2N_SUCCESS;
+}
+
+int s2n_kem_recv_public_key(struct s2n_stuffer *in, struct s2n_kem_params *kem_params) {
+ notnull_check(in);
+ notnull_check(kem_params);
+ notnull_check(kem_params->kem);
+
+ const struct s2n_kem *kem = kem_params->kem;
+ kem_public_key_size public_key_length;
+
+ GUARD(s2n_stuffer_read_uint16(in, &public_key_length));
+ S2N_ERROR_IF(public_key_length != kem->public_key_length, S2N_ERR_BAD_MESSAGE);
+
+ /* Alloc memory for the public key; the peer receiving it will need it
+ * later during the handshake to encapsulate the shared secret. */
+ GUARD(s2n_alloc(&(kem_params->public_key), public_key_length));
+ GUARD(s2n_stuffer_read_bytes(in, kem_params->public_key.data, public_key_length));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_kem_send_ciphertext(struct s2n_stuffer *out, struct s2n_kem_params *kem_params) {
+ notnull_check(out);
+ notnull_check(kem_params);
+ notnull_check(kem_params->kem);
+ notnull_check(kem_params->public_key.data);
+
+ const struct s2n_kem *kem = kem_params->kem;
+
+ GUARD(s2n_stuffer_write_uint16(out, kem->ciphertext_length));
+
+ /* Ciphertext will get written to *out */
+ struct s2n_blob ciphertext = {.data = s2n_stuffer_raw_write(out, kem->ciphertext_length), .size = kem->ciphertext_length};
+ notnull_check(ciphertext.data);
+
+ /* Saves the shared secret in kem_params */
+ GUARD_AS_POSIX(s2n_kem_encapsulate(kem_params, &ciphertext));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_kem_recv_ciphertext(struct s2n_stuffer *in, struct s2n_kem_params *kem_params) {
+ notnull_check(in);
+ notnull_check(kem_params);
+ notnull_check(kem_params->kem);
+ notnull_check(kem_params->private_key.data);
+
+ const struct s2n_kem *kem = kem_params->kem;
+ kem_ciphertext_key_size ciphertext_length;
+
+ GUARD(s2n_stuffer_read_uint16(in, &ciphertext_length));
+ S2N_ERROR_IF(ciphertext_length != kem->ciphertext_length, S2N_ERR_BAD_MESSAGE);
+
+ const struct s2n_blob ciphertext = {.data = s2n_stuffer_raw_read(in, ciphertext_length), .size = ciphertext_length};
+ notnull_check(ciphertext.data);
+
+ /* Saves the shared secret in kem_params */
+ GUARD_AS_POSIX(s2n_kem_decapsulate(kem_params, &ciphertext));
+
+ return S2N_SUCCESS;
+}
+
+#if defined(S2N_NO_PQ)
+/* IF S2N_NO_PQ was defined at compile time, the PQ KEM code will have been entirely excluded
+ * from compilation. We define stubs of these functions here to error if they are called. */
+/* sikep503r1 */
+int SIKE_P503_r1_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
+int SIKE_P503_r1_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
+int SIKE_P503_r1_crypto_kem_dec(OUT unsigned char *ss, IN const unsigned char *ct, IN const unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
+/* sikep434r2 */
+int SIKE_P434_r2_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
+int SIKE_P434_r2_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
+int SIKE_P434_r2_crypto_kem_dec(OUT unsigned char *ss, IN const unsigned char *ct, IN const unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
+/* bike1l1r1 */
+int BIKE1_L1_R1_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
+int BIKE1_L1_R1_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
+int BIKE1_L1_R1_crypto_kem_dec(OUT unsigned char *ss, IN const unsigned char *ct, IN const unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
+/* bike1l1r2*/
+int BIKE1_L1_R2_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
+int BIKE1_L1_R2_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
+int BIKE1_L1_R2_crypto_kem_dec(OUT unsigned char * ss, IN const unsigned char *ct, IN const unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
+/* kyber512r2 */
+int kyber_512_r2_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
+int kyber_512_r2_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
+int kyber_512_r2_crypto_kem_dec(OUT unsigned char *ss, IN const unsigned char *ct, IN const unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
+/* kyber512r2 90's version*/
+int kyber_512_90s_r2_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
+int kyber_512_90s_r2_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
+int kyber_512_90s_r2_crypto_kem_dec(OUT unsigned char *ss, IN const unsigned char *ct, IN const unsigned char *sk) { BAIL_POSIX(S2N_ERR_UNIMPLEMENTED); }
+#endif
diff --git a/contrib/restricted/aws/s2n/tls/s2n_kem.h b/contrib/restricted/aws/s2n/tls/s2n_kem.h
index 76908aa968..ddea9d09ca 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_kem.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_kem.h
@@ -1,181 +1,181 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <stdint.h>
-#include "tls/s2n_crypto_constants.h"
-#include "utils/s2n_blob.h"
-#include "stuffer/s2n_stuffer.h"
-#include "crypto/s2n_ecc_evp.h"
-
-typedef uint16_t kem_extension_size;
-typedef uint16_t kem_public_key_size;
-typedef uint16_t kem_private_key_size;
-typedef uint16_t kem_shared_secret_size;
-typedef uint16_t kem_ciphertext_key_size;
-
-#define IN /* Indicates a necessary function input */
-#define OUT /* Indicates a function output */
-
-struct s2n_kem {
- const char *name;
- const kem_extension_size kem_extension_id;
- const kem_public_key_size public_key_length;
- const kem_private_key_size private_key_length;
- const kem_shared_secret_size shared_secret_key_length;
- const kem_ciphertext_key_size ciphertext_length;
- /* NIST Post Quantum KEM submissions require the following API for compatibility */
- int (*generate_keypair)(OUT unsigned char *public_key, OUT unsigned char *private_key);
- int (*encapsulate)(OUT unsigned char *ciphertext, OUT unsigned char *shared_secret, IN const unsigned char *public_key);
- int (*decapsulate)(OUT unsigned char *shared_secret, IN const unsigned char *ciphertext, IN const unsigned char *private_key);
-};
-
-struct s2n_kem_params {
- const struct s2n_kem *kem;
- struct s2n_blob public_key;
- struct s2n_blob private_key;
- struct s2n_blob shared_secret;
-};
-
-struct s2n_iana_to_kem {
- const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN];
- const struct s2n_kem **kems;
- uint8_t kem_count;
-};
-
-struct s2n_kem_group {
- const char *name;
- uint16_t iana_id;
- uint16_t client_share_size;
- uint16_t server_share_size;
- const struct s2n_ecc_named_curve *curve;
- const struct s2n_kem *kem;
-};
-
-struct s2n_kem_group_params {
- const struct s2n_kem_group *kem_group;
- struct s2n_kem_params kem_params;
- struct s2n_ecc_evp_params ecc_params;
-};
-
-extern const struct s2n_kem s2n_bike1_l1_r1;
-extern const struct s2n_kem s2n_bike1_l1_r2;
-extern const struct s2n_kem s2n_sike_p503_r1;
-extern const struct s2n_kem s2n_sike_p434_r2;
-extern const struct s2n_kem s2n_kyber_512_r2;
-extern const struct s2n_kem s2n_kyber_512_90s_r2;
-
-/* x25519 based tls13_kem_groups require EVP_APIS_SUPPORTED */
-#if EVP_APIS_SUPPORTED
-#define S2N_SUPPORTED_KEM_GROUPS_COUNT 6
-#else
-#define S2N_SUPPORTED_KEM_GROUPS_COUNT 3
-#endif
-
-extern const struct s2n_kem_group s2n_secp256r1_sike_p434_r2;
-extern const struct s2n_kem_group s2n_secp256r1_bike1_l1_r2;
-extern const struct s2n_kem_group s2n_secp256r1_kyber_512_r2;
-extern const struct s2n_kem_group s2n_x25519_sike_p434_r2;
-extern const struct s2n_kem_group s2n_x25519_bike1_l1_r2;
-extern const struct s2n_kem_group s2n_x25519_kyber_512_r2;
-
-extern S2N_RESULT s2n_kem_generate_keypair(struct s2n_kem_params *kem_params);
-extern S2N_RESULT s2n_kem_encapsulate(struct s2n_kem_params *kem_params, struct s2n_blob *ciphertext);
-extern S2N_RESULT s2n_kem_decapsulate(struct s2n_kem_params *kem_params, const struct s2n_blob *ciphertext);
-extern int s2n_choose_kem_with_peer_pref_list(const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN],
- struct s2n_blob *client_kem_ids, const struct s2n_kem *server_kem_pref_list[],
- const uint8_t num_server_supported_kems, const struct s2n_kem **chosen_kem);
-extern int s2n_choose_kem_without_peer_pref_list(const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN],
- const struct s2n_kem *server_kem_pref_list[], const uint8_t num_server_supported_kems,
- const struct s2n_kem **chosen_kem);
-extern int s2n_kem_free(struct s2n_kem_params *kem_params);
-extern int s2n_kem_group_free(struct s2n_kem_group_params *kem_group_params);
-extern int s2n_cipher_suite_to_kem(const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN],
- const struct s2n_iana_to_kem **supported_params);
-extern int s2n_get_kem_from_extension_id(kem_extension_size kem_id, const struct s2n_kem **kem);
-extern int s2n_kem_send_public_key(struct s2n_stuffer *out, struct s2n_kem_params *kem_params);
-extern int s2n_kem_recv_public_key(struct s2n_stuffer *in, struct s2n_kem_params *kem_params);
-extern int s2n_kem_send_ciphertext(struct s2n_stuffer *out, struct s2n_kem_params *kem_params);
-extern int s2n_kem_recv_ciphertext(struct s2n_stuffer *in, struct s2n_kem_params *kem_params);
-
-/* The following are API signatures for PQ KEMs as defined by NIST. All functions return 0
- * on success, and !0 on failure. Avoid calling these functions directly within s2n. Instead,
- * use s2n_kem_{generate_keypair, encapsulate, decapsulate}, or
- * s2n_kem_{send_public_key, recv_public_key, send_ciphertext, recv_ciphertext}.
- *
- * int *_keypair(OUT pk, OUT sk) - Generate public/private keypair
- * pk - generated public key
- * sk - generated secret key
- *
- * int *_enc(OUT ct, OUT ss, IN pk) - Generate a shared secret and encapsulate it
- * ct - key encapsulation message (ciphertext)
- * ss - plaintext shared secret
- * pk - public key to use for encapsulation
- *
- * int *_dec(OUT ss, IN ct, IN sk) - Decapsulate a key encapsulation message and recover the shared secret
- * ss - plaintext shared secret
- * ct - key encapsulation message (ciphertext)
- * sk - secret key to use for decapsulation */
-
-/* If s2n is compiled with support for PQ crypto, these functions will be defined in the respective KEM directories.
- * If s2n is compiled without support for PQ, stubs of these functions are defined in s2n_kem.c. */
-/* sikep503r1 */
-#define SIKE_P503_R1_SECRET_KEY_BYTES 434
-#define SIKE_P503_R1_PUBLIC_KEY_BYTES 378
-#define SIKE_P503_R1_CIPHERTEXT_BYTES 402
-#define SIKE_P503_R1_SHARED_SECRET_BYTES 16
-int SIKE_P503_r1_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk);
-int SIKE_P503_r1_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk);
-int SIKE_P503_r1_crypto_kem_dec(OUT unsigned char *ss, IN const unsigned char *ct, IN const unsigned char *sk);
-
-/* sikep434r2 */
-#define SIKE_P434_R2_PUBLIC_KEY_BYTES 330
-#define SIKE_P434_R2_SECRET_KEY_BYTES 374
-#define SIKE_P434_R2_CIPHERTEXT_BYTES 346
-#define SIKE_P434_R2_SHARED_SECRET_BYTES 16
-int SIKE_P434_r2_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk);
-int SIKE_P434_r2_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk);
-int SIKE_P434_r2_crypto_kem_dec(OUT unsigned char *ss, IN const unsigned char *ct, IN const unsigned char *sk);
-
-/* bike1l1r1 */
-#define BIKE1_L1_R1_SECRET_KEY_BYTES 3110
-#define BIKE1_L1_R1_PUBLIC_KEY_BYTES 2542
-#define BIKE1_L1_R1_CIPHERTEXT_BYTES 2542
-#define BIKE1_L1_R1_SHARED_SECRET_BYTES 32
-int BIKE1_L1_R1_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk);
-int BIKE1_L1_R1_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk);
-int BIKE1_L1_R1_crypto_kem_dec(OUT unsigned char *ss, IN const unsigned char *ct, IN const unsigned char *sk);
-
-/* bike1l1r2 */
-#define BIKE1_L1_R2_SECRET_KEY_BYTES 6460
-#define BIKE1_L1_R2_PUBLIC_KEY_BYTES 2946
-#define BIKE1_L1_R2_CIPHERTEXT_BYTES 2946
-#define BIKE1_L1_R2_SHARED_SECRET_BYTES 32
-int BIKE1_L1_R2_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk);
-int BIKE1_L1_R2_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk);
-int BIKE1_L1_R2_crypto_kem_dec(OUT unsigned char * ss, IN const unsigned char *ct, IN const unsigned char *sk);
-
-/* kyber512r2 (the defined constants are identical for both regular and 90's version) */
-#define KYBER_512_R2_PUBLIC_KEY_BYTES 800
-#define KYBER_512_R2_SECRET_KEY_BYTES 1632
-#define KYBER_512_R2_CIPHERTEXT_BYTES 736
-#define KYBER_512_R2_SHARED_SECRET_BYTES 32
-int kyber_512_r2_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk);
-int kyber_512_r2_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk);
-int kyber_512_r2_crypto_kem_dec(OUT unsigned char *ss, IN const unsigned char *ct, IN const unsigned char *sk);
-int kyber_512_90s_r2_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk);
-int kyber_512_90s_r2_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk);
-int kyber_512_90s_r2_crypto_kem_dec(OUT unsigned char *ss, IN const unsigned char *ct, IN const unsigned char *sk);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include "tls/s2n_crypto_constants.h"
+#include "utils/s2n_blob.h"
+#include "stuffer/s2n_stuffer.h"
+#include "crypto/s2n_ecc_evp.h"
+
+typedef uint16_t kem_extension_size;
+typedef uint16_t kem_public_key_size;
+typedef uint16_t kem_private_key_size;
+typedef uint16_t kem_shared_secret_size;
+typedef uint16_t kem_ciphertext_key_size;
+
+#define IN /* Indicates a necessary function input */
+#define OUT /* Indicates a function output */
+
+struct s2n_kem {
+ const char *name;
+ const kem_extension_size kem_extension_id;
+ const kem_public_key_size public_key_length;
+ const kem_private_key_size private_key_length;
+ const kem_shared_secret_size shared_secret_key_length;
+ const kem_ciphertext_key_size ciphertext_length;
+ /* NIST Post Quantum KEM submissions require the following API for compatibility */
+ int (*generate_keypair)(OUT unsigned char *public_key, OUT unsigned char *private_key);
+ int (*encapsulate)(OUT unsigned char *ciphertext, OUT unsigned char *shared_secret, IN const unsigned char *public_key);
+ int (*decapsulate)(OUT unsigned char *shared_secret, IN const unsigned char *ciphertext, IN const unsigned char *private_key);
+};
+
+struct s2n_kem_params {
+ const struct s2n_kem *kem;
+ struct s2n_blob public_key;
+ struct s2n_blob private_key;
+ struct s2n_blob shared_secret;
+};
+
+struct s2n_iana_to_kem {
+ const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN];
+ const struct s2n_kem **kems;
+ uint8_t kem_count;
+};
+
+struct s2n_kem_group {
+ const char *name;
+ uint16_t iana_id;
+ uint16_t client_share_size;
+ uint16_t server_share_size;
+ const struct s2n_ecc_named_curve *curve;
+ const struct s2n_kem *kem;
+};
+
+struct s2n_kem_group_params {
+ const struct s2n_kem_group *kem_group;
+ struct s2n_kem_params kem_params;
+ struct s2n_ecc_evp_params ecc_params;
+};
+
+extern const struct s2n_kem s2n_bike1_l1_r1;
+extern const struct s2n_kem s2n_bike1_l1_r2;
+extern const struct s2n_kem s2n_sike_p503_r1;
+extern const struct s2n_kem s2n_sike_p434_r2;
+extern const struct s2n_kem s2n_kyber_512_r2;
+extern const struct s2n_kem s2n_kyber_512_90s_r2;
+
+/* x25519 based tls13_kem_groups require EVP_APIS_SUPPORTED */
+#if EVP_APIS_SUPPORTED
+#define S2N_SUPPORTED_KEM_GROUPS_COUNT 6
+#else
+#define S2N_SUPPORTED_KEM_GROUPS_COUNT 3
+#endif
+
+extern const struct s2n_kem_group s2n_secp256r1_sike_p434_r2;
+extern const struct s2n_kem_group s2n_secp256r1_bike1_l1_r2;
+extern const struct s2n_kem_group s2n_secp256r1_kyber_512_r2;
+extern const struct s2n_kem_group s2n_x25519_sike_p434_r2;
+extern const struct s2n_kem_group s2n_x25519_bike1_l1_r2;
+extern const struct s2n_kem_group s2n_x25519_kyber_512_r2;
+
+extern S2N_RESULT s2n_kem_generate_keypair(struct s2n_kem_params *kem_params);
+extern S2N_RESULT s2n_kem_encapsulate(struct s2n_kem_params *kem_params, struct s2n_blob *ciphertext);
+extern S2N_RESULT s2n_kem_decapsulate(struct s2n_kem_params *kem_params, const struct s2n_blob *ciphertext);
+extern int s2n_choose_kem_with_peer_pref_list(const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN],
+ struct s2n_blob *client_kem_ids, const struct s2n_kem *server_kem_pref_list[],
+ const uint8_t num_server_supported_kems, const struct s2n_kem **chosen_kem);
+extern int s2n_choose_kem_without_peer_pref_list(const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN],
+ const struct s2n_kem *server_kem_pref_list[], const uint8_t num_server_supported_kems,
+ const struct s2n_kem **chosen_kem);
+extern int s2n_kem_free(struct s2n_kem_params *kem_params);
+extern int s2n_kem_group_free(struct s2n_kem_group_params *kem_group_params);
+extern int s2n_cipher_suite_to_kem(const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN],
+ const struct s2n_iana_to_kem **supported_params);
+extern int s2n_get_kem_from_extension_id(kem_extension_size kem_id, const struct s2n_kem **kem);
+extern int s2n_kem_send_public_key(struct s2n_stuffer *out, struct s2n_kem_params *kem_params);
+extern int s2n_kem_recv_public_key(struct s2n_stuffer *in, struct s2n_kem_params *kem_params);
+extern int s2n_kem_send_ciphertext(struct s2n_stuffer *out, struct s2n_kem_params *kem_params);
+extern int s2n_kem_recv_ciphertext(struct s2n_stuffer *in, struct s2n_kem_params *kem_params);
+
+/* The following are API signatures for PQ KEMs as defined by NIST. All functions return 0
+ * on success, and !0 on failure. Avoid calling these functions directly within s2n. Instead,
+ * use s2n_kem_{generate_keypair, encapsulate, decapsulate}, or
+ * s2n_kem_{send_public_key, recv_public_key, send_ciphertext, recv_ciphertext}.
+ *
+ * int *_keypair(OUT pk, OUT sk) - Generate public/private keypair
+ * pk - generated public key
+ * sk - generated secret key
+ *
+ * int *_enc(OUT ct, OUT ss, IN pk) - Generate a shared secret and encapsulate it
+ * ct - key encapsulation message (ciphertext)
+ * ss - plaintext shared secret
+ * pk - public key to use for encapsulation
+ *
+ * int *_dec(OUT ss, IN ct, IN sk) - Decapsulate a key encapsulation message and recover the shared secret
+ * ss - plaintext shared secret
+ * ct - key encapsulation message (ciphertext)
+ * sk - secret key to use for decapsulation */
+
+/* If s2n is compiled with support for PQ crypto, these functions will be defined in the respective KEM directories.
+ * If s2n is compiled without support for PQ, stubs of these functions are defined in s2n_kem.c. */
+/* sikep503r1 */
+#define SIKE_P503_R1_SECRET_KEY_BYTES 434
+#define SIKE_P503_R1_PUBLIC_KEY_BYTES 378
+#define SIKE_P503_R1_CIPHERTEXT_BYTES 402
+#define SIKE_P503_R1_SHARED_SECRET_BYTES 16
+int SIKE_P503_r1_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk);
+int SIKE_P503_r1_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk);
+int SIKE_P503_r1_crypto_kem_dec(OUT unsigned char *ss, IN const unsigned char *ct, IN const unsigned char *sk);
+
+/* sikep434r2 */
+#define SIKE_P434_R2_PUBLIC_KEY_BYTES 330
+#define SIKE_P434_R2_SECRET_KEY_BYTES 374
+#define SIKE_P434_R2_CIPHERTEXT_BYTES 346
+#define SIKE_P434_R2_SHARED_SECRET_BYTES 16
+int SIKE_P434_r2_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk);
+int SIKE_P434_r2_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk);
+int SIKE_P434_r2_crypto_kem_dec(OUT unsigned char *ss, IN const unsigned char *ct, IN const unsigned char *sk);
+
+/* bike1l1r1 */
+#define BIKE1_L1_R1_SECRET_KEY_BYTES 3110
+#define BIKE1_L1_R1_PUBLIC_KEY_BYTES 2542
+#define BIKE1_L1_R1_CIPHERTEXT_BYTES 2542
+#define BIKE1_L1_R1_SHARED_SECRET_BYTES 32
+int BIKE1_L1_R1_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk);
+int BIKE1_L1_R1_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk);
+int BIKE1_L1_R1_crypto_kem_dec(OUT unsigned char *ss, IN const unsigned char *ct, IN const unsigned char *sk);
+
+/* bike1l1r2 */
+#define BIKE1_L1_R2_SECRET_KEY_BYTES 6460
+#define BIKE1_L1_R2_PUBLIC_KEY_BYTES 2946
+#define BIKE1_L1_R2_CIPHERTEXT_BYTES 2946
+#define BIKE1_L1_R2_SHARED_SECRET_BYTES 32
+int BIKE1_L1_R2_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk);
+int BIKE1_L1_R2_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk);
+int BIKE1_L1_R2_crypto_kem_dec(OUT unsigned char * ss, IN const unsigned char *ct, IN const unsigned char *sk);
+
+/* kyber512r2 (the defined constants are identical for both regular and 90's version) */
+#define KYBER_512_R2_PUBLIC_KEY_BYTES 800
+#define KYBER_512_R2_SECRET_KEY_BYTES 1632
+#define KYBER_512_R2_CIPHERTEXT_BYTES 736
+#define KYBER_512_R2_SHARED_SECRET_BYTES 32
+int kyber_512_r2_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk);
+int kyber_512_r2_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk);
+int kyber_512_r2_crypto_kem_dec(OUT unsigned char *ss, IN const unsigned char *ct, IN const unsigned char *sk);
+int kyber_512_90s_r2_crypto_kem_keypair(OUT unsigned char *pk, OUT unsigned char *sk);
+int kyber_512_90s_r2_crypto_kem_enc(OUT unsigned char *ct, OUT unsigned char *ss, IN const unsigned char *pk);
+int kyber_512_90s_r2_crypto_kem_dec(OUT unsigned char *ss, IN const unsigned char *ct, IN const unsigned char *sk);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_kem_preferences.c b/contrib/restricted/aws/s2n/tls/s2n_kem_preferences.c
index c725c242fe..4b9290c418 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_kem_preferences.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_kem_preferences.c
@@ -1,138 +1,138 @@
-/*
- * 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 "tls/s2n_kem_preferences.h"
-
-#if !defined(S2N_NO_PQ)
-
-/* Extension list for round 1 PQ KEMs, in order of preference */
-const struct s2n_kem *pq_kems_r1[2] = {
- &s2n_bike1_l1_r1,
- &s2n_sike_p503_r1,
-};
-
-/* Extension list for round 2 and round 1 PQ KEMs, in order of preference */
-const struct s2n_kem *pq_kems_r2r1[4] = {
- &s2n_bike1_l1_r2,
- &s2n_sike_p434_r2,
- &s2n_bike1_l1_r1,
- &s2n_sike_p503_r1,
-};
-
-const struct s2n_kem *pq_kems_r2r1_2020_07[5] = {
- &s2n_kyber_512_r2,
- &s2n_bike1_l1_r2,
- &s2n_sike_p434_r2,
- &s2n_bike1_l1_r1,
- &s2n_sike_p503_r1,
-};
-
-/* Extension list for SIKE P503 Round 1 only (for testing) */
-const struct s2n_kem *pq_kems_sike_r1[1] = {
- &s2n_sike_p503_r1,
-};
-
-/* Extension list for SIKE P434 Round 2 and SIKE P503 Round 1 only (for testing),
- * in order of preference */
-const struct s2n_kem *pq_kems_sike_r2r1[2] = {
- &s2n_sike_p434_r2,
- &s2n_sike_p503_r1,
-};
-
-const struct s2n_kem_group *pq_kem_groups_r2[] = {
-#if EVP_APIS_SUPPORTED
- &s2n_x25519_kyber_512_r2,
- &s2n_secp256r1_kyber_512_r2,
- &s2n_x25519_bike1_l1_r2,
- &s2n_secp256r1_bike1_l1_r2,
- &s2n_x25519_sike_p434_r2,
- &s2n_secp256r1_sike_p434_r2,
-#else
- &s2n_secp256r1_kyber_512_r2,
- &s2n_secp256r1_bike1_l1_r2,
- &s2n_secp256r1_sike_p434_r2,
-#endif
-};
-
-/* Includes only round 1 PQ KEM params */
-const struct s2n_kem_preferences kem_preferences_kms_pq_tls_1_0_2019_06 = {
- .kem_count = s2n_array_len(pq_kems_r1),
- .kems = pq_kems_r1,
- .tls13_kem_group_count = 0,
- .tls13_kem_groups = NULL,
-};
-
-/* Includes round 1 and round 2 PQ KEM params. */
-const struct s2n_kem_preferences kem_preferences_kms_pq_tls_1_0_2020_02 = {
- .kem_count = s2n_array_len(pq_kems_r2r1),
- .kems = pq_kems_r2r1,
- .tls13_kem_group_count = 0,
- .tls13_kem_groups = NULL,
-};
-
-const struct s2n_kem_preferences kem_preferences_kms_pq_tls_1_0_2020_07 = {
- .kem_count = s2n_array_len(pq_kems_r2r1_2020_07),
- .kems = pq_kems_r2r1_2020_07,
- .tls13_kem_group_count = 0,
- .tls13_kem_groups = NULL,
-};
-
-/* Includes only SIKE round 1 (for integration tests) */
-const struct s2n_kem_preferences kem_preferences_pq_sike_test_tls_1_0_2019_11 = {
- .kem_count = s2n_array_len(pq_kems_sike_r1),
- .kems = pq_kems_sike_r1,
- .tls13_kem_group_count = 0,
- .tls13_kem_groups = NULL,
-};
-
-/* Includes only SIKE round 1 and round 2 (for integration tests). */
-const struct s2n_kem_preferences kem_preferences_pq_sike_test_tls_1_0_2020_02 = {
- .kem_count = s2n_array_len(pq_kems_sike_r2r1),
- .kems = pq_kems_sike_r2r1,
- .tls13_kem_group_count = 0,
- .tls13_kem_groups = NULL,
-};
-
-const struct s2n_kem_preferences kem_preferences_pq_tls_1_0_2020_12 = {
- .kem_count = s2n_array_len(pq_kems_r2r1_2020_07),
- .kems = pq_kems_r2r1_2020_07,
- .tls13_kem_group_count = s2n_array_len(pq_kem_groups_r2),
- .tls13_kem_groups = pq_kem_groups_r2,
-};
-
-#endif
-
-const struct s2n_kem_preferences kem_preferences_null = {
- .kem_count = 0,
- .kems = NULL,
- .tls13_kem_group_count = 0,
- .tls13_kem_groups = NULL,
-};
-
-/* Determines if query_iana_id corresponds to a tls13_kem_group for these KEM preferences. */
-bool s2n_kem_preferences_includes_tls13_kem_group(const struct s2n_kem_preferences *kem_preferences,
- uint16_t query_iana_id) {
- if (kem_preferences == NULL) {
- return false;
- }
-
- for (size_t i = 0; i < kem_preferences->tls13_kem_group_count; i++) {
- if (query_iana_id == kem_preferences->tls13_kem_groups[i]->iana_id) {
- return true;
- }
- }
-
- return false;
-}
+/*
+ * 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 "tls/s2n_kem_preferences.h"
+
+#if !defined(S2N_NO_PQ)
+
+/* Extension list for round 1 PQ KEMs, in order of preference */
+const struct s2n_kem *pq_kems_r1[2] = {
+ &s2n_bike1_l1_r1,
+ &s2n_sike_p503_r1,
+};
+
+/* Extension list for round 2 and round 1 PQ KEMs, in order of preference */
+const struct s2n_kem *pq_kems_r2r1[4] = {
+ &s2n_bike1_l1_r2,
+ &s2n_sike_p434_r2,
+ &s2n_bike1_l1_r1,
+ &s2n_sike_p503_r1,
+};
+
+const struct s2n_kem *pq_kems_r2r1_2020_07[5] = {
+ &s2n_kyber_512_r2,
+ &s2n_bike1_l1_r2,
+ &s2n_sike_p434_r2,
+ &s2n_bike1_l1_r1,
+ &s2n_sike_p503_r1,
+};
+
+/* Extension list for SIKE P503 Round 1 only (for testing) */
+const struct s2n_kem *pq_kems_sike_r1[1] = {
+ &s2n_sike_p503_r1,
+};
+
+/* Extension list for SIKE P434 Round 2 and SIKE P503 Round 1 only (for testing),
+ * in order of preference */
+const struct s2n_kem *pq_kems_sike_r2r1[2] = {
+ &s2n_sike_p434_r2,
+ &s2n_sike_p503_r1,
+};
+
+const struct s2n_kem_group *pq_kem_groups_r2[] = {
+#if EVP_APIS_SUPPORTED
+ &s2n_x25519_kyber_512_r2,
+ &s2n_secp256r1_kyber_512_r2,
+ &s2n_x25519_bike1_l1_r2,
+ &s2n_secp256r1_bike1_l1_r2,
+ &s2n_x25519_sike_p434_r2,
+ &s2n_secp256r1_sike_p434_r2,
+#else
+ &s2n_secp256r1_kyber_512_r2,
+ &s2n_secp256r1_bike1_l1_r2,
+ &s2n_secp256r1_sike_p434_r2,
+#endif
+};
+
+/* Includes only round 1 PQ KEM params */
+const struct s2n_kem_preferences kem_preferences_kms_pq_tls_1_0_2019_06 = {
+ .kem_count = s2n_array_len(pq_kems_r1),
+ .kems = pq_kems_r1,
+ .tls13_kem_group_count = 0,
+ .tls13_kem_groups = NULL,
+};
+
+/* Includes round 1 and round 2 PQ KEM params. */
+const struct s2n_kem_preferences kem_preferences_kms_pq_tls_1_0_2020_02 = {
+ .kem_count = s2n_array_len(pq_kems_r2r1),
+ .kems = pq_kems_r2r1,
+ .tls13_kem_group_count = 0,
+ .tls13_kem_groups = NULL,
+};
+
+const struct s2n_kem_preferences kem_preferences_kms_pq_tls_1_0_2020_07 = {
+ .kem_count = s2n_array_len(pq_kems_r2r1_2020_07),
+ .kems = pq_kems_r2r1_2020_07,
+ .tls13_kem_group_count = 0,
+ .tls13_kem_groups = NULL,
+};
+
+/* Includes only SIKE round 1 (for integration tests) */
+const struct s2n_kem_preferences kem_preferences_pq_sike_test_tls_1_0_2019_11 = {
+ .kem_count = s2n_array_len(pq_kems_sike_r1),
+ .kems = pq_kems_sike_r1,
+ .tls13_kem_group_count = 0,
+ .tls13_kem_groups = NULL,
+};
+
+/* Includes only SIKE round 1 and round 2 (for integration tests). */
+const struct s2n_kem_preferences kem_preferences_pq_sike_test_tls_1_0_2020_02 = {
+ .kem_count = s2n_array_len(pq_kems_sike_r2r1),
+ .kems = pq_kems_sike_r2r1,
+ .tls13_kem_group_count = 0,
+ .tls13_kem_groups = NULL,
+};
+
+const struct s2n_kem_preferences kem_preferences_pq_tls_1_0_2020_12 = {
+ .kem_count = s2n_array_len(pq_kems_r2r1_2020_07),
+ .kems = pq_kems_r2r1_2020_07,
+ .tls13_kem_group_count = s2n_array_len(pq_kem_groups_r2),
+ .tls13_kem_groups = pq_kem_groups_r2,
+};
+
+#endif
+
+const struct s2n_kem_preferences kem_preferences_null = {
+ .kem_count = 0,
+ .kems = NULL,
+ .tls13_kem_group_count = 0,
+ .tls13_kem_groups = NULL,
+};
+
+/* Determines if query_iana_id corresponds to a tls13_kem_group for these KEM preferences. */
+bool s2n_kem_preferences_includes_tls13_kem_group(const struct s2n_kem_preferences *kem_preferences,
+ uint16_t query_iana_id) {
+ if (kem_preferences == NULL) {
+ return false;
+ }
+
+ for (size_t i = 0; i < kem_preferences->tls13_kem_group_count; i++) {
+ if (query_iana_id == kem_preferences->tls13_kem_groups[i]->iana_id) {
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_kem_preferences.h b/contrib/restricted/aws/s2n/tls/s2n_kem_preferences.h
index e62c60ec8a..e6226bb8f3 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_kem_preferences.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_kem_preferences.h
@@ -1,54 +1,54 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <stdbool.h>
-#include "tls/s2n_kem.h"
-#include "tls/s2n_kex.h"
-
-struct s2n_kem_preferences {
- /* kems used for hybrid TLS 1.2 */
- uint8_t kem_count;
- const struct s2n_kem **kems;
-
- /* tls13_kem_groups used for hybrid TLS 1.3 */
- uint8_t tls13_kem_group_count;
- const struct s2n_kem_group **tls13_kem_groups;
-};
-
-#if !defined(S2N_NO_PQ)
-
-extern const struct s2n_kem *pq_kems_r1[2];
-extern const struct s2n_kem *pq_kems_r2r1[4];
-extern const struct s2n_kem *pq_kems_r2r1_2020_07[5];
-extern const struct s2n_kem *pq_kems_sike_r1[1];
-extern const struct s2n_kem *pq_kems_sike_r2r1[2];
-
-extern const struct s2n_kem_group *pq_kem_groups_r2[];
-
-extern const struct s2n_kem_preferences kem_preferences_kms_pq_tls_1_0_2019_06;
-extern const struct s2n_kem_preferences kem_preferences_kms_pq_tls_1_0_2020_02;
-extern const struct s2n_kem_preferences kem_preferences_kms_pq_tls_1_0_2020_07;
-extern const struct s2n_kem_preferences kem_preferences_pq_sike_test_tls_1_0_2019_11;
-extern const struct s2n_kem_preferences kem_preferences_pq_sike_test_tls_1_0_2020_02;
-extern const struct s2n_kem_preferences kem_preferences_pq_tls_1_0_2020_12;
-
-#endif
-
-extern const struct s2n_kem_preferences kem_preferences_null;
-
-bool s2n_kem_preferences_includes_tls13_kem_group(const struct s2n_kem_preferences *kem_preferences,
- uint16_t query_iana_id);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stdbool.h>
+#include "tls/s2n_kem.h"
+#include "tls/s2n_kex.h"
+
+struct s2n_kem_preferences {
+ /* kems used for hybrid TLS 1.2 */
+ uint8_t kem_count;
+ const struct s2n_kem **kems;
+
+ /* tls13_kem_groups used for hybrid TLS 1.3 */
+ uint8_t tls13_kem_group_count;
+ const struct s2n_kem_group **tls13_kem_groups;
+};
+
+#if !defined(S2N_NO_PQ)
+
+extern const struct s2n_kem *pq_kems_r1[2];
+extern const struct s2n_kem *pq_kems_r2r1[4];
+extern const struct s2n_kem *pq_kems_r2r1_2020_07[5];
+extern const struct s2n_kem *pq_kems_sike_r1[1];
+extern const struct s2n_kem *pq_kems_sike_r2r1[2];
+
+extern const struct s2n_kem_group *pq_kem_groups_r2[];
+
+extern const struct s2n_kem_preferences kem_preferences_kms_pq_tls_1_0_2019_06;
+extern const struct s2n_kem_preferences kem_preferences_kms_pq_tls_1_0_2020_02;
+extern const struct s2n_kem_preferences kem_preferences_kms_pq_tls_1_0_2020_07;
+extern const struct s2n_kem_preferences kem_preferences_pq_sike_test_tls_1_0_2019_11;
+extern const struct s2n_kem_preferences kem_preferences_pq_sike_test_tls_1_0_2020_02;
+extern const struct s2n_kem_preferences kem_preferences_pq_tls_1_0_2020_12;
+
+#endif
+
+extern const struct s2n_kem_preferences kem_preferences_null;
+
+bool s2n_kem_preferences_includes_tls13_kem_group(const struct s2n_kem_preferences *kem_preferences,
+ uint16_t query_iana_id);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_kex.c b/contrib/restricted/aws/s2n/tls/s2n_kex.c
index 4b6f9e9435..d01a25faef 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_kex.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_kex.c
@@ -1,257 +1,257 @@
-/*
- * 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 "tls/s2n_kex.h"
-#include "crypto/s2n_fips.h"
-#include "tls/s2n_cipher_preferences.h"
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_client_key_exchange.h"
-#include "tls/s2n_kem.h"
-#include "tls/s2n_security_policies.h"
-#include "tls/s2n_server_key_exchange.h"
-#include "tls/s2n_tls.h"
-#include "utils/s2n_safety.h"
-
-static int s2n_check_rsa_key(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
-{
- return s2n_get_compatible_cert_chain_and_key(conn, S2N_PKEY_TYPE_RSA) != NULL;
-}
-
-static int s2n_check_dhe(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
-{
- return conn->config->dhparams != NULL;
-}
-
-static int s2n_check_ecdhe(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
-{
- return conn->secure.server_ecc_evp_params.negotiated_curve != NULL;
-}
-
-static int s2n_check_kem(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
-{
- notnull_check(conn);
- /* There is no support for PQ KEMs while in FIPS mode */
- if (s2n_is_in_fips_mode()) {
- return 0;
- }
-
- const struct s2n_kem_preferences *kem_preferences = NULL;
- GUARD(s2n_connection_get_kem_preferences(conn, &kem_preferences));
- notnull_check(kem_preferences);
-
- if (kem_preferences->kem_count == 0) {
- return 0;
- }
-
- const struct s2n_iana_to_kem *supported_params = NULL;
- /* If the cipher suite has no supported KEMs return false */
- if (s2n_cipher_suite_to_kem(cipher_suite->iana_value, &supported_params) != 0) {
- return 0;
- }
- if (supported_params->kem_count == 0) {
- return 0;
- }
-
- struct s2n_blob *client_kem_pref_list = &(conn->secure.client_pq_kem_extension);
- const struct s2n_kem *chosen_kem = NULL;
- if (client_kem_pref_list == NULL || client_kem_pref_list->data == NULL) {
- /* If the client did not send a PQ KEM extension, then the server can pick its preferred parameter */
- if (s2n_choose_kem_without_peer_pref_list(cipher_suite->iana_value, kem_preferences->kems,
- kem_preferences->kem_count, &chosen_kem)
- != 0) {
- return 0;
- }
- } else {
- /* If the client did send a PQ KEM extension, then the server must find a mutually supported parameter. */
- if (s2n_choose_kem_with_peer_pref_list(cipher_suite->iana_value, client_kem_pref_list, kem_preferences->kems,
- kem_preferences->kem_count, &chosen_kem)
- != 0) {
- return 0;
- }
- }
-
- return chosen_kem != NULL;
-}
-
-static int s2n_configure_kem(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
-{
- notnull_check(conn);
- /* There is no support for PQ KEMs while in FIPS mode */
- S2N_ERROR_IF(s2n_is_in_fips_mode(), S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS);
-
- const struct s2n_kem_preferences *kem_preferences = NULL;
- GUARD(s2n_connection_get_kem_preferences(conn, &kem_preferences));
- notnull_check(kem_preferences);
-
- struct s2n_blob *proposed_kems = &(conn->secure.client_pq_kem_extension);
- const struct s2n_kem *chosen_kem = NULL;
- if (proposed_kems == NULL || proposed_kems->data == NULL) {
- /* If the client did not send a PQ KEM extension, then the server can pick its preferred parameter */
- GUARD(s2n_choose_kem_without_peer_pref_list(cipher_suite->iana_value, kem_preferences->kems,
- kem_preferences->kem_count, &chosen_kem));
- } else {
- /* If the client did send a PQ KEM extension, then the server must find a mutually supported parameter. */
- GUARD(s2n_choose_kem_with_peer_pref_list(cipher_suite->iana_value, proposed_kems, kem_preferences->kems,
- kem_preferences->kem_count, &chosen_kem));
- }
-
- conn->secure.kem_params.kem = chosen_kem;
- return 0;
-}
-
-static int s2n_no_op_configure(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
-{
- return 0;
-}
-
-static int s2n_check_hybrid_ecdhe_kem(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
-{
- return s2n_check_ecdhe(cipher_suite, conn) && s2n_check_kem(cipher_suite, conn);
-}
-
-const struct s2n_kex s2n_kem = {
- .is_ephemeral = 1,
- .connection_supported = &s2n_check_kem,
- .configure_connection = &s2n_configure_kem,
- .server_key_recv_read_data = &s2n_kem_server_key_recv_read_data,
- .server_key_recv_parse_data = &s2n_kem_server_key_recv_parse_data,
- .server_key_send = &s2n_kem_server_key_send,
- .client_key_recv = &s2n_kem_client_key_recv,
- .client_key_send = &s2n_kem_client_key_send,
-};
-
-const struct s2n_kex s2n_rsa = {
- .is_ephemeral = 0,
- .connection_supported = &s2n_check_rsa_key,
- .configure_connection = &s2n_no_op_configure,
- .server_key_recv_read_data = NULL,
- .server_key_recv_parse_data = NULL,
- .server_key_send = NULL,
- .client_key_recv = &s2n_rsa_client_key_recv,
- .client_key_send = &s2n_rsa_client_key_send,
- .prf = &s2n_tls_prf_master_secret,
-};
-
-const struct s2n_kex s2n_dhe = {
- .is_ephemeral = 1,
- .connection_supported = &s2n_check_dhe,
- .configure_connection = &s2n_no_op_configure,
- .server_key_recv_read_data = &s2n_dhe_server_key_recv_read_data,
- .server_key_recv_parse_data = &s2n_dhe_server_key_recv_parse_data,
- .server_key_send = &s2n_dhe_server_key_send,
- .client_key_recv = &s2n_dhe_client_key_recv,
- .client_key_send = &s2n_dhe_client_key_send,
- .prf = &s2n_tls_prf_master_secret,
-};
-
-const struct s2n_kex s2n_ecdhe = {
- .is_ephemeral = 1,
- .connection_supported = &s2n_check_ecdhe,
- .configure_connection = &s2n_no_op_configure,
- .server_key_recv_read_data = &s2n_ecdhe_server_key_recv_read_data,
- .server_key_recv_parse_data = &s2n_ecdhe_server_key_recv_parse_data,
- .server_key_send = &s2n_ecdhe_server_key_send,
- .client_key_recv = &s2n_ecdhe_client_key_recv,
- .client_key_send = &s2n_ecdhe_client_key_send,
- .prf = &s2n_tls_prf_master_secret,
-};
-
-const struct s2n_kex s2n_hybrid_ecdhe_kem = {
- .is_ephemeral = 1,
- .hybrid = { &s2n_ecdhe, &s2n_kem },
- .connection_supported = &s2n_check_hybrid_ecdhe_kem,
- .configure_connection = &s2n_configure_kem,
- .server_key_recv_read_data = &s2n_hybrid_server_key_recv_read_data,
- .server_key_recv_parse_data = &s2n_hybrid_server_key_recv_parse_data,
- .server_key_send = &s2n_hybrid_server_key_send,
- .client_key_recv = &s2n_hybrid_client_key_recv,
- .client_key_send = &s2n_hybrid_client_key_send,
- .prf = &s2n_hybrid_prf_master_secret,
-};
-
-int s2n_kex_supported(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
-{
- /* Don't return -1 from notnull_check because that might allow a improperly configured kex to be marked as "supported" */
- return cipher_suite->key_exchange_alg->connection_supported != NULL && cipher_suite->key_exchange_alg->connection_supported(cipher_suite, conn);
-}
-
-int s2n_configure_kex(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
-{
- notnull_check(cipher_suite);
- notnull_check(cipher_suite->key_exchange_alg);
- notnull_check(cipher_suite->key_exchange_alg->configure_connection);
- return cipher_suite->key_exchange_alg->configure_connection(cipher_suite, conn);
-}
-
-int s2n_kex_is_ephemeral(const struct s2n_kex *kex)
-{
- notnull_check(kex);
- return kex->is_ephemeral;
-}
-
-int s2n_kex_server_key_recv_parse_data(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data)
-{
- notnull_check(kex);
- notnull_check(kex->server_key_recv_parse_data);
- return kex->server_key_recv_parse_data(conn, raw_server_data);
-}
-
-int s2n_kex_server_key_recv_read_data(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *data_to_verify, struct s2n_kex_raw_server_data *raw_server_data)
-{
- notnull_check(kex);
- notnull_check(kex->server_key_recv_read_data);
- return kex->server_key_recv_read_data(conn, data_to_verify, raw_server_data);
-}
-
-int s2n_kex_server_key_send(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *data_to_sign)
-{
- notnull_check(kex);
- notnull_check(kex->server_key_send);
- return kex->server_key_send(conn, data_to_sign);
-}
-
-int s2n_kex_client_key_recv(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *shared_key)
-{
- notnull_check(kex);
- notnull_check(kex->client_key_recv);
- return kex->client_key_recv(conn, shared_key);
-}
-
-int s2n_kex_client_key_send(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *shared_key)
-{
- notnull_check(kex);
- notnull_check(kex->client_key_send);
- return kex->client_key_send(conn, shared_key);
-}
-
-int s2n_kex_tls_prf(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *premaster_secret)
-{
- notnull_check(kex);
- notnull_check(kex->prf);
- return kex->prf(conn, premaster_secret);
-}
-
-bool s2n_kex_includes(const struct s2n_kex *kex, const struct s2n_kex *query)
-{
- if (kex == query) {
- return true;
- }
-
- if (kex == NULL || query == NULL) {
- return false;
- }
-
- return query == kex->hybrid[0] || query == kex->hybrid[1];
-}
+/*
+ * 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 "tls/s2n_kex.h"
+#include "crypto/s2n_fips.h"
+#include "tls/s2n_cipher_preferences.h"
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_client_key_exchange.h"
+#include "tls/s2n_kem.h"
+#include "tls/s2n_security_policies.h"
+#include "tls/s2n_server_key_exchange.h"
+#include "tls/s2n_tls.h"
+#include "utils/s2n_safety.h"
+
+static int s2n_check_rsa_key(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
+{
+ return s2n_get_compatible_cert_chain_and_key(conn, S2N_PKEY_TYPE_RSA) != NULL;
+}
+
+static int s2n_check_dhe(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
+{
+ return conn->config->dhparams != NULL;
+}
+
+static int s2n_check_ecdhe(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
+{
+ return conn->secure.server_ecc_evp_params.negotiated_curve != NULL;
+}
+
+static int s2n_check_kem(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
+{
+ notnull_check(conn);
+ /* There is no support for PQ KEMs while in FIPS mode */
+ if (s2n_is_in_fips_mode()) {
+ return 0;
+ }
+
+ const struct s2n_kem_preferences *kem_preferences = NULL;
+ GUARD(s2n_connection_get_kem_preferences(conn, &kem_preferences));
+ notnull_check(kem_preferences);
+
+ if (kem_preferences->kem_count == 0) {
+ return 0;
+ }
+
+ const struct s2n_iana_to_kem *supported_params = NULL;
+ /* If the cipher suite has no supported KEMs return false */
+ if (s2n_cipher_suite_to_kem(cipher_suite->iana_value, &supported_params) != 0) {
+ return 0;
+ }
+ if (supported_params->kem_count == 0) {
+ return 0;
+ }
+
+ struct s2n_blob *client_kem_pref_list = &(conn->secure.client_pq_kem_extension);
+ const struct s2n_kem *chosen_kem = NULL;
+ if (client_kem_pref_list == NULL || client_kem_pref_list->data == NULL) {
+ /* If the client did not send a PQ KEM extension, then the server can pick its preferred parameter */
+ if (s2n_choose_kem_without_peer_pref_list(cipher_suite->iana_value, kem_preferences->kems,
+ kem_preferences->kem_count, &chosen_kem)
+ != 0) {
+ return 0;
+ }
+ } else {
+ /* If the client did send a PQ KEM extension, then the server must find a mutually supported parameter. */
+ if (s2n_choose_kem_with_peer_pref_list(cipher_suite->iana_value, client_kem_pref_list, kem_preferences->kems,
+ kem_preferences->kem_count, &chosen_kem)
+ != 0) {
+ return 0;
+ }
+ }
+
+ return chosen_kem != NULL;
+}
+
+static int s2n_configure_kem(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
+{
+ notnull_check(conn);
+ /* There is no support for PQ KEMs while in FIPS mode */
+ S2N_ERROR_IF(s2n_is_in_fips_mode(), S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS);
+
+ const struct s2n_kem_preferences *kem_preferences = NULL;
+ GUARD(s2n_connection_get_kem_preferences(conn, &kem_preferences));
+ notnull_check(kem_preferences);
+
+ struct s2n_blob *proposed_kems = &(conn->secure.client_pq_kem_extension);
+ const struct s2n_kem *chosen_kem = NULL;
+ if (proposed_kems == NULL || proposed_kems->data == NULL) {
+ /* If the client did not send a PQ KEM extension, then the server can pick its preferred parameter */
+ GUARD(s2n_choose_kem_without_peer_pref_list(cipher_suite->iana_value, kem_preferences->kems,
+ kem_preferences->kem_count, &chosen_kem));
+ } else {
+ /* If the client did send a PQ KEM extension, then the server must find a mutually supported parameter. */
+ GUARD(s2n_choose_kem_with_peer_pref_list(cipher_suite->iana_value, proposed_kems, kem_preferences->kems,
+ kem_preferences->kem_count, &chosen_kem));
+ }
+
+ conn->secure.kem_params.kem = chosen_kem;
+ return 0;
+}
+
+static int s2n_no_op_configure(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
+{
+ return 0;
+}
+
+static int s2n_check_hybrid_ecdhe_kem(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
+{
+ return s2n_check_ecdhe(cipher_suite, conn) && s2n_check_kem(cipher_suite, conn);
+}
+
+const struct s2n_kex s2n_kem = {
+ .is_ephemeral = 1,
+ .connection_supported = &s2n_check_kem,
+ .configure_connection = &s2n_configure_kem,
+ .server_key_recv_read_data = &s2n_kem_server_key_recv_read_data,
+ .server_key_recv_parse_data = &s2n_kem_server_key_recv_parse_data,
+ .server_key_send = &s2n_kem_server_key_send,
+ .client_key_recv = &s2n_kem_client_key_recv,
+ .client_key_send = &s2n_kem_client_key_send,
+};
+
+const struct s2n_kex s2n_rsa = {
+ .is_ephemeral = 0,
+ .connection_supported = &s2n_check_rsa_key,
+ .configure_connection = &s2n_no_op_configure,
+ .server_key_recv_read_data = NULL,
+ .server_key_recv_parse_data = NULL,
+ .server_key_send = NULL,
+ .client_key_recv = &s2n_rsa_client_key_recv,
+ .client_key_send = &s2n_rsa_client_key_send,
+ .prf = &s2n_tls_prf_master_secret,
+};
+
+const struct s2n_kex s2n_dhe = {
+ .is_ephemeral = 1,
+ .connection_supported = &s2n_check_dhe,
+ .configure_connection = &s2n_no_op_configure,
+ .server_key_recv_read_data = &s2n_dhe_server_key_recv_read_data,
+ .server_key_recv_parse_data = &s2n_dhe_server_key_recv_parse_data,
+ .server_key_send = &s2n_dhe_server_key_send,
+ .client_key_recv = &s2n_dhe_client_key_recv,
+ .client_key_send = &s2n_dhe_client_key_send,
+ .prf = &s2n_tls_prf_master_secret,
+};
+
+const struct s2n_kex s2n_ecdhe = {
+ .is_ephemeral = 1,
+ .connection_supported = &s2n_check_ecdhe,
+ .configure_connection = &s2n_no_op_configure,
+ .server_key_recv_read_data = &s2n_ecdhe_server_key_recv_read_data,
+ .server_key_recv_parse_data = &s2n_ecdhe_server_key_recv_parse_data,
+ .server_key_send = &s2n_ecdhe_server_key_send,
+ .client_key_recv = &s2n_ecdhe_client_key_recv,
+ .client_key_send = &s2n_ecdhe_client_key_send,
+ .prf = &s2n_tls_prf_master_secret,
+};
+
+const struct s2n_kex s2n_hybrid_ecdhe_kem = {
+ .is_ephemeral = 1,
+ .hybrid = { &s2n_ecdhe, &s2n_kem },
+ .connection_supported = &s2n_check_hybrid_ecdhe_kem,
+ .configure_connection = &s2n_configure_kem,
+ .server_key_recv_read_data = &s2n_hybrid_server_key_recv_read_data,
+ .server_key_recv_parse_data = &s2n_hybrid_server_key_recv_parse_data,
+ .server_key_send = &s2n_hybrid_server_key_send,
+ .client_key_recv = &s2n_hybrid_client_key_recv,
+ .client_key_send = &s2n_hybrid_client_key_send,
+ .prf = &s2n_hybrid_prf_master_secret,
+};
+
+int s2n_kex_supported(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
+{
+ /* Don't return -1 from notnull_check because that might allow a improperly configured kex to be marked as "supported" */
+ return cipher_suite->key_exchange_alg->connection_supported != NULL && cipher_suite->key_exchange_alg->connection_supported(cipher_suite, conn);
+}
+
+int s2n_configure_kex(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
+{
+ notnull_check(cipher_suite);
+ notnull_check(cipher_suite->key_exchange_alg);
+ notnull_check(cipher_suite->key_exchange_alg->configure_connection);
+ return cipher_suite->key_exchange_alg->configure_connection(cipher_suite, conn);
+}
+
+int s2n_kex_is_ephemeral(const struct s2n_kex *kex)
+{
+ notnull_check(kex);
+ return kex->is_ephemeral;
+}
+
+int s2n_kex_server_key_recv_parse_data(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data)
+{
+ notnull_check(kex);
+ notnull_check(kex->server_key_recv_parse_data);
+ return kex->server_key_recv_parse_data(conn, raw_server_data);
+}
+
+int s2n_kex_server_key_recv_read_data(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *data_to_verify, struct s2n_kex_raw_server_data *raw_server_data)
+{
+ notnull_check(kex);
+ notnull_check(kex->server_key_recv_read_data);
+ return kex->server_key_recv_read_data(conn, data_to_verify, raw_server_data);
+}
+
+int s2n_kex_server_key_send(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *data_to_sign)
+{
+ notnull_check(kex);
+ notnull_check(kex->server_key_send);
+ return kex->server_key_send(conn, data_to_sign);
+}
+
+int s2n_kex_client_key_recv(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *shared_key)
+{
+ notnull_check(kex);
+ notnull_check(kex->client_key_recv);
+ return kex->client_key_recv(conn, shared_key);
+}
+
+int s2n_kex_client_key_send(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *shared_key)
+{
+ notnull_check(kex);
+ notnull_check(kex->client_key_send);
+ return kex->client_key_send(conn, shared_key);
+}
+
+int s2n_kex_tls_prf(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *premaster_secret)
+{
+ notnull_check(kex);
+ notnull_check(kex->prf);
+ return kex->prf(conn, premaster_secret);
+}
+
+bool s2n_kex_includes(const struct s2n_kex *kex, const struct s2n_kex *query)
+{
+ if (kex == query) {
+ return true;
+ }
+
+ if (kex == NULL || query == NULL) {
+ return false;
+ }
+
+ return query == kex->hybrid[0] || query == kex->hybrid[1];
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_kex.h b/contrib/restricted/aws/s2n/tls/s2n_kex.h
index f168df5384..587cde5d63 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_kex.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_kex.h
@@ -1,55 +1,55 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <stdint.h>
-#include "tls/s2n_connection.h"
-#include "tls/s2n_kex_data.h"
-
-struct s2n_kex {
- uint8_t is_ephemeral;
- const struct s2n_kex *hybrid[2];
-
- int (*connection_supported)(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn);
- int (*configure_connection)(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn);
- int (*server_key_recv_read_data)(struct s2n_connection *conn, struct s2n_blob *data_to_verify, struct s2n_kex_raw_server_data *kex_data);
- int (*server_key_recv_parse_data)(struct s2n_connection *conn, struct s2n_kex_raw_server_data *kex_data);
- int (*server_key_send)(struct s2n_connection *conn, struct s2n_blob *data_to_sign);
- int (*client_key_recv)(struct s2n_connection *conn, struct s2n_blob *shared_key);
- int (*client_key_send)(struct s2n_connection *conn, struct s2n_blob *shared_key);
- int (*prf)(struct s2n_connection *conn, struct s2n_blob *premaster_secret);
-};
-
-extern const struct s2n_kex s2n_kem;
-extern const struct s2n_kex s2n_rsa;
-extern const struct s2n_kex s2n_dhe;
-extern const struct s2n_kex s2n_ecdhe;
-extern const struct s2n_kex s2n_hybrid_ecdhe_kem;
-
-extern int s2n_kex_supported(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn);
-extern int s2n_configure_kex(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn);
-extern int s2n_kex_is_ephemeral(const struct s2n_kex *kex);
-
-extern int s2n_kex_server_key_recv_read_data(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *data_to_verify,
- struct s2n_kex_raw_server_data *raw_server_data);
-extern int s2n_kex_server_key_recv_parse_data(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data);
-extern int s2n_kex_server_key_send(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *data_to_sign);
-extern int s2n_kex_client_key_recv(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *shared_key);
-extern int s2n_kex_client_key_send(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *shared_key);
-
-extern int s2n_kex_tls_prf(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *premaster_secret);
-
-extern bool s2n_kex_includes(const struct s2n_kex *kex, const struct s2n_kex *query);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include "tls/s2n_connection.h"
+#include "tls/s2n_kex_data.h"
+
+struct s2n_kex {
+ uint8_t is_ephemeral;
+ const struct s2n_kex *hybrid[2];
+
+ int (*connection_supported)(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn);
+ int (*configure_connection)(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn);
+ int (*server_key_recv_read_data)(struct s2n_connection *conn, struct s2n_blob *data_to_verify, struct s2n_kex_raw_server_data *kex_data);
+ int (*server_key_recv_parse_data)(struct s2n_connection *conn, struct s2n_kex_raw_server_data *kex_data);
+ int (*server_key_send)(struct s2n_connection *conn, struct s2n_blob *data_to_sign);
+ int (*client_key_recv)(struct s2n_connection *conn, struct s2n_blob *shared_key);
+ int (*client_key_send)(struct s2n_connection *conn, struct s2n_blob *shared_key);
+ int (*prf)(struct s2n_connection *conn, struct s2n_blob *premaster_secret);
+};
+
+extern const struct s2n_kex s2n_kem;
+extern const struct s2n_kex s2n_rsa;
+extern const struct s2n_kex s2n_dhe;
+extern const struct s2n_kex s2n_ecdhe;
+extern const struct s2n_kex s2n_hybrid_ecdhe_kem;
+
+extern int s2n_kex_supported(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn);
+extern int s2n_configure_kex(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn);
+extern int s2n_kex_is_ephemeral(const struct s2n_kex *kex);
+
+extern int s2n_kex_server_key_recv_read_data(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *data_to_verify,
+ struct s2n_kex_raw_server_data *raw_server_data);
+extern int s2n_kex_server_key_recv_parse_data(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data);
+extern int s2n_kex_server_key_send(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *data_to_sign);
+extern int s2n_kex_client_key_recv(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *shared_key);
+extern int s2n_kex_client_key_send(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *shared_key);
+
+extern int s2n_kex_tls_prf(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *premaster_secret);
+
+extern bool s2n_kex_includes(const struct s2n_kex *kex, const struct s2n_kex *query);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_kex_data.h b/contrib/restricted/aws/s2n/tls/s2n_kex_data.h
index 9a202d3da6..425f427a27 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_kex_data.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_kex_data.h
@@ -1,40 +1,40 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "utils/s2n_blob.h"
-
-struct s2n_ecdhe_raw_server_params {
- struct s2n_blob point_blob;
- struct s2n_blob curve_blob;
-};
-
-struct s2n_dhe_raw_server_points {
- struct s2n_blob p;
- struct s2n_blob g;
- struct s2n_blob Ys;
-};
-
-struct s2n_kem_raw_server_params {
- struct s2n_blob kem_name;
- struct s2n_blob raw_public_key;
-};
-
-struct s2n_kex_raw_server_data {
- struct s2n_ecdhe_raw_server_params ecdhe_data;
- struct s2n_dhe_raw_server_points dhe_data;
- struct s2n_kem_raw_server_params kem_data;
-};
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "utils/s2n_blob.h"
+
+struct s2n_ecdhe_raw_server_params {
+ struct s2n_blob point_blob;
+ struct s2n_blob curve_blob;
+};
+
+struct s2n_dhe_raw_server_points {
+ struct s2n_blob p;
+ struct s2n_blob g;
+ struct s2n_blob Ys;
+};
+
+struct s2n_kem_raw_server_params {
+ struct s2n_blob kem_name;
+ struct s2n_blob raw_public_key;
+};
+
+struct s2n_kex_raw_server_data {
+ struct s2n_ecdhe_raw_server_params ecdhe_data;
+ struct s2n_dhe_raw_server_points dhe_data;
+ struct s2n_kem_raw_server_params kem_data;
+};
diff --git a/contrib/restricted/aws/s2n/tls/s2n_key_update.c b/contrib/restricted/aws/s2n/tls/s2n_key_update.c
index 02e5cf9978..6f63e02b38 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_key_update.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_key_update.c
@@ -1,115 +1,115 @@
-/*
- * 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 "error/s2n_errno.h"
-
-#include "tls/s2n_connection.h"
-#include "tls/s2n_key_update.h"
-#include "tls/s2n_tls13_handshake.h"
-#include "tls/s2n_record.h"
-
-#include "crypto/s2n_sequence.h"
-
-#include "utils/s2n_safety.h"
-
-int s2n_key_update_write(struct s2n_blob *out);
-int s2n_check_record_limit(struct s2n_connection *conn, struct s2n_blob *sequence_number);
-
-
-int s2n_key_update_recv(struct s2n_connection *conn, struct s2n_stuffer *request)
-{
- notnull_check(conn);
- ENSURE_POSIX(!conn->config->quic_enabled, S2N_ERR_BAD_MESSAGE);
-
- uint8_t key_update_request;
- GUARD(s2n_stuffer_read_uint8(request, &key_update_request));
- S2N_ERROR_IF(key_update_request != S2N_KEY_UPDATE_NOT_REQUESTED && key_update_request != S2N_KEY_UPDATE_REQUESTED,
- S2N_ERR_BAD_MESSAGE);
- conn->key_update_pending = key_update_request;
-
- /* Update peer's key since a key_update was received */
- if (conn->mode == S2N_CLIENT){
- GUARD(s2n_update_application_traffic_keys(conn, S2N_SERVER, RECEIVING));
- } else {
- GUARD(s2n_update_application_traffic_keys(conn, S2N_CLIENT, RECEIVING));
- }
-
- return S2N_SUCCESS;
-}
-
-int s2n_key_update_send(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- struct s2n_blob sequence_number = {0};
- if (conn->mode == S2N_CLIENT) {
- GUARD(s2n_blob_init(&sequence_number, conn->secure.client_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
- } else {
- GUARD(s2n_blob_init(&sequence_number, conn->secure.server_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
- }
-
- GUARD(s2n_check_record_limit(conn, &sequence_number));
-
- if (conn->key_update_pending) {
- uint8_t key_update_data[S2N_KEY_UPDATE_MESSAGE_SIZE];
- struct s2n_blob key_update_blob = {0};
- GUARD(s2n_blob_init(&key_update_blob, key_update_data, sizeof(key_update_data)));
-
- /* Write key update message */
- GUARD(s2n_key_update_write(&key_update_blob));
-
- /* Encrypt the message */
- GUARD(s2n_record_write(conn, TLS_HANDSHAKE, &key_update_blob));
-
- /* Update encryption key */
- GUARD(s2n_update_application_traffic_keys(conn, conn->mode, SENDING));
- conn->key_update_pending = false;
- }
-
- return S2N_SUCCESS;
-}
-
-int s2n_key_update_write(struct s2n_blob *out)
-{
- notnull_check(out);
-
- struct s2n_stuffer key_update_stuffer = {0};
- GUARD(s2n_stuffer_init(&key_update_stuffer, out));
- GUARD(s2n_stuffer_write_uint8(&key_update_stuffer, TLS_KEY_UPDATE));
- GUARD(s2n_stuffer_write_uint24(&key_update_stuffer, S2N_KEY_UPDATE_LENGTH));
-
- /* s2n currently does not require peers to update their encryption keys. */
- GUARD(s2n_stuffer_write_uint8(&key_update_stuffer, S2N_KEY_UPDATE_NOT_REQUESTED));
-
- return S2N_SUCCESS;
-}
-
-int s2n_check_record_limit(struct s2n_connection *conn, struct s2n_blob *sequence_number)
-{
- notnull_check(conn);
- notnull_check(sequence_number);
- notnull_check(conn->secure.cipher_suite);
- notnull_check(conn->secure.cipher_suite->record_alg);
-
- uint64_t output = 0;
- GUARD(s2n_sequence_number_to_uint64(sequence_number, &output));
-
- if (output + 1 > conn->secure.cipher_suite->record_alg->encryption_limit) {
- conn->key_update_pending = true;
- }
-
- return S2N_SUCCESS;
-}
-
+/*
+ * 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 "error/s2n_errno.h"
+
+#include "tls/s2n_connection.h"
+#include "tls/s2n_key_update.h"
+#include "tls/s2n_tls13_handshake.h"
+#include "tls/s2n_record.h"
+
+#include "crypto/s2n_sequence.h"
+
+#include "utils/s2n_safety.h"
+
+int s2n_key_update_write(struct s2n_blob *out);
+int s2n_check_record_limit(struct s2n_connection *conn, struct s2n_blob *sequence_number);
+
+
+int s2n_key_update_recv(struct s2n_connection *conn, struct s2n_stuffer *request)
+{
+ notnull_check(conn);
+ ENSURE_POSIX(!conn->config->quic_enabled, S2N_ERR_BAD_MESSAGE);
+
+ uint8_t key_update_request;
+ GUARD(s2n_stuffer_read_uint8(request, &key_update_request));
+ S2N_ERROR_IF(key_update_request != S2N_KEY_UPDATE_NOT_REQUESTED && key_update_request != S2N_KEY_UPDATE_REQUESTED,
+ S2N_ERR_BAD_MESSAGE);
+ conn->key_update_pending = key_update_request;
+
+ /* Update peer's key since a key_update was received */
+ if (conn->mode == S2N_CLIENT){
+ GUARD(s2n_update_application_traffic_keys(conn, S2N_SERVER, RECEIVING));
+ } else {
+ GUARD(s2n_update_application_traffic_keys(conn, S2N_CLIENT, RECEIVING));
+ }
+
+ return S2N_SUCCESS;
+}
+
+int s2n_key_update_send(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ struct s2n_blob sequence_number = {0};
+ if (conn->mode == S2N_CLIENT) {
+ GUARD(s2n_blob_init(&sequence_number, conn->secure.client_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
+ } else {
+ GUARD(s2n_blob_init(&sequence_number, conn->secure.server_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
+ }
+
+ GUARD(s2n_check_record_limit(conn, &sequence_number));
+
+ if (conn->key_update_pending) {
+ uint8_t key_update_data[S2N_KEY_UPDATE_MESSAGE_SIZE];
+ struct s2n_blob key_update_blob = {0};
+ GUARD(s2n_blob_init(&key_update_blob, key_update_data, sizeof(key_update_data)));
+
+ /* Write key update message */
+ GUARD(s2n_key_update_write(&key_update_blob));
+
+ /* Encrypt the message */
+ GUARD(s2n_record_write(conn, TLS_HANDSHAKE, &key_update_blob));
+
+ /* Update encryption key */
+ GUARD(s2n_update_application_traffic_keys(conn, conn->mode, SENDING));
+ conn->key_update_pending = false;
+ }
+
+ return S2N_SUCCESS;
+}
+
+int s2n_key_update_write(struct s2n_blob *out)
+{
+ notnull_check(out);
+
+ struct s2n_stuffer key_update_stuffer = {0};
+ GUARD(s2n_stuffer_init(&key_update_stuffer, out));
+ GUARD(s2n_stuffer_write_uint8(&key_update_stuffer, TLS_KEY_UPDATE));
+ GUARD(s2n_stuffer_write_uint24(&key_update_stuffer, S2N_KEY_UPDATE_LENGTH));
+
+ /* s2n currently does not require peers to update their encryption keys. */
+ GUARD(s2n_stuffer_write_uint8(&key_update_stuffer, S2N_KEY_UPDATE_NOT_REQUESTED));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_check_record_limit(struct s2n_connection *conn, struct s2n_blob *sequence_number)
+{
+ notnull_check(conn);
+ notnull_check(sequence_number);
+ notnull_check(conn->secure.cipher_suite);
+ notnull_check(conn->secure.cipher_suite->record_alg);
+
+ uint64_t output = 0;
+ GUARD(s2n_sequence_number_to_uint64(sequence_number, &output));
+
+ if (output + 1 > conn->secure.cipher_suite->record_alg->encryption_limit) {
+ conn->key_update_pending = true;
+ }
+
+ return S2N_SUCCESS;
+}
+
diff --git a/contrib/restricted/aws/s2n/tls/s2n_key_update.h b/contrib/restricted/aws/s2n/tls/s2n_key_update.h
index 2eaa69a5f8..20ac48411c 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_key_update.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_key_update.h
@@ -1,34 +1,34 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/s2n_connection.h"
-
-#define S2N_KEY_UPDATE_MESSAGE_SIZE 5
-#define S2N_KEY_UPDATE_LENGTH 1
-
-typedef enum {
- SENDING=0,
- RECEIVING
-} keyupdate_status;
-
-typedef enum {
- S2N_KEY_UPDATE_NOT_REQUESTED=0,
- S2N_KEY_UPDATE_REQUESTED
-} keyupdate_request;
-
-int s2n_key_update_recv(struct s2n_connection *conn, struct s2n_stuffer *request);
-int s2n_key_update_send(struct s2n_connection *conn);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/s2n_connection.h"
+
+#define S2N_KEY_UPDATE_MESSAGE_SIZE 5
+#define S2N_KEY_UPDATE_LENGTH 1
+
+typedef enum {
+ SENDING=0,
+ RECEIVING
+} keyupdate_status;
+
+typedef enum {
+ S2N_KEY_UPDATE_NOT_REQUESTED=0,
+ S2N_KEY_UPDATE_REQUESTED
+} keyupdate_request;
+
+int s2n_key_update_recv(struct s2n_connection *conn, struct s2n_stuffer *request);
+int s2n_key_update_send(struct s2n_connection *conn);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_ocsp_stapling.c b/contrib/restricted/aws/s2n/tls/s2n_ocsp_stapling.c
index f04b7b40e4..7ad96a4d31 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_ocsp_stapling.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_ocsp_stapling.c
@@ -1,40 +1,40 @@
-/*
- * 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 <strings.h>
-
-#include "error/s2n_errno.h"
-
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_config.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_x509_validator.h"
-#include "tls/extensions/s2n_server_certificate_status.h"
-#include "utils/s2n_safety.h"
-
-int s2n_server_status_send(struct s2n_connection *conn)
-{
- if (s2n_server_can_send_ocsp(conn)) {
- GUARD(s2n_server_certificate_status_send(conn, &conn->handshake.io));
- }
-
- return 0;
-}
-
-int s2n_server_status_recv(struct s2n_connection *conn)
-{
- return s2n_server_certificate_status_recv(conn, &conn->handshake.io);
-}
+/*
+ * 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 <strings.h>
+
+#include "error/s2n_errno.h"
+
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_config.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_x509_validator.h"
+#include "tls/extensions/s2n_server_certificate_status.h"
+#include "utils/s2n_safety.h"
+
+int s2n_server_status_send(struct s2n_connection *conn)
+{
+ if (s2n_server_can_send_ocsp(conn)) {
+ GUARD(s2n_server_certificate_status_send(conn, &conn->handshake.io));
+ }
+
+ return 0;
+}
+
+int s2n_server_status_recv(struct s2n_connection *conn)
+{
+ return s2n_server_certificate_status_recv(conn, &conn->handshake.io);
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_post_handshake.c b/contrib/restricted/aws/s2n/tls/s2n_post_handshake.c
index d5ba4ab672..34594576db 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_post_handshake.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_post_handshake.c
@@ -1,69 +1,69 @@
-/*
- * 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 "error/s2n_errno.h"
-
-#include "tls/s2n_connection.h"
-#include "tls/s2n_key_update.h"
-#include "tls/s2n_tls.h"
-#include "utils/s2n_safety.h"
-
-/* TLS 1.3 introducted several post handshake messages. This function currently only
- * supports parsing for the KeyUpdate message. Once the other post-handshake messages
- * have been implemented, this function can be altered to include the other messages.
- */
-int s2n_post_handshake_recv(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- uint8_t post_handshake_id;
- uint32_t message_length;
- S2N_ERROR_IF(conn->actual_protocol_version != S2N_TLS13, S2N_ERR_BAD_MESSAGE);
-
- GUARD(s2n_stuffer_read_uint8(&conn->in, &post_handshake_id));
- GUARD(s2n_stuffer_read_uint24(&conn->in, &message_length));
-
- struct s2n_blob post_handshake_blob = {0};
- uint8_t *message_data = s2n_stuffer_raw_read(&conn->in, message_length);
- notnull_check(message_data);
- GUARD(s2n_blob_init(&post_handshake_blob, message_data, message_length));
-
- struct s2n_stuffer post_handshake_stuffer = {0};
- GUARD(s2n_stuffer_init(&post_handshake_stuffer, &post_handshake_blob));
- GUARD(s2n_stuffer_skip_write(&post_handshake_stuffer, message_length));
-
- switch (post_handshake_id)
- {
- case TLS_KEY_UPDATE:
- GUARD(s2n_key_update_recv(conn, &post_handshake_stuffer));
- break;
- default:
- /* Ignore all other messages */
- break;
- }
-
- return S2N_SUCCESS;
-}
-
-int s2n_post_handshake_send(struct s2n_connection *conn, s2n_blocked_status *blocked)
-{
- notnull_check(conn);
-
- GUARD(s2n_key_update_send(conn));
- GUARD(s2n_flush(conn, blocked));
- GUARD(s2n_stuffer_rewrite(&conn->out));
-
- return S2N_SUCCESS;
-}
+/*
+ * 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 "error/s2n_errno.h"
+
+#include "tls/s2n_connection.h"
+#include "tls/s2n_key_update.h"
+#include "tls/s2n_tls.h"
+#include "utils/s2n_safety.h"
+
+/* TLS 1.3 introducted several post handshake messages. This function currently only
+ * supports parsing for the KeyUpdate message. Once the other post-handshake messages
+ * have been implemented, this function can be altered to include the other messages.
+ */
+int s2n_post_handshake_recv(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ uint8_t post_handshake_id;
+ uint32_t message_length;
+ S2N_ERROR_IF(conn->actual_protocol_version != S2N_TLS13, S2N_ERR_BAD_MESSAGE);
+
+ GUARD(s2n_stuffer_read_uint8(&conn->in, &post_handshake_id));
+ GUARD(s2n_stuffer_read_uint24(&conn->in, &message_length));
+
+ struct s2n_blob post_handshake_blob = {0};
+ uint8_t *message_data = s2n_stuffer_raw_read(&conn->in, message_length);
+ notnull_check(message_data);
+ GUARD(s2n_blob_init(&post_handshake_blob, message_data, message_length));
+
+ struct s2n_stuffer post_handshake_stuffer = {0};
+ GUARD(s2n_stuffer_init(&post_handshake_stuffer, &post_handshake_blob));
+ GUARD(s2n_stuffer_skip_write(&post_handshake_stuffer, message_length));
+
+ switch (post_handshake_id)
+ {
+ case TLS_KEY_UPDATE:
+ GUARD(s2n_key_update_recv(conn, &post_handshake_stuffer));
+ break;
+ default:
+ /* Ignore all other messages */
+ break;
+ }
+
+ return S2N_SUCCESS;
+}
+
+int s2n_post_handshake_send(struct s2n_connection *conn, s2n_blocked_status *blocked)
+{
+ notnull_check(conn);
+
+ GUARD(s2n_key_update_send(conn));
+ GUARD(s2n_flush(conn, blocked));
+ GUARD(s2n_stuffer_rewrite(&conn->out));
+
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_post_handshake.h b/contrib/restricted/aws/s2n/tls/s2n_post_handshake.h
index b2c646c367..f021f7afb5 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_post_handshake.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_post_handshake.h
@@ -1,21 +1,21 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/s2n_connection.h"
-
-int s2n_post_handshake_recv(struct s2n_connection *conn);
-int s2n_post_handshake_send(struct s2n_connection *conn, s2n_blocked_status *blocked);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/s2n_connection.h"
+
+int s2n_post_handshake_recv(struct s2n_connection *conn);
+int s2n_post_handshake_send(struct s2n_connection *conn, s2n_blocked_status *blocked);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_prf.c b/contrib/restricted/aws/s2n/tls/s2n_prf.c
index ebf6273880..fbfffb5fad 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_prf.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_prf.c
@@ -1,692 +1,692 @@
-/*
- * 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 <sys/param.h>
-#include <openssl/md5.h>
-#include <openssl/sha.h>
-#include <string.h>
-
-#include "error/s2n_errno.h"
-
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_prf.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "crypto/s2n_hmac.h"
-#include "crypto/s2n_hash.h"
-#include "crypto/s2n_openssl.h"
-#include "crypto/s2n_fips.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_blob.h"
-#include "utils/s2n_mem.h"
-
-static int s2n_sslv3_prf(struct s2n_prf_working_space *ws, struct s2n_blob *secret, struct s2n_blob *seed_a,
- struct s2n_blob *seed_b, struct s2n_blob *seed_c, struct s2n_blob *out)
-{
- struct s2n_hash_state *md5 = &ws->ssl3.md5;
- struct s2n_hash_state *sha1 = &ws->ssl3.sha1;
-
- uint32_t outputlen = out->size;
- uint8_t *output = out->data;
- uint8_t iteration = 1;
-
- uint8_t A = 'A';
- while (outputlen) {
- GUARD(s2n_hash_reset(sha1));
-
- for (int i = 0; i < iteration; i++) {
- GUARD(s2n_hash_update(sha1, &A, 1));
- }
-
- GUARD(s2n_hash_update(sha1, secret->data, secret->size));
- GUARD(s2n_hash_update(sha1, seed_a->data, seed_a->size));
-
- if (seed_b) {
- GUARD(s2n_hash_update(sha1, seed_b->data, seed_b->size));
- if (seed_c) {
- GUARD(s2n_hash_update(sha1, seed_c->data, seed_c->size));
- }
- }
-
- GUARD(s2n_hash_digest(sha1, ws->ssl3.sha1_digest, sizeof(ws->ssl3.sha1_digest)));
-
- GUARD(s2n_hash_reset(md5));
- GUARD(s2n_hash_update(md5, secret->data, secret->size));
- GUARD(s2n_hash_update(md5, ws->ssl3.sha1_digest, sizeof(ws->ssl3.sha1_digest)));
- GUARD(s2n_hash_digest(md5, ws->ssl3.md5_digest, sizeof(ws->ssl3.md5_digest)));
-
- uint32_t bytes_to_copy = MIN(outputlen, sizeof(ws->ssl3.md5_digest));
-
- memcpy_check(output, ws->ssl3.md5_digest, bytes_to_copy);
-
- outputlen -= bytes_to_copy;
- output += bytes_to_copy;
-
- /* Increment the letter */
- A++;
- iteration++;
- }
-
- GUARD(s2n_hash_reset(md5));
- GUARD(s2n_hash_reset(sha1));
-
- return 0;
-}
-
-#if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
-static int s2n_evp_hmac_p_hash_new(struct s2n_prf_working_space *ws)
-{
- notnull_check(ws->tls.p_hash.evp_hmac.evp_digest.ctx = S2N_EVP_MD_CTX_NEW());
- return 0;
-}
-
-static int s2n_evp_hmac_p_hash_digest_init(struct s2n_prf_working_space *ws)
-{
- notnull_check(ws->tls.p_hash.evp_hmac.evp_digest.md);
- notnull_check(ws->tls.p_hash.evp_hmac.evp_digest.ctx);
- notnull_check(ws->tls.p_hash.evp_hmac.mac_key);
-
- /* Ignore the MD5 check when in FIPS mode to comply with the TLS 1.0 RFC */
- if (s2n_is_in_fips_mode()) {
- GUARD(s2n_digest_allow_md5_for_fips(&ws->tls.p_hash.evp_hmac.evp_digest));
- }
-
- GUARD_OSSL(EVP_DigestSignInit(ws->tls.p_hash.evp_hmac.evp_digest.ctx, NULL, ws->tls.p_hash.evp_hmac.evp_digest.md, NULL, ws->tls.p_hash.evp_hmac.mac_key),
- S2N_ERR_P_HASH_INIT_FAILED);
-
- return 0;
-}
-
-static int s2n_evp_hmac_p_hash_init(struct s2n_prf_working_space *ws, s2n_hmac_algorithm alg, struct s2n_blob *secret)
-{
- /* Initialize the message digest */
- switch (alg) {
- case S2N_HMAC_SSLv3_MD5:
- case S2N_HMAC_MD5:
- ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_md5();
- break;
- case S2N_HMAC_SSLv3_SHA1:
- case S2N_HMAC_SHA1:
- ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha1();
- break;
- case S2N_HMAC_SHA224:
- ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha224();
- break;
- case S2N_HMAC_SHA256:
- ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha256();
- break;
- case S2N_HMAC_SHA384:
- ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha384();
- break;
- case S2N_HMAC_SHA512:
- ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha512();
- break;
- default:
- S2N_ERROR(S2N_ERR_P_HASH_INVALID_ALGORITHM);
- }
-
- /* Initialize the mac key using the provided secret */
- notnull_check(ws->tls.p_hash.evp_hmac.mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, secret->data, secret->size));
-
- /* Initialize the message digest context with the above message digest and mac key */
- return s2n_evp_hmac_p_hash_digest_init(ws);
-}
-
-static int s2n_evp_hmac_p_hash_update(struct s2n_prf_working_space *ws, const void *data, uint32_t size)
-{
- GUARD_OSSL(EVP_DigestSignUpdate(ws->tls.p_hash.evp_hmac.evp_digest.ctx, data, (size_t)size), S2N_ERR_P_HASH_UPDATE_FAILED);
-
- return 0;
-}
-
-static int s2n_evp_hmac_p_hash_digest(struct s2n_prf_working_space *ws, void *digest, uint32_t size)
-{
- /* EVP_DigestSign API's require size_t data structures */
- size_t digest_size = size;
-
- GUARD_OSSL(EVP_DigestSignFinal(ws->tls.p_hash.evp_hmac.evp_digest.ctx, (unsigned char *)digest, &digest_size), S2N_ERR_P_HASH_FINAL_FAILED);
-
- return 0;
-}
-
-static int s2n_evp_hmac_p_hash_wipe(struct s2n_prf_working_space *ws)
-{
- GUARD_OSSL(S2N_EVP_MD_CTX_RESET(ws->tls.p_hash.evp_hmac.evp_digest.ctx), S2N_ERR_P_HASH_WIPE_FAILED);
-
- return 0;
-}
-
-static int s2n_evp_hmac_p_hash_reset(struct s2n_prf_working_space *ws)
-{
- GUARD(s2n_evp_hmac_p_hash_wipe(ws));
-
- return s2n_evp_hmac_p_hash_digest_init(ws);
-}
-
-static int s2n_evp_hmac_p_hash_cleanup(struct s2n_prf_working_space *ws)
-{
- /* Prepare the workspace md_ctx for the next p_hash */
- GUARD(s2n_evp_hmac_p_hash_wipe(ws));
-
- /* Free mac key - PKEYs cannot be reused */
- notnull_check(ws->tls.p_hash.evp_hmac.mac_key);
- EVP_PKEY_free(ws->tls.p_hash.evp_hmac.mac_key);
- ws->tls.p_hash.evp_hmac.mac_key = NULL;
-
- return 0;
-}
-
-static int s2n_evp_hmac_p_hash_free(struct s2n_prf_working_space *ws)
-{
- notnull_check(ws->tls.p_hash.evp_hmac.evp_digest.ctx);
- S2N_EVP_MD_CTX_FREE(ws->tls.p_hash.evp_hmac.evp_digest.ctx);
- ws->tls.p_hash.evp_hmac.evp_digest.ctx = NULL;
-
- return 0;
-}
-
-static const struct s2n_p_hash_hmac s2n_evp_hmac = {
- .alloc = &s2n_evp_hmac_p_hash_new,
- .init = &s2n_evp_hmac_p_hash_init,
- .update = &s2n_evp_hmac_p_hash_update,
- .final = &s2n_evp_hmac_p_hash_digest,
- .reset = &s2n_evp_hmac_p_hash_reset,
- .cleanup = &s2n_evp_hmac_p_hash_cleanup,
- .free = &s2n_evp_hmac_p_hash_free,
-};
-#endif /* !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC) */
-
-static int s2n_hmac_p_hash_new(struct s2n_prf_working_space *ws)
-{
- GUARD(s2n_hmac_new(&ws->tls.p_hash.s2n_hmac));
-
- return s2n_hmac_init(&ws->tls.p_hash.s2n_hmac, S2N_HMAC_NONE, NULL, 0);
-}
-
-static int s2n_hmac_p_hash_init(struct s2n_prf_working_space *ws, s2n_hmac_algorithm alg, struct s2n_blob *secret)
-{
- return s2n_hmac_init(&ws->tls.p_hash.s2n_hmac, alg, secret->data, secret->size);
-}
-
-static int s2n_hmac_p_hash_update(struct s2n_prf_working_space *ws, const void *data, uint32_t size)
-{
- return s2n_hmac_update(&ws->tls.p_hash.s2n_hmac, data, size);
-}
-
-static int s2n_hmac_p_hash_digest(struct s2n_prf_working_space *ws, void *digest, uint32_t size)
-{
- return s2n_hmac_digest(&ws->tls.p_hash.s2n_hmac, digest, size);
-}
-
-static int s2n_hmac_p_hash_reset(struct s2n_prf_working_space *ws)
-{
- return s2n_hmac_reset(&ws->tls.p_hash.s2n_hmac);
-}
-
-static int s2n_hmac_p_hash_cleanup(struct s2n_prf_working_space *ws)
-{
- return s2n_hmac_p_hash_reset(ws);
-}
-
-static int s2n_hmac_p_hash_free(struct s2n_prf_working_space *ws)
-{
- return s2n_hmac_free(&ws->tls.p_hash.s2n_hmac);
-}
-
-static const struct s2n_p_hash_hmac s2n_hmac = {
- .alloc = &s2n_hmac_p_hash_new,
- .init = &s2n_hmac_p_hash_init,
- .update = &s2n_hmac_p_hash_update,
- .final = &s2n_hmac_p_hash_digest,
- .reset = &s2n_hmac_p_hash_reset,
- .cleanup = &s2n_hmac_p_hash_cleanup,
- .free = &s2n_hmac_p_hash_free,
-};
-
-static int s2n_p_hash(struct s2n_prf_working_space *ws, s2n_hmac_algorithm alg, struct s2n_blob *secret, struct s2n_blob *label,
- struct s2n_blob *seed_a, struct s2n_blob *seed_b, struct s2n_blob *seed_c, struct s2n_blob *out)
-{
- uint8_t digest_size;
- GUARD(s2n_hmac_digest_size(alg, &digest_size));
-
- const struct s2n_p_hash_hmac *hmac = ws->tls.p_hash_hmac_impl;
-
- /* First compute hmac(secret + A(0)) */
- GUARD(hmac->init(ws, alg, secret));
- GUARD(hmac->update(ws, label->data, label->size));
- GUARD(hmac->update(ws, seed_a->data, seed_a->size));
-
- if (seed_b) {
- GUARD(hmac->update(ws, seed_b->data, seed_b->size));
- if (seed_c) {
- GUARD(hmac->update(ws, seed_c->data, seed_c->size));
- }
- }
- GUARD(hmac->final(ws, ws->tls.digest0, digest_size));
-
- uint32_t outputlen = out->size;
- uint8_t *output = out->data;
-
- while (outputlen) {
- /* Now compute hmac(secret + A(N - 1) + seed) */
- GUARD(hmac->reset(ws));
- GUARD(hmac->update(ws, ws->tls.digest0, digest_size));
-
- /* Add the label + seed and compute this round's A */
- GUARD(hmac->update(ws, label->data, label->size));
- GUARD(hmac->update(ws, seed_a->data, seed_a->size));
- if (seed_b) {
- GUARD(hmac->update(ws, seed_b->data, seed_b->size));
- if (seed_c) {
- GUARD(hmac->update(ws, seed_c->data, seed_c->size));
- }
- }
-
- GUARD(hmac->final(ws, ws->tls.digest1, digest_size));
-
- uint32_t bytes_to_xor = MIN(outputlen, digest_size);
-
- for (int i = 0; i < bytes_to_xor; i++) {
- *output ^= ws->tls.digest1[i];
- output++;
- outputlen--;
- }
-
- /* Stash a digest of A(N), in A(N), for the next round */
- GUARD(hmac->reset(ws));
- GUARD(hmac->update(ws, ws->tls.digest0, digest_size));
- GUARD(hmac->final(ws, ws->tls.digest0, digest_size));
- }
-
- GUARD(hmac->cleanup(ws));
-
- return 0;
-}
-
-const struct s2n_p_hash_hmac *s2n_get_hmac_implementation() {
-#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
- return &s2n_hmac;
-#else
- return s2n_is_in_fips_mode() ? &s2n_evp_hmac : &s2n_hmac;
-#endif
-}
-
-int s2n_prf_new(struct s2n_connection *conn)
-{
- /* Set p_hash_hmac_impl on initial prf creation.
- * When in FIPS mode, the EVP API's must be used for the p_hash HMAC.
- */
- conn->prf_space.tls.p_hash_hmac_impl = s2n_get_hmac_implementation();
-
- return conn->prf_space.tls.p_hash_hmac_impl->alloc(&conn->prf_space);
-}
-
-int s2n_prf_free(struct s2n_connection *conn)
-{
- /* Ensure that p_hash_hmac_impl is set, as it may have been reset for prf_space on s2n_connection_wipe.
- * When in FIPS mode, the EVP API's must be used for the p_hash HMAC.
- */
- conn->prf_space.tls.p_hash_hmac_impl = s2n_get_hmac_implementation();
-
- return conn->prf_space.tls.p_hash_hmac_impl->free(&conn->prf_space);
-}
-
-static int s2n_prf(struct s2n_connection *conn, struct s2n_blob *secret, struct s2n_blob *label, struct s2n_blob *seed_a,
- struct s2n_blob *seed_b, struct s2n_blob *seed_c, struct s2n_blob *out)
-{
- /* seed_a is always required, seed_b is optional, if seed_c is provided seed_b must also be provided */
- S2N_ERROR_IF(seed_a == NULL, S2N_ERR_PRF_INVALID_SEED);
- S2N_ERROR_IF(seed_b == NULL && seed_c != NULL, S2N_ERR_PRF_INVALID_SEED);
-
- if (conn->actual_protocol_version == S2N_SSLv3) {
- return s2n_sslv3_prf(&conn->prf_space, secret, seed_a, seed_b, seed_c, out);
- }
-
- /* We zero the out blob because p_hash works by XOR'ing with the existing
- * buffer. This is a little convoluted but means we can avoid dynamic memory
- * allocation. When we call p_hash once (in the TLS1.2 case) it will produce
- * the right values. When we call it twice in the regular case, the two
- * outputs will be XORd just ass the TLS 1.0 and 1.1 RFCs require.
- */
- GUARD(s2n_blob_zero(out));
-
- /* Ensure that p_hash_hmac_impl is set, as it may have been reset for prf_space on s2n_connection_wipe.
- * When in FIPS mode, the EVP API's must be used for the p_hash HMAC.
- */
- conn->prf_space.tls.p_hash_hmac_impl = s2n_get_hmac_implementation();
-
- if (conn->actual_protocol_version == S2N_TLS12) {
- return s2n_p_hash(&conn->prf_space, conn->secure.cipher_suite->prf_alg, secret, label, seed_a, seed_b,
- seed_c, out);
- }
-
- struct s2n_blob half_secret = {.data = secret->data,.size = (secret->size + 1) / 2 };
-
- GUARD(s2n_p_hash(&conn->prf_space, S2N_HMAC_MD5, &half_secret, label, seed_a, seed_b, seed_c, out));
- half_secret.data += secret->size - half_secret.size;
- GUARD(s2n_p_hash(&conn->prf_space, S2N_HMAC_SHA1, &half_secret, label, seed_a, seed_b, seed_c, out));
-
- return 0;
-}
-
-int s2n_tls_prf_master_secret(struct s2n_connection *conn, struct s2n_blob *premaster_secret)
-{
- struct s2n_blob client_random = {.size = sizeof(conn->secure.client_random), .data = conn->secure.client_random};
- struct s2n_blob server_random = {.size = sizeof(conn->secure.server_random), .data = conn->secure.server_random};
- struct s2n_blob master_secret = {.size = sizeof(conn->secure.master_secret), .data = conn->secure.master_secret};
-
- uint8_t master_secret_label[] = "master secret";
- struct s2n_blob label = {.size = sizeof(master_secret_label) - 1, .data = master_secret_label};
-
- return s2n_prf(conn, premaster_secret, &label, &client_random, &server_random, NULL, &master_secret);
-}
-
-int s2n_hybrid_prf_master_secret(struct s2n_connection *conn, struct s2n_blob *premaster_secret)
-{
- struct s2n_blob client_random = {.size = sizeof(conn->secure.client_random), .data = conn->secure.client_random};
- struct s2n_blob server_random = {.size = sizeof(conn->secure.server_random), .data = conn->secure.server_random};
- struct s2n_blob master_secret = {.size = sizeof(conn->secure.master_secret), .data = conn->secure.master_secret};
-
- uint8_t master_secret_label[] = "hybrid master secret";
- struct s2n_blob label = {.size = sizeof(master_secret_label) - 1, .data = master_secret_label};
-
- return s2n_prf(conn, premaster_secret, &label, &client_random, &server_random, &conn->secure.client_key_exchange_message, &master_secret);
-}
-
-static int s2n_sslv3_finished(struct s2n_connection *conn, uint8_t prefix[4], struct s2n_hash_state *md5, struct s2n_hash_state *sha1, uint8_t * out)
-{
- uint8_t xorpad1[48] =
- { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
- };
- uint8_t xorpad2[48] =
- { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
- };
- uint8_t *md5_digest = out;
- uint8_t *sha_digest = out + MD5_DIGEST_LENGTH;
-
- lte_check(MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, sizeof(conn->handshake.client_finished));
-
- GUARD(s2n_hash_update(md5, prefix, 4));
- GUARD(s2n_hash_update(md5, conn->secure.master_secret, sizeof(conn->secure.master_secret)));
- GUARD(s2n_hash_update(md5, xorpad1, 48));
- GUARD(s2n_hash_digest(md5, md5_digest, MD5_DIGEST_LENGTH));
- GUARD(s2n_hash_reset(md5));
- GUARD(s2n_hash_update(md5, conn->secure.master_secret, sizeof(conn->secure.master_secret)));
- GUARD(s2n_hash_update(md5, xorpad2, 48));
- GUARD(s2n_hash_update(md5, md5_digest, MD5_DIGEST_LENGTH));
- GUARD(s2n_hash_digest(md5, md5_digest, MD5_DIGEST_LENGTH));
- GUARD(s2n_hash_reset(md5));
-
- GUARD(s2n_hash_update(sha1, prefix, 4));
- GUARD(s2n_hash_update(sha1, conn->secure.master_secret, sizeof(conn->secure.master_secret)));
- GUARD(s2n_hash_update(sha1, xorpad1, 40));
- GUARD(s2n_hash_digest(sha1, sha_digest, SHA_DIGEST_LENGTH));
- GUARD(s2n_hash_reset(sha1));
- GUARD(s2n_hash_update(sha1, conn->secure.master_secret, sizeof(conn->secure.master_secret)));
- GUARD(s2n_hash_update(sha1, xorpad2, 40));
- GUARD(s2n_hash_update(sha1, sha_digest, SHA_DIGEST_LENGTH));
- GUARD(s2n_hash_digest(sha1, sha_digest, SHA_DIGEST_LENGTH));
- GUARD(s2n_hash_reset(sha1));
-
- return 0;
-}
-
-static int s2n_sslv3_client_finished(struct s2n_connection *conn)
-{
- uint8_t prefix[4] = { 0x43, 0x4c, 0x4e, 0x54 };
-
- lte_check(MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, sizeof(conn->handshake.client_finished));
- GUARD(s2n_hash_copy(&conn->handshake.prf_md5_hash_copy, &conn->handshake.md5));
- GUARD(s2n_hash_copy(&conn->handshake.prf_sha1_hash_copy, &conn->handshake.sha1));
- return s2n_sslv3_finished(conn, prefix, &conn->handshake.prf_md5_hash_copy, &conn->handshake.prf_sha1_hash_copy, conn->handshake.client_finished);
-}
-
-static int s2n_sslv3_server_finished(struct s2n_connection *conn)
-{
- uint8_t prefix[4] = { 0x53, 0x52, 0x56, 0x52 };
-
- lte_check(MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, sizeof(conn->handshake.server_finished));
- GUARD(s2n_hash_copy(&conn->handshake.prf_md5_hash_copy, &conn->handshake.md5));
- GUARD(s2n_hash_copy(&conn->handshake.prf_sha1_hash_copy, &conn->handshake.sha1));
- return s2n_sslv3_finished(conn, prefix, &conn->handshake.prf_md5_hash_copy, &conn->handshake.prf_sha1_hash_copy, conn->handshake.server_finished);
-}
-
-int s2n_prf_client_finished(struct s2n_connection *conn)
-{
- struct s2n_blob master_secret, md5, sha;
- uint8_t md5_digest[MD5_DIGEST_LENGTH];
- uint8_t sha_digest[SHA384_DIGEST_LENGTH];
- uint8_t client_finished_label[] = "client finished";
- struct s2n_blob client_finished = {0};
- struct s2n_blob label = {0};
-
- if (conn->actual_protocol_version == S2N_SSLv3) {
- return s2n_sslv3_client_finished(conn);
- }
-
- client_finished.data = conn->handshake.client_finished;
- client_finished.size = S2N_TLS_FINISHED_LEN;
- label.data = client_finished_label;
- label.size = sizeof(client_finished_label) - 1;
-
- master_secret.data = conn->secure.master_secret;
- master_secret.size = sizeof(conn->secure.master_secret);
- if (conn->actual_protocol_version == S2N_TLS12) {
- switch (conn->secure.cipher_suite->prf_alg) {
- case S2N_HMAC_SHA256:
- GUARD(s2n_hash_copy(&conn->handshake.prf_tls12_hash_copy, &conn->handshake.sha256));
- GUARD(s2n_hash_digest(&conn->handshake.prf_tls12_hash_copy, sha_digest, SHA256_DIGEST_LENGTH));
- sha.size = SHA256_DIGEST_LENGTH;
- break;
- case S2N_HMAC_SHA384:
- GUARD(s2n_hash_copy(&conn->handshake.prf_tls12_hash_copy, &conn->handshake.sha384));
- GUARD(s2n_hash_digest(&conn->handshake.prf_tls12_hash_copy, sha_digest, SHA384_DIGEST_LENGTH));
- sha.size = SHA384_DIGEST_LENGTH;
- break;
- default:
- S2N_ERROR(S2N_ERR_PRF_INVALID_ALGORITHM);
- }
-
- sha.data = sha_digest;
- return s2n_prf(conn, &master_secret, &label, &sha, NULL, NULL, &client_finished);
- }
-
- GUARD(s2n_hash_copy(&conn->handshake.prf_md5_hash_copy, &conn->handshake.md5));
- GUARD(s2n_hash_copy(&conn->handshake.prf_sha1_hash_copy, &conn->handshake.sha1));
-
- GUARD(s2n_hash_digest(&conn->handshake.prf_md5_hash_copy, md5_digest, MD5_DIGEST_LENGTH));
- GUARD(s2n_hash_digest(&conn->handshake.prf_sha1_hash_copy, sha_digest, SHA_DIGEST_LENGTH));
- md5.data = md5_digest;
- md5.size = MD5_DIGEST_LENGTH;
- sha.data = sha_digest;
- sha.size = SHA_DIGEST_LENGTH;
-
- return s2n_prf(conn, &master_secret, &label, &md5, &sha, NULL, &client_finished);
-}
-
-int s2n_prf_server_finished(struct s2n_connection *conn)
-{
- struct s2n_blob master_secret, md5, sha;
- uint8_t md5_digest[MD5_DIGEST_LENGTH];
- uint8_t sha_digest[SHA384_DIGEST_LENGTH];
- uint8_t server_finished_label[] = "server finished";
- struct s2n_blob server_finished = {0};
- struct s2n_blob label = {0};
-
- if (conn->actual_protocol_version == S2N_SSLv3) {
- return s2n_sslv3_server_finished(conn);
- }
-
- server_finished.data = conn->handshake.server_finished;
- server_finished.size = S2N_TLS_FINISHED_LEN;
- label.data = server_finished_label;
- label.size = sizeof(server_finished_label) - 1;
-
- master_secret.data = conn->secure.master_secret;
- master_secret.size = sizeof(conn->secure.master_secret);
- if (conn->actual_protocol_version == S2N_TLS12) {
- switch (conn->secure.cipher_suite->prf_alg) {
- case S2N_HMAC_SHA256:
- GUARD(s2n_hash_copy(&conn->handshake.prf_tls12_hash_copy, &conn->handshake.sha256));
- GUARD(s2n_hash_digest(&conn->handshake.prf_tls12_hash_copy, sha_digest, SHA256_DIGEST_LENGTH));
- sha.size = SHA256_DIGEST_LENGTH;
- break;
- case S2N_HMAC_SHA384:
- GUARD(s2n_hash_copy(&conn->handshake.prf_tls12_hash_copy, &conn->handshake.sha384));
- GUARD(s2n_hash_digest(&conn->handshake.prf_tls12_hash_copy, sha_digest, SHA384_DIGEST_LENGTH));
- sha.size = SHA384_DIGEST_LENGTH;
- break;
- default:
- S2N_ERROR(S2N_ERR_PRF_INVALID_ALGORITHM);
- }
-
- sha.data = sha_digest;
- return s2n_prf(conn, &master_secret, &label, &sha, NULL, NULL, &server_finished);
- }
-
- GUARD(s2n_hash_copy(&conn->handshake.prf_md5_hash_copy, &conn->handshake.md5));
- GUARD(s2n_hash_copy(&conn->handshake.prf_sha1_hash_copy, &conn->handshake.sha1));
-
- GUARD(s2n_hash_digest(&conn->handshake.prf_md5_hash_copy, md5_digest, MD5_DIGEST_LENGTH));
- GUARD(s2n_hash_digest(&conn->handshake.prf_sha1_hash_copy, sha_digest, SHA_DIGEST_LENGTH));
- md5.data = md5_digest;
- md5.size = MD5_DIGEST_LENGTH;
- sha.data = sha_digest;
- sha.size = SHA_DIGEST_LENGTH;
-
- return s2n_prf(conn, &master_secret, &label, &md5, &sha, NULL, &server_finished);
-}
-
-static int s2n_prf_make_client_key(struct s2n_connection *conn, struct s2n_stuffer *key_material)
-{
- struct s2n_blob client_key = {0};
- client_key.size = conn->secure.cipher_suite->record_alg->cipher->key_material_size;
- client_key.data = s2n_stuffer_raw_read(key_material, client_key.size);
- notnull_check(client_key.data);
-
- if (conn->mode == S2N_CLIENT) {
- GUARD(conn->secure.cipher_suite->record_alg->cipher->set_encryption_key(&conn->secure.client_key, &client_key));
- } else {
- GUARD(conn->secure.cipher_suite->record_alg->cipher->set_decryption_key(&conn->secure.client_key, &client_key));
- }
-
- return 0;
-}
-
-static int s2n_prf_make_server_key(struct s2n_connection *conn, struct s2n_stuffer *key_material)
-{
- struct s2n_blob server_key = {0};
- server_key.size = conn->secure.cipher_suite->record_alg->cipher->key_material_size;
- server_key.data = s2n_stuffer_raw_read(key_material, server_key.size);
- notnull_check(server_key.data);
-
- if (conn->mode == S2N_SERVER) {
- GUARD(conn->secure.cipher_suite->record_alg->cipher->set_encryption_key(&conn->secure.server_key, &server_key));
- } else {
- GUARD(conn->secure.cipher_suite->record_alg->cipher->set_decryption_key(&conn->secure.server_key, &server_key));
- }
-
- return 0;
-}
-
-int s2n_prf_key_expansion(struct s2n_connection *conn)
-{
- struct s2n_blob client_random = {.data = conn->secure.client_random,.size = sizeof(conn->secure.client_random) };
- struct s2n_blob server_random = {.data = conn->secure.server_random,.size = sizeof(conn->secure.server_random) };
- struct s2n_blob master_secret = {.data = conn->secure.master_secret,.size = sizeof(conn->secure.master_secret) };
- struct s2n_blob label, out;
- uint8_t key_expansion_label[] = "key expansion";
- uint8_t key_block[S2N_MAX_KEY_BLOCK_LEN];
-
- label.data = key_expansion_label;
- label.size = sizeof(key_expansion_label) - 1;
- GUARD(s2n_blob_init(&out, key_block, sizeof(key_block)));
-
- struct s2n_stuffer key_material = {0};
- GUARD(s2n_prf(conn, &master_secret, &label, &server_random, &client_random, NULL, &out));
- GUARD(s2n_stuffer_init(&key_material, &out));
- GUARD(s2n_stuffer_write(&key_material, &out));
-
- ENSURE_POSIX(conn->secure.cipher_suite->available, S2N_ERR_PRF_INVALID_ALGORITHM);
- GUARD(conn->secure.cipher_suite->record_alg->cipher->init(&conn->secure.client_key));
- GUARD(conn->secure.cipher_suite->record_alg->cipher->init(&conn->secure.server_key));
-
- /* Check that we have a valid MAC and key size */
- uint8_t mac_size;
- if (conn->secure.cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
- mac_size = conn->secure.cipher_suite->record_alg->cipher->io.comp.mac_key_size;
- } else {
- GUARD(s2n_hmac_digest_size(conn->secure.cipher_suite->record_alg->hmac_alg, &mac_size));
- }
-
- /* Seed the client MAC */
- uint8_t *client_mac_write_key = s2n_stuffer_raw_read(&key_material, mac_size);
- notnull_check(client_mac_write_key);
- GUARD(s2n_hmac_reset(&conn->secure.client_record_mac));
- GUARD(s2n_hmac_init(&conn->secure.client_record_mac, conn->secure.cipher_suite->record_alg->hmac_alg, client_mac_write_key, mac_size));
-
- /* Seed the server MAC */
- uint8_t *server_mac_write_key = s2n_stuffer_raw_read(&key_material, mac_size);
- notnull_check(server_mac_write_key);
- GUARD(s2n_hmac_reset(&conn->secure.server_record_mac));
- GUARD(s2n_hmac_init(&conn->secure.server_record_mac, conn->secure.cipher_suite->record_alg->hmac_alg, server_mac_write_key, mac_size));
-
- /* Make the client key */
- GUARD(s2n_prf_make_client_key(conn, &key_material));
-
- /* Make the server key */
- GUARD(s2n_prf_make_server_key(conn, &key_material));
-
- /* Composite CBC does MAC inside the cipher, pass it the MAC key.
- * Must happen after setting encryption/decryption keys.
- */
- if (conn->secure.cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
- GUARD(conn->secure.cipher_suite->record_alg->cipher->io.comp.set_mac_write_key(&conn->secure.server_key, server_mac_write_key, mac_size));
- GUARD(conn->secure.cipher_suite->record_alg->cipher->io.comp.set_mac_write_key(&conn->secure.client_key, client_mac_write_key, mac_size));
- }
-
- /* TLS >= 1.1 has no implicit IVs for non AEAD ciphers */
- if (conn->actual_protocol_version > S2N_TLS10 && conn->secure.cipher_suite->record_alg->cipher->type != S2N_AEAD) {
- return 0;
- }
-
- uint32_t implicit_iv_size = 0;
- switch (conn->secure.cipher_suite->record_alg->cipher->type) {
- case S2N_AEAD:
- implicit_iv_size = conn->secure.cipher_suite->record_alg->cipher->io.aead.fixed_iv_size;
- break;
- case S2N_CBC:
- implicit_iv_size = conn->secure.cipher_suite->record_alg->cipher->io.cbc.block_size;
- break;
- case S2N_COMPOSITE:
- implicit_iv_size = conn->secure.cipher_suite->record_alg->cipher->io.comp.block_size;
- break;
- /* No-op for stream ciphers */
- default:
- break;
- }
-
- struct s2n_blob client_implicit_iv = {.data = conn->secure.client_implicit_iv,.size = implicit_iv_size };
- struct s2n_blob server_implicit_iv = {.data = conn->secure.server_implicit_iv,.size = implicit_iv_size };
- GUARD(s2n_stuffer_read(&key_material, &client_implicit_iv));
- GUARD(s2n_stuffer_read(&key_material, &server_implicit_iv));
-
- return 0;
-}
+/*
+ * 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 <sys/param.h>
+#include <openssl/md5.h>
+#include <openssl/sha.h>
+#include <string.h>
+
+#include "error/s2n_errno.h"
+
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_prf.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "crypto/s2n_hmac.h"
+#include "crypto/s2n_hash.h"
+#include "crypto/s2n_openssl.h"
+#include "crypto/s2n_fips.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_blob.h"
+#include "utils/s2n_mem.h"
+
+static int s2n_sslv3_prf(struct s2n_prf_working_space *ws, struct s2n_blob *secret, struct s2n_blob *seed_a,
+ struct s2n_blob *seed_b, struct s2n_blob *seed_c, struct s2n_blob *out)
+{
+ struct s2n_hash_state *md5 = &ws->ssl3.md5;
+ struct s2n_hash_state *sha1 = &ws->ssl3.sha1;
+
+ uint32_t outputlen = out->size;
+ uint8_t *output = out->data;
+ uint8_t iteration = 1;
+
+ uint8_t A = 'A';
+ while (outputlen) {
+ GUARD(s2n_hash_reset(sha1));
+
+ for (int i = 0; i < iteration; i++) {
+ GUARD(s2n_hash_update(sha1, &A, 1));
+ }
+
+ GUARD(s2n_hash_update(sha1, secret->data, secret->size));
+ GUARD(s2n_hash_update(sha1, seed_a->data, seed_a->size));
+
+ if (seed_b) {
+ GUARD(s2n_hash_update(sha1, seed_b->data, seed_b->size));
+ if (seed_c) {
+ GUARD(s2n_hash_update(sha1, seed_c->data, seed_c->size));
+ }
+ }
+
+ GUARD(s2n_hash_digest(sha1, ws->ssl3.sha1_digest, sizeof(ws->ssl3.sha1_digest)));
+
+ GUARD(s2n_hash_reset(md5));
+ GUARD(s2n_hash_update(md5, secret->data, secret->size));
+ GUARD(s2n_hash_update(md5, ws->ssl3.sha1_digest, sizeof(ws->ssl3.sha1_digest)));
+ GUARD(s2n_hash_digest(md5, ws->ssl3.md5_digest, sizeof(ws->ssl3.md5_digest)));
+
+ uint32_t bytes_to_copy = MIN(outputlen, sizeof(ws->ssl3.md5_digest));
+
+ memcpy_check(output, ws->ssl3.md5_digest, bytes_to_copy);
+
+ outputlen -= bytes_to_copy;
+ output += bytes_to_copy;
+
+ /* Increment the letter */
+ A++;
+ iteration++;
+ }
+
+ GUARD(s2n_hash_reset(md5));
+ GUARD(s2n_hash_reset(sha1));
+
+ return 0;
+}
+
+#if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
+static int s2n_evp_hmac_p_hash_new(struct s2n_prf_working_space *ws)
+{
+ notnull_check(ws->tls.p_hash.evp_hmac.evp_digest.ctx = S2N_EVP_MD_CTX_NEW());
+ return 0;
+}
+
+static int s2n_evp_hmac_p_hash_digest_init(struct s2n_prf_working_space *ws)
+{
+ notnull_check(ws->tls.p_hash.evp_hmac.evp_digest.md);
+ notnull_check(ws->tls.p_hash.evp_hmac.evp_digest.ctx);
+ notnull_check(ws->tls.p_hash.evp_hmac.mac_key);
+
+ /* Ignore the MD5 check when in FIPS mode to comply with the TLS 1.0 RFC */
+ if (s2n_is_in_fips_mode()) {
+ GUARD(s2n_digest_allow_md5_for_fips(&ws->tls.p_hash.evp_hmac.evp_digest));
+ }
+
+ GUARD_OSSL(EVP_DigestSignInit(ws->tls.p_hash.evp_hmac.evp_digest.ctx, NULL, ws->tls.p_hash.evp_hmac.evp_digest.md, NULL, ws->tls.p_hash.evp_hmac.mac_key),
+ S2N_ERR_P_HASH_INIT_FAILED);
+
+ return 0;
+}
+
+static int s2n_evp_hmac_p_hash_init(struct s2n_prf_working_space *ws, s2n_hmac_algorithm alg, struct s2n_blob *secret)
+{
+ /* Initialize the message digest */
+ switch (alg) {
+ case S2N_HMAC_SSLv3_MD5:
+ case S2N_HMAC_MD5:
+ ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_md5();
+ break;
+ case S2N_HMAC_SSLv3_SHA1:
+ case S2N_HMAC_SHA1:
+ ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha1();
+ break;
+ case S2N_HMAC_SHA224:
+ ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha224();
+ break;
+ case S2N_HMAC_SHA256:
+ ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha256();
+ break;
+ case S2N_HMAC_SHA384:
+ ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha384();
+ break;
+ case S2N_HMAC_SHA512:
+ ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha512();
+ break;
+ default:
+ S2N_ERROR(S2N_ERR_P_HASH_INVALID_ALGORITHM);
+ }
+
+ /* Initialize the mac key using the provided secret */
+ notnull_check(ws->tls.p_hash.evp_hmac.mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, secret->data, secret->size));
+
+ /* Initialize the message digest context with the above message digest and mac key */
+ return s2n_evp_hmac_p_hash_digest_init(ws);
+}
+
+static int s2n_evp_hmac_p_hash_update(struct s2n_prf_working_space *ws, const void *data, uint32_t size)
+{
+ GUARD_OSSL(EVP_DigestSignUpdate(ws->tls.p_hash.evp_hmac.evp_digest.ctx, data, (size_t)size), S2N_ERR_P_HASH_UPDATE_FAILED);
+
+ return 0;
+}
+
+static int s2n_evp_hmac_p_hash_digest(struct s2n_prf_working_space *ws, void *digest, uint32_t size)
+{
+ /* EVP_DigestSign API's require size_t data structures */
+ size_t digest_size = size;
+
+ GUARD_OSSL(EVP_DigestSignFinal(ws->tls.p_hash.evp_hmac.evp_digest.ctx, (unsigned char *)digest, &digest_size), S2N_ERR_P_HASH_FINAL_FAILED);
+
+ return 0;
+}
+
+static int s2n_evp_hmac_p_hash_wipe(struct s2n_prf_working_space *ws)
+{
+ GUARD_OSSL(S2N_EVP_MD_CTX_RESET(ws->tls.p_hash.evp_hmac.evp_digest.ctx), S2N_ERR_P_HASH_WIPE_FAILED);
+
+ return 0;
+}
+
+static int s2n_evp_hmac_p_hash_reset(struct s2n_prf_working_space *ws)
+{
+ GUARD(s2n_evp_hmac_p_hash_wipe(ws));
+
+ return s2n_evp_hmac_p_hash_digest_init(ws);
+}
+
+static int s2n_evp_hmac_p_hash_cleanup(struct s2n_prf_working_space *ws)
+{
+ /* Prepare the workspace md_ctx for the next p_hash */
+ GUARD(s2n_evp_hmac_p_hash_wipe(ws));
+
+ /* Free mac key - PKEYs cannot be reused */
+ notnull_check(ws->tls.p_hash.evp_hmac.mac_key);
+ EVP_PKEY_free(ws->tls.p_hash.evp_hmac.mac_key);
+ ws->tls.p_hash.evp_hmac.mac_key = NULL;
+
+ return 0;
+}
+
+static int s2n_evp_hmac_p_hash_free(struct s2n_prf_working_space *ws)
+{
+ notnull_check(ws->tls.p_hash.evp_hmac.evp_digest.ctx);
+ S2N_EVP_MD_CTX_FREE(ws->tls.p_hash.evp_hmac.evp_digest.ctx);
+ ws->tls.p_hash.evp_hmac.evp_digest.ctx = NULL;
+
+ return 0;
+}
+
+static const struct s2n_p_hash_hmac s2n_evp_hmac = {
+ .alloc = &s2n_evp_hmac_p_hash_new,
+ .init = &s2n_evp_hmac_p_hash_init,
+ .update = &s2n_evp_hmac_p_hash_update,
+ .final = &s2n_evp_hmac_p_hash_digest,
+ .reset = &s2n_evp_hmac_p_hash_reset,
+ .cleanup = &s2n_evp_hmac_p_hash_cleanup,
+ .free = &s2n_evp_hmac_p_hash_free,
+};
+#endif /* !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC) */
+
+static int s2n_hmac_p_hash_new(struct s2n_prf_working_space *ws)
+{
+ GUARD(s2n_hmac_new(&ws->tls.p_hash.s2n_hmac));
+
+ return s2n_hmac_init(&ws->tls.p_hash.s2n_hmac, S2N_HMAC_NONE, NULL, 0);
+}
+
+static int s2n_hmac_p_hash_init(struct s2n_prf_working_space *ws, s2n_hmac_algorithm alg, struct s2n_blob *secret)
+{
+ return s2n_hmac_init(&ws->tls.p_hash.s2n_hmac, alg, secret->data, secret->size);
+}
+
+static int s2n_hmac_p_hash_update(struct s2n_prf_working_space *ws, const void *data, uint32_t size)
+{
+ return s2n_hmac_update(&ws->tls.p_hash.s2n_hmac, data, size);
+}
+
+static int s2n_hmac_p_hash_digest(struct s2n_prf_working_space *ws, void *digest, uint32_t size)
+{
+ return s2n_hmac_digest(&ws->tls.p_hash.s2n_hmac, digest, size);
+}
+
+static int s2n_hmac_p_hash_reset(struct s2n_prf_working_space *ws)
+{
+ return s2n_hmac_reset(&ws->tls.p_hash.s2n_hmac);
+}
+
+static int s2n_hmac_p_hash_cleanup(struct s2n_prf_working_space *ws)
+{
+ return s2n_hmac_p_hash_reset(ws);
+}
+
+static int s2n_hmac_p_hash_free(struct s2n_prf_working_space *ws)
+{
+ return s2n_hmac_free(&ws->tls.p_hash.s2n_hmac);
+}
+
+static const struct s2n_p_hash_hmac s2n_hmac = {
+ .alloc = &s2n_hmac_p_hash_new,
+ .init = &s2n_hmac_p_hash_init,
+ .update = &s2n_hmac_p_hash_update,
+ .final = &s2n_hmac_p_hash_digest,
+ .reset = &s2n_hmac_p_hash_reset,
+ .cleanup = &s2n_hmac_p_hash_cleanup,
+ .free = &s2n_hmac_p_hash_free,
+};
+
+static int s2n_p_hash(struct s2n_prf_working_space *ws, s2n_hmac_algorithm alg, struct s2n_blob *secret, struct s2n_blob *label,
+ struct s2n_blob *seed_a, struct s2n_blob *seed_b, struct s2n_blob *seed_c, struct s2n_blob *out)
+{
+ uint8_t digest_size;
+ GUARD(s2n_hmac_digest_size(alg, &digest_size));
+
+ const struct s2n_p_hash_hmac *hmac = ws->tls.p_hash_hmac_impl;
+
+ /* First compute hmac(secret + A(0)) */
+ GUARD(hmac->init(ws, alg, secret));
+ GUARD(hmac->update(ws, label->data, label->size));
+ GUARD(hmac->update(ws, seed_a->data, seed_a->size));
+
+ if (seed_b) {
+ GUARD(hmac->update(ws, seed_b->data, seed_b->size));
+ if (seed_c) {
+ GUARD(hmac->update(ws, seed_c->data, seed_c->size));
+ }
+ }
+ GUARD(hmac->final(ws, ws->tls.digest0, digest_size));
+
+ uint32_t outputlen = out->size;
+ uint8_t *output = out->data;
+
+ while (outputlen) {
+ /* Now compute hmac(secret + A(N - 1) + seed) */
+ GUARD(hmac->reset(ws));
+ GUARD(hmac->update(ws, ws->tls.digest0, digest_size));
+
+ /* Add the label + seed and compute this round's A */
+ GUARD(hmac->update(ws, label->data, label->size));
+ GUARD(hmac->update(ws, seed_a->data, seed_a->size));
+ if (seed_b) {
+ GUARD(hmac->update(ws, seed_b->data, seed_b->size));
+ if (seed_c) {
+ GUARD(hmac->update(ws, seed_c->data, seed_c->size));
+ }
+ }
+
+ GUARD(hmac->final(ws, ws->tls.digest1, digest_size));
+
+ uint32_t bytes_to_xor = MIN(outputlen, digest_size);
+
+ for (int i = 0; i < bytes_to_xor; i++) {
+ *output ^= ws->tls.digest1[i];
+ output++;
+ outputlen--;
+ }
+
+ /* Stash a digest of A(N), in A(N), for the next round */
+ GUARD(hmac->reset(ws));
+ GUARD(hmac->update(ws, ws->tls.digest0, digest_size));
+ GUARD(hmac->final(ws, ws->tls.digest0, digest_size));
+ }
+
+ GUARD(hmac->cleanup(ws));
+
+ return 0;
+}
+
+const struct s2n_p_hash_hmac *s2n_get_hmac_implementation() {
+#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
+ return &s2n_hmac;
+#else
+ return s2n_is_in_fips_mode() ? &s2n_evp_hmac : &s2n_hmac;
+#endif
+}
+
+int s2n_prf_new(struct s2n_connection *conn)
+{
+ /* Set p_hash_hmac_impl on initial prf creation.
+ * When in FIPS mode, the EVP API's must be used for the p_hash HMAC.
+ */
+ conn->prf_space.tls.p_hash_hmac_impl = s2n_get_hmac_implementation();
+
+ return conn->prf_space.tls.p_hash_hmac_impl->alloc(&conn->prf_space);
+}
+
+int s2n_prf_free(struct s2n_connection *conn)
+{
+ /* Ensure that p_hash_hmac_impl is set, as it may have been reset for prf_space on s2n_connection_wipe.
+ * When in FIPS mode, the EVP API's must be used for the p_hash HMAC.
+ */
+ conn->prf_space.tls.p_hash_hmac_impl = s2n_get_hmac_implementation();
+
+ return conn->prf_space.tls.p_hash_hmac_impl->free(&conn->prf_space);
+}
+
+static int s2n_prf(struct s2n_connection *conn, struct s2n_blob *secret, struct s2n_blob *label, struct s2n_blob *seed_a,
+ struct s2n_blob *seed_b, struct s2n_blob *seed_c, struct s2n_blob *out)
+{
+ /* seed_a is always required, seed_b is optional, if seed_c is provided seed_b must also be provided */
+ S2N_ERROR_IF(seed_a == NULL, S2N_ERR_PRF_INVALID_SEED);
+ S2N_ERROR_IF(seed_b == NULL && seed_c != NULL, S2N_ERR_PRF_INVALID_SEED);
+
+ if (conn->actual_protocol_version == S2N_SSLv3) {
+ return s2n_sslv3_prf(&conn->prf_space, secret, seed_a, seed_b, seed_c, out);
+ }
+
+ /* We zero the out blob because p_hash works by XOR'ing with the existing
+ * buffer. This is a little convoluted but means we can avoid dynamic memory
+ * allocation. When we call p_hash once (in the TLS1.2 case) it will produce
+ * the right values. When we call it twice in the regular case, the two
+ * outputs will be XORd just ass the TLS 1.0 and 1.1 RFCs require.
+ */
+ GUARD(s2n_blob_zero(out));
+
+ /* Ensure that p_hash_hmac_impl is set, as it may have been reset for prf_space on s2n_connection_wipe.
+ * When in FIPS mode, the EVP API's must be used for the p_hash HMAC.
+ */
+ conn->prf_space.tls.p_hash_hmac_impl = s2n_get_hmac_implementation();
+
+ if (conn->actual_protocol_version == S2N_TLS12) {
+ return s2n_p_hash(&conn->prf_space, conn->secure.cipher_suite->prf_alg, secret, label, seed_a, seed_b,
+ seed_c, out);
+ }
+
+ struct s2n_blob half_secret = {.data = secret->data,.size = (secret->size + 1) / 2 };
+
+ GUARD(s2n_p_hash(&conn->prf_space, S2N_HMAC_MD5, &half_secret, label, seed_a, seed_b, seed_c, out));
+ half_secret.data += secret->size - half_secret.size;
+ GUARD(s2n_p_hash(&conn->prf_space, S2N_HMAC_SHA1, &half_secret, label, seed_a, seed_b, seed_c, out));
+
+ return 0;
+}
+
+int s2n_tls_prf_master_secret(struct s2n_connection *conn, struct s2n_blob *premaster_secret)
+{
+ struct s2n_blob client_random = {.size = sizeof(conn->secure.client_random), .data = conn->secure.client_random};
+ struct s2n_blob server_random = {.size = sizeof(conn->secure.server_random), .data = conn->secure.server_random};
+ struct s2n_blob master_secret = {.size = sizeof(conn->secure.master_secret), .data = conn->secure.master_secret};
+
+ uint8_t master_secret_label[] = "master secret";
+ struct s2n_blob label = {.size = sizeof(master_secret_label) - 1, .data = master_secret_label};
+
+ return s2n_prf(conn, premaster_secret, &label, &client_random, &server_random, NULL, &master_secret);
+}
+
+int s2n_hybrid_prf_master_secret(struct s2n_connection *conn, struct s2n_blob *premaster_secret)
+{
+ struct s2n_blob client_random = {.size = sizeof(conn->secure.client_random), .data = conn->secure.client_random};
+ struct s2n_blob server_random = {.size = sizeof(conn->secure.server_random), .data = conn->secure.server_random};
+ struct s2n_blob master_secret = {.size = sizeof(conn->secure.master_secret), .data = conn->secure.master_secret};
+
+ uint8_t master_secret_label[] = "hybrid master secret";
+ struct s2n_blob label = {.size = sizeof(master_secret_label) - 1, .data = master_secret_label};
+
+ return s2n_prf(conn, premaster_secret, &label, &client_random, &server_random, &conn->secure.client_key_exchange_message, &master_secret);
+}
+
+static int s2n_sslv3_finished(struct s2n_connection *conn, uint8_t prefix[4], struct s2n_hash_state *md5, struct s2n_hash_state *sha1, uint8_t * out)
+{
+ uint8_t xorpad1[48] =
+ { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
+ };
+ uint8_t xorpad2[48] =
+ { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
+ };
+ uint8_t *md5_digest = out;
+ uint8_t *sha_digest = out + MD5_DIGEST_LENGTH;
+
+ lte_check(MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, sizeof(conn->handshake.client_finished));
+
+ GUARD(s2n_hash_update(md5, prefix, 4));
+ GUARD(s2n_hash_update(md5, conn->secure.master_secret, sizeof(conn->secure.master_secret)));
+ GUARD(s2n_hash_update(md5, xorpad1, 48));
+ GUARD(s2n_hash_digest(md5, md5_digest, MD5_DIGEST_LENGTH));
+ GUARD(s2n_hash_reset(md5));
+ GUARD(s2n_hash_update(md5, conn->secure.master_secret, sizeof(conn->secure.master_secret)));
+ GUARD(s2n_hash_update(md5, xorpad2, 48));
+ GUARD(s2n_hash_update(md5, md5_digest, MD5_DIGEST_LENGTH));
+ GUARD(s2n_hash_digest(md5, md5_digest, MD5_DIGEST_LENGTH));
+ GUARD(s2n_hash_reset(md5));
+
+ GUARD(s2n_hash_update(sha1, prefix, 4));
+ GUARD(s2n_hash_update(sha1, conn->secure.master_secret, sizeof(conn->secure.master_secret)));
+ GUARD(s2n_hash_update(sha1, xorpad1, 40));
+ GUARD(s2n_hash_digest(sha1, sha_digest, SHA_DIGEST_LENGTH));
+ GUARD(s2n_hash_reset(sha1));
+ GUARD(s2n_hash_update(sha1, conn->secure.master_secret, sizeof(conn->secure.master_secret)));
+ GUARD(s2n_hash_update(sha1, xorpad2, 40));
+ GUARD(s2n_hash_update(sha1, sha_digest, SHA_DIGEST_LENGTH));
+ GUARD(s2n_hash_digest(sha1, sha_digest, SHA_DIGEST_LENGTH));
+ GUARD(s2n_hash_reset(sha1));
+
+ return 0;
+}
+
+static int s2n_sslv3_client_finished(struct s2n_connection *conn)
+{
+ uint8_t prefix[4] = { 0x43, 0x4c, 0x4e, 0x54 };
+
+ lte_check(MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, sizeof(conn->handshake.client_finished));
+ GUARD(s2n_hash_copy(&conn->handshake.prf_md5_hash_copy, &conn->handshake.md5));
+ GUARD(s2n_hash_copy(&conn->handshake.prf_sha1_hash_copy, &conn->handshake.sha1));
+ return s2n_sslv3_finished(conn, prefix, &conn->handshake.prf_md5_hash_copy, &conn->handshake.prf_sha1_hash_copy, conn->handshake.client_finished);
+}
+
+static int s2n_sslv3_server_finished(struct s2n_connection *conn)
+{
+ uint8_t prefix[4] = { 0x53, 0x52, 0x56, 0x52 };
+
+ lte_check(MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, sizeof(conn->handshake.server_finished));
+ GUARD(s2n_hash_copy(&conn->handshake.prf_md5_hash_copy, &conn->handshake.md5));
+ GUARD(s2n_hash_copy(&conn->handshake.prf_sha1_hash_copy, &conn->handshake.sha1));
+ return s2n_sslv3_finished(conn, prefix, &conn->handshake.prf_md5_hash_copy, &conn->handshake.prf_sha1_hash_copy, conn->handshake.server_finished);
+}
+
+int s2n_prf_client_finished(struct s2n_connection *conn)
+{
+ struct s2n_blob master_secret, md5, sha;
+ uint8_t md5_digest[MD5_DIGEST_LENGTH];
+ uint8_t sha_digest[SHA384_DIGEST_LENGTH];
+ uint8_t client_finished_label[] = "client finished";
+ struct s2n_blob client_finished = {0};
+ struct s2n_blob label = {0};
+
+ if (conn->actual_protocol_version == S2N_SSLv3) {
+ return s2n_sslv3_client_finished(conn);
+ }
+
+ client_finished.data = conn->handshake.client_finished;
+ client_finished.size = S2N_TLS_FINISHED_LEN;
+ label.data = client_finished_label;
+ label.size = sizeof(client_finished_label) - 1;
+
+ master_secret.data = conn->secure.master_secret;
+ master_secret.size = sizeof(conn->secure.master_secret);
+ if (conn->actual_protocol_version == S2N_TLS12) {
+ switch (conn->secure.cipher_suite->prf_alg) {
+ case S2N_HMAC_SHA256:
+ GUARD(s2n_hash_copy(&conn->handshake.prf_tls12_hash_copy, &conn->handshake.sha256));
+ GUARD(s2n_hash_digest(&conn->handshake.prf_tls12_hash_copy, sha_digest, SHA256_DIGEST_LENGTH));
+ sha.size = SHA256_DIGEST_LENGTH;
+ break;
+ case S2N_HMAC_SHA384:
+ GUARD(s2n_hash_copy(&conn->handshake.prf_tls12_hash_copy, &conn->handshake.sha384));
+ GUARD(s2n_hash_digest(&conn->handshake.prf_tls12_hash_copy, sha_digest, SHA384_DIGEST_LENGTH));
+ sha.size = SHA384_DIGEST_LENGTH;
+ break;
+ default:
+ S2N_ERROR(S2N_ERR_PRF_INVALID_ALGORITHM);
+ }
+
+ sha.data = sha_digest;
+ return s2n_prf(conn, &master_secret, &label, &sha, NULL, NULL, &client_finished);
+ }
+
+ GUARD(s2n_hash_copy(&conn->handshake.prf_md5_hash_copy, &conn->handshake.md5));
+ GUARD(s2n_hash_copy(&conn->handshake.prf_sha1_hash_copy, &conn->handshake.sha1));
+
+ GUARD(s2n_hash_digest(&conn->handshake.prf_md5_hash_copy, md5_digest, MD5_DIGEST_LENGTH));
+ GUARD(s2n_hash_digest(&conn->handshake.prf_sha1_hash_copy, sha_digest, SHA_DIGEST_LENGTH));
+ md5.data = md5_digest;
+ md5.size = MD5_DIGEST_LENGTH;
+ sha.data = sha_digest;
+ sha.size = SHA_DIGEST_LENGTH;
+
+ return s2n_prf(conn, &master_secret, &label, &md5, &sha, NULL, &client_finished);
+}
+
+int s2n_prf_server_finished(struct s2n_connection *conn)
+{
+ struct s2n_blob master_secret, md5, sha;
+ uint8_t md5_digest[MD5_DIGEST_LENGTH];
+ uint8_t sha_digest[SHA384_DIGEST_LENGTH];
+ uint8_t server_finished_label[] = "server finished";
+ struct s2n_blob server_finished = {0};
+ struct s2n_blob label = {0};
+
+ if (conn->actual_protocol_version == S2N_SSLv3) {
+ return s2n_sslv3_server_finished(conn);
+ }
+
+ server_finished.data = conn->handshake.server_finished;
+ server_finished.size = S2N_TLS_FINISHED_LEN;
+ label.data = server_finished_label;
+ label.size = sizeof(server_finished_label) - 1;
+
+ master_secret.data = conn->secure.master_secret;
+ master_secret.size = sizeof(conn->secure.master_secret);
+ if (conn->actual_protocol_version == S2N_TLS12) {
+ switch (conn->secure.cipher_suite->prf_alg) {
+ case S2N_HMAC_SHA256:
+ GUARD(s2n_hash_copy(&conn->handshake.prf_tls12_hash_copy, &conn->handshake.sha256));
+ GUARD(s2n_hash_digest(&conn->handshake.prf_tls12_hash_copy, sha_digest, SHA256_DIGEST_LENGTH));
+ sha.size = SHA256_DIGEST_LENGTH;
+ break;
+ case S2N_HMAC_SHA384:
+ GUARD(s2n_hash_copy(&conn->handshake.prf_tls12_hash_copy, &conn->handshake.sha384));
+ GUARD(s2n_hash_digest(&conn->handshake.prf_tls12_hash_copy, sha_digest, SHA384_DIGEST_LENGTH));
+ sha.size = SHA384_DIGEST_LENGTH;
+ break;
+ default:
+ S2N_ERROR(S2N_ERR_PRF_INVALID_ALGORITHM);
+ }
+
+ sha.data = sha_digest;
+ return s2n_prf(conn, &master_secret, &label, &sha, NULL, NULL, &server_finished);
+ }
+
+ GUARD(s2n_hash_copy(&conn->handshake.prf_md5_hash_copy, &conn->handshake.md5));
+ GUARD(s2n_hash_copy(&conn->handshake.prf_sha1_hash_copy, &conn->handshake.sha1));
+
+ GUARD(s2n_hash_digest(&conn->handshake.prf_md5_hash_copy, md5_digest, MD5_DIGEST_LENGTH));
+ GUARD(s2n_hash_digest(&conn->handshake.prf_sha1_hash_copy, sha_digest, SHA_DIGEST_LENGTH));
+ md5.data = md5_digest;
+ md5.size = MD5_DIGEST_LENGTH;
+ sha.data = sha_digest;
+ sha.size = SHA_DIGEST_LENGTH;
+
+ return s2n_prf(conn, &master_secret, &label, &md5, &sha, NULL, &server_finished);
+}
+
+static int s2n_prf_make_client_key(struct s2n_connection *conn, struct s2n_stuffer *key_material)
+{
+ struct s2n_blob client_key = {0};
+ client_key.size = conn->secure.cipher_suite->record_alg->cipher->key_material_size;
+ client_key.data = s2n_stuffer_raw_read(key_material, client_key.size);
+ notnull_check(client_key.data);
+
+ if (conn->mode == S2N_CLIENT) {
+ GUARD(conn->secure.cipher_suite->record_alg->cipher->set_encryption_key(&conn->secure.client_key, &client_key));
+ } else {
+ GUARD(conn->secure.cipher_suite->record_alg->cipher->set_decryption_key(&conn->secure.client_key, &client_key));
+ }
+
+ return 0;
+}
+
+static int s2n_prf_make_server_key(struct s2n_connection *conn, struct s2n_stuffer *key_material)
+{
+ struct s2n_blob server_key = {0};
+ server_key.size = conn->secure.cipher_suite->record_alg->cipher->key_material_size;
+ server_key.data = s2n_stuffer_raw_read(key_material, server_key.size);
+ notnull_check(server_key.data);
+
+ if (conn->mode == S2N_SERVER) {
+ GUARD(conn->secure.cipher_suite->record_alg->cipher->set_encryption_key(&conn->secure.server_key, &server_key));
+ } else {
+ GUARD(conn->secure.cipher_suite->record_alg->cipher->set_decryption_key(&conn->secure.server_key, &server_key));
+ }
+
+ return 0;
+}
+
+int s2n_prf_key_expansion(struct s2n_connection *conn)
+{
+ struct s2n_blob client_random = {.data = conn->secure.client_random,.size = sizeof(conn->secure.client_random) };
+ struct s2n_blob server_random = {.data = conn->secure.server_random,.size = sizeof(conn->secure.server_random) };
+ struct s2n_blob master_secret = {.data = conn->secure.master_secret,.size = sizeof(conn->secure.master_secret) };
+ struct s2n_blob label, out;
+ uint8_t key_expansion_label[] = "key expansion";
+ uint8_t key_block[S2N_MAX_KEY_BLOCK_LEN];
+
+ label.data = key_expansion_label;
+ label.size = sizeof(key_expansion_label) - 1;
+ GUARD(s2n_blob_init(&out, key_block, sizeof(key_block)));
+
+ struct s2n_stuffer key_material = {0};
+ GUARD(s2n_prf(conn, &master_secret, &label, &server_random, &client_random, NULL, &out));
+ GUARD(s2n_stuffer_init(&key_material, &out));
+ GUARD(s2n_stuffer_write(&key_material, &out));
+
+ ENSURE_POSIX(conn->secure.cipher_suite->available, S2N_ERR_PRF_INVALID_ALGORITHM);
+ GUARD(conn->secure.cipher_suite->record_alg->cipher->init(&conn->secure.client_key));
+ GUARD(conn->secure.cipher_suite->record_alg->cipher->init(&conn->secure.server_key));
+
+ /* Check that we have a valid MAC and key size */
+ uint8_t mac_size;
+ if (conn->secure.cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
+ mac_size = conn->secure.cipher_suite->record_alg->cipher->io.comp.mac_key_size;
+ } else {
+ GUARD(s2n_hmac_digest_size(conn->secure.cipher_suite->record_alg->hmac_alg, &mac_size));
+ }
+
+ /* Seed the client MAC */
+ uint8_t *client_mac_write_key = s2n_stuffer_raw_read(&key_material, mac_size);
+ notnull_check(client_mac_write_key);
+ GUARD(s2n_hmac_reset(&conn->secure.client_record_mac));
+ GUARD(s2n_hmac_init(&conn->secure.client_record_mac, conn->secure.cipher_suite->record_alg->hmac_alg, client_mac_write_key, mac_size));
+
+ /* Seed the server MAC */
+ uint8_t *server_mac_write_key = s2n_stuffer_raw_read(&key_material, mac_size);
+ notnull_check(server_mac_write_key);
+ GUARD(s2n_hmac_reset(&conn->secure.server_record_mac));
+ GUARD(s2n_hmac_init(&conn->secure.server_record_mac, conn->secure.cipher_suite->record_alg->hmac_alg, server_mac_write_key, mac_size));
+
+ /* Make the client key */
+ GUARD(s2n_prf_make_client_key(conn, &key_material));
+
+ /* Make the server key */
+ GUARD(s2n_prf_make_server_key(conn, &key_material));
+
+ /* Composite CBC does MAC inside the cipher, pass it the MAC key.
+ * Must happen after setting encryption/decryption keys.
+ */
+ if (conn->secure.cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
+ GUARD(conn->secure.cipher_suite->record_alg->cipher->io.comp.set_mac_write_key(&conn->secure.server_key, server_mac_write_key, mac_size));
+ GUARD(conn->secure.cipher_suite->record_alg->cipher->io.comp.set_mac_write_key(&conn->secure.client_key, client_mac_write_key, mac_size));
+ }
+
+ /* TLS >= 1.1 has no implicit IVs for non AEAD ciphers */
+ if (conn->actual_protocol_version > S2N_TLS10 && conn->secure.cipher_suite->record_alg->cipher->type != S2N_AEAD) {
+ return 0;
+ }
+
+ uint32_t implicit_iv_size = 0;
+ switch (conn->secure.cipher_suite->record_alg->cipher->type) {
+ case S2N_AEAD:
+ implicit_iv_size = conn->secure.cipher_suite->record_alg->cipher->io.aead.fixed_iv_size;
+ break;
+ case S2N_CBC:
+ implicit_iv_size = conn->secure.cipher_suite->record_alg->cipher->io.cbc.block_size;
+ break;
+ case S2N_COMPOSITE:
+ implicit_iv_size = conn->secure.cipher_suite->record_alg->cipher->io.comp.block_size;
+ break;
+ /* No-op for stream ciphers */
+ default:
+ break;
+ }
+
+ struct s2n_blob client_implicit_iv = {.data = conn->secure.client_implicit_iv,.size = implicit_iv_size };
+ struct s2n_blob server_implicit_iv = {.data = conn->secure.server_implicit_iv,.size = implicit_iv_size };
+ GUARD(s2n_stuffer_read(&key_material, &client_implicit_iv));
+ GUARD(s2n_stuffer_read(&key_material, &server_implicit_iv));
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_prf.h b/contrib/restricted/aws/s2n/tls/s2n_prf.h
index 3f1bcde090..a3679436b2 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_prf.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_prf.h
@@ -1,70 +1,70 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <stdint.h>
-
-#include "crypto/s2n_hash.h"
-#include "crypto/s2n_hmac.h"
-#include "crypto/s2n_openssl.h"
-
-#include "utils/s2n_blob.h"
-
-/* Enough to support TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, 2*SHA384_DIGEST_LEN + 2*AES256_KEY_SIZE */
-#define S2N_MAX_KEY_BLOCK_LEN 160
-
-struct p_hash_state {
- struct s2n_hmac_state s2n_hmac;
- struct s2n_evp_hmac_state evp_hmac;
-};
-
-struct s2n_prf_working_space {
- struct {
- const struct s2n_p_hash_hmac *p_hash_hmac_impl;
- struct p_hash_state p_hash;
- uint8_t digest0[S2N_MAX_DIGEST_LEN];
- uint8_t digest1[S2N_MAX_DIGEST_LEN];
- } tls;
-
- struct {
- struct s2n_hash_state md5;
- struct s2n_hash_state sha1;
- uint8_t md5_digest[MD5_DIGEST_LENGTH];
- uint8_t sha1_digest[SHA_DIGEST_LENGTH];
- } ssl3;
-};
-
-/* The s2n p_hash implementation is abstracted to allow for separate implementations, using
- * either s2n's formally verified HMAC or OpenSSL's EVP HMAC, for use by the TLS PRF. */
-struct s2n_p_hash_hmac {
- int (*alloc) (struct s2n_prf_working_space *ws);
- int (*init) (struct s2n_prf_working_space *ws, s2n_hmac_algorithm alg, struct s2n_blob *secret);
- int (*update) (struct s2n_prf_working_space *ws, const void *data, uint32_t size);
- int (*final) (struct s2n_prf_working_space *ws, void *digest, uint32_t size);
- int (*reset) (struct s2n_prf_working_space *ws);
- int (*cleanup) (struct s2n_prf_working_space *ws);
- int (*free) (struct s2n_prf_working_space *ws);
-};
-
-#include "tls/s2n_connection.h"
-
-extern int s2n_prf_new(struct s2n_connection *conn);
-extern int s2n_prf_free(struct s2n_connection *conn);
-extern int s2n_tls_prf_master_secret(struct s2n_connection *conn, struct s2n_blob *premaster_secret);
-extern int s2n_hybrid_prf_master_secret(struct s2n_connection *conn, struct s2n_blob *premaster_secret);
-extern int s2n_prf_key_expansion(struct s2n_connection *conn);
-extern int s2n_prf_server_finished(struct s2n_connection *conn);
-extern int s2n_prf_client_finished(struct s2n_connection *conn);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#include "crypto/s2n_hash.h"
+#include "crypto/s2n_hmac.h"
+#include "crypto/s2n_openssl.h"
+
+#include "utils/s2n_blob.h"
+
+/* Enough to support TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, 2*SHA384_DIGEST_LEN + 2*AES256_KEY_SIZE */
+#define S2N_MAX_KEY_BLOCK_LEN 160
+
+struct p_hash_state {
+ struct s2n_hmac_state s2n_hmac;
+ struct s2n_evp_hmac_state evp_hmac;
+};
+
+struct s2n_prf_working_space {
+ struct {
+ const struct s2n_p_hash_hmac *p_hash_hmac_impl;
+ struct p_hash_state p_hash;
+ uint8_t digest0[S2N_MAX_DIGEST_LEN];
+ uint8_t digest1[S2N_MAX_DIGEST_LEN];
+ } tls;
+
+ struct {
+ struct s2n_hash_state md5;
+ struct s2n_hash_state sha1;
+ uint8_t md5_digest[MD5_DIGEST_LENGTH];
+ uint8_t sha1_digest[SHA_DIGEST_LENGTH];
+ } ssl3;
+};
+
+/* The s2n p_hash implementation is abstracted to allow for separate implementations, using
+ * either s2n's formally verified HMAC or OpenSSL's EVP HMAC, for use by the TLS PRF. */
+struct s2n_p_hash_hmac {
+ int (*alloc) (struct s2n_prf_working_space *ws);
+ int (*init) (struct s2n_prf_working_space *ws, s2n_hmac_algorithm alg, struct s2n_blob *secret);
+ int (*update) (struct s2n_prf_working_space *ws, const void *data, uint32_t size);
+ int (*final) (struct s2n_prf_working_space *ws, void *digest, uint32_t size);
+ int (*reset) (struct s2n_prf_working_space *ws);
+ int (*cleanup) (struct s2n_prf_working_space *ws);
+ int (*free) (struct s2n_prf_working_space *ws);
+};
+
+#include "tls/s2n_connection.h"
+
+extern int s2n_prf_new(struct s2n_connection *conn);
+extern int s2n_prf_free(struct s2n_connection *conn);
+extern int s2n_tls_prf_master_secret(struct s2n_connection *conn, struct s2n_blob *premaster_secret);
+extern int s2n_hybrid_prf_master_secret(struct s2n_connection *conn, struct s2n_blob *premaster_secret);
+extern int s2n_prf_key_expansion(struct s2n_connection *conn);
+extern int s2n_prf_server_finished(struct s2n_connection *conn);
+extern int s2n_prf_client_finished(struct s2n_connection *conn);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_protocol_preferences.c b/contrib/restricted/aws/s2n/tls/s2n_protocol_preferences.c
index 1137b67277..e0157f4ae4 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_protocol_preferences.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_protocol_preferences.c
@@ -1,55 +1,55 @@
-/*
- * 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 "tls/s2n_connection.h"
-#include "error/s2n_errno.h"
-#include "utils/s2n_safety.h"
-
-int s2n_blob_set_protocol_preferences(struct s2n_blob *application_protocols, const char *const *protocols, int protocol_count)
-{
- struct s2n_stuffer protocol_stuffer = {0};
-
- GUARD(s2n_free(application_protocols));
-
- if (protocols == NULL || protocol_count == 0) {
- /* NULL value indicates no preference, so nothing to do */
- return 0;
- }
-
- GUARD(s2n_stuffer_growable_alloc(&protocol_stuffer, 256));
- for (int i = 0; i < protocol_count; i++) {
- size_t length = strlen(protocols[i]);
- uint8_t protocol[255];
-
- S2N_ERROR_IF(length > 255 || (s2n_stuffer_data_available(&protocol_stuffer) + length + 1) > 65535, S2N_ERR_APPLICATION_PROTOCOL_TOO_LONG);
- memcpy_check(protocol, protocols[i], length);
- GUARD(s2n_stuffer_write_uint8(&protocol_stuffer, length));
- GUARD(s2n_stuffer_write_bytes(&protocol_stuffer, protocol, length));
- }
-
- GUARD(s2n_stuffer_extract_blob(&protocol_stuffer, application_protocols));
- GUARD(s2n_stuffer_free(&protocol_stuffer));
- return 0;
-}
-
-int s2n_config_set_protocol_preferences(struct s2n_config *config, const char *const *protocols, int protocol_count)
-{
- return s2n_blob_set_protocol_preferences(&config->application_protocols, protocols, protocol_count);
-}
-
-int s2n_connection_set_protocol_preferences(struct s2n_connection *conn, const char * const *protocols, int protocol_count)
-{
- return s2n_blob_set_protocol_preferences(&conn->application_protocols_overridden, protocols, protocol_count);
-}
+/*
+ * 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 "tls/s2n_connection.h"
+#include "error/s2n_errno.h"
+#include "utils/s2n_safety.h"
+
+int s2n_blob_set_protocol_preferences(struct s2n_blob *application_protocols, const char *const *protocols, int protocol_count)
+{
+ struct s2n_stuffer protocol_stuffer = {0};
+
+ GUARD(s2n_free(application_protocols));
+
+ if (protocols == NULL || protocol_count == 0) {
+ /* NULL value indicates no preference, so nothing to do */
+ return 0;
+ }
+
+ GUARD(s2n_stuffer_growable_alloc(&protocol_stuffer, 256));
+ for (int i = 0; i < protocol_count; i++) {
+ size_t length = strlen(protocols[i]);
+ uint8_t protocol[255];
+
+ S2N_ERROR_IF(length > 255 || (s2n_stuffer_data_available(&protocol_stuffer) + length + 1) > 65535, S2N_ERR_APPLICATION_PROTOCOL_TOO_LONG);
+ memcpy_check(protocol, protocols[i], length);
+ GUARD(s2n_stuffer_write_uint8(&protocol_stuffer, length));
+ GUARD(s2n_stuffer_write_bytes(&protocol_stuffer, protocol, length));
+ }
+
+ GUARD(s2n_stuffer_extract_blob(&protocol_stuffer, application_protocols));
+ GUARD(s2n_stuffer_free(&protocol_stuffer));
+ return 0;
+}
+
+int s2n_config_set_protocol_preferences(struct s2n_config *config, const char *const *protocols, int protocol_count)
+{
+ return s2n_blob_set_protocol_preferences(&config->application_protocols, protocols, protocol_count);
+}
+
+int s2n_connection_set_protocol_preferences(struct s2n_connection *conn, const char * const *protocols, int protocol_count)
+{
+ return s2n_blob_set_protocol_preferences(&conn->application_protocols_overridden, protocols, protocol_count);
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_psk.c b/contrib/restricted/aws/s2n/tls/s2n_psk.c
index 0ce4e1a140..2d764a00ed 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_psk.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_psk.c
@@ -1,302 +1,302 @@
-/*
- * 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_tls13_keys.h"
-
-#include "tls/s2n_handshake.h"
-#include "tls/s2n_psk.h"
-#include "tls/s2n_tls13_handshake.h"
-#include "tls/s2n_tls.h"
-
-#include "utils/s2n_array.h"
-#include "utils/s2n_mem.h"
-#include "utils/s2n_safety.h"
-
-#define S2N_HASH_ALG_COUNT S2N_HASH_SENTINEL
-
-int s2n_psk_init(struct s2n_psk *psk, s2n_psk_type type)
-{
- notnull_check(psk);
-
- memset_check(psk, 0, sizeof(struct s2n_psk));
- psk->hash_alg = S2N_HASH_SHA256;
- psk->type = type;
-
- return S2N_SUCCESS;
-}
-
-int s2n_psk_new_identity(struct s2n_psk *psk, const uint8_t *identity, size_t identity_size)
-{
- notnull_check(psk);
-
- GUARD(s2n_realloc(&psk->identity, identity_size));
- memcpy_check(psk->identity.data, identity, identity_size);
-
- return S2N_SUCCESS;
-}
-
-int s2n_psk_new_secret(struct s2n_psk *psk, const uint8_t *secret, size_t secret_size)
-{
- notnull_check(psk);
-
- GUARD(s2n_realloc(&psk->secret, secret_size));
- memcpy_check(psk->secret.data, secret, secret_size);
-
- return S2N_SUCCESS;
-}
-
-int s2n_psk_free(struct s2n_psk *psk)
-{
- if (psk == NULL) {
- return S2N_SUCCESS;
- }
-
- GUARD(s2n_free(&psk->early_secret));
- GUARD(s2n_free(&psk->identity));
- GUARD(s2n_free(&psk->secret));
-
- return S2N_SUCCESS;
-}
-
-S2N_RESULT s2n_psk_parameters_init(struct s2n_psk_parameters *params)
-{
- ENSURE_REF(params);
- CHECKED_MEMSET(params, 0, sizeof(struct s2n_psk_parameters));
- GUARD_RESULT(s2n_array_init(&params->psk_list, sizeof(struct s2n_psk)));
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_psk_parameters_free_unused_psks(struct s2n_psk_parameters *params)
-{
- ENSURE_REF(params);
- for (size_t i = 0; i < params->psk_list.len; i++) {
- struct s2n_psk *psk;
- GUARD_RESULT(s2n_array_get(&params->psk_list, i, (void**)&psk));
-
- if(psk == params->chosen_psk) {
- continue;
- }
- GUARD_AS_RESULT(s2n_psk_free(psk));
- }
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_psk_parameters_wipe(struct s2n_psk_parameters *params)
-{
- ENSURE_REF(params);
-
- /* Free all PSKs */
- GUARD_RESULT(s2n_psk_parameters_free_unused_psks(params));
- GUARD_AS_RESULT(s2n_psk_free(params->chosen_psk));
-
- struct s2n_blob psk_list_mem = params->psk_list.mem;
- s2n_result result = s2n_psk_parameters_init(params);
- params->psk_list.mem = psk_list_mem;
-
- return result;
-}
-
-int s2n_psk_parameters_free(struct s2n_psk_parameters *params)
-{
- notnull_check(params);
- GUARD_AS_POSIX(s2n_psk_parameters_wipe(params));
- GUARD(s2n_free(&params->psk_list.mem));
- return S2N_SUCCESS;
-}
-
-/* The binder hash is computed by hashing the concatenation of the current transcript
- * and a partial ClientHello that does not include the binders themselves.
- */
-int s2n_psk_calculate_binder_hash(struct s2n_connection *conn, s2n_hash_algorithm hash_alg,
- const struct s2n_blob *partial_client_hello, struct s2n_blob *output_binder_hash)
-{
- notnull_check(partial_client_hello);
- notnull_check(output_binder_hash);
-
- /* Retrieve the current transcript.
- * The current transcript will be empty unless this handshake included a HelloRetryRequest. */
- struct s2n_hash_state current_hash_state = {0};
- GUARD(s2n_handshake_get_hash_state(conn, hash_alg, &current_hash_state));
-
- /* Copy the current transcript to avoid modifying the original. */
- DEFER_CLEANUP(struct s2n_hash_state hash_copy, s2n_hash_free);
- GUARD(s2n_hash_new(&hash_copy));
- GUARD(s2n_hash_copy(&hash_copy, &current_hash_state));
-
- /* Add the partial client hello to the transcript. */
- GUARD(s2n_hash_update(&hash_copy, partial_client_hello->data, partial_client_hello->size));
-
- /* Get the transcript digest */
- GUARD(s2n_hash_digest(&hash_copy, output_binder_hash->data, output_binder_hash->size));
-
- return S2N_SUCCESS;
-}
-
-static int s2n_tls13_keys_init_with_psk(struct s2n_tls13_keys *keys, struct s2n_psk *psk)
-{
- notnull_check(keys);
-
- keys->hash_algorithm = psk->hash_alg;
- GUARD(s2n_hash_hmac_alg(keys->hash_algorithm, &keys->hmac_algorithm));
- GUARD(s2n_hash_digest_size(keys->hash_algorithm, &keys->size));
- GUARD(s2n_blob_init(&keys->extract_secret, keys->extract_secret_bytes, keys->size));
- GUARD(s2n_blob_init(&keys->derive_secret, keys->derive_secret_bytes, keys->size));
- GUARD(s2n_hmac_new(&keys->hmac));
-
- return S2N_SUCCESS;
-}
-
-/* The binder is computed in the same way as the Finished message
- * (https://tools.ietf.org/html/rfc8446#section-4.4.4) but with the BaseKey being the binder_key
- * derived via the key schedule from the corresponding PSK which is being offered
- * (https://tools.ietf.org/html/rfc8446#section-7.1)
- */
-int s2n_psk_calculate_binder(struct s2n_psk *psk, const struct s2n_blob *binder_hash,
- struct s2n_blob *output_binder)
-{
- notnull_check(psk);
- notnull_check(binder_hash);
- notnull_check(output_binder);
-
- DEFER_CLEANUP(struct s2n_tls13_keys psk_keys, s2n_tls13_keys_free);
- GUARD(s2n_tls13_keys_init_with_psk(&psk_keys, psk));
- eq_check(binder_hash->size, psk_keys.size);
- eq_check(output_binder->size, psk_keys.size);
-
- /* Make sure the early secret is saved on the psk structure for later use */
- GUARD(s2n_realloc(&psk->early_secret, psk_keys.size));
- GUARD(s2n_blob_init(&psk_keys.extract_secret, psk->early_secret.data, psk_keys.size));
-
- /* Derive the binder key */
- GUARD(s2n_tls13_derive_binder_key(&psk_keys, psk));
- struct s2n_blob *binder_key = &psk_keys.derive_secret;
-
- /* Expand the binder key into the finished key */
- s2n_tls13_key_blob(finished_key, psk_keys.size);
- GUARD(s2n_tls13_derive_finished_key(&psk_keys, binder_key, &finished_key));
-
- /* HMAC the binder hash with the binder finished key */
- GUARD(s2n_hkdf_extract(&psk_keys.hmac, psk_keys.hmac_algorithm, &finished_key, binder_hash, output_binder));
-
- return S2N_SUCCESS;
-}
-
-int s2n_psk_verify_binder(struct s2n_connection *conn, struct s2n_psk *psk,
- const struct s2n_blob *partial_client_hello, struct s2n_blob *binder_to_verify)
-{
- notnull_check(psk);
- notnull_check(binder_to_verify);
-
- DEFER_CLEANUP(struct s2n_tls13_keys psk_keys, s2n_tls13_keys_free);
- GUARD(s2n_tls13_keys_init_with_psk(&psk_keys, psk));
- eq_check(binder_to_verify->size, psk_keys.size);
-
- /* Calculate the binder hash from the transcript */
- s2n_tls13_key_blob(binder_hash, psk_keys.size);
- GUARD(s2n_psk_calculate_binder_hash(conn, psk->hash_alg, partial_client_hello, &binder_hash));
-
- /* Calculate the expected binder from the binder hash */
- s2n_tls13_key_blob(expected_binder, psk_keys.size);
- GUARD(s2n_psk_calculate_binder(psk, &binder_hash, &expected_binder));
-
- /* Verify the expected binder matches the given binder.
- * This operation must be constant time. */
- GUARD(s2n_tls13_mac_verify(&psk_keys, &expected_binder, binder_to_verify));
-
- return S2N_SUCCESS;
-}
-
-static S2N_RESULT s2n_psk_write_binder(struct s2n_connection *conn, struct s2n_psk *psk,
- const struct s2n_blob *binder_hash, struct s2n_stuffer *out)
-{
- ENSURE_REF(binder_hash);
-
- struct s2n_blob binder;
- uint8_t binder_data[S2N_TLS13_SECRET_MAX_LEN] = { 0 };
- GUARD_AS_RESULT(s2n_blob_init(&binder, binder_data, binder_hash->size));
-
- GUARD_AS_RESULT(s2n_psk_calculate_binder(psk, binder_hash, &binder));
- GUARD_AS_RESULT(s2n_stuffer_write_uint8(out, binder.size));
- GUARD_AS_RESULT(s2n_stuffer_write(out, &binder));
-
- return S2N_RESULT_OK;
-}
-
-static S2N_RESULT s2n_psk_write_binder_list(struct s2n_connection *conn, const struct s2n_blob *partial_client_hello,
- struct s2n_stuffer *out)
-{
- ENSURE_REF(conn);
- ENSURE_REF(partial_client_hello);
-
- struct s2n_psk_parameters *psk_params = &conn->psk_params;
- struct s2n_array *psk_list = &psk_params->psk_list;
-
- /* Setup memory to hold the binder hashes. We potentially need one for
- * every hash algorithm. */
- uint8_t binder_hashes_data[S2N_HASH_ALG_COUNT][S2N_TLS13_SECRET_MAX_LEN] = { 0 };
- struct s2n_blob binder_hashes[S2N_HASH_ALG_COUNT] = { 0 };
-
- struct s2n_stuffer_reservation binder_list_size = { 0 };
- GUARD_AS_RESULT(s2n_stuffer_reserve_uint16(out, &binder_list_size));
-
- /* Write binder for every psk */
- for (size_t i = 0; i < psk_list->len; i++) {
- struct s2n_psk *psk = NULL;
- GUARD_RESULT(s2n_array_get(psk_list, i, (void**) &psk));
- ENSURE_REF(psk);
-
- /* Retrieve or calculate the binder hash. */
- struct s2n_blob *binder_hash = &binder_hashes[psk->hash_alg];
- if (binder_hash->size == 0) {
- uint8_t hash_size = 0;
- GUARD_AS_RESULT(s2n_hash_digest_size(psk->hash_alg, &hash_size));
- GUARD_AS_RESULT(s2n_blob_init(binder_hash, binder_hashes_data[psk->hash_alg], hash_size));
- GUARD_AS_RESULT(s2n_psk_calculate_binder_hash(conn, psk->hash_alg, partial_client_hello, binder_hash));
- }
-
- GUARD_RESULT(s2n_psk_write_binder(conn, psk, binder_hash, out));
- }
- GUARD_AS_RESULT(s2n_stuffer_write_vector_size(&binder_list_size));
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_finish_psk_extension(struct s2n_connection *conn)
-{
- ENSURE_REF(conn);
-
- if (!conn->psk_params.binder_list_size) {
- return S2N_RESULT_OK;
- }
-
- struct s2n_stuffer *client_hello = &conn->handshake.io;
- struct s2n_psk_parameters *psk_params = &conn->psk_params;
-
- /* Fill in the correct message size. */
- GUARD_AS_RESULT(s2n_handshake_finish_header(client_hello));
-
- /* Remove the empty space allocated for the binder list.
- * It was originally added to ensure the extension / extension list / message sizes
- * were properly calculated. */
- GUARD_AS_RESULT(s2n_stuffer_wipe_n(client_hello, psk_params->binder_list_size));
-
- /* Store the partial client hello for use in calculating the binder hash. */
- struct s2n_blob partial_client_hello = { 0 };
- GUARD_AS_RESULT(s2n_blob_init(&partial_client_hello, client_hello->blob.data,
- s2n_stuffer_data_available(client_hello)));
-
- GUARD_RESULT(s2n_psk_write_binder_list(conn, &partial_client_hello, client_hello));
- return S2N_RESULT_OK;
-}
+/*
+ * 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_tls13_keys.h"
+
+#include "tls/s2n_handshake.h"
+#include "tls/s2n_psk.h"
+#include "tls/s2n_tls13_handshake.h"
+#include "tls/s2n_tls.h"
+
+#include "utils/s2n_array.h"
+#include "utils/s2n_mem.h"
+#include "utils/s2n_safety.h"
+
+#define S2N_HASH_ALG_COUNT S2N_HASH_SENTINEL
+
+int s2n_psk_init(struct s2n_psk *psk, s2n_psk_type type)
+{
+ notnull_check(psk);
+
+ memset_check(psk, 0, sizeof(struct s2n_psk));
+ psk->hash_alg = S2N_HASH_SHA256;
+ psk->type = type;
+
+ return S2N_SUCCESS;
+}
+
+int s2n_psk_new_identity(struct s2n_psk *psk, const uint8_t *identity, size_t identity_size)
+{
+ notnull_check(psk);
+
+ GUARD(s2n_realloc(&psk->identity, identity_size));
+ memcpy_check(psk->identity.data, identity, identity_size);
+
+ return S2N_SUCCESS;
+}
+
+int s2n_psk_new_secret(struct s2n_psk *psk, const uint8_t *secret, size_t secret_size)
+{
+ notnull_check(psk);
+
+ GUARD(s2n_realloc(&psk->secret, secret_size));
+ memcpy_check(psk->secret.data, secret, secret_size);
+
+ return S2N_SUCCESS;
+}
+
+int s2n_psk_free(struct s2n_psk *psk)
+{
+ if (psk == NULL) {
+ return S2N_SUCCESS;
+ }
+
+ GUARD(s2n_free(&psk->early_secret));
+ GUARD(s2n_free(&psk->identity));
+ GUARD(s2n_free(&psk->secret));
+
+ return S2N_SUCCESS;
+}
+
+S2N_RESULT s2n_psk_parameters_init(struct s2n_psk_parameters *params)
+{
+ ENSURE_REF(params);
+ CHECKED_MEMSET(params, 0, sizeof(struct s2n_psk_parameters));
+ GUARD_RESULT(s2n_array_init(&params->psk_list, sizeof(struct s2n_psk)));
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_psk_parameters_free_unused_psks(struct s2n_psk_parameters *params)
+{
+ ENSURE_REF(params);
+ for (size_t i = 0; i < params->psk_list.len; i++) {
+ struct s2n_psk *psk;
+ GUARD_RESULT(s2n_array_get(&params->psk_list, i, (void**)&psk));
+
+ if(psk == params->chosen_psk) {
+ continue;
+ }
+ GUARD_AS_RESULT(s2n_psk_free(psk));
+ }
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_psk_parameters_wipe(struct s2n_psk_parameters *params)
+{
+ ENSURE_REF(params);
+
+ /* Free all PSKs */
+ GUARD_RESULT(s2n_psk_parameters_free_unused_psks(params));
+ GUARD_AS_RESULT(s2n_psk_free(params->chosen_psk));
+
+ struct s2n_blob psk_list_mem = params->psk_list.mem;
+ s2n_result result = s2n_psk_parameters_init(params);
+ params->psk_list.mem = psk_list_mem;
+
+ return result;
+}
+
+int s2n_psk_parameters_free(struct s2n_psk_parameters *params)
+{
+ notnull_check(params);
+ GUARD_AS_POSIX(s2n_psk_parameters_wipe(params));
+ GUARD(s2n_free(&params->psk_list.mem));
+ return S2N_SUCCESS;
+}
+
+/* The binder hash is computed by hashing the concatenation of the current transcript
+ * and a partial ClientHello that does not include the binders themselves.
+ */
+int s2n_psk_calculate_binder_hash(struct s2n_connection *conn, s2n_hash_algorithm hash_alg,
+ const struct s2n_blob *partial_client_hello, struct s2n_blob *output_binder_hash)
+{
+ notnull_check(partial_client_hello);
+ notnull_check(output_binder_hash);
+
+ /* Retrieve the current transcript.
+ * The current transcript will be empty unless this handshake included a HelloRetryRequest. */
+ struct s2n_hash_state current_hash_state = {0};
+ GUARD(s2n_handshake_get_hash_state(conn, hash_alg, &current_hash_state));
+
+ /* Copy the current transcript to avoid modifying the original. */
+ DEFER_CLEANUP(struct s2n_hash_state hash_copy, s2n_hash_free);
+ GUARD(s2n_hash_new(&hash_copy));
+ GUARD(s2n_hash_copy(&hash_copy, &current_hash_state));
+
+ /* Add the partial client hello to the transcript. */
+ GUARD(s2n_hash_update(&hash_copy, partial_client_hello->data, partial_client_hello->size));
+
+ /* Get the transcript digest */
+ GUARD(s2n_hash_digest(&hash_copy, output_binder_hash->data, output_binder_hash->size));
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_tls13_keys_init_with_psk(struct s2n_tls13_keys *keys, struct s2n_psk *psk)
+{
+ notnull_check(keys);
+
+ keys->hash_algorithm = psk->hash_alg;
+ GUARD(s2n_hash_hmac_alg(keys->hash_algorithm, &keys->hmac_algorithm));
+ GUARD(s2n_hash_digest_size(keys->hash_algorithm, &keys->size));
+ GUARD(s2n_blob_init(&keys->extract_secret, keys->extract_secret_bytes, keys->size));
+ GUARD(s2n_blob_init(&keys->derive_secret, keys->derive_secret_bytes, keys->size));
+ GUARD(s2n_hmac_new(&keys->hmac));
+
+ return S2N_SUCCESS;
+}
+
+/* The binder is computed in the same way as the Finished message
+ * (https://tools.ietf.org/html/rfc8446#section-4.4.4) but with the BaseKey being the binder_key
+ * derived via the key schedule from the corresponding PSK which is being offered
+ * (https://tools.ietf.org/html/rfc8446#section-7.1)
+ */
+int s2n_psk_calculate_binder(struct s2n_psk *psk, const struct s2n_blob *binder_hash,
+ struct s2n_blob *output_binder)
+{
+ notnull_check(psk);
+ notnull_check(binder_hash);
+ notnull_check(output_binder);
+
+ DEFER_CLEANUP(struct s2n_tls13_keys psk_keys, s2n_tls13_keys_free);
+ GUARD(s2n_tls13_keys_init_with_psk(&psk_keys, psk));
+ eq_check(binder_hash->size, psk_keys.size);
+ eq_check(output_binder->size, psk_keys.size);
+
+ /* Make sure the early secret is saved on the psk structure for later use */
+ GUARD(s2n_realloc(&psk->early_secret, psk_keys.size));
+ GUARD(s2n_blob_init(&psk_keys.extract_secret, psk->early_secret.data, psk_keys.size));
+
+ /* Derive the binder key */
+ GUARD(s2n_tls13_derive_binder_key(&psk_keys, psk));
+ struct s2n_blob *binder_key = &psk_keys.derive_secret;
+
+ /* Expand the binder key into the finished key */
+ s2n_tls13_key_blob(finished_key, psk_keys.size);
+ GUARD(s2n_tls13_derive_finished_key(&psk_keys, binder_key, &finished_key));
+
+ /* HMAC the binder hash with the binder finished key */
+ GUARD(s2n_hkdf_extract(&psk_keys.hmac, psk_keys.hmac_algorithm, &finished_key, binder_hash, output_binder));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_psk_verify_binder(struct s2n_connection *conn, struct s2n_psk *psk,
+ const struct s2n_blob *partial_client_hello, struct s2n_blob *binder_to_verify)
+{
+ notnull_check(psk);
+ notnull_check(binder_to_verify);
+
+ DEFER_CLEANUP(struct s2n_tls13_keys psk_keys, s2n_tls13_keys_free);
+ GUARD(s2n_tls13_keys_init_with_psk(&psk_keys, psk));
+ eq_check(binder_to_verify->size, psk_keys.size);
+
+ /* Calculate the binder hash from the transcript */
+ s2n_tls13_key_blob(binder_hash, psk_keys.size);
+ GUARD(s2n_psk_calculate_binder_hash(conn, psk->hash_alg, partial_client_hello, &binder_hash));
+
+ /* Calculate the expected binder from the binder hash */
+ s2n_tls13_key_blob(expected_binder, psk_keys.size);
+ GUARD(s2n_psk_calculate_binder(psk, &binder_hash, &expected_binder));
+
+ /* Verify the expected binder matches the given binder.
+ * This operation must be constant time. */
+ GUARD(s2n_tls13_mac_verify(&psk_keys, &expected_binder, binder_to_verify));
+
+ return S2N_SUCCESS;
+}
+
+static S2N_RESULT s2n_psk_write_binder(struct s2n_connection *conn, struct s2n_psk *psk,
+ const struct s2n_blob *binder_hash, struct s2n_stuffer *out)
+{
+ ENSURE_REF(binder_hash);
+
+ struct s2n_blob binder;
+ uint8_t binder_data[S2N_TLS13_SECRET_MAX_LEN] = { 0 };
+ GUARD_AS_RESULT(s2n_blob_init(&binder, binder_data, binder_hash->size));
+
+ GUARD_AS_RESULT(s2n_psk_calculate_binder(psk, binder_hash, &binder));
+ GUARD_AS_RESULT(s2n_stuffer_write_uint8(out, binder.size));
+ GUARD_AS_RESULT(s2n_stuffer_write(out, &binder));
+
+ return S2N_RESULT_OK;
+}
+
+static S2N_RESULT s2n_psk_write_binder_list(struct s2n_connection *conn, const struct s2n_blob *partial_client_hello,
+ struct s2n_stuffer *out)
+{
+ ENSURE_REF(conn);
+ ENSURE_REF(partial_client_hello);
+
+ struct s2n_psk_parameters *psk_params = &conn->psk_params;
+ struct s2n_array *psk_list = &psk_params->psk_list;
+
+ /* Setup memory to hold the binder hashes. We potentially need one for
+ * every hash algorithm. */
+ uint8_t binder_hashes_data[S2N_HASH_ALG_COUNT][S2N_TLS13_SECRET_MAX_LEN] = { 0 };
+ struct s2n_blob binder_hashes[S2N_HASH_ALG_COUNT] = { 0 };
+
+ struct s2n_stuffer_reservation binder_list_size = { 0 };
+ GUARD_AS_RESULT(s2n_stuffer_reserve_uint16(out, &binder_list_size));
+
+ /* Write binder for every psk */
+ for (size_t i = 0; i < psk_list->len; i++) {
+ struct s2n_psk *psk = NULL;
+ GUARD_RESULT(s2n_array_get(psk_list, i, (void**) &psk));
+ ENSURE_REF(psk);
+
+ /* Retrieve or calculate the binder hash. */
+ struct s2n_blob *binder_hash = &binder_hashes[psk->hash_alg];
+ if (binder_hash->size == 0) {
+ uint8_t hash_size = 0;
+ GUARD_AS_RESULT(s2n_hash_digest_size(psk->hash_alg, &hash_size));
+ GUARD_AS_RESULT(s2n_blob_init(binder_hash, binder_hashes_data[psk->hash_alg], hash_size));
+ GUARD_AS_RESULT(s2n_psk_calculate_binder_hash(conn, psk->hash_alg, partial_client_hello, binder_hash));
+ }
+
+ GUARD_RESULT(s2n_psk_write_binder(conn, psk, binder_hash, out));
+ }
+ GUARD_AS_RESULT(s2n_stuffer_write_vector_size(&binder_list_size));
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_finish_psk_extension(struct s2n_connection *conn)
+{
+ ENSURE_REF(conn);
+
+ if (!conn->psk_params.binder_list_size) {
+ return S2N_RESULT_OK;
+ }
+
+ struct s2n_stuffer *client_hello = &conn->handshake.io;
+ struct s2n_psk_parameters *psk_params = &conn->psk_params;
+
+ /* Fill in the correct message size. */
+ GUARD_AS_RESULT(s2n_handshake_finish_header(client_hello));
+
+ /* Remove the empty space allocated for the binder list.
+ * It was originally added to ensure the extension / extension list / message sizes
+ * were properly calculated. */
+ GUARD_AS_RESULT(s2n_stuffer_wipe_n(client_hello, psk_params->binder_list_size));
+
+ /* Store the partial client hello for use in calculating the binder hash. */
+ struct s2n_blob partial_client_hello = { 0 };
+ GUARD_AS_RESULT(s2n_blob_init(&partial_client_hello, client_hello->blob.data,
+ s2n_stuffer_data_available(client_hello)));
+
+ GUARD_RESULT(s2n_psk_write_binder_list(conn, &partial_client_hello, client_hello));
+ return S2N_RESULT_OK;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_psk.h b/contrib/restricted/aws/s2n/tls/s2n_psk.h
index 5568bf0ca5..a805eaddfa 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_psk.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_psk.h
@@ -1,63 +1,63 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <s2n.h>
-
-#include "crypto/s2n_hash.h"
-#include "utils/s2n_array.h"
-#include "utils/s2n_blob.h"
-#include "utils/s2n_result.h"
-
-typedef enum {
- S2N_PSK_TYPE_RESUMPTION,
- S2N_PSK_TYPE_EXTERNAL,
-} s2n_psk_type;
-
-struct s2n_psk {
- s2n_psk_type type;
- struct s2n_blob identity;
- struct s2n_blob secret;
- s2n_hash_algorithm hash_alg;
- uint32_t obfuscated_ticket_age;
- struct s2n_blob early_secret;
-};
-
-struct s2n_psk_parameters {
- struct s2n_array psk_list;
- uint16_t binder_list_size;
- uint8_t chosen_psk_wire_index;
- struct s2n_psk *chosen_psk;
-};
-
-int s2n_psk_init(struct s2n_psk *psk, s2n_psk_type type);
-int s2n_psk_new_identity(struct s2n_psk *psk, const uint8_t *identity, size_t identity_size);
-int s2n_psk_new_secret(struct s2n_psk *psk, const uint8_t *secret, size_t secret_size);
-int s2n_psk_free(struct s2n_psk *psk);
-
-S2N_RESULT s2n_psk_parameters_init(struct s2n_psk_parameters *params);
-S2N_RESULT s2n_psk_parameters_wipe(struct s2n_psk_parameters *params);
-S2N_RESULT s2n_psk_parameters_free_unused_psks(struct s2n_psk_parameters *params);
-int s2n_psk_parameters_free(struct s2n_psk_parameters *params);
-
-S2N_RESULT s2n_finish_psk_extension(struct s2n_connection *conn);
-
-int s2n_psk_calculate_binder_hash(struct s2n_connection *conn, s2n_hash_algorithm hash_alg,
- const struct s2n_blob *partial_client_hello, struct s2n_blob *output_binder_hash);
-int s2n_psk_calculate_binder(struct s2n_psk *psk, const struct s2n_blob *binder_hash,
- struct s2n_blob *output_binder);
-int s2n_psk_verify_binder(struct s2n_connection *conn, struct s2n_psk *psk,
- const struct s2n_blob *partial_client_hello, struct s2n_blob *binder_to_verify);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <s2n.h>
+
+#include "crypto/s2n_hash.h"
+#include "utils/s2n_array.h"
+#include "utils/s2n_blob.h"
+#include "utils/s2n_result.h"
+
+typedef enum {
+ S2N_PSK_TYPE_RESUMPTION,
+ S2N_PSK_TYPE_EXTERNAL,
+} s2n_psk_type;
+
+struct s2n_psk {
+ s2n_psk_type type;
+ struct s2n_blob identity;
+ struct s2n_blob secret;
+ s2n_hash_algorithm hash_alg;
+ uint32_t obfuscated_ticket_age;
+ struct s2n_blob early_secret;
+};
+
+struct s2n_psk_parameters {
+ struct s2n_array psk_list;
+ uint16_t binder_list_size;
+ uint8_t chosen_psk_wire_index;
+ struct s2n_psk *chosen_psk;
+};
+
+int s2n_psk_init(struct s2n_psk *psk, s2n_psk_type type);
+int s2n_psk_new_identity(struct s2n_psk *psk, const uint8_t *identity, size_t identity_size);
+int s2n_psk_new_secret(struct s2n_psk *psk, const uint8_t *secret, size_t secret_size);
+int s2n_psk_free(struct s2n_psk *psk);
+
+S2N_RESULT s2n_psk_parameters_init(struct s2n_psk_parameters *params);
+S2N_RESULT s2n_psk_parameters_wipe(struct s2n_psk_parameters *params);
+S2N_RESULT s2n_psk_parameters_free_unused_psks(struct s2n_psk_parameters *params);
+int s2n_psk_parameters_free(struct s2n_psk_parameters *params);
+
+S2N_RESULT s2n_finish_psk_extension(struct s2n_connection *conn);
+
+int s2n_psk_calculate_binder_hash(struct s2n_connection *conn, s2n_hash_algorithm hash_alg,
+ const struct s2n_blob *partial_client_hello, struct s2n_blob *output_binder_hash);
+int s2n_psk_calculate_binder(struct s2n_psk *psk, const struct s2n_blob *binder_hash,
+ struct s2n_blob *output_binder);
+int s2n_psk_verify_binder(struct s2n_connection *conn, struct s2n_psk *psk,
+ const struct s2n_blob *partial_client_hello, struct s2n_blob *binder_to_verify);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_quic_support.c b/contrib/restricted/aws/s2n/tls/s2n_quic_support.c
index 33ee5e6ad8..226b87ee9a 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_quic_support.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_quic_support.c
@@ -1,115 +1,115 @@
-/*
- * 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 "tls/s2n_quic_support.h"
-
-#include "tls/s2n_connection.h"
-#include "tls/s2n_tls13.h"
-#include "tls/s2n_tls.h"
-
-#include "utils/s2n_mem.h"
-#include "utils/s2n_safety.h"
-
-/* When reading and writing records with TCP, S2N sets its input and output buffers
- * to the maximum record fragment size to prevent resizing those buffers later.
- *
- * However, because S2N with QUIC reads and writes messages instead of records,
- * the "maximum size" for the input and output buffers would be the maximum message size: 64k.
- * Since most messages are MUCH smaller than that (<3k), setting the buffer that large is wasteful.
- *
- * Instead, we intentionally choose a smaller size and accept that an abnormally large message
- * could cause the buffer to resize. */
-#define S2N_EXPECTED_QUIC_MESSAGE_SIZE S2N_DEFAULT_FRAGMENT_LENGTH
-
-S2N_RESULT s2n_read_in_bytes(struct s2n_connection *conn, struct s2n_stuffer *output, uint32_t length);
-
-int s2n_config_enable_quic(struct s2n_config *config)
-{
- notnull_check(config);
- config->quic_enabled = true;
- return S2N_SUCCESS;
-}
-
-int s2n_connection_set_quic_transport_parameters(struct s2n_connection *conn,
- const uint8_t *data_buffer, uint16_t data_len)
-{
- notnull_check(conn);
-
- GUARD(s2n_free(&conn->our_quic_transport_parameters));
- GUARD(s2n_alloc(&conn->our_quic_transport_parameters, data_len));
- memcpy_check(conn->our_quic_transport_parameters.data, data_buffer, data_len);
-
- return S2N_SUCCESS;
-}
-
-int s2n_connection_get_quic_transport_parameters(struct s2n_connection *conn,
- const uint8_t **data_buffer, uint16_t *data_len)
-{
- notnull_check(conn);
- notnull_check(data_buffer);
- notnull_check(data_len);
-
- *data_buffer = conn->peer_quic_transport_parameters.data;
- *data_len = conn->peer_quic_transport_parameters.size;
-
- return S2N_SUCCESS;
-}
-
-int s2n_connection_set_secret_callback(struct s2n_connection *conn, s2n_secret_cb cb_func, void *ctx)
-{
- notnull_check(conn);
- notnull_check(cb_func);
-
- conn->secret_cb = cb_func;
- conn->secret_cb_context = ctx;
-
- return S2N_SUCCESS;
-}
-
-/* When using QUIC, S2N reads unencrypted handshake messages instead of encrypted records.
- * This method sets up the S2N input buffers to match the results of using s2n_read_full_record.
- */
-S2N_RESULT s2n_quic_read_handshake_message(struct s2n_connection *conn, uint8_t *message_type)
-{
- ENSURE_REF(conn);
-
- /* Allocate stuffer space now so that we don't have to realloc later in the handshake. */
- GUARD_AS_RESULT(s2n_stuffer_resize_if_empty(&conn->in, S2N_EXPECTED_QUIC_MESSAGE_SIZE));
-
- GUARD_RESULT(s2n_read_in_bytes(conn, &conn->handshake.io, TLS_HANDSHAKE_HEADER_LENGTH));
-
- uint32_t message_len;
- GUARD_AS_RESULT(s2n_handshake_parse_header(conn, message_type, &message_len));
- GUARD_AS_RESULT(s2n_stuffer_reread(&conn->handshake.io));
-
- ENSURE(message_len < S2N_MAXIMUM_HANDSHAKE_MESSAGE_LENGTH, S2N_ERR_BAD_MESSAGE);
- GUARD_RESULT(s2n_read_in_bytes(conn, &conn->in, message_len));
-
- return S2N_RESULT_OK;
-}
-
-/* When using QUIC, S2N writes unencrypted handshake messages instead of encrypted records.
- * This method sets up the S2N output buffer to match the result of using s2n_record_write.
- */
-S2N_RESULT s2n_quic_write_handshake_message(struct s2n_connection *conn, struct s2n_blob *in)
-{
- ENSURE_REF(conn);
-
- /* Allocate stuffer space now so that we don't have to realloc later in the handshake. */
- GUARD_AS_RESULT(s2n_stuffer_resize_if_empty(&conn->out, S2N_EXPECTED_QUIC_MESSAGE_SIZE));
-
- GUARD_AS_RESULT(s2n_stuffer_write(&conn->out, in));
- return S2N_RESULT_OK;
-}
+/*
+ * 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 "tls/s2n_quic_support.h"
+
+#include "tls/s2n_connection.h"
+#include "tls/s2n_tls13.h"
+#include "tls/s2n_tls.h"
+
+#include "utils/s2n_mem.h"
+#include "utils/s2n_safety.h"
+
+/* When reading and writing records with TCP, S2N sets its input and output buffers
+ * to the maximum record fragment size to prevent resizing those buffers later.
+ *
+ * However, because S2N with QUIC reads and writes messages instead of records,
+ * the "maximum size" for the input and output buffers would be the maximum message size: 64k.
+ * Since most messages are MUCH smaller than that (<3k), setting the buffer that large is wasteful.
+ *
+ * Instead, we intentionally choose a smaller size and accept that an abnormally large message
+ * could cause the buffer to resize. */
+#define S2N_EXPECTED_QUIC_MESSAGE_SIZE S2N_DEFAULT_FRAGMENT_LENGTH
+
+S2N_RESULT s2n_read_in_bytes(struct s2n_connection *conn, struct s2n_stuffer *output, uint32_t length);
+
+int s2n_config_enable_quic(struct s2n_config *config)
+{
+ notnull_check(config);
+ config->quic_enabled = true;
+ return S2N_SUCCESS;
+}
+
+int s2n_connection_set_quic_transport_parameters(struct s2n_connection *conn,
+ const uint8_t *data_buffer, uint16_t data_len)
+{
+ notnull_check(conn);
+
+ GUARD(s2n_free(&conn->our_quic_transport_parameters));
+ GUARD(s2n_alloc(&conn->our_quic_transport_parameters, data_len));
+ memcpy_check(conn->our_quic_transport_parameters.data, data_buffer, data_len);
+
+ return S2N_SUCCESS;
+}
+
+int s2n_connection_get_quic_transport_parameters(struct s2n_connection *conn,
+ const uint8_t **data_buffer, uint16_t *data_len)
+{
+ notnull_check(conn);
+ notnull_check(data_buffer);
+ notnull_check(data_len);
+
+ *data_buffer = conn->peer_quic_transport_parameters.data;
+ *data_len = conn->peer_quic_transport_parameters.size;
+
+ return S2N_SUCCESS;
+}
+
+int s2n_connection_set_secret_callback(struct s2n_connection *conn, s2n_secret_cb cb_func, void *ctx)
+{
+ notnull_check(conn);
+ notnull_check(cb_func);
+
+ conn->secret_cb = cb_func;
+ conn->secret_cb_context = ctx;
+
+ return S2N_SUCCESS;
+}
+
+/* When using QUIC, S2N reads unencrypted handshake messages instead of encrypted records.
+ * This method sets up the S2N input buffers to match the results of using s2n_read_full_record.
+ */
+S2N_RESULT s2n_quic_read_handshake_message(struct s2n_connection *conn, uint8_t *message_type)
+{
+ ENSURE_REF(conn);
+
+ /* Allocate stuffer space now so that we don't have to realloc later in the handshake. */
+ GUARD_AS_RESULT(s2n_stuffer_resize_if_empty(&conn->in, S2N_EXPECTED_QUIC_MESSAGE_SIZE));
+
+ GUARD_RESULT(s2n_read_in_bytes(conn, &conn->handshake.io, TLS_HANDSHAKE_HEADER_LENGTH));
+
+ uint32_t message_len;
+ GUARD_AS_RESULT(s2n_handshake_parse_header(conn, message_type, &message_len));
+ GUARD_AS_RESULT(s2n_stuffer_reread(&conn->handshake.io));
+
+ ENSURE(message_len < S2N_MAXIMUM_HANDSHAKE_MESSAGE_LENGTH, S2N_ERR_BAD_MESSAGE);
+ GUARD_RESULT(s2n_read_in_bytes(conn, &conn->in, message_len));
+
+ return S2N_RESULT_OK;
+}
+
+/* When using QUIC, S2N writes unencrypted handshake messages instead of encrypted records.
+ * This method sets up the S2N output buffer to match the result of using s2n_record_write.
+ */
+S2N_RESULT s2n_quic_write_handshake_message(struct s2n_connection *conn, struct s2n_blob *in)
+{
+ ENSURE_REF(conn);
+
+ /* Allocate stuffer space now so that we don't have to realloc later in the handshake. */
+ GUARD_AS_RESULT(s2n_stuffer_resize_if_empty(&conn->out, S2N_EXPECTED_QUIC_MESSAGE_SIZE));
+
+ GUARD_AS_RESULT(s2n_stuffer_write(&conn->out, in));
+ return S2N_RESULT_OK;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_quic_support.h b/contrib/restricted/aws/s2n/tls/s2n_quic_support.h
index 621c4dcd0f..459e03a2fd 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_quic_support.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_quic_support.h
@@ -1,76 +1,76 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "api/s2n.h"
-
-/*
- * APIs intended to support an external implementation of the QUIC protocol:
- * https://datatracker.ietf.org/wg/quic/about/
- *
- * QUIC requires access to parts of S2N not usually surfaced to customers. These APIs change
- * the behavior of S2N in potentially dangerous ways and should only be used by implementations
- * of the QUIC protocol.
- *
- * Additionally, the QUIC RFC is not yet finalized, so all QUIC APIs are considered experimental
- * and are subject to change without notice. They should only be used for testing purposes.
- */
-
-S2N_API int s2n_config_enable_quic(struct s2n_config *config);
-
-/*
- * Set the data to be sent in the quic_transport_parameters extension.
- * The data provided will be copied into a buffer owned by S2N.
- */
-S2N_API int s2n_connection_set_quic_transport_parameters(struct s2n_connection *conn,
- const uint8_t *data_buffer, uint16_t data_len);
-
-/*
- * Retrieve the data from the peer's quic_transport_parameters extension.
- * data_buffer will be set to a buffer owned by S2N which will be freed when the connection is freed.
- * data_len will be set to the length of the data returned.
- *
- * S2N treats the extension data as opaque bytes and performs no validation.
- */
-S2N_API int s2n_connection_get_quic_transport_parameters(struct s2n_connection *conn,
- const uint8_t **data_buffer, uint16_t *data_len);
-
-typedef enum {
- S2N_CLIENT_EARLY_TRAFFIC_SECRET = 0,
- S2N_CLIENT_HANDSHAKE_TRAFFIC_SECRET,
- S2N_SERVER_HANDSHAKE_TRAFFIC_SECRET,
- S2N_CLIENT_APPLICATION_TRAFFIC_SECRET,
- S2N_SERVER_APPLICATION_TRAFFIC_SECRET,
-} s2n_secret_type_t;
-
-/*
- * Called when S2N begins using a new key.
- *
- * The memory pointed to by "secret" will be wiped after this method returns and should be copied by
- * the application if necessary. The application should also be very careful managing the memory and
- * lifespan of the secret: if the secret is compromised, TLS is compromised.
- */
-typedef int (*s2n_secret_cb) (void* context, struct s2n_connection *conn,
- s2n_secret_type_t secret_type,
- uint8_t *secret, uint8_t secret_size);
-
-/*
- * Set the function to be called when S2N begins using a new key.
- *
- * The callback function will ONLY be triggered if QUIC is enabled. This API is not intended to be
- * used outside of a QUIC implementation.
- */
-int s2n_connection_set_secret_callback(struct s2n_connection *conn, s2n_secret_cb cb_func, void *ctx);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "api/s2n.h"
+
+/*
+ * APIs intended to support an external implementation of the QUIC protocol:
+ * https://datatracker.ietf.org/wg/quic/about/
+ *
+ * QUIC requires access to parts of S2N not usually surfaced to customers. These APIs change
+ * the behavior of S2N in potentially dangerous ways and should only be used by implementations
+ * of the QUIC protocol.
+ *
+ * Additionally, the QUIC RFC is not yet finalized, so all QUIC APIs are considered experimental
+ * and are subject to change without notice. They should only be used for testing purposes.
+ */
+
+S2N_API int s2n_config_enable_quic(struct s2n_config *config);
+
+/*
+ * Set the data to be sent in the quic_transport_parameters extension.
+ * The data provided will be copied into a buffer owned by S2N.
+ */
+S2N_API int s2n_connection_set_quic_transport_parameters(struct s2n_connection *conn,
+ const uint8_t *data_buffer, uint16_t data_len);
+
+/*
+ * Retrieve the data from the peer's quic_transport_parameters extension.
+ * data_buffer will be set to a buffer owned by S2N which will be freed when the connection is freed.
+ * data_len will be set to the length of the data returned.
+ *
+ * S2N treats the extension data as opaque bytes and performs no validation.
+ */
+S2N_API int s2n_connection_get_quic_transport_parameters(struct s2n_connection *conn,
+ const uint8_t **data_buffer, uint16_t *data_len);
+
+typedef enum {
+ S2N_CLIENT_EARLY_TRAFFIC_SECRET = 0,
+ S2N_CLIENT_HANDSHAKE_TRAFFIC_SECRET,
+ S2N_SERVER_HANDSHAKE_TRAFFIC_SECRET,
+ S2N_CLIENT_APPLICATION_TRAFFIC_SECRET,
+ S2N_SERVER_APPLICATION_TRAFFIC_SECRET,
+} s2n_secret_type_t;
+
+/*
+ * Called when S2N begins using a new key.
+ *
+ * The memory pointed to by "secret" will be wiped after this method returns and should be copied by
+ * the application if necessary. The application should also be very careful managing the memory and
+ * lifespan of the secret: if the secret is compromised, TLS is compromised.
+ */
+typedef int (*s2n_secret_cb) (void* context, struct s2n_connection *conn,
+ s2n_secret_type_t secret_type,
+ uint8_t *secret, uint8_t secret_size);
+
+/*
+ * Set the function to be called when S2N begins using a new key.
+ *
+ * The callback function will ONLY be triggered if QUIC is enabled. This API is not intended to be
+ * used outside of a QUIC implementation.
+ */
+int s2n_connection_set_secret_callback(struct s2n_connection *conn, s2n_secret_cb cb_func, void *ctx);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_record.h b/contrib/restricted/aws/s2n/tls/s2n_record.h
index 2e081c2876..f5b6f27502 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_record.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_record.h
@@ -1,34 +1,34 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <stdint.h>
-
-#include "s2n_connection.h"
-
-#define TLS13_CONTENT_TYPE_LENGTH 1
-
-extern S2N_RESULT s2n_record_max_write_payload_size(struct s2n_connection *conn, uint16_t *max_fragment_size);
-extern S2N_RESULT s2n_record_min_write_payload_size(struct s2n_connection *conn, uint16_t *payload_size);
-extern int s2n_record_write(struct s2n_connection *conn, uint8_t content_type, struct s2n_blob *in);
-extern int s2n_record_writev(struct s2n_connection *conn, uint8_t content_type, const struct iovec *in, int in_count, size_t offs, size_t to_write);
-extern int s2n_record_parse(struct s2n_connection *conn);
-extern int s2n_record_header_parse(struct s2n_connection *conn, uint8_t * content_type, uint16_t * fragment_length);
-extern int s2n_tls13_parse_record_type(struct s2n_stuffer *stuffer, uint8_t * record_type);
-extern int s2n_sslv2_record_header_parse(struct s2n_connection *conn, uint8_t * record_type, uint8_t * client_protocol_version, uint16_t * fragment_length);
-extern int s2n_verify_cbc(struct s2n_connection *conn, struct s2n_hmac_state *hmac, struct s2n_blob *decrypted);
-extern S2N_RESULT s2n_aead_aad_init(const struct s2n_connection *conn, uint8_t * sequence_number, uint8_t content_type, uint16_t record_length, struct s2n_stuffer *ad);
-extern S2N_RESULT s2n_tls13_aead_aad_init(uint16_t record_length, uint8_t tag_length, struct s2n_stuffer *ad);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#include "s2n_connection.h"
+
+#define TLS13_CONTENT_TYPE_LENGTH 1
+
+extern S2N_RESULT s2n_record_max_write_payload_size(struct s2n_connection *conn, uint16_t *max_fragment_size);
+extern S2N_RESULT s2n_record_min_write_payload_size(struct s2n_connection *conn, uint16_t *payload_size);
+extern int s2n_record_write(struct s2n_connection *conn, uint8_t content_type, struct s2n_blob *in);
+extern int s2n_record_writev(struct s2n_connection *conn, uint8_t content_type, const struct iovec *in, int in_count, size_t offs, size_t to_write);
+extern int s2n_record_parse(struct s2n_connection *conn);
+extern int s2n_record_header_parse(struct s2n_connection *conn, uint8_t * content_type, uint16_t * fragment_length);
+extern int s2n_tls13_parse_record_type(struct s2n_stuffer *stuffer, uint8_t * record_type);
+extern int s2n_sslv2_record_header_parse(struct s2n_connection *conn, uint8_t * record_type, uint8_t * client_protocol_version, uint16_t * fragment_length);
+extern int s2n_verify_cbc(struct s2n_connection *conn, struct s2n_hmac_state *hmac, struct s2n_blob *decrypted);
+extern S2N_RESULT s2n_aead_aad_init(const struct s2n_connection *conn, uint8_t * sequence_number, uint8_t content_type, uint16_t record_length, struct s2n_stuffer *ad);
+extern S2N_RESULT s2n_tls13_aead_aad_init(uint16_t record_length, uint8_t tag_length, struct s2n_stuffer *ad);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_record_read.c b/contrib/restricted/aws/s2n/tls/s2n_record_read.c
index 28fe7681f5..7b8536818e 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_record_read.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_record_read.c
@@ -1,210 +1,210 @@
-/*
- * 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 <sys/param.h>
-
-#include "crypto/s2n_sequence.h"
-#include "crypto/s2n_cipher.h"
-#include "crypto/s2n_hmac.h"
-
-#include "error/s2n_errno.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_crypto.h"
-#include "tls/s2n_record_read.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_blob.h"
-
-int s2n_sslv2_record_header_parse(
- struct s2n_connection *conn,
- uint8_t * record_type,
- uint8_t * client_protocol_version,
- uint16_t * fragment_length)
-{
- struct s2n_stuffer *in = &conn->header_in;
-
- S2N_ERROR_IF(s2n_stuffer_data_available(in) < S2N_TLS_RECORD_HEADER_LENGTH, S2N_ERR_BAD_MESSAGE);
-
- GUARD(s2n_stuffer_read_uint16(in, fragment_length));
-
- /* Adjust to account for the 3 bytes of payload data we consumed in the header */
- *fragment_length -= 3;
-
- GUARD(s2n_stuffer_read_uint8(in, record_type));
-
- uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN];
- GUARD(s2n_stuffer_read_bytes(in, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
-
- *client_protocol_version = (protocol_version[0] * 10) + protocol_version[1];
-
- return 0;
-}
-
-int s2n_record_header_parse(
- struct s2n_connection *conn,
- uint8_t *content_type,
- uint16_t *fragment_length)
-{
- struct s2n_stuffer *in = &conn->header_in;
-
- S2N_ERROR_IF(s2n_stuffer_data_available(in) < S2N_TLS_RECORD_HEADER_LENGTH, S2N_ERR_BAD_MESSAGE);
-
- GUARD(s2n_stuffer_read_uint8(in, content_type));
-
- uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN];
- GUARD(s2n_stuffer_read_bytes(in, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
-
- const uint8_t version = (protocol_version[0] * 10) + protocol_version[1];
- /* https://tools.ietf.org/html/rfc5246#appendix-E.1 states that servers must accept any value {03,XX} as the record
- * layer version number for the first TLS record. There is some ambiguity here because the client does not know
- * what version to use in the record header prior to receiving the ServerHello. Some client implementations may use
- * a garbage value(not {03,XX}) in the ClientHello.
- * Choose to be lenient to these clients. After protocol negotiation, we will enforce that all record versions
- * match the negotiated version.
- */
-
- S2N_ERROR_IF(conn->actual_protocol_version_established &&
- MIN(conn->actual_protocol_version, S2N_TLS12) /* check against legacy record version (1.2) in tls 1.3 */
- != version, S2N_ERR_BAD_MESSAGE);
- GUARD(s2n_stuffer_read_uint16(in, fragment_length));
-
- /* Some servers send fragments that are above the maximum length. (e.g.
- * Openssl 1.0.1, so we don't check if the fragment length is >
- * S2N_TLS_MAXIMUM_FRAGMENT_LENGTH. The on-the-wire max is 65k
- */
- GUARD(s2n_stuffer_reread(in));
-
- return 0;
-}
-
-/* In TLS 1.3, handle CCS message as unprotected records all the time.
- * https://tools.ietf.org/html/rfc8446#section-5
- *
- * In TLS 1.2 and TLS 1.3 Alert messages are plaintext or encrypted
- * depending on the context of the connection. If we receive an encrypted
- * alert, the record type is TLS_APPLICATION_DATA at this point. It will
- * be decrypted and processed in s2n_handshake_io. We may receive a
- * plaintext alert if we hit an error before the handshake completed
- * (like a certificate failed to validate).
- * https://tools.ietf.org/html/rfc8446#section-6
- *
- * This function is specific to TLS 1.3 to avoid changing the behavior
- * of existing interpretation of TLS 1.2 alerts. */
-static bool s2n_is_tls13_plaintext_content(struct s2n_connection *conn, uint8_t content_type)
-{
- return conn->actual_protocol_version == S2N_TLS13 && (content_type == TLS_ALERT || content_type == TLS_CHANGE_CIPHER_SPEC);
-}
-
-int s2n_record_parse(struct s2n_connection *conn)
-{
- uint8_t content_type;
- uint16_t encrypted_length;
- GUARD(s2n_record_header_parse(conn, &content_type, &encrypted_length));
-
- struct s2n_crypto_parameters *current_client_crypto = conn->client;
- struct s2n_crypto_parameters *current_server_crypto = conn->server;
- if (s2n_is_tls13_plaintext_content(conn, content_type)) {
- conn->client = &conn->initial;
- conn->server = &conn->initial;
- }
-
- const struct s2n_cipher_suite *cipher_suite = conn->client->cipher_suite;
- uint8_t *implicit_iv = conn->client->client_implicit_iv;
- struct s2n_hmac_state *mac = &conn->client->client_record_mac;
- uint8_t *sequence_number = conn->client->client_sequence_number;
- struct s2n_session_key *session_key = &conn->client->client_key;
-
- if (conn->mode == S2N_CLIENT) {
- cipher_suite = conn->server->cipher_suite;
- implicit_iv = conn->server->server_implicit_iv;
- mac = &conn->server->server_record_mac;
- sequence_number = conn->server->server_sequence_number;
- session_key = &conn->server->server_key;
- }
-
- if (s2n_is_tls13_plaintext_content(conn, content_type)) {
- conn->client = current_client_crypto;
- conn->server = current_server_crypto;
- }
-
- switch (cipher_suite->record_alg->cipher->type) {
- case S2N_AEAD:
- GUARD(s2n_record_parse_aead(cipher_suite, conn, content_type, encrypted_length, implicit_iv, mac, sequence_number, session_key));
- break;
- case S2N_CBC:
- GUARD(s2n_record_parse_cbc(cipher_suite, conn, content_type, encrypted_length, implicit_iv, mac, sequence_number, session_key));
- break;
- case S2N_COMPOSITE:
- GUARD(s2n_record_parse_composite(cipher_suite, conn, content_type, encrypted_length, implicit_iv, mac, sequence_number, session_key));
- break;
- case S2N_STREAM:
- GUARD(s2n_record_parse_stream(cipher_suite, conn, content_type, encrypted_length, implicit_iv, mac, sequence_number, session_key));
- break;
- default:
- S2N_ERROR(S2N_ERR_CIPHER_TYPE);
- break;
- }
-
- return 0;
-}
-
-int s2n_tls13_parse_record_type(struct s2n_stuffer *stuffer, uint8_t *record_type)
-{
- uint32_t bytes_left = s2n_stuffer_data_available(stuffer);
-
- /* From rfc8446 Section 5.4
- * The presence of padding does not change the overall record size
- * limitations: the full encoded TLSInnerPlaintext MUST NOT exceed 2^14
- * + 1 octets
- *
- * Certain versions of Java can generate inner plaintexts with lengths up to
- * S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH + 16 (See JDK-8221253)
- * However, after the padding is stripped, the result will always be no more than
- * S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH - 1
- */
- S2N_ERROR_IF(bytes_left > S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH + 16, S2N_ERR_MAX_INNER_PLAINTEXT_SIZE);
-
- /* set cursor to the end of the stuffer */
- GUARD(s2n_stuffer_skip_read(stuffer, bytes_left));
-
- /* Record type should have values greater than zero.
- * If zero, treat as padding, keep reading and wiping from the back
- * until a non-zero value is found
- */
- *record_type = 0;
- while (*record_type == 0) {
- /* back the cursor by one to read off the last byte */
- GUARD(s2n_stuffer_rewind_read(stuffer, 1));
-
- /* set the record type */
- GUARD(s2n_stuffer_read_uint8(stuffer, record_type));
-
- /* wipe the last byte at the end of the stuffer */
- GUARD(s2n_stuffer_wipe_n(stuffer, 1));
- }
-
- /* only the original plaintext should remain */
- /* now reset the read cursor at where it should be */
- GUARD(s2n_stuffer_reread(stuffer));
-
- /* Even in the incorrect case above with up to 16 extra bytes, we should never see too much data after unpadding */
- S2N_ERROR_IF(s2n_stuffer_data_available(stuffer) > S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH - 1, S2N_ERR_MAX_INNER_PLAINTEXT_SIZE);
-
- return 0;
-}
+/*
+ * 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 <sys/param.h>
+
+#include "crypto/s2n_sequence.h"
+#include "crypto/s2n_cipher.h"
+#include "crypto/s2n_hmac.h"
+
+#include "error/s2n_errno.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_crypto.h"
+#include "tls/s2n_record_read.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_blob.h"
+
+int s2n_sslv2_record_header_parse(
+ struct s2n_connection *conn,
+ uint8_t * record_type,
+ uint8_t * client_protocol_version,
+ uint16_t * fragment_length)
+{
+ struct s2n_stuffer *in = &conn->header_in;
+
+ S2N_ERROR_IF(s2n_stuffer_data_available(in) < S2N_TLS_RECORD_HEADER_LENGTH, S2N_ERR_BAD_MESSAGE);
+
+ GUARD(s2n_stuffer_read_uint16(in, fragment_length));
+
+ /* Adjust to account for the 3 bytes of payload data we consumed in the header */
+ *fragment_length -= 3;
+
+ GUARD(s2n_stuffer_read_uint8(in, record_type));
+
+ uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN];
+ GUARD(s2n_stuffer_read_bytes(in, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
+
+ *client_protocol_version = (protocol_version[0] * 10) + protocol_version[1];
+
+ return 0;
+}
+
+int s2n_record_header_parse(
+ struct s2n_connection *conn,
+ uint8_t *content_type,
+ uint16_t *fragment_length)
+{
+ struct s2n_stuffer *in = &conn->header_in;
+
+ S2N_ERROR_IF(s2n_stuffer_data_available(in) < S2N_TLS_RECORD_HEADER_LENGTH, S2N_ERR_BAD_MESSAGE);
+
+ GUARD(s2n_stuffer_read_uint8(in, content_type));
+
+ uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN];
+ GUARD(s2n_stuffer_read_bytes(in, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
+
+ const uint8_t version = (protocol_version[0] * 10) + protocol_version[1];
+ /* https://tools.ietf.org/html/rfc5246#appendix-E.1 states that servers must accept any value {03,XX} as the record
+ * layer version number for the first TLS record. There is some ambiguity here because the client does not know
+ * what version to use in the record header prior to receiving the ServerHello. Some client implementations may use
+ * a garbage value(not {03,XX}) in the ClientHello.
+ * Choose to be lenient to these clients. After protocol negotiation, we will enforce that all record versions
+ * match the negotiated version.
+ */
+
+ S2N_ERROR_IF(conn->actual_protocol_version_established &&
+ MIN(conn->actual_protocol_version, S2N_TLS12) /* check against legacy record version (1.2) in tls 1.3 */
+ != version, S2N_ERR_BAD_MESSAGE);
+ GUARD(s2n_stuffer_read_uint16(in, fragment_length));
+
+ /* Some servers send fragments that are above the maximum length. (e.g.
+ * Openssl 1.0.1, so we don't check if the fragment length is >
+ * S2N_TLS_MAXIMUM_FRAGMENT_LENGTH. The on-the-wire max is 65k
+ */
+ GUARD(s2n_stuffer_reread(in));
+
+ return 0;
+}
+
+/* In TLS 1.3, handle CCS message as unprotected records all the time.
+ * https://tools.ietf.org/html/rfc8446#section-5
+ *
+ * In TLS 1.2 and TLS 1.3 Alert messages are plaintext or encrypted
+ * depending on the context of the connection. If we receive an encrypted
+ * alert, the record type is TLS_APPLICATION_DATA at this point. It will
+ * be decrypted and processed in s2n_handshake_io. We may receive a
+ * plaintext alert if we hit an error before the handshake completed
+ * (like a certificate failed to validate).
+ * https://tools.ietf.org/html/rfc8446#section-6
+ *
+ * This function is specific to TLS 1.3 to avoid changing the behavior
+ * of existing interpretation of TLS 1.2 alerts. */
+static bool s2n_is_tls13_plaintext_content(struct s2n_connection *conn, uint8_t content_type)
+{
+ return conn->actual_protocol_version == S2N_TLS13 && (content_type == TLS_ALERT || content_type == TLS_CHANGE_CIPHER_SPEC);
+}
+
+int s2n_record_parse(struct s2n_connection *conn)
+{
+ uint8_t content_type;
+ uint16_t encrypted_length;
+ GUARD(s2n_record_header_parse(conn, &content_type, &encrypted_length));
+
+ struct s2n_crypto_parameters *current_client_crypto = conn->client;
+ struct s2n_crypto_parameters *current_server_crypto = conn->server;
+ if (s2n_is_tls13_plaintext_content(conn, content_type)) {
+ conn->client = &conn->initial;
+ conn->server = &conn->initial;
+ }
+
+ const struct s2n_cipher_suite *cipher_suite = conn->client->cipher_suite;
+ uint8_t *implicit_iv = conn->client->client_implicit_iv;
+ struct s2n_hmac_state *mac = &conn->client->client_record_mac;
+ uint8_t *sequence_number = conn->client->client_sequence_number;
+ struct s2n_session_key *session_key = &conn->client->client_key;
+
+ if (conn->mode == S2N_CLIENT) {
+ cipher_suite = conn->server->cipher_suite;
+ implicit_iv = conn->server->server_implicit_iv;
+ mac = &conn->server->server_record_mac;
+ sequence_number = conn->server->server_sequence_number;
+ session_key = &conn->server->server_key;
+ }
+
+ if (s2n_is_tls13_plaintext_content(conn, content_type)) {
+ conn->client = current_client_crypto;
+ conn->server = current_server_crypto;
+ }
+
+ switch (cipher_suite->record_alg->cipher->type) {
+ case S2N_AEAD:
+ GUARD(s2n_record_parse_aead(cipher_suite, conn, content_type, encrypted_length, implicit_iv, mac, sequence_number, session_key));
+ break;
+ case S2N_CBC:
+ GUARD(s2n_record_parse_cbc(cipher_suite, conn, content_type, encrypted_length, implicit_iv, mac, sequence_number, session_key));
+ break;
+ case S2N_COMPOSITE:
+ GUARD(s2n_record_parse_composite(cipher_suite, conn, content_type, encrypted_length, implicit_iv, mac, sequence_number, session_key));
+ break;
+ case S2N_STREAM:
+ GUARD(s2n_record_parse_stream(cipher_suite, conn, content_type, encrypted_length, implicit_iv, mac, sequence_number, session_key));
+ break;
+ default:
+ S2N_ERROR(S2N_ERR_CIPHER_TYPE);
+ break;
+ }
+
+ return 0;
+}
+
+int s2n_tls13_parse_record_type(struct s2n_stuffer *stuffer, uint8_t *record_type)
+{
+ uint32_t bytes_left = s2n_stuffer_data_available(stuffer);
+
+ /* From rfc8446 Section 5.4
+ * The presence of padding does not change the overall record size
+ * limitations: the full encoded TLSInnerPlaintext MUST NOT exceed 2^14
+ * + 1 octets
+ *
+ * Certain versions of Java can generate inner plaintexts with lengths up to
+ * S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH + 16 (See JDK-8221253)
+ * However, after the padding is stripped, the result will always be no more than
+ * S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH - 1
+ */
+ S2N_ERROR_IF(bytes_left > S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH + 16, S2N_ERR_MAX_INNER_PLAINTEXT_SIZE);
+
+ /* set cursor to the end of the stuffer */
+ GUARD(s2n_stuffer_skip_read(stuffer, bytes_left));
+
+ /* Record type should have values greater than zero.
+ * If zero, treat as padding, keep reading and wiping from the back
+ * until a non-zero value is found
+ */
+ *record_type = 0;
+ while (*record_type == 0) {
+ /* back the cursor by one to read off the last byte */
+ GUARD(s2n_stuffer_rewind_read(stuffer, 1));
+
+ /* set the record type */
+ GUARD(s2n_stuffer_read_uint8(stuffer, record_type));
+
+ /* wipe the last byte at the end of the stuffer */
+ GUARD(s2n_stuffer_wipe_n(stuffer, 1));
+ }
+
+ /* only the original plaintext should remain */
+ /* now reset the read cursor at where it should be */
+ GUARD(s2n_stuffer_reread(stuffer));
+
+ /* Even in the incorrect case above with up to 16 extra bytes, we should never see too much data after unpadding */
+ S2N_ERROR_IF(s2n_stuffer_data_available(stuffer) > S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH - 1, S2N_ERR_MAX_INNER_PLAINTEXT_SIZE);
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_record_read.h b/contrib/restricted/aws/s2n/tls/s2n_record_read.h
index 1c79e42f73..dd54f3d1fe 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_record_read.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_record_read.h
@@ -1,55 +1,55 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/s2n_connection.h"
-
-int s2n_record_parse_aead(
- const struct s2n_cipher_suite *cipher_suite,
- struct s2n_connection *conn,
- uint8_t content_type,
- uint16_t encrypted_length,
- uint8_t * implicit_iv,
- struct s2n_hmac_state *mac,
- uint8_t * sequence_number,
- struct s2n_session_key *session_key);
-int s2n_record_parse_cbc(
- const struct s2n_cipher_suite *cipher_suite,
- struct s2n_connection *conn,
- uint8_t content_type,
- uint16_t encrypted_length,
- uint8_t * implicit_iv,
- struct s2n_hmac_state *mac,
- uint8_t * sequence_number,
- struct s2n_session_key *session_key);
-int s2n_record_parse_composite(
- const struct s2n_cipher_suite *cipher_suite,
- struct s2n_connection *conn,
- uint8_t content_type,
- uint16_t encrypted_length,
- uint8_t * implicit_iv,
- struct s2n_hmac_state *mac,
- uint8_t * sequence_number,
- struct s2n_session_key *session_key);
-int s2n_record_parse_stream(
- const struct s2n_cipher_suite *cipher_suite,
- struct s2n_connection *conn,
- uint8_t content_type,
- uint16_t encrypted_length,
- uint8_t * implicit_iv,
- struct s2n_hmac_state *mac,
- uint8_t * sequence_number,
- struct s2n_session_key *session_key);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/s2n_connection.h"
+
+int s2n_record_parse_aead(
+ const struct s2n_cipher_suite *cipher_suite,
+ struct s2n_connection *conn,
+ uint8_t content_type,
+ uint16_t encrypted_length,
+ uint8_t * implicit_iv,
+ struct s2n_hmac_state *mac,
+ uint8_t * sequence_number,
+ struct s2n_session_key *session_key);
+int s2n_record_parse_cbc(
+ const struct s2n_cipher_suite *cipher_suite,
+ struct s2n_connection *conn,
+ uint8_t content_type,
+ uint16_t encrypted_length,
+ uint8_t * implicit_iv,
+ struct s2n_hmac_state *mac,
+ uint8_t * sequence_number,
+ struct s2n_session_key *session_key);
+int s2n_record_parse_composite(
+ const struct s2n_cipher_suite *cipher_suite,
+ struct s2n_connection *conn,
+ uint8_t content_type,
+ uint16_t encrypted_length,
+ uint8_t * implicit_iv,
+ struct s2n_hmac_state *mac,
+ uint8_t * sequence_number,
+ struct s2n_session_key *session_key);
+int s2n_record_parse_stream(
+ const struct s2n_cipher_suite *cipher_suite,
+ struct s2n_connection *conn,
+ uint8_t content_type,
+ uint16_t encrypted_length,
+ uint8_t * implicit_iv,
+ struct s2n_hmac_state *mac,
+ uint8_t * sequence_number,
+ struct s2n_session_key *session_key);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_record_read_aead.c b/contrib/restricted/aws/s2n/tls/s2n_record_read_aead.c
index b613ca6235..2c2c8df1f1 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_record_read_aead.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_record_read_aead.c
@@ -1,127 +1,127 @@
-/*
- * 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_sequence.h"
-#include "crypto/s2n_cipher.h"
-#include "crypto/s2n_hmac.h"
-
-#include "error/s2n_errno.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_crypto.h"
-#include "tls/s2n_record.h"
-#include "tls/s2n_record_read.h"
-
-#include "utils/s2n_annotations.h"
-#include "utils/s2n_blob.h"
-#include "utils/s2n_safety.h"
-
-int s2n_record_parse_aead(
- const struct s2n_cipher_suite *cipher_suite,
- struct s2n_connection *conn,
- uint8_t content_type,
- uint16_t encrypted_length,
- uint8_t * implicit_iv,
- struct s2n_hmac_state *mac,
- uint8_t * sequence_number,
- struct s2n_session_key *session_key)
-{
- const int is_tls13_record = cipher_suite->record_alg->flags & S2N_TLS13_RECORD_AEAD_NONCE;
- /* TLS 1.3 record protection uses a different 5 byte associated data than TLS 1.2's */
- s2n_stack_blob(aad, is_tls13_record ? S2N_TLS13_AAD_LEN : S2N_TLS_MAX_AAD_LEN, S2N_TLS_MAX_AAD_LEN);
-
- struct s2n_blob en = {.size = encrypted_length,.data = s2n_stuffer_raw_read(&conn->in, encrypted_length) };
- notnull_check(en.data);
- /* In AEAD mode, the explicit IV is in the record */
- gte_check(en.size, cipher_suite->record_alg->cipher->io.aead.record_iv_size);
-
- uint8_t aad_iv[S2N_TLS_MAX_IV_LEN] = { 0 };
- struct s2n_blob iv = {.data = aad_iv,.size = sizeof(aad_iv) };
- struct s2n_stuffer iv_stuffer = {0};
- GUARD(s2n_stuffer_init(&iv_stuffer, &iv));
-
- if (cipher_suite->record_alg->flags & S2N_TLS12_AES_GCM_AEAD_NONCE) {
- /* Partially explicit nonce. See RFC 5288 Section 3 */
- GUARD(s2n_stuffer_write_bytes(&iv_stuffer, implicit_iv, cipher_suite->record_alg->cipher->io.aead.fixed_iv_size));
- GUARD(s2n_stuffer_write_bytes(&iv_stuffer, en.data, cipher_suite->record_alg->cipher->io.aead.record_iv_size));
- } else if (cipher_suite->record_alg->flags & S2N_TLS12_CHACHA_POLY_AEAD_NONCE || is_tls13_record) {
- /* Fully implicit nonce.
- * This is introduced with ChaChaPoly with RFC 7905 Section 2
- * and also used for TLS 1.3 record protection (RFC 8446 Section 5.2).
- *
- * In these cipher modes, the sequence number (64 bits) is left padded by 4 bytes
- * to align and xor-ed with the 96-bit IV.
- **/
- uint8_t four_zeroes[4] = { 0 };
- GUARD(s2n_stuffer_write_bytes(&iv_stuffer, four_zeroes, 4));
- GUARD(s2n_stuffer_write_bytes(&iv_stuffer, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
- for (int i = 0; i < cipher_suite->record_alg->cipher->io.aead.fixed_iv_size; i++) {
- S2N_INVARIENT(i <= cipher_suite->record_alg->cipher->io.aead.fixed_iv_size);
- aad_iv[i] = aad_iv[i] ^ implicit_iv[i];
- }
- } else {
- S2N_ERROR(S2N_ERR_INVALID_NONCE_TYPE);
- }
-
- /* Set the IV size to the amount of data written */
- iv.size = s2n_stuffer_data_available(&iv_stuffer);
-
- uint16_t payload_length = encrypted_length;
- /* remove the AEAD overhead from the record size */
- gte_check(payload_length, cipher_suite->record_alg->cipher->io.aead.record_iv_size + cipher_suite->record_alg->cipher->io.aead.tag_size);
- payload_length -= cipher_suite->record_alg->cipher->io.aead.record_iv_size;
- payload_length -= cipher_suite->record_alg->cipher->io.aead.tag_size;
-
- struct s2n_stuffer ad_stuffer = {0};
- GUARD(s2n_stuffer_init(&ad_stuffer, &aad));
-
- if (is_tls13_record) {
- GUARD_AS_POSIX(s2n_tls13_aead_aad_init(payload_length, cipher_suite->record_alg->cipher->io.aead.tag_size, &ad_stuffer));
- } else {
- GUARD_AS_POSIX(s2n_aead_aad_init(conn, sequence_number, content_type, payload_length, &ad_stuffer));
- }
-
- /* Decrypt stuff! */
- /* Skip explicit IV for decryption */
- en.size -= cipher_suite->record_alg->cipher->io.aead.record_iv_size;
- en.data += cipher_suite->record_alg->cipher->io.aead.record_iv_size;
-
- /* Check that we have some data to decrypt */
- ne_check(en.size, 0);
-
- GUARD(cipher_suite->record_alg->cipher->io.aead.decrypt(session_key, &iv, &aad, &en, &en));
- struct s2n_blob seq = {.data = sequence_number,.size = S2N_TLS_SEQUENCE_NUM_LEN };
- GUARD(s2n_increment_sequence_number(&seq));
-
- /* O.k., we've successfully read and decrypted the record, now we need to align the stuffer
- * for reading the plaintext data.
- */
- GUARD(s2n_stuffer_reread(&conn->in));
- GUARD(s2n_stuffer_reread(&conn->header_in));
-
- /* Skip the IV, if any */
- if (conn->actual_protocol_version >= S2N_TLS12) {
- GUARD(s2n_stuffer_skip_read(&conn->in, cipher_suite->record_alg->cipher->io.aead.record_iv_size));
- }
-
- /* Truncate and wipe the MAC and any padding */
- GUARD(s2n_stuffer_wipe_n(&conn->in, s2n_stuffer_data_available(&conn->in) - payload_length));
- conn->in_status = PLAINTEXT;
-
- return 0;
-}
+/*
+ * 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_sequence.h"
+#include "crypto/s2n_cipher.h"
+#include "crypto/s2n_hmac.h"
+
+#include "error/s2n_errno.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_crypto.h"
+#include "tls/s2n_record.h"
+#include "tls/s2n_record_read.h"
+
+#include "utils/s2n_annotations.h"
+#include "utils/s2n_blob.h"
+#include "utils/s2n_safety.h"
+
+int s2n_record_parse_aead(
+ const struct s2n_cipher_suite *cipher_suite,
+ struct s2n_connection *conn,
+ uint8_t content_type,
+ uint16_t encrypted_length,
+ uint8_t * implicit_iv,
+ struct s2n_hmac_state *mac,
+ uint8_t * sequence_number,
+ struct s2n_session_key *session_key)
+{
+ const int is_tls13_record = cipher_suite->record_alg->flags & S2N_TLS13_RECORD_AEAD_NONCE;
+ /* TLS 1.3 record protection uses a different 5 byte associated data than TLS 1.2's */
+ s2n_stack_blob(aad, is_tls13_record ? S2N_TLS13_AAD_LEN : S2N_TLS_MAX_AAD_LEN, S2N_TLS_MAX_AAD_LEN);
+
+ struct s2n_blob en = {.size = encrypted_length,.data = s2n_stuffer_raw_read(&conn->in, encrypted_length) };
+ notnull_check(en.data);
+ /* In AEAD mode, the explicit IV is in the record */
+ gte_check(en.size, cipher_suite->record_alg->cipher->io.aead.record_iv_size);
+
+ uint8_t aad_iv[S2N_TLS_MAX_IV_LEN] = { 0 };
+ struct s2n_blob iv = {.data = aad_iv,.size = sizeof(aad_iv) };
+ struct s2n_stuffer iv_stuffer = {0};
+ GUARD(s2n_stuffer_init(&iv_stuffer, &iv));
+
+ if (cipher_suite->record_alg->flags & S2N_TLS12_AES_GCM_AEAD_NONCE) {
+ /* Partially explicit nonce. See RFC 5288 Section 3 */
+ GUARD(s2n_stuffer_write_bytes(&iv_stuffer, implicit_iv, cipher_suite->record_alg->cipher->io.aead.fixed_iv_size));
+ GUARD(s2n_stuffer_write_bytes(&iv_stuffer, en.data, cipher_suite->record_alg->cipher->io.aead.record_iv_size));
+ } else if (cipher_suite->record_alg->flags & S2N_TLS12_CHACHA_POLY_AEAD_NONCE || is_tls13_record) {
+ /* Fully implicit nonce.
+ * This is introduced with ChaChaPoly with RFC 7905 Section 2
+ * and also used for TLS 1.3 record protection (RFC 8446 Section 5.2).
+ *
+ * In these cipher modes, the sequence number (64 bits) is left padded by 4 bytes
+ * to align and xor-ed with the 96-bit IV.
+ **/
+ uint8_t four_zeroes[4] = { 0 };
+ GUARD(s2n_stuffer_write_bytes(&iv_stuffer, four_zeroes, 4));
+ GUARD(s2n_stuffer_write_bytes(&iv_stuffer, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
+ for (int i = 0; i < cipher_suite->record_alg->cipher->io.aead.fixed_iv_size; i++) {
+ S2N_INVARIENT(i <= cipher_suite->record_alg->cipher->io.aead.fixed_iv_size);
+ aad_iv[i] = aad_iv[i] ^ implicit_iv[i];
+ }
+ } else {
+ S2N_ERROR(S2N_ERR_INVALID_NONCE_TYPE);
+ }
+
+ /* Set the IV size to the amount of data written */
+ iv.size = s2n_stuffer_data_available(&iv_stuffer);
+
+ uint16_t payload_length = encrypted_length;
+ /* remove the AEAD overhead from the record size */
+ gte_check(payload_length, cipher_suite->record_alg->cipher->io.aead.record_iv_size + cipher_suite->record_alg->cipher->io.aead.tag_size);
+ payload_length -= cipher_suite->record_alg->cipher->io.aead.record_iv_size;
+ payload_length -= cipher_suite->record_alg->cipher->io.aead.tag_size;
+
+ struct s2n_stuffer ad_stuffer = {0};
+ GUARD(s2n_stuffer_init(&ad_stuffer, &aad));
+
+ if (is_tls13_record) {
+ GUARD_AS_POSIX(s2n_tls13_aead_aad_init(payload_length, cipher_suite->record_alg->cipher->io.aead.tag_size, &ad_stuffer));
+ } else {
+ GUARD_AS_POSIX(s2n_aead_aad_init(conn, sequence_number, content_type, payload_length, &ad_stuffer));
+ }
+
+ /* Decrypt stuff! */
+ /* Skip explicit IV for decryption */
+ en.size -= cipher_suite->record_alg->cipher->io.aead.record_iv_size;
+ en.data += cipher_suite->record_alg->cipher->io.aead.record_iv_size;
+
+ /* Check that we have some data to decrypt */
+ ne_check(en.size, 0);
+
+ GUARD(cipher_suite->record_alg->cipher->io.aead.decrypt(session_key, &iv, &aad, &en, &en));
+ struct s2n_blob seq = {.data = sequence_number,.size = S2N_TLS_SEQUENCE_NUM_LEN };
+ GUARD(s2n_increment_sequence_number(&seq));
+
+ /* O.k., we've successfully read and decrypted the record, now we need to align the stuffer
+ * for reading the plaintext data.
+ */
+ GUARD(s2n_stuffer_reread(&conn->in));
+ GUARD(s2n_stuffer_reread(&conn->header_in));
+
+ /* Skip the IV, if any */
+ if (conn->actual_protocol_version >= S2N_TLS12) {
+ GUARD(s2n_stuffer_skip_read(&conn->in, cipher_suite->record_alg->cipher->io.aead.record_iv_size));
+ }
+
+ /* Truncate and wipe the MAC and any padding */
+ GUARD(s2n_stuffer_wipe_n(&conn->in, s2n_stuffer_data_available(&conn->in) - payload_length));
+ conn->in_status = PLAINTEXT;
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_record_read_cbc.c b/contrib/restricted/aws/s2n/tls/s2n_record_read_cbc.c
index 21d96e8370..9948469593 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_record_read_cbc.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_record_read_cbc.c
@@ -1,130 +1,130 @@
-/*
- * 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_sequence.h"
-#include "crypto/s2n_cipher.h"
-#include "crypto/s2n_hmac.h"
-
-#include "error/s2n_errno.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_crypto.h"
-#include "tls/s2n_record.h"
-#include "tls/s2n_record_read.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_blob.h"
-
-int s2n_record_parse_cbc(
- const struct s2n_cipher_suite *cipher_suite,
- struct s2n_connection *conn,
- uint8_t content_type,
- uint16_t encrypted_length,
- uint8_t * implicit_iv,
- struct s2n_hmac_state *mac,
- uint8_t * sequence_number,
- struct s2n_session_key *session_key)
-{
- struct s2n_blob iv = {.data = implicit_iv,.size = cipher_suite->record_alg->cipher->io.cbc.record_iv_size };
- uint8_t ivpad[S2N_TLS_MAX_IV_LEN];
-
- /* Add the header to the HMAC */
- uint8_t *header = s2n_stuffer_raw_read(&conn->header_in, S2N_TLS_RECORD_HEADER_LENGTH);
- notnull_check(header);
-
- lte_check(cipher_suite->record_alg->cipher->io.cbc.record_iv_size, S2N_TLS_MAX_IV_LEN);
-
- /* For TLS >= 1.1 the IV is in the packet */
- if (conn->actual_protocol_version > S2N_TLS10) {
- GUARD(s2n_stuffer_read(&conn->in, &iv));
- gte_check(encrypted_length, iv.size);
- encrypted_length -= iv.size;
- }
-
- struct s2n_blob en = {.size = encrypted_length,.data = s2n_stuffer_raw_read(&conn->in, encrypted_length) };
- notnull_check(en.data);
-
- uint16_t payload_length = encrypted_length;
- uint8_t mac_digest_size;
- GUARD(s2n_hmac_digest_size(mac->alg, &mac_digest_size));
-
- gte_check(payload_length, mac_digest_size);
- payload_length -= mac_digest_size;
-
- /* Decrypt stuff! */
- /* Check that we have some data to decrypt */
- ne_check(en.size, 0);
-
- /* ... and that we have a multiple of the block size */
- eq_check(en.size % iv.size, 0);
-
- /* Copy the last encrypted block to be the next IV */
- if (conn->actual_protocol_version < S2N_TLS11) {
- memcpy_check(ivpad, en.data + en.size - iv.size, iv.size);
- }
-
- GUARD(cipher_suite->record_alg->cipher->io.cbc.decrypt(session_key, &iv, &en, &en));
-
- if (conn->actual_protocol_version < S2N_TLS11) {
- memcpy_check(implicit_iv, ivpad, iv.size);
- }
-
- /* Subtract the padding length */
- gt_check(en.size, 0);
- uint32_t out = 0;
- GUARD(s2n_sub_overflow(payload_length, en.data[en.size - 1] + 1, &out));
- payload_length = out;
- /* Update the MAC */
- header[3] = (payload_length >> 8);
- header[4] = payload_length & 0xff;
- GUARD(s2n_hmac_reset(mac));
- GUARD(s2n_hmac_update(mac, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
-
- if (conn->actual_protocol_version == S2N_SSLv3) {
- GUARD(s2n_hmac_update(mac, header, 1));
- GUARD(s2n_hmac_update(mac, header + 3, 2));
- } else {
- GUARD(s2n_hmac_update(mac, header, S2N_TLS_RECORD_HEADER_LENGTH));
- }
-
- struct s2n_blob seq = {.data = sequence_number,.size = S2N_TLS_SEQUENCE_NUM_LEN };
- GUARD(s2n_increment_sequence_number(&seq));
-
- /* Padding */
- if (s2n_verify_cbc(conn, mac, &en) < 0) {
- GUARD(s2n_stuffer_wipe(&conn->in));
- S2N_ERROR(S2N_ERR_BAD_MESSAGE);
- }
-
- /* O.k., we've successfully read and decrypted the record, now we need to align the stuffer
- * for reading the plaintext data.
- */
- GUARD(s2n_stuffer_reread(&conn->in));
- GUARD(s2n_stuffer_reread(&conn->header_in));
-
- /* Skip the IV, if any */
- if (conn->actual_protocol_version > S2N_TLS10) {
- GUARD(s2n_stuffer_skip_read(&conn->in, cipher_suite->record_alg->cipher->io.cbc.record_iv_size));
- }
-
- /* Truncate and wipe the MAC and any padding */
- GUARD(s2n_stuffer_wipe_n(&conn->in, s2n_stuffer_data_available(&conn->in) - payload_length));
- conn->in_status = PLAINTEXT;
-
- return 0;
-}
+/*
+ * 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_sequence.h"
+#include "crypto/s2n_cipher.h"
+#include "crypto/s2n_hmac.h"
+
+#include "error/s2n_errno.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_crypto.h"
+#include "tls/s2n_record.h"
+#include "tls/s2n_record_read.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_blob.h"
+
+int s2n_record_parse_cbc(
+ const struct s2n_cipher_suite *cipher_suite,
+ struct s2n_connection *conn,
+ uint8_t content_type,
+ uint16_t encrypted_length,
+ uint8_t * implicit_iv,
+ struct s2n_hmac_state *mac,
+ uint8_t * sequence_number,
+ struct s2n_session_key *session_key)
+{
+ struct s2n_blob iv = {.data = implicit_iv,.size = cipher_suite->record_alg->cipher->io.cbc.record_iv_size };
+ uint8_t ivpad[S2N_TLS_MAX_IV_LEN];
+
+ /* Add the header to the HMAC */
+ uint8_t *header = s2n_stuffer_raw_read(&conn->header_in, S2N_TLS_RECORD_HEADER_LENGTH);
+ notnull_check(header);
+
+ lte_check(cipher_suite->record_alg->cipher->io.cbc.record_iv_size, S2N_TLS_MAX_IV_LEN);
+
+ /* For TLS >= 1.1 the IV is in the packet */
+ if (conn->actual_protocol_version > S2N_TLS10) {
+ GUARD(s2n_stuffer_read(&conn->in, &iv));
+ gte_check(encrypted_length, iv.size);
+ encrypted_length -= iv.size;
+ }
+
+ struct s2n_blob en = {.size = encrypted_length,.data = s2n_stuffer_raw_read(&conn->in, encrypted_length) };
+ notnull_check(en.data);
+
+ uint16_t payload_length = encrypted_length;
+ uint8_t mac_digest_size;
+ GUARD(s2n_hmac_digest_size(mac->alg, &mac_digest_size));
+
+ gte_check(payload_length, mac_digest_size);
+ payload_length -= mac_digest_size;
+
+ /* Decrypt stuff! */
+ /* Check that we have some data to decrypt */
+ ne_check(en.size, 0);
+
+ /* ... and that we have a multiple of the block size */
+ eq_check(en.size % iv.size, 0);
+
+ /* Copy the last encrypted block to be the next IV */
+ if (conn->actual_protocol_version < S2N_TLS11) {
+ memcpy_check(ivpad, en.data + en.size - iv.size, iv.size);
+ }
+
+ GUARD(cipher_suite->record_alg->cipher->io.cbc.decrypt(session_key, &iv, &en, &en));
+
+ if (conn->actual_protocol_version < S2N_TLS11) {
+ memcpy_check(implicit_iv, ivpad, iv.size);
+ }
+
+ /* Subtract the padding length */
+ gt_check(en.size, 0);
+ uint32_t out = 0;
+ GUARD(s2n_sub_overflow(payload_length, en.data[en.size - 1] + 1, &out));
+ payload_length = out;
+ /* Update the MAC */
+ header[3] = (payload_length >> 8);
+ header[4] = payload_length & 0xff;
+ GUARD(s2n_hmac_reset(mac));
+ GUARD(s2n_hmac_update(mac, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
+
+ if (conn->actual_protocol_version == S2N_SSLv3) {
+ GUARD(s2n_hmac_update(mac, header, 1));
+ GUARD(s2n_hmac_update(mac, header + 3, 2));
+ } else {
+ GUARD(s2n_hmac_update(mac, header, S2N_TLS_RECORD_HEADER_LENGTH));
+ }
+
+ struct s2n_blob seq = {.data = sequence_number,.size = S2N_TLS_SEQUENCE_NUM_LEN };
+ GUARD(s2n_increment_sequence_number(&seq));
+
+ /* Padding */
+ if (s2n_verify_cbc(conn, mac, &en) < 0) {
+ GUARD(s2n_stuffer_wipe(&conn->in));
+ S2N_ERROR(S2N_ERR_BAD_MESSAGE);
+ }
+
+ /* O.k., we've successfully read and decrypted the record, now we need to align the stuffer
+ * for reading the plaintext data.
+ */
+ GUARD(s2n_stuffer_reread(&conn->in));
+ GUARD(s2n_stuffer_reread(&conn->header_in));
+
+ /* Skip the IV, if any */
+ if (conn->actual_protocol_version > S2N_TLS10) {
+ GUARD(s2n_stuffer_skip_read(&conn->in, cipher_suite->record_alg->cipher->io.cbc.record_iv_size));
+ }
+
+ /* Truncate and wipe the MAC and any padding */
+ GUARD(s2n_stuffer_wipe_n(&conn->in, s2n_stuffer_data_available(&conn->in) - payload_length));
+ conn->in_status = PLAINTEXT;
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_record_read_composite.c b/contrib/restricted/aws/s2n/tls/s2n_record_read_composite.c
index a35cc8bf11..3d39bdd8c7 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_record_read_composite.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_record_read_composite.c
@@ -1,114 +1,114 @@
-/*
- * 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_sequence.h"
-#include "crypto/s2n_cipher.h"
-#include "crypto/s2n_hmac.h"
-
-#include "error/s2n_errno.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_crypto.h"
-#include "tls/s2n_record_read.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_blob.h"
-
-int s2n_record_parse_composite(
- const struct s2n_cipher_suite *cipher_suite,
- struct s2n_connection *conn,
- uint8_t content_type,
- uint16_t encrypted_length,
- uint8_t * implicit_iv,
- struct s2n_hmac_state *mac,
- uint8_t * sequence_number,
- struct s2n_session_key *session_key)
-{
- /* Don't reduce encrypted length for explicit IV, composite decrypt expects it */
- struct s2n_blob iv = {.data = implicit_iv,.size = cipher_suite->record_alg->cipher->io.comp.record_iv_size };
- uint8_t ivpad[S2N_TLS_MAX_IV_LEN];
-
- /* Add the header to the HMAC */
- uint8_t *header = s2n_stuffer_raw_read(&conn->header_in, S2N_TLS_RECORD_HEADER_LENGTH);
- notnull_check(header);
-
- struct s2n_blob en = {.size = encrypted_length,.data = s2n_stuffer_raw_read(&conn->in, encrypted_length) };
- notnull_check(en.data);
-
- uint16_t payload_length = encrypted_length;
- uint8_t mac_digest_size;
- GUARD(s2n_hmac_digest_size(mac->alg, &mac_digest_size));
-
- gte_check(payload_length, mac_digest_size);
- payload_length -= mac_digest_size;
-
- /* Compute non-payload parts of the MAC(seq num, type, proto vers, fragment length) for composite ciphers.
- * Composite "decrypt" will MAC the actual payload data.
- */
- /* In the decrypt case, this outputs the MAC digest length:
- * https://github.com/openssl/openssl/blob/master/crypto/evp/e_aes_cbc_hmac_sha1.c#L842 */
- int mac_size = 0;
- GUARD(cipher_suite->record_alg->cipher->io.comp.initial_hmac(session_key, sequence_number, content_type, conn->actual_protocol_version, payload_length, &mac_size));
-
- gte_check(payload_length, mac_size);
- payload_length -= mac_size;
- /* Adjust payload_length for explicit IV */
- if (conn->actual_protocol_version > S2N_TLS10) {
- uint32_t out = 0;
- GUARD(s2n_sub_overflow(payload_length, cipher_suite->record_alg->cipher->io.comp.record_iv_size, &out));
- payload_length = out;
- }
-
- /* Decrypt stuff! */
- ne_check(en.size, 0);
- eq_check(en.size % iv.size, 0);
-
- /* Copy the last encrypted block to be the next IV */
- memcpy_check(ivpad, en.data + en.size - iv.size, iv.size);
-
- /* This will: Skip the explicit IV(if applicable), decrypt the payload, verify the MAC and padding. */
- GUARD((cipher_suite->record_alg->cipher->io.comp.decrypt(session_key, &iv, &en, &en)));
-
- memcpy_check(implicit_iv, ivpad, iv.size);
-
- /* Subtract the padding length */
- gt_check(en.size, 0);
- uint32_t out = 0;
- GUARD(s2n_sub_overflow(payload_length, en.data[en.size - 1] + 1, &out));
- payload_length = out;
-
- struct s2n_blob seq = {.data = sequence_number,.size = S2N_TLS_SEQUENCE_NUM_LEN };
- GUARD(s2n_increment_sequence_number(&seq));
-
- /* O.k., we've successfully read and decrypted the record, now we need to align the stuffer
- * for reading the plaintext data.
- */
- GUARD(s2n_stuffer_reread(&conn->in));
- GUARD(s2n_stuffer_reread(&conn->header_in));
-
- /* Skip the IV, if any */
- if (conn->actual_protocol_version > S2N_TLS10) {
- GUARD(s2n_stuffer_skip_read(&conn->in, cipher_suite->record_alg->cipher->io.comp.record_iv_size));
- }
-
- /* Truncate and wipe the MAC and any padding */
- GUARD(s2n_stuffer_wipe_n(&conn->in, s2n_stuffer_data_available(&conn->in) - payload_length));
- conn->in_status = PLAINTEXT;
-
- return 0;
-}
+/*
+ * 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_sequence.h"
+#include "crypto/s2n_cipher.h"
+#include "crypto/s2n_hmac.h"
+
+#include "error/s2n_errno.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_crypto.h"
+#include "tls/s2n_record_read.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_blob.h"
+
+int s2n_record_parse_composite(
+ const struct s2n_cipher_suite *cipher_suite,
+ struct s2n_connection *conn,
+ uint8_t content_type,
+ uint16_t encrypted_length,
+ uint8_t * implicit_iv,
+ struct s2n_hmac_state *mac,
+ uint8_t * sequence_number,
+ struct s2n_session_key *session_key)
+{
+ /* Don't reduce encrypted length for explicit IV, composite decrypt expects it */
+ struct s2n_blob iv = {.data = implicit_iv,.size = cipher_suite->record_alg->cipher->io.comp.record_iv_size };
+ uint8_t ivpad[S2N_TLS_MAX_IV_LEN];
+
+ /* Add the header to the HMAC */
+ uint8_t *header = s2n_stuffer_raw_read(&conn->header_in, S2N_TLS_RECORD_HEADER_LENGTH);
+ notnull_check(header);
+
+ struct s2n_blob en = {.size = encrypted_length,.data = s2n_stuffer_raw_read(&conn->in, encrypted_length) };
+ notnull_check(en.data);
+
+ uint16_t payload_length = encrypted_length;
+ uint8_t mac_digest_size;
+ GUARD(s2n_hmac_digest_size(mac->alg, &mac_digest_size));
+
+ gte_check(payload_length, mac_digest_size);
+ payload_length -= mac_digest_size;
+
+ /* Compute non-payload parts of the MAC(seq num, type, proto vers, fragment length) for composite ciphers.
+ * Composite "decrypt" will MAC the actual payload data.
+ */
+ /* In the decrypt case, this outputs the MAC digest length:
+ * https://github.com/openssl/openssl/blob/master/crypto/evp/e_aes_cbc_hmac_sha1.c#L842 */
+ int mac_size = 0;
+ GUARD(cipher_suite->record_alg->cipher->io.comp.initial_hmac(session_key, sequence_number, content_type, conn->actual_protocol_version, payload_length, &mac_size));
+
+ gte_check(payload_length, mac_size);
+ payload_length -= mac_size;
+ /* Adjust payload_length for explicit IV */
+ if (conn->actual_protocol_version > S2N_TLS10) {
+ uint32_t out = 0;
+ GUARD(s2n_sub_overflow(payload_length, cipher_suite->record_alg->cipher->io.comp.record_iv_size, &out));
+ payload_length = out;
+ }
+
+ /* Decrypt stuff! */
+ ne_check(en.size, 0);
+ eq_check(en.size % iv.size, 0);
+
+ /* Copy the last encrypted block to be the next IV */
+ memcpy_check(ivpad, en.data + en.size - iv.size, iv.size);
+
+ /* This will: Skip the explicit IV(if applicable), decrypt the payload, verify the MAC and padding. */
+ GUARD((cipher_suite->record_alg->cipher->io.comp.decrypt(session_key, &iv, &en, &en)));
+
+ memcpy_check(implicit_iv, ivpad, iv.size);
+
+ /* Subtract the padding length */
+ gt_check(en.size, 0);
+ uint32_t out = 0;
+ GUARD(s2n_sub_overflow(payload_length, en.data[en.size - 1] + 1, &out));
+ payload_length = out;
+
+ struct s2n_blob seq = {.data = sequence_number,.size = S2N_TLS_SEQUENCE_NUM_LEN };
+ GUARD(s2n_increment_sequence_number(&seq));
+
+ /* O.k., we've successfully read and decrypted the record, now we need to align the stuffer
+ * for reading the plaintext data.
+ */
+ GUARD(s2n_stuffer_reread(&conn->in));
+ GUARD(s2n_stuffer_reread(&conn->header_in));
+
+ /* Skip the IV, if any */
+ if (conn->actual_protocol_version > S2N_TLS10) {
+ GUARD(s2n_stuffer_skip_read(&conn->in, cipher_suite->record_alg->cipher->io.comp.record_iv_size));
+ }
+
+ /* Truncate and wipe the MAC and any padding */
+ GUARD(s2n_stuffer_wipe_n(&conn->in, s2n_stuffer_data_available(&conn->in) - payload_length));
+ conn->in_status = PLAINTEXT;
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_record_read_stream.c b/contrib/restricted/aws/s2n/tls/s2n_record_read_stream.c
index 718fb3e8aa..dc6d6cb93e 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_record_read_stream.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_record_read_stream.c
@@ -1,98 +1,98 @@
-/*
- * 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_sequence.h"
-#include "crypto/s2n_cipher.h"
-#include "crypto/s2n_hmac.h"
-
-#include "error/s2n_errno.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_crypto.h"
-#include "tls/s2n_record_read.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_blob.h"
-
-int s2n_record_parse_stream(
- const struct s2n_cipher_suite *cipher_suite,
- struct s2n_connection *conn,
- uint8_t content_type,
- uint16_t encrypted_length,
- uint8_t * implicit_iv,
- struct s2n_hmac_state *mac,
- uint8_t * sequence_number,
- struct s2n_session_key *session_key)
-{
- /* Add the header to the HMAC */
- uint8_t *header = s2n_stuffer_raw_read(&conn->header_in, S2N_TLS_RECORD_HEADER_LENGTH);
- notnull_check(header);
-
- struct s2n_blob en = {.size = encrypted_length,.data = s2n_stuffer_raw_read(&conn->in, encrypted_length) };
- notnull_check(en.data);
-
- uint16_t payload_length = encrypted_length;
- uint8_t mac_digest_size;
- GUARD(s2n_hmac_digest_size(mac->alg, &mac_digest_size));
-
- gte_check(payload_length, mac_digest_size);
- payload_length -= mac_digest_size;
-
- /* Decrypt stuff! */
- GUARD(cipher_suite->record_alg->cipher->io.stream.decrypt(session_key, &en, &en));
-
- /* Update the MAC */
- header[3] = (payload_length >> 8);
- header[4] = payload_length & 0xff;
- GUARD(s2n_hmac_reset(mac));
- GUARD(s2n_hmac_update(mac, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
-
- if (conn->actual_protocol_version == S2N_SSLv3) {
- GUARD(s2n_hmac_update(mac, header, 1));
- GUARD(s2n_hmac_update(mac, header + 3, 2));
- } else {
- GUARD(s2n_hmac_update(mac, header, S2N_TLS_RECORD_HEADER_LENGTH));
- }
-
- struct s2n_blob seq = {.data = sequence_number,.size = S2N_TLS_SEQUENCE_NUM_LEN };
- GUARD(s2n_increment_sequence_number(&seq));
-
- /* MAC check for streaming ciphers - no padding */
- GUARD(s2n_hmac_update(mac, en.data, payload_length));
-
- uint8_t check_digest[S2N_MAX_DIGEST_LEN];
- lte_check(mac_digest_size, sizeof(check_digest));
- GUARD(s2n_hmac_digest(mac, check_digest, mac_digest_size));
-
- if (s2n_hmac_digest_verify(en.data + payload_length, check_digest, mac_digest_size) < 0) {
- GUARD(s2n_stuffer_wipe(&conn->in));
- S2N_ERROR(S2N_ERR_BAD_MESSAGE);
- }
-
- /* O.k., we've successfully read and decrypted the record, now we need to align the stuffer
- * for reading the plaintext data.
- */
- GUARD(s2n_stuffer_reread(&conn->in));
- GUARD(s2n_stuffer_reread(&conn->header_in));
-
- /* Truncate and wipe the MAC and any padding */
- GUARD(s2n_stuffer_wipe_n(&conn->in, s2n_stuffer_data_available(&conn->in) - payload_length));
- conn->in_status = PLAINTEXT;
-
- return 0;
-}
+/*
+ * 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_sequence.h"
+#include "crypto/s2n_cipher.h"
+#include "crypto/s2n_hmac.h"
+
+#include "error/s2n_errno.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_crypto.h"
+#include "tls/s2n_record_read.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_blob.h"
+
+int s2n_record_parse_stream(
+ const struct s2n_cipher_suite *cipher_suite,
+ struct s2n_connection *conn,
+ uint8_t content_type,
+ uint16_t encrypted_length,
+ uint8_t * implicit_iv,
+ struct s2n_hmac_state *mac,
+ uint8_t * sequence_number,
+ struct s2n_session_key *session_key)
+{
+ /* Add the header to the HMAC */
+ uint8_t *header = s2n_stuffer_raw_read(&conn->header_in, S2N_TLS_RECORD_HEADER_LENGTH);
+ notnull_check(header);
+
+ struct s2n_blob en = {.size = encrypted_length,.data = s2n_stuffer_raw_read(&conn->in, encrypted_length) };
+ notnull_check(en.data);
+
+ uint16_t payload_length = encrypted_length;
+ uint8_t mac_digest_size;
+ GUARD(s2n_hmac_digest_size(mac->alg, &mac_digest_size));
+
+ gte_check(payload_length, mac_digest_size);
+ payload_length -= mac_digest_size;
+
+ /* Decrypt stuff! */
+ GUARD(cipher_suite->record_alg->cipher->io.stream.decrypt(session_key, &en, &en));
+
+ /* Update the MAC */
+ header[3] = (payload_length >> 8);
+ header[4] = payload_length & 0xff;
+ GUARD(s2n_hmac_reset(mac));
+ GUARD(s2n_hmac_update(mac, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
+
+ if (conn->actual_protocol_version == S2N_SSLv3) {
+ GUARD(s2n_hmac_update(mac, header, 1));
+ GUARD(s2n_hmac_update(mac, header + 3, 2));
+ } else {
+ GUARD(s2n_hmac_update(mac, header, S2N_TLS_RECORD_HEADER_LENGTH));
+ }
+
+ struct s2n_blob seq = {.data = sequence_number,.size = S2N_TLS_SEQUENCE_NUM_LEN };
+ GUARD(s2n_increment_sequence_number(&seq));
+
+ /* MAC check for streaming ciphers - no padding */
+ GUARD(s2n_hmac_update(mac, en.data, payload_length));
+
+ uint8_t check_digest[S2N_MAX_DIGEST_LEN];
+ lte_check(mac_digest_size, sizeof(check_digest));
+ GUARD(s2n_hmac_digest(mac, check_digest, mac_digest_size));
+
+ if (s2n_hmac_digest_verify(en.data + payload_length, check_digest, mac_digest_size) < 0) {
+ GUARD(s2n_stuffer_wipe(&conn->in));
+ S2N_ERROR(S2N_ERR_BAD_MESSAGE);
+ }
+
+ /* O.k., we've successfully read and decrypted the record, now we need to align the stuffer
+ * for reading the plaintext data.
+ */
+ GUARD(s2n_stuffer_reread(&conn->in));
+ GUARD(s2n_stuffer_reread(&conn->header_in));
+
+ /* Truncate and wipe the MAC and any padding */
+ GUARD(s2n_stuffer_wipe_n(&conn->in, s2n_stuffer_data_available(&conn->in) - payload_length));
+ conn->in_status = PLAINTEXT;
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_record_write.c b/contrib/restricted/aws/s2n/tls/s2n_record_write.c
index 4cb2648ffd..df28a9d58e 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_record_write.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_record_write.c
@@ -1,455 +1,455 @@
-/*
- * 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 <stdint.h>
-#include <sys/param.h>
-
-#include "error/s2n_errno.h"
-
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_record.h"
-#include "tls/s2n_crypto.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "crypto/s2n_sequence.h"
-#include "crypto/s2n_cipher.h"
-#include "crypto/s2n_hmac.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_random.h"
-#include "utils/s2n_blob.h"
-
-extern uint8_t s2n_unknown_protocol_version;
-
-/* How much overhead does the IV, MAC, TAG and padding bytes introduce ? */
-static S2N_RESULT s2n_tls_record_overhead(struct s2n_connection *conn, uint16_t *out)
-{
- ENSURE_REF(conn);
- ENSURE_MUT(out);
- struct s2n_crypto_parameters *active = conn->server;
-
- if (conn->mode == S2N_CLIENT) {
- active = conn->client;
- }
-
- uint8_t extra;
- GUARD_AS_RESULT(s2n_hmac_digest_size(active->cipher_suite->record_alg->hmac_alg, &extra));
-
- if (active->cipher_suite->record_alg->cipher->type == S2N_CBC) {
- /* Subtract one for the padding length byte */
- extra += 1;
-
- if (conn->actual_protocol_version > S2N_TLS10) {
- extra += active->cipher_suite->record_alg->cipher->io.cbc.record_iv_size;
- }
- } else if (active->cipher_suite->record_alg->cipher->type == S2N_AEAD) {
- extra += active->cipher_suite->record_alg->cipher->io.aead.tag_size;
- extra += active->cipher_suite->record_alg->cipher->io.aead.record_iv_size;
- } else if (active->cipher_suite->record_alg->cipher->type == S2N_COMPOSITE && conn->actual_protocol_version > S2N_TLS10) {
- extra += active->cipher_suite->record_alg->cipher->io.comp.record_iv_size;
- }
-
- *out = extra;
-
- return S2N_RESULT_OK;
-}
-
-/* This function returns maximum size of plaintext data to write for the payload.
- * Record overheads are not included here.
- */
-S2N_RESULT s2n_record_max_write_payload_size(struct s2n_connection *conn, uint16_t *max_fragment_size)
-{
- ENSURE_REF(conn);
- ENSURE_MUT(max_fragment_size);
- ENSURE(conn->max_outgoing_fragment_length > 0, S2N_ERR_FRAGMENT_LENGTH_TOO_SMALL);
-
- *max_fragment_size = MIN(conn->max_outgoing_fragment_length, S2N_TLS_MAXIMUM_FRAGMENT_LENGTH);
-
- return S2N_RESULT_OK;
-}
-
-/* Find the largest size that will fit within an ethernet frame for a "small" payload */
-S2N_RESULT s2n_record_min_write_payload_size(struct s2n_connection *conn, uint16_t *payload_size)
-{
- ENSURE_REF(conn);
- ENSURE_MUT(payload_size);
- /* remove ethernet, TCP/IP and TLS header overheads */
- const uint16_t min_outgoing_fragment_length = ETH_MTU - (conn->ipv6 ? IP_V6_HEADER_LENGTH : IP_V4_HEADER_LENGTH)
- - TCP_HEADER_LENGTH - TCP_OPTIONS_LENGTH - S2N_TLS_RECORD_HEADER_LENGTH;
-
- ENSURE(min_outgoing_fragment_length <= S2N_TLS_MAXIMUM_FRAGMENT_LENGTH, S2N_ERR_FRAGMENT_LENGTH_TOO_LARGE);
- uint16_t size = min_outgoing_fragment_length;
-
- const struct s2n_crypto_parameters *active = conn->mode == S2N_CLIENT ? conn->client : conn->server;
-
- /* Round the fragment size down to be block aligned */
- if (active->cipher_suite->record_alg->cipher->type == S2N_CBC) {
- size -= size % active->cipher_suite->record_alg->cipher->io.cbc.block_size;
- } else if (active->cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
- size -= size % active->cipher_suite->record_alg->cipher->io.comp.block_size;
- /* Composite digest length */
- size -= active->cipher_suite->record_alg->cipher->io.comp.mac_key_size;
- /* Padding length byte */
- size -= 1;
- }
-
- /* subtract overheads of a TLS record */
- uint16_t overhead = 0;
- GUARD_RESULT(s2n_tls_record_overhead(conn, &overhead));
- ENSURE(size > overhead, S2N_ERR_FRAGMENT_LENGTH_TOO_SMALL);
- size -= overhead;
-
- ENSURE(size > 0, S2N_ERR_FRAGMENT_LENGTH_TOO_SMALL);
- ENSURE(size <= ETH_MTU, S2N_ERR_FRAGMENT_LENGTH_TOO_LARGE);
-
- *payload_size = size;
-
- return S2N_RESULT_OK;
-}
-
-int s2n_record_write_protocol_version(struct s2n_connection *conn)
-{
- uint8_t record_protocol_version = conn->actual_protocol_version;
- if (conn->server_protocol_version == s2n_unknown_protocol_version) {
- /* Some legacy TLS implementations can't handle records with protocol version higher than TLS1.0.
- * To provide maximum compatibility, send record version as TLS1.0 if server protocol version isn't
- * established yet, which happens only during ClientHello message. Note, this has no effect on
- * protocol version in ClientHello, so we're still able to negotiate protocol versions above TLS1.0 */
- record_protocol_version = MIN(record_protocol_version, S2N_TLS10);
- }
-
- /* In accordance to TLS 1.3 spec, https://tools.ietf.org/html/rfc8446#section-5.1
- * tls record version should never be greater than 33 (legacy TLS 1.2 version).
- */
- record_protocol_version = MIN(record_protocol_version, S2N_TLS12);
-
- uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN];
- protocol_version[0] = record_protocol_version / 10;
- protocol_version[1] = record_protocol_version % 10;
-
- GUARD(s2n_stuffer_write_bytes(&conn->out, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
-
- return 0;
-}
-
-static inline int s2n_record_encrypt(
- struct s2n_connection *conn,
- const struct s2n_cipher_suite *cipher_suite,
- struct s2n_session_key *session_key,
- struct s2n_blob *iv,
- struct s2n_blob *aad,
- struct s2n_blob *en,
- uint8_t *implicit_iv, uint16_t block_size)
-{
- notnull_check(en->data);
-
- switch (cipher_suite->record_alg->cipher->type) {
- case S2N_STREAM:
- GUARD(cipher_suite->record_alg->cipher->io.stream.encrypt(session_key, en, en));
- break;
- case S2N_CBC:
- GUARD(cipher_suite->record_alg->cipher->io.cbc.encrypt(session_key, iv, en, en));
-
- /* Copy the last encrypted block to be the next IV */
- if (conn->actual_protocol_version < S2N_TLS11) {
- gte_check(en->size, block_size);
- memcpy_check(implicit_iv, en->data + en->size - block_size, block_size);
- }
- break;
- case S2N_AEAD:
- GUARD(cipher_suite->record_alg->cipher->io.aead.encrypt(session_key, iv, aad, en, en));
- break;
- case S2N_COMPOSITE:
- /* This will: compute mac, append padding, append padding length, and encrypt */
- GUARD(cipher_suite->record_alg->cipher->io.comp.encrypt(session_key, iv, en, en));
-
- /* Copy the last encrypted block to be the next IV */
- gte_check(en->size, block_size);
- memcpy_check(implicit_iv, en->data + en->size - block_size, block_size);
- break;
- default:
- S2N_ERROR(S2N_ERR_CIPHER_TYPE);
- break;
- }
-
- return 0;
-}
-
-int s2n_record_writev(struct s2n_connection *conn, uint8_t content_type, const struct iovec *in, int in_count, size_t offs, size_t to_write)
-{
- struct s2n_blob iv = { 0 };
- uint8_t padding = 0;
- uint16_t block_size = 0;
- uint8_t aad_iv[S2N_TLS_MAX_IV_LEN] = { 0 };
-
- /* In TLS 1.3, handle CCS message as unprotected records */
- struct s2n_crypto_parameters *current_client_crypto = conn->client;
- struct s2n_crypto_parameters *current_server_crypto = conn->server;
- if (conn->actual_protocol_version == S2N_TLS13 && content_type == TLS_CHANGE_CIPHER_SPEC) {
- conn->client = &conn->initial;
- conn->server = &conn->initial;
- }
-
- uint8_t *sequence_number = conn->server->server_sequence_number;
- struct s2n_hmac_state *mac = &conn->server->server_record_mac;
- struct s2n_session_key *session_key = &conn->server->server_key;
- const struct s2n_cipher_suite *cipher_suite = conn->server->cipher_suite;
- uint8_t *implicit_iv = conn->server->server_implicit_iv;
-
- if (conn->mode == S2N_CLIENT) {
- sequence_number = conn->client->client_sequence_number;
- mac = &conn->client->client_record_mac;
- session_key = &conn->client->client_key;
- cipher_suite = conn->client->cipher_suite;
- implicit_iv = conn->client->client_implicit_iv;
- }
-
- const int is_tls13_record = cipher_suite->record_alg->flags & S2N_TLS13_RECORD_AEAD_NONCE;
- s2n_stack_blob(aad, is_tls13_record ? S2N_TLS13_AAD_LEN : S2N_TLS_MAX_AAD_LEN, S2N_TLS_MAX_AAD_LEN);
-
- S2N_ERROR_IF(s2n_stuffer_data_available(&conn->out), S2N_ERR_RECORD_STUFFER_NEEDS_DRAINING);
-
- uint8_t mac_digest_size;
- GUARD(s2n_hmac_digest_size(mac->alg, &mac_digest_size));
-
- /* Before we do anything, we need to figure out what the length of the
- * fragment is going to be.
- */
- uint16_t max_write_payload_size = 0;
- GUARD_AS_POSIX(s2n_record_max_write_payload_size(conn, &max_write_payload_size));
- const uint16_t data_bytes_to_take = MIN(to_write, max_write_payload_size);
-
- uint16_t extra = 0;
- GUARD_AS_POSIX(s2n_tls_record_overhead(conn, &extra));
-
- /* If we have padding to worry about, figure that out too */
- if (cipher_suite->record_alg->cipher->type == S2N_CBC) {
- block_size = cipher_suite->record_alg->cipher->io.cbc.block_size;
- if (((data_bytes_to_take + extra) % block_size)) {
- padding = block_size - ((data_bytes_to_take + extra) % block_size);
- }
- } else if (cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
- block_size = cipher_suite->record_alg->cipher->io.comp.block_size;
- }
-
- /* Start the MAC with the sequence number */
- GUARD(s2n_hmac_update(mac, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
-
- GUARD(s2n_stuffer_resize_if_empty(&conn->out, S2N_LARGE_RECORD_LENGTH));
-
- /* Now that we know the length, start writing the record */
- GUARD(s2n_stuffer_write_uint8(&conn->out, is_tls13_record ?
- /* tls 1.3 opaque type */ TLS_APPLICATION_DATA :
- /* actual content_type */ content_type ));
- GUARD(s2n_record_write_protocol_version(conn));
-
- /* First write a header that has the payload length, this is for the MAC */
- GUARD(s2n_stuffer_write_uint16(&conn->out, data_bytes_to_take));
-
- if (conn->actual_protocol_version > S2N_SSLv3) {
- GUARD(s2n_hmac_update(mac, conn->out.blob.data, S2N_TLS_RECORD_HEADER_LENGTH));
- } else {
- /* SSLv3 doesn't include the protocol version in the MAC */
- GUARD(s2n_hmac_update(mac, conn->out.blob.data, 1));
- GUARD(s2n_hmac_update(mac, conn->out.blob.data + 3, 2));
- }
-
- /* Compute non-payload parts of the MAC(seq num, type, proto vers, fragment length) for composite ciphers.
- * Composite "encrypt" will MAC the payload data and fill in padding.
- */
- if (cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
- /* Only fragment length is needed for MAC, but the EVP ctrl function needs fragment length + eiv len. */
- uint16_t payload_and_eiv_len = data_bytes_to_take;
- if (conn->actual_protocol_version > S2N_TLS10) {
- payload_and_eiv_len += block_size;
- }
-
- /* Outputs number of extra bytes required for MAC and padding */
- int pad_and_mac_len;
- GUARD(cipher_suite->record_alg->cipher->io.comp.initial_hmac(session_key, sequence_number, content_type, conn->actual_protocol_version,
- payload_and_eiv_len, &pad_and_mac_len));
- extra += pad_and_mac_len;
- }
-
- /* TLS 1.3 protected record occupies one extra byte for content type */
- if (is_tls13_record) {
- extra += TLS13_CONTENT_TYPE_LENGTH;
- }
-
- /* Rewrite the length to be the actual fragment length */
- const uint16_t actual_fragment_length = data_bytes_to_take + padding + extra;
- /* ensure actual_fragment_length + S2N_TLS_RECORD_HEADER_LENGTH <= max record length */
- const uint16_t max_record_length = is_tls13_record ? S2N_TLS13_MAXIMUM_RECORD_LENGTH : S2N_TLS_MAXIMUM_RECORD_LENGTH;
- S2N_ERROR_IF(actual_fragment_length + S2N_TLS_RECORD_HEADER_LENGTH > max_record_length, S2N_ERR_RECORD_LENGTH_TOO_LARGE);
- GUARD(s2n_stuffer_wipe_n(&conn->out, 2));
- GUARD(s2n_stuffer_write_uint16(&conn->out, actual_fragment_length));
-
- /* If we're AEAD, write the sequence number as an IV, and generate the AAD */
- if (cipher_suite->record_alg->cipher->type == S2N_AEAD) {
- struct s2n_stuffer iv_stuffer = {0};
- s2n_blob_init(&iv, aad_iv, sizeof(aad_iv));
- GUARD(s2n_stuffer_init(&iv_stuffer, &iv));
-
- if (cipher_suite->record_alg->flags & S2N_TLS12_AES_GCM_AEAD_NONCE) {
- /* Partially explicit nonce. See RFC 5288 Section 3 */
- GUARD(s2n_stuffer_write_bytes(&conn->out, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
- GUARD(s2n_stuffer_write_bytes(&iv_stuffer, implicit_iv, cipher_suite->record_alg->cipher->io.aead.fixed_iv_size));
- GUARD(s2n_stuffer_write_bytes(&iv_stuffer, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
- } else if (cipher_suite->record_alg->flags & S2N_TLS12_CHACHA_POLY_AEAD_NONCE || is_tls13_record) {
- /* Fully implicit nonce. See RFC7905 Section 2 */
- uint8_t four_zeroes[4] = { 0 };
- GUARD(s2n_stuffer_write_bytes(&iv_stuffer, four_zeroes, 4));
- GUARD(s2n_stuffer_write_bytes(&iv_stuffer, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
- for(int i = 0; i < cipher_suite->record_alg->cipher->io.aead.fixed_iv_size; i++) {
- aad_iv[i] = aad_iv[i] ^ implicit_iv[i];
- }
- } else {
- S2N_ERROR(S2N_ERR_INVALID_NONCE_TYPE);
- }
-
- /* Set the IV size to the amount of data written */
- iv.size = s2n_stuffer_data_available(&iv_stuffer);
-
- struct s2n_stuffer ad_stuffer = {0};
- GUARD(s2n_stuffer_init(&ad_stuffer, &aad));
- if (is_tls13_record) {
- GUARD_AS_POSIX(s2n_tls13_aead_aad_init(data_bytes_to_take + TLS13_CONTENT_TYPE_LENGTH, cipher_suite->record_alg->cipher->io.aead.tag_size, &ad_stuffer));
- } else {
- GUARD_AS_POSIX(s2n_aead_aad_init(conn, sequence_number, content_type, data_bytes_to_take, &ad_stuffer));
- }
- } else if (cipher_suite->record_alg->cipher->type == S2N_CBC || cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
- s2n_blob_init(&iv, implicit_iv, block_size);
-
- /* For TLS1.1/1.2; write the IV with random data */
- if (conn->actual_protocol_version > S2N_TLS10) {
- GUARD_AS_POSIX(s2n_get_public_random_data(&iv));
- if (cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
- /* Write a separate random block to the record. This will be used along with the previously generated
- * iv blob to generate the final explicit_iv for this record.
- *
- * How? Openssl's AES-CBC stitched encrypt populates the first block of application data with:
- * AES(Key, XOR(iv, initial_block))
- *
- * If we make initial_block a random block unrelated to random_iv, explicit IV for this record
- * is random value based on the two random blobs we just generated:
- * AES(Key, XOR(random_iv, explicit_iv_placeholder) == AES(Key, XOR(random_iv, random_iv2))
- *
- * NOTE: We can't use the same random IV blob as both the initial block and IV since it will result in:
- * AES(Key, XOR(random_iv, random_iv)) == AES(Key, 0), which will be shared by all records in this session.
- */
- struct s2n_blob explicit_iv_placeholder;
- uint8_t zero_block[S2N_TLS_MAX_IV_LEN] = { 0 };
- GUARD(s2n_blob_init(&explicit_iv_placeholder, zero_block, block_size));
- GUARD_AS_POSIX(s2n_get_public_random_data(&explicit_iv_placeholder));
- GUARD(s2n_stuffer_write(&conn->out, &explicit_iv_placeholder));
- } else {
- /* We can write the explicit IV directly to the record for non composite CBC because
- * s2n starts AES *after* the explicit IV.
- */
- GUARD(s2n_stuffer_write(&conn->out, &iv));
- }
- }
- }
-
- /* We are done with this sequence number, so we can increment it */
- struct s2n_blob seq = {.data = sequence_number,.size = S2N_TLS_SEQUENCE_NUM_LEN };
- GUARD(s2n_increment_sequence_number(&seq));
-
- /* Write the plaintext data */
- GUARD(s2n_stuffer_writev_bytes(&conn->out, in, in_count, offs, data_bytes_to_take));
- void *orig_write_ptr = conn->out.blob.data + conn->out.write_cursor - data_bytes_to_take;
- GUARD(s2n_hmac_update(mac, orig_write_ptr, data_bytes_to_take));
-
- /* Write the digest */
- uint8_t *digest = s2n_stuffer_raw_write(&conn->out, mac_digest_size);
- notnull_check(digest);
-
- GUARD(s2n_hmac_digest(mac, digest, mac_digest_size));
- GUARD(s2n_hmac_reset(mac));
-
- /* Write content type for TLS 1.3 record (RFC 8446 Section 5.2) */
- if (is_tls13_record) {
- GUARD(s2n_stuffer_write_uint8(&conn->out, content_type));
- }
-
- if (cipher_suite->record_alg->cipher->type == S2N_CBC) {
- /* Include padding bytes, each with the value 'p', and
- * include an extra padding length byte, also with the value 'p'.
- */
- for (int i = 0; i <= padding; i++) {
- GUARD(s2n_stuffer_write_uint8(&conn->out, padding));
- }
- }
-
- /* Rewind to rewrite/encrypt the packet */
- GUARD(s2n_stuffer_rewrite(&conn->out));
-
- /* Skip the header */
- GUARD(s2n_stuffer_skip_write(&conn->out, S2N_TLS_RECORD_HEADER_LENGTH));
-
- uint16_t encrypted_length = data_bytes_to_take + mac_digest_size;
- switch (cipher_suite->record_alg->cipher->type) {
- case S2N_AEAD:
- GUARD(s2n_stuffer_skip_write(&conn->out, cipher_suite->record_alg->cipher->io.aead.record_iv_size));
- encrypted_length += cipher_suite->record_alg->cipher->io.aead.tag_size;
- if (is_tls13_record) {
- /* one extra byte for content type */
- encrypted_length += TLS13_CONTENT_TYPE_LENGTH;
- }
- break;
- case S2N_CBC:
- if (conn->actual_protocol_version > S2N_TLS10) {
- /* Leave the IV alone and unencrypted */
- GUARD(s2n_stuffer_skip_write(&conn->out, iv.size));
- }
- /* Encrypt the padding and the padding length byte too */
- encrypted_length += padding + 1;
- break;
- case S2N_COMPOSITE:
- /* Composite CBC expects a pointer starting at explicit IV: [Explicit IV | fragment | MAC | padding | padding len ]
- * extra will account for the explicit IV len(if applicable), MAC digest len, padding len + padding byte.
- */
- encrypted_length += extra;
- break;
- default:
- break;
- }
-
- /* Check that stuffer have enough space to write encrypted record, because raw_write cannot expand tainted stuffer */
- S2N_ERROR_IF(s2n_stuffer_space_remaining(&conn->out) < encrypted_length, S2N_ERR_RECORD_STUFFER_SIZE);
-
- /* Do the encryption */
- struct s2n_blob en = { .size = encrypted_length, .data = s2n_stuffer_raw_write(&conn->out, encrypted_length) };
- GUARD(s2n_record_encrypt(conn, cipher_suite, session_key, &iv, &aad, &en, implicit_iv, block_size));
-
- if (conn->actual_protocol_version == S2N_TLS13 && content_type == TLS_CHANGE_CIPHER_SPEC) {
- conn->client = current_client_crypto;
- conn->server = current_server_crypto;
- }
-
- conn->wire_bytes_out += actual_fragment_length + S2N_TLS_RECORD_HEADER_LENGTH;
-
- return data_bytes_to_take;
-}
-
-int s2n_record_write(struct s2n_connection *conn, uint8_t content_type, struct s2n_blob *in)
-{
- struct iovec iov;
- iov.iov_base = in->data;
- iov.iov_len = in->size;
- return s2n_record_writev(conn, content_type, &iov, 1, 0, in->size);
-}
+/*
+ * 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 <stdint.h>
+#include <sys/param.h>
+
+#include "error/s2n_errno.h"
+
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_record.h"
+#include "tls/s2n_crypto.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "crypto/s2n_sequence.h"
+#include "crypto/s2n_cipher.h"
+#include "crypto/s2n_hmac.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_random.h"
+#include "utils/s2n_blob.h"
+
+extern uint8_t s2n_unknown_protocol_version;
+
+/* How much overhead does the IV, MAC, TAG and padding bytes introduce ? */
+static S2N_RESULT s2n_tls_record_overhead(struct s2n_connection *conn, uint16_t *out)
+{
+ ENSURE_REF(conn);
+ ENSURE_MUT(out);
+ struct s2n_crypto_parameters *active = conn->server;
+
+ if (conn->mode == S2N_CLIENT) {
+ active = conn->client;
+ }
+
+ uint8_t extra;
+ GUARD_AS_RESULT(s2n_hmac_digest_size(active->cipher_suite->record_alg->hmac_alg, &extra));
+
+ if (active->cipher_suite->record_alg->cipher->type == S2N_CBC) {
+ /* Subtract one for the padding length byte */
+ extra += 1;
+
+ if (conn->actual_protocol_version > S2N_TLS10) {
+ extra += active->cipher_suite->record_alg->cipher->io.cbc.record_iv_size;
+ }
+ } else if (active->cipher_suite->record_alg->cipher->type == S2N_AEAD) {
+ extra += active->cipher_suite->record_alg->cipher->io.aead.tag_size;
+ extra += active->cipher_suite->record_alg->cipher->io.aead.record_iv_size;
+ } else if (active->cipher_suite->record_alg->cipher->type == S2N_COMPOSITE && conn->actual_protocol_version > S2N_TLS10) {
+ extra += active->cipher_suite->record_alg->cipher->io.comp.record_iv_size;
+ }
+
+ *out = extra;
+
+ return S2N_RESULT_OK;
+}
+
+/* This function returns maximum size of plaintext data to write for the payload.
+ * Record overheads are not included here.
+ */
+S2N_RESULT s2n_record_max_write_payload_size(struct s2n_connection *conn, uint16_t *max_fragment_size)
+{
+ ENSURE_REF(conn);
+ ENSURE_MUT(max_fragment_size);
+ ENSURE(conn->max_outgoing_fragment_length > 0, S2N_ERR_FRAGMENT_LENGTH_TOO_SMALL);
+
+ *max_fragment_size = MIN(conn->max_outgoing_fragment_length, S2N_TLS_MAXIMUM_FRAGMENT_LENGTH);
+
+ return S2N_RESULT_OK;
+}
+
+/* Find the largest size that will fit within an ethernet frame for a "small" payload */
+S2N_RESULT s2n_record_min_write_payload_size(struct s2n_connection *conn, uint16_t *payload_size)
+{
+ ENSURE_REF(conn);
+ ENSURE_MUT(payload_size);
+ /* remove ethernet, TCP/IP and TLS header overheads */
+ const uint16_t min_outgoing_fragment_length = ETH_MTU - (conn->ipv6 ? IP_V6_HEADER_LENGTH : IP_V4_HEADER_LENGTH)
+ - TCP_HEADER_LENGTH - TCP_OPTIONS_LENGTH - S2N_TLS_RECORD_HEADER_LENGTH;
+
+ ENSURE(min_outgoing_fragment_length <= S2N_TLS_MAXIMUM_FRAGMENT_LENGTH, S2N_ERR_FRAGMENT_LENGTH_TOO_LARGE);
+ uint16_t size = min_outgoing_fragment_length;
+
+ const struct s2n_crypto_parameters *active = conn->mode == S2N_CLIENT ? conn->client : conn->server;
+
+ /* Round the fragment size down to be block aligned */
+ if (active->cipher_suite->record_alg->cipher->type == S2N_CBC) {
+ size -= size % active->cipher_suite->record_alg->cipher->io.cbc.block_size;
+ } else if (active->cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
+ size -= size % active->cipher_suite->record_alg->cipher->io.comp.block_size;
+ /* Composite digest length */
+ size -= active->cipher_suite->record_alg->cipher->io.comp.mac_key_size;
+ /* Padding length byte */
+ size -= 1;
+ }
+
+ /* subtract overheads of a TLS record */
+ uint16_t overhead = 0;
+ GUARD_RESULT(s2n_tls_record_overhead(conn, &overhead));
+ ENSURE(size > overhead, S2N_ERR_FRAGMENT_LENGTH_TOO_SMALL);
+ size -= overhead;
+
+ ENSURE(size > 0, S2N_ERR_FRAGMENT_LENGTH_TOO_SMALL);
+ ENSURE(size <= ETH_MTU, S2N_ERR_FRAGMENT_LENGTH_TOO_LARGE);
+
+ *payload_size = size;
+
+ return S2N_RESULT_OK;
+}
+
+int s2n_record_write_protocol_version(struct s2n_connection *conn)
+{
+ uint8_t record_protocol_version = conn->actual_protocol_version;
+ if (conn->server_protocol_version == s2n_unknown_protocol_version) {
+ /* Some legacy TLS implementations can't handle records with protocol version higher than TLS1.0.
+ * To provide maximum compatibility, send record version as TLS1.0 if server protocol version isn't
+ * established yet, which happens only during ClientHello message. Note, this has no effect on
+ * protocol version in ClientHello, so we're still able to negotiate protocol versions above TLS1.0 */
+ record_protocol_version = MIN(record_protocol_version, S2N_TLS10);
+ }
+
+ /* In accordance to TLS 1.3 spec, https://tools.ietf.org/html/rfc8446#section-5.1
+ * tls record version should never be greater than 33 (legacy TLS 1.2 version).
+ */
+ record_protocol_version = MIN(record_protocol_version, S2N_TLS12);
+
+ uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN];
+ protocol_version[0] = record_protocol_version / 10;
+ protocol_version[1] = record_protocol_version % 10;
+
+ GUARD(s2n_stuffer_write_bytes(&conn->out, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
+
+ return 0;
+}
+
+static inline int s2n_record_encrypt(
+ struct s2n_connection *conn,
+ const struct s2n_cipher_suite *cipher_suite,
+ struct s2n_session_key *session_key,
+ struct s2n_blob *iv,
+ struct s2n_blob *aad,
+ struct s2n_blob *en,
+ uint8_t *implicit_iv, uint16_t block_size)
+{
+ notnull_check(en->data);
+
+ switch (cipher_suite->record_alg->cipher->type) {
+ case S2N_STREAM:
+ GUARD(cipher_suite->record_alg->cipher->io.stream.encrypt(session_key, en, en));
+ break;
+ case S2N_CBC:
+ GUARD(cipher_suite->record_alg->cipher->io.cbc.encrypt(session_key, iv, en, en));
+
+ /* Copy the last encrypted block to be the next IV */
+ if (conn->actual_protocol_version < S2N_TLS11) {
+ gte_check(en->size, block_size);
+ memcpy_check(implicit_iv, en->data + en->size - block_size, block_size);
+ }
+ break;
+ case S2N_AEAD:
+ GUARD(cipher_suite->record_alg->cipher->io.aead.encrypt(session_key, iv, aad, en, en));
+ break;
+ case S2N_COMPOSITE:
+ /* This will: compute mac, append padding, append padding length, and encrypt */
+ GUARD(cipher_suite->record_alg->cipher->io.comp.encrypt(session_key, iv, en, en));
+
+ /* Copy the last encrypted block to be the next IV */
+ gte_check(en->size, block_size);
+ memcpy_check(implicit_iv, en->data + en->size - block_size, block_size);
+ break;
+ default:
+ S2N_ERROR(S2N_ERR_CIPHER_TYPE);
+ break;
+ }
+
+ return 0;
+}
+
+int s2n_record_writev(struct s2n_connection *conn, uint8_t content_type, const struct iovec *in, int in_count, size_t offs, size_t to_write)
+{
+ struct s2n_blob iv = { 0 };
+ uint8_t padding = 0;
+ uint16_t block_size = 0;
+ uint8_t aad_iv[S2N_TLS_MAX_IV_LEN] = { 0 };
+
+ /* In TLS 1.3, handle CCS message as unprotected records */
+ struct s2n_crypto_parameters *current_client_crypto = conn->client;
+ struct s2n_crypto_parameters *current_server_crypto = conn->server;
+ if (conn->actual_protocol_version == S2N_TLS13 && content_type == TLS_CHANGE_CIPHER_SPEC) {
+ conn->client = &conn->initial;
+ conn->server = &conn->initial;
+ }
+
+ uint8_t *sequence_number = conn->server->server_sequence_number;
+ struct s2n_hmac_state *mac = &conn->server->server_record_mac;
+ struct s2n_session_key *session_key = &conn->server->server_key;
+ const struct s2n_cipher_suite *cipher_suite = conn->server->cipher_suite;
+ uint8_t *implicit_iv = conn->server->server_implicit_iv;
+
+ if (conn->mode == S2N_CLIENT) {
+ sequence_number = conn->client->client_sequence_number;
+ mac = &conn->client->client_record_mac;
+ session_key = &conn->client->client_key;
+ cipher_suite = conn->client->cipher_suite;
+ implicit_iv = conn->client->client_implicit_iv;
+ }
+
+ const int is_tls13_record = cipher_suite->record_alg->flags & S2N_TLS13_RECORD_AEAD_NONCE;
+ s2n_stack_blob(aad, is_tls13_record ? S2N_TLS13_AAD_LEN : S2N_TLS_MAX_AAD_LEN, S2N_TLS_MAX_AAD_LEN);
+
+ S2N_ERROR_IF(s2n_stuffer_data_available(&conn->out), S2N_ERR_RECORD_STUFFER_NEEDS_DRAINING);
+
+ uint8_t mac_digest_size;
+ GUARD(s2n_hmac_digest_size(mac->alg, &mac_digest_size));
+
+ /* Before we do anything, we need to figure out what the length of the
+ * fragment is going to be.
+ */
+ uint16_t max_write_payload_size = 0;
+ GUARD_AS_POSIX(s2n_record_max_write_payload_size(conn, &max_write_payload_size));
+ const uint16_t data_bytes_to_take = MIN(to_write, max_write_payload_size);
+
+ uint16_t extra = 0;
+ GUARD_AS_POSIX(s2n_tls_record_overhead(conn, &extra));
+
+ /* If we have padding to worry about, figure that out too */
+ if (cipher_suite->record_alg->cipher->type == S2N_CBC) {
+ block_size = cipher_suite->record_alg->cipher->io.cbc.block_size;
+ if (((data_bytes_to_take + extra) % block_size)) {
+ padding = block_size - ((data_bytes_to_take + extra) % block_size);
+ }
+ } else if (cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
+ block_size = cipher_suite->record_alg->cipher->io.comp.block_size;
+ }
+
+ /* Start the MAC with the sequence number */
+ GUARD(s2n_hmac_update(mac, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
+
+ GUARD(s2n_stuffer_resize_if_empty(&conn->out, S2N_LARGE_RECORD_LENGTH));
+
+ /* Now that we know the length, start writing the record */
+ GUARD(s2n_stuffer_write_uint8(&conn->out, is_tls13_record ?
+ /* tls 1.3 opaque type */ TLS_APPLICATION_DATA :
+ /* actual content_type */ content_type ));
+ GUARD(s2n_record_write_protocol_version(conn));
+
+ /* First write a header that has the payload length, this is for the MAC */
+ GUARD(s2n_stuffer_write_uint16(&conn->out, data_bytes_to_take));
+
+ if (conn->actual_protocol_version > S2N_SSLv3) {
+ GUARD(s2n_hmac_update(mac, conn->out.blob.data, S2N_TLS_RECORD_HEADER_LENGTH));
+ } else {
+ /* SSLv3 doesn't include the protocol version in the MAC */
+ GUARD(s2n_hmac_update(mac, conn->out.blob.data, 1));
+ GUARD(s2n_hmac_update(mac, conn->out.blob.data + 3, 2));
+ }
+
+ /* Compute non-payload parts of the MAC(seq num, type, proto vers, fragment length) for composite ciphers.
+ * Composite "encrypt" will MAC the payload data and fill in padding.
+ */
+ if (cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
+ /* Only fragment length is needed for MAC, but the EVP ctrl function needs fragment length + eiv len. */
+ uint16_t payload_and_eiv_len = data_bytes_to_take;
+ if (conn->actual_protocol_version > S2N_TLS10) {
+ payload_and_eiv_len += block_size;
+ }
+
+ /* Outputs number of extra bytes required for MAC and padding */
+ int pad_and_mac_len;
+ GUARD(cipher_suite->record_alg->cipher->io.comp.initial_hmac(session_key, sequence_number, content_type, conn->actual_protocol_version,
+ payload_and_eiv_len, &pad_and_mac_len));
+ extra += pad_and_mac_len;
+ }
+
+ /* TLS 1.3 protected record occupies one extra byte for content type */
+ if (is_tls13_record) {
+ extra += TLS13_CONTENT_TYPE_LENGTH;
+ }
+
+ /* Rewrite the length to be the actual fragment length */
+ const uint16_t actual_fragment_length = data_bytes_to_take + padding + extra;
+ /* ensure actual_fragment_length + S2N_TLS_RECORD_HEADER_LENGTH <= max record length */
+ const uint16_t max_record_length = is_tls13_record ? S2N_TLS13_MAXIMUM_RECORD_LENGTH : S2N_TLS_MAXIMUM_RECORD_LENGTH;
+ S2N_ERROR_IF(actual_fragment_length + S2N_TLS_RECORD_HEADER_LENGTH > max_record_length, S2N_ERR_RECORD_LENGTH_TOO_LARGE);
+ GUARD(s2n_stuffer_wipe_n(&conn->out, 2));
+ GUARD(s2n_stuffer_write_uint16(&conn->out, actual_fragment_length));
+
+ /* If we're AEAD, write the sequence number as an IV, and generate the AAD */
+ if (cipher_suite->record_alg->cipher->type == S2N_AEAD) {
+ struct s2n_stuffer iv_stuffer = {0};
+ s2n_blob_init(&iv, aad_iv, sizeof(aad_iv));
+ GUARD(s2n_stuffer_init(&iv_stuffer, &iv));
+
+ if (cipher_suite->record_alg->flags & S2N_TLS12_AES_GCM_AEAD_NONCE) {
+ /* Partially explicit nonce. See RFC 5288 Section 3 */
+ GUARD(s2n_stuffer_write_bytes(&conn->out, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
+ GUARD(s2n_stuffer_write_bytes(&iv_stuffer, implicit_iv, cipher_suite->record_alg->cipher->io.aead.fixed_iv_size));
+ GUARD(s2n_stuffer_write_bytes(&iv_stuffer, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
+ } else if (cipher_suite->record_alg->flags & S2N_TLS12_CHACHA_POLY_AEAD_NONCE || is_tls13_record) {
+ /* Fully implicit nonce. See RFC7905 Section 2 */
+ uint8_t four_zeroes[4] = { 0 };
+ GUARD(s2n_stuffer_write_bytes(&iv_stuffer, four_zeroes, 4));
+ GUARD(s2n_stuffer_write_bytes(&iv_stuffer, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
+ for(int i = 0; i < cipher_suite->record_alg->cipher->io.aead.fixed_iv_size; i++) {
+ aad_iv[i] = aad_iv[i] ^ implicit_iv[i];
+ }
+ } else {
+ S2N_ERROR(S2N_ERR_INVALID_NONCE_TYPE);
+ }
+
+ /* Set the IV size to the amount of data written */
+ iv.size = s2n_stuffer_data_available(&iv_stuffer);
+
+ struct s2n_stuffer ad_stuffer = {0};
+ GUARD(s2n_stuffer_init(&ad_stuffer, &aad));
+ if (is_tls13_record) {
+ GUARD_AS_POSIX(s2n_tls13_aead_aad_init(data_bytes_to_take + TLS13_CONTENT_TYPE_LENGTH, cipher_suite->record_alg->cipher->io.aead.tag_size, &ad_stuffer));
+ } else {
+ GUARD_AS_POSIX(s2n_aead_aad_init(conn, sequence_number, content_type, data_bytes_to_take, &ad_stuffer));
+ }
+ } else if (cipher_suite->record_alg->cipher->type == S2N_CBC || cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
+ s2n_blob_init(&iv, implicit_iv, block_size);
+
+ /* For TLS1.1/1.2; write the IV with random data */
+ if (conn->actual_protocol_version > S2N_TLS10) {
+ GUARD_AS_POSIX(s2n_get_public_random_data(&iv));
+ if (cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
+ /* Write a separate random block to the record. This will be used along with the previously generated
+ * iv blob to generate the final explicit_iv for this record.
+ *
+ * How? Openssl's AES-CBC stitched encrypt populates the first block of application data with:
+ * AES(Key, XOR(iv, initial_block))
+ *
+ * If we make initial_block a random block unrelated to random_iv, explicit IV for this record
+ * is random value based on the two random blobs we just generated:
+ * AES(Key, XOR(random_iv, explicit_iv_placeholder) == AES(Key, XOR(random_iv, random_iv2))
+ *
+ * NOTE: We can't use the same random IV blob as both the initial block and IV since it will result in:
+ * AES(Key, XOR(random_iv, random_iv)) == AES(Key, 0), which will be shared by all records in this session.
+ */
+ struct s2n_blob explicit_iv_placeholder;
+ uint8_t zero_block[S2N_TLS_MAX_IV_LEN] = { 0 };
+ GUARD(s2n_blob_init(&explicit_iv_placeholder, zero_block, block_size));
+ GUARD_AS_POSIX(s2n_get_public_random_data(&explicit_iv_placeholder));
+ GUARD(s2n_stuffer_write(&conn->out, &explicit_iv_placeholder));
+ } else {
+ /* We can write the explicit IV directly to the record for non composite CBC because
+ * s2n starts AES *after* the explicit IV.
+ */
+ GUARD(s2n_stuffer_write(&conn->out, &iv));
+ }
+ }
+ }
+
+ /* We are done with this sequence number, so we can increment it */
+ struct s2n_blob seq = {.data = sequence_number,.size = S2N_TLS_SEQUENCE_NUM_LEN };
+ GUARD(s2n_increment_sequence_number(&seq));
+
+ /* Write the plaintext data */
+ GUARD(s2n_stuffer_writev_bytes(&conn->out, in, in_count, offs, data_bytes_to_take));
+ void *orig_write_ptr = conn->out.blob.data + conn->out.write_cursor - data_bytes_to_take;
+ GUARD(s2n_hmac_update(mac, orig_write_ptr, data_bytes_to_take));
+
+ /* Write the digest */
+ uint8_t *digest = s2n_stuffer_raw_write(&conn->out, mac_digest_size);
+ notnull_check(digest);
+
+ GUARD(s2n_hmac_digest(mac, digest, mac_digest_size));
+ GUARD(s2n_hmac_reset(mac));
+
+ /* Write content type for TLS 1.3 record (RFC 8446 Section 5.2) */
+ if (is_tls13_record) {
+ GUARD(s2n_stuffer_write_uint8(&conn->out, content_type));
+ }
+
+ if (cipher_suite->record_alg->cipher->type == S2N_CBC) {
+ /* Include padding bytes, each with the value 'p', and
+ * include an extra padding length byte, also with the value 'p'.
+ */
+ for (int i = 0; i <= padding; i++) {
+ GUARD(s2n_stuffer_write_uint8(&conn->out, padding));
+ }
+ }
+
+ /* Rewind to rewrite/encrypt the packet */
+ GUARD(s2n_stuffer_rewrite(&conn->out));
+
+ /* Skip the header */
+ GUARD(s2n_stuffer_skip_write(&conn->out, S2N_TLS_RECORD_HEADER_LENGTH));
+
+ uint16_t encrypted_length = data_bytes_to_take + mac_digest_size;
+ switch (cipher_suite->record_alg->cipher->type) {
+ case S2N_AEAD:
+ GUARD(s2n_stuffer_skip_write(&conn->out, cipher_suite->record_alg->cipher->io.aead.record_iv_size));
+ encrypted_length += cipher_suite->record_alg->cipher->io.aead.tag_size;
+ if (is_tls13_record) {
+ /* one extra byte for content type */
+ encrypted_length += TLS13_CONTENT_TYPE_LENGTH;
+ }
+ break;
+ case S2N_CBC:
+ if (conn->actual_protocol_version > S2N_TLS10) {
+ /* Leave the IV alone and unencrypted */
+ GUARD(s2n_stuffer_skip_write(&conn->out, iv.size));
+ }
+ /* Encrypt the padding and the padding length byte too */
+ encrypted_length += padding + 1;
+ break;
+ case S2N_COMPOSITE:
+ /* Composite CBC expects a pointer starting at explicit IV: [Explicit IV | fragment | MAC | padding | padding len ]
+ * extra will account for the explicit IV len(if applicable), MAC digest len, padding len + padding byte.
+ */
+ encrypted_length += extra;
+ break;
+ default:
+ break;
+ }
+
+ /* Check that stuffer have enough space to write encrypted record, because raw_write cannot expand tainted stuffer */
+ S2N_ERROR_IF(s2n_stuffer_space_remaining(&conn->out) < encrypted_length, S2N_ERR_RECORD_STUFFER_SIZE);
+
+ /* Do the encryption */
+ struct s2n_blob en = { .size = encrypted_length, .data = s2n_stuffer_raw_write(&conn->out, encrypted_length) };
+ GUARD(s2n_record_encrypt(conn, cipher_suite, session_key, &iv, &aad, &en, implicit_iv, block_size));
+
+ if (conn->actual_protocol_version == S2N_TLS13 && content_type == TLS_CHANGE_CIPHER_SPEC) {
+ conn->client = current_client_crypto;
+ conn->server = current_server_crypto;
+ }
+
+ conn->wire_bytes_out += actual_fragment_length + S2N_TLS_RECORD_HEADER_LENGTH;
+
+ return data_bytes_to_take;
+}
+
+int s2n_record_write(struct s2n_connection *conn, uint8_t content_type, struct s2n_blob *in)
+{
+ struct iovec iov;
+ iov.iov_base = in->data;
+ iov.iov_len = in->size;
+ return s2n_record_writev(conn, content_type, &iov, 1, 0, in->size);
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_recv.c b/contrib/restricted/aws/s2n/tls/s2n_recv.c
index e04b752fe8..8d0d04d4f0 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_recv.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_recv.c
@@ -1,229 +1,229 @@
-/*
- * 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 <sys/param.h>
-
-/* Use usleep */
-#define _XOPEN_SOURCE 500
-#include <unistd.h>
-
-#include <errno.h>
-#include <s2n.h>
-
-#include "error/s2n_errno.h"
-
-#include "tls/s2n_connection.h"
-#include "tls/s2n_handshake.h"
-#include "tls/s2n_record.h"
-#include "tls/s2n_resume.h"
-#include "tls/s2n_alerts.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_post_handshake.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_socket.h"
-#include "utils/s2n_safety.h"
-#include "utils/s2n_blob.h"
-
-S2N_RESULT s2n_read_in_bytes(struct s2n_connection *conn, struct s2n_stuffer *output, uint32_t length)
-{
- while (s2n_stuffer_data_available(output) < length) {
- uint32_t remaining = length - s2n_stuffer_data_available(output);
-
- errno = 0;
- int r = s2n_connection_recv_stuffer(output, conn, remaining);
- if (r == 0) {
- conn->closed = 1;
- BAIL(S2N_ERR_CLOSED);
- } else if (r < 0) {
- if (errno == EWOULDBLOCK || errno == EAGAIN) {
- BAIL(S2N_ERR_IO_BLOCKED);
- }
- BAIL(S2N_ERR_IO);
- }
- conn->wire_bytes_in += r;
- }
-
- return S2N_RESULT_OK;
-}
-
-int s2n_read_full_record(struct s2n_connection *conn, uint8_t * record_type, int *isSSLv2)
-{
- *isSSLv2 = 0;
-
- /* If the record has already been decrypted, then leave it alone */
- if (conn->in_status == PLAINTEXT) {
- /* Only application data packets count as plaintext */
- *record_type = TLS_APPLICATION_DATA;
- return S2N_SUCCESS;
- }
- GUARD(s2n_stuffer_resize_if_empty(&conn->in, S2N_LARGE_FRAGMENT_LENGTH));
-
- /* Read the record until we at least have a header */
- GUARD_AS_POSIX(s2n_read_in_bytes(conn, &conn->header_in, S2N_TLS_RECORD_HEADER_LENGTH));
-
- uint16_t fragment_length;
-
- /* If the first bit is set then this is an SSLv2 record */
- if (conn->header_in.blob.data[0] & 0x80) {
- conn->header_in.blob.data[0] &= 0x7f;
- *isSSLv2 = 1;
-
- if (s2n_sslv2_record_header_parse(conn, record_type, &conn->client_protocol_version, &fragment_length) < 0) {
- GUARD(s2n_connection_kill(conn));
- S2N_ERROR_PRESERVE_ERRNO();
- }
- } else {
- if (s2n_record_header_parse(conn, record_type, &fragment_length) < 0) {
- GUARD(s2n_connection_kill(conn));
- S2N_ERROR_PRESERVE_ERRNO();
- }
- }
-
- /* Read enough to have the whole record */
- GUARD_AS_POSIX(s2n_read_in_bytes(conn, &conn->in, fragment_length));
-
- if (*isSSLv2) {
- return 0;
- }
-
- /* Decrypt and parse the record */
- if (s2n_record_parse(conn) < 0) {
- GUARD(s2n_connection_kill(conn));
- S2N_ERROR_PRESERVE_ERRNO();
- }
-
- /* In TLS 1.3, encrypted handshake records would appear to be of record type
- * TLS_APPLICATION_DATA. The actual record content type is found after the encrypted
- * is decrypted.
- */
- if (conn->actual_protocol_version == S2N_TLS13 && *record_type == TLS_APPLICATION_DATA) {
- GUARD(s2n_tls13_parse_record_type(&conn->in, record_type));
- }
-
- return 0;
-}
-
-ssize_t s2n_recv(struct s2n_connection * conn, void *buf, ssize_t size, s2n_blocked_status * blocked)
-{
- ssize_t bytes_read = 0;
- struct s2n_blob out = {.data = (uint8_t *) buf };
-
- if (conn->closed) {
- return 0;
- }
- *blocked = S2N_BLOCKED_ON_READ;
-
- S2N_ERROR_IF(conn->config->quic_enabled, S2N_ERR_UNSUPPORTED_WITH_QUIC);
-
- while (size && !conn->closed) {
- int isSSLv2 = 0;
- uint8_t record_type;
- int r = s2n_read_full_record(conn, &record_type, &isSSLv2);
- if (r < 0) {
- if (s2n_errno == S2N_ERR_CLOSED) {
- *blocked = S2N_NOT_BLOCKED;
- if (!bytes_read) {
- return 0;
- } else {
- return bytes_read;
- }
- }
-
- /* Don't propagate the error if we already read some bytes */
- if (s2n_errno == S2N_ERR_IO_BLOCKED && bytes_read) {
- s2n_errno = S2N_ERR_OK;
- return bytes_read;
- }
-
- /* If we get here, it's an error condition */
- if (s2n_errno != S2N_ERR_IO_BLOCKED && s2n_allowed_to_cache_connection(conn) && conn->session_id_len) {
- conn->config->cache_delete(conn, conn->config->cache_delete_data, conn->session_id, conn->session_id_len);
- }
-
- S2N_ERROR_PRESERVE_ERRNO();
- }
-
- S2N_ERROR_IF(isSSLv2, S2N_ERR_BAD_MESSAGE);
-
- if (record_type != TLS_APPLICATION_DATA) {
- switch (record_type)
- {
- case TLS_ALERT:
- GUARD(s2n_process_alert_fragment(conn));
- GUARD(s2n_flush(conn, blocked));
- break;
- case TLS_HANDSHAKE:
- GUARD(s2n_post_handshake_recv(conn));
- break;
- }
- GUARD(s2n_stuffer_wipe(&conn->header_in));
- GUARD(s2n_stuffer_wipe(&conn->in));
- conn->in_status = ENCRYPTED;
- continue;
- }
-
- out.size = MIN(size, s2n_stuffer_data_available(&conn->in));
-
- GUARD(s2n_stuffer_erase_and_read(&conn->in, &out));
- bytes_read += out.size;
-
- out.data += out.size;
- size -= out.size;
-
- /* Are we ready for more encrypted data? */
- if (s2n_stuffer_data_available(&conn->in) == 0) {
- GUARD(s2n_stuffer_wipe(&conn->header_in));
- GUARD(s2n_stuffer_wipe(&conn->in));
- conn->in_status = ENCRYPTED;
- }
-
- /* If we've read some data, return it */
- if (bytes_read) {
- break;
- }
- }
-
- if (s2n_stuffer_data_available(&conn->in) == 0) {
- *blocked = S2N_NOT_BLOCKED;
- }
-
- return bytes_read;
-}
-
-uint32_t s2n_peek(struct s2n_connection *conn) {
- return s2n_stuffer_data_available(&conn->in);
-}
-
-int s2n_recv_close_notify(struct s2n_connection *conn, s2n_blocked_status * blocked)
-{
- uint8_t record_type;
- int isSSLv2;
- *blocked = S2N_BLOCKED_ON_READ;
-
- GUARD(s2n_read_full_record(conn, &record_type, &isSSLv2));
-
- S2N_ERROR_IF(isSSLv2, S2N_ERR_BAD_MESSAGE);
-
- S2N_ERROR_IF(record_type != TLS_ALERT, S2N_ERR_SHUTDOWN_RECORD_TYPE);
-
- /* Only succeeds for an incoming close_notify alert */
- GUARD(s2n_process_alert_fragment(conn));
-
- *blocked = S2N_NOT_BLOCKED;
- return 0;
-}
-
+/*
+ * 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 <sys/param.h>
+
+/* Use usleep */
+#define _XOPEN_SOURCE 500
+#include <unistd.h>
+
+#include <errno.h>
+#include <s2n.h>
+
+#include "error/s2n_errno.h"
+
+#include "tls/s2n_connection.h"
+#include "tls/s2n_handshake.h"
+#include "tls/s2n_record.h"
+#include "tls/s2n_resume.h"
+#include "tls/s2n_alerts.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_post_handshake.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_socket.h"
+#include "utils/s2n_safety.h"
+#include "utils/s2n_blob.h"
+
+S2N_RESULT s2n_read_in_bytes(struct s2n_connection *conn, struct s2n_stuffer *output, uint32_t length)
+{
+ while (s2n_stuffer_data_available(output) < length) {
+ uint32_t remaining = length - s2n_stuffer_data_available(output);
+
+ errno = 0;
+ int r = s2n_connection_recv_stuffer(output, conn, remaining);
+ if (r == 0) {
+ conn->closed = 1;
+ BAIL(S2N_ERR_CLOSED);
+ } else if (r < 0) {
+ if (errno == EWOULDBLOCK || errno == EAGAIN) {
+ BAIL(S2N_ERR_IO_BLOCKED);
+ }
+ BAIL(S2N_ERR_IO);
+ }
+ conn->wire_bytes_in += r;
+ }
+
+ return S2N_RESULT_OK;
+}
+
+int s2n_read_full_record(struct s2n_connection *conn, uint8_t * record_type, int *isSSLv2)
+{
+ *isSSLv2 = 0;
+
+ /* If the record has already been decrypted, then leave it alone */
+ if (conn->in_status == PLAINTEXT) {
+ /* Only application data packets count as plaintext */
+ *record_type = TLS_APPLICATION_DATA;
+ return S2N_SUCCESS;
+ }
+ GUARD(s2n_stuffer_resize_if_empty(&conn->in, S2N_LARGE_FRAGMENT_LENGTH));
+
+ /* Read the record until we at least have a header */
+ GUARD_AS_POSIX(s2n_read_in_bytes(conn, &conn->header_in, S2N_TLS_RECORD_HEADER_LENGTH));
+
+ uint16_t fragment_length;
+
+ /* If the first bit is set then this is an SSLv2 record */
+ if (conn->header_in.blob.data[0] & 0x80) {
+ conn->header_in.blob.data[0] &= 0x7f;
+ *isSSLv2 = 1;
+
+ if (s2n_sslv2_record_header_parse(conn, record_type, &conn->client_protocol_version, &fragment_length) < 0) {
+ GUARD(s2n_connection_kill(conn));
+ S2N_ERROR_PRESERVE_ERRNO();
+ }
+ } else {
+ if (s2n_record_header_parse(conn, record_type, &fragment_length) < 0) {
+ GUARD(s2n_connection_kill(conn));
+ S2N_ERROR_PRESERVE_ERRNO();
+ }
+ }
+
+ /* Read enough to have the whole record */
+ GUARD_AS_POSIX(s2n_read_in_bytes(conn, &conn->in, fragment_length));
+
+ if (*isSSLv2) {
+ return 0;
+ }
+
+ /* Decrypt and parse the record */
+ if (s2n_record_parse(conn) < 0) {
+ GUARD(s2n_connection_kill(conn));
+ S2N_ERROR_PRESERVE_ERRNO();
+ }
+
+ /* In TLS 1.3, encrypted handshake records would appear to be of record type
+ * TLS_APPLICATION_DATA. The actual record content type is found after the encrypted
+ * is decrypted.
+ */
+ if (conn->actual_protocol_version == S2N_TLS13 && *record_type == TLS_APPLICATION_DATA) {
+ GUARD(s2n_tls13_parse_record_type(&conn->in, record_type));
+ }
+
+ return 0;
+}
+
+ssize_t s2n_recv(struct s2n_connection * conn, void *buf, ssize_t size, s2n_blocked_status * blocked)
+{
+ ssize_t bytes_read = 0;
+ struct s2n_blob out = {.data = (uint8_t *) buf };
+
+ if (conn->closed) {
+ return 0;
+ }
+ *blocked = S2N_BLOCKED_ON_READ;
+
+ S2N_ERROR_IF(conn->config->quic_enabled, S2N_ERR_UNSUPPORTED_WITH_QUIC);
+
+ while (size && !conn->closed) {
+ int isSSLv2 = 0;
+ uint8_t record_type;
+ int r = s2n_read_full_record(conn, &record_type, &isSSLv2);
+ if (r < 0) {
+ if (s2n_errno == S2N_ERR_CLOSED) {
+ *blocked = S2N_NOT_BLOCKED;
+ if (!bytes_read) {
+ return 0;
+ } else {
+ return bytes_read;
+ }
+ }
+
+ /* Don't propagate the error if we already read some bytes */
+ if (s2n_errno == S2N_ERR_IO_BLOCKED && bytes_read) {
+ s2n_errno = S2N_ERR_OK;
+ return bytes_read;
+ }
+
+ /* If we get here, it's an error condition */
+ if (s2n_errno != S2N_ERR_IO_BLOCKED && s2n_allowed_to_cache_connection(conn) && conn->session_id_len) {
+ conn->config->cache_delete(conn, conn->config->cache_delete_data, conn->session_id, conn->session_id_len);
+ }
+
+ S2N_ERROR_PRESERVE_ERRNO();
+ }
+
+ S2N_ERROR_IF(isSSLv2, S2N_ERR_BAD_MESSAGE);
+
+ if (record_type != TLS_APPLICATION_DATA) {
+ switch (record_type)
+ {
+ case TLS_ALERT:
+ GUARD(s2n_process_alert_fragment(conn));
+ GUARD(s2n_flush(conn, blocked));
+ break;
+ case TLS_HANDSHAKE:
+ GUARD(s2n_post_handshake_recv(conn));
+ break;
+ }
+ GUARD(s2n_stuffer_wipe(&conn->header_in));
+ GUARD(s2n_stuffer_wipe(&conn->in));
+ conn->in_status = ENCRYPTED;
+ continue;
+ }
+
+ out.size = MIN(size, s2n_stuffer_data_available(&conn->in));
+
+ GUARD(s2n_stuffer_erase_and_read(&conn->in, &out));
+ bytes_read += out.size;
+
+ out.data += out.size;
+ size -= out.size;
+
+ /* Are we ready for more encrypted data? */
+ if (s2n_stuffer_data_available(&conn->in) == 0) {
+ GUARD(s2n_stuffer_wipe(&conn->header_in));
+ GUARD(s2n_stuffer_wipe(&conn->in));
+ conn->in_status = ENCRYPTED;
+ }
+
+ /* If we've read some data, return it */
+ if (bytes_read) {
+ break;
+ }
+ }
+
+ if (s2n_stuffer_data_available(&conn->in) == 0) {
+ *blocked = S2N_NOT_BLOCKED;
+ }
+
+ return bytes_read;
+}
+
+uint32_t s2n_peek(struct s2n_connection *conn) {
+ return s2n_stuffer_data_available(&conn->in);
+}
+
+int s2n_recv_close_notify(struct s2n_connection *conn, s2n_blocked_status * blocked)
+{
+ uint8_t record_type;
+ int isSSLv2;
+ *blocked = S2N_BLOCKED_ON_READ;
+
+ GUARD(s2n_read_full_record(conn, &record_type, &isSSLv2));
+
+ S2N_ERROR_IF(isSSLv2, S2N_ERR_BAD_MESSAGE);
+
+ S2N_ERROR_IF(record_type != TLS_ALERT, S2N_ERR_SHUTDOWN_RECORD_TYPE);
+
+ /* Only succeeds for an incoming close_notify alert */
+ GUARD(s2n_process_alert_fragment(conn));
+
+ *blocked = S2N_NOT_BLOCKED;
+ return 0;
+}
+
diff --git a/contrib/restricted/aws/s2n/tls/s2n_resume.c b/contrib/restricted/aws/s2n/tls/s2n_resume.c
index 20dc850a9f..f4571bf042 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_resume.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_resume.c
@@ -1,712 +1,712 @@
-/*
- * 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 <math.h>
-
-#include <s2n.h>
-
-#include "error/s2n_errno.h"
-#include "stuffer/s2n_stuffer.h"
-#include "utils/s2n_safety.h"
-#include "utils/s2n_blob.h"
-#include "utils/s2n_random.h"
-#include "utils/s2n_set.h"
-
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_resume.h"
-#include "tls/s2n_crypto.h"
-#include "tls/s2n_tls.h"
-
-int s2n_allowed_to_cache_connection(struct s2n_connection *conn)
-{
- /* We're unable to cache connections with a Client Cert since we currently don't serialize the Client Cert,
- * which means that callers won't have access to the Client's Cert if the connection is resumed. */
- if (s2n_connection_is_client_auth_enabled(conn) > 0) {
- return 0;
- }
-
- struct s2n_config *config = conn->config;
-
- notnull_check(config);
- return config->use_session_cache;
-}
-
-static int s2n_serialize_resumption_state(struct s2n_connection *conn, struct s2n_stuffer *to)
-{
- uint64_t now;
-
- S2N_ERROR_IF(s2n_stuffer_space_remaining(to) < S2N_STATE_SIZE_IN_BYTES, S2N_ERR_STUFFER_IS_FULL);
-
- /* Get the time */
- GUARD(conn->config->wall_clock(conn->config->sys_clock_ctx, &now));
-
- /* Write the entry */
- GUARD(s2n_stuffer_write_uint8(to, S2N_SERIALIZED_FORMAT_VERSION));
- GUARD(s2n_stuffer_write_uint8(to, conn->actual_protocol_version));
- GUARD(s2n_stuffer_write_bytes(to, conn->secure.cipher_suite->iana_value, S2N_TLS_CIPHER_SUITE_LEN));
- GUARD(s2n_stuffer_write_uint64(to, now));
- GUARD(s2n_stuffer_write_bytes(to, conn->secure.master_secret, S2N_TLS_SECRET_LEN));
-
- return 0;
-}
-
-static int s2n_deserialize_resumption_state(struct s2n_connection *conn, struct s2n_stuffer *from)
-{
- uint8_t format;
- uint8_t protocol_version;
- uint8_t cipher_suite[S2N_TLS_CIPHER_SUITE_LEN];
-
- S2N_ERROR_IF(s2n_stuffer_data_available(from) < S2N_STATE_SIZE_IN_BYTES, S2N_ERR_STUFFER_OUT_OF_DATA);
-
- GUARD(s2n_stuffer_read_uint8(from, &format));
- S2N_ERROR_IF(format != S2N_SERIALIZED_FORMAT_VERSION, S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
-
- GUARD(s2n_stuffer_read_uint8(from, &protocol_version));
- S2N_ERROR_IF(protocol_version != conn->actual_protocol_version, S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
-
- GUARD(s2n_stuffer_read_bytes(from, cipher_suite, S2N_TLS_CIPHER_SUITE_LEN));
- S2N_ERROR_IF(memcmp(conn->secure.cipher_suite->iana_value, cipher_suite, S2N_TLS_CIPHER_SUITE_LEN), S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
-
- uint64_t now;
- GUARD(conn->config->wall_clock(conn->config->sys_clock_ctx, &now));
-
- uint64_t then;
- GUARD(s2n_stuffer_read_uint64(from, &then));
- S2N_ERROR_IF(then > now, S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
- S2N_ERROR_IF(now - then > conn->config->session_state_lifetime_in_nanos, S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
-
- /* Last but not least, put the master secret in place */
- GUARD(s2n_stuffer_read_bytes(from, conn->secure.master_secret, S2N_TLS_SECRET_LEN));
-
- return 0;
-}
-
-static int s2n_client_serialize_resumption_state(struct s2n_connection *conn, struct s2n_stuffer *to)
-{
- /* Serialize session ticket */
- if (conn->config->use_tickets && conn->client_ticket.size > 0) {
- GUARD(s2n_stuffer_write_uint8(to, S2N_STATE_WITH_SESSION_TICKET));
- GUARD(s2n_stuffer_write_uint16(to, conn->client_ticket.size));
- GUARD(s2n_stuffer_write(to, &conn->client_ticket));
- } else {
- /* Serialize session id */
- GUARD(s2n_stuffer_write_uint8(to, S2N_STATE_WITH_SESSION_ID));
- GUARD(s2n_stuffer_write_uint8(to, conn->session_id_len));
- GUARD(s2n_stuffer_write_bytes(to, conn->session_id, conn->session_id_len));
- }
-
- /* Serialize session state */
- GUARD(s2n_serialize_resumption_state(conn, to));
-
- return 0;
-}
-
-static int s2n_client_deserialize_session_state(struct s2n_connection *conn, struct s2n_stuffer *from)
-{
- if (s2n_stuffer_data_available(from) < S2N_STATE_SIZE_IN_BYTES) {
- S2N_ERROR(S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
- }
-
- uint8_t format;
- uint64_t then;
-
- GUARD(s2n_stuffer_read_uint8(from, &format));
- if (format != S2N_SERIALIZED_FORMAT_VERSION) {
- S2N_ERROR(S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
- }
-
- GUARD(s2n_stuffer_read_uint8(from, &conn->actual_protocol_version));
-
- uint8_t *cipher_suite_wire = s2n_stuffer_raw_read(from, S2N_TLS_CIPHER_SUITE_LEN);
- notnull_check(cipher_suite_wire);
- GUARD(s2n_set_cipher_as_client(conn, cipher_suite_wire));
-
- GUARD(s2n_stuffer_read_uint64(from, &then));
-
- /* Last but not least, put the master secret in place */
- GUARD(s2n_stuffer_read_bytes(from, conn->secure.master_secret, S2N_TLS_SECRET_LEN));
-
- return 0;
-}
-
-static int s2n_client_deserialize_with_session_id(struct s2n_connection *conn, struct s2n_stuffer *from)
-{
- uint8_t session_id_len;
- GUARD(s2n_stuffer_read_uint8(from, &session_id_len));
-
- if (session_id_len == 0 || session_id_len > S2N_TLS_SESSION_ID_MAX_LEN
- || session_id_len > s2n_stuffer_data_available(from)) {
- S2N_ERROR(S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
- }
-
- conn->session_id_len = session_id_len;
- GUARD(s2n_stuffer_read_bytes(from, conn->session_id, session_id_len));
-
- GUARD(s2n_client_deserialize_session_state(conn, from));
-
- return 0;
-}
-
-static int s2n_client_deserialize_with_session_ticket(struct s2n_connection *conn, struct s2n_stuffer *from)
-{
- uint16_t session_ticket_len;
- GUARD(s2n_stuffer_read_uint16(from, &session_ticket_len));
-
- if (session_ticket_len == 0 || session_ticket_len > s2n_stuffer_data_available(from)) {
- S2N_ERROR(S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
- }
-
- GUARD(s2n_realloc(&conn->client_ticket, session_ticket_len));
- GUARD(s2n_stuffer_read(from, &conn->client_ticket));
-
- GUARD(s2n_client_deserialize_session_state(conn, from));
-
- return 0;
-}
-
-static int s2n_client_deserialize_resumption_state(struct s2n_connection *conn, struct s2n_stuffer *from)
-{
- uint8_t format;
- GUARD(s2n_stuffer_read_uint8(from, &format));
-
- switch (format) {
- case S2N_STATE_WITH_SESSION_ID:
- GUARD(s2n_client_deserialize_with_session_id(conn, from));
- break;
- case S2N_STATE_WITH_SESSION_TICKET:
- GUARD(s2n_client_deserialize_with_session_ticket(conn, from));
- break;
- default:
- S2N_ERROR(S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
- }
-
- return 0;
-}
-
-int s2n_resume_from_cache(struct s2n_connection *conn)
-{
- S2N_ERROR_IF(conn->session_id_len == 0, S2N_ERR_SESSION_ID_TOO_SHORT);
- S2N_ERROR_IF(conn->session_id_len > S2N_TLS_SESSION_ID_MAX_LEN, S2N_ERR_SESSION_ID_TOO_LONG);
-
- uint8_t data[S2N_TICKET_SIZE_IN_BYTES] = { 0 };
- struct s2n_blob entry = {0};
- GUARD(s2n_blob_init(&entry, data, S2N_TICKET_SIZE_IN_BYTES));
- uint64_t size = entry.size;
- int result = conn->config->cache_retrieve(conn, conn->config->cache_retrieve_data, conn->session_id, conn->session_id_len, entry.data, &size);
- if (result == S2N_CALLBACK_BLOCKED) {
- S2N_ERROR(S2N_ERR_ASYNC_BLOCKED);
- }
- GUARD(result);
-
- S2N_ERROR_IF(size != entry.size, S2N_ERR_SIZE_MISMATCH);
-
- struct s2n_stuffer from = {0};
- GUARD(s2n_stuffer_init(&from, &entry));
- GUARD(s2n_stuffer_write(&from, &entry));
- GUARD(s2n_decrypt_session_cache(conn, &from));
-
- return 0;
-}
-
-int s2n_store_to_cache(struct s2n_connection *conn)
-{
- uint8_t data[S2N_TICKET_SIZE_IN_BYTES] = { 0 };
- struct s2n_blob entry = {0};
- GUARD(s2n_blob_init(&entry, data, S2N_TICKET_SIZE_IN_BYTES));
- struct s2n_stuffer to = {0};
-
- /* session_id_len should always be >0 since either the Client provided a SessionId or the Server generated a new
- * one for the Client */
- S2N_ERROR_IF(conn->session_id_len == 0, S2N_ERR_SESSION_ID_TOO_SHORT);
- S2N_ERROR_IF(conn->session_id_len > S2N_TLS_SESSION_ID_MAX_LEN, S2N_ERR_SESSION_ID_TOO_LONG);
-
- GUARD(s2n_stuffer_init(&to, &entry));
- GUARD(s2n_encrypt_session_cache(conn, &to));
-
- /* Store to the cache */
- conn->config->cache_store(conn, conn->config->cache_store_data, S2N_TLS_SESSION_CACHE_TTL, conn->session_id, conn->session_id_len, entry.data, entry.size);
-
- return 0;
-}
-
-int s2n_connection_set_session(struct s2n_connection *conn, const uint8_t *session, size_t length)
-{
- notnull_check(conn);
- notnull_check(session);
-
- DEFER_CLEANUP(struct s2n_blob session_data = {0}, s2n_free);
- GUARD(s2n_alloc(&session_data, length));
- memcpy(session_data.data, session, length);
-
- struct s2n_stuffer from = {0};
- GUARD(s2n_stuffer_init(&from, &session_data));
- GUARD(s2n_stuffer_write(&from, &session_data));
- GUARD(s2n_client_deserialize_resumption_state(conn, &from));
- return 0;
-}
-
-int s2n_connection_get_session(struct s2n_connection *conn, uint8_t *session, size_t max_length)
-{
- notnull_check(conn);
- notnull_check(session);
-
- int len = s2n_connection_get_session_length(conn);
-
- if (len == 0) {
- return 0;
- }
-
- S2N_ERROR_IF(len > max_length, S2N_ERR_SERIALIZED_SESSION_STATE_TOO_LONG);
-
- struct s2n_blob serialized_data = {0};
- GUARD(s2n_blob_init(&serialized_data, session, len));
- GUARD(s2n_blob_zero(&serialized_data));
-
- struct s2n_stuffer to = {0};
- GUARD(s2n_stuffer_init(&to, &serialized_data));
- GUARD(s2n_client_serialize_resumption_state(conn, &to));
-
- return len;
-}
-
-int s2n_connection_get_session_ticket_lifetime_hint(struct s2n_connection *conn)
-{
- notnull_check(conn);
- S2N_ERROR_IF(!(conn->config->use_tickets && conn->client_ticket.size > 0), S2N_ERR_SESSION_TICKET_NOT_SUPPORTED);
-
- /* Session resumption using session ticket */
- return conn->ticket_lifetime_hint;
-}
-
-int s2n_connection_get_session_length(struct s2n_connection *conn)
-{
- /* Session resumption using session ticket "format (1) + session_ticket_len + session_ticket + session state" */
- if (conn->config->use_tickets && conn->client_ticket.size > 0) {
- return S2N_STATE_FORMAT_LEN + S2N_SESSION_TICKET_SIZE_LEN + conn->client_ticket.size + S2N_STATE_SIZE_IN_BYTES;
- } else if (conn->session_id_len > 0) {
- /* Session resumption using session id: "format (0) + session_id_len + session_id + session state" */
- return S2N_STATE_FORMAT_LEN + 1 + conn->session_id_len + S2N_STATE_SIZE_IN_BYTES;
- } else {
- return 0;
- }
-}
-
-int s2n_connection_is_session_resumed(struct s2n_connection *conn)
-{
- notnull_check(conn);
- return IS_RESUMPTION_HANDSHAKE(conn->handshake.handshake_type) ? 1 : 0;
-}
-
-int s2n_connection_is_ocsp_stapled(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- if (conn->actual_protocol_version >= S2N_TLS13) {
- return (s2n_server_can_send_ocsp(conn) || s2n_server_sent_ocsp(conn));
- } else {
- return IS_OCSP_STAPLED(conn->handshake.handshake_type);
- }
-}
-
-int s2n_config_is_encrypt_decrypt_key_available(struct s2n_config *config)
-{
- uint64_t now;
- struct s2n_ticket_key *ticket_key = NULL;
- GUARD(config->wall_clock(config->sys_clock_ctx, &now));
- notnull_check(config->ticket_keys);
-
- uint32_t ticket_keys_len = 0;
- GUARD_AS_POSIX(s2n_set_len(config->ticket_keys, &ticket_keys_len));
-
- for (uint32_t i = ticket_keys_len; i > 0; i--) {
- uint32_t idx = i - 1;
- GUARD_AS_POSIX(s2n_set_get(config->ticket_keys, idx, (void **)&ticket_key));
- uint64_t key_intro_time = ticket_key->intro_timestamp;
-
- if (key_intro_time < now
- && now < key_intro_time + config->encrypt_decrypt_key_lifetime_in_nanos) {
- return 1;
- }
- }
-
- return 0;
-}
-
-/* This function is used in s2n_get_ticket_encrypt_decrypt_key to compute the weight
- * of the keys and to choose a single key from all of the encrypt-decrypt keys.
- * Higher the weight of the key, higher the probability of being picked.
- */
-int s2n_compute_weight_of_encrypt_decrypt_keys(struct s2n_config *config,
- uint8_t *encrypt_decrypt_keys_index,
- uint8_t num_encrypt_decrypt_keys,
- uint64_t now)
-{
- double total_weight = 0;
- struct s2n_ticket_key_weight ticket_keys_weight[S2N_MAX_TICKET_KEYS];
- struct s2n_ticket_key *ticket_key = NULL;
-
- /* Compute weight of encrypt-decrypt keys */
- for (int i = 0; i < num_encrypt_decrypt_keys; i++) {
- GUARD_AS_POSIX(s2n_set_get(config->ticket_keys, encrypt_decrypt_keys_index[i], (void **)&ticket_key));
-
- uint64_t key_intro_time = ticket_key->intro_timestamp;
- uint64_t key_encryption_peak_time = key_intro_time + (config->encrypt_decrypt_key_lifetime_in_nanos / 2);
-
- /* The % of encryption using this key is linearly increasing */
- if (now < key_encryption_peak_time) {
- ticket_keys_weight[i].key_weight = now - key_intro_time;
- } else {
- /* The % of encryption using this key is linearly decreasing */
- ticket_keys_weight[i].key_weight = (config->encrypt_decrypt_key_lifetime_in_nanos / 2) - (now - key_encryption_peak_time);
- }
-
- ticket_keys_weight[i].key_index = encrypt_decrypt_keys_index[i];
- total_weight += ticket_keys_weight[i].key_weight;
- }
-
- /* Pick a random number in [0, 1). Using 53 bits (IEEE 754 double-precision floats). */
- uint64_t random_int = 0;
- GUARD_AS_POSIX(s2n_public_random(pow(2, 53), &random_int));
- double random = (double)random_int / (double)pow(2, 53);
-
- /* Compute cumulative weight of encrypt-decrypt keys */
- for (int i = 0; i < num_encrypt_decrypt_keys; i++) {
- ticket_keys_weight[i].key_weight = ticket_keys_weight[i].key_weight / total_weight;
-
- if (i > 0) {
- ticket_keys_weight[i].key_weight += ticket_keys_weight[i - 1].key_weight;
- }
-
- if (ticket_keys_weight[i].key_weight > random) {
- return ticket_keys_weight[i].key_index;
- }
- }
-
- S2N_ERROR(S2N_ERR_ENCRYPT_DECRYPT_KEY_SELECTION_FAILED);
-}
-
-/* This function is used in s2n_encrypt_session_ticket in order for s2n to
- * choose a key in encrypt-decrypt state from all of the keys added to config
- */
-struct s2n_ticket_key *s2n_get_ticket_encrypt_decrypt_key(struct s2n_config *config)
-{
- uint8_t num_encrypt_decrypt_keys = 0;
- uint8_t encrypt_decrypt_keys_index[S2N_MAX_TICKET_KEYS] = { 0 };
- struct s2n_ticket_key *ticket_key = NULL;
-
- uint64_t now;
- GUARD_PTR(config->wall_clock(config->sys_clock_ctx, &now));
- notnull_check_ptr(config->ticket_keys);
-
- uint32_t ticket_keys_len = 0;
- GUARD_RESULT_PTR(s2n_set_len(config->ticket_keys, &ticket_keys_len));
-
- for (uint32_t i = ticket_keys_len; i > 0; i--) {
- uint32_t idx = i - 1;
- GUARD_RESULT_PTR(s2n_set_get(config->ticket_keys, idx, (void **)&ticket_key));
- uint64_t key_intro_time = ticket_key->intro_timestamp;
-
- if (key_intro_time < now
- && now < key_intro_time + config->encrypt_decrypt_key_lifetime_in_nanos) {
- encrypt_decrypt_keys_index[num_encrypt_decrypt_keys] = idx;
- num_encrypt_decrypt_keys++;
- }
- }
-
- if (num_encrypt_decrypt_keys == 0) {
- S2N_ERROR_PTR(S2N_ERR_NO_TICKET_ENCRYPT_DECRYPT_KEY);
- }
-
- if (num_encrypt_decrypt_keys == 1) {
- GUARD_RESULT_PTR(s2n_set_get(config->ticket_keys, encrypt_decrypt_keys_index[0], (void **)&ticket_key));
- return ticket_key;
- }
-
- int8_t idx;
- GUARD_PTR(idx = s2n_compute_weight_of_encrypt_decrypt_keys(config, encrypt_decrypt_keys_index, num_encrypt_decrypt_keys, now));
-
- GUARD_RESULT_PTR(s2n_set_get(config->ticket_keys, idx, (void **)&ticket_key));
- return ticket_key;
-}
-
-/* This function is used in s2n_decrypt_session_ticket in order for s2n to
- * find the matching key that was used for encryption.
- */
-struct s2n_ticket_key *s2n_find_ticket_key(struct s2n_config *config, const uint8_t *name)
-{
- uint64_t now;
- struct s2n_ticket_key *ticket_key = NULL;
- GUARD_PTR(config->wall_clock(config->sys_clock_ctx, &now));
- notnull_check_ptr(config->ticket_keys);
-
- uint32_t ticket_keys_len = 0;
- GUARD_RESULT_PTR(s2n_set_len(config->ticket_keys, &ticket_keys_len));
-
- for (uint32_t i = 0; i < ticket_keys_len; i++) {
- GUARD_RESULT_PTR(s2n_set_get(config->ticket_keys, i, (void **)&ticket_key));
-
- if (memcmp(ticket_key->key_name, name, S2N_TICKET_KEY_NAME_LEN) == 0) {
-
- /* Check to see if the key has expired */
- if (now >= ticket_key->intro_timestamp +
- config->encrypt_decrypt_key_lifetime_in_nanos + config->decrypt_key_lifetime_in_nanos) {
- s2n_config_wipe_expired_ticket_crypto_keys(config, i);
-
- return NULL;
- }
-
- return ticket_key;
- }
- }
-
- return NULL;
-}
-
-int s2n_encrypt_session_ticket(struct s2n_connection *conn, struct s2n_stuffer *to)
-{
- struct s2n_ticket_key *key;
- struct s2n_session_key aes_ticket_key = {0};
- struct s2n_blob aes_key_blob = {0};
-
- uint8_t iv_data[S2N_TLS_GCM_IV_LEN] = { 0 };
- struct s2n_blob iv = {0};
- GUARD(s2n_blob_init(&iv, iv_data, sizeof(iv_data)));
-
- uint8_t aad_data[S2N_TICKET_AAD_LEN] = { 0 };
- struct s2n_blob aad_blob = {0};
- GUARD(s2n_blob_init(&aad_blob, aad_data, sizeof(aad_data)));
- struct s2n_stuffer aad = {0};
-
- uint8_t s_data[S2N_STATE_SIZE_IN_BYTES + S2N_TLS_GCM_TAG_LEN] = { 0 };
- struct s2n_blob state_blob = {0};
- GUARD(s2n_blob_init(&state_blob, s_data, sizeof(s_data)));
- struct s2n_stuffer state = {0};
-
- key = s2n_get_ticket_encrypt_decrypt_key(conn->config);
-
- /* No keys loaded by the user or the keys are either in decrypt-only or expired state */
- S2N_ERROR_IF(!key, S2N_ERR_NO_TICKET_ENCRYPT_DECRYPT_KEY);
-
- GUARD(s2n_stuffer_write_bytes(to, key->key_name, S2N_TICKET_KEY_NAME_LEN));
-
- GUARD_AS_POSIX(s2n_get_public_random_data(&iv));
- GUARD(s2n_stuffer_write(to, &iv));
-
- GUARD(s2n_blob_init(&aes_key_blob, key->aes_key, S2N_AES256_KEY_LEN));
- GUARD(s2n_session_key_alloc(&aes_ticket_key));
- GUARD(s2n_aes256_gcm.init(&aes_ticket_key));
- GUARD(s2n_aes256_gcm.set_encryption_key(&aes_ticket_key, &aes_key_blob));
-
- GUARD(s2n_stuffer_init(&aad, &aad_blob));
- GUARD(s2n_stuffer_write_bytes(&aad, key->implicit_aad, S2N_TICKET_AAD_IMPLICIT_LEN));
- GUARD(s2n_stuffer_write_bytes(&aad, key->key_name, S2N_TICKET_KEY_NAME_LEN));
-
- GUARD(s2n_stuffer_init(&state, &state_blob));
- GUARD(s2n_serialize_resumption_state(conn, &state));
-
- GUARD(s2n_aes256_gcm.io.aead.encrypt(&aes_ticket_key, &iv, &aad_blob, &state_blob, &state_blob));
-
- GUARD(s2n_stuffer_write(to, &state_blob));
-
- GUARD(s2n_aes256_gcm.destroy_key(&aes_ticket_key));
- GUARD(s2n_session_key_free(&aes_ticket_key));
-
- return 0;
-}
-
-int s2n_decrypt_session_ticket(struct s2n_connection *conn)
-{
- struct s2n_ticket_key *key;
- DEFER_CLEANUP(struct s2n_session_key aes_ticket_key = {0}, s2n_session_key_free);
- struct s2n_blob aes_key_blob = {0};
- struct s2n_stuffer *from;
-
- uint8_t key_name[S2N_TICKET_KEY_NAME_LEN];
-
- uint8_t iv_data[S2N_TLS_GCM_IV_LEN] = { 0 };
- struct s2n_blob iv = { 0 };
- GUARD(s2n_blob_init(&iv, iv_data, sizeof(iv_data)));
-
- uint8_t aad_data[S2N_TICKET_AAD_LEN] = { 0 };
- struct s2n_blob aad_blob = {0};
- GUARD(s2n_blob_init(&aad_blob, aad_data, sizeof(aad_data)));
- struct s2n_stuffer aad = {0};
-
- uint8_t s_data[S2N_STATE_SIZE_IN_BYTES] = { 0 };
- struct s2n_blob state_blob = {0};
- GUARD(s2n_blob_init(&state_blob, s_data, sizeof(s_data)));
- struct s2n_stuffer state = {0};
-
- uint8_t en_data[S2N_STATE_SIZE_IN_BYTES + S2N_TLS_GCM_TAG_LEN] = {0};
- struct s2n_blob en_blob = {0};
- GUARD(s2n_blob_init(&en_blob, en_data, sizeof(en_data)));
-
- from = &conn->client_ticket_to_decrypt;
- GUARD(s2n_stuffer_read_bytes(from, key_name, S2N_TICKET_KEY_NAME_LEN));
-
- key = s2n_find_ticket_key(conn->config, key_name);
-
- /* Key has expired; do full handshake with New Session Ticket (NST) */
- S2N_ERROR_IF(!key, S2N_ERR_KEY_USED_IN_SESSION_TICKET_NOT_FOUND);
-
- GUARD(s2n_stuffer_read(from, &iv));
-
- s2n_blob_init(&aes_key_blob, key->aes_key, S2N_AES256_KEY_LEN);
- GUARD(s2n_session_key_alloc(&aes_ticket_key));
- GUARD(s2n_aes256_gcm.init(&aes_ticket_key));
- GUARD(s2n_aes256_gcm.set_decryption_key(&aes_ticket_key, &aes_key_blob));
-
- GUARD(s2n_stuffer_init(&aad, &aad_blob));
- GUARD(s2n_stuffer_write_bytes(&aad, key->implicit_aad, S2N_TICKET_AAD_IMPLICIT_LEN));
- GUARD(s2n_stuffer_write_bytes(&aad, key->key_name, S2N_TICKET_KEY_NAME_LEN));
-
- GUARD(s2n_stuffer_read(from, &en_blob));
-
- GUARD(s2n_aes256_gcm.io.aead.decrypt(&aes_ticket_key, &iv, &aad_blob, &en_blob, &en_blob));
-
- GUARD(s2n_stuffer_init(&state, &state_blob));
- GUARD(s2n_stuffer_write_bytes(&state, en_data, S2N_STATE_SIZE_IN_BYTES));
-
- GUARD(s2n_deserialize_resumption_state(conn, &state));
-
- uint64_t now;
- GUARD(conn->config->wall_clock(conn->config->sys_clock_ctx, &now));
-
- /* If the key is in decrypt-only state, then a new key is assigned
- * for the ticket.
- */
- if (now >= key->intro_timestamp + conn->config->encrypt_decrypt_key_lifetime_in_nanos) {
- /* Check if a key in encrypt-decrypt state is available */
- if (s2n_config_is_encrypt_decrypt_key_available(conn->config) == 1) {
- conn->session_ticket_status = S2N_NEW_TICKET;
- conn->handshake.handshake_type |= WITH_SESSION_TICKET;
-
- return 0;
- }
- }
-
- return 0;
-}
-
-int s2n_encrypt_session_cache(struct s2n_connection *conn, struct s2n_stuffer *to)
-{
- return s2n_encrypt_session_ticket(conn, to);
-}
-
-
-int s2n_decrypt_session_cache(struct s2n_connection *conn, struct s2n_stuffer *from)
-{
- struct s2n_ticket_key *key;
- struct s2n_session_key aes_ticket_key = {0};
- struct s2n_blob aes_key_blob = {0};
-
- uint8_t key_name[S2N_TICKET_KEY_NAME_LEN] = {0};
-
- uint8_t iv_data[S2N_TLS_GCM_IV_LEN] = { 0 };
- struct s2n_blob iv = {0};
- GUARD(s2n_blob_init(&iv, iv_data, sizeof(iv_data)));
-
- uint8_t aad_data[S2N_TICKET_AAD_LEN] = { 0 };
- struct s2n_blob aad_blob = {0};
- GUARD(s2n_blob_init(&aad_blob, aad_data, sizeof(aad_data)));
- struct s2n_stuffer aad = {0};
-
- uint8_t s_data[S2N_STATE_SIZE_IN_BYTES] = { 0 };
- struct s2n_blob state_blob = {0};
- GUARD(s2n_blob_init(&state_blob, s_data, sizeof(s_data)));
- struct s2n_stuffer state = {0};
-
- uint8_t en_data[S2N_STATE_SIZE_IN_BYTES + S2N_TLS_GCM_TAG_LEN] = {0};
- struct s2n_blob en_blob = {0};
- GUARD(s2n_blob_init(&en_blob, en_data, sizeof(en_data)));
-
- GUARD(s2n_stuffer_read_bytes(from, key_name, S2N_TICKET_KEY_NAME_LEN));
-
- key = s2n_find_ticket_key(conn->config, key_name);
-
- /* Key has expired; do full handshake with New Session Ticket (NST) */
- S2N_ERROR_IF(!key, S2N_ERR_KEY_USED_IN_SESSION_TICKET_NOT_FOUND);
-
- GUARD(s2n_stuffer_read(from, &iv));
-
- s2n_blob_init(&aes_key_blob, key->aes_key, S2N_AES256_KEY_LEN);
- GUARD(s2n_session_key_alloc(&aes_ticket_key));
- GUARD(s2n_aes256_gcm.init(&aes_ticket_key));
- GUARD(s2n_aes256_gcm.set_decryption_key(&aes_ticket_key, &aes_key_blob));
-
- GUARD(s2n_stuffer_init(&aad, &aad_blob));
- GUARD(s2n_stuffer_write_bytes(&aad, key->implicit_aad, S2N_TICKET_AAD_IMPLICIT_LEN));
- GUARD(s2n_stuffer_write_bytes(&aad, key->key_name, S2N_TICKET_KEY_NAME_LEN));
-
- GUARD(s2n_stuffer_read(from, &en_blob));
-
- GUARD(s2n_aes256_gcm.io.aead.decrypt(&aes_ticket_key, &iv, &aad_blob, &en_blob, &en_blob));
-
- GUARD(s2n_stuffer_init(&state, &state_blob));
- GUARD(s2n_stuffer_write_bytes(&state, en_data, S2N_STATE_SIZE_IN_BYTES));
-
- GUARD(s2n_deserialize_resumption_state(conn, &state));
-
- GUARD(s2n_aes256_gcm.destroy_key(&aes_ticket_key));
- GUARD(s2n_session_key_free(&aes_ticket_key));
-
- return 0;
-}
-
-/* This function is used to remove all or just one expired key from server config */
-int s2n_config_wipe_expired_ticket_crypto_keys(struct s2n_config *config, int8_t expired_key_index)
-{
- int num_of_expired_keys = 0;
- int expired_keys_index[S2N_MAX_TICKET_KEYS];
- struct s2n_ticket_key *ticket_key = NULL;
-
- if (expired_key_index != -1) {
- expired_keys_index[num_of_expired_keys] = expired_key_index;
- num_of_expired_keys++;
-
- goto end;
- }
-
- uint64_t now;
- GUARD(config->wall_clock(config->sys_clock_ctx, &now));
- notnull_check(config->ticket_keys);
-
- uint32_t ticket_keys_len = 0;
- GUARD_AS_POSIX(s2n_set_len(config->ticket_keys, &ticket_keys_len));
-
- for (uint32_t i = 0; i < ticket_keys_len; i++) {
- GUARD_AS_POSIX(s2n_set_get(config->ticket_keys, i, (void **)&ticket_key));
- if (now >= ticket_key->intro_timestamp +
- config->encrypt_decrypt_key_lifetime_in_nanos + config->decrypt_key_lifetime_in_nanos) {
- expired_keys_index[num_of_expired_keys] = i;
- num_of_expired_keys++;
- }
- }
-
-end:
- for (int j = 0; j < num_of_expired_keys; j++) {
- GUARD_AS_POSIX(s2n_set_remove(config->ticket_keys, expired_keys_index[j] - j));
- }
-
- return 0;
-}
-
-
-int s2n_config_store_ticket_key(struct s2n_config *config, struct s2n_ticket_key *key)
-{
- /* Keys are stored from oldest to newest */
- GUARD_AS_POSIX(s2n_set_add(config->ticket_keys, key));
- return S2N_SUCCESS;
-}
+/*
+ * 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 <math.h>
+
+#include <s2n.h>
+
+#include "error/s2n_errno.h"
+#include "stuffer/s2n_stuffer.h"
+#include "utils/s2n_safety.h"
+#include "utils/s2n_blob.h"
+#include "utils/s2n_random.h"
+#include "utils/s2n_set.h"
+
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_resume.h"
+#include "tls/s2n_crypto.h"
+#include "tls/s2n_tls.h"
+
+int s2n_allowed_to_cache_connection(struct s2n_connection *conn)
+{
+ /* We're unable to cache connections with a Client Cert since we currently don't serialize the Client Cert,
+ * which means that callers won't have access to the Client's Cert if the connection is resumed. */
+ if (s2n_connection_is_client_auth_enabled(conn) > 0) {
+ return 0;
+ }
+
+ struct s2n_config *config = conn->config;
+
+ notnull_check(config);
+ return config->use_session_cache;
+}
+
+static int s2n_serialize_resumption_state(struct s2n_connection *conn, struct s2n_stuffer *to)
+{
+ uint64_t now;
+
+ S2N_ERROR_IF(s2n_stuffer_space_remaining(to) < S2N_STATE_SIZE_IN_BYTES, S2N_ERR_STUFFER_IS_FULL);
+
+ /* Get the time */
+ GUARD(conn->config->wall_clock(conn->config->sys_clock_ctx, &now));
+
+ /* Write the entry */
+ GUARD(s2n_stuffer_write_uint8(to, S2N_SERIALIZED_FORMAT_VERSION));
+ GUARD(s2n_stuffer_write_uint8(to, conn->actual_protocol_version));
+ GUARD(s2n_stuffer_write_bytes(to, conn->secure.cipher_suite->iana_value, S2N_TLS_CIPHER_SUITE_LEN));
+ GUARD(s2n_stuffer_write_uint64(to, now));
+ GUARD(s2n_stuffer_write_bytes(to, conn->secure.master_secret, S2N_TLS_SECRET_LEN));
+
+ return 0;
+}
+
+static int s2n_deserialize_resumption_state(struct s2n_connection *conn, struct s2n_stuffer *from)
+{
+ uint8_t format;
+ uint8_t protocol_version;
+ uint8_t cipher_suite[S2N_TLS_CIPHER_SUITE_LEN];
+
+ S2N_ERROR_IF(s2n_stuffer_data_available(from) < S2N_STATE_SIZE_IN_BYTES, S2N_ERR_STUFFER_OUT_OF_DATA);
+
+ GUARD(s2n_stuffer_read_uint8(from, &format));
+ S2N_ERROR_IF(format != S2N_SERIALIZED_FORMAT_VERSION, S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
+
+ GUARD(s2n_stuffer_read_uint8(from, &protocol_version));
+ S2N_ERROR_IF(protocol_version != conn->actual_protocol_version, S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
+
+ GUARD(s2n_stuffer_read_bytes(from, cipher_suite, S2N_TLS_CIPHER_SUITE_LEN));
+ S2N_ERROR_IF(memcmp(conn->secure.cipher_suite->iana_value, cipher_suite, S2N_TLS_CIPHER_SUITE_LEN), S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
+
+ uint64_t now;
+ GUARD(conn->config->wall_clock(conn->config->sys_clock_ctx, &now));
+
+ uint64_t then;
+ GUARD(s2n_stuffer_read_uint64(from, &then));
+ S2N_ERROR_IF(then > now, S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
+ S2N_ERROR_IF(now - then > conn->config->session_state_lifetime_in_nanos, S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
+
+ /* Last but not least, put the master secret in place */
+ GUARD(s2n_stuffer_read_bytes(from, conn->secure.master_secret, S2N_TLS_SECRET_LEN));
+
+ return 0;
+}
+
+static int s2n_client_serialize_resumption_state(struct s2n_connection *conn, struct s2n_stuffer *to)
+{
+ /* Serialize session ticket */
+ if (conn->config->use_tickets && conn->client_ticket.size > 0) {
+ GUARD(s2n_stuffer_write_uint8(to, S2N_STATE_WITH_SESSION_TICKET));
+ GUARD(s2n_stuffer_write_uint16(to, conn->client_ticket.size));
+ GUARD(s2n_stuffer_write(to, &conn->client_ticket));
+ } else {
+ /* Serialize session id */
+ GUARD(s2n_stuffer_write_uint8(to, S2N_STATE_WITH_SESSION_ID));
+ GUARD(s2n_stuffer_write_uint8(to, conn->session_id_len));
+ GUARD(s2n_stuffer_write_bytes(to, conn->session_id, conn->session_id_len));
+ }
+
+ /* Serialize session state */
+ GUARD(s2n_serialize_resumption_state(conn, to));
+
+ return 0;
+}
+
+static int s2n_client_deserialize_session_state(struct s2n_connection *conn, struct s2n_stuffer *from)
+{
+ if (s2n_stuffer_data_available(from) < S2N_STATE_SIZE_IN_BYTES) {
+ S2N_ERROR(S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
+ }
+
+ uint8_t format;
+ uint64_t then;
+
+ GUARD(s2n_stuffer_read_uint8(from, &format));
+ if (format != S2N_SERIALIZED_FORMAT_VERSION) {
+ S2N_ERROR(S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
+ }
+
+ GUARD(s2n_stuffer_read_uint8(from, &conn->actual_protocol_version));
+
+ uint8_t *cipher_suite_wire = s2n_stuffer_raw_read(from, S2N_TLS_CIPHER_SUITE_LEN);
+ notnull_check(cipher_suite_wire);
+ GUARD(s2n_set_cipher_as_client(conn, cipher_suite_wire));
+
+ GUARD(s2n_stuffer_read_uint64(from, &then));
+
+ /* Last but not least, put the master secret in place */
+ GUARD(s2n_stuffer_read_bytes(from, conn->secure.master_secret, S2N_TLS_SECRET_LEN));
+
+ return 0;
+}
+
+static int s2n_client_deserialize_with_session_id(struct s2n_connection *conn, struct s2n_stuffer *from)
+{
+ uint8_t session_id_len;
+ GUARD(s2n_stuffer_read_uint8(from, &session_id_len));
+
+ if (session_id_len == 0 || session_id_len > S2N_TLS_SESSION_ID_MAX_LEN
+ || session_id_len > s2n_stuffer_data_available(from)) {
+ S2N_ERROR(S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
+ }
+
+ conn->session_id_len = session_id_len;
+ GUARD(s2n_stuffer_read_bytes(from, conn->session_id, session_id_len));
+
+ GUARD(s2n_client_deserialize_session_state(conn, from));
+
+ return 0;
+}
+
+static int s2n_client_deserialize_with_session_ticket(struct s2n_connection *conn, struct s2n_stuffer *from)
+{
+ uint16_t session_ticket_len;
+ GUARD(s2n_stuffer_read_uint16(from, &session_ticket_len));
+
+ if (session_ticket_len == 0 || session_ticket_len > s2n_stuffer_data_available(from)) {
+ S2N_ERROR(S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
+ }
+
+ GUARD(s2n_realloc(&conn->client_ticket, session_ticket_len));
+ GUARD(s2n_stuffer_read(from, &conn->client_ticket));
+
+ GUARD(s2n_client_deserialize_session_state(conn, from));
+
+ return 0;
+}
+
+static int s2n_client_deserialize_resumption_state(struct s2n_connection *conn, struct s2n_stuffer *from)
+{
+ uint8_t format;
+ GUARD(s2n_stuffer_read_uint8(from, &format));
+
+ switch (format) {
+ case S2N_STATE_WITH_SESSION_ID:
+ GUARD(s2n_client_deserialize_with_session_id(conn, from));
+ break;
+ case S2N_STATE_WITH_SESSION_TICKET:
+ GUARD(s2n_client_deserialize_with_session_ticket(conn, from));
+ break;
+ default:
+ S2N_ERROR(S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
+ }
+
+ return 0;
+}
+
+int s2n_resume_from_cache(struct s2n_connection *conn)
+{
+ S2N_ERROR_IF(conn->session_id_len == 0, S2N_ERR_SESSION_ID_TOO_SHORT);
+ S2N_ERROR_IF(conn->session_id_len > S2N_TLS_SESSION_ID_MAX_LEN, S2N_ERR_SESSION_ID_TOO_LONG);
+
+ uint8_t data[S2N_TICKET_SIZE_IN_BYTES] = { 0 };
+ struct s2n_blob entry = {0};
+ GUARD(s2n_blob_init(&entry, data, S2N_TICKET_SIZE_IN_BYTES));
+ uint64_t size = entry.size;
+ int result = conn->config->cache_retrieve(conn, conn->config->cache_retrieve_data, conn->session_id, conn->session_id_len, entry.data, &size);
+ if (result == S2N_CALLBACK_BLOCKED) {
+ S2N_ERROR(S2N_ERR_ASYNC_BLOCKED);
+ }
+ GUARD(result);
+
+ S2N_ERROR_IF(size != entry.size, S2N_ERR_SIZE_MISMATCH);
+
+ struct s2n_stuffer from = {0};
+ GUARD(s2n_stuffer_init(&from, &entry));
+ GUARD(s2n_stuffer_write(&from, &entry));
+ GUARD(s2n_decrypt_session_cache(conn, &from));
+
+ return 0;
+}
+
+int s2n_store_to_cache(struct s2n_connection *conn)
+{
+ uint8_t data[S2N_TICKET_SIZE_IN_BYTES] = { 0 };
+ struct s2n_blob entry = {0};
+ GUARD(s2n_blob_init(&entry, data, S2N_TICKET_SIZE_IN_BYTES));
+ struct s2n_stuffer to = {0};
+
+ /* session_id_len should always be >0 since either the Client provided a SessionId or the Server generated a new
+ * one for the Client */
+ S2N_ERROR_IF(conn->session_id_len == 0, S2N_ERR_SESSION_ID_TOO_SHORT);
+ S2N_ERROR_IF(conn->session_id_len > S2N_TLS_SESSION_ID_MAX_LEN, S2N_ERR_SESSION_ID_TOO_LONG);
+
+ GUARD(s2n_stuffer_init(&to, &entry));
+ GUARD(s2n_encrypt_session_cache(conn, &to));
+
+ /* Store to the cache */
+ conn->config->cache_store(conn, conn->config->cache_store_data, S2N_TLS_SESSION_CACHE_TTL, conn->session_id, conn->session_id_len, entry.data, entry.size);
+
+ return 0;
+}
+
+int s2n_connection_set_session(struct s2n_connection *conn, const uint8_t *session, size_t length)
+{
+ notnull_check(conn);
+ notnull_check(session);
+
+ DEFER_CLEANUP(struct s2n_blob session_data = {0}, s2n_free);
+ GUARD(s2n_alloc(&session_data, length));
+ memcpy(session_data.data, session, length);
+
+ struct s2n_stuffer from = {0};
+ GUARD(s2n_stuffer_init(&from, &session_data));
+ GUARD(s2n_stuffer_write(&from, &session_data));
+ GUARD(s2n_client_deserialize_resumption_state(conn, &from));
+ return 0;
+}
+
+int s2n_connection_get_session(struct s2n_connection *conn, uint8_t *session, size_t max_length)
+{
+ notnull_check(conn);
+ notnull_check(session);
+
+ int len = s2n_connection_get_session_length(conn);
+
+ if (len == 0) {
+ return 0;
+ }
+
+ S2N_ERROR_IF(len > max_length, S2N_ERR_SERIALIZED_SESSION_STATE_TOO_LONG);
+
+ struct s2n_blob serialized_data = {0};
+ GUARD(s2n_blob_init(&serialized_data, session, len));
+ GUARD(s2n_blob_zero(&serialized_data));
+
+ struct s2n_stuffer to = {0};
+ GUARD(s2n_stuffer_init(&to, &serialized_data));
+ GUARD(s2n_client_serialize_resumption_state(conn, &to));
+
+ return len;
+}
+
+int s2n_connection_get_session_ticket_lifetime_hint(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+ S2N_ERROR_IF(!(conn->config->use_tickets && conn->client_ticket.size > 0), S2N_ERR_SESSION_TICKET_NOT_SUPPORTED);
+
+ /* Session resumption using session ticket */
+ return conn->ticket_lifetime_hint;
+}
+
+int s2n_connection_get_session_length(struct s2n_connection *conn)
+{
+ /* Session resumption using session ticket "format (1) + session_ticket_len + session_ticket + session state" */
+ if (conn->config->use_tickets && conn->client_ticket.size > 0) {
+ return S2N_STATE_FORMAT_LEN + S2N_SESSION_TICKET_SIZE_LEN + conn->client_ticket.size + S2N_STATE_SIZE_IN_BYTES;
+ } else if (conn->session_id_len > 0) {
+ /* Session resumption using session id: "format (0) + session_id_len + session_id + session state" */
+ return S2N_STATE_FORMAT_LEN + 1 + conn->session_id_len + S2N_STATE_SIZE_IN_BYTES;
+ } else {
+ return 0;
+ }
+}
+
+int s2n_connection_is_session_resumed(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+ return IS_RESUMPTION_HANDSHAKE(conn->handshake.handshake_type) ? 1 : 0;
+}
+
+int s2n_connection_is_ocsp_stapled(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ if (conn->actual_protocol_version >= S2N_TLS13) {
+ return (s2n_server_can_send_ocsp(conn) || s2n_server_sent_ocsp(conn));
+ } else {
+ return IS_OCSP_STAPLED(conn->handshake.handshake_type);
+ }
+}
+
+int s2n_config_is_encrypt_decrypt_key_available(struct s2n_config *config)
+{
+ uint64_t now;
+ struct s2n_ticket_key *ticket_key = NULL;
+ GUARD(config->wall_clock(config->sys_clock_ctx, &now));
+ notnull_check(config->ticket_keys);
+
+ uint32_t ticket_keys_len = 0;
+ GUARD_AS_POSIX(s2n_set_len(config->ticket_keys, &ticket_keys_len));
+
+ for (uint32_t i = ticket_keys_len; i > 0; i--) {
+ uint32_t idx = i - 1;
+ GUARD_AS_POSIX(s2n_set_get(config->ticket_keys, idx, (void **)&ticket_key));
+ uint64_t key_intro_time = ticket_key->intro_timestamp;
+
+ if (key_intro_time < now
+ && now < key_intro_time + config->encrypt_decrypt_key_lifetime_in_nanos) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* This function is used in s2n_get_ticket_encrypt_decrypt_key to compute the weight
+ * of the keys and to choose a single key from all of the encrypt-decrypt keys.
+ * Higher the weight of the key, higher the probability of being picked.
+ */
+int s2n_compute_weight_of_encrypt_decrypt_keys(struct s2n_config *config,
+ uint8_t *encrypt_decrypt_keys_index,
+ uint8_t num_encrypt_decrypt_keys,
+ uint64_t now)
+{
+ double total_weight = 0;
+ struct s2n_ticket_key_weight ticket_keys_weight[S2N_MAX_TICKET_KEYS];
+ struct s2n_ticket_key *ticket_key = NULL;
+
+ /* Compute weight of encrypt-decrypt keys */
+ for (int i = 0; i < num_encrypt_decrypt_keys; i++) {
+ GUARD_AS_POSIX(s2n_set_get(config->ticket_keys, encrypt_decrypt_keys_index[i], (void **)&ticket_key));
+
+ uint64_t key_intro_time = ticket_key->intro_timestamp;
+ uint64_t key_encryption_peak_time = key_intro_time + (config->encrypt_decrypt_key_lifetime_in_nanos / 2);
+
+ /* The % of encryption using this key is linearly increasing */
+ if (now < key_encryption_peak_time) {
+ ticket_keys_weight[i].key_weight = now - key_intro_time;
+ } else {
+ /* The % of encryption using this key is linearly decreasing */
+ ticket_keys_weight[i].key_weight = (config->encrypt_decrypt_key_lifetime_in_nanos / 2) - (now - key_encryption_peak_time);
+ }
+
+ ticket_keys_weight[i].key_index = encrypt_decrypt_keys_index[i];
+ total_weight += ticket_keys_weight[i].key_weight;
+ }
+
+ /* Pick a random number in [0, 1). Using 53 bits (IEEE 754 double-precision floats). */
+ uint64_t random_int = 0;
+ GUARD_AS_POSIX(s2n_public_random(pow(2, 53), &random_int));
+ double random = (double)random_int / (double)pow(2, 53);
+
+ /* Compute cumulative weight of encrypt-decrypt keys */
+ for (int i = 0; i < num_encrypt_decrypt_keys; i++) {
+ ticket_keys_weight[i].key_weight = ticket_keys_weight[i].key_weight / total_weight;
+
+ if (i > 0) {
+ ticket_keys_weight[i].key_weight += ticket_keys_weight[i - 1].key_weight;
+ }
+
+ if (ticket_keys_weight[i].key_weight > random) {
+ return ticket_keys_weight[i].key_index;
+ }
+ }
+
+ S2N_ERROR(S2N_ERR_ENCRYPT_DECRYPT_KEY_SELECTION_FAILED);
+}
+
+/* This function is used in s2n_encrypt_session_ticket in order for s2n to
+ * choose a key in encrypt-decrypt state from all of the keys added to config
+ */
+struct s2n_ticket_key *s2n_get_ticket_encrypt_decrypt_key(struct s2n_config *config)
+{
+ uint8_t num_encrypt_decrypt_keys = 0;
+ uint8_t encrypt_decrypt_keys_index[S2N_MAX_TICKET_KEYS] = { 0 };
+ struct s2n_ticket_key *ticket_key = NULL;
+
+ uint64_t now;
+ GUARD_PTR(config->wall_clock(config->sys_clock_ctx, &now));
+ notnull_check_ptr(config->ticket_keys);
+
+ uint32_t ticket_keys_len = 0;
+ GUARD_RESULT_PTR(s2n_set_len(config->ticket_keys, &ticket_keys_len));
+
+ for (uint32_t i = ticket_keys_len; i > 0; i--) {
+ uint32_t idx = i - 1;
+ GUARD_RESULT_PTR(s2n_set_get(config->ticket_keys, idx, (void **)&ticket_key));
+ uint64_t key_intro_time = ticket_key->intro_timestamp;
+
+ if (key_intro_time < now
+ && now < key_intro_time + config->encrypt_decrypt_key_lifetime_in_nanos) {
+ encrypt_decrypt_keys_index[num_encrypt_decrypt_keys] = idx;
+ num_encrypt_decrypt_keys++;
+ }
+ }
+
+ if (num_encrypt_decrypt_keys == 0) {
+ S2N_ERROR_PTR(S2N_ERR_NO_TICKET_ENCRYPT_DECRYPT_KEY);
+ }
+
+ if (num_encrypt_decrypt_keys == 1) {
+ GUARD_RESULT_PTR(s2n_set_get(config->ticket_keys, encrypt_decrypt_keys_index[0], (void **)&ticket_key));
+ return ticket_key;
+ }
+
+ int8_t idx;
+ GUARD_PTR(idx = s2n_compute_weight_of_encrypt_decrypt_keys(config, encrypt_decrypt_keys_index, num_encrypt_decrypt_keys, now));
+
+ GUARD_RESULT_PTR(s2n_set_get(config->ticket_keys, idx, (void **)&ticket_key));
+ return ticket_key;
+}
+
+/* This function is used in s2n_decrypt_session_ticket in order for s2n to
+ * find the matching key that was used for encryption.
+ */
+struct s2n_ticket_key *s2n_find_ticket_key(struct s2n_config *config, const uint8_t *name)
+{
+ uint64_t now;
+ struct s2n_ticket_key *ticket_key = NULL;
+ GUARD_PTR(config->wall_clock(config->sys_clock_ctx, &now));
+ notnull_check_ptr(config->ticket_keys);
+
+ uint32_t ticket_keys_len = 0;
+ GUARD_RESULT_PTR(s2n_set_len(config->ticket_keys, &ticket_keys_len));
+
+ for (uint32_t i = 0; i < ticket_keys_len; i++) {
+ GUARD_RESULT_PTR(s2n_set_get(config->ticket_keys, i, (void **)&ticket_key));
+
+ if (memcmp(ticket_key->key_name, name, S2N_TICKET_KEY_NAME_LEN) == 0) {
+
+ /* Check to see if the key has expired */
+ if (now >= ticket_key->intro_timestamp +
+ config->encrypt_decrypt_key_lifetime_in_nanos + config->decrypt_key_lifetime_in_nanos) {
+ s2n_config_wipe_expired_ticket_crypto_keys(config, i);
+
+ return NULL;
+ }
+
+ return ticket_key;
+ }
+ }
+
+ return NULL;
+}
+
+int s2n_encrypt_session_ticket(struct s2n_connection *conn, struct s2n_stuffer *to)
+{
+ struct s2n_ticket_key *key;
+ struct s2n_session_key aes_ticket_key = {0};
+ struct s2n_blob aes_key_blob = {0};
+
+ uint8_t iv_data[S2N_TLS_GCM_IV_LEN] = { 0 };
+ struct s2n_blob iv = {0};
+ GUARD(s2n_blob_init(&iv, iv_data, sizeof(iv_data)));
+
+ uint8_t aad_data[S2N_TICKET_AAD_LEN] = { 0 };
+ struct s2n_blob aad_blob = {0};
+ GUARD(s2n_blob_init(&aad_blob, aad_data, sizeof(aad_data)));
+ struct s2n_stuffer aad = {0};
+
+ uint8_t s_data[S2N_STATE_SIZE_IN_BYTES + S2N_TLS_GCM_TAG_LEN] = { 0 };
+ struct s2n_blob state_blob = {0};
+ GUARD(s2n_blob_init(&state_blob, s_data, sizeof(s_data)));
+ struct s2n_stuffer state = {0};
+
+ key = s2n_get_ticket_encrypt_decrypt_key(conn->config);
+
+ /* No keys loaded by the user or the keys are either in decrypt-only or expired state */
+ S2N_ERROR_IF(!key, S2N_ERR_NO_TICKET_ENCRYPT_DECRYPT_KEY);
+
+ GUARD(s2n_stuffer_write_bytes(to, key->key_name, S2N_TICKET_KEY_NAME_LEN));
+
+ GUARD_AS_POSIX(s2n_get_public_random_data(&iv));
+ GUARD(s2n_stuffer_write(to, &iv));
+
+ GUARD(s2n_blob_init(&aes_key_blob, key->aes_key, S2N_AES256_KEY_LEN));
+ GUARD(s2n_session_key_alloc(&aes_ticket_key));
+ GUARD(s2n_aes256_gcm.init(&aes_ticket_key));
+ GUARD(s2n_aes256_gcm.set_encryption_key(&aes_ticket_key, &aes_key_blob));
+
+ GUARD(s2n_stuffer_init(&aad, &aad_blob));
+ GUARD(s2n_stuffer_write_bytes(&aad, key->implicit_aad, S2N_TICKET_AAD_IMPLICIT_LEN));
+ GUARD(s2n_stuffer_write_bytes(&aad, key->key_name, S2N_TICKET_KEY_NAME_LEN));
+
+ GUARD(s2n_stuffer_init(&state, &state_blob));
+ GUARD(s2n_serialize_resumption_state(conn, &state));
+
+ GUARD(s2n_aes256_gcm.io.aead.encrypt(&aes_ticket_key, &iv, &aad_blob, &state_blob, &state_blob));
+
+ GUARD(s2n_stuffer_write(to, &state_blob));
+
+ GUARD(s2n_aes256_gcm.destroy_key(&aes_ticket_key));
+ GUARD(s2n_session_key_free(&aes_ticket_key));
+
+ return 0;
+}
+
+int s2n_decrypt_session_ticket(struct s2n_connection *conn)
+{
+ struct s2n_ticket_key *key;
+ DEFER_CLEANUP(struct s2n_session_key aes_ticket_key = {0}, s2n_session_key_free);
+ struct s2n_blob aes_key_blob = {0};
+ struct s2n_stuffer *from;
+
+ uint8_t key_name[S2N_TICKET_KEY_NAME_LEN];
+
+ uint8_t iv_data[S2N_TLS_GCM_IV_LEN] = { 0 };
+ struct s2n_blob iv = { 0 };
+ GUARD(s2n_blob_init(&iv, iv_data, sizeof(iv_data)));
+
+ uint8_t aad_data[S2N_TICKET_AAD_LEN] = { 0 };
+ struct s2n_blob aad_blob = {0};
+ GUARD(s2n_blob_init(&aad_blob, aad_data, sizeof(aad_data)));
+ struct s2n_stuffer aad = {0};
+
+ uint8_t s_data[S2N_STATE_SIZE_IN_BYTES] = { 0 };
+ struct s2n_blob state_blob = {0};
+ GUARD(s2n_blob_init(&state_blob, s_data, sizeof(s_data)));
+ struct s2n_stuffer state = {0};
+
+ uint8_t en_data[S2N_STATE_SIZE_IN_BYTES + S2N_TLS_GCM_TAG_LEN] = {0};
+ struct s2n_blob en_blob = {0};
+ GUARD(s2n_blob_init(&en_blob, en_data, sizeof(en_data)));
+
+ from = &conn->client_ticket_to_decrypt;
+ GUARD(s2n_stuffer_read_bytes(from, key_name, S2N_TICKET_KEY_NAME_LEN));
+
+ key = s2n_find_ticket_key(conn->config, key_name);
+
+ /* Key has expired; do full handshake with New Session Ticket (NST) */
+ S2N_ERROR_IF(!key, S2N_ERR_KEY_USED_IN_SESSION_TICKET_NOT_FOUND);
+
+ GUARD(s2n_stuffer_read(from, &iv));
+
+ s2n_blob_init(&aes_key_blob, key->aes_key, S2N_AES256_KEY_LEN);
+ GUARD(s2n_session_key_alloc(&aes_ticket_key));
+ GUARD(s2n_aes256_gcm.init(&aes_ticket_key));
+ GUARD(s2n_aes256_gcm.set_decryption_key(&aes_ticket_key, &aes_key_blob));
+
+ GUARD(s2n_stuffer_init(&aad, &aad_blob));
+ GUARD(s2n_stuffer_write_bytes(&aad, key->implicit_aad, S2N_TICKET_AAD_IMPLICIT_LEN));
+ GUARD(s2n_stuffer_write_bytes(&aad, key->key_name, S2N_TICKET_KEY_NAME_LEN));
+
+ GUARD(s2n_stuffer_read(from, &en_blob));
+
+ GUARD(s2n_aes256_gcm.io.aead.decrypt(&aes_ticket_key, &iv, &aad_blob, &en_blob, &en_blob));
+
+ GUARD(s2n_stuffer_init(&state, &state_blob));
+ GUARD(s2n_stuffer_write_bytes(&state, en_data, S2N_STATE_SIZE_IN_BYTES));
+
+ GUARD(s2n_deserialize_resumption_state(conn, &state));
+
+ uint64_t now;
+ GUARD(conn->config->wall_clock(conn->config->sys_clock_ctx, &now));
+
+ /* If the key is in decrypt-only state, then a new key is assigned
+ * for the ticket.
+ */
+ if (now >= key->intro_timestamp + conn->config->encrypt_decrypt_key_lifetime_in_nanos) {
+ /* Check if a key in encrypt-decrypt state is available */
+ if (s2n_config_is_encrypt_decrypt_key_available(conn->config) == 1) {
+ conn->session_ticket_status = S2N_NEW_TICKET;
+ conn->handshake.handshake_type |= WITH_SESSION_TICKET;
+
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+int s2n_encrypt_session_cache(struct s2n_connection *conn, struct s2n_stuffer *to)
+{
+ return s2n_encrypt_session_ticket(conn, to);
+}
+
+
+int s2n_decrypt_session_cache(struct s2n_connection *conn, struct s2n_stuffer *from)
+{
+ struct s2n_ticket_key *key;
+ struct s2n_session_key aes_ticket_key = {0};
+ struct s2n_blob aes_key_blob = {0};
+
+ uint8_t key_name[S2N_TICKET_KEY_NAME_LEN] = {0};
+
+ uint8_t iv_data[S2N_TLS_GCM_IV_LEN] = { 0 };
+ struct s2n_blob iv = {0};
+ GUARD(s2n_blob_init(&iv, iv_data, sizeof(iv_data)));
+
+ uint8_t aad_data[S2N_TICKET_AAD_LEN] = { 0 };
+ struct s2n_blob aad_blob = {0};
+ GUARD(s2n_blob_init(&aad_blob, aad_data, sizeof(aad_data)));
+ struct s2n_stuffer aad = {0};
+
+ uint8_t s_data[S2N_STATE_SIZE_IN_BYTES] = { 0 };
+ struct s2n_blob state_blob = {0};
+ GUARD(s2n_blob_init(&state_blob, s_data, sizeof(s_data)));
+ struct s2n_stuffer state = {0};
+
+ uint8_t en_data[S2N_STATE_SIZE_IN_BYTES + S2N_TLS_GCM_TAG_LEN] = {0};
+ struct s2n_blob en_blob = {0};
+ GUARD(s2n_blob_init(&en_blob, en_data, sizeof(en_data)));
+
+ GUARD(s2n_stuffer_read_bytes(from, key_name, S2N_TICKET_KEY_NAME_LEN));
+
+ key = s2n_find_ticket_key(conn->config, key_name);
+
+ /* Key has expired; do full handshake with New Session Ticket (NST) */
+ S2N_ERROR_IF(!key, S2N_ERR_KEY_USED_IN_SESSION_TICKET_NOT_FOUND);
+
+ GUARD(s2n_stuffer_read(from, &iv));
+
+ s2n_blob_init(&aes_key_blob, key->aes_key, S2N_AES256_KEY_LEN);
+ GUARD(s2n_session_key_alloc(&aes_ticket_key));
+ GUARD(s2n_aes256_gcm.init(&aes_ticket_key));
+ GUARD(s2n_aes256_gcm.set_decryption_key(&aes_ticket_key, &aes_key_blob));
+
+ GUARD(s2n_stuffer_init(&aad, &aad_blob));
+ GUARD(s2n_stuffer_write_bytes(&aad, key->implicit_aad, S2N_TICKET_AAD_IMPLICIT_LEN));
+ GUARD(s2n_stuffer_write_bytes(&aad, key->key_name, S2N_TICKET_KEY_NAME_LEN));
+
+ GUARD(s2n_stuffer_read(from, &en_blob));
+
+ GUARD(s2n_aes256_gcm.io.aead.decrypt(&aes_ticket_key, &iv, &aad_blob, &en_blob, &en_blob));
+
+ GUARD(s2n_stuffer_init(&state, &state_blob));
+ GUARD(s2n_stuffer_write_bytes(&state, en_data, S2N_STATE_SIZE_IN_BYTES));
+
+ GUARD(s2n_deserialize_resumption_state(conn, &state));
+
+ GUARD(s2n_aes256_gcm.destroy_key(&aes_ticket_key));
+ GUARD(s2n_session_key_free(&aes_ticket_key));
+
+ return 0;
+}
+
+/* This function is used to remove all or just one expired key from server config */
+int s2n_config_wipe_expired_ticket_crypto_keys(struct s2n_config *config, int8_t expired_key_index)
+{
+ int num_of_expired_keys = 0;
+ int expired_keys_index[S2N_MAX_TICKET_KEYS];
+ struct s2n_ticket_key *ticket_key = NULL;
+
+ if (expired_key_index != -1) {
+ expired_keys_index[num_of_expired_keys] = expired_key_index;
+ num_of_expired_keys++;
+
+ goto end;
+ }
+
+ uint64_t now;
+ GUARD(config->wall_clock(config->sys_clock_ctx, &now));
+ notnull_check(config->ticket_keys);
+
+ uint32_t ticket_keys_len = 0;
+ GUARD_AS_POSIX(s2n_set_len(config->ticket_keys, &ticket_keys_len));
+
+ for (uint32_t i = 0; i < ticket_keys_len; i++) {
+ GUARD_AS_POSIX(s2n_set_get(config->ticket_keys, i, (void **)&ticket_key));
+ if (now >= ticket_key->intro_timestamp +
+ config->encrypt_decrypt_key_lifetime_in_nanos + config->decrypt_key_lifetime_in_nanos) {
+ expired_keys_index[num_of_expired_keys] = i;
+ num_of_expired_keys++;
+ }
+ }
+
+end:
+ for (int j = 0; j < num_of_expired_keys; j++) {
+ GUARD_AS_POSIX(s2n_set_remove(config->ticket_keys, expired_keys_index[j] - j));
+ }
+
+ return 0;
+}
+
+
+int s2n_config_store_ticket_key(struct s2n_config *config, struct s2n_ticket_key *key)
+{
+ /* Keys are stored from oldest to newest */
+ GUARD_AS_POSIX(s2n_set_add(config->ticket_keys, key));
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_resume.h b/contrib/restricted/aws/s2n/tls/s2n_resume.h
index 2ce6a8559c..c58025e41f 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_resume.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_resume.h
@@ -1,72 +1,72 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "utils/s2n_blob.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#define S2N_SERIALIZED_FORMAT_VERSION 1
-#define S2N_STATE_LIFETIME_IN_NANOS 54000000000000 /* 15 hours */
-#define S2N_STATE_SIZE_IN_BYTES (1 + 8 + 1 + S2N_TLS_CIPHER_SUITE_LEN + S2N_TLS_SECRET_LEN)
-#define S2N_TLS_SESSION_CACHE_TTL (6 * 60 * 60)
-#define S2N_TICKET_KEY_NAME_LEN 16
-#define S2N_TICKET_AAD_IMPLICIT_LEN 12
-#define S2N_TICKET_AAD_LEN (S2N_TICKET_AAD_IMPLICIT_LEN + S2N_TICKET_KEY_NAME_LEN)
-#define S2N_AES256_KEY_LEN 32
-#define ONE_SEC_IN_NANOS 1000000000
-#define S2N_TICKET_SIZE_IN_BYTES (S2N_TICKET_KEY_NAME_LEN + S2N_TLS_GCM_IV_LEN + S2N_STATE_SIZE_IN_BYTES + S2N_TLS_GCM_TAG_LEN)
-#define S2N_TICKET_ENCRYPT_DECRYPT_KEY_LIFETIME_IN_NANOS 7200000000000 /* 2 hours */
-#define S2N_TICKET_DECRYPT_KEY_LIFETIME_IN_NANOS 46800000000000 /* 13 hours */
-#define S2N_STATE_FORMAT_LEN 1
-#define S2N_TICKET_LIFETIME_HINT_LEN 4
-#define S2N_SESSION_TICKET_SIZE_LEN 2
-#define S2N_GREATER_OR_EQUAL 1
-#define S2N_LESS_THAN -1
-
-struct s2n_connection;
-struct s2n_config;
-
-struct s2n_ticket_key {
- unsigned char key_name[S2N_TICKET_KEY_NAME_LEN];
- uint8_t aes_key[S2N_AES256_KEY_LEN];
- uint8_t implicit_aad[S2N_TICKET_AAD_IMPLICIT_LEN];
- uint64_t intro_timestamp;
-};
-
-struct s2n_ticket_key_weight {
- double key_weight;
- uint8_t key_index;
-};
-
-extern struct s2n_ticket_key *s2n_find_ticket_key(struct s2n_config *config, const uint8_t *name);
-extern int s2n_encrypt_session_ticket(struct s2n_connection *conn, struct s2n_stuffer *to);
-extern int s2n_decrypt_session_ticket(struct s2n_connection *conn);
-extern int s2n_encrypt_session_cache(struct s2n_connection *conn, struct s2n_stuffer *to);
-extern int s2n_decrypt_session_cache(struct s2n_connection *conn, struct s2n_stuffer *from);
-extern int s2n_config_is_encrypt_decrypt_key_available(struct s2n_config *config);
-extern int s2n_verify_unique_ticket_key(struct s2n_config *config, uint8_t *hash, uint16_t *insert_index);
-extern int s2n_config_wipe_expired_ticket_crypto_keys(struct s2n_config *config, int8_t expired_key_index);
-extern int s2n_config_store_ticket_key(struct s2n_config *config, struct s2n_ticket_key *key);
-
-typedef enum {
- S2N_STATE_WITH_SESSION_ID = 0,
- S2N_STATE_WITH_SESSION_TICKET
-} s2n_client_tls_session_state_format;
-
-extern int s2n_allowed_to_cache_connection(struct s2n_connection *conn);
-extern int s2n_resume_from_cache(struct s2n_connection *conn);
-extern int s2n_store_to_cache(struct s2n_connection *conn);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "utils/s2n_blob.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#define S2N_SERIALIZED_FORMAT_VERSION 1
+#define S2N_STATE_LIFETIME_IN_NANOS 54000000000000 /* 15 hours */
+#define S2N_STATE_SIZE_IN_BYTES (1 + 8 + 1 + S2N_TLS_CIPHER_SUITE_LEN + S2N_TLS_SECRET_LEN)
+#define S2N_TLS_SESSION_CACHE_TTL (6 * 60 * 60)
+#define S2N_TICKET_KEY_NAME_LEN 16
+#define S2N_TICKET_AAD_IMPLICIT_LEN 12
+#define S2N_TICKET_AAD_LEN (S2N_TICKET_AAD_IMPLICIT_LEN + S2N_TICKET_KEY_NAME_LEN)
+#define S2N_AES256_KEY_LEN 32
+#define ONE_SEC_IN_NANOS 1000000000
+#define S2N_TICKET_SIZE_IN_BYTES (S2N_TICKET_KEY_NAME_LEN + S2N_TLS_GCM_IV_LEN + S2N_STATE_SIZE_IN_BYTES + S2N_TLS_GCM_TAG_LEN)
+#define S2N_TICKET_ENCRYPT_DECRYPT_KEY_LIFETIME_IN_NANOS 7200000000000 /* 2 hours */
+#define S2N_TICKET_DECRYPT_KEY_LIFETIME_IN_NANOS 46800000000000 /* 13 hours */
+#define S2N_STATE_FORMAT_LEN 1
+#define S2N_TICKET_LIFETIME_HINT_LEN 4
+#define S2N_SESSION_TICKET_SIZE_LEN 2
+#define S2N_GREATER_OR_EQUAL 1
+#define S2N_LESS_THAN -1
+
+struct s2n_connection;
+struct s2n_config;
+
+struct s2n_ticket_key {
+ unsigned char key_name[S2N_TICKET_KEY_NAME_LEN];
+ uint8_t aes_key[S2N_AES256_KEY_LEN];
+ uint8_t implicit_aad[S2N_TICKET_AAD_IMPLICIT_LEN];
+ uint64_t intro_timestamp;
+};
+
+struct s2n_ticket_key_weight {
+ double key_weight;
+ uint8_t key_index;
+};
+
+extern struct s2n_ticket_key *s2n_find_ticket_key(struct s2n_config *config, const uint8_t *name);
+extern int s2n_encrypt_session_ticket(struct s2n_connection *conn, struct s2n_stuffer *to);
+extern int s2n_decrypt_session_ticket(struct s2n_connection *conn);
+extern int s2n_encrypt_session_cache(struct s2n_connection *conn, struct s2n_stuffer *to);
+extern int s2n_decrypt_session_cache(struct s2n_connection *conn, struct s2n_stuffer *from);
+extern int s2n_config_is_encrypt_decrypt_key_available(struct s2n_config *config);
+extern int s2n_verify_unique_ticket_key(struct s2n_config *config, uint8_t *hash, uint16_t *insert_index);
+extern int s2n_config_wipe_expired_ticket_crypto_keys(struct s2n_config *config, int8_t expired_key_index);
+extern int s2n_config_store_ticket_key(struct s2n_config *config, struct s2n_ticket_key *key);
+
+typedef enum {
+ S2N_STATE_WITH_SESSION_ID = 0,
+ S2N_STATE_WITH_SESSION_TICKET
+} s2n_client_tls_session_state_format;
+
+extern int s2n_allowed_to_cache_connection(struct s2n_connection *conn);
+extern int s2n_resume_from_cache(struct s2n_connection *conn);
+extern int s2n_store_to_cache(struct s2n_connection *conn);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_security_policies.c b/contrib/restricted/aws/s2n/tls/s2n_security_policies.c
index 47edfd32c7..2daa495369 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_security_policies.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_security_policies.c
@@ -1,826 +1,826 @@
-/*
- * 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 <s2n.h>
-
-#include "tls/s2n_security_policies.h"
-#include "tls/s2n_connection.h"
-#include "utils/s2n_safety.h"
-
-const struct s2n_security_policy security_policy_20170210 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_20170210,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_20201110 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_20190801,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20200207,
- .certificate_signature_preferences = &s2n_certificate_signature_preferences_20201110,
- .ecc_preferences = &s2n_ecc_preferences_20200310,
-};
-
-const struct s2n_security_policy security_policy_20190801 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_20190801,
- .kem_preferences = &kem_preferences_null,
- /* The discrepancy in the date exists because the signature preferences
- * were named when cipher preferences and signature preferences were
- * tracked separately, and we chose to keep the cipher preference
- * name because customers use it.
- */
- .signature_preferences = &s2n_signature_preferences_20200207,
- .ecc_preferences = &s2n_ecc_preferences_20200310,
-};
-
-const struct s2n_security_policy security_policy_20190802 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_20190801,
- .kem_preferences = &kem_preferences_null,
- /* The discrepancy in the date exists because the signature preferences
- * were named when cipher preferences and signature preferences were
- * tracked separately, and we chose to keep the cipher preference
- * name because customers use it.
- */
- .signature_preferences = &s2n_signature_preferences_20200207,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_20170405 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_20170405,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_elb_2015_04 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &elb_security_policy_2015_04,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_elb_2016_08 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &elb_security_policy_2016_08,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_elb_tls_1_1_2017_01 = {
- .minimum_protocol_version = S2N_TLS11,
- .cipher_preferences = &elb_security_policy_tls_1_1_2017_01,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_elb_tls_1_2_2017_01 = {
- .minimum_protocol_version = S2N_TLS12,
- .cipher_preferences = &elb_security_policy_tls_1_2_2017_01,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_elb_tls_1_2_ext_2018_06 = {
- .minimum_protocol_version = S2N_TLS12,
- .cipher_preferences = &elb_security_policy_tls_1_2_ext_2018_06,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_elb_fs_2018_06 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &elb_security_policy_fs_2018_06,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_elb_fs_1_2_2019_08 = {
- .minimum_protocol_version = S2N_TLS12,
- .cipher_preferences = &elb_security_policy_fs_1_2_2019_08,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_elb_fs_1_1_2019_08 = {
- .minimum_protocol_version = S2N_TLS11,
- .cipher_preferences = &elb_security_policy_fs_1_1_2019_08,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_elb_fs_1_2_Res_2019_08 = {
- .minimum_protocol_version = S2N_TLS12,
- .cipher_preferences = &elb_security_policy_fs_1_2_Res_2019_08,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-/* CloudFront upstream */
-const struct s2n_security_policy security_policy_cloudfront_upstream = {
- .minimum_protocol_version = S2N_SSLv3,
- .cipher_preferences = &cipher_preferences_cloudfront_upstream,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_cloudfront_upstream_tls10 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_cloudfront_upstream_tls10,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_cloudfront_upstream_tls11 = {
- .minimum_protocol_version = S2N_TLS11,
- .cipher_preferences = &cipher_preferences_cloudfront_upstream_tls11,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_cloudfront_upstream_tls12 = {
- .minimum_protocol_version = S2N_TLS12,
- .cipher_preferences = &cipher_preferences_cloudfront_upstream_tls12,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-/* CloudFront viewer facing */
-const struct s2n_security_policy security_policy_cloudfront_ssl_v_3 = {
- .minimum_protocol_version = S2N_SSLv3,
- .cipher_preferences = &cipher_preferences_cloudfront_ssl_v_3,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20200207,
- .ecc_preferences = &s2n_ecc_preferences_20200310,
-};
-
-const struct s2n_security_policy security_policy_cloudfront_tls_1_0_2014 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_cloudfront_tls_1_0_2014,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20200207,
- .ecc_preferences = &s2n_ecc_preferences_20200310,
-};
-
-const struct s2n_security_policy security_policy_cloudfront_tls_1_0_2016 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_cloudfront_tls_1_0_2016,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20200207,
- .ecc_preferences = &s2n_ecc_preferences_20200310,
-};
-
-const struct s2n_security_policy security_policy_cloudfront_tls_1_1_2016 = {
- .minimum_protocol_version = S2N_TLS11,
- .cipher_preferences = &cipher_preferences_cloudfront_tls_1_1_2016,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20200207,
- .ecc_preferences = &s2n_ecc_preferences_20200310,
-};
-
-const struct s2n_security_policy security_policy_cloudfront_tls_1_2_2018 = {
- .minimum_protocol_version = S2N_TLS12,
- .cipher_preferences = &cipher_preferences_cloudfront_tls_1_2_2018,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20200207,
- .ecc_preferences = &s2n_ecc_preferences_20200310,
-};
-
-const struct s2n_security_policy security_policy_cloudfront_tls_1_2_2019 = {
- .minimum_protocol_version = S2N_TLS12,
- .cipher_preferences = &cipher_preferences_cloudfront_tls_1_2_2019,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20200207,
- .ecc_preferences = &s2n_ecc_preferences_20200310,
-};
-
-/* CloudFront viewer facing legacy TLS 1.2 policies */
-const struct s2n_security_policy security_policy_cloudfront_ssl_v_3_legacy = {
- .minimum_protocol_version = S2N_SSLv3,
- .cipher_preferences = &cipher_preferences_cloudfront_ssl_v_3_legacy,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_cloudfront_tls_1_0_2014_legacy = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_cloudfront_tls_1_0_2014_legacy,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_cloudfront_tls_1_0_2016_legacy = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_cloudfront_tls_1_0_2016_legacy,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_cloudfront_tls_1_1_2016_legacy = {
- .minimum_protocol_version = S2N_TLS11,
- .cipher_preferences = &cipher_preferences_cloudfront_tls_1_1_2016_legacy,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_cloudfront_tls_1_2_2018_legacy = {
- .minimum_protocol_version = S2N_TLS12,
- .cipher_preferences = &cipher_preferences_cloudfront_tls_1_2_2018_legacy,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_cloudfront_tls_1_2_2019_legacy = {
- .minimum_protocol_version = S2N_TLS12,
- .cipher_preferences = &cipher_preferences_cloudfront_tls_1_2_2019_legacy,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_kms_tls_1_0_2018_10 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_kms_tls_1_0_2018_10,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-#if !defined(S2N_NO_PQ)
-
-const struct s2n_security_policy security_policy_kms_pq_tls_1_0_2019_06 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_kms_pq_tls_1_0_2019_06,
- .kem_preferences = &kem_preferences_kms_pq_tls_1_0_2019_06,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_kms_pq_tls_1_0_2020_02 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_kms_pq_tls_1_0_2020_02,
- .kem_preferences = &kem_preferences_kms_pq_tls_1_0_2020_02,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_pq_sike_test_tls_1_0_2019_11 = {
- .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,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_pq_sike_test_tls_1_0_2020_02 = {
- .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,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_kms_pq_tls_1_0_2020_07 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_kms_pq_tls_1_0_2020_07,
- .kem_preferences = &kem_preferences_kms_pq_tls_1_0_2020_07,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_pq_tls_1_0_2020_12 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_pq_tls_1_0_2020_12,
- .kem_preferences = &kem_preferences_pq_tls_1_0_2020_12,
- .signature_preferences = &s2n_signature_preferences_20200207,
- .ecc_preferences = &s2n_ecc_preferences_20200310,
-};
-
-#endif
-const struct s2n_security_policy security_policy_kms_fips_tls_1_2_2018_10 = {
- .minimum_protocol_version = S2N_TLS12,
- .cipher_preferences = &cipher_preferences_kms_fips_tls_1_2_2018_10,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_20140601 = {
- .minimum_protocol_version = S2N_SSLv3,
- .cipher_preferences = &cipher_preferences_20140601,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_20141001 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_20141001,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_20150202 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_20150202,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_20150214 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_20150214,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_20160411 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_20160411,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_20150306 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_20150306,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_20160804 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_20160804,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_20160824 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_20160824,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_20190122 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_20190122,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_20190121 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_20190121,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_20190120 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_20190120,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_20190214 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_20190214,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_20170328 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_20170328,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_20170718 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_20170718,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_20201021 = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_20190122,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20201021,
- .ecc_preferences = &s2n_ecc_preferences_20201021,
-};
-
-const struct s2n_security_policy security_policy_test_all = {
- .minimum_protocol_version = S2N_SSLv3,
- .cipher_preferences = &cipher_preferences_test_all,
-#if !defined(S2N_NO_PQ)
- .kem_preferences = &kem_preferences_kms_pq_tls_1_0_2020_07,
-#else
- .kem_preferences = &kem_preferences_null,
-#endif
- .signature_preferences = &s2n_signature_preferences_20201021,
- .ecc_preferences = &s2n_ecc_preferences_test_all,
-};
-
-const struct s2n_security_policy security_policy_test_all_tls12 = {
- .minimum_protocol_version = S2N_SSLv3,
- .cipher_preferences = &cipher_preferences_test_all_tls12,
-#if !defined(S2N_NO_PQ)
- .kem_preferences = &kem_preferences_kms_pq_tls_1_0_2020_07,
-#else
- .kem_preferences = &kem_preferences_null,
-#endif
- .signature_preferences = &s2n_signature_preferences_20201021,
- .ecc_preferences = &s2n_ecc_preferences_20201021,
-};
-
-const struct s2n_security_policy security_policy_test_all_fips = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_test_all_fips,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_test_all_ecdsa = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_test_all_ecdsa,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20201021,
- .ecc_preferences = &s2n_ecc_preferences_test_all,
-};
-
-const struct s2n_security_policy security_policy_test_all_rsa_kex = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_test_all_rsa_kex,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20140601,
- .ecc_preferences = &s2n_ecc_preferences_20140601,
-};
-
-const struct s2n_security_policy security_policy_test_all_tls13 = {
- .minimum_protocol_version = S2N_SSLv3,
- .cipher_preferences = &cipher_preferences_test_all_tls13,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20201021,
- .ecc_preferences = &s2n_ecc_preferences_test_all,
-};
-
-const struct s2n_security_policy security_policy_test_ecdsa_priority = {
- .minimum_protocol_version = S2N_SSLv3,
- .cipher_preferences = &cipher_preferences_test_ecdsa_priority,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_20201021,
- .ecc_preferences = &s2n_ecc_preferences_test_all,
-};
-
-const struct s2n_security_policy security_policy_null = {
- .minimum_protocol_version = S2N_TLS10,
- .cipher_preferences = &cipher_preferences_null,
- .kem_preferences = &kem_preferences_null,
- .signature_preferences = &s2n_signature_preferences_null,
- .ecc_preferences = &s2n_ecc_preferences_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_20201110, .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="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 },
- { .version="ELBSecurityPolicy-2016-08", .security_policy=&security_policy_elb_2016_08, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="ELBSecurityPolicy-TLS-1-1-2017-01", .security_policy=&security_policy_elb_tls_1_1_2017_01, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .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="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 },
- { .version="CloudFront-Upstream-TLS-1-2", .security_policy=&security_policy_cloudfront_upstream_tls12, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- /* CloudFront Viewer Facing */
- { .version="CloudFront-SSL-v-3", .security_policy=&security_policy_cloudfront_ssl_v_3, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="CloudFront-TLS-1-0-2014", .security_policy=&security_policy_cloudfront_tls_1_0_2014, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="CloudFront-TLS-1-0-2016", .security_policy=&security_policy_cloudfront_tls_1_0_2016, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="CloudFront-TLS-1-1-2016", .security_policy=&security_policy_cloudfront_tls_1_1_2016, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="CloudFront-TLS-1-2-2018", .security_policy=&security_policy_cloudfront_tls_1_2_2018, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="CloudFront-TLS-1-2-2019", .security_policy=&security_policy_cloudfront_tls_1_2_2019, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- /* CloudFront Legacy (TLS 1.2) policies */
- { .version="CloudFront-SSL-v-3-Legacy", .security_policy=&security_policy_cloudfront_ssl_v_3_legacy, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="CloudFront-TLS-1-0-2014-Legacy", .security_policy=&security_policy_cloudfront_tls_1_0_2014_legacy, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="CloudFront-TLS-1-0-2016-Legacy", .security_policy=&security_policy_cloudfront_tls_1_0_2016_legacy, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="CloudFront-TLS-1-1-2016-Legacy", .security_policy=&security_policy_cloudfront_tls_1_1_2016_legacy, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="CloudFront-TLS-1-2-2018-Legacy", .security_policy=&security_policy_cloudfront_tls_1_2_2018_legacy, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="CloudFront-TLS-1-2-2019-Legacy", .security_policy=&security_policy_cloudfront_tls_1_2_2019_legacy, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="KMS-TLS-1-0-2018-10", .security_policy=&security_policy_kms_tls_1_0_2018_10, .ecc_extension_required=0, .pq_kem_extension_required=0 },
-#if !defined(S2N_NO_PQ)
- { .version="KMS-PQ-TLS-1-0-2019-06", .security_policy=&security_policy_kms_pq_tls_1_0_2019_06, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="KMS-PQ-TLS-1-0-2020-02", .security_policy=&security_policy_kms_pq_tls_1_0_2020_02, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="KMS-PQ-TLS-1-0-2020-07", .security_policy=&security_policy_kms_pq_tls_1_0_2020_07, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="PQ-SIKE-TEST-TLS-1-0-2019-11", .security_policy=&security_policy_pq_sike_test_tls_1_0_2019_11, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="PQ-SIKE-TEST-TLS-1-0-2020-02", .security_policy=&security_policy_pq_sike_test_tls_1_0_2020_02, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="PQ-TLS-1-0-2020-12", .security_policy=&security_policy_pq_tls_1_0_2020_12, .ecc_extension_required=0, .pq_kem_extension_required=0 },
-#endif
- { .version="KMS-FIPS-TLS-1-2-2018-10", .security_policy=&security_policy_kms_fips_tls_1_2_2018_10, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="20140601", .security_policy=&security_policy_20140601, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="20141001", .security_policy=&security_policy_20141001, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="20150202", .security_policy=&security_policy_20150202, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="20150214", .security_policy=&security_policy_20150214, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="20150306", .security_policy=&security_policy_20150306, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="20160411", .security_policy=&security_policy_20160411, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="20160804", .security_policy=&security_policy_20160804, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="20160824", .security_policy=&security_policy_20160824, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="20170210", .security_policy=&security_policy_20170210, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="20170328", .security_policy=&security_policy_20170328, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="20190214", .security_policy=&security_policy_20190214, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="20170405", .security_policy=&security_policy_20170405, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="20170718", .security_policy=&security_policy_20170718, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="20190120", .security_policy=&security_policy_20190120, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="20190121", .security_policy=&security_policy_20190121, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="20190122", .security_policy=&security_policy_20190122, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="20190801", .security_policy=&security_policy_20190801, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="20190802", .security_policy=&security_policy_20190802, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="20200207", .security_policy=&security_policy_test_all_tls13, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="20201021", .security_policy=&security_policy_20201021, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="test_all", .security_policy=&security_policy_test_all, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="test_all_fips", .security_policy=&security_policy_test_all_fips, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="test_all_ecdsa", .security_policy=&security_policy_test_all_ecdsa, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="test_all_rsa_kex", .security_policy=&security_policy_test_all_rsa_kex, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="test_ecdsa_priority", .security_policy=&security_policy_test_ecdsa_priority, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="test_all_tls12", .security_policy=&security_policy_test_all_tls12, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="test_all_tls13", .security_policy=&security_policy_test_all_tls13, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version="null", .security_policy=&security_policy_null, .ecc_extension_required=0, .pq_kem_extension_required=0 },
- { .version=NULL, .security_policy=NULL, .ecc_extension_required=0, .pq_kem_extension_required=0 }
-};
-
-int s2n_find_security_policy_from_version(const char *version, const struct s2n_security_policy **security_policy)
-{
- notnull_check(version);
- notnull_check(security_policy);
-
- for (int i = 0; security_policy_selection[i].version != NULL; i++) {
- if (!strcasecmp(version, security_policy_selection[i].version)) {
- *security_policy = security_policy_selection[i].security_policy;
- return 0;
- }
- }
-
- S2N_ERROR(S2N_ERR_INVALID_SECURITY_POLICY);
-}
-
-int s2n_config_set_cipher_preferences(struct s2n_config *config, const char *version)
-{
- const struct s2n_security_policy *security_policy = NULL;
- GUARD(s2n_find_security_policy_from_version(version, &security_policy));
- ENSURE_POSIX_REF(security_policy);
- ENSURE_POSIX_REF(security_policy->cipher_preferences);
- ENSURE_POSIX_REF(security_policy->kem_preferences);
- ENSURE_POSIX_REF(security_policy->signature_preferences);
- ENSURE_POSIX_REF(security_policy->ecc_preferences);
-
- config->security_policy = security_policy;
- return 0;
-}
-
-int s2n_connection_set_cipher_preferences(struct s2n_connection *conn, const char *version)
-{
- const struct s2n_security_policy *security_policy = NULL;
- GUARD(s2n_find_security_policy_from_version(version, &security_policy));
- ENSURE_POSIX_REF(security_policy);
- ENSURE_POSIX_REF(security_policy->cipher_preferences);
- ENSURE_POSIX_REF(security_policy->kem_preferences);
- ENSURE_POSIX_REF(security_policy->signature_preferences);
- ENSURE_POSIX_REF(security_policy->ecc_preferences);
-
- conn->security_policy_override = security_policy;
- return 0;
-}
-
-int s2n_security_policies_init()
-{
- for (int i = 0; security_policy_selection[i].version != NULL; i++) {
- const struct s2n_security_policy *security_policy = security_policy_selection[i].security_policy;
- notnull_check(security_policy);
- const struct s2n_cipher_preferences *cipher_preference = security_policy->cipher_preferences;
- notnull_check(cipher_preference);
- const struct s2n_kem_preferences *kem_preference = security_policy->kem_preferences;
- notnull_check(kem_preference);
- const struct s2n_ecc_preferences *ecc_preference = security_policy->ecc_preferences;
- notnull_check(ecc_preference);
- GUARD(s2n_check_ecc_preferences_curves_list(ecc_preference));
-
- const struct s2n_signature_preferences *certificate_signature_preference = security_policy->certificate_signature_preferences;
- if (certificate_signature_preference != NULL) {
- GUARD_AS_POSIX(s2n_validate_certificate_signature_preferences(certificate_signature_preference));
- }
-
- if (security_policy != &security_policy_null) {
- /* catch any offending security policy that does not support P-256 */
- S2N_ERROR_IF(!s2n_ecc_preferences_includes_curve(ecc_preference, TLS_EC_CURVE_SECP_256_R1), S2N_ERR_INVALID_SECURITY_POLICY);
- }
-
- for (int j = 0; j < cipher_preference->count; j++) {
- struct s2n_cipher_suite *cipher = cipher_preference->suites[j];
- notnull_check(cipher);
-
- /* TLS1.3 does not include key exchange algorithms in its cipher suites,
- * but the elliptic curves extension is always required. */
- if (cipher->minimum_required_tls_version >= S2N_TLS13) {
- security_policy_selection[i].ecc_extension_required = 1;
- security_policy_selection[i].supports_tls13 = 1;
- }
-
- /* Sanity check that valid tls13 has minimum tls version set correctly */
- S2N_ERROR_IF(s2n_is_valid_tls13_cipher(cipher->iana_value) ^
- (cipher->minimum_required_tls_version >= S2N_TLS13), S2N_ERR_INVALID_SECURITY_POLICY);
-
- if (s2n_kex_includes(cipher->key_exchange_alg, &s2n_ecdhe)) {
- security_policy_selection[i].ecc_extension_required = 1;
- }
-
- if (s2n_kex_includes(cipher->key_exchange_alg, &s2n_kem)) {
- security_policy_selection[i].pq_kem_extension_required = 1;
- }
- }
-
- GUARD(s2n_validate_kem_preferences(kem_preference, security_policy_selection[i].pq_kem_extension_required));
- }
- return 0;
-}
-
-bool s2n_ecc_is_extension_required(const struct s2n_security_policy *security_policy)
-{
- if (security_policy == NULL) {
- return false;
- }
-
- for (int i = 0; security_policy_selection[i].version != NULL; i++) {
- if (security_policy_selection[i].security_policy == security_policy) {
- return 1 == security_policy_selection[i].ecc_extension_required;
- }
- }
- return false;
-}
-
-bool s2n_pq_kem_is_extension_required(const struct s2n_security_policy *security_policy)
-{
- if (security_policy == NULL) {
- return false;
- }
-
- for (int i = 0; security_policy_selection[i].version != NULL; i++) {
- if (security_policy_selection[i].security_policy == security_policy) {
- return 1 == security_policy_selection[i].pq_kem_extension_required;
- }
- }
- return false;
-}
-
-/* Checks whether cipher preference supports TLS 1.3 based on whether it is configured
- * with TLS 1.3 ciphers. Returns true or false.
- */
-bool s2n_security_policy_supports_tls13(const struct s2n_security_policy *security_policy)
-{
- if (security_policy == NULL) {
- return false;
- }
-
- for (uint8_t i = 0; security_policy_selection[i].version != NULL; i++) {
- if (security_policy_selection[i].security_policy == security_policy) {
- return security_policy_selection[i].supports_tls13 == 1;
- }
- }
-
- /* if cipher preference is not in the official list, compute the result */
- const struct s2n_cipher_preferences *cipher_preferences = security_policy->cipher_preferences;
- if (cipher_preferences == NULL) {
- return false;
- }
-
- for (uint8_t i = 0; i < cipher_preferences->count; i++) {
- if (s2n_is_valid_tls13_cipher(cipher_preferences->suites[i]->iana_value)) {
- return true;
- }
- }
-
- return false;
-}
-
-int s2n_connection_is_valid_for_cipher_preferences(struct s2n_connection *conn, const char *version)
-{
- notnull_check(conn);
- notnull_check(version);
- notnull_check(conn->secure.cipher_suite);
-
- const struct s2n_security_policy *security_policy = NULL;
- GUARD(s2n_find_security_policy_from_version(version, &security_policy));
- notnull_check(security_policy);
-
- /* make sure we dont use a tls version lower than that configured by the version */
- if (s2n_connection_get_actual_protocol_version(conn) < security_policy->minimum_protocol_version) {
- return 0;
- }
-
- struct s2n_cipher_suite *cipher = conn->secure.cipher_suite;
- notnull_check(cipher);
- for (int i = 0; i < security_policy->cipher_preferences->count; ++i) {
- if (0 == memcmp(security_policy->cipher_preferences->suites[i]->iana_value, cipher->iana_value, S2N_TLS_CIPHER_SUITE_LEN)) {
- return 1;
- }
- }
-
- return 0;
-}
-
-int s2n_validate_kem_preferences(const struct s2n_kem_preferences *kem_preferences, bool pq_kem_extension_required) {
- notnull_check(kem_preferences);
-
- /* Basic sanity checks to assert that the count is 0 if and only if the associated list is NULL */
- ENSURE_POSIX(S2N_IFF(kem_preferences->tls13_kem_group_count == 0, kem_preferences->tls13_kem_groups == NULL),
- S2N_ERR_INVALID_SECURITY_POLICY);
- ENSURE_POSIX(S2N_IFF(kem_preferences->kem_count == 0, kem_preferences->kems == NULL),
- S2N_ERR_INVALID_SECURITY_POLICY);
-
- /* The PQ KEM extension is applicable only to TLS 1.2 */
- if (pq_kem_extension_required) {
- ENSURE_POSIX(kem_preferences->kem_count > 0, S2N_ERR_INVALID_SECURITY_POLICY);
- ENSURE_POSIX(kem_preferences->kems != NULL, S2N_ERR_INVALID_SECURITY_POLICY);
- } else {
- ENSURE_POSIX(kem_preferences->kem_count == 0, S2N_ERR_INVALID_SECURITY_POLICY);
- ENSURE_POSIX(kem_preferences->kems == NULL, S2N_ERR_INVALID_SECURITY_POLICY);
- }
-
- return S2N_SUCCESS;
-}
-
-S2N_RESULT s2n_validate_certificate_signature_preferences(const struct s2n_signature_preferences *certificate_signature_preferences)
-{
- ENSURE_REF(certificate_signature_preferences);
-
- size_t rsa_pss_scheme_count = 0;
-
- for (size_t i = 0; i < certificate_signature_preferences->count; i++) {
- if (certificate_signature_preferences->signature_schemes[i]->libcrypto_nid == NID_rsassaPss) {
- rsa_pss_scheme_count++;
- }
- }
-
- /* The Openssl function used to parse signatures off certificates does not differentiate between any rsa pss
- * signature schemes. Therefore a security policy with a certificate signatures preference list must include
- * all rsa_pss signature schemes. */
- ENSURE(rsa_pss_scheme_count == NUM_RSA_PSS_SCHEMES || rsa_pss_scheme_count == 0, S2N_ERR_INVALID_SECURITY_POLICY);
- return S2N_RESULT_OK;
-}
+/*
+ * 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 <s2n.h>
+
+#include "tls/s2n_security_policies.h"
+#include "tls/s2n_connection.h"
+#include "utils/s2n_safety.h"
+
+const struct s2n_security_policy security_policy_20170210 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_20170210,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_20201110 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_20190801,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20200207,
+ .certificate_signature_preferences = &s2n_certificate_signature_preferences_20201110,
+ .ecc_preferences = &s2n_ecc_preferences_20200310,
+};
+
+const struct s2n_security_policy security_policy_20190801 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_20190801,
+ .kem_preferences = &kem_preferences_null,
+ /* The discrepancy in the date exists because the signature preferences
+ * were named when cipher preferences and signature preferences were
+ * tracked separately, and we chose to keep the cipher preference
+ * name because customers use it.
+ */
+ .signature_preferences = &s2n_signature_preferences_20200207,
+ .ecc_preferences = &s2n_ecc_preferences_20200310,
+};
+
+const struct s2n_security_policy security_policy_20190802 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_20190801,
+ .kem_preferences = &kem_preferences_null,
+ /* The discrepancy in the date exists because the signature preferences
+ * were named when cipher preferences and signature preferences were
+ * tracked separately, and we chose to keep the cipher preference
+ * name because customers use it.
+ */
+ .signature_preferences = &s2n_signature_preferences_20200207,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_20170405 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_20170405,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_elb_2015_04 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &elb_security_policy_2015_04,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_elb_2016_08 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &elb_security_policy_2016_08,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_elb_tls_1_1_2017_01 = {
+ .minimum_protocol_version = S2N_TLS11,
+ .cipher_preferences = &elb_security_policy_tls_1_1_2017_01,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_elb_tls_1_2_2017_01 = {
+ .minimum_protocol_version = S2N_TLS12,
+ .cipher_preferences = &elb_security_policy_tls_1_2_2017_01,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_elb_tls_1_2_ext_2018_06 = {
+ .minimum_protocol_version = S2N_TLS12,
+ .cipher_preferences = &elb_security_policy_tls_1_2_ext_2018_06,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_elb_fs_2018_06 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &elb_security_policy_fs_2018_06,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_elb_fs_1_2_2019_08 = {
+ .minimum_protocol_version = S2N_TLS12,
+ .cipher_preferences = &elb_security_policy_fs_1_2_2019_08,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_elb_fs_1_1_2019_08 = {
+ .minimum_protocol_version = S2N_TLS11,
+ .cipher_preferences = &elb_security_policy_fs_1_1_2019_08,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_elb_fs_1_2_Res_2019_08 = {
+ .minimum_protocol_version = S2N_TLS12,
+ .cipher_preferences = &elb_security_policy_fs_1_2_Res_2019_08,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+/* CloudFront upstream */
+const struct s2n_security_policy security_policy_cloudfront_upstream = {
+ .minimum_protocol_version = S2N_SSLv3,
+ .cipher_preferences = &cipher_preferences_cloudfront_upstream,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_cloudfront_upstream_tls10 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_cloudfront_upstream_tls10,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_cloudfront_upstream_tls11 = {
+ .minimum_protocol_version = S2N_TLS11,
+ .cipher_preferences = &cipher_preferences_cloudfront_upstream_tls11,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_cloudfront_upstream_tls12 = {
+ .minimum_protocol_version = S2N_TLS12,
+ .cipher_preferences = &cipher_preferences_cloudfront_upstream_tls12,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+/* CloudFront viewer facing */
+const struct s2n_security_policy security_policy_cloudfront_ssl_v_3 = {
+ .minimum_protocol_version = S2N_SSLv3,
+ .cipher_preferences = &cipher_preferences_cloudfront_ssl_v_3,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20200207,
+ .ecc_preferences = &s2n_ecc_preferences_20200310,
+};
+
+const struct s2n_security_policy security_policy_cloudfront_tls_1_0_2014 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_cloudfront_tls_1_0_2014,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20200207,
+ .ecc_preferences = &s2n_ecc_preferences_20200310,
+};
+
+const struct s2n_security_policy security_policy_cloudfront_tls_1_0_2016 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_cloudfront_tls_1_0_2016,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20200207,
+ .ecc_preferences = &s2n_ecc_preferences_20200310,
+};
+
+const struct s2n_security_policy security_policy_cloudfront_tls_1_1_2016 = {
+ .minimum_protocol_version = S2N_TLS11,
+ .cipher_preferences = &cipher_preferences_cloudfront_tls_1_1_2016,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20200207,
+ .ecc_preferences = &s2n_ecc_preferences_20200310,
+};
+
+const struct s2n_security_policy security_policy_cloudfront_tls_1_2_2018 = {
+ .minimum_protocol_version = S2N_TLS12,
+ .cipher_preferences = &cipher_preferences_cloudfront_tls_1_2_2018,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20200207,
+ .ecc_preferences = &s2n_ecc_preferences_20200310,
+};
+
+const struct s2n_security_policy security_policy_cloudfront_tls_1_2_2019 = {
+ .minimum_protocol_version = S2N_TLS12,
+ .cipher_preferences = &cipher_preferences_cloudfront_tls_1_2_2019,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20200207,
+ .ecc_preferences = &s2n_ecc_preferences_20200310,
+};
+
+/* CloudFront viewer facing legacy TLS 1.2 policies */
+const struct s2n_security_policy security_policy_cloudfront_ssl_v_3_legacy = {
+ .minimum_protocol_version = S2N_SSLv3,
+ .cipher_preferences = &cipher_preferences_cloudfront_ssl_v_3_legacy,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_cloudfront_tls_1_0_2014_legacy = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_cloudfront_tls_1_0_2014_legacy,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_cloudfront_tls_1_0_2016_legacy = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_cloudfront_tls_1_0_2016_legacy,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_cloudfront_tls_1_1_2016_legacy = {
+ .minimum_protocol_version = S2N_TLS11,
+ .cipher_preferences = &cipher_preferences_cloudfront_tls_1_1_2016_legacy,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_cloudfront_tls_1_2_2018_legacy = {
+ .minimum_protocol_version = S2N_TLS12,
+ .cipher_preferences = &cipher_preferences_cloudfront_tls_1_2_2018_legacy,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_cloudfront_tls_1_2_2019_legacy = {
+ .minimum_protocol_version = S2N_TLS12,
+ .cipher_preferences = &cipher_preferences_cloudfront_tls_1_2_2019_legacy,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_kms_tls_1_0_2018_10 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_kms_tls_1_0_2018_10,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+#if !defined(S2N_NO_PQ)
+
+const struct s2n_security_policy security_policy_kms_pq_tls_1_0_2019_06 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_kms_pq_tls_1_0_2019_06,
+ .kem_preferences = &kem_preferences_kms_pq_tls_1_0_2019_06,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_kms_pq_tls_1_0_2020_02 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_kms_pq_tls_1_0_2020_02,
+ .kem_preferences = &kem_preferences_kms_pq_tls_1_0_2020_02,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_pq_sike_test_tls_1_0_2019_11 = {
+ .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,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_pq_sike_test_tls_1_0_2020_02 = {
+ .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,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_kms_pq_tls_1_0_2020_07 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_kms_pq_tls_1_0_2020_07,
+ .kem_preferences = &kem_preferences_kms_pq_tls_1_0_2020_07,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_pq_tls_1_0_2020_12 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_pq_tls_1_0_2020_12,
+ .kem_preferences = &kem_preferences_pq_tls_1_0_2020_12,
+ .signature_preferences = &s2n_signature_preferences_20200207,
+ .ecc_preferences = &s2n_ecc_preferences_20200310,
+};
+
+#endif
+const struct s2n_security_policy security_policy_kms_fips_tls_1_2_2018_10 = {
+ .minimum_protocol_version = S2N_TLS12,
+ .cipher_preferences = &cipher_preferences_kms_fips_tls_1_2_2018_10,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_20140601 = {
+ .minimum_protocol_version = S2N_SSLv3,
+ .cipher_preferences = &cipher_preferences_20140601,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_20141001 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_20141001,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_20150202 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_20150202,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_20150214 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_20150214,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_20160411 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_20160411,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_20150306 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_20150306,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_20160804 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_20160804,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_20160824 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_20160824,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_20190122 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_20190122,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_20190121 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_20190121,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_20190120 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_20190120,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_20190214 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_20190214,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_20170328 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_20170328,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_20170718 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_20170718,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_20201021 = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_20190122,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20201021,
+ .ecc_preferences = &s2n_ecc_preferences_20201021,
+};
+
+const struct s2n_security_policy security_policy_test_all = {
+ .minimum_protocol_version = S2N_SSLv3,
+ .cipher_preferences = &cipher_preferences_test_all,
+#if !defined(S2N_NO_PQ)
+ .kem_preferences = &kem_preferences_kms_pq_tls_1_0_2020_07,
+#else
+ .kem_preferences = &kem_preferences_null,
+#endif
+ .signature_preferences = &s2n_signature_preferences_20201021,
+ .ecc_preferences = &s2n_ecc_preferences_test_all,
+};
+
+const struct s2n_security_policy security_policy_test_all_tls12 = {
+ .minimum_protocol_version = S2N_SSLv3,
+ .cipher_preferences = &cipher_preferences_test_all_tls12,
+#if !defined(S2N_NO_PQ)
+ .kem_preferences = &kem_preferences_kms_pq_tls_1_0_2020_07,
+#else
+ .kem_preferences = &kem_preferences_null,
+#endif
+ .signature_preferences = &s2n_signature_preferences_20201021,
+ .ecc_preferences = &s2n_ecc_preferences_20201021,
+};
+
+const struct s2n_security_policy security_policy_test_all_fips = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_test_all_fips,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_test_all_ecdsa = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_test_all_ecdsa,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20201021,
+ .ecc_preferences = &s2n_ecc_preferences_test_all,
+};
+
+const struct s2n_security_policy security_policy_test_all_rsa_kex = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_test_all_rsa_kex,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20140601,
+ .ecc_preferences = &s2n_ecc_preferences_20140601,
+};
+
+const struct s2n_security_policy security_policy_test_all_tls13 = {
+ .minimum_protocol_version = S2N_SSLv3,
+ .cipher_preferences = &cipher_preferences_test_all_tls13,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20201021,
+ .ecc_preferences = &s2n_ecc_preferences_test_all,
+};
+
+const struct s2n_security_policy security_policy_test_ecdsa_priority = {
+ .minimum_protocol_version = S2N_SSLv3,
+ .cipher_preferences = &cipher_preferences_test_ecdsa_priority,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_20201021,
+ .ecc_preferences = &s2n_ecc_preferences_test_all,
+};
+
+const struct s2n_security_policy security_policy_null = {
+ .minimum_protocol_version = S2N_TLS10,
+ .cipher_preferences = &cipher_preferences_null,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_null,
+ .ecc_preferences = &s2n_ecc_preferences_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_20201110, .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="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 },
+ { .version="ELBSecurityPolicy-2016-08", .security_policy=&security_policy_elb_2016_08, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="ELBSecurityPolicy-TLS-1-1-2017-01", .security_policy=&security_policy_elb_tls_1_1_2017_01, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .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="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 },
+ { .version="CloudFront-Upstream-TLS-1-2", .security_policy=&security_policy_cloudfront_upstream_tls12, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ /* CloudFront Viewer Facing */
+ { .version="CloudFront-SSL-v-3", .security_policy=&security_policy_cloudfront_ssl_v_3, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="CloudFront-TLS-1-0-2014", .security_policy=&security_policy_cloudfront_tls_1_0_2014, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="CloudFront-TLS-1-0-2016", .security_policy=&security_policy_cloudfront_tls_1_0_2016, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="CloudFront-TLS-1-1-2016", .security_policy=&security_policy_cloudfront_tls_1_1_2016, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="CloudFront-TLS-1-2-2018", .security_policy=&security_policy_cloudfront_tls_1_2_2018, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="CloudFront-TLS-1-2-2019", .security_policy=&security_policy_cloudfront_tls_1_2_2019, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ /* CloudFront Legacy (TLS 1.2) policies */
+ { .version="CloudFront-SSL-v-3-Legacy", .security_policy=&security_policy_cloudfront_ssl_v_3_legacy, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="CloudFront-TLS-1-0-2014-Legacy", .security_policy=&security_policy_cloudfront_tls_1_0_2014_legacy, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="CloudFront-TLS-1-0-2016-Legacy", .security_policy=&security_policy_cloudfront_tls_1_0_2016_legacy, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="CloudFront-TLS-1-1-2016-Legacy", .security_policy=&security_policy_cloudfront_tls_1_1_2016_legacy, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="CloudFront-TLS-1-2-2018-Legacy", .security_policy=&security_policy_cloudfront_tls_1_2_2018_legacy, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="CloudFront-TLS-1-2-2019-Legacy", .security_policy=&security_policy_cloudfront_tls_1_2_2019_legacy, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="KMS-TLS-1-0-2018-10", .security_policy=&security_policy_kms_tls_1_0_2018_10, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+#if !defined(S2N_NO_PQ)
+ { .version="KMS-PQ-TLS-1-0-2019-06", .security_policy=&security_policy_kms_pq_tls_1_0_2019_06, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="KMS-PQ-TLS-1-0-2020-02", .security_policy=&security_policy_kms_pq_tls_1_0_2020_02, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="KMS-PQ-TLS-1-0-2020-07", .security_policy=&security_policy_kms_pq_tls_1_0_2020_07, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="PQ-SIKE-TEST-TLS-1-0-2019-11", .security_policy=&security_policy_pq_sike_test_tls_1_0_2019_11, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="PQ-SIKE-TEST-TLS-1-0-2020-02", .security_policy=&security_policy_pq_sike_test_tls_1_0_2020_02, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="PQ-TLS-1-0-2020-12", .security_policy=&security_policy_pq_tls_1_0_2020_12, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+#endif
+ { .version="KMS-FIPS-TLS-1-2-2018-10", .security_policy=&security_policy_kms_fips_tls_1_2_2018_10, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="20140601", .security_policy=&security_policy_20140601, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="20141001", .security_policy=&security_policy_20141001, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="20150202", .security_policy=&security_policy_20150202, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="20150214", .security_policy=&security_policy_20150214, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="20150306", .security_policy=&security_policy_20150306, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="20160411", .security_policy=&security_policy_20160411, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="20160804", .security_policy=&security_policy_20160804, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="20160824", .security_policy=&security_policy_20160824, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="20170210", .security_policy=&security_policy_20170210, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="20170328", .security_policy=&security_policy_20170328, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="20190214", .security_policy=&security_policy_20190214, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="20170405", .security_policy=&security_policy_20170405, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="20170718", .security_policy=&security_policy_20170718, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="20190120", .security_policy=&security_policy_20190120, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="20190121", .security_policy=&security_policy_20190121, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="20190122", .security_policy=&security_policy_20190122, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="20190801", .security_policy=&security_policy_20190801, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="20190802", .security_policy=&security_policy_20190802, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="20200207", .security_policy=&security_policy_test_all_tls13, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="20201021", .security_policy=&security_policy_20201021, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="test_all", .security_policy=&security_policy_test_all, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="test_all_fips", .security_policy=&security_policy_test_all_fips, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="test_all_ecdsa", .security_policy=&security_policy_test_all_ecdsa, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="test_all_rsa_kex", .security_policy=&security_policy_test_all_rsa_kex, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="test_ecdsa_priority", .security_policy=&security_policy_test_ecdsa_priority, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="test_all_tls12", .security_policy=&security_policy_test_all_tls12, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="test_all_tls13", .security_policy=&security_policy_test_all_tls13, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="null", .security_policy=&security_policy_null, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version=NULL, .security_policy=NULL, .ecc_extension_required=0, .pq_kem_extension_required=0 }
+};
+
+int s2n_find_security_policy_from_version(const char *version, const struct s2n_security_policy **security_policy)
+{
+ notnull_check(version);
+ notnull_check(security_policy);
+
+ for (int i = 0; security_policy_selection[i].version != NULL; i++) {
+ if (!strcasecmp(version, security_policy_selection[i].version)) {
+ *security_policy = security_policy_selection[i].security_policy;
+ return 0;
+ }
+ }
+
+ S2N_ERROR(S2N_ERR_INVALID_SECURITY_POLICY);
+}
+
+int s2n_config_set_cipher_preferences(struct s2n_config *config, const char *version)
+{
+ const struct s2n_security_policy *security_policy = NULL;
+ GUARD(s2n_find_security_policy_from_version(version, &security_policy));
+ ENSURE_POSIX_REF(security_policy);
+ ENSURE_POSIX_REF(security_policy->cipher_preferences);
+ ENSURE_POSIX_REF(security_policy->kem_preferences);
+ ENSURE_POSIX_REF(security_policy->signature_preferences);
+ ENSURE_POSIX_REF(security_policy->ecc_preferences);
+
+ config->security_policy = security_policy;
+ return 0;
+}
+
+int s2n_connection_set_cipher_preferences(struct s2n_connection *conn, const char *version)
+{
+ const struct s2n_security_policy *security_policy = NULL;
+ GUARD(s2n_find_security_policy_from_version(version, &security_policy));
+ ENSURE_POSIX_REF(security_policy);
+ ENSURE_POSIX_REF(security_policy->cipher_preferences);
+ ENSURE_POSIX_REF(security_policy->kem_preferences);
+ ENSURE_POSIX_REF(security_policy->signature_preferences);
+ ENSURE_POSIX_REF(security_policy->ecc_preferences);
+
+ conn->security_policy_override = security_policy;
+ return 0;
+}
+
+int s2n_security_policies_init()
+{
+ for (int i = 0; security_policy_selection[i].version != NULL; i++) {
+ const struct s2n_security_policy *security_policy = security_policy_selection[i].security_policy;
+ notnull_check(security_policy);
+ const struct s2n_cipher_preferences *cipher_preference = security_policy->cipher_preferences;
+ notnull_check(cipher_preference);
+ const struct s2n_kem_preferences *kem_preference = security_policy->kem_preferences;
+ notnull_check(kem_preference);
+ const struct s2n_ecc_preferences *ecc_preference = security_policy->ecc_preferences;
+ notnull_check(ecc_preference);
+ GUARD(s2n_check_ecc_preferences_curves_list(ecc_preference));
+
+ const struct s2n_signature_preferences *certificate_signature_preference = security_policy->certificate_signature_preferences;
+ if (certificate_signature_preference != NULL) {
+ GUARD_AS_POSIX(s2n_validate_certificate_signature_preferences(certificate_signature_preference));
+ }
+
+ if (security_policy != &security_policy_null) {
+ /* catch any offending security policy that does not support P-256 */
+ S2N_ERROR_IF(!s2n_ecc_preferences_includes_curve(ecc_preference, TLS_EC_CURVE_SECP_256_R1), S2N_ERR_INVALID_SECURITY_POLICY);
+ }
+
+ for (int j = 0; j < cipher_preference->count; j++) {
+ struct s2n_cipher_suite *cipher = cipher_preference->suites[j];
+ notnull_check(cipher);
+
+ /* TLS1.3 does not include key exchange algorithms in its cipher suites,
+ * but the elliptic curves extension is always required. */
+ if (cipher->minimum_required_tls_version >= S2N_TLS13) {
+ security_policy_selection[i].ecc_extension_required = 1;
+ security_policy_selection[i].supports_tls13 = 1;
+ }
+
+ /* Sanity check that valid tls13 has minimum tls version set correctly */
+ S2N_ERROR_IF(s2n_is_valid_tls13_cipher(cipher->iana_value) ^
+ (cipher->minimum_required_tls_version >= S2N_TLS13), S2N_ERR_INVALID_SECURITY_POLICY);
+
+ if (s2n_kex_includes(cipher->key_exchange_alg, &s2n_ecdhe)) {
+ security_policy_selection[i].ecc_extension_required = 1;
+ }
+
+ if (s2n_kex_includes(cipher->key_exchange_alg, &s2n_kem)) {
+ security_policy_selection[i].pq_kem_extension_required = 1;
+ }
+ }
+
+ GUARD(s2n_validate_kem_preferences(kem_preference, security_policy_selection[i].pq_kem_extension_required));
+ }
+ return 0;
+}
+
+bool s2n_ecc_is_extension_required(const struct s2n_security_policy *security_policy)
+{
+ if (security_policy == NULL) {
+ return false;
+ }
+
+ for (int i = 0; security_policy_selection[i].version != NULL; i++) {
+ if (security_policy_selection[i].security_policy == security_policy) {
+ return 1 == security_policy_selection[i].ecc_extension_required;
+ }
+ }
+ return false;
+}
+
+bool s2n_pq_kem_is_extension_required(const struct s2n_security_policy *security_policy)
+{
+ if (security_policy == NULL) {
+ return false;
+ }
+
+ for (int i = 0; security_policy_selection[i].version != NULL; i++) {
+ if (security_policy_selection[i].security_policy == security_policy) {
+ return 1 == security_policy_selection[i].pq_kem_extension_required;
+ }
+ }
+ return false;
+}
+
+/* Checks whether cipher preference supports TLS 1.3 based on whether it is configured
+ * with TLS 1.3 ciphers. Returns true or false.
+ */
+bool s2n_security_policy_supports_tls13(const struct s2n_security_policy *security_policy)
+{
+ if (security_policy == NULL) {
+ return false;
+ }
+
+ for (uint8_t i = 0; security_policy_selection[i].version != NULL; i++) {
+ if (security_policy_selection[i].security_policy == security_policy) {
+ return security_policy_selection[i].supports_tls13 == 1;
+ }
+ }
+
+ /* if cipher preference is not in the official list, compute the result */
+ const struct s2n_cipher_preferences *cipher_preferences = security_policy->cipher_preferences;
+ if (cipher_preferences == NULL) {
+ return false;
+ }
+
+ for (uint8_t i = 0; i < cipher_preferences->count; i++) {
+ if (s2n_is_valid_tls13_cipher(cipher_preferences->suites[i]->iana_value)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+int s2n_connection_is_valid_for_cipher_preferences(struct s2n_connection *conn, const char *version)
+{
+ notnull_check(conn);
+ notnull_check(version);
+ notnull_check(conn->secure.cipher_suite);
+
+ const struct s2n_security_policy *security_policy = NULL;
+ GUARD(s2n_find_security_policy_from_version(version, &security_policy));
+ notnull_check(security_policy);
+
+ /* make sure we dont use a tls version lower than that configured by the version */
+ if (s2n_connection_get_actual_protocol_version(conn) < security_policy->minimum_protocol_version) {
+ return 0;
+ }
+
+ struct s2n_cipher_suite *cipher = conn->secure.cipher_suite;
+ notnull_check(cipher);
+ for (int i = 0; i < security_policy->cipher_preferences->count; ++i) {
+ if (0 == memcmp(security_policy->cipher_preferences->suites[i]->iana_value, cipher->iana_value, S2N_TLS_CIPHER_SUITE_LEN)) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int s2n_validate_kem_preferences(const struct s2n_kem_preferences *kem_preferences, bool pq_kem_extension_required) {
+ notnull_check(kem_preferences);
+
+ /* Basic sanity checks to assert that the count is 0 if and only if the associated list is NULL */
+ ENSURE_POSIX(S2N_IFF(kem_preferences->tls13_kem_group_count == 0, kem_preferences->tls13_kem_groups == NULL),
+ S2N_ERR_INVALID_SECURITY_POLICY);
+ ENSURE_POSIX(S2N_IFF(kem_preferences->kem_count == 0, kem_preferences->kems == NULL),
+ S2N_ERR_INVALID_SECURITY_POLICY);
+
+ /* The PQ KEM extension is applicable only to TLS 1.2 */
+ if (pq_kem_extension_required) {
+ ENSURE_POSIX(kem_preferences->kem_count > 0, S2N_ERR_INVALID_SECURITY_POLICY);
+ ENSURE_POSIX(kem_preferences->kems != NULL, S2N_ERR_INVALID_SECURITY_POLICY);
+ } else {
+ ENSURE_POSIX(kem_preferences->kem_count == 0, S2N_ERR_INVALID_SECURITY_POLICY);
+ ENSURE_POSIX(kem_preferences->kems == NULL, S2N_ERR_INVALID_SECURITY_POLICY);
+ }
+
+ return S2N_SUCCESS;
+}
+
+S2N_RESULT s2n_validate_certificate_signature_preferences(const struct s2n_signature_preferences *certificate_signature_preferences)
+{
+ ENSURE_REF(certificate_signature_preferences);
+
+ size_t rsa_pss_scheme_count = 0;
+
+ for (size_t i = 0; i < certificate_signature_preferences->count; i++) {
+ if (certificate_signature_preferences->signature_schemes[i]->libcrypto_nid == NID_rsassaPss) {
+ rsa_pss_scheme_count++;
+ }
+ }
+
+ /* The Openssl function used to parse signatures off certificates does not differentiate between any rsa pss
+ * signature schemes. Therefore a security policy with a certificate signatures preference list must include
+ * all rsa_pss signature schemes. */
+ ENSURE(rsa_pss_scheme_count == NUM_RSA_PSS_SCHEMES || rsa_pss_scheme_count == 0, S2N_ERR_INVALID_SECURITY_POLICY);
+ return S2N_RESULT_OK;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_security_policies.h b/contrib/restricted/aws/s2n/tls/s2n_security_policies.h
index d4ca93a220..ab71889ad7 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_security_policies.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_security_policies.h
@@ -1,118 +1,118 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <stdint.h>
-#include "tls/s2n_cipher_preferences.h"
-#include "tls/s2n_kem_preferences.h"
-#include "tls/s2n_signature_scheme.h"
-#include "tls/s2n_ecc_preferences.h"
-
-/* Kept up-to-date by s2n_security_policies_test */
-#define NUM_RSA_PSS_SCHEMES 6
-
-struct s2n_security_policy {
- uint8_t minimum_protocol_version;
- const struct s2n_cipher_preferences *cipher_preferences;
- const struct s2n_kem_preferences *kem_preferences;
- const struct s2n_signature_preferences *signature_preferences;
- const struct s2n_signature_preferences *certificate_signature_preferences;
- const struct s2n_ecc_preferences *ecc_preferences;
-};
-
-struct s2n_security_policy_selection {
- const char *version;
- const struct s2n_security_policy *security_policy;
- unsigned ecc_extension_required:1;
- unsigned pq_kem_extension_required:1;
- unsigned supports_tls13:1;
-};
-
-extern struct s2n_security_policy_selection security_policy_selection[];
-
-extern const struct s2n_security_policy security_policy_20140601;
-extern const struct s2n_security_policy security_policy_20141001;
-extern const struct s2n_security_policy security_policy_20150202;
-extern const struct s2n_security_policy security_policy_20150214;
-extern const struct s2n_security_policy security_policy_20150306;
-extern const struct s2n_security_policy security_policy_20160411;
-extern const struct s2n_security_policy security_policy_20160804;
-extern const struct s2n_security_policy security_policy_20160824;
-extern const struct s2n_security_policy security_policy_20170210;
-extern const struct s2n_security_policy security_policy_20170328;
-extern const struct s2n_security_policy security_policy_20170405;
-extern const struct s2n_security_policy security_policy_20170718;
-extern const struct s2n_security_policy security_policy_20190214;
-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_20201110;
-extern const struct s2n_security_policy security_policy_test_all;
-
-extern const struct s2n_security_policy security_policy_test_all_tls12;
-extern const struct s2n_security_policy security_policy_test_all_fips;
-extern const struct s2n_security_policy security_policy_test_all_ecdsa;
-extern const struct s2n_security_policy security_policy_test_ecdsa_priority;
-extern const struct s2n_security_policy security_policy_test_all_rsa_kex;
-extern const struct s2n_security_policy security_policy_test_all_tls13;
-
-/* See https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html */
-extern const struct s2n_security_policy security_policy_elb_2015_04;
-extern const struct s2n_security_policy security_policy_elb_2016_08;
-extern const struct s2n_security_policy security_policy_elb_tls_1_2_2017_01;
-extern const struct s2n_security_policy security_policy_elb_tls_1_1_2017_01;
-extern const struct s2n_security_policy security_policy_elb_tls_1_2_ext_2018_06;
-extern const struct s2n_security_policy security_policy_elb_fs_2018_06;
-extern const struct s2n_security_policy security_policy_elb_fs_1_2_2019_08;
-extern const struct s2n_security_policy security_policy_elb_fs_1_1_2019_08;
-extern const struct s2n_security_policy security_policy_elb_fs_1_2_res_2019_08;
-
-#if !defined(S2N_NO_PQ)
-extern const struct s2n_security_policy security_policy_kms_pq_tls_1_0_2019_06;
-extern const struct s2n_security_policy security_policy_kms_pq_tls_1_0_2020_02;
-extern const struct s2n_security_policy security_policy_kms_pq_tls_1_0_2020_07;
-extern const struct s2n_security_policy security_policy_pq_sike_test_tls_1_0_2019_11;
-extern const struct s2n_security_policy security_policy_pq_sike_test_tls_1_0_2020_02;
-extern const struct s2n_security_policy security_policy_pq_tls_1_0_2020_12;
-#endif
-
-extern const struct s2n_security_policy security_policy_cloudfront_upstream;
-extern const struct s2n_security_policy security_policy_cloudfront_upstream_tls10;
-extern const struct s2n_security_policy security_policy_cloudfront_upstream_tls12;
-extern const struct s2n_security_policy security_policy_cloudfront_ssl_v_3;
-extern const struct s2n_security_policy security_policy_cloudfront_tls_1_0_2014;
-extern const struct s2n_security_policy security_policy_cloudfront_tls_1_0_2016;
-extern const struct s2n_security_policy security_policy_cloudfront_tls_1_1_2016;
-extern const struct s2n_security_policy security_policy_cloudfront_tls_1_2_2018;
-extern const struct s2n_security_policy security_policy_cloudfront_tls_1_2_2019;
-
-extern const struct s2n_security_policy security_policy_kms_tls_1_0_2018_10;
-extern const struct s2n_security_policy security_policy_kms_fips_tls_1_2_2018_10;
-
-extern const struct s2n_security_policy security_policy_20190120;
-extern const struct s2n_security_policy security_policy_20190121;
-extern const struct s2n_security_policy security_policy_20190122;
-
-extern const struct s2n_security_policy security_policy_null;
-
-int s2n_security_policies_init();
-int s2n_config_set_cipher_preferences(struct s2n_config *config, const char *version);
-int s2n_connection_set_cipher_preferences(struct s2n_connection *conn, const char *version);
-bool s2n_ecc_is_extension_required(const struct s2n_security_policy *security_policy);
-bool s2n_pq_kem_is_extension_required(const struct s2n_security_policy *security_policy);
-bool s2n_security_policy_supports_tls13(const struct s2n_security_policy *security_policy);
-int s2n_find_security_policy_from_version(const char *version, const struct s2n_security_policy **security_policy);
-int s2n_validate_kem_preferences(const struct s2n_kem_preferences *kem_preferences, bool pq_kem_extension_required);
-S2N_RESULT s2n_validate_certificate_signature_preferences(const struct s2n_signature_preferences *s2n_certificate_signature_preferences);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include "tls/s2n_cipher_preferences.h"
+#include "tls/s2n_kem_preferences.h"
+#include "tls/s2n_signature_scheme.h"
+#include "tls/s2n_ecc_preferences.h"
+
+/* Kept up-to-date by s2n_security_policies_test */
+#define NUM_RSA_PSS_SCHEMES 6
+
+struct s2n_security_policy {
+ uint8_t minimum_protocol_version;
+ const struct s2n_cipher_preferences *cipher_preferences;
+ const struct s2n_kem_preferences *kem_preferences;
+ const struct s2n_signature_preferences *signature_preferences;
+ const struct s2n_signature_preferences *certificate_signature_preferences;
+ const struct s2n_ecc_preferences *ecc_preferences;
+};
+
+struct s2n_security_policy_selection {
+ const char *version;
+ const struct s2n_security_policy *security_policy;
+ unsigned ecc_extension_required:1;
+ unsigned pq_kem_extension_required:1;
+ unsigned supports_tls13:1;
+};
+
+extern struct s2n_security_policy_selection security_policy_selection[];
+
+extern const struct s2n_security_policy security_policy_20140601;
+extern const struct s2n_security_policy security_policy_20141001;
+extern const struct s2n_security_policy security_policy_20150202;
+extern const struct s2n_security_policy security_policy_20150214;
+extern const struct s2n_security_policy security_policy_20150306;
+extern const struct s2n_security_policy security_policy_20160411;
+extern const struct s2n_security_policy security_policy_20160804;
+extern const struct s2n_security_policy security_policy_20160824;
+extern const struct s2n_security_policy security_policy_20170210;
+extern const struct s2n_security_policy security_policy_20170328;
+extern const struct s2n_security_policy security_policy_20170405;
+extern const struct s2n_security_policy security_policy_20170718;
+extern const struct s2n_security_policy security_policy_20190214;
+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_20201110;
+extern const struct s2n_security_policy security_policy_test_all;
+
+extern const struct s2n_security_policy security_policy_test_all_tls12;
+extern const struct s2n_security_policy security_policy_test_all_fips;
+extern const struct s2n_security_policy security_policy_test_all_ecdsa;
+extern const struct s2n_security_policy security_policy_test_ecdsa_priority;
+extern const struct s2n_security_policy security_policy_test_all_rsa_kex;
+extern const struct s2n_security_policy security_policy_test_all_tls13;
+
+/* See https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html */
+extern const struct s2n_security_policy security_policy_elb_2015_04;
+extern const struct s2n_security_policy security_policy_elb_2016_08;
+extern const struct s2n_security_policy security_policy_elb_tls_1_2_2017_01;
+extern const struct s2n_security_policy security_policy_elb_tls_1_1_2017_01;
+extern const struct s2n_security_policy security_policy_elb_tls_1_2_ext_2018_06;
+extern const struct s2n_security_policy security_policy_elb_fs_2018_06;
+extern const struct s2n_security_policy security_policy_elb_fs_1_2_2019_08;
+extern const struct s2n_security_policy security_policy_elb_fs_1_1_2019_08;
+extern const struct s2n_security_policy security_policy_elb_fs_1_2_res_2019_08;
+
+#if !defined(S2N_NO_PQ)
+extern const struct s2n_security_policy security_policy_kms_pq_tls_1_0_2019_06;
+extern const struct s2n_security_policy security_policy_kms_pq_tls_1_0_2020_02;
+extern const struct s2n_security_policy security_policy_kms_pq_tls_1_0_2020_07;
+extern const struct s2n_security_policy security_policy_pq_sike_test_tls_1_0_2019_11;
+extern const struct s2n_security_policy security_policy_pq_sike_test_tls_1_0_2020_02;
+extern const struct s2n_security_policy security_policy_pq_tls_1_0_2020_12;
+#endif
+
+extern const struct s2n_security_policy security_policy_cloudfront_upstream;
+extern const struct s2n_security_policy security_policy_cloudfront_upstream_tls10;
+extern const struct s2n_security_policy security_policy_cloudfront_upstream_tls12;
+extern const struct s2n_security_policy security_policy_cloudfront_ssl_v_3;
+extern const struct s2n_security_policy security_policy_cloudfront_tls_1_0_2014;
+extern const struct s2n_security_policy security_policy_cloudfront_tls_1_0_2016;
+extern const struct s2n_security_policy security_policy_cloudfront_tls_1_1_2016;
+extern const struct s2n_security_policy security_policy_cloudfront_tls_1_2_2018;
+extern const struct s2n_security_policy security_policy_cloudfront_tls_1_2_2019;
+
+extern const struct s2n_security_policy security_policy_kms_tls_1_0_2018_10;
+extern const struct s2n_security_policy security_policy_kms_fips_tls_1_2_2018_10;
+
+extern const struct s2n_security_policy security_policy_20190120;
+extern const struct s2n_security_policy security_policy_20190121;
+extern const struct s2n_security_policy security_policy_20190122;
+
+extern const struct s2n_security_policy security_policy_null;
+
+int s2n_security_policies_init();
+int s2n_config_set_cipher_preferences(struct s2n_config *config, const char *version);
+int s2n_connection_set_cipher_preferences(struct s2n_connection *conn, const char *version);
+bool s2n_ecc_is_extension_required(const struct s2n_security_policy *security_policy);
+bool s2n_pq_kem_is_extension_required(const struct s2n_security_policy *security_policy);
+bool s2n_security_policy_supports_tls13(const struct s2n_security_policy *security_policy);
+int s2n_find_security_policy_from_version(const char *version, const struct s2n_security_policy **security_policy);
+int s2n_validate_kem_preferences(const struct s2n_kem_preferences *kem_preferences, bool pq_kem_extension_required);
+S2N_RESULT s2n_validate_certificate_signature_preferences(const struct s2n_signature_preferences *s2n_certificate_signature_preferences);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_send.c b/contrib/restricted/aws/s2n/tls/s2n_send.c
index 47551d7af6..c9f9cf89d6 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_send.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_send.c
@@ -1,217 +1,217 @@
-/*
- * 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 <sys/param.h>
-#include <errno.h>
-#include <s2n.h>
-
-#include "error/s2n_errno.h"
-
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_handshake.h"
-#include "tls/s2n_post_handshake.h"
-#include "tls/s2n_record.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "crypto/s2n_cipher.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_blob.h"
-
-int s2n_flush(struct s2n_connection *conn, s2n_blocked_status * blocked)
-{
- int w;
-
- *blocked = S2N_BLOCKED_ON_WRITE;
-
- /* Write any data that's already pending */
- WRITE:
- while (s2n_stuffer_data_available(&conn->out)) {
- errno = 0;
- w = s2n_connection_send_stuffer(&conn->out, conn, s2n_stuffer_data_available(&conn->out));
- if (w < 0) {
- if (errno == EWOULDBLOCK || errno == EAGAIN) {
- S2N_ERROR(S2N_ERR_IO_BLOCKED);
- }
- S2N_ERROR(S2N_ERR_IO);
- }
- conn->wire_bytes_out += w;
- }
-
- if (conn->closing) {
- conn->closed = 1;
- }
- GUARD(s2n_stuffer_rewrite(&conn->out));
-
- /* If there's an alert pending out, send that */
- if (s2n_stuffer_data_available(&conn->reader_alert_out) == 2) {
- struct s2n_blob alert = {0};
- alert.data = conn->reader_alert_out.blob.data;
- alert.size = 2;
- GUARD(s2n_record_write(conn, TLS_ALERT, &alert));
- GUARD(s2n_stuffer_rewrite(&conn->reader_alert_out));
- conn->closing = 1;
-
- /* Actually write it ... */
- goto WRITE;
- }
-
- /* Do the same for writer driven alerts */
- if (s2n_stuffer_data_available(&conn->writer_alert_out) == 2) {
- struct s2n_blob alert = {0};
- alert.data = conn->writer_alert_out.blob.data;
- alert.size = 2;
- GUARD(s2n_record_write(conn, TLS_ALERT, &alert));
- GUARD(s2n_stuffer_rewrite(&conn->writer_alert_out));
- conn->closing = 1;
-
- /* Actually write it ... */
- goto WRITE;
- }
-
- *blocked = S2N_NOT_BLOCKED;
-
- return 0;
-}
-
-ssize_t s2n_sendv_with_offset(struct s2n_connection *conn, const struct iovec *bufs, ssize_t count, ssize_t offs, s2n_blocked_status *blocked)
-{
- ssize_t user_data_sent, total_size = 0;
-
- S2N_ERROR_IF(conn->closed, S2N_ERR_CLOSED);
- S2N_ERROR_IF(conn->config->quic_enabled, S2N_ERR_UNSUPPORTED_WITH_QUIC);
-
- /* Flush any pending I/O */
- GUARD(s2n_flush(conn, blocked));
-
- /* Acknowledge consumed and flushed user data as sent */
- user_data_sent = conn->current_user_data_consumed;
-
- *blocked = S2N_BLOCKED_ON_WRITE;
-
- uint16_t max_payload_size = 0;
- GUARD_AS_POSIX(s2n_record_max_write_payload_size(conn, &max_payload_size));
-
- /* TLS 1.0 and SSLv3 are vulnerable to the so-called Beast attack. Work
- * around this by splitting messages into one byte records, and then
- * the remainder can follow as usual.
- */
- int cbcHackUsed = 0;
-
- struct s2n_crypto_parameters *writer = conn->server;
- if (conn->mode == S2N_CLIENT) {
- writer = conn->client;
- }
-
- /* Defensive check against an invalid retry */
- if (offs) {
- const struct iovec* _bufs = bufs;
- ssize_t _count = count;
- while (offs >= _bufs->iov_len && _count > 0) {
- offs -= _bufs->iov_len;
- _bufs++;
- _count--;
- }
- bufs = _bufs;
- count = _count;
- }
- for (int i = 0; i < count; i++) {
- total_size += bufs[i].iov_len;
- }
- total_size -= offs;
- S2N_ERROR_IF(conn->current_user_data_consumed > total_size, S2N_ERR_SEND_SIZE);
-
- if (conn->dynamic_record_timeout_threshold > 0) {
- uint64_t elapsed;
- GUARD_AS_POSIX(s2n_timer_elapsed(conn->config, &conn->write_timer, &elapsed));
- /* Reset record size back to a single segment after threshold seconds of inactivity */
- if (elapsed - conn->last_write_elapsed > (uint64_t) conn->dynamic_record_timeout_threshold * 1000000000) {
- conn->active_application_bytes_consumed = 0;
- }
- conn->last_write_elapsed = elapsed;
- }
-
- /* Now write the data we were asked to send this round */
- while (total_size - conn->current_user_data_consumed) {
- ssize_t to_write = MIN(total_size - conn->current_user_data_consumed, max_payload_size);
-
- /* If dynamic record size is enabled,
- * use small TLS records that fit into a single TCP segment for the threshold bytes of data
- */
- if (conn->active_application_bytes_consumed < (uint64_t) conn->dynamic_record_resize_threshold) {
- uint16_t min_payload_size = 0;
- GUARD_AS_POSIX(s2n_record_min_write_payload_size(conn, &min_payload_size));
- to_write = MIN(min_payload_size, to_write);
- }
-
- /* Don't split messages in server mode for interoperability with naive clients.
- * Some clients may have expectations based on the amount of content in the first record.
- */
- if (conn->actual_protocol_version < S2N_TLS11 && writer->cipher_suite->record_alg->cipher->type == S2N_CBC && conn->mode != S2N_SERVER) {
- if (to_write > 1 && cbcHackUsed == 0) {
- to_write = 1;
- cbcHackUsed = 1;
- }
- }
-
- GUARD(s2n_stuffer_rewrite(&conn->out));
-
- GUARD(s2n_post_handshake_send(conn, blocked));
-
- /* Write and encrypt the record */
- GUARD(s2n_record_writev(conn, TLS_APPLICATION_DATA, bufs, count,
- conn->current_user_data_consumed + offs, to_write));
- conn->current_user_data_consumed += to_write;
- conn->active_application_bytes_consumed += to_write;
-
- /* Send it */
- if (s2n_flush(conn, blocked) < 0) {
- if (s2n_errno == S2N_ERR_IO_BLOCKED && user_data_sent > 0) {
- /* We successfully sent >0 user bytes on the wire, but not the full requested payload
- * because we became blocked on I/O. Acknowledge the data sent. */
-
- conn->current_user_data_consumed -= user_data_sent;
- return user_data_sent;
- } else {
- S2N_ERROR_PRESERVE_ERRNO();
- }
- }
-
- /* Acknowledge consumed and flushed user data as sent */
- user_data_sent = conn->current_user_data_consumed;
- }
-
- /* If everything has been written, then there's no user data pending */
- conn->current_user_data_consumed = 0;
-
- *blocked = S2N_NOT_BLOCKED;
-
- return total_size;
-}
-
-ssize_t s2n_sendv(struct s2n_connection *conn, const struct iovec *bufs, ssize_t count, s2n_blocked_status *blocked)
-{
- return s2n_sendv_with_offset(conn, bufs, count, 0, blocked);
-}
-
-ssize_t s2n_send(struct s2n_connection *conn, const void *buf, ssize_t size, s2n_blocked_status *blocked)
-{
- struct iovec iov;
- iov.iov_base = (void*)(uintptr_t)buf;
- iov.iov_len = size;
- return s2n_sendv_with_offset(conn, &iov, 1, 0, blocked);
-}
+/*
+ * 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 <sys/param.h>
+#include <errno.h>
+#include <s2n.h>
+
+#include "error/s2n_errno.h"
+
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_handshake.h"
+#include "tls/s2n_post_handshake.h"
+#include "tls/s2n_record.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "crypto/s2n_cipher.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_blob.h"
+
+int s2n_flush(struct s2n_connection *conn, s2n_blocked_status * blocked)
+{
+ int w;
+
+ *blocked = S2N_BLOCKED_ON_WRITE;
+
+ /* Write any data that's already pending */
+ WRITE:
+ while (s2n_stuffer_data_available(&conn->out)) {
+ errno = 0;
+ w = s2n_connection_send_stuffer(&conn->out, conn, s2n_stuffer_data_available(&conn->out));
+ if (w < 0) {
+ if (errno == EWOULDBLOCK || errno == EAGAIN) {
+ S2N_ERROR(S2N_ERR_IO_BLOCKED);
+ }
+ S2N_ERROR(S2N_ERR_IO);
+ }
+ conn->wire_bytes_out += w;
+ }
+
+ if (conn->closing) {
+ conn->closed = 1;
+ }
+ GUARD(s2n_stuffer_rewrite(&conn->out));
+
+ /* If there's an alert pending out, send that */
+ if (s2n_stuffer_data_available(&conn->reader_alert_out) == 2) {
+ struct s2n_blob alert = {0};
+ alert.data = conn->reader_alert_out.blob.data;
+ alert.size = 2;
+ GUARD(s2n_record_write(conn, TLS_ALERT, &alert));
+ GUARD(s2n_stuffer_rewrite(&conn->reader_alert_out));
+ conn->closing = 1;
+
+ /* Actually write it ... */
+ goto WRITE;
+ }
+
+ /* Do the same for writer driven alerts */
+ if (s2n_stuffer_data_available(&conn->writer_alert_out) == 2) {
+ struct s2n_blob alert = {0};
+ alert.data = conn->writer_alert_out.blob.data;
+ alert.size = 2;
+ GUARD(s2n_record_write(conn, TLS_ALERT, &alert));
+ GUARD(s2n_stuffer_rewrite(&conn->writer_alert_out));
+ conn->closing = 1;
+
+ /* Actually write it ... */
+ goto WRITE;
+ }
+
+ *blocked = S2N_NOT_BLOCKED;
+
+ return 0;
+}
+
+ssize_t s2n_sendv_with_offset(struct s2n_connection *conn, const struct iovec *bufs, ssize_t count, ssize_t offs, s2n_blocked_status *blocked)
+{
+ ssize_t user_data_sent, total_size = 0;
+
+ S2N_ERROR_IF(conn->closed, S2N_ERR_CLOSED);
+ S2N_ERROR_IF(conn->config->quic_enabled, S2N_ERR_UNSUPPORTED_WITH_QUIC);
+
+ /* Flush any pending I/O */
+ GUARD(s2n_flush(conn, blocked));
+
+ /* Acknowledge consumed and flushed user data as sent */
+ user_data_sent = conn->current_user_data_consumed;
+
+ *blocked = S2N_BLOCKED_ON_WRITE;
+
+ uint16_t max_payload_size = 0;
+ GUARD_AS_POSIX(s2n_record_max_write_payload_size(conn, &max_payload_size));
+
+ /* TLS 1.0 and SSLv3 are vulnerable to the so-called Beast attack. Work
+ * around this by splitting messages into one byte records, and then
+ * the remainder can follow as usual.
+ */
+ int cbcHackUsed = 0;
+
+ struct s2n_crypto_parameters *writer = conn->server;
+ if (conn->mode == S2N_CLIENT) {
+ writer = conn->client;
+ }
+
+ /* Defensive check against an invalid retry */
+ if (offs) {
+ const struct iovec* _bufs = bufs;
+ ssize_t _count = count;
+ while (offs >= _bufs->iov_len && _count > 0) {
+ offs -= _bufs->iov_len;
+ _bufs++;
+ _count--;
+ }
+ bufs = _bufs;
+ count = _count;
+ }
+ for (int i = 0; i < count; i++) {
+ total_size += bufs[i].iov_len;
+ }
+ total_size -= offs;
+ S2N_ERROR_IF(conn->current_user_data_consumed > total_size, S2N_ERR_SEND_SIZE);
+
+ if (conn->dynamic_record_timeout_threshold > 0) {
+ uint64_t elapsed;
+ GUARD_AS_POSIX(s2n_timer_elapsed(conn->config, &conn->write_timer, &elapsed));
+ /* Reset record size back to a single segment after threshold seconds of inactivity */
+ if (elapsed - conn->last_write_elapsed > (uint64_t) conn->dynamic_record_timeout_threshold * 1000000000) {
+ conn->active_application_bytes_consumed = 0;
+ }
+ conn->last_write_elapsed = elapsed;
+ }
+
+ /* Now write the data we were asked to send this round */
+ while (total_size - conn->current_user_data_consumed) {
+ ssize_t to_write = MIN(total_size - conn->current_user_data_consumed, max_payload_size);
+
+ /* If dynamic record size is enabled,
+ * use small TLS records that fit into a single TCP segment for the threshold bytes of data
+ */
+ if (conn->active_application_bytes_consumed < (uint64_t) conn->dynamic_record_resize_threshold) {
+ uint16_t min_payload_size = 0;
+ GUARD_AS_POSIX(s2n_record_min_write_payload_size(conn, &min_payload_size));
+ to_write = MIN(min_payload_size, to_write);
+ }
+
+ /* Don't split messages in server mode for interoperability with naive clients.
+ * Some clients may have expectations based on the amount of content in the first record.
+ */
+ if (conn->actual_protocol_version < S2N_TLS11 && writer->cipher_suite->record_alg->cipher->type == S2N_CBC && conn->mode != S2N_SERVER) {
+ if (to_write > 1 && cbcHackUsed == 0) {
+ to_write = 1;
+ cbcHackUsed = 1;
+ }
+ }
+
+ GUARD(s2n_stuffer_rewrite(&conn->out));
+
+ GUARD(s2n_post_handshake_send(conn, blocked));
+
+ /* Write and encrypt the record */
+ GUARD(s2n_record_writev(conn, TLS_APPLICATION_DATA, bufs, count,
+ conn->current_user_data_consumed + offs, to_write));
+ conn->current_user_data_consumed += to_write;
+ conn->active_application_bytes_consumed += to_write;
+
+ /* Send it */
+ if (s2n_flush(conn, blocked) < 0) {
+ if (s2n_errno == S2N_ERR_IO_BLOCKED && user_data_sent > 0) {
+ /* We successfully sent >0 user bytes on the wire, but not the full requested payload
+ * because we became blocked on I/O. Acknowledge the data sent. */
+
+ conn->current_user_data_consumed -= user_data_sent;
+ return user_data_sent;
+ } else {
+ S2N_ERROR_PRESERVE_ERRNO();
+ }
+ }
+
+ /* Acknowledge consumed and flushed user data as sent */
+ user_data_sent = conn->current_user_data_consumed;
+ }
+
+ /* If everything has been written, then there's no user data pending */
+ conn->current_user_data_consumed = 0;
+
+ *blocked = S2N_NOT_BLOCKED;
+
+ return total_size;
+}
+
+ssize_t s2n_sendv(struct s2n_connection *conn, const struct iovec *bufs, ssize_t count, s2n_blocked_status *blocked)
+{
+ return s2n_sendv_with_offset(conn, bufs, count, 0, blocked);
+}
+
+ssize_t s2n_send(struct s2n_connection *conn, const void *buf, ssize_t size, s2n_blocked_status *blocked)
+{
+ struct iovec iov;
+ iov.iov_base = (void*)(uintptr_t)buf;
+ iov.iov_len = size;
+ return s2n_sendv_with_offset(conn, &iov, 1, 0, blocked);
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_server_cert.c b/contrib/restricted/aws/s2n/tls/s2n_server_cert.c
index cd50e5acd6..0188505ae1 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_server_cert.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_server_cert.c
@@ -1,71 +1,71 @@
-/*
- * 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 <s2n.h>
-
-#include "error/s2n_errno.h"
-
-#include "tls/s2n_auth_selection.h"
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_tls.h"
-
-#include "utils/s2n_safety.h"
-
-int s2n_server_cert_recv(struct s2n_connection *conn)
-{
- if (conn->actual_protocol_version == S2N_TLS13) {
- uint8_t certificate_request_context_len;
- GUARD(s2n_stuffer_read_uint8(&conn->handshake.io, &certificate_request_context_len));
- S2N_ERROR_IF(certificate_request_context_len != 0, S2N_ERR_BAD_MESSAGE);
- }
-
- uint32_t size_of_all_certificates;
- GUARD(s2n_stuffer_read_uint24(&conn->handshake.io, &size_of_all_certificates));
-
- S2N_ERROR_IF(size_of_all_certificates > s2n_stuffer_data_available(&conn->handshake.io) || size_of_all_certificates < 3, S2N_ERR_BAD_MESSAGE);
-
- s2n_cert_public_key public_key;
- GUARD(s2n_pkey_zero_init(&public_key));
-
- s2n_pkey_type actual_cert_pkey_type;
- struct s2n_blob cert_chain = {0};
- cert_chain.size = size_of_all_certificates;
- cert_chain.data = s2n_stuffer_raw_read(&conn->handshake.io, size_of_all_certificates);
- notnull_check(cert_chain.data);
-
- GUARD(s2n_x509_validator_validate_cert_chain(&conn->x509_validator, conn, cert_chain.data,
- cert_chain.size, &actual_cert_pkey_type, &public_key));
-
- GUARD(s2n_is_cert_type_valid_for_auth(conn, actual_cert_pkey_type));
- GUARD(s2n_pkey_setup_for_type(&public_key, actual_cert_pkey_type));
- conn->secure.server_public_key = public_key;
-
- return 0;
-}
-
-int s2n_server_cert_send(struct s2n_connection *conn)
-{
- S2N_ERROR_IF(conn->handshake_params.our_chain_and_key == NULL, S2N_ERR_CERT_TYPE_UNSUPPORTED);
- if (conn->actual_protocol_version == S2N_TLS13) {
- /* server's certificate request context should always be of zero length */
- /* https://tools.ietf.org/html/rfc8446#section-4.4.2 */
- uint8_t certificate_request_context_len = 0;
- GUARD(s2n_stuffer_write_uint8(&conn->handshake.io, certificate_request_context_len));
- }
-
- GUARD(s2n_send_cert_chain(conn, &conn->handshake.io, conn->handshake_params.our_chain_and_key));
-
- return 0;
-}
+/*
+ * 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 <s2n.h>
+
+#include "error/s2n_errno.h"
+
+#include "tls/s2n_auth_selection.h"
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_tls.h"
+
+#include "utils/s2n_safety.h"
+
+int s2n_server_cert_recv(struct s2n_connection *conn)
+{
+ if (conn->actual_protocol_version == S2N_TLS13) {
+ uint8_t certificate_request_context_len;
+ GUARD(s2n_stuffer_read_uint8(&conn->handshake.io, &certificate_request_context_len));
+ S2N_ERROR_IF(certificate_request_context_len != 0, S2N_ERR_BAD_MESSAGE);
+ }
+
+ uint32_t size_of_all_certificates;
+ GUARD(s2n_stuffer_read_uint24(&conn->handshake.io, &size_of_all_certificates));
+
+ S2N_ERROR_IF(size_of_all_certificates > s2n_stuffer_data_available(&conn->handshake.io) || size_of_all_certificates < 3, S2N_ERR_BAD_MESSAGE);
+
+ s2n_cert_public_key public_key;
+ GUARD(s2n_pkey_zero_init(&public_key));
+
+ s2n_pkey_type actual_cert_pkey_type;
+ struct s2n_blob cert_chain = {0};
+ cert_chain.size = size_of_all_certificates;
+ cert_chain.data = s2n_stuffer_raw_read(&conn->handshake.io, size_of_all_certificates);
+ notnull_check(cert_chain.data);
+
+ GUARD(s2n_x509_validator_validate_cert_chain(&conn->x509_validator, conn, cert_chain.data,
+ cert_chain.size, &actual_cert_pkey_type, &public_key));
+
+ GUARD(s2n_is_cert_type_valid_for_auth(conn, actual_cert_pkey_type));
+ GUARD(s2n_pkey_setup_for_type(&public_key, actual_cert_pkey_type));
+ conn->secure.server_public_key = public_key;
+
+ return 0;
+}
+
+int s2n_server_cert_send(struct s2n_connection *conn)
+{
+ S2N_ERROR_IF(conn->handshake_params.our_chain_and_key == NULL, S2N_ERR_CERT_TYPE_UNSUPPORTED);
+ if (conn->actual_protocol_version == S2N_TLS13) {
+ /* server's certificate request context should always be of zero length */
+ /* https://tools.ietf.org/html/rfc8446#section-4.4.2 */
+ uint8_t certificate_request_context_len = 0;
+ GUARD(s2n_stuffer_write_uint8(&conn->handshake.io, certificate_request_context_len));
+ }
+
+ GUARD(s2n_send_cert_chain(conn, &conn->handshake.io, conn->handshake_params.our_chain_and_key));
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_server_cert_request.c b/contrib/restricted/aws/s2n/tls/s2n_server_cert_request.c
index 92b591890d..26dcecc56c 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_server_cert_request.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_server_cert_request.c
@@ -1,197 +1,197 @@
-/*
- * 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 <s2n.h>
-
-#include "crypto/s2n_certificate.h"
-#include "error/s2n_errno.h"
-#include "extensions/s2n_extension_list.h"
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_config.h"
-#include "tls/s2n_signature_algorithms.h"
-#include "tls/s2n_signature_scheme.h"
-#include "tls/s2n_tls.h"
-#include "stuffer/s2n_stuffer.h"
-#include "utils/s2n_safety.h"
-#include "utils/s2n_array.h"
-
-/* RFC's that define below values:
- * - https://tools.ietf.org/html/rfc5246#section-7.4.4
- * - https://tools.ietf.org/search/rfc4492#section-5.5
- */
-typedef enum {
- S2N_CERT_TYPE_RSA_SIGN = 1,
- S2N_CERT_TYPE_DSS_SIGN = 2,
- S2N_CERT_TYPE_RSA_FIXED_DH = 3,
- S2N_CERT_TYPE_DSS_FIXED_DH = 4,
- S2N_CERT_TYPE_RSA_EPHEMERAL_DH_RESERVED = 5,
- S2N_CERT_TYPE_DSS_EPHEMERAL_DH_RESERVED = 6,
- S2N_CERT_TYPE_FORTEZZA_DMS_RESERVED = 20,
- S2N_CERT_TYPE_ECDSA_SIGN = 64,
- S2N_CERT_TYPE_RSA_FIXED_ECDH = 65,
- S2N_CERT_TYPE_ECDSA_FIXED_ECDH = 66,
-} s2n_cert_type;
-
-static uint8_t s2n_cert_type_preference_list[] = {
- S2N_CERT_TYPE_RSA_SIGN,
- S2N_CERT_TYPE_ECDSA_SIGN
-};
-
-/*
- * Include DSS sign certificate type in server certificate request.
- * Only will be used if cert_req_dss_legacy_compat_enabled is set by calling s2n_config_enable_cert_req_dss_legacy_compat.
- */
-static uint8_t s2n_cert_type_preference_list_legacy_dss[] = {
- S2N_CERT_TYPE_RSA_SIGN,
- S2N_CERT_TYPE_DSS_SIGN,
- S2N_CERT_TYPE_ECDSA_SIGN
-};
-
-static int s2n_cert_type_to_pkey_type(s2n_cert_type cert_type_in, s2n_pkey_type *pkey_type_out) {
- switch(cert_type_in) {
- case S2N_CERT_TYPE_RSA_SIGN:
- *pkey_type_out = S2N_PKEY_TYPE_RSA;
- return 0;
- case S2N_CERT_TYPE_ECDSA_SIGN:
- *pkey_type_out = S2N_PKEY_TYPE_ECDSA;
- return 0;
- default:
- S2N_ERROR(S2N_CERT_ERR_TYPE_UNSUPPORTED);
- }
-}
-
-static int s2n_recv_client_cert_preferences(struct s2n_stuffer *in, s2n_cert_type *chosen_cert_type_out)
-{
- uint8_t cert_types_len;
- GUARD(s2n_stuffer_read_uint8(in, &cert_types_len));
-
- uint8_t *their_cert_type_pref_list = s2n_stuffer_raw_read(in, cert_types_len);
- notnull_check(their_cert_type_pref_list);
-
- /* Iterate through our preference list from most to least preferred, and return the first match that we find. */
- for (int our_cert_pref_idx = 0; our_cert_pref_idx < sizeof(s2n_cert_type_preference_list); our_cert_pref_idx++) {
- for (int their_cert_idx = 0; their_cert_idx < cert_types_len; their_cert_idx++) {
- if (their_cert_type_pref_list[their_cert_idx] == s2n_cert_type_preference_list[our_cert_pref_idx]) {
- *chosen_cert_type_out = s2n_cert_type_preference_list[our_cert_pref_idx];
- return 0;
- }
- }
- }
-
- S2N_ERROR(S2N_ERR_CERT_TYPE_UNSUPPORTED);
-}
-
-static int s2n_set_cert_chain_as_client(struct s2n_connection *conn)
-{
- if (s2n_config_get_num_default_certs(conn->config) > 0) {
- GUARD(s2n_choose_sig_scheme_from_peer_preference_list(conn, &conn->handshake_params.server_sig_hash_algs,
- &conn->secure.client_cert_sig_scheme));
-
- struct s2n_cert_chain_and_key *cert = s2n_config_get_single_default_cert(conn->config);
- notnull_check(cert);
- conn->handshake_params.our_chain_and_key = cert;
- }
-
- return 0;
-}
-
-int s2n_tls13_cert_req_recv(struct s2n_connection *conn)
-{
- struct s2n_stuffer *in = &conn->handshake.io;
-
- /* read request context length */
- uint8_t request_context_length;
- GUARD(s2n_stuffer_read_uint8(in, &request_context_length));
- /* RFC 8446: This field SHALL be zero length unless used for the post-handshake authentication */
- S2N_ERROR_IF(request_context_length != 0, S2N_ERR_BAD_MESSAGE);
-
- GUARD(s2n_extension_list_recv(S2N_EXTENSION_LIST_CERT_REQ, conn, in));
-
- GUARD(s2n_set_cert_chain_as_client(conn));
-
- return S2N_SUCCESS;
-}
-
-int s2n_cert_req_recv(struct s2n_connection *conn)
-{
- struct s2n_stuffer *in = &conn->handshake.io;
-
- s2n_cert_type cert_type = 0;
- GUARD(s2n_recv_client_cert_preferences(in, &cert_type));
- GUARD(s2n_cert_type_to_pkey_type(cert_type, &conn->secure.client_cert_pkey_type));
-
- if (conn->actual_protocol_version == S2N_TLS12) {
- GUARD(s2n_recv_supported_sig_scheme_list(in, &conn->handshake_params.server_sig_hash_algs));
- }
-
- uint16_t cert_authorities_len = 0;
- GUARD(s2n_stuffer_read_uint16(in, &cert_authorities_len));
-
- /* For now we don't parse X.501 encoded CA Distinguished Names.
- * Don't fail just yet as we still may succeed if we provide
- * right certificate or if ClientAuth is optional. */
- GUARD(s2n_stuffer_skip_read(in, cert_authorities_len));
-
- /* In the future we may have more advanced logic to match a set of configured certificates against
- * The cert authorities extension and the signature algorithms advertised.
- * For now, this will just set the only certificate configured.
- */
- GUARD(s2n_set_cert_chain_as_client(conn));
-
- return 0;
-}
-
-int s2n_tls13_cert_req_send(struct s2n_connection *conn)
-{
- struct s2n_stuffer *out = &conn->handshake.io;
-
- /* Write 0 length request context https://tools.ietf.org/html/rfc8446#section-4.3.2 */
- GUARD(s2n_stuffer_write_uint8(out, 0));
-
- GUARD(s2n_extension_list_send(S2N_EXTENSION_LIST_CERT_REQ, conn, out));
-
- return S2N_SUCCESS;
-}
-
-int s2n_cert_req_send(struct s2n_connection *conn)
-{
- struct s2n_stuffer *out = &conn->handshake.io;
-
- uint8_t client_cert_preference_list_size = sizeof(s2n_cert_type_preference_list);
- if (conn->config->cert_req_dss_legacy_compat_enabled) {
- client_cert_preference_list_size = sizeof(s2n_cert_type_preference_list_legacy_dss);
- }
- GUARD(s2n_stuffer_write_uint8(out, client_cert_preference_list_size));
-
- for (int i = 0; i < client_cert_preference_list_size; i++) {
- if (conn->config->cert_req_dss_legacy_compat_enabled) {
- GUARD(s2n_stuffer_write_uint8(out, s2n_cert_type_preference_list_legacy_dss[i]));
- } else {
- GUARD(s2n_stuffer_write_uint8(out, s2n_cert_type_preference_list[i]));
- }
- }
-
- if (conn->actual_protocol_version == S2N_TLS12) {
- GUARD(s2n_send_supported_sig_scheme_list(conn, out));
- }
-
- /* RFC 5246 7.4.4 - If the certificate_authorities list is empty, then the
- * client MAY send any certificate of the appropriate ClientCertificateType */
- uint16_t acceptable_cert_authorities_len = 0;
- GUARD(s2n_stuffer_write_uint16(out, acceptable_cert_authorities_len));
-
- return 0;
-}
+/*
+ * 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 <s2n.h>
+
+#include "crypto/s2n_certificate.h"
+#include "error/s2n_errno.h"
+#include "extensions/s2n_extension_list.h"
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_config.h"
+#include "tls/s2n_signature_algorithms.h"
+#include "tls/s2n_signature_scheme.h"
+#include "tls/s2n_tls.h"
+#include "stuffer/s2n_stuffer.h"
+#include "utils/s2n_safety.h"
+#include "utils/s2n_array.h"
+
+/* RFC's that define below values:
+ * - https://tools.ietf.org/html/rfc5246#section-7.4.4
+ * - https://tools.ietf.org/search/rfc4492#section-5.5
+ */
+typedef enum {
+ S2N_CERT_TYPE_RSA_SIGN = 1,
+ S2N_CERT_TYPE_DSS_SIGN = 2,
+ S2N_CERT_TYPE_RSA_FIXED_DH = 3,
+ S2N_CERT_TYPE_DSS_FIXED_DH = 4,
+ S2N_CERT_TYPE_RSA_EPHEMERAL_DH_RESERVED = 5,
+ S2N_CERT_TYPE_DSS_EPHEMERAL_DH_RESERVED = 6,
+ S2N_CERT_TYPE_FORTEZZA_DMS_RESERVED = 20,
+ S2N_CERT_TYPE_ECDSA_SIGN = 64,
+ S2N_CERT_TYPE_RSA_FIXED_ECDH = 65,
+ S2N_CERT_TYPE_ECDSA_FIXED_ECDH = 66,
+} s2n_cert_type;
+
+static uint8_t s2n_cert_type_preference_list[] = {
+ S2N_CERT_TYPE_RSA_SIGN,
+ S2N_CERT_TYPE_ECDSA_SIGN
+};
+
+/*
+ * Include DSS sign certificate type in server certificate request.
+ * Only will be used if cert_req_dss_legacy_compat_enabled is set by calling s2n_config_enable_cert_req_dss_legacy_compat.
+ */
+static uint8_t s2n_cert_type_preference_list_legacy_dss[] = {
+ S2N_CERT_TYPE_RSA_SIGN,
+ S2N_CERT_TYPE_DSS_SIGN,
+ S2N_CERT_TYPE_ECDSA_SIGN
+};
+
+static int s2n_cert_type_to_pkey_type(s2n_cert_type cert_type_in, s2n_pkey_type *pkey_type_out) {
+ switch(cert_type_in) {
+ case S2N_CERT_TYPE_RSA_SIGN:
+ *pkey_type_out = S2N_PKEY_TYPE_RSA;
+ return 0;
+ case S2N_CERT_TYPE_ECDSA_SIGN:
+ *pkey_type_out = S2N_PKEY_TYPE_ECDSA;
+ return 0;
+ default:
+ S2N_ERROR(S2N_CERT_ERR_TYPE_UNSUPPORTED);
+ }
+}
+
+static int s2n_recv_client_cert_preferences(struct s2n_stuffer *in, s2n_cert_type *chosen_cert_type_out)
+{
+ uint8_t cert_types_len;
+ GUARD(s2n_stuffer_read_uint8(in, &cert_types_len));
+
+ uint8_t *their_cert_type_pref_list = s2n_stuffer_raw_read(in, cert_types_len);
+ notnull_check(their_cert_type_pref_list);
+
+ /* Iterate through our preference list from most to least preferred, and return the first match that we find. */
+ for (int our_cert_pref_idx = 0; our_cert_pref_idx < sizeof(s2n_cert_type_preference_list); our_cert_pref_idx++) {
+ for (int their_cert_idx = 0; their_cert_idx < cert_types_len; their_cert_idx++) {
+ if (their_cert_type_pref_list[their_cert_idx] == s2n_cert_type_preference_list[our_cert_pref_idx]) {
+ *chosen_cert_type_out = s2n_cert_type_preference_list[our_cert_pref_idx];
+ return 0;
+ }
+ }
+ }
+
+ S2N_ERROR(S2N_ERR_CERT_TYPE_UNSUPPORTED);
+}
+
+static int s2n_set_cert_chain_as_client(struct s2n_connection *conn)
+{
+ if (s2n_config_get_num_default_certs(conn->config) > 0) {
+ GUARD(s2n_choose_sig_scheme_from_peer_preference_list(conn, &conn->handshake_params.server_sig_hash_algs,
+ &conn->secure.client_cert_sig_scheme));
+
+ struct s2n_cert_chain_and_key *cert = s2n_config_get_single_default_cert(conn->config);
+ notnull_check(cert);
+ conn->handshake_params.our_chain_and_key = cert;
+ }
+
+ return 0;
+}
+
+int s2n_tls13_cert_req_recv(struct s2n_connection *conn)
+{
+ struct s2n_stuffer *in = &conn->handshake.io;
+
+ /* read request context length */
+ uint8_t request_context_length;
+ GUARD(s2n_stuffer_read_uint8(in, &request_context_length));
+ /* RFC 8446: This field SHALL be zero length unless used for the post-handshake authentication */
+ S2N_ERROR_IF(request_context_length != 0, S2N_ERR_BAD_MESSAGE);
+
+ GUARD(s2n_extension_list_recv(S2N_EXTENSION_LIST_CERT_REQ, conn, in));
+
+ GUARD(s2n_set_cert_chain_as_client(conn));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_cert_req_recv(struct s2n_connection *conn)
+{
+ struct s2n_stuffer *in = &conn->handshake.io;
+
+ s2n_cert_type cert_type = 0;
+ GUARD(s2n_recv_client_cert_preferences(in, &cert_type));
+ GUARD(s2n_cert_type_to_pkey_type(cert_type, &conn->secure.client_cert_pkey_type));
+
+ if (conn->actual_protocol_version == S2N_TLS12) {
+ GUARD(s2n_recv_supported_sig_scheme_list(in, &conn->handshake_params.server_sig_hash_algs));
+ }
+
+ uint16_t cert_authorities_len = 0;
+ GUARD(s2n_stuffer_read_uint16(in, &cert_authorities_len));
+
+ /* For now we don't parse X.501 encoded CA Distinguished Names.
+ * Don't fail just yet as we still may succeed if we provide
+ * right certificate or if ClientAuth is optional. */
+ GUARD(s2n_stuffer_skip_read(in, cert_authorities_len));
+
+ /* In the future we may have more advanced logic to match a set of configured certificates against
+ * The cert authorities extension and the signature algorithms advertised.
+ * For now, this will just set the only certificate configured.
+ */
+ GUARD(s2n_set_cert_chain_as_client(conn));
+
+ return 0;
+}
+
+int s2n_tls13_cert_req_send(struct s2n_connection *conn)
+{
+ struct s2n_stuffer *out = &conn->handshake.io;
+
+ /* Write 0 length request context https://tools.ietf.org/html/rfc8446#section-4.3.2 */
+ GUARD(s2n_stuffer_write_uint8(out, 0));
+
+ GUARD(s2n_extension_list_send(S2N_EXTENSION_LIST_CERT_REQ, conn, out));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_cert_req_send(struct s2n_connection *conn)
+{
+ struct s2n_stuffer *out = &conn->handshake.io;
+
+ uint8_t client_cert_preference_list_size = sizeof(s2n_cert_type_preference_list);
+ if (conn->config->cert_req_dss_legacy_compat_enabled) {
+ client_cert_preference_list_size = sizeof(s2n_cert_type_preference_list_legacy_dss);
+ }
+ GUARD(s2n_stuffer_write_uint8(out, client_cert_preference_list_size));
+
+ for (int i = 0; i < client_cert_preference_list_size; i++) {
+ if (conn->config->cert_req_dss_legacy_compat_enabled) {
+ GUARD(s2n_stuffer_write_uint8(out, s2n_cert_type_preference_list_legacy_dss[i]));
+ } else {
+ GUARD(s2n_stuffer_write_uint8(out, s2n_cert_type_preference_list[i]));
+ }
+ }
+
+ if (conn->actual_protocol_version == S2N_TLS12) {
+ GUARD(s2n_send_supported_sig_scheme_list(conn, out));
+ }
+
+ /* RFC 5246 7.4.4 - If the certificate_authorities list is empty, then the
+ * client MAY send any certificate of the appropriate ClientCertificateType */
+ uint16_t acceptable_cert_authorities_len = 0;
+ GUARD(s2n_stuffer_write_uint16(out, acceptable_cert_authorities_len));
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_server_done.c b/contrib/restricted/aws/s2n/tls/s2n_server_done.c
index ebd2bc9e7b..6ddc123140 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_server_done.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_server_done.c
@@ -1,35 +1,35 @@
-/*
- * 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 <stdint.h>
-
-#include "error/s2n_errno.h"
-
-#include "tls/s2n_connection.h"
-#include "tls/s2n_tls.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-int s2n_server_done_recv(struct s2n_connection *conn)
-{
- S2N_ERROR_IF(s2n_stuffer_data_available(&conn->handshake.io), S2N_ERR_BAD_MESSAGE);
-
- return 0;
-}
-
-int s2n_server_done_send(struct s2n_connection *conn)
-{
- return 0;
-}
+/*
+ * 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 <stdint.h>
+
+#include "error/s2n_errno.h"
+
+#include "tls/s2n_connection.h"
+#include "tls/s2n_tls.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+int s2n_server_done_recv(struct s2n_connection *conn)
+{
+ S2N_ERROR_IF(s2n_stuffer_data_available(&conn->handshake.io), S2N_ERR_BAD_MESSAGE);
+
+ return 0;
+}
+
+int s2n_server_done_send(struct s2n_connection *conn)
+{
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_server_extensions.c b/contrib/restricted/aws/s2n/tls/s2n_server_extensions.c
index 6a022b14e2..0fc8f6bb15 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_server_extensions.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_server_extensions.c
@@ -1,72 +1,72 @@
-/*
- * 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 "tls/s2n_server_extensions.h"
-
-#include "tls/extensions/s2n_extension_list.h"
-#include "tls/extensions/s2n_server_supported_versions.h"
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-#include "utils/s2n_safety.h"
-
-
-/* An empty list will just contain the uint16_t list size */
-#define S2N_EMPTY_EXTENSION_LIST_SIZE sizeof(uint16_t)
-
-int s2n_server_extensions_send(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- uint32_t data_available_before_extensions = s2n_stuffer_data_available(out);
-
- if (conn->actual_protocol_version >= S2N_TLS13) {
- GUARD(s2n_extension_list_send(S2N_EXTENSION_LIST_SERVER_HELLO_TLS13, conn, out));
- } else {
- GUARD(s2n_extension_list_send(S2N_EXTENSION_LIST_SERVER_HELLO_DEFAULT, conn, out));
- }
-
- /* The ServerHello extension list size (uint16_t) is NOT written if the list is empty.
- * This is to support older clients written before extensions existed that might fail
- * on any unexpected bytes at the end of the ServerHello.
- *
- * This behavior is outlined in the TLS1.2 RFC: https://tools.ietf.org/html/rfc5246#appendix-A.4.1
- *
- * This behavior does not affect TLS1.3, which always requires at least the supported_version extension
- * so will never produce an empty list.
- */
- if(s2n_stuffer_data_available(out) - data_available_before_extensions == S2N_EMPTY_EXTENSION_LIST_SIZE) {
- GUARD(s2n_stuffer_wipe_n(out, S2N_EMPTY_EXTENSION_LIST_SIZE));
- }
-
- return S2N_SUCCESS;
-}
-
-int s2n_server_extensions_recv(struct s2n_connection *conn, struct s2n_stuffer *in)
-{
- s2n_parsed_extensions_list parsed_extension_list = { 0 };
- GUARD(s2n_extension_list_parse(in, &parsed_extension_list));
-
- /* 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. */
- GUARD(s2n_extension_process(&s2n_server_supported_versions_extension, conn, &parsed_extension_list));
-
- if (conn->server_protocol_version >= S2N_TLS13) {
- GUARD(s2n_extension_list_process(S2N_EXTENSION_LIST_SERVER_HELLO_TLS13, conn, &parsed_extension_list));
- } else {
- GUARD(s2n_extension_list_process(S2N_EXTENSION_LIST_SERVER_HELLO_DEFAULT, conn, &parsed_extension_list));
- }
-
- return S2N_SUCCESS;
-}
+/*
+ * 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 "tls/s2n_server_extensions.h"
+
+#include "tls/extensions/s2n_extension_list.h"
+#include "tls/extensions/s2n_server_supported_versions.h"
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+#include "utils/s2n_safety.h"
+
+
+/* An empty list will just contain the uint16_t list size */
+#define S2N_EMPTY_EXTENSION_LIST_SIZE sizeof(uint16_t)
+
+int s2n_server_extensions_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ uint32_t data_available_before_extensions = s2n_stuffer_data_available(out);
+
+ if (conn->actual_protocol_version >= S2N_TLS13) {
+ GUARD(s2n_extension_list_send(S2N_EXTENSION_LIST_SERVER_HELLO_TLS13, conn, out));
+ } else {
+ GUARD(s2n_extension_list_send(S2N_EXTENSION_LIST_SERVER_HELLO_DEFAULT, conn, out));
+ }
+
+ /* The ServerHello extension list size (uint16_t) is NOT written if the list is empty.
+ * This is to support older clients written before extensions existed that might fail
+ * on any unexpected bytes at the end of the ServerHello.
+ *
+ * This behavior is outlined in the TLS1.2 RFC: https://tools.ietf.org/html/rfc5246#appendix-A.4.1
+ *
+ * This behavior does not affect TLS1.3, which always requires at least the supported_version extension
+ * so will never produce an empty list.
+ */
+ if(s2n_stuffer_data_available(out) - data_available_before_extensions == S2N_EMPTY_EXTENSION_LIST_SIZE) {
+ GUARD(s2n_stuffer_wipe_n(out, S2N_EMPTY_EXTENSION_LIST_SIZE));
+ }
+
+ return S2N_SUCCESS;
+}
+
+int s2n_server_extensions_recv(struct s2n_connection *conn, struct s2n_stuffer *in)
+{
+ s2n_parsed_extensions_list parsed_extension_list = { 0 };
+ GUARD(s2n_extension_list_parse(in, &parsed_extension_list));
+
+ /* 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. */
+ GUARD(s2n_extension_process(&s2n_server_supported_versions_extension, conn, &parsed_extension_list));
+
+ if (conn->server_protocol_version >= S2N_TLS13) {
+ GUARD(s2n_extension_list_process(S2N_EXTENSION_LIST_SERVER_HELLO_TLS13, conn, &parsed_extension_list));
+ } else {
+ GUARD(s2n_extension_list_process(S2N_EXTENSION_LIST_SERVER_HELLO_DEFAULT, conn, &parsed_extension_list));
+ }
+
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_server_extensions.h b/contrib/restricted/aws/s2n/tls/s2n_server_extensions.h
index f196a2396a..57b720395c 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_server_extensions.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_server_extensions.h
@@ -1,22 +1,22 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/s2n_connection.h"
-#include "stuffer/s2n_stuffer.h"
-
-int s2n_server_extensions_send(struct s2n_connection *conn, struct s2n_stuffer *out);
-int s2n_server_extensions_recv(struct s2n_connection *conn, struct s2n_stuffer *in);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/s2n_connection.h"
+#include "stuffer/s2n_stuffer.h"
+
+int s2n_server_extensions_send(struct s2n_connection *conn, struct s2n_stuffer *out);
+int s2n_server_extensions_recv(struct s2n_connection *conn, struct s2n_stuffer *in);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_server_finished.c b/contrib/restricted/aws/s2n/tls/s2n_server_finished.c
index 1df8bfc8fe..156641dd14 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_server_finished.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_server_finished.c
@@ -1,131 +1,131 @@
-/*
- * 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 <stdint.h>
-
-#include "error/s2n_errno.h"
-
-#include "tls/s2n_connection.h"
-#include "tls/s2n_resume.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls13_handshake.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_safety.h"
-
-int s2n_server_finished_recv(struct s2n_connection *conn)
-{
- uint8_t *our_version;
- int length = S2N_TLS_FINISHED_LEN;
- our_version = conn->handshake.server_finished;
-
- if (conn->actual_protocol_version == S2N_SSLv3) {
- length = S2N_SSL_FINISHED_LEN;
- }
-
- uint8_t *their_version = s2n_stuffer_raw_read(&conn->handshake.io, length);
- notnull_check(their_version);
-
- S2N_ERROR_IF(!s2n_constant_time_equals(our_version, their_version, length), S2N_ERR_BAD_MESSAGE);
-
- return 0;
-}
-
-int s2n_server_finished_send(struct s2n_connection *conn)
-{
- uint8_t *our_version;
- int length = S2N_TLS_FINISHED_LEN;
-
- /* Compute the finished message */
- GUARD(s2n_prf_server_finished(conn));
-
- our_version = conn->handshake.server_finished;
-
- if (conn->actual_protocol_version == S2N_SSLv3) {
- length = S2N_SSL_FINISHED_LEN;
- }
-
- GUARD(s2n_stuffer_write_bytes(&conn->handshake.io, our_version, length));
-
- /* Zero the sequence number */
- struct s2n_blob seq = {.data = conn->secure.server_sequence_number,.size = S2N_TLS_SEQUENCE_NUM_LEN };
- GUARD(s2n_blob_zero(&seq));
-
- /* Update the secure state to active, and point the client at the active state */
- conn->server = &conn->secure;
-
- if (IS_RESUMPTION_HANDSHAKE(conn->handshake.handshake_type)) {
- GUARD(s2n_prf_key_expansion(conn));
- }
-
- return 0;
-}
-
-
-int s2n_tls13_server_finished_recv(struct s2n_connection *conn) {
- eq_check(conn->actual_protocol_version, S2N_TLS13);
-
- uint8_t length = s2n_stuffer_data_available(&conn->handshake.io);
- S2N_ERROR_IF(length == 0, S2N_ERR_BAD_MESSAGE);
-
- /* read finished mac from handshake */
- struct s2n_blob wire_finished_mac = {0};
- s2n_blob_init(&wire_finished_mac, s2n_stuffer_raw_read(&conn->handshake.io, length), length);
-
- /* get tls13 keys */
- s2n_tls13_connection_keys(keys, conn);
-
- /* get transcript hash */
- struct s2n_hash_state hash_state = {0};
- GUARD(s2n_handshake_get_hash_state(conn, keys.hash_algorithm, &hash_state));
-
- /* look up finished secret key */
- struct s2n_blob finished_key = {0};
- GUARD(s2n_blob_init(&finished_key, conn->handshake.server_finished, keys.size));
-
- /* generate the hashed message authenticated code */
- s2n_tls13_key_blob(server_finished_mac, keys.size);
- GUARD(s2n_tls13_calculate_finished_mac(&keys, &finished_key, &hash_state, &server_finished_mac));
-
- /* compare mac with received message */
- GUARD(s2n_tls13_mac_verify(&keys, &server_finished_mac, &wire_finished_mac));
-
- return 0;
-}
-
-int s2n_tls13_server_finished_send(struct s2n_connection *conn) {
- eq_check(conn->actual_protocol_version, S2N_TLS13);
-
- /* get tls13 keys */
- s2n_tls13_connection_keys(keys, conn);
-
- /* get transcript hash */
- struct s2n_hash_state hash_state = {0};
- GUARD(s2n_handshake_get_hash_state(conn, keys.hash_algorithm, &hash_state));
-
- /* look up finished secret key */
- struct s2n_blob finished_key = {0};
- GUARD(s2n_blob_init(&finished_key, conn->handshake.server_finished, keys.size));
-
- /* generate the hashed message authenticated code */
- s2n_tls13_key_blob(server_finished_mac, keys.size);
- GUARD(s2n_tls13_calculate_finished_mac(&keys, &finished_key, &hash_state, &server_finished_mac));
-
- /* write to handshake io */
- GUARD(s2n_stuffer_write(&conn->handshake.io, &server_finished_mac));
-
- return 0;
-}
+/*
+ * 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 <stdint.h>
+
+#include "error/s2n_errno.h"
+
+#include "tls/s2n_connection.h"
+#include "tls/s2n_resume.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls13_handshake.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_safety.h"
+
+int s2n_server_finished_recv(struct s2n_connection *conn)
+{
+ uint8_t *our_version;
+ int length = S2N_TLS_FINISHED_LEN;
+ our_version = conn->handshake.server_finished;
+
+ if (conn->actual_protocol_version == S2N_SSLv3) {
+ length = S2N_SSL_FINISHED_LEN;
+ }
+
+ uint8_t *their_version = s2n_stuffer_raw_read(&conn->handshake.io, length);
+ notnull_check(their_version);
+
+ S2N_ERROR_IF(!s2n_constant_time_equals(our_version, their_version, length), S2N_ERR_BAD_MESSAGE);
+
+ return 0;
+}
+
+int s2n_server_finished_send(struct s2n_connection *conn)
+{
+ uint8_t *our_version;
+ int length = S2N_TLS_FINISHED_LEN;
+
+ /* Compute the finished message */
+ GUARD(s2n_prf_server_finished(conn));
+
+ our_version = conn->handshake.server_finished;
+
+ if (conn->actual_protocol_version == S2N_SSLv3) {
+ length = S2N_SSL_FINISHED_LEN;
+ }
+
+ GUARD(s2n_stuffer_write_bytes(&conn->handshake.io, our_version, length));
+
+ /* Zero the sequence number */
+ struct s2n_blob seq = {.data = conn->secure.server_sequence_number,.size = S2N_TLS_SEQUENCE_NUM_LEN };
+ GUARD(s2n_blob_zero(&seq));
+
+ /* Update the secure state to active, and point the client at the active state */
+ conn->server = &conn->secure;
+
+ if (IS_RESUMPTION_HANDSHAKE(conn->handshake.handshake_type)) {
+ GUARD(s2n_prf_key_expansion(conn));
+ }
+
+ return 0;
+}
+
+
+int s2n_tls13_server_finished_recv(struct s2n_connection *conn) {
+ eq_check(conn->actual_protocol_version, S2N_TLS13);
+
+ uint8_t length = s2n_stuffer_data_available(&conn->handshake.io);
+ S2N_ERROR_IF(length == 0, S2N_ERR_BAD_MESSAGE);
+
+ /* read finished mac from handshake */
+ struct s2n_blob wire_finished_mac = {0};
+ s2n_blob_init(&wire_finished_mac, s2n_stuffer_raw_read(&conn->handshake.io, length), length);
+
+ /* get tls13 keys */
+ s2n_tls13_connection_keys(keys, conn);
+
+ /* get transcript hash */
+ struct s2n_hash_state hash_state = {0};
+ GUARD(s2n_handshake_get_hash_state(conn, keys.hash_algorithm, &hash_state));
+
+ /* look up finished secret key */
+ struct s2n_blob finished_key = {0};
+ GUARD(s2n_blob_init(&finished_key, conn->handshake.server_finished, keys.size));
+
+ /* generate the hashed message authenticated code */
+ s2n_tls13_key_blob(server_finished_mac, keys.size);
+ GUARD(s2n_tls13_calculate_finished_mac(&keys, &finished_key, &hash_state, &server_finished_mac));
+
+ /* compare mac with received message */
+ GUARD(s2n_tls13_mac_verify(&keys, &server_finished_mac, &wire_finished_mac));
+
+ return 0;
+}
+
+int s2n_tls13_server_finished_send(struct s2n_connection *conn) {
+ eq_check(conn->actual_protocol_version, S2N_TLS13);
+
+ /* get tls13 keys */
+ s2n_tls13_connection_keys(keys, conn);
+
+ /* get transcript hash */
+ struct s2n_hash_state hash_state = {0};
+ GUARD(s2n_handshake_get_hash_state(conn, keys.hash_algorithm, &hash_state));
+
+ /* look up finished secret key */
+ struct s2n_blob finished_key = {0};
+ GUARD(s2n_blob_init(&finished_key, conn->handshake.server_finished, keys.size));
+
+ /* generate the hashed message authenticated code */
+ s2n_tls13_key_blob(server_finished_mac, keys.size);
+ GUARD(s2n_tls13_calculate_finished_mac(&keys, &finished_key, &hash_state, &server_finished_mac));
+
+ /* write to handshake io */
+ GUARD(s2n_stuffer_write(&conn->handshake.io, &server_finished_mac));
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_server_hello.c b/contrib/restricted/aws/s2n/tls/s2n_server_hello.c
index 11259dad7b..010c06547a 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_server_hello.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_server_hello.c
@@ -1,251 +1,251 @@
-/*
- * 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 <sys/param.h>
-
-#include <s2n.h>
-#include <time.h>
-
-#include "crypto/s2n_fips.h"
-
-#include "error/s2n_errno.h"
-
-#include "tls/s2n_cipher_preferences.h"
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_alerts.h"
-#include "tls/s2n_server_extensions.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls13.h"
-#include "tls/s2n_security_policies.h"
-#include "tls/s2n_tls13_handshake.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_random.h"
-
-/* From RFC5246 7.4.1.2. */
-#define S2N_TLS_COMPRESSION_METHOD_NULL 0
-
-/* From RFC8446 4.1.3. */
-#define S2N_DOWNGRADE_PROTECTION_SIZE 8
-const uint8_t tls12_downgrade_protection_bytes[] = {
- 0x44, 0x4F, 0x57, 0x4E, 0x47, 0x52, 0x44, 0x01
-};
-
-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) {
- notnull_check(conn);
-
- ENSURE_POSIX(memcmp(hello_retry_req_random, conn->secure.server_random, S2N_TLS_RANDOM_DATA_LEN) == 0,
- S2N_ERR_INVALID_HELLO_RETRY);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_client_detect_downgrade_mechanism(struct s2n_connection *conn) {
- notnull_check(conn);
- uint8_t *downgrade_bytes = &conn->secure.server_random[S2N_TLS_RANDOM_DATA_LEN - S2N_DOWNGRADE_PROTECTION_SIZE];
-
- /* Detect downgrade attacks according to RFC 8446 section 4.1.3 */
- if (conn->client_protocol_version == S2N_TLS13 && conn->server_protocol_version == S2N_TLS12) {
- if (s2n_constant_time_equals(downgrade_bytes, tls12_downgrade_protection_bytes, S2N_DOWNGRADE_PROTECTION_SIZE)) {
- S2N_ERROR(S2N_ERR_PROTOCOL_DOWNGRADE_DETECTED);
- }
- } else if (conn->client_protocol_version == S2N_TLS13 && conn->server_protocol_version <= S2N_TLS11) {
- if (s2n_constant_time_equals(downgrade_bytes, tls11_downgrade_protection_bytes, S2N_DOWNGRADE_PROTECTION_SIZE)) {
- S2N_ERROR(S2N_ERR_PROTOCOL_DOWNGRADE_DETECTED);
- }
- }
-
- return 0;
-}
-
-static int s2n_server_add_downgrade_mechanism(struct s2n_connection *conn) {
- notnull_check(conn);
- uint8_t *downgrade_bytes = &conn->secure.server_random[S2N_TLS_RANDOM_DATA_LEN - S2N_DOWNGRADE_PROTECTION_SIZE];
-
- /* Protect against downgrade attacks according to RFC 8446 section 4.1.3 */
- if (conn->server_protocol_version >= S2N_TLS13 && conn->actual_protocol_version == S2N_TLS12) {
- /* TLS1.3 servers MUST use a special random value when negotiating TLS1.2 */
- memcpy_check(downgrade_bytes, tls12_downgrade_protection_bytes, S2N_DOWNGRADE_PROTECTION_SIZE);
- } else if (conn->server_protocol_version >= S2N_TLS13 && conn->actual_protocol_version <= S2N_TLS11) {
- /* TLS1.3 servers MUST, use a special random value when negotiating TLS1.1 or below */
- memcpy_check(downgrade_bytes, tls11_downgrade_protection_bytes, S2N_DOWNGRADE_PROTECTION_SIZE);
- }
-
- return 0;
-}
-
-static int s2n_server_hello_parse(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- struct s2n_stuffer *in = &conn->handshake.io;
- uint8_t compression_method;
- uint8_t session_id_len;
- uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN];
- uint8_t session_id[S2N_TLS_SESSION_ID_MAX_LEN];
-
- GUARD(s2n_stuffer_read_bytes(in, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
- GUARD(s2n_stuffer_read_bytes(in, conn->secure.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) {
- ENSURE_POSIX(!s2n_is_hello_retry_handshake(conn), S2N_ERR_INVALID_HELLO_RETRY);
- GUARD(s2n_set_hello_retry_required(conn));
- }
-
- GUARD(s2n_stuffer_read_uint8(in, &session_id_len));
- S2N_ERROR_IF(session_id_len > S2N_TLS_SESSION_ID_MAX_LEN, S2N_ERR_BAD_MESSAGE);
- GUARD(s2n_stuffer_read_bytes(in, session_id, session_id_len));
-
- uint8_t *cipher_suite_wire = s2n_stuffer_raw_read(in, S2N_TLS_CIPHER_SUITE_LEN);
- notnull_check(cipher_suite_wire);
-
- GUARD(s2n_stuffer_read_uint8(in, &compression_method));
- S2N_ERROR_IF(compression_method != S2N_TLS_COMPRESSION_METHOD_NULL, S2N_ERR_BAD_MESSAGE);
-
- GUARD(s2n_server_extensions_recv(conn, in));
-
- if (conn->server_protocol_version >= S2N_TLS13) {
- S2N_ERROR_IF(session_id_len != conn->session_id_len || memcmp(session_id, conn->session_id, session_id_len), S2N_ERR_BAD_MESSAGE);
- conn->actual_protocol_version = conn->server_protocol_version;
- GUARD(s2n_set_cipher_as_client(conn, cipher_suite_wire));
- } else {
- conn->server_protocol_version = (uint8_t)(protocol_version[0] * 10) + protocol_version[1];
-
- S2N_ERROR_IF(s2n_client_detect_downgrade_mechanism(conn), S2N_ERR_PROTOCOL_DOWNGRADE_DETECTED);
- ENSURE_POSIX(!conn->config->quic_enabled, S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED);
-
- const struct s2n_security_policy *security_policy;
- GUARD(s2n_connection_get_security_policy(conn, &security_policy));
-
- if (conn->server_protocol_version < security_policy->minimum_protocol_version
- || conn->server_protocol_version > conn->client_protocol_version) {
- GUARD(s2n_queue_reader_unsupported_protocol_version_alert(conn));
- S2N_ERROR(S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED);
- }
-
- uint8_t actual_protocol_version = MIN(conn->server_protocol_version, conn->client_protocol_version);
- /* Use the session state if server sent same session id as client sent in client hello */
- if (session_id_len != 0 && session_id_len == conn->session_id_len
- && !memcmp(session_id, conn->session_id, session_id_len)) {
- /* check if the resumed session state is valid */
- S2N_ERROR_IF(conn->actual_protocol_version != actual_protocol_version, S2N_ERR_BAD_MESSAGE);
- S2N_ERROR_IF(memcmp(conn->secure.cipher_suite->iana_value, cipher_suite_wire, S2N_TLS_CIPHER_SUITE_LEN) != 0, S2N_ERR_BAD_MESSAGE);
-
- /* Session is resumed */
- conn->client_session_resumed = 1;
- } else {
- conn->session_id_len = session_id_len;
- memcpy_check(conn->session_id, session_id, session_id_len);
- conn->actual_protocol_version = actual_protocol_version;
- GUARD(s2n_set_cipher_as_client(conn, cipher_suite_wire));
- /* Erase master secret which might have been set for session resumption */
- memset_check((uint8_t *)conn->secure.master_secret, 0, S2N_TLS_SECRET_LEN);
-
- /* Erase client session ticket which might have been set for session resumption */
- GUARD(s2n_free(&conn->client_ticket));
- }
- }
-
- return 0;
-}
-
-int s2n_server_hello_recv(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- /* Read the message off the wire */
- GUARD(s2n_server_hello_parse(conn));
-
- conn->actual_protocol_version_established = 1;
-
- GUARD(s2n_conn_set_handshake_type(conn));
-
- /* If this is a HelloRetryRequest, we don't process the ServerHello.
- * Instead we proceed with retry logic. */
- if (s2n_is_hello_retry_message(conn)) {
- GUARD(s2n_server_hello_retry_recv(conn));
- return 0;
- }
-
- if (IS_RESUMPTION_HANDSHAKE(conn->handshake.handshake_type)) {
- GUARD(s2n_prf_key_expansion(conn));
- }
-
- /* Choose a default signature scheme */
- GUARD(s2n_choose_default_sig_scheme(conn, &conn->secure.conn_sig_scheme));
-
- /* Update the required hashes for this connection */
- GUARD(s2n_conn_update_required_handshake_hashes(conn));
-
- return 0;
-}
-
-int s2n_server_hello_write_message(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- /* The actual_protocol_version is set while processing the CLIENT_HELLO message, so
- * it could be S2N_TLS13. SERVER_HELLO should always respond with the legacy version.
- * https://tools.ietf.org/html/rfc8446#section-4.1.3 */
- const uint16_t legacy_protocol_version = MIN(conn->actual_protocol_version, S2N_TLS12);
- uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN];
- protocol_version[0] = (uint8_t)(legacy_protocol_version / 10);
- protocol_version[1] = (uint8_t)(legacy_protocol_version % 10);
-
- GUARD(s2n_stuffer_write_bytes(&conn->handshake.io, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
- GUARD(s2n_stuffer_write_bytes(&conn->handshake.io, conn->secure.server_random, S2N_TLS_RANDOM_DATA_LEN));
- GUARD(s2n_stuffer_write_uint8(&conn->handshake.io, conn->session_id_len));
- GUARD(s2n_stuffer_write_bytes(&conn->handshake.io, conn->session_id, conn->session_id_len));
- GUARD(s2n_stuffer_write_bytes(&conn->handshake.io, conn->secure.cipher_suite->iana_value, S2N_TLS_CIPHER_SUITE_LEN));
- GUARD(s2n_stuffer_write_uint8(&conn->handshake.io, S2N_TLS_COMPRESSION_METHOD_NULL));
-
- return 0;
-}
-
-int s2n_server_hello_send(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- struct s2n_stuffer server_random = {0};
- struct s2n_blob b = {0};
- GUARD(s2n_blob_init(&b, conn->secure.server_random, S2N_TLS_RANDOM_DATA_LEN));
-
- /* Create the server random data */
- GUARD(s2n_stuffer_init(&server_random, &b));
-
- struct s2n_blob rand_data = {0};
- GUARD(s2n_blob_init(&rand_data, s2n_stuffer_raw_write(&server_random, S2N_TLS_RANDOM_DATA_LEN), S2N_TLS_RANDOM_DATA_LEN));
- notnull_check(rand_data.data);
- GUARD_AS_POSIX(s2n_get_public_random_data(&rand_data));
-
- /* Add a downgrade detection mechanism if required */
- GUARD(s2n_server_add_downgrade_mechanism(conn));
-
- GUARD(s2n_server_hello_write_message(conn));
-
- GUARD(s2n_server_extensions_send(conn, &conn->handshake.io));
-
- conn->actual_protocol_version_established = 1;
-
- return 0;
-}
+/*
+ * 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 <sys/param.h>
+
+#include <s2n.h>
+#include <time.h>
+
+#include "crypto/s2n_fips.h"
+
+#include "error/s2n_errno.h"
+
+#include "tls/s2n_cipher_preferences.h"
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_alerts.h"
+#include "tls/s2n_server_extensions.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls13.h"
+#include "tls/s2n_security_policies.h"
+#include "tls/s2n_tls13_handshake.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_random.h"
+
+/* From RFC5246 7.4.1.2. */
+#define S2N_TLS_COMPRESSION_METHOD_NULL 0
+
+/* From RFC8446 4.1.3. */
+#define S2N_DOWNGRADE_PROTECTION_SIZE 8
+const uint8_t tls12_downgrade_protection_bytes[] = {
+ 0x44, 0x4F, 0x57, 0x4E, 0x47, 0x52, 0x44, 0x01
+};
+
+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) {
+ notnull_check(conn);
+
+ ENSURE_POSIX(memcmp(hello_retry_req_random, conn->secure.server_random, S2N_TLS_RANDOM_DATA_LEN) == 0,
+ S2N_ERR_INVALID_HELLO_RETRY);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_client_detect_downgrade_mechanism(struct s2n_connection *conn) {
+ notnull_check(conn);
+ uint8_t *downgrade_bytes = &conn->secure.server_random[S2N_TLS_RANDOM_DATA_LEN - S2N_DOWNGRADE_PROTECTION_SIZE];
+
+ /* Detect downgrade attacks according to RFC 8446 section 4.1.3 */
+ if (conn->client_protocol_version == S2N_TLS13 && conn->server_protocol_version == S2N_TLS12) {
+ if (s2n_constant_time_equals(downgrade_bytes, tls12_downgrade_protection_bytes, S2N_DOWNGRADE_PROTECTION_SIZE)) {
+ S2N_ERROR(S2N_ERR_PROTOCOL_DOWNGRADE_DETECTED);
+ }
+ } else if (conn->client_protocol_version == S2N_TLS13 && conn->server_protocol_version <= S2N_TLS11) {
+ if (s2n_constant_time_equals(downgrade_bytes, tls11_downgrade_protection_bytes, S2N_DOWNGRADE_PROTECTION_SIZE)) {
+ S2N_ERROR(S2N_ERR_PROTOCOL_DOWNGRADE_DETECTED);
+ }
+ }
+
+ return 0;
+}
+
+static int s2n_server_add_downgrade_mechanism(struct s2n_connection *conn) {
+ notnull_check(conn);
+ uint8_t *downgrade_bytes = &conn->secure.server_random[S2N_TLS_RANDOM_DATA_LEN - S2N_DOWNGRADE_PROTECTION_SIZE];
+
+ /* Protect against downgrade attacks according to RFC 8446 section 4.1.3 */
+ if (conn->server_protocol_version >= S2N_TLS13 && conn->actual_protocol_version == S2N_TLS12) {
+ /* TLS1.3 servers MUST use a special random value when negotiating TLS1.2 */
+ memcpy_check(downgrade_bytes, tls12_downgrade_protection_bytes, S2N_DOWNGRADE_PROTECTION_SIZE);
+ } else if (conn->server_protocol_version >= S2N_TLS13 && conn->actual_protocol_version <= S2N_TLS11) {
+ /* TLS1.3 servers MUST, use a special random value when negotiating TLS1.1 or below */
+ memcpy_check(downgrade_bytes, tls11_downgrade_protection_bytes, S2N_DOWNGRADE_PROTECTION_SIZE);
+ }
+
+ return 0;
+}
+
+static int s2n_server_hello_parse(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ struct s2n_stuffer *in = &conn->handshake.io;
+ uint8_t compression_method;
+ uint8_t session_id_len;
+ uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN];
+ uint8_t session_id[S2N_TLS_SESSION_ID_MAX_LEN];
+
+ GUARD(s2n_stuffer_read_bytes(in, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
+ GUARD(s2n_stuffer_read_bytes(in, conn->secure.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) {
+ ENSURE_POSIX(!s2n_is_hello_retry_handshake(conn), S2N_ERR_INVALID_HELLO_RETRY);
+ GUARD(s2n_set_hello_retry_required(conn));
+ }
+
+ GUARD(s2n_stuffer_read_uint8(in, &session_id_len));
+ S2N_ERROR_IF(session_id_len > S2N_TLS_SESSION_ID_MAX_LEN, S2N_ERR_BAD_MESSAGE);
+ GUARD(s2n_stuffer_read_bytes(in, session_id, session_id_len));
+
+ uint8_t *cipher_suite_wire = s2n_stuffer_raw_read(in, S2N_TLS_CIPHER_SUITE_LEN);
+ notnull_check(cipher_suite_wire);
+
+ GUARD(s2n_stuffer_read_uint8(in, &compression_method));
+ S2N_ERROR_IF(compression_method != S2N_TLS_COMPRESSION_METHOD_NULL, S2N_ERR_BAD_MESSAGE);
+
+ GUARD(s2n_server_extensions_recv(conn, in));
+
+ if (conn->server_protocol_version >= S2N_TLS13) {
+ S2N_ERROR_IF(session_id_len != conn->session_id_len || memcmp(session_id, conn->session_id, session_id_len), S2N_ERR_BAD_MESSAGE);
+ conn->actual_protocol_version = conn->server_protocol_version;
+ GUARD(s2n_set_cipher_as_client(conn, cipher_suite_wire));
+ } else {
+ conn->server_protocol_version = (uint8_t)(protocol_version[0] * 10) + protocol_version[1];
+
+ S2N_ERROR_IF(s2n_client_detect_downgrade_mechanism(conn), S2N_ERR_PROTOCOL_DOWNGRADE_DETECTED);
+ ENSURE_POSIX(!conn->config->quic_enabled, S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED);
+
+ const struct s2n_security_policy *security_policy;
+ GUARD(s2n_connection_get_security_policy(conn, &security_policy));
+
+ if (conn->server_protocol_version < security_policy->minimum_protocol_version
+ || conn->server_protocol_version > conn->client_protocol_version) {
+ GUARD(s2n_queue_reader_unsupported_protocol_version_alert(conn));
+ S2N_ERROR(S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED);
+ }
+
+ uint8_t actual_protocol_version = MIN(conn->server_protocol_version, conn->client_protocol_version);
+ /* Use the session state if server sent same session id as client sent in client hello */
+ if (session_id_len != 0 && session_id_len == conn->session_id_len
+ && !memcmp(session_id, conn->session_id, session_id_len)) {
+ /* check if the resumed session state is valid */
+ S2N_ERROR_IF(conn->actual_protocol_version != actual_protocol_version, S2N_ERR_BAD_MESSAGE);
+ S2N_ERROR_IF(memcmp(conn->secure.cipher_suite->iana_value, cipher_suite_wire, S2N_TLS_CIPHER_SUITE_LEN) != 0, S2N_ERR_BAD_MESSAGE);
+
+ /* Session is resumed */
+ conn->client_session_resumed = 1;
+ } else {
+ conn->session_id_len = session_id_len;
+ memcpy_check(conn->session_id, session_id, session_id_len);
+ conn->actual_protocol_version = actual_protocol_version;
+ GUARD(s2n_set_cipher_as_client(conn, cipher_suite_wire));
+ /* Erase master secret which might have been set for session resumption */
+ memset_check((uint8_t *)conn->secure.master_secret, 0, S2N_TLS_SECRET_LEN);
+
+ /* Erase client session ticket which might have been set for session resumption */
+ GUARD(s2n_free(&conn->client_ticket));
+ }
+ }
+
+ return 0;
+}
+
+int s2n_server_hello_recv(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ /* Read the message off the wire */
+ GUARD(s2n_server_hello_parse(conn));
+
+ conn->actual_protocol_version_established = 1;
+
+ GUARD(s2n_conn_set_handshake_type(conn));
+
+ /* If this is a HelloRetryRequest, we don't process the ServerHello.
+ * Instead we proceed with retry logic. */
+ if (s2n_is_hello_retry_message(conn)) {
+ GUARD(s2n_server_hello_retry_recv(conn));
+ return 0;
+ }
+
+ if (IS_RESUMPTION_HANDSHAKE(conn->handshake.handshake_type)) {
+ GUARD(s2n_prf_key_expansion(conn));
+ }
+
+ /* Choose a default signature scheme */
+ GUARD(s2n_choose_default_sig_scheme(conn, &conn->secure.conn_sig_scheme));
+
+ /* Update the required hashes for this connection */
+ GUARD(s2n_conn_update_required_handshake_hashes(conn));
+
+ return 0;
+}
+
+int s2n_server_hello_write_message(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ /* The actual_protocol_version is set while processing the CLIENT_HELLO message, so
+ * it could be S2N_TLS13. SERVER_HELLO should always respond with the legacy version.
+ * https://tools.ietf.org/html/rfc8446#section-4.1.3 */
+ const uint16_t legacy_protocol_version = MIN(conn->actual_protocol_version, S2N_TLS12);
+ uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN];
+ protocol_version[0] = (uint8_t)(legacy_protocol_version / 10);
+ protocol_version[1] = (uint8_t)(legacy_protocol_version % 10);
+
+ GUARD(s2n_stuffer_write_bytes(&conn->handshake.io, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
+ GUARD(s2n_stuffer_write_bytes(&conn->handshake.io, conn->secure.server_random, S2N_TLS_RANDOM_DATA_LEN));
+ GUARD(s2n_stuffer_write_uint8(&conn->handshake.io, conn->session_id_len));
+ GUARD(s2n_stuffer_write_bytes(&conn->handshake.io, conn->session_id, conn->session_id_len));
+ GUARD(s2n_stuffer_write_bytes(&conn->handshake.io, conn->secure.cipher_suite->iana_value, S2N_TLS_CIPHER_SUITE_LEN));
+ GUARD(s2n_stuffer_write_uint8(&conn->handshake.io, S2N_TLS_COMPRESSION_METHOD_NULL));
+
+ return 0;
+}
+
+int s2n_server_hello_send(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ struct s2n_stuffer server_random = {0};
+ struct s2n_blob b = {0};
+ GUARD(s2n_blob_init(&b, conn->secure.server_random, S2N_TLS_RANDOM_DATA_LEN));
+
+ /* Create the server random data */
+ GUARD(s2n_stuffer_init(&server_random, &b));
+
+ struct s2n_blob rand_data = {0};
+ GUARD(s2n_blob_init(&rand_data, s2n_stuffer_raw_write(&server_random, S2N_TLS_RANDOM_DATA_LEN), S2N_TLS_RANDOM_DATA_LEN));
+ notnull_check(rand_data.data);
+ GUARD_AS_POSIX(s2n_get_public_random_data(&rand_data));
+
+ /* Add a downgrade detection mechanism if required */
+ GUARD(s2n_server_add_downgrade_mechanism(conn));
+
+ GUARD(s2n_server_hello_write_message(conn));
+
+ GUARD(s2n_server_extensions_send(conn, &conn->handshake.io));
+
+ conn->actual_protocol_version_established = 1;
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_server_hello_retry.c b/contrib/restricted/aws/s2n/tls/s2n_server_hello_retry.c
index 6bff554dee..f35c5a0016 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_server_hello_retry.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_server_hello_retry.c
@@ -1,131 +1,131 @@
-/*
- * 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 <stdbool.h>
-
-#include "error/s2n_errno.h"
-#include "utils/s2n_blob.h"
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_server_extensions.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls13.h"
-#include "tls/s2n_tls13_handshake.h"
-#include "utils/s2n_safety.h"
-#include "crypto/s2n_fips.h"
-
-/* From RFC5246 7.4.1.2. */
-#define S2N_TLS_COMPRESSION_METHOD_NULL 0
-
-/* from RFC: https://tools.ietf.org/html/rfc8446#section-4.1.3*/
-uint8_t hello_retry_req_random[S2N_TLS_RANDOM_DATA_LEN] = {
- 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, 0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91,
- 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E, 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C
-};
-
-static int s2n_conn_reset_retry_values(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- /* Reset handshake values */
- conn->handshake.client_hello_received = 0;
-
- /* Reset client hello state */
- GUARD(s2n_stuffer_wipe(&conn->client_hello.raw_message));
- GUARD(s2n_stuffer_resize(&conn->client_hello.raw_message, 0));
- GUARD(s2n_client_hello_free(&conn->client_hello));
- GUARD(s2n_stuffer_growable_alloc(&conn->client_hello.raw_message, 0));
-
- return 0;
-}
-
-int s2n_server_hello_retry_send(struct s2n_connection *conn)
-{
- notnull_check(conn);
-
- memcpy_check(conn->secure.server_random, hello_retry_req_random, S2N_TLS_RANDOM_DATA_LEN);
-
- GUARD(s2n_server_hello_write_message(conn));
-
- /* Write the extensions */
- GUARD(s2n_server_extensions_send(conn, &conn->handshake.io));
-
- /* Update transcript */
- GUARD(s2n_server_hello_retry_recreate_transcript(conn));
- GUARD(s2n_conn_reset_retry_values(conn));
-
- return 0;
-}
-
-int s2n_server_hello_retry_recv(struct s2n_connection *conn)
-{
- notnull_check(conn);
- ENSURE_POSIX(conn->actual_protocol_version >= S2N_TLS13, S2N_ERR_INVALID_HELLO_RETRY);
-
- const struct s2n_ecc_preferences *ecc_pref = NULL;
- GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
- notnull_check(ecc_pref);
-
- const struct s2n_kem_preferences *kem_pref = NULL;
- GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
- notnull_check(kem_pref);
-
- /* Upon receipt of the HelloRetryRequest, the client MUST verify that:
- * (1) the selected_group field corresponds to a group
- * which was provided in the "supported_groups" extension in the
- * original ClientHello and
- * (2) the selected_group field does not correspond to a group which was provided
- * in the "key_share" extension in the original ClientHello.
- * If either of these checks fails, then the client MUST abort the handshake. */
-
- bool match_found = false;
-
- const struct s2n_ecc_named_curve *named_curve = conn->secure.server_ecc_evp_params.negotiated_curve;
- const struct s2n_kem_group *kem_group = conn->secure.server_kem_group_params.kem_group;
-
- /* Boolean XOR check: exactly one of {named_curve, kem_group} should be non-null. */
- ENSURE_POSIX( (named_curve != NULL) != (kem_group != NULL), S2N_ERR_INVALID_HELLO_RETRY);
-
- if (named_curve != NULL) {
- for (size_t i = 0; i < ecc_pref->count; i++) {
- if (ecc_pref->ecc_curves[i] == named_curve) {
- match_found = true;
- ENSURE_POSIX(conn->secure.client_ecc_evp_params[i].evp_pkey == NULL, S2N_ERR_INVALID_HELLO_RETRY);
- break;
- }
- }
- }
-
- if (kem_group != NULL) {
- /* If in FIPS mode, the client should not have sent any PQ IDs
- * in the supported_groups list of the initial ClientHello */
- ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS);
-
- for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) {
- if (kem_pref->tls13_kem_groups[i] == kem_group) {
- match_found = true;
- ENSURE_POSIX(conn->secure.client_kem_group_params[i].kem_params.private_key.data == NULL,
- S2N_ERR_INVALID_HELLO_RETRY);
- ENSURE_POSIX(conn->secure.client_kem_group_params[i].ecc_params.evp_pkey == NULL,
- S2N_ERR_INVALID_HELLO_RETRY);
- }
- }
- }
-
- ENSURE_POSIX(match_found, S2N_ERR_INVALID_HELLO_RETRY);
-
- /* Update transcript hash */
- GUARD(s2n_server_hello_retry_recreate_transcript(conn));
-
- return S2N_SUCCESS;
-}
+/*
+ * 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 <stdbool.h>
+
+#include "error/s2n_errno.h"
+#include "utils/s2n_blob.h"
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_server_extensions.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls13.h"
+#include "tls/s2n_tls13_handshake.h"
+#include "utils/s2n_safety.h"
+#include "crypto/s2n_fips.h"
+
+/* From RFC5246 7.4.1.2. */
+#define S2N_TLS_COMPRESSION_METHOD_NULL 0
+
+/* from RFC: https://tools.ietf.org/html/rfc8446#section-4.1.3*/
+uint8_t hello_retry_req_random[S2N_TLS_RANDOM_DATA_LEN] = {
+ 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, 0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91,
+ 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E, 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C
+};
+
+static int s2n_conn_reset_retry_values(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ /* Reset handshake values */
+ conn->handshake.client_hello_received = 0;
+
+ /* Reset client hello state */
+ GUARD(s2n_stuffer_wipe(&conn->client_hello.raw_message));
+ GUARD(s2n_stuffer_resize(&conn->client_hello.raw_message, 0));
+ GUARD(s2n_client_hello_free(&conn->client_hello));
+ GUARD(s2n_stuffer_growable_alloc(&conn->client_hello.raw_message, 0));
+
+ return 0;
+}
+
+int s2n_server_hello_retry_send(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+
+ memcpy_check(conn->secure.server_random, hello_retry_req_random, S2N_TLS_RANDOM_DATA_LEN);
+
+ GUARD(s2n_server_hello_write_message(conn));
+
+ /* Write the extensions */
+ GUARD(s2n_server_extensions_send(conn, &conn->handshake.io));
+
+ /* Update transcript */
+ GUARD(s2n_server_hello_retry_recreate_transcript(conn));
+ GUARD(s2n_conn_reset_retry_values(conn));
+
+ return 0;
+}
+
+int s2n_server_hello_retry_recv(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+ ENSURE_POSIX(conn->actual_protocol_version >= S2N_TLS13, S2N_ERR_INVALID_HELLO_RETRY);
+
+ const struct s2n_ecc_preferences *ecc_pref = NULL;
+ GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
+ notnull_check(ecc_pref);
+
+ const struct s2n_kem_preferences *kem_pref = NULL;
+ GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref));
+ notnull_check(kem_pref);
+
+ /* Upon receipt of the HelloRetryRequest, the client MUST verify that:
+ * (1) the selected_group field corresponds to a group
+ * which was provided in the "supported_groups" extension in the
+ * original ClientHello and
+ * (2) the selected_group field does not correspond to a group which was provided
+ * in the "key_share" extension in the original ClientHello.
+ * If either of these checks fails, then the client MUST abort the handshake. */
+
+ bool match_found = false;
+
+ const struct s2n_ecc_named_curve *named_curve = conn->secure.server_ecc_evp_params.negotiated_curve;
+ const struct s2n_kem_group *kem_group = conn->secure.server_kem_group_params.kem_group;
+
+ /* Boolean XOR check: exactly one of {named_curve, kem_group} should be non-null. */
+ ENSURE_POSIX( (named_curve != NULL) != (kem_group != NULL), S2N_ERR_INVALID_HELLO_RETRY);
+
+ if (named_curve != NULL) {
+ for (size_t i = 0; i < ecc_pref->count; i++) {
+ if (ecc_pref->ecc_curves[i] == named_curve) {
+ match_found = true;
+ ENSURE_POSIX(conn->secure.client_ecc_evp_params[i].evp_pkey == NULL, S2N_ERR_INVALID_HELLO_RETRY);
+ break;
+ }
+ }
+ }
+
+ if (kem_group != NULL) {
+ /* If in FIPS mode, the client should not have sent any PQ IDs
+ * in the supported_groups list of the initial ClientHello */
+ ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS);
+
+ for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) {
+ if (kem_pref->tls13_kem_groups[i] == kem_group) {
+ match_found = true;
+ ENSURE_POSIX(conn->secure.client_kem_group_params[i].kem_params.private_key.data == NULL,
+ S2N_ERR_INVALID_HELLO_RETRY);
+ ENSURE_POSIX(conn->secure.client_kem_group_params[i].ecc_params.evp_pkey == NULL,
+ S2N_ERR_INVALID_HELLO_RETRY);
+ }
+ }
+ }
+
+ ENSURE_POSIX(match_found, S2N_ERR_INVALID_HELLO_RETRY);
+
+ /* Update transcript hash */
+ GUARD(s2n_server_hello_retry_recreate_transcript(conn));
+
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_server_key_exchange.c b/contrib/restricted/aws/s2n/tls/s2n_server_key_exchange.c
index 855d2373b1..2169f7c5e2 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_server_key_exchange.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_server_key_exchange.c
@@ -1,335 +1,335 @@
-/*
- * 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 <s2n.h>
-
-#include "error/s2n_errno.h"
-
-#include "tls/s2n_async_pkey.h"
-#include "tls/s2n_tls_digest_preferences.h"
-#include "tls/s2n_kem.h"
-#include "tls/s2n_kex.h"
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_signature_algorithms.h"
-#include "tls/s2n_cipher_preferences.h"
-#include "tls/s2n_security_policies.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "crypto/s2n_dhe.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_random.h"
-
-static int s2n_server_key_send_write_signature(struct s2n_connection *conn, struct s2n_blob *signature);
-
-int s2n_server_key_recv(struct s2n_connection *conn)
-{
- notnull_check(conn);
- notnull_check(conn->secure.cipher_suite);
- notnull_check(conn->secure.cipher_suite->key_exchange_alg);
-
- struct s2n_hash_state *signature_hash = &conn->secure.signature_hash;
- const struct s2n_kex *key_exchange = conn->secure.cipher_suite->key_exchange_alg;
- struct s2n_stuffer *in = &conn->handshake.io;
- struct s2n_blob data_to_verify = {0};
-
- /* Read the KEX data */
- struct s2n_kex_raw_server_data kex_data = {0};
- GUARD(s2n_kex_server_key_recv_read_data(key_exchange, conn, &data_to_verify, &kex_data));
-
- /* Add common signature data */
- struct s2n_signature_scheme active_sig_scheme;
- if (conn->actual_protocol_version == S2N_TLS12) {
- /* Verify the SigScheme picked by the Server was in the preference list we sent (or is the default SigScheme) */
- GUARD(s2n_get_and_validate_negotiated_signature_scheme(conn, in, &active_sig_scheme));
- } else {
- active_sig_scheme = conn->secure.conn_sig_scheme;
- }
- GUARD(s2n_hash_init(signature_hash, active_sig_scheme.hash_alg));
- GUARD(s2n_hash_update(signature_hash, conn->secure.client_random, S2N_TLS_RANDOM_DATA_LEN));
- GUARD(s2n_hash_update(signature_hash, conn->secure.server_random, S2N_TLS_RANDOM_DATA_LEN));
-
- /* Add KEX specific data */
- GUARD(s2n_hash_update(signature_hash, data_to_verify.data, data_to_verify.size));
-
- /* Verify the signature */
- uint16_t signature_length;
- GUARD(s2n_stuffer_read_uint16(in, &signature_length));
-
- struct s2n_blob signature = {.size = signature_length, .data = s2n_stuffer_raw_read(in, signature_length)};
- notnull_check(signature.data);
- gt_check(signature_length, 0);
-
- S2N_ERROR_IF(s2n_pkey_verify(&conn->secure.server_public_key, active_sig_scheme.sig_alg,signature_hash, &signature) < 0,
- S2N_ERR_BAD_MESSAGE);
-
- /* We don't need the key any more, so free it */
- GUARD(s2n_pkey_free(&conn->secure.server_public_key));
-
- /* Parse the KEX data into whatever form needed and save it to the connection object */
- GUARD(s2n_kex_server_key_recv_parse_data(key_exchange, conn, &kex_data));
- return 0;
-}
-
-int s2n_ecdhe_server_key_recv_read_data(struct s2n_connection *conn, struct s2n_blob *data_to_verify, struct s2n_kex_raw_server_data *raw_server_data)
-{
- struct s2n_stuffer *in = &conn->handshake.io;
-
- GUARD(s2n_ecc_evp_read_params(in, data_to_verify, &raw_server_data->ecdhe_data));
- return 0;
-}
-
-int s2n_ecdhe_server_key_recv_parse_data(struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data)
-{
- GUARD(s2n_ecc_evp_parse_params(&raw_server_data->ecdhe_data, &conn->secure.server_ecc_evp_params));
-
- return 0;
-}
-
-int s2n_dhe_server_key_recv_read_data(struct s2n_connection *conn, struct s2n_blob *data_to_verify, struct s2n_kex_raw_server_data *raw_server_data)
-{
- struct s2n_stuffer *in = &conn->handshake.io;
- struct s2n_dhe_raw_server_points *dhe_data = &raw_server_data->dhe_data;
-
- uint16_t p_length;
- uint16_t g_length;
- uint16_t Ys_length;
-
- /* Keep a copy to the start of the whole structure for the signature check */
- data_to_verify->data = s2n_stuffer_raw_read(in, 0);
- notnull_check(data_to_verify->data);
-
- /* Read each of the three elements in */
- GUARD(s2n_stuffer_read_uint16(in, &p_length));
- dhe_data->p.size = p_length;
- dhe_data->p.data = s2n_stuffer_raw_read(in, p_length);
- notnull_check(dhe_data->p.data);
-
- GUARD(s2n_stuffer_read_uint16(in, &g_length));
- dhe_data->g.size = g_length;
- dhe_data->g.data = s2n_stuffer_raw_read(in, g_length);
- notnull_check(dhe_data->g.data);
-
- GUARD(s2n_stuffer_read_uint16(in, &Ys_length));
- dhe_data->Ys.size = Ys_length;
- dhe_data->Ys.data = s2n_stuffer_raw_read(in, Ys_length);
- notnull_check(dhe_data->Ys.data);
-
- /* Now we know the total size of the structure */
- data_to_verify->size = 2 + p_length + 2 + g_length + 2 + Ys_length;
- return 0;
-}
-
-int s2n_dhe_server_key_recv_parse_data(struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data)
-{
- struct s2n_dhe_raw_server_points dhe_data = raw_server_data->dhe_data;
-
- /* Copy the DH details */
- GUARD(s2n_dh_p_g_Ys_to_dh_params(&conn->secure.server_dh_params, &dhe_data.p, &dhe_data.g, &dhe_data.Ys));
- return 0;
-}
-
-int s2n_kem_server_key_recv_read_data(struct s2n_connection *conn, struct s2n_blob *data_to_verify, struct s2n_kex_raw_server_data *raw_server_data)
-{
- struct s2n_kem_raw_server_params *kem_data = &raw_server_data->kem_data;
- struct s2n_stuffer *in = &conn->handshake.io;
-
- /* Keep a copy to the start of the whole structure for the signature check */
- data_to_verify->data = s2n_stuffer_raw_read(in, 0);
- notnull_check(data_to_verify->data);
-
- /* the server sends the KEM ID */
- kem_data->kem_name.data = s2n_stuffer_raw_read(in, 2);
- notnull_check(kem_data->kem_name.data);
- kem_data->kem_name.size = 2;
-
- struct s2n_stuffer kem_id_stuffer = { 0 };
- uint8_t kem_id_arr[2];
- kem_extension_size kem_id;
- struct s2n_blob kem_id_blob = { .data = kem_id_arr, .size = s2n_array_len(kem_id_arr) };
- GUARD(s2n_stuffer_init(&kem_id_stuffer, &kem_id_blob));
- GUARD(s2n_stuffer_write(&kem_id_stuffer, &(kem_data->kem_name)));
- GUARD(s2n_stuffer_read_uint16(&kem_id_stuffer, &kem_id));
-
- GUARD(s2n_get_kem_from_extension_id(kem_id, &(conn->secure.kem_params.kem)));
- GUARD(s2n_kem_recv_public_key(in, &(conn->secure.kem_params)));
-
- kem_data->raw_public_key.data = conn->secure.kem_params.public_key.data;
- kem_data->raw_public_key.size = conn->secure.kem_params.public_key.size;
-
- data_to_verify->size = sizeof(kem_extension_size) + sizeof(kem_public_key_size) + kem_data->raw_public_key.size;
-
- return 0;
-}
-
-int s2n_kem_server_key_recv_parse_data(struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data)
-{
- struct s2n_kem_raw_server_params *kem_data = &raw_server_data->kem_data;
-
- /* Check that the server's requested kem is supported by the client */
- const struct s2n_kem_preferences *kem_preferences = NULL;
- GUARD(s2n_connection_get_kem_preferences(conn, &kem_preferences));
- notnull_check(kem_preferences);
-
- const struct s2n_cipher_suite *cipher_suite = conn->secure.cipher_suite;
- const struct s2n_kem *match = NULL;
- S2N_ERROR_IF(s2n_choose_kem_with_peer_pref_list(cipher_suite->iana_value, &kem_data->kem_name, kem_preferences->kems,
- kem_preferences->kem_count, &match) != 0, S2N_ERR_KEM_UNSUPPORTED_PARAMS);
- conn->secure.kem_params.kem = match;
-
- S2N_ERROR_IF(kem_data->raw_public_key.size != conn->secure.kem_params.kem->public_key_length, S2N_ERR_BAD_MESSAGE);
-
- return 0;
-}
-
-int s2n_hybrid_server_key_recv_read_data(struct s2n_connection *conn, struct s2n_blob *total_data_to_verify, struct s2n_kex_raw_server_data *raw_server_data)
-{
- notnull_check(conn);
- notnull_check(conn->secure.cipher_suite);
- const struct s2n_kex *kex = conn->secure.cipher_suite->key_exchange_alg;
- const struct s2n_kex *hybrid_kex_0 = kex->hybrid[0];
- const struct s2n_kex *hybrid_kex_1 = kex->hybrid[1];
-
- /* Keep a copy to the start of the whole structure for the signature check */
- total_data_to_verify->data = s2n_stuffer_raw_read(&conn->handshake.io, 0);
- notnull_check(total_data_to_verify->data);
-
- struct s2n_blob data_to_verify_0 = {0};
- GUARD(s2n_kex_server_key_recv_read_data(hybrid_kex_0, conn, &data_to_verify_0, raw_server_data));
-
- struct s2n_blob data_to_verify_1 = {0};
- GUARD(s2n_kex_server_key_recv_read_data(hybrid_kex_1, conn, &data_to_verify_1, raw_server_data));
-
- total_data_to_verify->size = data_to_verify_0.size + data_to_verify_1.size;
- return 0;
-}
-
-int s2n_hybrid_server_key_recv_parse_data(struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data)
-{
- notnull_check(conn);
- notnull_check(conn->secure.cipher_suite);
- const struct s2n_kex *kex = conn->secure.cipher_suite->key_exchange_alg;
- const struct s2n_kex *hybrid_kex_0 = kex->hybrid[0];
- const struct s2n_kex *hybrid_kex_1 = kex->hybrid[1];
-
- GUARD(s2n_kex_server_key_recv_parse_data(hybrid_kex_0, conn, raw_server_data));
- GUARD(s2n_kex_server_key_recv_parse_data(hybrid_kex_1, conn, raw_server_data));
- return 0;
-}
-
-int s2n_server_key_send(struct s2n_connection *conn)
-{
- S2N_ASYNC_PKEY_GUARD(conn);
-
- struct s2n_hash_state *signature_hash = &conn->secure.signature_hash;
- const struct s2n_kex *key_exchange = conn->secure.cipher_suite->key_exchange_alg;
- struct s2n_stuffer *out = &conn->handshake.io;
- struct s2n_blob data_to_sign = {0};
-
- /* Call the negotiated key exchange method to send it's data */
- GUARD(s2n_kex_server_key_send(key_exchange, conn, &data_to_sign));
-
- /* Add common signature data */
- if (conn->actual_protocol_version == S2N_TLS12) {
- GUARD(s2n_stuffer_write_uint16(out, conn->secure.conn_sig_scheme.iana_value));
- }
-
- /* Add the random data to the hash */
- GUARD(s2n_hash_init(signature_hash, conn->secure.conn_sig_scheme.hash_alg));
- GUARD(s2n_hash_update(signature_hash, conn->secure.client_random, S2N_TLS_RANDOM_DATA_LEN));
- GUARD(s2n_hash_update(signature_hash, conn->secure.server_random, S2N_TLS_RANDOM_DATA_LEN));
-
- /* Add KEX specific data to the hash */
- GUARD(s2n_hash_update(signature_hash, data_to_sign.data, data_to_sign.size));
-
- S2N_ASYNC_PKEY_SIGN(conn, conn->secure.conn_sig_scheme.sig_alg, signature_hash, s2n_server_key_send_write_signature);
-}
-
-int s2n_ecdhe_server_key_send(struct s2n_connection *conn, struct s2n_blob *data_to_sign)
-{
- struct s2n_stuffer *out = &conn->handshake.io;
-
- /* Generate an ephemeral key and */
- GUARD(s2n_ecc_evp_generate_ephemeral_key(&conn->secure.server_ecc_evp_params));
-
- /* Write it out and calculate the data to sign later */
- GUARD(s2n_ecc_evp_write_params(&conn->secure.server_ecc_evp_params, out, data_to_sign));
- return 0;
-}
-
-int s2n_dhe_server_key_send(struct s2n_connection *conn, struct s2n_blob *data_to_sign)
-{
- struct s2n_stuffer *out = &conn->handshake.io;
-
- /* Duplicate the DH key from the config */
- GUARD(s2n_dh_params_copy(conn->config->dhparams, &conn->secure.server_dh_params));
-
- /* Generate an ephemeral key */
- GUARD(s2n_dh_generate_ephemeral_key(&conn->secure.server_dh_params));
-
- /* Write it out and calculate the data to sign later */
- GUARD(s2n_dh_params_to_p_g_Ys(&conn->secure.server_dh_params, out, data_to_sign));
- return 0;
-}
-
-int s2n_kem_server_key_send(struct s2n_connection *conn, struct s2n_blob *data_to_sign)
-{
- struct s2n_stuffer *out = &conn->handshake.io;
- const struct s2n_kem *kem = conn->secure.kem_params.kem;
-
- data_to_sign->data = s2n_stuffer_raw_write(out, 0);
- notnull_check(data_to_sign->data);
-
- GUARD(s2n_stuffer_write_uint16(out, kem->kem_extension_id));
- GUARD(s2n_kem_send_public_key(out, &(conn->secure.kem_params)));
-
- data_to_sign->size = sizeof(kem_extension_size) + sizeof(kem_public_key_size) + kem->public_key_length;
-
- return 0;
-}
-
-int s2n_hybrid_server_key_send(struct s2n_connection *conn, struct s2n_blob *total_data_to_sign)
-{
- notnull_check(conn);
- notnull_check(conn->secure.cipher_suite);
- const struct s2n_kex *kex = conn->secure.cipher_suite->key_exchange_alg;
- const struct s2n_kex *hybrid_kex_0 = kex->hybrid[0];
- const struct s2n_kex *hybrid_kex_1 = kex->hybrid[1];
-
- /* Keep a copy to the start of the whole structure for the signature check */
- total_data_to_sign->data = s2n_stuffer_raw_write(&conn->handshake.io, 0);
- notnull_check(total_data_to_sign->data);
-
- struct s2n_blob data_to_verify_0 = {0};
- GUARD(s2n_kex_server_key_send(hybrid_kex_0, conn, &data_to_verify_0));
-
- struct s2n_blob data_to_verify_1 = {0};
- GUARD(s2n_kex_server_key_send(hybrid_kex_1, conn, &data_to_verify_1));
-
- total_data_to_sign->size = data_to_verify_0.size + data_to_verify_1.size;
- return 0;
-}
-
-int s2n_server_key_send_write_signature(struct s2n_connection *conn, struct s2n_blob *signature)
-{
- struct s2n_stuffer *out = &conn->handshake.io;
-
- GUARD(s2n_stuffer_write_uint16(out, signature->size));
- GUARD(s2n_stuffer_write_bytes(out, signature->data, signature->size));
-
- return 0;
-}
+/*
+ * 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 <s2n.h>
+
+#include "error/s2n_errno.h"
+
+#include "tls/s2n_async_pkey.h"
+#include "tls/s2n_tls_digest_preferences.h"
+#include "tls/s2n_kem.h"
+#include "tls/s2n_kex.h"
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_signature_algorithms.h"
+#include "tls/s2n_cipher_preferences.h"
+#include "tls/s2n_security_policies.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "crypto/s2n_dhe.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_random.h"
+
+static int s2n_server_key_send_write_signature(struct s2n_connection *conn, struct s2n_blob *signature);
+
+int s2n_server_key_recv(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+ notnull_check(conn->secure.cipher_suite);
+ notnull_check(conn->secure.cipher_suite->key_exchange_alg);
+
+ struct s2n_hash_state *signature_hash = &conn->secure.signature_hash;
+ const struct s2n_kex *key_exchange = conn->secure.cipher_suite->key_exchange_alg;
+ struct s2n_stuffer *in = &conn->handshake.io;
+ struct s2n_blob data_to_verify = {0};
+
+ /* Read the KEX data */
+ struct s2n_kex_raw_server_data kex_data = {0};
+ GUARD(s2n_kex_server_key_recv_read_data(key_exchange, conn, &data_to_verify, &kex_data));
+
+ /* Add common signature data */
+ struct s2n_signature_scheme active_sig_scheme;
+ if (conn->actual_protocol_version == S2N_TLS12) {
+ /* Verify the SigScheme picked by the Server was in the preference list we sent (or is the default SigScheme) */
+ GUARD(s2n_get_and_validate_negotiated_signature_scheme(conn, in, &active_sig_scheme));
+ } else {
+ active_sig_scheme = conn->secure.conn_sig_scheme;
+ }
+ GUARD(s2n_hash_init(signature_hash, active_sig_scheme.hash_alg));
+ GUARD(s2n_hash_update(signature_hash, conn->secure.client_random, S2N_TLS_RANDOM_DATA_LEN));
+ GUARD(s2n_hash_update(signature_hash, conn->secure.server_random, S2N_TLS_RANDOM_DATA_LEN));
+
+ /* Add KEX specific data */
+ GUARD(s2n_hash_update(signature_hash, data_to_verify.data, data_to_verify.size));
+
+ /* Verify the signature */
+ uint16_t signature_length;
+ GUARD(s2n_stuffer_read_uint16(in, &signature_length));
+
+ struct s2n_blob signature = {.size = signature_length, .data = s2n_stuffer_raw_read(in, signature_length)};
+ notnull_check(signature.data);
+ gt_check(signature_length, 0);
+
+ S2N_ERROR_IF(s2n_pkey_verify(&conn->secure.server_public_key, active_sig_scheme.sig_alg,signature_hash, &signature) < 0,
+ S2N_ERR_BAD_MESSAGE);
+
+ /* We don't need the key any more, so free it */
+ GUARD(s2n_pkey_free(&conn->secure.server_public_key));
+
+ /* Parse the KEX data into whatever form needed and save it to the connection object */
+ GUARD(s2n_kex_server_key_recv_parse_data(key_exchange, conn, &kex_data));
+ return 0;
+}
+
+int s2n_ecdhe_server_key_recv_read_data(struct s2n_connection *conn, struct s2n_blob *data_to_verify, struct s2n_kex_raw_server_data *raw_server_data)
+{
+ struct s2n_stuffer *in = &conn->handshake.io;
+
+ GUARD(s2n_ecc_evp_read_params(in, data_to_verify, &raw_server_data->ecdhe_data));
+ return 0;
+}
+
+int s2n_ecdhe_server_key_recv_parse_data(struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data)
+{
+ GUARD(s2n_ecc_evp_parse_params(&raw_server_data->ecdhe_data, &conn->secure.server_ecc_evp_params));
+
+ return 0;
+}
+
+int s2n_dhe_server_key_recv_read_data(struct s2n_connection *conn, struct s2n_blob *data_to_verify, struct s2n_kex_raw_server_data *raw_server_data)
+{
+ struct s2n_stuffer *in = &conn->handshake.io;
+ struct s2n_dhe_raw_server_points *dhe_data = &raw_server_data->dhe_data;
+
+ uint16_t p_length;
+ uint16_t g_length;
+ uint16_t Ys_length;
+
+ /* Keep a copy to the start of the whole structure for the signature check */
+ data_to_verify->data = s2n_stuffer_raw_read(in, 0);
+ notnull_check(data_to_verify->data);
+
+ /* Read each of the three elements in */
+ GUARD(s2n_stuffer_read_uint16(in, &p_length));
+ dhe_data->p.size = p_length;
+ dhe_data->p.data = s2n_stuffer_raw_read(in, p_length);
+ notnull_check(dhe_data->p.data);
+
+ GUARD(s2n_stuffer_read_uint16(in, &g_length));
+ dhe_data->g.size = g_length;
+ dhe_data->g.data = s2n_stuffer_raw_read(in, g_length);
+ notnull_check(dhe_data->g.data);
+
+ GUARD(s2n_stuffer_read_uint16(in, &Ys_length));
+ dhe_data->Ys.size = Ys_length;
+ dhe_data->Ys.data = s2n_stuffer_raw_read(in, Ys_length);
+ notnull_check(dhe_data->Ys.data);
+
+ /* Now we know the total size of the structure */
+ data_to_verify->size = 2 + p_length + 2 + g_length + 2 + Ys_length;
+ return 0;
+}
+
+int s2n_dhe_server_key_recv_parse_data(struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data)
+{
+ struct s2n_dhe_raw_server_points dhe_data = raw_server_data->dhe_data;
+
+ /* Copy the DH details */
+ GUARD(s2n_dh_p_g_Ys_to_dh_params(&conn->secure.server_dh_params, &dhe_data.p, &dhe_data.g, &dhe_data.Ys));
+ return 0;
+}
+
+int s2n_kem_server_key_recv_read_data(struct s2n_connection *conn, struct s2n_blob *data_to_verify, struct s2n_kex_raw_server_data *raw_server_data)
+{
+ struct s2n_kem_raw_server_params *kem_data = &raw_server_data->kem_data;
+ struct s2n_stuffer *in = &conn->handshake.io;
+
+ /* Keep a copy to the start of the whole structure for the signature check */
+ data_to_verify->data = s2n_stuffer_raw_read(in, 0);
+ notnull_check(data_to_verify->data);
+
+ /* the server sends the KEM ID */
+ kem_data->kem_name.data = s2n_stuffer_raw_read(in, 2);
+ notnull_check(kem_data->kem_name.data);
+ kem_data->kem_name.size = 2;
+
+ struct s2n_stuffer kem_id_stuffer = { 0 };
+ uint8_t kem_id_arr[2];
+ kem_extension_size kem_id;
+ struct s2n_blob kem_id_blob = { .data = kem_id_arr, .size = s2n_array_len(kem_id_arr) };
+ GUARD(s2n_stuffer_init(&kem_id_stuffer, &kem_id_blob));
+ GUARD(s2n_stuffer_write(&kem_id_stuffer, &(kem_data->kem_name)));
+ GUARD(s2n_stuffer_read_uint16(&kem_id_stuffer, &kem_id));
+
+ GUARD(s2n_get_kem_from_extension_id(kem_id, &(conn->secure.kem_params.kem)));
+ GUARD(s2n_kem_recv_public_key(in, &(conn->secure.kem_params)));
+
+ kem_data->raw_public_key.data = conn->secure.kem_params.public_key.data;
+ kem_data->raw_public_key.size = conn->secure.kem_params.public_key.size;
+
+ data_to_verify->size = sizeof(kem_extension_size) + sizeof(kem_public_key_size) + kem_data->raw_public_key.size;
+
+ return 0;
+}
+
+int s2n_kem_server_key_recv_parse_data(struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data)
+{
+ struct s2n_kem_raw_server_params *kem_data = &raw_server_data->kem_data;
+
+ /* Check that the server's requested kem is supported by the client */
+ const struct s2n_kem_preferences *kem_preferences = NULL;
+ GUARD(s2n_connection_get_kem_preferences(conn, &kem_preferences));
+ notnull_check(kem_preferences);
+
+ const struct s2n_cipher_suite *cipher_suite = conn->secure.cipher_suite;
+ const struct s2n_kem *match = NULL;
+ S2N_ERROR_IF(s2n_choose_kem_with_peer_pref_list(cipher_suite->iana_value, &kem_data->kem_name, kem_preferences->kems,
+ kem_preferences->kem_count, &match) != 0, S2N_ERR_KEM_UNSUPPORTED_PARAMS);
+ conn->secure.kem_params.kem = match;
+
+ S2N_ERROR_IF(kem_data->raw_public_key.size != conn->secure.kem_params.kem->public_key_length, S2N_ERR_BAD_MESSAGE);
+
+ return 0;
+}
+
+int s2n_hybrid_server_key_recv_read_data(struct s2n_connection *conn, struct s2n_blob *total_data_to_verify, struct s2n_kex_raw_server_data *raw_server_data)
+{
+ notnull_check(conn);
+ notnull_check(conn->secure.cipher_suite);
+ const struct s2n_kex *kex = conn->secure.cipher_suite->key_exchange_alg;
+ const struct s2n_kex *hybrid_kex_0 = kex->hybrid[0];
+ const struct s2n_kex *hybrid_kex_1 = kex->hybrid[1];
+
+ /* Keep a copy to the start of the whole structure for the signature check */
+ total_data_to_verify->data = s2n_stuffer_raw_read(&conn->handshake.io, 0);
+ notnull_check(total_data_to_verify->data);
+
+ struct s2n_blob data_to_verify_0 = {0};
+ GUARD(s2n_kex_server_key_recv_read_data(hybrid_kex_0, conn, &data_to_verify_0, raw_server_data));
+
+ struct s2n_blob data_to_verify_1 = {0};
+ GUARD(s2n_kex_server_key_recv_read_data(hybrid_kex_1, conn, &data_to_verify_1, raw_server_data));
+
+ total_data_to_verify->size = data_to_verify_0.size + data_to_verify_1.size;
+ return 0;
+}
+
+int s2n_hybrid_server_key_recv_parse_data(struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data)
+{
+ notnull_check(conn);
+ notnull_check(conn->secure.cipher_suite);
+ const struct s2n_kex *kex = conn->secure.cipher_suite->key_exchange_alg;
+ const struct s2n_kex *hybrid_kex_0 = kex->hybrid[0];
+ const struct s2n_kex *hybrid_kex_1 = kex->hybrid[1];
+
+ GUARD(s2n_kex_server_key_recv_parse_data(hybrid_kex_0, conn, raw_server_data));
+ GUARD(s2n_kex_server_key_recv_parse_data(hybrid_kex_1, conn, raw_server_data));
+ return 0;
+}
+
+int s2n_server_key_send(struct s2n_connection *conn)
+{
+ S2N_ASYNC_PKEY_GUARD(conn);
+
+ struct s2n_hash_state *signature_hash = &conn->secure.signature_hash;
+ const struct s2n_kex *key_exchange = conn->secure.cipher_suite->key_exchange_alg;
+ struct s2n_stuffer *out = &conn->handshake.io;
+ struct s2n_blob data_to_sign = {0};
+
+ /* Call the negotiated key exchange method to send it's data */
+ GUARD(s2n_kex_server_key_send(key_exchange, conn, &data_to_sign));
+
+ /* Add common signature data */
+ if (conn->actual_protocol_version == S2N_TLS12) {
+ GUARD(s2n_stuffer_write_uint16(out, conn->secure.conn_sig_scheme.iana_value));
+ }
+
+ /* Add the random data to the hash */
+ GUARD(s2n_hash_init(signature_hash, conn->secure.conn_sig_scheme.hash_alg));
+ GUARD(s2n_hash_update(signature_hash, conn->secure.client_random, S2N_TLS_RANDOM_DATA_LEN));
+ GUARD(s2n_hash_update(signature_hash, conn->secure.server_random, S2N_TLS_RANDOM_DATA_LEN));
+
+ /* Add KEX specific data to the hash */
+ GUARD(s2n_hash_update(signature_hash, data_to_sign.data, data_to_sign.size));
+
+ S2N_ASYNC_PKEY_SIGN(conn, conn->secure.conn_sig_scheme.sig_alg, signature_hash, s2n_server_key_send_write_signature);
+}
+
+int s2n_ecdhe_server_key_send(struct s2n_connection *conn, struct s2n_blob *data_to_sign)
+{
+ struct s2n_stuffer *out = &conn->handshake.io;
+
+ /* Generate an ephemeral key and */
+ GUARD(s2n_ecc_evp_generate_ephemeral_key(&conn->secure.server_ecc_evp_params));
+
+ /* Write it out and calculate the data to sign later */
+ GUARD(s2n_ecc_evp_write_params(&conn->secure.server_ecc_evp_params, out, data_to_sign));
+ return 0;
+}
+
+int s2n_dhe_server_key_send(struct s2n_connection *conn, struct s2n_blob *data_to_sign)
+{
+ struct s2n_stuffer *out = &conn->handshake.io;
+
+ /* Duplicate the DH key from the config */
+ GUARD(s2n_dh_params_copy(conn->config->dhparams, &conn->secure.server_dh_params));
+
+ /* Generate an ephemeral key */
+ GUARD(s2n_dh_generate_ephemeral_key(&conn->secure.server_dh_params));
+
+ /* Write it out and calculate the data to sign later */
+ GUARD(s2n_dh_params_to_p_g_Ys(&conn->secure.server_dh_params, out, data_to_sign));
+ return 0;
+}
+
+int s2n_kem_server_key_send(struct s2n_connection *conn, struct s2n_blob *data_to_sign)
+{
+ struct s2n_stuffer *out = &conn->handshake.io;
+ const struct s2n_kem *kem = conn->secure.kem_params.kem;
+
+ data_to_sign->data = s2n_stuffer_raw_write(out, 0);
+ notnull_check(data_to_sign->data);
+
+ GUARD(s2n_stuffer_write_uint16(out, kem->kem_extension_id));
+ GUARD(s2n_kem_send_public_key(out, &(conn->secure.kem_params)));
+
+ data_to_sign->size = sizeof(kem_extension_size) + sizeof(kem_public_key_size) + kem->public_key_length;
+
+ return 0;
+}
+
+int s2n_hybrid_server_key_send(struct s2n_connection *conn, struct s2n_blob *total_data_to_sign)
+{
+ notnull_check(conn);
+ notnull_check(conn->secure.cipher_suite);
+ const struct s2n_kex *kex = conn->secure.cipher_suite->key_exchange_alg;
+ const struct s2n_kex *hybrid_kex_0 = kex->hybrid[0];
+ const struct s2n_kex *hybrid_kex_1 = kex->hybrid[1];
+
+ /* Keep a copy to the start of the whole structure for the signature check */
+ total_data_to_sign->data = s2n_stuffer_raw_write(&conn->handshake.io, 0);
+ notnull_check(total_data_to_sign->data);
+
+ struct s2n_blob data_to_verify_0 = {0};
+ GUARD(s2n_kex_server_key_send(hybrid_kex_0, conn, &data_to_verify_0));
+
+ struct s2n_blob data_to_verify_1 = {0};
+ GUARD(s2n_kex_server_key_send(hybrid_kex_1, conn, &data_to_verify_1));
+
+ total_data_to_sign->size = data_to_verify_0.size + data_to_verify_1.size;
+ return 0;
+}
+
+int s2n_server_key_send_write_signature(struct s2n_connection *conn, struct s2n_blob *signature)
+{
+ struct s2n_stuffer *out = &conn->handshake.io;
+
+ GUARD(s2n_stuffer_write_uint16(out, signature->size));
+ GUARD(s2n_stuffer_write_bytes(out, signature->data, signature->size));
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_server_key_exchange.h b/contrib/restricted/aws/s2n/tls/s2n_server_key_exchange.h
index 2c1deb9eba..2402bd3281 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_server_key_exchange.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_server_key_exchange.h
@@ -1,35 +1,35 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/s2n_connection.h"
-#include "tls/s2n_kex.h"
-#include "utils/s2n_blob.h"
-
-int s2n_dhe_server_key_recv_read_data(struct s2n_connection *conn, struct s2n_blob *data_to_verify, struct s2n_kex_raw_server_data *raw_server_data);
-int s2n_ecdhe_server_key_recv_read_data(struct s2n_connection *conn, struct s2n_blob *data_to_verify, struct s2n_kex_raw_server_data *raw_server_data);
-int s2n_kem_server_key_recv_read_data(struct s2n_connection *conn, struct s2n_blob *data_to_verify, struct s2n_kex_raw_server_data *raw_server_data);
-int s2n_hybrid_server_key_recv_read_data(struct s2n_connection *conn, struct s2n_blob *total_data_to_verify, struct s2n_kex_raw_server_data *raw_server_data);
-
-int s2n_dhe_server_key_recv_parse_data(struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data);
-int s2n_ecdhe_server_key_recv_parse_data(struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data);
-int s2n_kem_server_key_recv_parse_data(struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data);
-int s2n_hybrid_server_key_recv_parse_data(struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data);
-
-int s2n_dhe_server_key_send(struct s2n_connection *conn, struct s2n_blob *data_to_sign);
-int s2n_ecdhe_server_key_send(struct s2n_connection *conn, struct s2n_blob *data_to_sign);
-int s2n_kem_server_key_send(struct s2n_connection *conn, struct s2n_blob *data_to_sign);
-int s2n_hybrid_server_key_send(struct s2n_connection *conn, struct s2n_blob *data_to_sign);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/s2n_connection.h"
+#include "tls/s2n_kex.h"
+#include "utils/s2n_blob.h"
+
+int s2n_dhe_server_key_recv_read_data(struct s2n_connection *conn, struct s2n_blob *data_to_verify, struct s2n_kex_raw_server_data *raw_server_data);
+int s2n_ecdhe_server_key_recv_read_data(struct s2n_connection *conn, struct s2n_blob *data_to_verify, struct s2n_kex_raw_server_data *raw_server_data);
+int s2n_kem_server_key_recv_read_data(struct s2n_connection *conn, struct s2n_blob *data_to_verify, struct s2n_kex_raw_server_data *raw_server_data);
+int s2n_hybrid_server_key_recv_read_data(struct s2n_connection *conn, struct s2n_blob *total_data_to_verify, struct s2n_kex_raw_server_data *raw_server_data);
+
+int s2n_dhe_server_key_recv_parse_data(struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data);
+int s2n_ecdhe_server_key_recv_parse_data(struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data);
+int s2n_kem_server_key_recv_parse_data(struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data);
+int s2n_hybrid_server_key_recv_parse_data(struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data);
+
+int s2n_dhe_server_key_send(struct s2n_connection *conn, struct s2n_blob *data_to_sign);
+int s2n_ecdhe_server_key_send(struct s2n_connection *conn, struct s2n_blob *data_to_sign);
+int s2n_kem_server_key_send(struct s2n_connection *conn, struct s2n_blob *data_to_sign);
+int s2n_hybrid_server_key_send(struct s2n_connection *conn, struct s2n_blob *data_to_sign);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_server_new_session_ticket.c b/contrib/restricted/aws/s2n/tls/s2n_server_new_session_ticket.c
index 593a1efdba..a42c5029d2 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_server_new_session_ticket.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_server_new_session_ticket.c
@@ -1,76 +1,76 @@
-/*
- * 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 <sys/param.h>
-
-#include <s2n.h>
-#include <time.h>
-
-#include "error/s2n_errno.h"
-
-#include "tls/s2n_connection.h"
-#include "tls/s2n_alerts.h"
-#include "tls/s2n_tls.h"
-#include "tls/s2n_resume.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_random.h"
-
-int s2n_server_nst_recv(struct s2n_connection *conn) {
- GUARD(s2n_stuffer_read_uint32(&conn->handshake.io, &conn->ticket_lifetime_hint));
-
- uint16_t session_ticket_len;
- GUARD(s2n_stuffer_read_uint16(&conn->handshake.io, &session_ticket_len));
-
- if (session_ticket_len > 0) {
- GUARD(s2n_realloc(&conn->client_ticket, session_ticket_len));
-
- GUARD(s2n_stuffer_read(&conn->handshake.io, &conn->client_ticket));
- }
-
- return 0;
-}
-
-int s2n_server_nst_send(struct s2n_connection *conn)
-{
- uint16_t session_ticket_len = S2N_TICKET_SIZE_IN_BYTES;
- uint8_t data[S2N_TICKET_SIZE_IN_BYTES];
- struct s2n_blob entry = { .data = data, .size = sizeof(data) };
- struct s2n_stuffer to;
- uint32_t lifetime_hint_in_secs = (conn->config->encrypt_decrypt_key_lifetime_in_nanos + conn->config->decrypt_key_lifetime_in_nanos) / ONE_SEC_IN_NANOS;
-
- /* When server changes it's mind mid handshake send lifetime hint and session ticket length as zero */
- if (!conn->config->use_tickets) {
- GUARD(s2n_stuffer_write_uint32(&conn->handshake.io, 0));
- GUARD(s2n_stuffer_write_uint16(&conn->handshake.io, 0));
-
- return 0;
- }
-
- if (!s2n_server_sending_nst(conn)) {
- S2N_ERROR(S2N_ERR_SENDING_NST);
- }
-
- GUARD(s2n_stuffer_init(&to, &entry));
- GUARD(s2n_stuffer_write_uint32(&conn->handshake.io, lifetime_hint_in_secs));
- GUARD(s2n_stuffer_write_uint16(&conn->handshake.io, session_ticket_len));
-
- GUARD(s2n_encrypt_session_ticket(conn, &to));
- GUARD(s2n_stuffer_write(&conn->handshake.io, &to.blob));
-
- return 0;
-}
+/*
+ * 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 <sys/param.h>
+
+#include <s2n.h>
+#include <time.h>
+
+#include "error/s2n_errno.h"
+
+#include "tls/s2n_connection.h"
+#include "tls/s2n_alerts.h"
+#include "tls/s2n_tls.h"
+#include "tls/s2n_resume.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_random.h"
+
+int s2n_server_nst_recv(struct s2n_connection *conn) {
+ GUARD(s2n_stuffer_read_uint32(&conn->handshake.io, &conn->ticket_lifetime_hint));
+
+ uint16_t session_ticket_len;
+ GUARD(s2n_stuffer_read_uint16(&conn->handshake.io, &session_ticket_len));
+
+ if (session_ticket_len > 0) {
+ GUARD(s2n_realloc(&conn->client_ticket, session_ticket_len));
+
+ GUARD(s2n_stuffer_read(&conn->handshake.io, &conn->client_ticket));
+ }
+
+ return 0;
+}
+
+int s2n_server_nst_send(struct s2n_connection *conn)
+{
+ uint16_t session_ticket_len = S2N_TICKET_SIZE_IN_BYTES;
+ uint8_t data[S2N_TICKET_SIZE_IN_BYTES];
+ struct s2n_blob entry = { .data = data, .size = sizeof(data) };
+ struct s2n_stuffer to;
+ uint32_t lifetime_hint_in_secs = (conn->config->encrypt_decrypt_key_lifetime_in_nanos + conn->config->decrypt_key_lifetime_in_nanos) / ONE_SEC_IN_NANOS;
+
+ /* When server changes it's mind mid handshake send lifetime hint and session ticket length as zero */
+ if (!conn->config->use_tickets) {
+ GUARD(s2n_stuffer_write_uint32(&conn->handshake.io, 0));
+ GUARD(s2n_stuffer_write_uint16(&conn->handshake.io, 0));
+
+ return 0;
+ }
+
+ if (!s2n_server_sending_nst(conn)) {
+ S2N_ERROR(S2N_ERR_SENDING_NST);
+ }
+
+ GUARD(s2n_stuffer_init(&to, &entry));
+ GUARD(s2n_stuffer_write_uint32(&conn->handshake.io, lifetime_hint_in_secs));
+ GUARD(s2n_stuffer_write_uint16(&conn->handshake.io, session_ticket_len));
+
+ GUARD(s2n_encrypt_session_ticket(conn, &to));
+ GUARD(s2n_stuffer_write(&conn->handshake.io, &to.blob));
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_shutdown.c b/contrib/restricted/aws/s2n/tls/s2n_shutdown.c
index 4963e0e25d..700d94b1d1 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_shutdown.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_shutdown.c
@@ -1,55 +1,55 @@
-/*
- * 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 <s2n.h>
-
-#include "tls/s2n_alerts.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_tls.h"
-
-#include "utils/s2n_safety.h"
-
-int s2n_shutdown(struct s2n_connection *conn, s2n_blocked_status * more)
-{
- notnull_check(conn);
- notnull_check(more);
-
- /* Treat this call as a no-op if already wiped */
- if (conn->send == NULL && conn->recv == NULL) {
- return 0;
- }
-
- uint64_t elapsed;
- GUARD_AS_POSIX(s2n_timer_elapsed(conn->config, &conn->write_timer, &elapsed));
- S2N_ERROR_IF(elapsed < conn->delay, S2N_ERR_SHUTDOWN_PAUSED);
-
- /* Queue our close notify, once. Use warning level so clients don't give up */
- GUARD(s2n_queue_writer_close_alert_warning(conn));
-
- /* Write it */
- GUARD(s2n_flush(conn, more));
-
- /* Assume caller isn't interested in pending incoming data */
- if (conn->in_status == PLAINTEXT) {
- GUARD(s2n_stuffer_wipe(&conn->header_in));
- GUARD(s2n_stuffer_wipe(&conn->in));
- conn->in_status = ENCRYPTED;
- }
-
- /* Fails with S2N_ERR_SHUTDOWN_RECORD_TYPE or S2N_ERR_ALERT on receipt of anything but a close_notify */
- GUARD(s2n_recv_close_notify(conn, more));
-
- return 0;
-}
+/*
+ * 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 <s2n.h>
+
+#include "tls/s2n_alerts.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_tls.h"
+
+#include "utils/s2n_safety.h"
+
+int s2n_shutdown(struct s2n_connection *conn, s2n_blocked_status * more)
+{
+ notnull_check(conn);
+ notnull_check(more);
+
+ /* Treat this call as a no-op if already wiped */
+ if (conn->send == NULL && conn->recv == NULL) {
+ return 0;
+ }
+
+ uint64_t elapsed;
+ GUARD_AS_POSIX(s2n_timer_elapsed(conn->config, &conn->write_timer, &elapsed));
+ S2N_ERROR_IF(elapsed < conn->delay, S2N_ERR_SHUTDOWN_PAUSED);
+
+ /* Queue our close notify, once. Use warning level so clients don't give up */
+ GUARD(s2n_queue_writer_close_alert_warning(conn));
+
+ /* Write it */
+ GUARD(s2n_flush(conn, more));
+
+ /* Assume caller isn't interested in pending incoming data */
+ if (conn->in_status == PLAINTEXT) {
+ GUARD(s2n_stuffer_wipe(&conn->header_in));
+ GUARD(s2n_stuffer_wipe(&conn->in));
+ conn->in_status = ENCRYPTED;
+ }
+
+ /* Fails with S2N_ERR_SHUTDOWN_RECORD_TYPE or S2N_ERR_ALERT on receipt of anything but a close_notify */
+ GUARD(s2n_recv_close_notify(conn, more));
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.c b/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.c
index 310b48aeb0..4645eae5f1 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.c
@@ -1,290 +1,290 @@
-/*
- * 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 "crypto/s2n_rsa_signing.h"
-#include "crypto/s2n_rsa_pss.h"
-#include "error/s2n_errno.h"
-
-#include "tls/s2n_auth_selection.h"
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_kex.h"
-#include "tls/s2n_tls_digest_preferences.h"
-#include "tls/s2n_signature_algorithms.h"
-#include "tls/s2n_signature_scheme.h"
-#include "tls/s2n_security_policies.h"
-
-#include "utils/s2n_safety.h"
-
-static int s2n_signature_scheme_valid_to_offer(struct s2n_connection *conn, const struct s2n_signature_scheme *scheme)
-{
- /* We don't know what protocol version we will eventually negotiate, but we know that it won't be any higher. */
- gte_check(conn->actual_protocol_version, scheme->minimum_protocol_version);
-
- if (!s2n_is_rsa_pss_signing_supported()) {
- ne_check(scheme->sig_alg, S2N_SIGNATURE_RSA_PSS_RSAE);
- }
-
- if (!s2n_is_rsa_pss_certs_supported()) {
- ne_check(scheme->sig_alg, S2N_SIGNATURE_RSA_PSS_PSS);
- }
-
- return 0;
-}
-
-static int s2n_signature_scheme_valid_to_accept(struct s2n_connection *conn, const struct s2n_signature_scheme *scheme)
-{
- notnull_check(scheme);
-
- GUARD(s2n_signature_scheme_valid_to_offer(conn, scheme));
-
- if (scheme->maximum_protocol_version != S2N_UNKNOWN_PROTOCOL_VERSION) {
- lte_check(conn->actual_protocol_version, scheme->maximum_protocol_version);
- }
-
- return 0;
-}
-
-static int s2n_is_signature_scheme_usable(struct s2n_connection *conn, const struct s2n_signature_scheme *candidate) {
- notnull_check(conn);
- notnull_check(candidate);
-
- GUARD(s2n_signature_scheme_valid_to_accept(conn, candidate));
- GUARD(s2n_is_sig_scheme_valid_for_auth(conn, candidate));
-
- return S2N_SUCCESS;
-}
-
-static int s2n_choose_sig_scheme(struct s2n_connection *conn, struct s2n_sig_scheme_list *peer_wire_prefs,
- struct s2n_signature_scheme *chosen_scheme_out)
-{
- notnull_check(conn);
- const struct s2n_signature_preferences *signature_preferences = NULL;
- GUARD(s2n_connection_get_signature_preferences(conn, &signature_preferences));
- notnull_check(signature_preferences);
-
- struct s2n_cipher_suite *cipher_suite = conn->secure.cipher_suite;
- notnull_check(cipher_suite);
-
- for (size_t i = 0; i < signature_preferences->count; i++) {
- const struct s2n_signature_scheme *candidate = signature_preferences->signature_schemes[i];
-
- if (s2n_is_signature_scheme_usable(conn, candidate) != S2N_SUCCESS) {
- continue;
- }
-
- for (size_t j = 0; j < peer_wire_prefs->len; j++) {
- uint16_t their_iana_val = peer_wire_prefs->iana_list[j];
-
- if (candidate->iana_value == their_iana_val) {
- *chosen_scheme_out = *candidate;
- return S2N_SUCCESS;
- }
- }
- }
-
- /* do not error even if there's no match */
- return S2N_SUCCESS;
-}
-
-/* similar to s2n_choose_sig_scheme() without matching client's preference */
-static int s2n_tls13_default_sig_scheme(struct s2n_connection *conn, struct s2n_signature_scheme *chosen_scheme_out)
-{
- notnull_check(conn);
- const struct s2n_signature_preferences *signature_preferences = NULL;
- GUARD(s2n_connection_get_signature_preferences(conn, &signature_preferences));
- notnull_check(signature_preferences);
-
- struct s2n_cipher_suite *cipher_suite = conn->secure.cipher_suite;
- notnull_check(cipher_suite);
-
- for (size_t i = 0; i < signature_preferences->count; i++) {
- const struct s2n_signature_scheme *candidate = signature_preferences->signature_schemes[i];
-
- if (s2n_is_signature_scheme_usable(conn, candidate) != S2N_SUCCESS) {
- continue;
- }
-
- *chosen_scheme_out = *candidate;
- return S2N_SUCCESS;
- }
-
- S2N_ERROR(S2N_ERR_INVALID_SIGNATURE_SCHEME);
-}
-
-int s2n_get_and_validate_negotiated_signature_scheme(struct s2n_connection *conn, struct s2n_stuffer *in,
- struct s2n_signature_scheme *chosen_sig_scheme)
-{
- uint16_t actual_iana_val;
- GUARD(s2n_stuffer_read_uint16(in, &actual_iana_val));
-
- const struct s2n_signature_preferences *signature_preferences = NULL;
- GUARD(s2n_connection_get_signature_preferences(conn, &signature_preferences));
- notnull_check(signature_preferences);
-
- for (size_t i = 0; i < signature_preferences->count; i++) {
- const struct s2n_signature_scheme *candidate = signature_preferences->signature_schemes[i];
-
- if (0 != s2n_signature_scheme_valid_to_accept(conn, candidate)) {
- continue;
- }
-
- if (candidate->iana_value == actual_iana_val) {
- *chosen_sig_scheme = *candidate;
- return S2N_SUCCESS;
- }
- }
-
- /* We require an exact match in TLS 1.3, but all previous versions can fall back to the default SignatureScheme.
- * This means that an s2n client will accept the default SignatureScheme from a TLS server, even if the client did
- * not send it in it's ClientHello. This pre-TLS1.3 behavior is an intentional choice to maximize support. */
- struct s2n_signature_scheme default_scheme;
- GUARD(s2n_choose_default_sig_scheme(conn, &default_scheme));
-
- if ((conn->actual_protocol_version <= S2N_TLS12)
- && (s2n_signature_scheme_valid_to_accept(conn, &default_scheme) == S2N_SUCCESS)
- && (actual_iana_val == default_scheme.iana_value)) {
-
- *chosen_sig_scheme = default_scheme;
- return S2N_SUCCESS;
- }
-
- S2N_ERROR(S2N_ERR_INVALID_SIGNATURE_SCHEME);
-}
-
-int s2n_choose_default_sig_scheme(struct s2n_connection *conn, struct s2n_signature_scheme *sig_scheme_out)
-{
- notnull_check(conn);
- notnull_check(conn->secure.cipher_suite);
- notnull_check(sig_scheme_out);
-
- s2n_authentication_method cipher_suite_auth_method = conn->secure.cipher_suite->auth_method;
-
- /* Default our signature digest algorithms. For TLS 1.2 this default is different and may be
- * overridden by the signature_algorithms extension. If the server chooses an ECDHE_ECDSA
- * cipher suite, this will be overridden to SHA1.
- */
- *sig_scheme_out = s2n_rsa_pkcs1_md5_sha1;
-
- if (cipher_suite_auth_method == S2N_AUTHENTICATION_ECDSA) {
- *sig_scheme_out = s2n_ecdsa_sha1;
- }
-
- /* Default RSA Hash Algorithm is SHA1 (instead of MD5_SHA1) if TLS 1.2 or FIPS mode */
- if ((conn->actual_protocol_version >= S2N_TLS12 || s2n_is_in_fips_mode())
- && (sig_scheme_out->sig_alg == S2N_SIGNATURE_RSA)) {
- *sig_scheme_out = s2n_rsa_pkcs1_sha1;
- }
-
- return S2N_SUCCESS;
-}
-
-int s2n_choose_sig_scheme_from_peer_preference_list(struct s2n_connection *conn, struct s2n_sig_scheme_list *peer_wire_prefs,
- struct s2n_signature_scheme *sig_scheme_out)
-{
- notnull_check(conn);
- notnull_check(sig_scheme_out);
-
- struct s2n_signature_scheme chosen_scheme;
-
- if (conn->actual_protocol_version < S2N_TLS13) {
- GUARD(s2n_choose_default_sig_scheme(conn, &chosen_scheme));
- } else {
- /* Pick a default signature algorithm in TLS 1.3 https://tools.ietf.org/html/rfc8446#section-4.4.2.2 */
- GUARD(s2n_tls13_default_sig_scheme(conn, &chosen_scheme));
- }
-
- /* SignatureScheme preference list was first added in TLS 1.2. It will be empty in older TLS versions. */
- if (peer_wire_prefs != NULL && peer_wire_prefs->len > 0) {
- /* Use a best effort approach to selecting a signature scheme matching client's preferences */
- GUARD(s2n_choose_sig_scheme(conn, peer_wire_prefs, &chosen_scheme));
- }
-
- *sig_scheme_out = chosen_scheme;
-
- return S2N_SUCCESS;
-}
-
-int s2n_send_supported_sig_scheme_list(struct s2n_connection *conn, struct s2n_stuffer *out)
-{
- const struct s2n_signature_preferences *signature_preferences = NULL;
- GUARD(s2n_connection_get_signature_preferences(conn, &signature_preferences));
- notnull_check(signature_preferences);
-
- GUARD(s2n_stuffer_write_uint16(out, s2n_supported_sig_scheme_list_size(conn)));
-
- for (size_t i = 0; i < signature_preferences->count; i++) {
- const struct s2n_signature_scheme *const scheme = signature_preferences->signature_schemes[i];
- if (0 == s2n_signature_scheme_valid_to_offer(conn, scheme)) {
- GUARD(s2n_stuffer_write_uint16(out, scheme->iana_value));
- }
- }
-
- return 0;
-}
-
-int s2n_supported_sig_scheme_list_size(struct s2n_connection *conn)
-{
- return s2n_supported_sig_schemes_count(conn) * TLS_SIGNATURE_SCHEME_LEN;
-}
-
-int s2n_supported_sig_schemes_count(struct s2n_connection *conn)
-{
- const struct s2n_signature_preferences *signature_preferences = NULL;
- GUARD(s2n_connection_get_signature_preferences(conn, &signature_preferences));
- notnull_check(signature_preferences);
-
- uint8_t count = 0;
- for (size_t i = 0; i < signature_preferences->count; i++) {
- if (0 == s2n_signature_scheme_valid_to_offer(conn, signature_preferences->signature_schemes[i])) {
- count ++;
- }
- }
- return count;
-}
-
-int s2n_recv_supported_sig_scheme_list(struct s2n_stuffer *in, struct s2n_sig_scheme_list *sig_hash_algs)
-{
- uint16_t length_of_all_pairs;
- GUARD(s2n_stuffer_read_uint16(in, &length_of_all_pairs));
- if (length_of_all_pairs > s2n_stuffer_data_available(in)) {
- /* Malformed length, ignore the extension */
- return 0;
- }
-
- if (length_of_all_pairs % 2) {
- /* Pairs occur in two byte lengths. Malformed length, ignore the extension and skip ahead */
- GUARD(s2n_stuffer_skip_read(in, length_of_all_pairs));
- return 0;
- }
-
- int pairs_available = length_of_all_pairs / 2;
-
- if (pairs_available > TLS_SIGNATURE_SCHEME_LIST_MAX_LEN) {
- S2N_ERROR(S2N_ERR_TOO_MANY_SIGNATURE_SCHEMES);
- }
-
- sig_hash_algs->len = 0;
-
- for (size_t i = 0; i < pairs_available; i++) {
- uint16_t sig_scheme = 0;
- GUARD(s2n_stuffer_read_uint16(in, &sig_scheme));
-
- sig_hash_algs->iana_list[sig_hash_algs->len] = sig_scheme;
- sig_hash_algs->len += 1;
- }
-
- return 0;
-}
+/*
+ * 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 "crypto/s2n_rsa_signing.h"
+#include "crypto/s2n_rsa_pss.h"
+#include "error/s2n_errno.h"
+
+#include "tls/s2n_auth_selection.h"
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_kex.h"
+#include "tls/s2n_tls_digest_preferences.h"
+#include "tls/s2n_signature_algorithms.h"
+#include "tls/s2n_signature_scheme.h"
+#include "tls/s2n_security_policies.h"
+
+#include "utils/s2n_safety.h"
+
+static int s2n_signature_scheme_valid_to_offer(struct s2n_connection *conn, const struct s2n_signature_scheme *scheme)
+{
+ /* We don't know what protocol version we will eventually negotiate, but we know that it won't be any higher. */
+ gte_check(conn->actual_protocol_version, scheme->minimum_protocol_version);
+
+ if (!s2n_is_rsa_pss_signing_supported()) {
+ ne_check(scheme->sig_alg, S2N_SIGNATURE_RSA_PSS_RSAE);
+ }
+
+ if (!s2n_is_rsa_pss_certs_supported()) {
+ ne_check(scheme->sig_alg, S2N_SIGNATURE_RSA_PSS_PSS);
+ }
+
+ return 0;
+}
+
+static int s2n_signature_scheme_valid_to_accept(struct s2n_connection *conn, const struct s2n_signature_scheme *scheme)
+{
+ notnull_check(scheme);
+
+ GUARD(s2n_signature_scheme_valid_to_offer(conn, scheme));
+
+ if (scheme->maximum_protocol_version != S2N_UNKNOWN_PROTOCOL_VERSION) {
+ lte_check(conn->actual_protocol_version, scheme->maximum_protocol_version);
+ }
+
+ return 0;
+}
+
+static int s2n_is_signature_scheme_usable(struct s2n_connection *conn, const struct s2n_signature_scheme *candidate) {
+ notnull_check(conn);
+ notnull_check(candidate);
+
+ GUARD(s2n_signature_scheme_valid_to_accept(conn, candidate));
+ GUARD(s2n_is_sig_scheme_valid_for_auth(conn, candidate));
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_choose_sig_scheme(struct s2n_connection *conn, struct s2n_sig_scheme_list *peer_wire_prefs,
+ struct s2n_signature_scheme *chosen_scheme_out)
+{
+ notnull_check(conn);
+ const struct s2n_signature_preferences *signature_preferences = NULL;
+ GUARD(s2n_connection_get_signature_preferences(conn, &signature_preferences));
+ notnull_check(signature_preferences);
+
+ struct s2n_cipher_suite *cipher_suite = conn->secure.cipher_suite;
+ notnull_check(cipher_suite);
+
+ for (size_t i = 0; i < signature_preferences->count; i++) {
+ const struct s2n_signature_scheme *candidate = signature_preferences->signature_schemes[i];
+
+ if (s2n_is_signature_scheme_usable(conn, candidate) != S2N_SUCCESS) {
+ continue;
+ }
+
+ for (size_t j = 0; j < peer_wire_prefs->len; j++) {
+ uint16_t their_iana_val = peer_wire_prefs->iana_list[j];
+
+ if (candidate->iana_value == their_iana_val) {
+ *chosen_scheme_out = *candidate;
+ return S2N_SUCCESS;
+ }
+ }
+ }
+
+ /* do not error even if there's no match */
+ return S2N_SUCCESS;
+}
+
+/* similar to s2n_choose_sig_scheme() without matching client's preference */
+static int s2n_tls13_default_sig_scheme(struct s2n_connection *conn, struct s2n_signature_scheme *chosen_scheme_out)
+{
+ notnull_check(conn);
+ const struct s2n_signature_preferences *signature_preferences = NULL;
+ GUARD(s2n_connection_get_signature_preferences(conn, &signature_preferences));
+ notnull_check(signature_preferences);
+
+ struct s2n_cipher_suite *cipher_suite = conn->secure.cipher_suite;
+ notnull_check(cipher_suite);
+
+ for (size_t i = 0; i < signature_preferences->count; i++) {
+ const struct s2n_signature_scheme *candidate = signature_preferences->signature_schemes[i];
+
+ if (s2n_is_signature_scheme_usable(conn, candidate) != S2N_SUCCESS) {
+ continue;
+ }
+
+ *chosen_scheme_out = *candidate;
+ return S2N_SUCCESS;
+ }
+
+ S2N_ERROR(S2N_ERR_INVALID_SIGNATURE_SCHEME);
+}
+
+int s2n_get_and_validate_negotiated_signature_scheme(struct s2n_connection *conn, struct s2n_stuffer *in,
+ struct s2n_signature_scheme *chosen_sig_scheme)
+{
+ uint16_t actual_iana_val;
+ GUARD(s2n_stuffer_read_uint16(in, &actual_iana_val));
+
+ const struct s2n_signature_preferences *signature_preferences = NULL;
+ GUARD(s2n_connection_get_signature_preferences(conn, &signature_preferences));
+ notnull_check(signature_preferences);
+
+ for (size_t i = 0; i < signature_preferences->count; i++) {
+ const struct s2n_signature_scheme *candidate = signature_preferences->signature_schemes[i];
+
+ if (0 != s2n_signature_scheme_valid_to_accept(conn, candidate)) {
+ continue;
+ }
+
+ if (candidate->iana_value == actual_iana_val) {
+ *chosen_sig_scheme = *candidate;
+ return S2N_SUCCESS;
+ }
+ }
+
+ /* We require an exact match in TLS 1.3, but all previous versions can fall back to the default SignatureScheme.
+ * This means that an s2n client will accept the default SignatureScheme from a TLS server, even if the client did
+ * not send it in it's ClientHello. This pre-TLS1.3 behavior is an intentional choice to maximize support. */
+ struct s2n_signature_scheme default_scheme;
+ GUARD(s2n_choose_default_sig_scheme(conn, &default_scheme));
+
+ if ((conn->actual_protocol_version <= S2N_TLS12)
+ && (s2n_signature_scheme_valid_to_accept(conn, &default_scheme) == S2N_SUCCESS)
+ && (actual_iana_val == default_scheme.iana_value)) {
+
+ *chosen_sig_scheme = default_scheme;
+ return S2N_SUCCESS;
+ }
+
+ S2N_ERROR(S2N_ERR_INVALID_SIGNATURE_SCHEME);
+}
+
+int s2n_choose_default_sig_scheme(struct s2n_connection *conn, struct s2n_signature_scheme *sig_scheme_out)
+{
+ notnull_check(conn);
+ notnull_check(conn->secure.cipher_suite);
+ notnull_check(sig_scheme_out);
+
+ s2n_authentication_method cipher_suite_auth_method = conn->secure.cipher_suite->auth_method;
+
+ /* Default our signature digest algorithms. For TLS 1.2 this default is different and may be
+ * overridden by the signature_algorithms extension. If the server chooses an ECDHE_ECDSA
+ * cipher suite, this will be overridden to SHA1.
+ */
+ *sig_scheme_out = s2n_rsa_pkcs1_md5_sha1;
+
+ if (cipher_suite_auth_method == S2N_AUTHENTICATION_ECDSA) {
+ *sig_scheme_out = s2n_ecdsa_sha1;
+ }
+
+ /* Default RSA Hash Algorithm is SHA1 (instead of MD5_SHA1) if TLS 1.2 or FIPS mode */
+ if ((conn->actual_protocol_version >= S2N_TLS12 || s2n_is_in_fips_mode())
+ && (sig_scheme_out->sig_alg == S2N_SIGNATURE_RSA)) {
+ *sig_scheme_out = s2n_rsa_pkcs1_sha1;
+ }
+
+ return S2N_SUCCESS;
+}
+
+int s2n_choose_sig_scheme_from_peer_preference_list(struct s2n_connection *conn, struct s2n_sig_scheme_list *peer_wire_prefs,
+ struct s2n_signature_scheme *sig_scheme_out)
+{
+ notnull_check(conn);
+ notnull_check(sig_scheme_out);
+
+ struct s2n_signature_scheme chosen_scheme;
+
+ if (conn->actual_protocol_version < S2N_TLS13) {
+ GUARD(s2n_choose_default_sig_scheme(conn, &chosen_scheme));
+ } else {
+ /* Pick a default signature algorithm in TLS 1.3 https://tools.ietf.org/html/rfc8446#section-4.4.2.2 */
+ GUARD(s2n_tls13_default_sig_scheme(conn, &chosen_scheme));
+ }
+
+ /* SignatureScheme preference list was first added in TLS 1.2. It will be empty in older TLS versions. */
+ if (peer_wire_prefs != NULL && peer_wire_prefs->len > 0) {
+ /* Use a best effort approach to selecting a signature scheme matching client's preferences */
+ GUARD(s2n_choose_sig_scheme(conn, peer_wire_prefs, &chosen_scheme));
+ }
+
+ *sig_scheme_out = chosen_scheme;
+
+ return S2N_SUCCESS;
+}
+
+int s2n_send_supported_sig_scheme_list(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ const struct s2n_signature_preferences *signature_preferences = NULL;
+ GUARD(s2n_connection_get_signature_preferences(conn, &signature_preferences));
+ notnull_check(signature_preferences);
+
+ GUARD(s2n_stuffer_write_uint16(out, s2n_supported_sig_scheme_list_size(conn)));
+
+ for (size_t i = 0; i < signature_preferences->count; i++) {
+ const struct s2n_signature_scheme *const scheme = signature_preferences->signature_schemes[i];
+ if (0 == s2n_signature_scheme_valid_to_offer(conn, scheme)) {
+ GUARD(s2n_stuffer_write_uint16(out, scheme->iana_value));
+ }
+ }
+
+ return 0;
+}
+
+int s2n_supported_sig_scheme_list_size(struct s2n_connection *conn)
+{
+ return s2n_supported_sig_schemes_count(conn) * TLS_SIGNATURE_SCHEME_LEN;
+}
+
+int s2n_supported_sig_schemes_count(struct s2n_connection *conn)
+{
+ const struct s2n_signature_preferences *signature_preferences = NULL;
+ GUARD(s2n_connection_get_signature_preferences(conn, &signature_preferences));
+ notnull_check(signature_preferences);
+
+ uint8_t count = 0;
+ for (size_t i = 0; i < signature_preferences->count; i++) {
+ if (0 == s2n_signature_scheme_valid_to_offer(conn, signature_preferences->signature_schemes[i])) {
+ count ++;
+ }
+ }
+ return count;
+}
+
+int s2n_recv_supported_sig_scheme_list(struct s2n_stuffer *in, struct s2n_sig_scheme_list *sig_hash_algs)
+{
+ uint16_t length_of_all_pairs;
+ GUARD(s2n_stuffer_read_uint16(in, &length_of_all_pairs));
+ if (length_of_all_pairs > s2n_stuffer_data_available(in)) {
+ /* Malformed length, ignore the extension */
+ return 0;
+ }
+
+ if (length_of_all_pairs % 2) {
+ /* Pairs occur in two byte lengths. Malformed length, ignore the extension and skip ahead */
+ GUARD(s2n_stuffer_skip_read(in, length_of_all_pairs));
+ return 0;
+ }
+
+ int pairs_available = length_of_all_pairs / 2;
+
+ if (pairs_available > TLS_SIGNATURE_SCHEME_LIST_MAX_LEN) {
+ S2N_ERROR(S2N_ERR_TOO_MANY_SIGNATURE_SCHEMES);
+ }
+
+ sig_hash_algs->len = 0;
+
+ for (size_t i = 0; i < pairs_available; i++) {
+ uint16_t sig_scheme = 0;
+ GUARD(s2n_stuffer_read_uint16(in, &sig_scheme));
+
+ sig_hash_algs->iana_list[sig_hash_algs->len] = sig_scheme;
+ sig_hash_algs->len += 1;
+ }
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.h b/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.h
index 123c4266d9..b400977a16 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.h
@@ -1,41 +1,41 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <s2n.h>
-
-#include "crypto/s2n_hash.h"
-#include "crypto/s2n_signature.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-struct s2n_connection;
-
-struct s2n_sig_scheme_list {
- uint16_t iana_list[TLS_SIGNATURE_SCHEME_LIST_MAX_LEN];
- uint8_t len;
-};
-
-int s2n_choose_default_sig_scheme(struct s2n_connection *conn, struct s2n_signature_scheme *sig_scheme_out);
-int s2n_choose_sig_scheme_from_peer_preference_list(struct s2n_connection *conn, struct s2n_sig_scheme_list *sig_hash_algs,
- struct s2n_signature_scheme *sig_scheme_out);
-int s2n_get_and_validate_negotiated_signature_scheme(struct s2n_connection *conn, struct s2n_stuffer *in,
- struct s2n_signature_scheme *chosen_sig_scheme);
-
-int s2n_recv_supported_sig_scheme_list(struct s2n_stuffer *in, struct s2n_sig_scheme_list *sig_hash_algs);
-int s2n_send_supported_sig_scheme_list(struct s2n_connection *conn, struct s2n_stuffer *out);
-int s2n_supported_sig_schemes_count(struct s2n_connection *conn);
-int s2n_supported_sig_scheme_list_size(struct s2n_connection *conn);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <s2n.h>
+
+#include "crypto/s2n_hash.h"
+#include "crypto/s2n_signature.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+struct s2n_connection;
+
+struct s2n_sig_scheme_list {
+ uint16_t iana_list[TLS_SIGNATURE_SCHEME_LIST_MAX_LEN];
+ uint8_t len;
+};
+
+int s2n_choose_default_sig_scheme(struct s2n_connection *conn, struct s2n_signature_scheme *sig_scheme_out);
+int s2n_choose_sig_scheme_from_peer_preference_list(struct s2n_connection *conn, struct s2n_sig_scheme_list *sig_hash_algs,
+ struct s2n_signature_scheme *sig_scheme_out);
+int s2n_get_and_validate_negotiated_signature_scheme(struct s2n_connection *conn, struct s2n_stuffer *in,
+ struct s2n_signature_scheme *chosen_sig_scheme);
+
+int s2n_recv_supported_sig_scheme_list(struct s2n_stuffer *in, struct s2n_sig_scheme_list *sig_hash_algs);
+int s2n_send_supported_sig_scheme_list(struct s2n_connection *conn, struct s2n_stuffer *out);
+int s2n_supported_sig_schemes_count(struct s2n_connection *conn);
+int s2n_supported_sig_scheme_list_size(struct s2n_connection *conn);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.c b/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.c
index 3f3ad6dfd4..911e717127 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.c
@@ -1,341 +1,341 @@
-/*
- * 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 <s2n.h>
-
-#include "crypto/s2n_hash.h"
-#include "crypto/s2n_signature.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_signature_scheme.h"
-#include "crypto/s2n_ecc_evp.h"
-#include "utils/s2n_safety.h"
-
-/* RSA PKCS1 */
-const struct s2n_signature_scheme s2n_rsa_pkcs1_md5_sha1 = {
- .iana_value = TLS_SIGNATURE_SCHEME_PRIVATE_INTERNAL_RSA_PKCS1_MD5_SHA1,
- .hash_alg = S2N_HASH_MD5_SHA1,
- .sig_alg = S2N_SIGNATURE_RSA,
- .libcrypto_nid = NID_md5_sha1,
- .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
- .maximum_protocol_version = S2N_TLS12, /* TLS1.3 does not support pkcs1 or sha1 */
-};
-
-const struct s2n_signature_scheme s2n_rsa_pkcs1_sha1 = {
- .iana_value = TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA1,
- .hash_alg = S2N_HASH_SHA1,
- .sig_alg = S2N_SIGNATURE_RSA,
- .libcrypto_nid = NID_sha1WithRSAEncryption,
- .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
- .maximum_protocol_version = S2N_TLS12, /* TLS1.3 does not support pkcs1 or sha1 */
-};
-
-const struct s2n_signature_scheme s2n_rsa_pkcs1_sha224 = {
- .iana_value = TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA224,
- .hash_alg = S2N_HASH_SHA224,
- .sig_alg = S2N_SIGNATURE_RSA,
- .libcrypto_nid = NID_sha224WithRSAEncryption,
- .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
- .maximum_protocol_version = S2N_TLS12, /* TLS1.3 does not support pkcs1 */
-};
-
-const struct s2n_signature_scheme s2n_rsa_pkcs1_sha256 = {
- .iana_value = TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA256,
- .hash_alg = S2N_HASH_SHA256,
- .sig_alg = S2N_SIGNATURE_RSA,
- .libcrypto_nid = NID_sha256WithRSAEncryption,
- .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
- .maximum_protocol_version = S2N_TLS12, /* TLS1.3 does not support pkcs1 */
-};
-
-const struct s2n_signature_scheme s2n_rsa_pkcs1_sha384 = {
- .iana_value = TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA384,
- .hash_alg = S2N_HASH_SHA384,
- .sig_alg = S2N_SIGNATURE_RSA,
- .libcrypto_nid = NID_sha384WithRSAEncryption,
- .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
- .maximum_protocol_version = S2N_TLS12, /* TLS1.3 does not support pkcs1 */
-};
-
-const struct s2n_signature_scheme s2n_rsa_pkcs1_sha512 = {
- .iana_value = TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA512,
- .hash_alg = S2N_HASH_SHA512,
- .sig_alg = S2N_SIGNATURE_RSA,
- .libcrypto_nid = NID_sha512WithRSAEncryption,
- .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
- .maximum_protocol_version = S2N_TLS12, /* TLS1.3 does not support pkcs1 */
-};
-
-/* TLS 1.2 Compatible ECDSA Signature Schemes */
-const struct s2n_signature_scheme s2n_ecdsa_sha1 = {
- .iana_value = TLS_SIGNATURE_SCHEME_ECDSA_SHA1,
- .hash_alg = S2N_HASH_SHA1,
- .sig_alg = S2N_SIGNATURE_ECDSA,
- .libcrypto_nid = NID_ecdsa_with_SHA1,
- .signature_curve = NULL, /* Decided by supported_groups Extension in TLS 1.2 and before */
- .maximum_protocol_version = S2N_TLS12, /* TLS1.3 does not support sha1 and requires a signature curve */
-};
-
-const struct s2n_signature_scheme s2n_ecdsa_sha224 = {
- .iana_value = TLS_SIGNATURE_SCHEME_ECDSA_SHA224,
- .hash_alg = S2N_HASH_SHA224,
- .sig_alg = S2N_SIGNATURE_ECDSA,
- .libcrypto_nid = NID_ecdsa_with_SHA224,
- .signature_curve = NULL, /* Decided by supported_groups Extension in TLS 1.2 and before */
- .maximum_protocol_version = S2N_TLS12, /* TLS1.3 requires a signature curve */
-};
-
-const struct s2n_signature_scheme s2n_ecdsa_sha256 = {
- .iana_value = TLS_SIGNATURE_SCHEME_ECDSA_SHA256,
- .hash_alg = S2N_HASH_SHA256,
- .sig_alg = S2N_SIGNATURE_ECDSA,
- .libcrypto_nid = NID_ecdsa_with_SHA256,
- .signature_curve = NULL, /* Decided by supported_groups Extension in TLS 1.2 and before */
- .maximum_protocol_version = S2N_TLS12, /* TLS1.3 requires a signature curve */
-};
-
-const struct s2n_signature_scheme s2n_ecdsa_sha384 = {
- .iana_value = TLS_SIGNATURE_SCHEME_ECDSA_SHA384,
- .hash_alg = S2N_HASH_SHA384,
- .sig_alg = S2N_SIGNATURE_ECDSA,
- .libcrypto_nid = NID_ecdsa_with_SHA384,
- .signature_curve = NULL, /* Decided by supported_groups Extension in TLS 1.2 and before */
- .maximum_protocol_version = S2N_TLS12, /* TLS1.3 requires a signature curve */
-};
-
-const struct s2n_signature_scheme s2n_ecdsa_sha512 = {
- .iana_value = TLS_SIGNATURE_SCHEME_ECDSA_SHA512,
- .hash_alg = S2N_HASH_SHA512,
- .sig_alg = S2N_SIGNATURE_ECDSA,
- .libcrypto_nid = NID_ecdsa_with_SHA512,
- .signature_curve = NULL, /* Decided by supported_groups Extension in TLS 1.2 and before */
- .maximum_protocol_version = S2N_TLS12, /* TLS1.3 requires a signature curve */
-};
-
-/* TLS 1.3 Compatible ECDSA Schemes */
-/* In TLS 1.3 the two byte IANA value also defines the Curve to use for signing */
-
-const struct s2n_signature_scheme s2n_ecdsa_secp256r1_sha256 = {
- .iana_value = TLS_SIGNATURE_SCHEME_ECDSA_SECP256R1_SHA256,
- .hash_alg = S2N_HASH_SHA256,
- .sig_alg = S2N_SIGNATURE_ECDSA,
- .libcrypto_nid = NID_ecdsa_with_SHA256,
- .signature_curve = &s2n_ecc_curve_secp256r1, /* Hardcoded as of TLS 1.3 */
- .minimum_protocol_version = S2N_TLS13,
-};
-
-const struct s2n_signature_scheme s2n_ecdsa_secp384r1_sha384 = {
- .iana_value = TLS_SIGNATURE_SCHEME_ECDSA_SECP384R1_SHA384,
- .hash_alg = S2N_HASH_SHA384,
- .sig_alg = S2N_SIGNATURE_ECDSA,
- .libcrypto_nid = NID_ecdsa_with_SHA384,
- .signature_curve = &s2n_ecc_curve_secp384r1, /* Hardcoded as of TLS 1.3 */
- .minimum_protocol_version = S2N_TLS13,
-};
-
-const struct s2n_signature_scheme s2n_ecdsa_secp521r1_sha512 = {
- .iana_value = TLS_SIGNATURE_SCHEME_ECDSA_SECP521R1_SHA512,
- .hash_alg = S2N_HASH_SHA512,
- .sig_alg = S2N_SIGNATURE_ECDSA,
- .signature_curve = &s2n_ecc_curve_secp521r1, /* Hardcoded as of TLS 1.3 */
- .minimum_protocol_version = S2N_TLS13,
-};
-
-/**
- * RSA-PSS-RSAE
- */
-const struct s2n_signature_scheme s2n_rsa_pss_rsae_sha256 = {
- .iana_value = TLS_SIGNATURE_SCHEME_RSA_PSS_RSAE_SHA256,
- .hash_alg = S2N_HASH_SHA256,
- .sig_alg = S2N_SIGNATURE_RSA_PSS_RSAE,
- .libcrypto_nid = NID_rsassaPss,
- .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
-};
-
-const struct s2n_signature_scheme s2n_rsa_pss_rsae_sha384 = {
- .iana_value = TLS_SIGNATURE_SCHEME_RSA_PSS_RSAE_SHA384,
- .hash_alg = S2N_HASH_SHA384,
- .sig_alg = S2N_SIGNATURE_RSA_PSS_RSAE,
- .libcrypto_nid = NID_rsassaPss,
- .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
-};
-
-const struct s2n_signature_scheme s2n_rsa_pss_rsae_sha512 = {
- .iana_value = TLS_SIGNATURE_SCHEME_RSA_PSS_RSAE_SHA512,
- .hash_alg = S2N_HASH_SHA512,
- .sig_alg = S2N_SIGNATURE_RSA_PSS_RSAE,
- .libcrypto_nid = NID_rsassaPss,
- .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
-};
-
-/**
- * RSA-PSS-PSS
- */
-const struct s2n_signature_scheme s2n_rsa_pss_pss_sha256 = {
- .iana_value = TLS_SIGNATURE_SCHEME_RSA_PSS_PSS_SHA256,
- .hash_alg = S2N_HASH_SHA256,
- .sig_alg = S2N_SIGNATURE_RSA_PSS_PSS,
- .libcrypto_nid = NID_rsassaPss,
- .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
- .minimum_protocol_version = S2N_TLS13,
-};
-
-const struct s2n_signature_scheme s2n_rsa_pss_pss_sha384 = {
- .iana_value = TLS_SIGNATURE_SCHEME_RSA_PSS_PSS_SHA384,
- .hash_alg = S2N_HASH_SHA384,
- .sig_alg = S2N_SIGNATURE_RSA_PSS_PSS,
- .libcrypto_nid = NID_rsassaPss,
- .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
- .minimum_protocol_version = S2N_TLS13,
-};
-
-const struct s2n_signature_scheme s2n_rsa_pss_pss_sha512 = {
- .iana_value = TLS_SIGNATURE_SCHEME_RSA_PSS_PSS_SHA512,
- .hash_alg = S2N_HASH_SHA512,
- .sig_alg = S2N_SIGNATURE_RSA_PSS_PSS,
- .libcrypto_nid = NID_rsassaPss,
- .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
- .minimum_protocol_version = S2N_TLS13,
-};
-
-/* All Supported SignatureSchemes. */
-/* No MD5 to avoid SLOTH Vulnerability */
-const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_20140601[] = {
- /* RSA PKCS1 */
- &s2n_rsa_pkcs1_sha256,
- &s2n_rsa_pkcs1_sha384,
- &s2n_rsa_pkcs1_sha512,
- &s2n_rsa_pkcs1_sha224,
-
- /* ECDSA - TLS 1.2 */
- &s2n_ecdsa_sha256, /* same iana value as TLS 1.3 s2n_ecdsa_secp256r1_sha256 */
- &s2n_ecdsa_secp256r1_sha256,
- &s2n_ecdsa_sha384, /* same iana value as TLS 1.3 s2n_ecdsa_secp384r1_sha384 */
- &s2n_ecdsa_secp384r1_sha384,
- &s2n_ecdsa_sha512,
- &s2n_ecdsa_sha224,
-
- /* SHA-1 Legacy */
- &s2n_rsa_pkcs1_sha1,
- &s2n_ecdsa_sha1,
-};
-
-/* The original preference list, but with rsa_pss supported. */
-const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_20200207[] = {
- /* RSA PSS */
- &s2n_rsa_pss_pss_sha256,
- &s2n_rsa_pss_pss_sha384,
- &s2n_rsa_pss_pss_sha512,
- &s2n_rsa_pss_rsae_sha256,
- &s2n_rsa_pss_rsae_sha384,
- &s2n_rsa_pss_rsae_sha512,
-
- /* RSA PKCS1 */
- &s2n_rsa_pkcs1_sha256,
- &s2n_rsa_pkcs1_sha384,
- &s2n_rsa_pkcs1_sha512,
- &s2n_rsa_pkcs1_sha224,
-
- /* ECDSA - TLS 1.2 */
- &s2n_ecdsa_sha256, /* same iana value as TLS 1.3 s2n_ecdsa_secp256r1_sha256 */
- &s2n_ecdsa_secp256r1_sha256,
- &s2n_ecdsa_sha384, /* same iana value as TLS 1.3 s2n_ecdsa_secp384r1_sha384 */
- &s2n_ecdsa_secp384r1_sha384,
- &s2n_ecdsa_sha512,
- &s2n_ecdsa_sha224,
-
- /* SHA-1 Legacy */
- &s2n_rsa_pkcs1_sha1,
- &s2n_ecdsa_sha1,
-};
-
-/* Add s2n_ecdsa_secp521r1_sha512 */
-const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_20201021[] = {
- /* RSA PSS */
- &s2n_rsa_pss_pss_sha256,
- &s2n_rsa_pss_pss_sha384,
- &s2n_rsa_pss_pss_sha512,
- &s2n_rsa_pss_rsae_sha256,
- &s2n_rsa_pss_rsae_sha384,
- &s2n_rsa_pss_rsae_sha512,
-
- /* RSA PKCS1 */
- &s2n_rsa_pkcs1_sha256,
- &s2n_rsa_pkcs1_sha384,
- &s2n_rsa_pkcs1_sha512,
- &s2n_rsa_pkcs1_sha224,
-
- /* ECDSA - TLS 1.2 */
- &s2n_ecdsa_sha256, /* same iana value as TLS 1.3 s2n_ecdsa_secp256r1_sha256 */
- &s2n_ecdsa_secp256r1_sha256,
- &s2n_ecdsa_sha384, /* same iana value as TLS 1.3 s2n_ecdsa_secp384r1_sha384 */
- &s2n_ecdsa_secp384r1_sha384,
- &s2n_ecdsa_sha512, /* same iana value as TLS 1.3 s2n_ecdsa_secp521r1_sha512 */
- &s2n_ecdsa_secp521r1_sha512,
- &s2n_ecdsa_sha224,
-
- /* SHA-1 Legacy */
- &s2n_rsa_pkcs1_sha1,
- &s2n_ecdsa_sha1,
-};
-
-const struct s2n_signature_preferences s2n_signature_preferences_20140601 = {
- .count = s2n_array_len(s2n_sig_scheme_pref_list_20140601),
- .signature_schemes = s2n_sig_scheme_pref_list_20140601,
-};
-
-const struct s2n_signature_preferences s2n_signature_preferences_20200207 = {
- .count = s2n_array_len(s2n_sig_scheme_pref_list_20200207),
- .signature_schemes = s2n_sig_scheme_pref_list_20200207,
-};
-
-const struct s2n_signature_preferences s2n_signature_preferences_20201021 = {
- .count = s2n_array_len(s2n_sig_scheme_pref_list_20201021),
- .signature_schemes = s2n_sig_scheme_pref_list_20201021,
-};
-
-const struct s2n_signature_preferences s2n_signature_preferences_null = {
- .count = 0,
- .signature_schemes = NULL,
-};
-
-/* TLS1.3 supported signature schemes, without SHA-1 legacy algorithms */
-const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_20201110[] = {
- /* RSA PSS */
- &s2n_rsa_pss_pss_sha256,
- &s2n_rsa_pss_pss_sha384,
- &s2n_rsa_pss_pss_sha512,
- &s2n_rsa_pss_rsae_sha256,
- &s2n_rsa_pss_rsae_sha384,
- &s2n_rsa_pss_rsae_sha512,
-
- /* RSA PKCS1 */
- &s2n_rsa_pkcs1_sha256,
- &s2n_rsa_pkcs1_sha384,
- &s2n_rsa_pkcs1_sha512,
- &s2n_rsa_pkcs1_sha224,
-
- /* ECDSA - TLS 1.2 */
- &s2n_ecdsa_sha256, /* same iana value as TLS 1.3 s2n_ecdsa_secp256r1_sha256 */
- &s2n_ecdsa_secp256r1_sha256,
- &s2n_ecdsa_sha384, /* same iana value as TLS 1.3 s2n_ecdsa_secp384r1_sha384 */
- &s2n_ecdsa_secp384r1_sha384,
- &s2n_ecdsa_sha512,
- &s2n_ecdsa_sha224,
-};
-
-const struct s2n_signature_preferences s2n_certificate_signature_preferences_20201110 = {
- .count = s2n_array_len(s2n_sig_scheme_pref_list_20201110),
- .signature_schemes = s2n_sig_scheme_pref_list_20201110,
-};
+/*
+ * 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 <s2n.h>
+
+#include "crypto/s2n_hash.h"
+#include "crypto/s2n_signature.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_signature_scheme.h"
+#include "crypto/s2n_ecc_evp.h"
+#include "utils/s2n_safety.h"
+
+/* RSA PKCS1 */
+const struct s2n_signature_scheme s2n_rsa_pkcs1_md5_sha1 = {
+ .iana_value = TLS_SIGNATURE_SCHEME_PRIVATE_INTERNAL_RSA_PKCS1_MD5_SHA1,
+ .hash_alg = S2N_HASH_MD5_SHA1,
+ .sig_alg = S2N_SIGNATURE_RSA,
+ .libcrypto_nid = NID_md5_sha1,
+ .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
+ .maximum_protocol_version = S2N_TLS12, /* TLS1.3 does not support pkcs1 or sha1 */
+};
+
+const struct s2n_signature_scheme s2n_rsa_pkcs1_sha1 = {
+ .iana_value = TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA1,
+ .hash_alg = S2N_HASH_SHA1,
+ .sig_alg = S2N_SIGNATURE_RSA,
+ .libcrypto_nid = NID_sha1WithRSAEncryption,
+ .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
+ .maximum_protocol_version = S2N_TLS12, /* TLS1.3 does not support pkcs1 or sha1 */
+};
+
+const struct s2n_signature_scheme s2n_rsa_pkcs1_sha224 = {
+ .iana_value = TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA224,
+ .hash_alg = S2N_HASH_SHA224,
+ .sig_alg = S2N_SIGNATURE_RSA,
+ .libcrypto_nid = NID_sha224WithRSAEncryption,
+ .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
+ .maximum_protocol_version = S2N_TLS12, /* TLS1.3 does not support pkcs1 */
+};
+
+const struct s2n_signature_scheme s2n_rsa_pkcs1_sha256 = {
+ .iana_value = TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA256,
+ .hash_alg = S2N_HASH_SHA256,
+ .sig_alg = S2N_SIGNATURE_RSA,
+ .libcrypto_nid = NID_sha256WithRSAEncryption,
+ .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
+ .maximum_protocol_version = S2N_TLS12, /* TLS1.3 does not support pkcs1 */
+};
+
+const struct s2n_signature_scheme s2n_rsa_pkcs1_sha384 = {
+ .iana_value = TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA384,
+ .hash_alg = S2N_HASH_SHA384,
+ .sig_alg = S2N_SIGNATURE_RSA,
+ .libcrypto_nid = NID_sha384WithRSAEncryption,
+ .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
+ .maximum_protocol_version = S2N_TLS12, /* TLS1.3 does not support pkcs1 */
+};
+
+const struct s2n_signature_scheme s2n_rsa_pkcs1_sha512 = {
+ .iana_value = TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA512,
+ .hash_alg = S2N_HASH_SHA512,
+ .sig_alg = S2N_SIGNATURE_RSA,
+ .libcrypto_nid = NID_sha512WithRSAEncryption,
+ .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
+ .maximum_protocol_version = S2N_TLS12, /* TLS1.3 does not support pkcs1 */
+};
+
+/* TLS 1.2 Compatible ECDSA Signature Schemes */
+const struct s2n_signature_scheme s2n_ecdsa_sha1 = {
+ .iana_value = TLS_SIGNATURE_SCHEME_ECDSA_SHA1,
+ .hash_alg = S2N_HASH_SHA1,
+ .sig_alg = S2N_SIGNATURE_ECDSA,
+ .libcrypto_nid = NID_ecdsa_with_SHA1,
+ .signature_curve = NULL, /* Decided by supported_groups Extension in TLS 1.2 and before */
+ .maximum_protocol_version = S2N_TLS12, /* TLS1.3 does not support sha1 and requires a signature curve */
+};
+
+const struct s2n_signature_scheme s2n_ecdsa_sha224 = {
+ .iana_value = TLS_SIGNATURE_SCHEME_ECDSA_SHA224,
+ .hash_alg = S2N_HASH_SHA224,
+ .sig_alg = S2N_SIGNATURE_ECDSA,
+ .libcrypto_nid = NID_ecdsa_with_SHA224,
+ .signature_curve = NULL, /* Decided by supported_groups Extension in TLS 1.2 and before */
+ .maximum_protocol_version = S2N_TLS12, /* TLS1.3 requires a signature curve */
+};
+
+const struct s2n_signature_scheme s2n_ecdsa_sha256 = {
+ .iana_value = TLS_SIGNATURE_SCHEME_ECDSA_SHA256,
+ .hash_alg = S2N_HASH_SHA256,
+ .sig_alg = S2N_SIGNATURE_ECDSA,
+ .libcrypto_nid = NID_ecdsa_with_SHA256,
+ .signature_curve = NULL, /* Decided by supported_groups Extension in TLS 1.2 and before */
+ .maximum_protocol_version = S2N_TLS12, /* TLS1.3 requires a signature curve */
+};
+
+const struct s2n_signature_scheme s2n_ecdsa_sha384 = {
+ .iana_value = TLS_SIGNATURE_SCHEME_ECDSA_SHA384,
+ .hash_alg = S2N_HASH_SHA384,
+ .sig_alg = S2N_SIGNATURE_ECDSA,
+ .libcrypto_nid = NID_ecdsa_with_SHA384,
+ .signature_curve = NULL, /* Decided by supported_groups Extension in TLS 1.2 and before */
+ .maximum_protocol_version = S2N_TLS12, /* TLS1.3 requires a signature curve */
+};
+
+const struct s2n_signature_scheme s2n_ecdsa_sha512 = {
+ .iana_value = TLS_SIGNATURE_SCHEME_ECDSA_SHA512,
+ .hash_alg = S2N_HASH_SHA512,
+ .sig_alg = S2N_SIGNATURE_ECDSA,
+ .libcrypto_nid = NID_ecdsa_with_SHA512,
+ .signature_curve = NULL, /* Decided by supported_groups Extension in TLS 1.2 and before */
+ .maximum_protocol_version = S2N_TLS12, /* TLS1.3 requires a signature curve */
+};
+
+/* TLS 1.3 Compatible ECDSA Schemes */
+/* In TLS 1.3 the two byte IANA value also defines the Curve to use for signing */
+
+const struct s2n_signature_scheme s2n_ecdsa_secp256r1_sha256 = {
+ .iana_value = TLS_SIGNATURE_SCHEME_ECDSA_SECP256R1_SHA256,
+ .hash_alg = S2N_HASH_SHA256,
+ .sig_alg = S2N_SIGNATURE_ECDSA,
+ .libcrypto_nid = NID_ecdsa_with_SHA256,
+ .signature_curve = &s2n_ecc_curve_secp256r1, /* Hardcoded as of TLS 1.3 */
+ .minimum_protocol_version = S2N_TLS13,
+};
+
+const struct s2n_signature_scheme s2n_ecdsa_secp384r1_sha384 = {
+ .iana_value = TLS_SIGNATURE_SCHEME_ECDSA_SECP384R1_SHA384,
+ .hash_alg = S2N_HASH_SHA384,
+ .sig_alg = S2N_SIGNATURE_ECDSA,
+ .libcrypto_nid = NID_ecdsa_with_SHA384,
+ .signature_curve = &s2n_ecc_curve_secp384r1, /* Hardcoded as of TLS 1.3 */
+ .minimum_protocol_version = S2N_TLS13,
+};
+
+const struct s2n_signature_scheme s2n_ecdsa_secp521r1_sha512 = {
+ .iana_value = TLS_SIGNATURE_SCHEME_ECDSA_SECP521R1_SHA512,
+ .hash_alg = S2N_HASH_SHA512,
+ .sig_alg = S2N_SIGNATURE_ECDSA,
+ .signature_curve = &s2n_ecc_curve_secp521r1, /* Hardcoded as of TLS 1.3 */
+ .minimum_protocol_version = S2N_TLS13,
+};
+
+/**
+ * RSA-PSS-RSAE
+ */
+const struct s2n_signature_scheme s2n_rsa_pss_rsae_sha256 = {
+ .iana_value = TLS_SIGNATURE_SCHEME_RSA_PSS_RSAE_SHA256,
+ .hash_alg = S2N_HASH_SHA256,
+ .sig_alg = S2N_SIGNATURE_RSA_PSS_RSAE,
+ .libcrypto_nid = NID_rsassaPss,
+ .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
+};
+
+const struct s2n_signature_scheme s2n_rsa_pss_rsae_sha384 = {
+ .iana_value = TLS_SIGNATURE_SCHEME_RSA_PSS_RSAE_SHA384,
+ .hash_alg = S2N_HASH_SHA384,
+ .sig_alg = S2N_SIGNATURE_RSA_PSS_RSAE,
+ .libcrypto_nid = NID_rsassaPss,
+ .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
+};
+
+const struct s2n_signature_scheme s2n_rsa_pss_rsae_sha512 = {
+ .iana_value = TLS_SIGNATURE_SCHEME_RSA_PSS_RSAE_SHA512,
+ .hash_alg = S2N_HASH_SHA512,
+ .sig_alg = S2N_SIGNATURE_RSA_PSS_RSAE,
+ .libcrypto_nid = NID_rsassaPss,
+ .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
+};
+
+/**
+ * RSA-PSS-PSS
+ */
+const struct s2n_signature_scheme s2n_rsa_pss_pss_sha256 = {
+ .iana_value = TLS_SIGNATURE_SCHEME_RSA_PSS_PSS_SHA256,
+ .hash_alg = S2N_HASH_SHA256,
+ .sig_alg = S2N_SIGNATURE_RSA_PSS_PSS,
+ .libcrypto_nid = NID_rsassaPss,
+ .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
+ .minimum_protocol_version = S2N_TLS13,
+};
+
+const struct s2n_signature_scheme s2n_rsa_pss_pss_sha384 = {
+ .iana_value = TLS_SIGNATURE_SCHEME_RSA_PSS_PSS_SHA384,
+ .hash_alg = S2N_HASH_SHA384,
+ .sig_alg = S2N_SIGNATURE_RSA_PSS_PSS,
+ .libcrypto_nid = NID_rsassaPss,
+ .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
+ .minimum_protocol_version = S2N_TLS13,
+};
+
+const struct s2n_signature_scheme s2n_rsa_pss_pss_sha512 = {
+ .iana_value = TLS_SIGNATURE_SCHEME_RSA_PSS_PSS_SHA512,
+ .hash_alg = S2N_HASH_SHA512,
+ .sig_alg = S2N_SIGNATURE_RSA_PSS_PSS,
+ .libcrypto_nid = NID_rsassaPss,
+ .signature_curve = NULL, /* Elliptic Curve not needed for RSA */
+ .minimum_protocol_version = S2N_TLS13,
+};
+
+/* All Supported SignatureSchemes. */
+/* No MD5 to avoid SLOTH Vulnerability */
+const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_20140601[] = {
+ /* RSA PKCS1 */
+ &s2n_rsa_pkcs1_sha256,
+ &s2n_rsa_pkcs1_sha384,
+ &s2n_rsa_pkcs1_sha512,
+ &s2n_rsa_pkcs1_sha224,
+
+ /* ECDSA - TLS 1.2 */
+ &s2n_ecdsa_sha256, /* same iana value as TLS 1.3 s2n_ecdsa_secp256r1_sha256 */
+ &s2n_ecdsa_secp256r1_sha256,
+ &s2n_ecdsa_sha384, /* same iana value as TLS 1.3 s2n_ecdsa_secp384r1_sha384 */
+ &s2n_ecdsa_secp384r1_sha384,
+ &s2n_ecdsa_sha512,
+ &s2n_ecdsa_sha224,
+
+ /* SHA-1 Legacy */
+ &s2n_rsa_pkcs1_sha1,
+ &s2n_ecdsa_sha1,
+};
+
+/* The original preference list, but with rsa_pss supported. */
+const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_20200207[] = {
+ /* RSA PSS */
+ &s2n_rsa_pss_pss_sha256,
+ &s2n_rsa_pss_pss_sha384,
+ &s2n_rsa_pss_pss_sha512,
+ &s2n_rsa_pss_rsae_sha256,
+ &s2n_rsa_pss_rsae_sha384,
+ &s2n_rsa_pss_rsae_sha512,
+
+ /* RSA PKCS1 */
+ &s2n_rsa_pkcs1_sha256,
+ &s2n_rsa_pkcs1_sha384,
+ &s2n_rsa_pkcs1_sha512,
+ &s2n_rsa_pkcs1_sha224,
+
+ /* ECDSA - TLS 1.2 */
+ &s2n_ecdsa_sha256, /* same iana value as TLS 1.3 s2n_ecdsa_secp256r1_sha256 */
+ &s2n_ecdsa_secp256r1_sha256,
+ &s2n_ecdsa_sha384, /* same iana value as TLS 1.3 s2n_ecdsa_secp384r1_sha384 */
+ &s2n_ecdsa_secp384r1_sha384,
+ &s2n_ecdsa_sha512,
+ &s2n_ecdsa_sha224,
+
+ /* SHA-1 Legacy */
+ &s2n_rsa_pkcs1_sha1,
+ &s2n_ecdsa_sha1,
+};
+
+/* Add s2n_ecdsa_secp521r1_sha512 */
+const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_20201021[] = {
+ /* RSA PSS */
+ &s2n_rsa_pss_pss_sha256,
+ &s2n_rsa_pss_pss_sha384,
+ &s2n_rsa_pss_pss_sha512,
+ &s2n_rsa_pss_rsae_sha256,
+ &s2n_rsa_pss_rsae_sha384,
+ &s2n_rsa_pss_rsae_sha512,
+
+ /* RSA PKCS1 */
+ &s2n_rsa_pkcs1_sha256,
+ &s2n_rsa_pkcs1_sha384,
+ &s2n_rsa_pkcs1_sha512,
+ &s2n_rsa_pkcs1_sha224,
+
+ /* ECDSA - TLS 1.2 */
+ &s2n_ecdsa_sha256, /* same iana value as TLS 1.3 s2n_ecdsa_secp256r1_sha256 */
+ &s2n_ecdsa_secp256r1_sha256,
+ &s2n_ecdsa_sha384, /* same iana value as TLS 1.3 s2n_ecdsa_secp384r1_sha384 */
+ &s2n_ecdsa_secp384r1_sha384,
+ &s2n_ecdsa_sha512, /* same iana value as TLS 1.3 s2n_ecdsa_secp521r1_sha512 */
+ &s2n_ecdsa_secp521r1_sha512,
+ &s2n_ecdsa_sha224,
+
+ /* SHA-1 Legacy */
+ &s2n_rsa_pkcs1_sha1,
+ &s2n_ecdsa_sha1,
+};
+
+const struct s2n_signature_preferences s2n_signature_preferences_20140601 = {
+ .count = s2n_array_len(s2n_sig_scheme_pref_list_20140601),
+ .signature_schemes = s2n_sig_scheme_pref_list_20140601,
+};
+
+const struct s2n_signature_preferences s2n_signature_preferences_20200207 = {
+ .count = s2n_array_len(s2n_sig_scheme_pref_list_20200207),
+ .signature_schemes = s2n_sig_scheme_pref_list_20200207,
+};
+
+const struct s2n_signature_preferences s2n_signature_preferences_20201021 = {
+ .count = s2n_array_len(s2n_sig_scheme_pref_list_20201021),
+ .signature_schemes = s2n_sig_scheme_pref_list_20201021,
+};
+
+const struct s2n_signature_preferences s2n_signature_preferences_null = {
+ .count = 0,
+ .signature_schemes = NULL,
+};
+
+/* TLS1.3 supported signature schemes, without SHA-1 legacy algorithms */
+const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_20201110[] = {
+ /* RSA PSS */
+ &s2n_rsa_pss_pss_sha256,
+ &s2n_rsa_pss_pss_sha384,
+ &s2n_rsa_pss_pss_sha512,
+ &s2n_rsa_pss_rsae_sha256,
+ &s2n_rsa_pss_rsae_sha384,
+ &s2n_rsa_pss_rsae_sha512,
+
+ /* RSA PKCS1 */
+ &s2n_rsa_pkcs1_sha256,
+ &s2n_rsa_pkcs1_sha384,
+ &s2n_rsa_pkcs1_sha512,
+ &s2n_rsa_pkcs1_sha224,
+
+ /* ECDSA - TLS 1.2 */
+ &s2n_ecdsa_sha256, /* same iana value as TLS 1.3 s2n_ecdsa_secp256r1_sha256 */
+ &s2n_ecdsa_secp256r1_sha256,
+ &s2n_ecdsa_sha384, /* same iana value as TLS 1.3 s2n_ecdsa_secp384r1_sha384 */
+ &s2n_ecdsa_secp384r1_sha384,
+ &s2n_ecdsa_sha512,
+ &s2n_ecdsa_sha224,
+};
+
+const struct s2n_signature_preferences s2n_certificate_signature_preferences_20201110 = {
+ .count = s2n_array_len(s2n_sig_scheme_pref_list_20201110),
+ .signature_schemes = s2n_sig_scheme_pref_list_20201110,
+};
diff --git a/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.h b/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.h
index 1f16a61276..416f936a6d 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.h
@@ -1,81 +1,81 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <s2n.h>
-#include <strings.h>
-
-#include "crypto/s2n_hash.h"
-#include "crypto/s2n_signature.h"
-#include "crypto/s2n_ecc_evp.h"
-
-struct s2n_signature_scheme {
- uint16_t iana_value;
- s2n_hash_algorithm hash_alg;
- s2n_signature_algorithm sig_alg;
- uint8_t minimum_protocol_version;
- uint8_t maximum_protocol_version;
- uint16_t libcrypto_nid;
-
- /* Curve is only specified for ECDSA Signatures */
- struct s2n_ecc_named_curve const *signature_curve;
-};
-
-struct s2n_signature_preferences{
- uint8_t count;
- const struct s2n_signature_scheme *const *signature_schemes;
-};
-
-/* RSA PKCS1 */
-/* s2n_rsa_pkcs1_md5_sha1 is not in any preference list, but it is needed since it's the default for TLS 1.0 and 1.1 if
- * no SignatureScheme is sent. */
-extern const struct s2n_signature_scheme s2n_rsa_pkcs1_md5_sha1;
-extern const struct s2n_signature_scheme s2n_rsa_pkcs1_sha1;
-extern const struct s2n_signature_scheme s2n_rsa_pkcs1_sha224;
-extern const struct s2n_signature_scheme s2n_rsa_pkcs1_sha256;
-extern const struct s2n_signature_scheme s2n_rsa_pkcs1_sha384;
-extern const struct s2n_signature_scheme s2n_rsa_pkcs1_sha512;
-
-/* TLS 1.2 Compatible ECDSA Schemes */
-extern const struct s2n_signature_scheme s2n_ecdsa_sha1;
-extern const struct s2n_signature_scheme s2n_ecdsa_sha224;
-extern const struct s2n_signature_scheme s2n_ecdsa_sha256;
-extern const struct s2n_signature_scheme s2n_ecdsa_sha384;
-extern const struct s2n_signature_scheme s2n_ecdsa_sha512;
-
-/* TLS 1.3 Compatible ECDSA Schemes */
-extern const struct s2n_signature_scheme s2n_ecdsa_secp256r1_sha256;
-extern const struct s2n_signature_scheme s2n_ecdsa_secp384r1_sha384;
-extern const struct s2n_signature_scheme s2n_ecdsa_secp521r1_sha512;
-
-/* RSA PSS */
-/*
- * Use RSA-PSS-RSAE instead of RSA-PSS-PSS in order to work with older certificates.
- * For more info see: https://crypto.stackexchange.com/a/58708
- */
-extern const struct s2n_signature_scheme s2n_rsa_pss_pss_sha256;
-extern const struct s2n_signature_scheme s2n_rsa_pss_pss_sha384;
-extern const struct s2n_signature_scheme s2n_rsa_pss_pss_sha512;
-extern const struct s2n_signature_scheme s2n_rsa_pss_rsae_sha256;
-extern const struct s2n_signature_scheme s2n_rsa_pss_rsae_sha384;
-extern const struct s2n_signature_scheme s2n_rsa_pss_rsae_sha512;
-
-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_null;
-
-extern const struct s2n_signature_preferences s2n_certificate_signature_preferences_20201110;
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <s2n.h>
+#include <strings.h>
+
+#include "crypto/s2n_hash.h"
+#include "crypto/s2n_signature.h"
+#include "crypto/s2n_ecc_evp.h"
+
+struct s2n_signature_scheme {
+ uint16_t iana_value;
+ s2n_hash_algorithm hash_alg;
+ s2n_signature_algorithm sig_alg;
+ uint8_t minimum_protocol_version;
+ uint8_t maximum_protocol_version;
+ uint16_t libcrypto_nid;
+
+ /* Curve is only specified for ECDSA Signatures */
+ struct s2n_ecc_named_curve const *signature_curve;
+};
+
+struct s2n_signature_preferences{
+ uint8_t count;
+ const struct s2n_signature_scheme *const *signature_schemes;
+};
+
+/* RSA PKCS1 */
+/* s2n_rsa_pkcs1_md5_sha1 is not in any preference list, but it is needed since it's the default for TLS 1.0 and 1.1 if
+ * no SignatureScheme is sent. */
+extern const struct s2n_signature_scheme s2n_rsa_pkcs1_md5_sha1;
+extern const struct s2n_signature_scheme s2n_rsa_pkcs1_sha1;
+extern const struct s2n_signature_scheme s2n_rsa_pkcs1_sha224;
+extern const struct s2n_signature_scheme s2n_rsa_pkcs1_sha256;
+extern const struct s2n_signature_scheme s2n_rsa_pkcs1_sha384;
+extern const struct s2n_signature_scheme s2n_rsa_pkcs1_sha512;
+
+/* TLS 1.2 Compatible ECDSA Schemes */
+extern const struct s2n_signature_scheme s2n_ecdsa_sha1;
+extern const struct s2n_signature_scheme s2n_ecdsa_sha224;
+extern const struct s2n_signature_scheme s2n_ecdsa_sha256;
+extern const struct s2n_signature_scheme s2n_ecdsa_sha384;
+extern const struct s2n_signature_scheme s2n_ecdsa_sha512;
+
+/* TLS 1.3 Compatible ECDSA Schemes */
+extern const struct s2n_signature_scheme s2n_ecdsa_secp256r1_sha256;
+extern const struct s2n_signature_scheme s2n_ecdsa_secp384r1_sha384;
+extern const struct s2n_signature_scheme s2n_ecdsa_secp521r1_sha512;
+
+/* RSA PSS */
+/*
+ * Use RSA-PSS-RSAE instead of RSA-PSS-PSS in order to work with older certificates.
+ * For more info see: https://crypto.stackexchange.com/a/58708
+ */
+extern const struct s2n_signature_scheme s2n_rsa_pss_pss_sha256;
+extern const struct s2n_signature_scheme s2n_rsa_pss_pss_sha384;
+extern const struct s2n_signature_scheme s2n_rsa_pss_pss_sha512;
+extern const struct s2n_signature_scheme s2n_rsa_pss_rsae_sha256;
+extern const struct s2n_signature_scheme s2n_rsa_pss_rsae_sha384;
+extern const struct s2n_signature_scheme s2n_rsa_pss_rsae_sha512;
+
+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_null;
+
+extern const struct s2n_signature_preferences s2n_certificate_signature_preferences_20201110;
diff --git a/contrib/restricted/aws/s2n/tls/s2n_tls.c b/contrib/restricted/aws/s2n/tls/s2n_tls.c
index b8507d1124..07ef4ff382 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_tls.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_tls.c
@@ -1,39 +1,39 @@
-/*
- * 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 <stdint.h>
-
-#include "tls/s2n_tls.h"
-#include "tls/s2n_tls_parameters.h"
-
-uint8_t s2n_highest_protocol_version = S2N_TLS13;
-uint8_t s2n_unknown_protocol_version = S2N_UNKNOWN_PROTOCOL_VERSION;
-
-/*
- * Convert max_fragment_length codes to length.
- * RFC 6066 says:
- * enum{
- * 2^9(1), 2^10(2), 2^11(3), 2^12(4), (255)
- * } MaxFragmentLength;
- * and we add 0 -> extension unused
- */
-uint16_t mfl_code_to_length[5] =
-{
- S2N_DEFAULT_FRAGMENT_LENGTH, /* S2N_TLS_MAX_FRAG_LEN_EXT_NONE */
- 512, /* S2N_TLS_MAX_FRAG_LEN_512 */
- 1024, /* S2N_TLS_MAX_FRAG_LEN_1024 */
- 2048, /* S2N_TLS_MAX_FRAG_LEN_2048 */
- 4096, /* S2N_TLS_MAX_FRAG_LEN_4096 */
-};
+/*
+ * 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 <stdint.h>
+
+#include "tls/s2n_tls.h"
+#include "tls/s2n_tls_parameters.h"
+
+uint8_t s2n_highest_protocol_version = S2N_TLS13;
+uint8_t s2n_unknown_protocol_version = S2N_UNKNOWN_PROTOCOL_VERSION;
+
+/*
+ * Convert max_fragment_length codes to length.
+ * RFC 6066 says:
+ * enum{
+ * 2^9(1), 2^10(2), 2^11(3), 2^12(4), (255)
+ * } MaxFragmentLength;
+ * and we add 0 -> extension unused
+ */
+uint16_t mfl_code_to_length[5] =
+{
+ S2N_DEFAULT_FRAGMENT_LENGTH, /* S2N_TLS_MAX_FRAG_LEN_EXT_NONE */
+ 512, /* S2N_TLS_MAX_FRAG_LEN_512 */
+ 1024, /* S2N_TLS_MAX_FRAG_LEN_1024 */
+ 2048, /* S2N_TLS_MAX_FRAG_LEN_2048 */
+ 4096, /* S2N_TLS_MAX_FRAG_LEN_4096 */
+};
diff --git a/contrib/restricted/aws/s2n/tls/s2n_tls.h b/contrib/restricted/aws/s2n/tls/s2n_tls.h
index 3ab543942a..d74822a236 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_tls.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_tls.h
@@ -1,100 +1,100 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <stdint.h>
-#include <stdbool.h>
-
-#include "tls/s2n_connection.h"
-
-extern uint8_t s2n_unknown_protocol_version;
-extern uint8_t s2n_highest_protocol_version;
-
-extern int s2n_flush(struct s2n_connection *conn, s2n_blocked_status * more);
-extern int s2n_client_hello_send(struct s2n_connection *conn);
-extern int s2n_client_hello_recv(struct s2n_connection *conn);
-extern int s2n_establish_session(struct s2n_connection *conn);
-extern int s2n_sslv2_client_hello_recv(struct s2n_connection *conn);
-extern int s2n_server_hello_retry_send(struct s2n_connection *conn);
-extern int s2n_server_hello_retry_recv(struct s2n_connection *conn);
-extern int s2n_server_hello_write_message(struct s2n_connection *conn);
-extern int s2n_server_hello_send(struct s2n_connection *conn);
-extern int s2n_server_hello_recv(struct s2n_connection *conn);
-extern int s2n_encrypted_extensions_send(struct s2n_connection *conn);
-extern int s2n_encrypted_extensions_recv(struct s2n_connection *conn);
-extern int s2n_server_cert_send(struct s2n_connection *conn);
-extern int s2n_server_cert_recv(struct s2n_connection *conn);
-extern int s2n_server_status_send(struct s2n_connection *conn);
-extern int s2n_server_status_recv(struct s2n_connection *conn);
-extern int s2n_server_key_send(struct s2n_connection *conn);
-extern int s2n_server_key_recv(struct s2n_connection *conn);
-extern int s2n_cert_req_recv(struct s2n_connection *conn);
-extern int s2n_cert_req_send(struct s2n_connection *conn);
-extern int s2n_tls13_cert_req_send(struct s2n_connection *conn);
-extern int s2n_tls13_cert_req_recv(struct s2n_connection *conn);
-extern int s2n_server_done_send(struct s2n_connection *conn);
-extern int s2n_server_done_recv(struct s2n_connection *conn);
-extern int s2n_client_cert_recv(struct s2n_connection *conn);
-extern int s2n_client_cert_send(struct s2n_connection *conn);
-extern int s2n_client_key_send(struct s2n_connection *conn);
-extern int s2n_client_key_recv(struct s2n_connection *conn);
-extern int s2n_client_cert_verify_recv(struct s2n_connection *conn);
-extern int s2n_client_cert_verify_send(struct s2n_connection *conn);
-extern int s2n_tls13_cert_verify_recv(struct s2n_connection *conn);
-extern int s2n_tls13_cert_verify_send(struct s2n_connection *conn);
-extern int s2n_server_nst_send(struct s2n_connection *conn);
-extern int s2n_server_nst_recv(struct s2n_connection *conn);
-extern int s2n_ccs_send(struct s2n_connection *conn);
-extern int s2n_basic_ccs_recv(struct s2n_connection *conn);
-extern int s2n_server_ccs_recv(struct s2n_connection *conn);
-extern int s2n_client_ccs_recv(struct s2n_connection *conn);
-extern int s2n_client_finished_send(struct s2n_connection *conn);
-extern int s2n_client_finished_recv(struct s2n_connection *conn);
-extern int s2n_server_finished_send(struct s2n_connection *conn);
-extern int s2n_server_finished_recv(struct s2n_connection *conn);
-extern int s2n_tls13_client_finished_send(struct s2n_connection *conn);
-extern int s2n_tls13_client_finished_recv(struct s2n_connection *conn);
-extern int s2n_tls13_server_finished_send(struct s2n_connection *conn);
-extern int s2n_tls13_server_finished_recv(struct s2n_connection *conn);
-extern int s2n_process_client_hello(struct s2n_connection *conn);
-extern int s2n_handshake_write_header(struct s2n_stuffer *out, uint8_t message_type);
-extern int s2n_handshake_finish_header(struct s2n_stuffer *out);
-extern int s2n_handshake_parse_header(struct s2n_connection *conn, uint8_t * message_type, uint32_t * length);
-extern int s2n_read_full_record(struct s2n_connection *conn, uint8_t * record_type, int *isSSLv2);
-extern int s2n_recv_close_notify(struct s2n_connection *conn, s2n_blocked_status * blocked);
-
-extern uint16_t mfl_code_to_length[5];
-
-#define s2n_server_received_server_name(conn) ((conn)->server_name[0] != 0)
-
-#define s2n_server_can_send_ec_point_formats(conn) \
- ((conn)->ec_point_formats)
-
-#define s2n_server_can_send_ocsp(conn) ((conn)->mode == S2N_SERVER && \
- (conn)->status_type == S2N_STATUS_REQUEST_OCSP && \
- (conn)->handshake_params.our_chain_and_key && \
- (conn)->handshake_params.our_chain_and_key->ocsp_status.size > 0)
-
-#define s2n_server_sent_ocsp(conn) ((conn)->mode == S2N_CLIENT && \
- (conn)->status_type == S2N_STATUS_REQUEST_OCSP)
-
-#define s2n_server_can_send_sct_list(conn) ((conn)->mode == S2N_SERVER && \
- (conn)->ct_level_requested == S2N_CT_SUPPORT_REQUEST && \
- (conn)->handshake_params.our_chain_and_key && \
- (conn)->handshake_params.our_chain_and_key->sct_list.size > 0)
-
-#define s2n_server_sending_nst(conn) ((conn)->config->use_tickets && \
- (conn)->session_ticket_status == S2N_NEW_TICKET)
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "tls/s2n_connection.h"
+
+extern uint8_t s2n_unknown_protocol_version;
+extern uint8_t s2n_highest_protocol_version;
+
+extern int s2n_flush(struct s2n_connection *conn, s2n_blocked_status * more);
+extern int s2n_client_hello_send(struct s2n_connection *conn);
+extern int s2n_client_hello_recv(struct s2n_connection *conn);
+extern int s2n_establish_session(struct s2n_connection *conn);
+extern int s2n_sslv2_client_hello_recv(struct s2n_connection *conn);
+extern int s2n_server_hello_retry_send(struct s2n_connection *conn);
+extern int s2n_server_hello_retry_recv(struct s2n_connection *conn);
+extern int s2n_server_hello_write_message(struct s2n_connection *conn);
+extern int s2n_server_hello_send(struct s2n_connection *conn);
+extern int s2n_server_hello_recv(struct s2n_connection *conn);
+extern int s2n_encrypted_extensions_send(struct s2n_connection *conn);
+extern int s2n_encrypted_extensions_recv(struct s2n_connection *conn);
+extern int s2n_server_cert_send(struct s2n_connection *conn);
+extern int s2n_server_cert_recv(struct s2n_connection *conn);
+extern int s2n_server_status_send(struct s2n_connection *conn);
+extern int s2n_server_status_recv(struct s2n_connection *conn);
+extern int s2n_server_key_send(struct s2n_connection *conn);
+extern int s2n_server_key_recv(struct s2n_connection *conn);
+extern int s2n_cert_req_recv(struct s2n_connection *conn);
+extern int s2n_cert_req_send(struct s2n_connection *conn);
+extern int s2n_tls13_cert_req_send(struct s2n_connection *conn);
+extern int s2n_tls13_cert_req_recv(struct s2n_connection *conn);
+extern int s2n_server_done_send(struct s2n_connection *conn);
+extern int s2n_server_done_recv(struct s2n_connection *conn);
+extern int s2n_client_cert_recv(struct s2n_connection *conn);
+extern int s2n_client_cert_send(struct s2n_connection *conn);
+extern int s2n_client_key_send(struct s2n_connection *conn);
+extern int s2n_client_key_recv(struct s2n_connection *conn);
+extern int s2n_client_cert_verify_recv(struct s2n_connection *conn);
+extern int s2n_client_cert_verify_send(struct s2n_connection *conn);
+extern int s2n_tls13_cert_verify_recv(struct s2n_connection *conn);
+extern int s2n_tls13_cert_verify_send(struct s2n_connection *conn);
+extern int s2n_server_nst_send(struct s2n_connection *conn);
+extern int s2n_server_nst_recv(struct s2n_connection *conn);
+extern int s2n_ccs_send(struct s2n_connection *conn);
+extern int s2n_basic_ccs_recv(struct s2n_connection *conn);
+extern int s2n_server_ccs_recv(struct s2n_connection *conn);
+extern int s2n_client_ccs_recv(struct s2n_connection *conn);
+extern int s2n_client_finished_send(struct s2n_connection *conn);
+extern int s2n_client_finished_recv(struct s2n_connection *conn);
+extern int s2n_server_finished_send(struct s2n_connection *conn);
+extern int s2n_server_finished_recv(struct s2n_connection *conn);
+extern int s2n_tls13_client_finished_send(struct s2n_connection *conn);
+extern int s2n_tls13_client_finished_recv(struct s2n_connection *conn);
+extern int s2n_tls13_server_finished_send(struct s2n_connection *conn);
+extern int s2n_tls13_server_finished_recv(struct s2n_connection *conn);
+extern int s2n_process_client_hello(struct s2n_connection *conn);
+extern int s2n_handshake_write_header(struct s2n_stuffer *out, uint8_t message_type);
+extern int s2n_handshake_finish_header(struct s2n_stuffer *out);
+extern int s2n_handshake_parse_header(struct s2n_connection *conn, uint8_t * message_type, uint32_t * length);
+extern int s2n_read_full_record(struct s2n_connection *conn, uint8_t * record_type, int *isSSLv2);
+extern int s2n_recv_close_notify(struct s2n_connection *conn, s2n_blocked_status * blocked);
+
+extern uint16_t mfl_code_to_length[5];
+
+#define s2n_server_received_server_name(conn) ((conn)->server_name[0] != 0)
+
+#define s2n_server_can_send_ec_point_formats(conn) \
+ ((conn)->ec_point_formats)
+
+#define s2n_server_can_send_ocsp(conn) ((conn)->mode == S2N_SERVER && \
+ (conn)->status_type == S2N_STATUS_REQUEST_OCSP && \
+ (conn)->handshake_params.our_chain_and_key && \
+ (conn)->handshake_params.our_chain_and_key->ocsp_status.size > 0)
+
+#define s2n_server_sent_ocsp(conn) ((conn)->mode == S2N_CLIENT && \
+ (conn)->status_type == S2N_STATUS_REQUEST_OCSP)
+
+#define s2n_server_can_send_sct_list(conn) ((conn)->mode == S2N_SERVER && \
+ (conn)->ct_level_requested == S2N_CT_SUPPORT_REQUEST && \
+ (conn)->handshake_params.our_chain_and_key && \
+ (conn)->handshake_params.our_chain_and_key->sct_list.size > 0)
+
+#define s2n_server_sending_nst(conn) ((conn)->config->use_tickets && \
+ (conn)->session_ticket_status == S2N_NEW_TICKET)
diff --git a/contrib/restricted/aws/s2n/tls/s2n_tls13.c b/contrib/restricted/aws/s2n/tls/s2n_tls13.c
index 038ca9db3f..52dd99a86a 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_tls13.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_tls13.c
@@ -1,75 +1,75 @@
-/*
- * 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 "tls/s2n_tls.h"
-#include "tls/s2n_tls13.h"
-#include "crypto/s2n_rsa_signing.h"
-
-bool s2n_use_default_tls13_config_flag = false;
-
-bool s2n_use_default_tls13_config()
-{
- return s2n_use_default_tls13_config_flag;
-}
-
-/* Allow TLS1.3 to be negotiated, and use the default TLS1.3 security policy.
- * This is NOT the default behavior, and this method is deprecated.
- *
- * Please consider using the default behavior and configuring
- * TLS1.2/TLS1.3 via explicit security policy instead.
- */
-int s2n_enable_tls13()
-{
- s2n_highest_protocol_version = S2N_TLS13;
- s2n_use_default_tls13_config_flag = true;
- return S2N_SUCCESS;
-}
-
-/* Do NOT allow TLS1.3 to be negotiated, regardless of security policy.
- * This is NOT the default behavior, and this method is deprecated.
- *
- * Please consider using the default behavior and configuring
- * TLS1.2/TLS1.3 via explicit security policy instead.
- */
-int s2n_disable_tls13()
-{
- ENSURE_POSIX(s2n_in_unit_test(), S2N_ERR_NOT_IN_UNIT_TEST);
- s2n_highest_protocol_version = S2N_TLS12;
- s2n_use_default_tls13_config_flag = false;
- return S2N_SUCCESS;
-}
-
-/* Reset S2N to the default protocol version behavior.
- *
- * This method is intended for use in existing unit tests when the APIs
- * to enable/disable TLS1.3 have already been called.
- */
-int s2n_reset_tls13()
-{
- ENSURE_POSIX(s2n_in_unit_test(), S2N_ERR_NOT_IN_UNIT_TEST);
- s2n_highest_protocol_version = S2N_TLS13;
- s2n_use_default_tls13_config_flag = false;
- return S2N_SUCCESS;
-}
-
-/* Returns whether a uint16 iana value is a valid TLS 1.3 cipher suite */
-bool s2n_is_valid_tls13_cipher(const uint8_t version[2]) {
- /* Valid TLS 1.3 Ciphers are
- * 0x1301, 0x1302, 0x1303, 0x1304, 0x1305.
- * (https://tools.ietf.org/html/rfc8446#appendix-B.4)
- */
- return version[0] == 0x13 && version[1] >= 0x01 && version[1] <= 0x05;
-}
+/*
+ * 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 "tls/s2n_tls.h"
+#include "tls/s2n_tls13.h"
+#include "crypto/s2n_rsa_signing.h"
+
+bool s2n_use_default_tls13_config_flag = false;
+
+bool s2n_use_default_tls13_config()
+{
+ return s2n_use_default_tls13_config_flag;
+}
+
+/* Allow TLS1.3 to be negotiated, and use the default TLS1.3 security policy.
+ * This is NOT the default behavior, and this method is deprecated.
+ *
+ * Please consider using the default behavior and configuring
+ * TLS1.2/TLS1.3 via explicit security policy instead.
+ */
+int s2n_enable_tls13()
+{
+ s2n_highest_protocol_version = S2N_TLS13;
+ s2n_use_default_tls13_config_flag = true;
+ return S2N_SUCCESS;
+}
+
+/* Do NOT allow TLS1.3 to be negotiated, regardless of security policy.
+ * This is NOT the default behavior, and this method is deprecated.
+ *
+ * Please consider using the default behavior and configuring
+ * TLS1.2/TLS1.3 via explicit security policy instead.
+ */
+int s2n_disable_tls13()
+{
+ ENSURE_POSIX(s2n_in_unit_test(), S2N_ERR_NOT_IN_UNIT_TEST);
+ s2n_highest_protocol_version = S2N_TLS12;
+ s2n_use_default_tls13_config_flag = false;
+ return S2N_SUCCESS;
+}
+
+/* Reset S2N to the default protocol version behavior.
+ *
+ * This method is intended for use in existing unit tests when the APIs
+ * to enable/disable TLS1.3 have already been called.
+ */
+int s2n_reset_tls13()
+{
+ ENSURE_POSIX(s2n_in_unit_test(), S2N_ERR_NOT_IN_UNIT_TEST);
+ s2n_highest_protocol_version = S2N_TLS13;
+ s2n_use_default_tls13_config_flag = false;
+ return S2N_SUCCESS;
+}
+
+/* Returns whether a uint16 iana value is a valid TLS 1.3 cipher suite */
+bool s2n_is_valid_tls13_cipher(const uint8_t version[2]) {
+ /* Valid TLS 1.3 Ciphers are
+ * 0x1301, 0x1302, 0x1303, 0x1304, 0x1305.
+ * (https://tools.ietf.org/html/rfc8446#appendix-B.4)
+ */
+ return version[0] == 0x13 && version[1] >= 0x01 && version[1] <= 0x05;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_tls13.h b/contrib/restricted/aws/s2n/tls/s2n_tls13.h
index 1a48bd5ecd..53dedaf02e 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_tls13.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_tls13.h
@@ -1,51 +1,51 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "api/s2n.h"
-#include "tls/s2n_crypto.h"
-#include "utils/s2n_compiler.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if S2N_GCC_VERSION_AT_LEAST(4, 5, 0)
- S2N_API
- __attribute__((deprecated("The use of TLS1.3 is configured through security policies")))
- extern int s2n_enable_tls13();
-#else
- S2N_API
- __attribute__((deprecated))
- extern int s2n_enable_tls13();
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-
-/* from RFC: https://tools.ietf.org/html/rfc8446#section-4.1.3*/
-extern uint8_t hello_retry_req_random[S2N_TLS_RANDOM_DATA_LEN];
-
-bool s2n_use_default_tls13_config();
-int s2n_disable_tls13();
-int s2n_reset_tls13();
-bool s2n_is_valid_tls13_cipher(const uint8_t version[2]);
-
-bool s2n_is_hello_retry_handshake(struct s2n_connection *conn);
-bool s2n_is_hello_retry_message(struct s2n_connection *conn);
-int s2n_set_hello_retry_required(struct s2n_connection *conn);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "api/s2n.h"
+#include "tls/s2n_crypto.h"
+#include "utils/s2n_compiler.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if S2N_GCC_VERSION_AT_LEAST(4, 5, 0)
+ S2N_API
+ __attribute__((deprecated("The use of TLS1.3 is configured through security policies")))
+ extern int s2n_enable_tls13();
+#else
+ S2N_API
+ __attribute__((deprecated))
+ extern int s2n_enable_tls13();
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* from RFC: https://tools.ietf.org/html/rfc8446#section-4.1.3*/
+extern uint8_t hello_retry_req_random[S2N_TLS_RANDOM_DATA_LEN];
+
+bool s2n_use_default_tls13_config();
+int s2n_disable_tls13();
+int s2n_reset_tls13();
+bool s2n_is_valid_tls13_cipher(const uint8_t version[2]);
+
+bool s2n_is_hello_retry_handshake(struct s2n_connection *conn);
+bool s2n_is_hello_retry_message(struct s2n_connection *conn);
+int s2n_set_hello_retry_required(struct s2n_connection *conn);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_tls13_certificate_verify.c b/contrib/restricted/aws/s2n/tls/s2n_tls13_certificate_verify.c
index fbaf926a4b..74654f33cf 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_tls13_certificate_verify.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_tls13_certificate_verify.c
@@ -1,197 +1,197 @@
-/*
- * 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_hash.h"
-#include "error/s2n_errno.h"
-#include "stuffer/s2n_stuffer.h"
-#include "tls/s2n_async_pkey.h"
-#include "tls/s2n_tls13_handshake.h"
-#include "tls/s2n_tls13_certificate_verify.h"
-#include "tls/s2n_connection.h"
-#include "utils/s2n_safety.h"
-
-#include <stdint.h>
-
-/**
- * Specified in https://tools.ietf.org/html/rfc8446#section-4.4.3
- *
- * Servers MUST send this message when authenticating via a certificate.
- * Clients MUST send this message whenever authenticating via a certificate.
- * When sent, this message MUST appear immediately after the Certificate
- * message and immediately prior to the Finished message.
- **/
-
-/* 64 'space' characters (0x20) */
-const uint8_t S2N_CERT_VERIFY_PREFIX[] = {0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
-/* 'TLS 1.3, server CertificateVerify' with 0x00 separator */
-const uint8_t S2N_SERVER_CERT_VERIFY_CONTEXT[] = {0x54, 0x4c, 0x53, 0x20, 0x31, 0x2e, 0x33,
- 0x2c, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x00};
-/* 'TLS 1.3, client CertificateVerify' with 0x00 separator */
-const uint8_t S2N_CLIENT_CERT_VERIFY_CONTEXT[] = {0x54, 0x4c, 0x53, 0x20, 0x31, 0x2e, 0x33,
- 0x2c, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x00};
-
-
-static int s2n_tls13_write_cert_verify_signature(struct s2n_connection *conn, struct s2n_signature_scheme *chosen_sig_scheme);
-static int s2n_tls13_write_signature(struct s2n_connection *conn, struct s2n_blob *signature);
-static int s2n_tls13_generate_unsigned_cert_verify_content(struct s2n_connection *conn, struct s2n_stuffer *unsigned_content, s2n_mode mode);
-static int s2n_tls13_cert_read_and_verify_signature(struct s2n_connection *conn, struct s2n_signature_scheme *chosen_sig_scheme);
-static uint8_t s2n_tls13_cert_verify_header_length(s2n_mode mode);
-
-int s2n_tls13_cert_verify_send(struct s2n_connection *conn)
-{
- S2N_ASYNC_PKEY_GUARD(conn);
-
- if (conn->mode == S2N_SERVER) {
- /* Write digital signature */
- GUARD(s2n_tls13_write_cert_verify_signature(conn, &conn->secure.conn_sig_scheme));
- } else {
- /* Write digital signature */
- GUARD(s2n_tls13_write_cert_verify_signature(conn, &conn->secure.client_cert_sig_scheme));
- }
-
-
- return 0;
-}
-
-int s2n_tls13_write_cert_verify_signature(struct s2n_connection *conn, struct s2n_signature_scheme *chosen_sig_scheme)
-{
- notnull_check(conn->handshake_params.our_chain_and_key);
-
- /* Write the SignatureScheme out */
- struct s2n_stuffer *out = &conn->handshake.io;
- GUARD(s2n_stuffer_write_uint16(out, chosen_sig_scheme->iana_value));
-
- DEFER_CLEANUP(struct s2n_hash_state message_hash = {0}, s2n_hash_free);
- GUARD(s2n_hash_new(&message_hash));
- GUARD(s2n_hash_init(&message_hash, chosen_sig_scheme->hash_alg));
-
- DEFER_CLEANUP(struct s2n_stuffer unsigned_content = {0}, s2n_stuffer_free);
- GUARD(s2n_tls13_generate_unsigned_cert_verify_content(conn, &unsigned_content, conn->mode));
-
- GUARD(s2n_hash_update(&message_hash, unsigned_content.blob.data, s2n_stuffer_data_available(&unsigned_content)));
-
- S2N_ASYNC_PKEY_SIGN(conn, chosen_sig_scheme->sig_alg, &message_hash, s2n_tls13_write_signature);
-}
-
-int s2n_tls13_write_signature(struct s2n_connection *conn, struct s2n_blob *signature)
-{
- struct s2n_stuffer *out = &conn->handshake.io;
-
- GUARD(s2n_stuffer_write_uint16(out, signature->size));
- GUARD(s2n_stuffer_write_bytes(out, signature->data, signature->size));
-
- return 0;
-}
-
-int s2n_tls13_generate_unsigned_cert_verify_content(struct s2n_connection *conn, struct s2n_stuffer *unsigned_content, s2n_mode mode)
-{
- s2n_tls13_connection_keys(tls13_ctx, conn);
-
- struct s2n_hash_state handshake_hash, hash_copy;
- uint8_t hash_digest_length = tls13_ctx.size;
- uint8_t digest_out[S2N_MAX_DIGEST_LEN];
-
- /* Get current handshake hash */
- GUARD(s2n_handshake_get_hash_state(conn, tls13_ctx.hash_algorithm, &handshake_hash));
-
- /* Copy current hash content */
- GUARD(s2n_hash_new(&hash_copy));
- GUARD(s2n_hash_copy(&hash_copy, &handshake_hash));
- GUARD(s2n_hash_digest(&hash_copy, digest_out, hash_digest_length));
- GUARD(s2n_hash_free(&hash_copy));
-
- /* Concatenate the content to be signed/verified */
- GUARD(s2n_stuffer_alloc(unsigned_content, hash_digest_length + s2n_tls13_cert_verify_header_length(mode)));
- GUARD(s2n_stuffer_write_bytes(unsigned_content, S2N_CERT_VERIFY_PREFIX, sizeof(S2N_CERT_VERIFY_PREFIX)));
-
- if (mode == S2N_CLIENT) {
- GUARD(s2n_stuffer_write_bytes(unsigned_content, S2N_CLIENT_CERT_VERIFY_CONTEXT, sizeof(S2N_CLIENT_CERT_VERIFY_CONTEXT)));
- } else {
- GUARD(s2n_stuffer_write_bytes(unsigned_content, S2N_SERVER_CERT_VERIFY_CONTEXT, sizeof(S2N_SERVER_CERT_VERIFY_CONTEXT)));
- }
-
- GUARD(s2n_stuffer_write_bytes(unsigned_content, digest_out, hash_digest_length));
-
- return 0;
-}
-
-uint8_t s2n_tls13_cert_verify_header_length(s2n_mode mode)
-{
- if (mode == S2N_CLIENT) {
- return sizeof(S2N_CERT_VERIFY_PREFIX) + sizeof(S2N_CLIENT_CERT_VERIFY_CONTEXT);
- }
- return sizeof(S2N_CERT_VERIFY_PREFIX) + sizeof(S2N_SERVER_CERT_VERIFY_CONTEXT);
-}
-
-int s2n_tls13_cert_verify_recv(struct s2n_connection *conn)
-{
- if (conn->mode == S2N_SERVER) {
- /* Read the algorithm and update sig_scheme */
- GUARD(s2n_get_and_validate_negotiated_signature_scheme(conn, &conn->handshake.io, &conn->secure.client_cert_sig_scheme));
-
- /* Read the rest of the signature and verify */
- GUARD(s2n_tls13_cert_read_and_verify_signature(conn, &conn->secure.client_cert_sig_scheme));
- } else {
- /* Read the algorithm and update sig_scheme */
- GUARD(s2n_get_and_validate_negotiated_signature_scheme(conn, &conn->handshake.io, &conn->secure.conn_sig_scheme));
-
- /* Read the rest of the signature and verify */
- GUARD(s2n_tls13_cert_read_and_verify_signature(conn, &conn->secure.conn_sig_scheme));
- }
-
- return 0;
-}
-
-int s2n_tls13_cert_read_and_verify_signature(struct s2n_connection *conn, struct s2n_signature_scheme *chosen_sig_scheme)
-{
- struct s2n_stuffer *in = &conn->handshake.io;
- DEFER_CLEANUP(struct s2n_blob signed_content = {0}, s2n_free);
- DEFER_CLEANUP(struct s2n_stuffer unsigned_content = {0}, s2n_stuffer_free);
- DEFER_CLEANUP(struct s2n_hash_state message_hash = {0}, s2n_hash_free);
- GUARD(s2n_hash_new(&message_hash));
-
- /* Get signature size */
- uint16_t signature_size;
- GUARD(s2n_stuffer_read_uint16(in, &signature_size));
- S2N_ERROR_IF(signature_size > s2n_stuffer_data_available(in), S2N_ERR_BAD_MESSAGE);
-
- /* Get wire signature */
- GUARD(s2n_alloc(&signed_content, signature_size));
- signed_content.size = signature_size;
- GUARD(s2n_stuffer_read_bytes(in, signed_content.data, signature_size));
-
- /* Verify signature. We send the opposite mode as we are trying to verify what was sent to us */
- if (conn->mode == S2N_CLIENT) {
- GUARD(s2n_tls13_generate_unsigned_cert_verify_content(conn, &unsigned_content, S2N_SERVER));
- } else {
- GUARD(s2n_tls13_generate_unsigned_cert_verify_content(conn, &unsigned_content, S2N_CLIENT));
- }
-
- GUARD(s2n_hash_init(&message_hash, chosen_sig_scheme->hash_alg));
- GUARD(s2n_hash_update(&message_hash, unsigned_content.blob.data, s2n_stuffer_data_available(&unsigned_content)));
-
- if (conn->mode == S2N_CLIENT) {
- GUARD(s2n_pkey_verify(&conn->secure.server_public_key, chosen_sig_scheme->sig_alg, &message_hash, &signed_content));
- } else {
- GUARD(s2n_pkey_verify(&conn->secure.client_public_key, chosen_sig_scheme->sig_alg, &message_hash, &signed_content));
- }
-
- return 0;
-}
+/*
+ * 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_hash.h"
+#include "error/s2n_errno.h"
+#include "stuffer/s2n_stuffer.h"
+#include "tls/s2n_async_pkey.h"
+#include "tls/s2n_tls13_handshake.h"
+#include "tls/s2n_tls13_certificate_verify.h"
+#include "tls/s2n_connection.h"
+#include "utils/s2n_safety.h"
+
+#include <stdint.h>
+
+/**
+ * Specified in https://tools.ietf.org/html/rfc8446#section-4.4.3
+ *
+ * Servers MUST send this message when authenticating via a certificate.
+ * Clients MUST send this message whenever authenticating via a certificate.
+ * When sent, this message MUST appear immediately after the Certificate
+ * message and immediately prior to the Finished message.
+ **/
+
+/* 64 'space' characters (0x20) */
+const uint8_t S2N_CERT_VERIFY_PREFIX[] = {0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
+/* 'TLS 1.3, server CertificateVerify' with 0x00 separator */
+const uint8_t S2N_SERVER_CERT_VERIFY_CONTEXT[] = {0x54, 0x4c, 0x53, 0x20, 0x31, 0x2e, 0x33,
+ 0x2c, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+ 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x00};
+/* 'TLS 1.3, client CertificateVerify' with 0x00 separator */
+const uint8_t S2N_CLIENT_CERT_VERIFY_CONTEXT[] = {0x54, 0x4c, 0x53, 0x20, 0x31, 0x2e, 0x33,
+ 0x2c, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+ 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x00};
+
+
+static int s2n_tls13_write_cert_verify_signature(struct s2n_connection *conn, struct s2n_signature_scheme *chosen_sig_scheme);
+static int s2n_tls13_write_signature(struct s2n_connection *conn, struct s2n_blob *signature);
+static int s2n_tls13_generate_unsigned_cert_verify_content(struct s2n_connection *conn, struct s2n_stuffer *unsigned_content, s2n_mode mode);
+static int s2n_tls13_cert_read_and_verify_signature(struct s2n_connection *conn, struct s2n_signature_scheme *chosen_sig_scheme);
+static uint8_t s2n_tls13_cert_verify_header_length(s2n_mode mode);
+
+int s2n_tls13_cert_verify_send(struct s2n_connection *conn)
+{
+ S2N_ASYNC_PKEY_GUARD(conn);
+
+ if (conn->mode == S2N_SERVER) {
+ /* Write digital signature */
+ GUARD(s2n_tls13_write_cert_verify_signature(conn, &conn->secure.conn_sig_scheme));
+ } else {
+ /* Write digital signature */
+ GUARD(s2n_tls13_write_cert_verify_signature(conn, &conn->secure.client_cert_sig_scheme));
+ }
+
+
+ return 0;
+}
+
+int s2n_tls13_write_cert_verify_signature(struct s2n_connection *conn, struct s2n_signature_scheme *chosen_sig_scheme)
+{
+ notnull_check(conn->handshake_params.our_chain_and_key);
+
+ /* Write the SignatureScheme out */
+ struct s2n_stuffer *out = &conn->handshake.io;
+ GUARD(s2n_stuffer_write_uint16(out, chosen_sig_scheme->iana_value));
+
+ DEFER_CLEANUP(struct s2n_hash_state message_hash = {0}, s2n_hash_free);
+ GUARD(s2n_hash_new(&message_hash));
+ GUARD(s2n_hash_init(&message_hash, chosen_sig_scheme->hash_alg));
+
+ DEFER_CLEANUP(struct s2n_stuffer unsigned_content = {0}, s2n_stuffer_free);
+ GUARD(s2n_tls13_generate_unsigned_cert_verify_content(conn, &unsigned_content, conn->mode));
+
+ GUARD(s2n_hash_update(&message_hash, unsigned_content.blob.data, s2n_stuffer_data_available(&unsigned_content)));
+
+ S2N_ASYNC_PKEY_SIGN(conn, chosen_sig_scheme->sig_alg, &message_hash, s2n_tls13_write_signature);
+}
+
+int s2n_tls13_write_signature(struct s2n_connection *conn, struct s2n_blob *signature)
+{
+ struct s2n_stuffer *out = &conn->handshake.io;
+
+ GUARD(s2n_stuffer_write_uint16(out, signature->size));
+ GUARD(s2n_stuffer_write_bytes(out, signature->data, signature->size));
+
+ return 0;
+}
+
+int s2n_tls13_generate_unsigned_cert_verify_content(struct s2n_connection *conn, struct s2n_stuffer *unsigned_content, s2n_mode mode)
+{
+ s2n_tls13_connection_keys(tls13_ctx, conn);
+
+ struct s2n_hash_state handshake_hash, hash_copy;
+ uint8_t hash_digest_length = tls13_ctx.size;
+ uint8_t digest_out[S2N_MAX_DIGEST_LEN];
+
+ /* Get current handshake hash */
+ GUARD(s2n_handshake_get_hash_state(conn, tls13_ctx.hash_algorithm, &handshake_hash));
+
+ /* Copy current hash content */
+ GUARD(s2n_hash_new(&hash_copy));
+ GUARD(s2n_hash_copy(&hash_copy, &handshake_hash));
+ GUARD(s2n_hash_digest(&hash_copy, digest_out, hash_digest_length));
+ GUARD(s2n_hash_free(&hash_copy));
+
+ /* Concatenate the content to be signed/verified */
+ GUARD(s2n_stuffer_alloc(unsigned_content, hash_digest_length + s2n_tls13_cert_verify_header_length(mode)));
+ GUARD(s2n_stuffer_write_bytes(unsigned_content, S2N_CERT_VERIFY_PREFIX, sizeof(S2N_CERT_VERIFY_PREFIX)));
+
+ if (mode == S2N_CLIENT) {
+ GUARD(s2n_stuffer_write_bytes(unsigned_content, S2N_CLIENT_CERT_VERIFY_CONTEXT, sizeof(S2N_CLIENT_CERT_VERIFY_CONTEXT)));
+ } else {
+ GUARD(s2n_stuffer_write_bytes(unsigned_content, S2N_SERVER_CERT_VERIFY_CONTEXT, sizeof(S2N_SERVER_CERT_VERIFY_CONTEXT)));
+ }
+
+ GUARD(s2n_stuffer_write_bytes(unsigned_content, digest_out, hash_digest_length));
+
+ return 0;
+}
+
+uint8_t s2n_tls13_cert_verify_header_length(s2n_mode mode)
+{
+ if (mode == S2N_CLIENT) {
+ return sizeof(S2N_CERT_VERIFY_PREFIX) + sizeof(S2N_CLIENT_CERT_VERIFY_CONTEXT);
+ }
+ return sizeof(S2N_CERT_VERIFY_PREFIX) + sizeof(S2N_SERVER_CERT_VERIFY_CONTEXT);
+}
+
+int s2n_tls13_cert_verify_recv(struct s2n_connection *conn)
+{
+ if (conn->mode == S2N_SERVER) {
+ /* Read the algorithm and update sig_scheme */
+ GUARD(s2n_get_and_validate_negotiated_signature_scheme(conn, &conn->handshake.io, &conn->secure.client_cert_sig_scheme));
+
+ /* Read the rest of the signature and verify */
+ GUARD(s2n_tls13_cert_read_and_verify_signature(conn, &conn->secure.client_cert_sig_scheme));
+ } else {
+ /* Read the algorithm and update sig_scheme */
+ GUARD(s2n_get_and_validate_negotiated_signature_scheme(conn, &conn->handshake.io, &conn->secure.conn_sig_scheme));
+
+ /* Read the rest of the signature and verify */
+ GUARD(s2n_tls13_cert_read_and_verify_signature(conn, &conn->secure.conn_sig_scheme));
+ }
+
+ return 0;
+}
+
+int s2n_tls13_cert_read_and_verify_signature(struct s2n_connection *conn, struct s2n_signature_scheme *chosen_sig_scheme)
+{
+ struct s2n_stuffer *in = &conn->handshake.io;
+ DEFER_CLEANUP(struct s2n_blob signed_content = {0}, s2n_free);
+ DEFER_CLEANUP(struct s2n_stuffer unsigned_content = {0}, s2n_stuffer_free);
+ DEFER_CLEANUP(struct s2n_hash_state message_hash = {0}, s2n_hash_free);
+ GUARD(s2n_hash_new(&message_hash));
+
+ /* Get signature size */
+ uint16_t signature_size;
+ GUARD(s2n_stuffer_read_uint16(in, &signature_size));
+ S2N_ERROR_IF(signature_size > s2n_stuffer_data_available(in), S2N_ERR_BAD_MESSAGE);
+
+ /* Get wire signature */
+ GUARD(s2n_alloc(&signed_content, signature_size));
+ signed_content.size = signature_size;
+ GUARD(s2n_stuffer_read_bytes(in, signed_content.data, signature_size));
+
+ /* Verify signature. We send the opposite mode as we are trying to verify what was sent to us */
+ if (conn->mode == S2N_CLIENT) {
+ GUARD(s2n_tls13_generate_unsigned_cert_verify_content(conn, &unsigned_content, S2N_SERVER));
+ } else {
+ GUARD(s2n_tls13_generate_unsigned_cert_verify_content(conn, &unsigned_content, S2N_CLIENT));
+ }
+
+ GUARD(s2n_hash_init(&message_hash, chosen_sig_scheme->hash_alg));
+ GUARD(s2n_hash_update(&message_hash, unsigned_content.blob.data, s2n_stuffer_data_available(&unsigned_content)));
+
+ if (conn->mode == S2N_CLIENT) {
+ GUARD(s2n_pkey_verify(&conn->secure.server_public_key, chosen_sig_scheme->sig_alg, &message_hash, &signed_content));
+ } else {
+ GUARD(s2n_pkey_verify(&conn->secure.client_public_key, chosen_sig_scheme->sig_alg, &message_hash, &signed_content));
+ }
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_tls13_certificate_verify.h b/contrib/restricted/aws/s2n/tls/s2n_tls13_certificate_verify.h
index a64204a18a..e70bb46298 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_tls13_certificate_verify.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_tls13_certificate_verify.h
@@ -1,21 +1,21 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/s2n_connection.h"
-
-int s2n_tls13_cert_verify_recv(struct s2n_connection *conn);
-int s2n_tls13_cert_verify_send(struct s2n_connection *conn);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/s2n_connection.h"
+
+int s2n_tls13_cert_verify_recv(struct s2n_connection *conn);
+int s2n_tls13_cert_verify_send(struct s2n_connection *conn);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.c b/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.c
index b89c6f04fb..fe000814e7 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.c
@@ -1,401 +1,401 @@
-/*
- * 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 "tls/s2n_tls13_handshake.h"
-#include "tls/s2n_cipher_suites.h"
-#include "tls/s2n_security_policies.h"
-
-static int s2n_zero_sequence_number(struct s2n_connection *conn, s2n_mode mode)
-{
- notnull_check(conn);
- struct s2n_blob sequence_number;
- if (mode == S2N_CLIENT) {
- GUARD(s2n_blob_init(&sequence_number, conn->secure.client_sequence_number, sizeof(conn->secure.client_sequence_number)));
- } else {
- GUARD(s2n_blob_init(&sequence_number, conn->secure.server_sequence_number, sizeof(conn->secure.server_sequence_number)));
- }
- GUARD(s2n_blob_zero(&sequence_number));
- return S2N_SUCCESS;
-}
-
-int s2n_tls13_mac_verify(struct s2n_tls13_keys *keys, struct s2n_blob *finished_verify, struct s2n_blob *wire_verify)
-{
- notnull_check(wire_verify->data);
- eq_check(wire_verify->size, keys->size);
-
- S2N_ERROR_IF(!s2n_constant_time_equals(finished_verify->data, wire_verify->data, keys->size), S2N_ERR_BAD_MESSAGE);
-
- return 0;
-}
-
-/*
- * Initializes the tls13_keys struct
- */
-static int s2n_tls13_keys_init_with_ref(struct s2n_tls13_keys *handshake, s2n_hmac_algorithm alg, uint8_t * extract, uint8_t * derive)
-{
- notnull_check(handshake);
-
- handshake->hmac_algorithm = alg;
- GUARD(s2n_hmac_hash_alg(alg, &handshake->hash_algorithm));
- GUARD(s2n_hash_digest_size(handshake->hash_algorithm, &handshake->size));
- GUARD(s2n_blob_init(&handshake->extract_secret, extract, handshake->size));
- GUARD(s2n_blob_init(&handshake->derive_secret, derive, handshake->size));
- GUARD(s2n_hmac_new(&handshake->hmac));
-
- return 0;
-}
-
-int s2n_tls13_keys_from_conn(struct s2n_tls13_keys *keys, struct s2n_connection *conn)
-{
- GUARD(s2n_tls13_keys_init_with_ref(keys, conn->secure.cipher_suite->prf_alg, conn->secure.rsa_premaster_secret, conn->secure.master_secret));
-
- return 0;
-}
-
-int s2n_tls13_compute_ecc_shared_secret(struct s2n_connection *conn, struct s2n_blob *shared_secret) {
- notnull_check(conn);
-
- const struct s2n_ecc_preferences *ecc_preferences = NULL;
- GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_preferences));
- notnull_check(ecc_preferences);
-
- struct s2n_ecc_evp_params *server_key = &conn->secure.server_ecc_evp_params;
- notnull_check(server_key);
- notnull_check(server_key->negotiated_curve);
- /* for now we do this tedious loop to find the matching client key selection.
- * this can be simplified if we get an index or a pointer to a specific key */
- int selection = -1;
- for (int i = 0; i < ecc_preferences->count; i++) {
- if (server_key->negotiated_curve->iana_id == ecc_preferences->ecc_curves[i]->iana_id) {
- selection = i;
- break;
- }
- }
-
- S2N_ERROR_IF(selection < 0, S2N_ERR_BAD_KEY_SHARE);
- struct s2n_ecc_evp_params *client_key = &conn->secure.client_ecc_evp_params[selection];
- notnull_check(client_key);
-
- if (conn->mode == S2N_CLIENT) {
- GUARD(s2n_ecc_evp_compute_shared_secret_from_params(client_key, server_key, shared_secret));
- } else {
- GUARD(s2n_ecc_evp_compute_shared_secret_from_params(server_key, client_key, shared_secret));
- }
-
- return 0;
-}
-
-/* Computes the ECDHE+PQKEM hybrid shared secret as defined in
- * https://tools.ietf.org/html/draft-stebila-tls-hybrid-design */
-int s2n_tls13_compute_pq_hybrid_shared_secret(struct s2n_connection *conn, struct s2n_blob *shared_secret) {
- notnull_check(conn);
- notnull_check(shared_secret);
-
- /* conn->secure.server_ecc_evp_params should be set only during a classic/non-hybrid handshake */
- eq_check(NULL, conn->secure.server_ecc_evp_params.negotiated_curve);
- eq_check(NULL, conn->secure.server_ecc_evp_params.evp_pkey);
-
- struct s2n_kem_group_params *server_kem_group_params = &conn->secure.server_kem_group_params;
- notnull_check(server_kem_group_params);
- struct s2n_ecc_evp_params *server_ecc_params = &server_kem_group_params->ecc_params;
- notnull_check(server_ecc_params);
-
- struct s2n_kem_group_params *client_kem_group_params = conn->secure.chosen_client_kem_group_params;
- notnull_check(client_kem_group_params);
- struct s2n_ecc_evp_params *client_ecc_params = &client_kem_group_params->ecc_params;
- notnull_check(client_ecc_params);
-
- DEFER_CLEANUP(struct s2n_blob ecdhe_shared_secret = { 0 }, s2n_blob_zeroize_free);
-
- /* Compute the ECDHE shared secret, and retrieve the PQ shared secret. */
- if (conn->mode == S2N_CLIENT) {
- GUARD(s2n_ecc_evp_compute_shared_secret_from_params(client_ecc_params, server_ecc_params, &ecdhe_shared_secret));
- } else {
- GUARD(s2n_ecc_evp_compute_shared_secret_from_params(server_ecc_params, client_ecc_params, &ecdhe_shared_secret));
- }
-
- struct s2n_blob *pq_shared_secret = &client_kem_group_params->kem_params.shared_secret;
- notnull_check(pq_shared_secret);
- notnull_check(pq_shared_secret->data);
-
- const struct s2n_kem_group *negotiated_kem_group = conn->secure.server_kem_group_params.kem_group;
- notnull_check(negotiated_kem_group);
- notnull_check(negotiated_kem_group->kem);
-
- eq_check(pq_shared_secret->size, negotiated_kem_group->kem->shared_secret_key_length);
-
- /* Construct the concatenated/hybrid shared secret */
- uint32_t hybrid_shared_secret_size = ecdhe_shared_secret.size + negotiated_kem_group->kem->shared_secret_key_length;
- GUARD(s2n_alloc(shared_secret, hybrid_shared_secret_size));
- struct s2n_stuffer stuffer_combiner = { 0 };
- GUARD(s2n_stuffer_init(&stuffer_combiner, shared_secret));
- GUARD(s2n_stuffer_write(&stuffer_combiner, &ecdhe_shared_secret));
- GUARD(s2n_stuffer_write(&stuffer_combiner, pq_shared_secret));
-
- /* No longer need PQ shared secret or ECC keys */
- GUARD(s2n_kem_group_free(server_kem_group_params));
- GUARD(s2n_kem_group_free(client_kem_group_params));
-
- return S2N_SUCCESS;
-}
-
-static int s2n_tls13_pq_hybrid_supported(struct s2n_connection *conn) {
- return conn->secure.server_kem_group_params.kem_group != NULL;
-}
-
-int s2n_tls13_compute_shared_secret(struct s2n_connection *conn, struct s2n_blob *shared_secret)
-{
- notnull_check(conn);
-
- if (s2n_tls13_pq_hybrid_supported(conn)) {
- GUARD(s2n_tls13_compute_pq_hybrid_shared_secret(conn, shared_secret));
- } else {
- GUARD(s2n_tls13_compute_ecc_shared_secret(conn, shared_secret));
- }
-
- return S2N_SUCCESS;
-}
-
-/*
- * This function executes after Server Hello is processed
- * and handshake hashes are computed. It produces and configure
- * the shared secret, handshake secrets, handshake traffic keys,
- * and finished keys.
- */
-int s2n_tls13_handle_handshake_secrets(struct s2n_connection *conn)
-{
- notnull_check(conn);
- const struct s2n_ecc_preferences *ecc_preferences = NULL;
- GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_preferences));
- notnull_check(ecc_preferences);
-
- /* get tls13 key context */
- s2n_tls13_connection_keys(secrets, conn);
-
- /* get shared secret */
- DEFER_CLEANUP(struct s2n_blob shared_secret = { 0 }, s2n_free);
- GUARD(s2n_tls13_compute_shared_secret(conn, &shared_secret));
-
- /* derive early secrets */
- GUARD(s2n_tls13_derive_early_secrets(&secrets));
-
- /* produce handshake secrets */
- s2n_stack_blob(client_hs_secret, secrets.size, S2N_TLS13_SECRET_MAX_LEN);
- s2n_stack_blob(server_hs_secret, secrets.size, S2N_TLS13_SECRET_MAX_LEN);
-
- struct s2n_hash_state hash_state = {0};
- GUARD(s2n_handshake_get_hash_state(conn, secrets.hash_algorithm, &hash_state));
- GUARD(s2n_tls13_derive_handshake_secrets(&secrets, &shared_secret, &hash_state, &client_hs_secret, &server_hs_secret));
-
- /* trigger secret callbacks */
- if (conn->secret_cb && conn->config->quic_enabled) {
- GUARD(conn->secret_cb(conn->secret_cb_context, conn, S2N_CLIENT_HANDSHAKE_TRAFFIC_SECRET,
- client_hs_secret.data, client_hs_secret.size));
- GUARD(conn->secret_cb(conn->secret_cb_context, conn, S2N_SERVER_HANDSHAKE_TRAFFIC_SECRET,
- server_hs_secret.data, server_hs_secret.size));
- }
-
- /* produce handshake traffic keys and configure record algorithm */
- s2n_tls13_key_blob(server_hs_key, conn->secure.cipher_suite->record_alg->cipher->key_material_size);
- struct s2n_blob server_hs_iv = { .data = conn->secure.server_implicit_iv, .size = S2N_TLS13_FIXED_IV_LEN };
- GUARD(s2n_tls13_derive_traffic_keys(&secrets, &server_hs_secret, &server_hs_key, &server_hs_iv));
-
- s2n_tls13_key_blob(client_hs_key, conn->secure.cipher_suite->record_alg->cipher->key_material_size);
- struct s2n_blob client_hs_iv = { .data = conn->secure.client_implicit_iv, .size = S2N_TLS13_FIXED_IV_LEN };
- GUARD(s2n_tls13_derive_traffic_keys(&secrets, &client_hs_secret, &client_hs_key, &client_hs_iv));
-
- GUARD(conn->secure.cipher_suite->record_alg->cipher->init(&conn->secure.server_key));
- GUARD(conn->secure.cipher_suite->record_alg->cipher->init(&conn->secure.client_key));
-
- if (conn->mode == S2N_CLIENT) {
- GUARD(conn->secure.cipher_suite->record_alg->cipher->set_decryption_key(&conn->secure.server_key, &server_hs_key));
- GUARD(conn->secure.cipher_suite->record_alg->cipher->set_encryption_key(&conn->secure.client_key, &client_hs_key));
- } else {
- GUARD(conn->secure.cipher_suite->record_alg->cipher->set_encryption_key(&conn->secure.server_key, &server_hs_key));
- GUARD(conn->secure.cipher_suite->record_alg->cipher->set_decryption_key(&conn->secure.client_key, &client_hs_key));
- }
-
- /* calculate server + client finished keys and store them in handshake struct */
- struct s2n_blob server_finished_key = { .data = conn->handshake.server_finished, .size = secrets.size };
- struct s2n_blob client_finished_key = { .data = conn->handshake.client_finished, .size = secrets.size };
- GUARD(s2n_tls13_derive_finished_key(&secrets, &server_hs_secret, &server_finished_key));
- GUARD(s2n_tls13_derive_finished_key(&secrets, &client_hs_secret, &client_finished_key));
-
- /* since shared secret has been computed, clean up keys */
- GUARD(s2n_ecc_evp_params_free(&conn->secure.server_ecc_evp_params));
- for (int i = 0; i < ecc_preferences->count; i++) {
- GUARD(s2n_ecc_evp_params_free(&conn->secure.client_ecc_evp_params[i]));
- }
-
- /* According to https://tools.ietf.org/html/rfc8446#section-5.3:
- * Each sequence number is set to zero at the beginning of a connection and
- * whenever the key is changed
- */
- GUARD(s2n_zero_sequence_number(conn, S2N_CLIENT));
- GUARD(s2n_zero_sequence_number(conn, S2N_SERVER));
-
- return 0;
-}
-
-static int s2n_tls13_handle_application_secret(struct s2n_connection *conn, s2n_mode mode)
-{
- /* get tls13 key context */
- s2n_tls13_connection_keys(keys, conn);
- bool is_sending_secret = (mode == conn->mode);
-
- uint8_t *app_secret_data, *implicit_iv_data;
- struct s2n_session_key *session_key;
- s2n_secret_type_t secret_type;
- if (mode == S2N_CLIENT) {
- app_secret_data = conn->secure.client_app_secret;
- implicit_iv_data = conn->secure.client_implicit_iv;
- session_key = &conn->secure.client_key;
- secret_type = S2N_CLIENT_APPLICATION_TRAFFIC_SECRET;
- } else {
- app_secret_data = conn->secure.server_app_secret;
- implicit_iv_data = conn->secure.server_implicit_iv;
- session_key = &conn->secure.server_key;
- secret_type = S2N_SERVER_APPLICATION_TRAFFIC_SECRET;
- }
-
- /* use frozen hashes during the server finished state */
- struct s2n_hash_state *hash_state;
- GUARD_NONNULL(hash_state = &conn->handshake.server_finished_copy);
-
- /* calculate secret */
- struct s2n_blob app_secret = { .data = app_secret_data, .size = keys.size };
- GUARD(s2n_tls13_derive_application_secret(&keys, hash_state, &app_secret, mode));
-
- /* trigger secret callback */
- if (conn->secret_cb && conn->config->quic_enabled) {
- GUARD(conn->secret_cb(conn->secret_cb_context, conn, secret_type,
- app_secret.data, app_secret.size));
- }
-
- /* derive key from secret */
- s2n_tls13_key_blob(app_key, conn->secure.cipher_suite->record_alg->cipher->key_material_size);
- struct s2n_blob app_iv = { .data = implicit_iv_data, .size = S2N_TLS13_FIXED_IV_LEN };
- GUARD(s2n_tls13_derive_traffic_keys(&keys, &app_secret, &app_key, &app_iv));
-
- /* update record algorithm secrets */
- if (is_sending_secret) {
- GUARD(conn->secure.cipher_suite->record_alg->cipher->set_encryption_key(session_key, &app_key));
- } else {
- GUARD(conn->secure.cipher_suite->record_alg->cipher->set_decryption_key(session_key, &app_key));
- }
-
- /* According to https://tools.ietf.org/html/rfc8446#section-5.3:
- * Each sequence number is set to zero at the beginning of a connection and
- * whenever the key is changed
- */
- GUARD(s2n_zero_sequence_number(conn, mode));
-
- return S2N_SUCCESS;
-}
-
-/* The application secrets are derived from the master secret, so the
- * master secret must be handled BEFORE the application secrets.
- */
-static int s2n_tls13_handle_master_secret(struct s2n_connection *conn)
-{
- s2n_tls13_connection_keys(keys, conn);
- GUARD(s2n_tls13_extract_master_secret(&keys));
- return S2N_SUCCESS;
-}
-
-int s2n_tls13_handle_secrets(struct s2n_connection *conn)
-{
- notnull_check(conn);
- if (conn->actual_protocol_version < S2N_TLS13) {
- return S2N_SUCCESS;
- }
-
- switch(s2n_conn_get_current_message_type(conn)) {
- case SERVER_HELLO:
- GUARD(s2n_tls13_handle_handshake_secrets(conn));
- /* Set negotiated crypto parameters for encryption */
- conn->server = &conn->secure;
- conn->client = &conn->secure;
- break;
- case SERVER_FINISHED:
- if (conn->mode == S2N_SERVER) {
- GUARD(s2n_tls13_handle_master_secret(conn));
- GUARD(s2n_tls13_handle_application_secret(conn, S2N_SERVER));
- }
- break;
- case CLIENT_FINISHED:
- if (conn->mode == S2N_CLIENT) {
- GUARD(s2n_tls13_handle_master_secret(conn));
- GUARD(s2n_tls13_handle_application_secret(conn, S2N_SERVER));
- }
- GUARD(s2n_tls13_handle_application_secret(conn, S2N_CLIENT));
- break;
- default:
- break;
- }
- return S2N_SUCCESS;
-}
-
-int s2n_update_application_traffic_keys(struct s2n_connection *conn, s2n_mode mode, keyupdate_status status)
-{
- notnull_check(conn);
-
- /* get tls13 key context */
- s2n_tls13_connection_keys(keys, conn);
-
- struct s2n_session_key *old_key;
- struct s2n_blob old_app_secret;
- struct s2n_blob app_iv;
-
- if (mode == S2N_CLIENT) {
- old_key = &conn->secure.client_key;
- GUARD(s2n_blob_init(&old_app_secret, conn->secure.client_app_secret, keys.size));
- GUARD(s2n_blob_init(&app_iv, conn->secure.client_implicit_iv, S2N_TLS13_FIXED_IV_LEN));
- } else {
- old_key = &conn->secure.server_key;
- GUARD(s2n_blob_init(&old_app_secret, conn->secure.server_app_secret, keys.size));
- GUARD(s2n_blob_init(&app_iv, conn->secure.server_implicit_iv, S2N_TLS13_FIXED_IV_LEN));
- }
-
- /* Produce new application secret */
- s2n_stack_blob(app_secret_update, keys.size, S2N_TLS13_SECRET_MAX_LEN);
-
- /* Derives next generation of traffic secret */
- GUARD(s2n_tls13_update_application_traffic_secret(&keys, &old_app_secret, &app_secret_update));
-
- s2n_tls13_key_blob(app_key, conn->secure.cipher_suite->record_alg->cipher->key_material_size);
-
- /* Derives next generation of traffic key */
- GUARD(s2n_tls13_derive_traffic_keys(&keys, &app_secret_update, &app_key, &app_iv));
- if (status == RECEIVING) {
- GUARD(conn->secure.cipher_suite->record_alg->cipher->set_decryption_key(old_key, &app_key));
- } else {
- GUARD(conn->secure.cipher_suite->record_alg->cipher->set_encryption_key(old_key, &app_key));
- }
-
- /* According to https://tools.ietf.org/html/rfc8446#section-5.3:
- * Each sequence number is set to zero at the beginning of a connection and
- * whenever the key is changed; the first record transmitted under a particular traffic key
- * MUST use sequence number 0.
- */
- GUARD(s2n_zero_sequence_number(conn, mode));
-
- /* Save updated secret */
- struct s2n_stuffer old_secret_stuffer = {0};
- GUARD(s2n_stuffer_init(&old_secret_stuffer, &old_app_secret));
- GUARD(s2n_stuffer_write_bytes(&old_secret_stuffer, app_secret_update.data, keys.size));
-
- return S2N_SUCCESS;
-}
+/*
+ * 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 "tls/s2n_tls13_handshake.h"
+#include "tls/s2n_cipher_suites.h"
+#include "tls/s2n_security_policies.h"
+
+static int s2n_zero_sequence_number(struct s2n_connection *conn, s2n_mode mode)
+{
+ notnull_check(conn);
+ struct s2n_blob sequence_number;
+ if (mode == S2N_CLIENT) {
+ GUARD(s2n_blob_init(&sequence_number, conn->secure.client_sequence_number, sizeof(conn->secure.client_sequence_number)));
+ } else {
+ GUARD(s2n_blob_init(&sequence_number, conn->secure.server_sequence_number, sizeof(conn->secure.server_sequence_number)));
+ }
+ GUARD(s2n_blob_zero(&sequence_number));
+ return S2N_SUCCESS;
+}
+
+int s2n_tls13_mac_verify(struct s2n_tls13_keys *keys, struct s2n_blob *finished_verify, struct s2n_blob *wire_verify)
+{
+ notnull_check(wire_verify->data);
+ eq_check(wire_verify->size, keys->size);
+
+ S2N_ERROR_IF(!s2n_constant_time_equals(finished_verify->data, wire_verify->data, keys->size), S2N_ERR_BAD_MESSAGE);
+
+ return 0;
+}
+
+/*
+ * Initializes the tls13_keys struct
+ */
+static int s2n_tls13_keys_init_with_ref(struct s2n_tls13_keys *handshake, s2n_hmac_algorithm alg, uint8_t * extract, uint8_t * derive)
+{
+ notnull_check(handshake);
+
+ handshake->hmac_algorithm = alg;
+ GUARD(s2n_hmac_hash_alg(alg, &handshake->hash_algorithm));
+ GUARD(s2n_hash_digest_size(handshake->hash_algorithm, &handshake->size));
+ GUARD(s2n_blob_init(&handshake->extract_secret, extract, handshake->size));
+ GUARD(s2n_blob_init(&handshake->derive_secret, derive, handshake->size));
+ GUARD(s2n_hmac_new(&handshake->hmac));
+
+ return 0;
+}
+
+int s2n_tls13_keys_from_conn(struct s2n_tls13_keys *keys, struct s2n_connection *conn)
+{
+ GUARD(s2n_tls13_keys_init_with_ref(keys, conn->secure.cipher_suite->prf_alg, conn->secure.rsa_premaster_secret, conn->secure.master_secret));
+
+ return 0;
+}
+
+int s2n_tls13_compute_ecc_shared_secret(struct s2n_connection *conn, struct s2n_blob *shared_secret) {
+ notnull_check(conn);
+
+ const struct s2n_ecc_preferences *ecc_preferences = NULL;
+ GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_preferences));
+ notnull_check(ecc_preferences);
+
+ struct s2n_ecc_evp_params *server_key = &conn->secure.server_ecc_evp_params;
+ notnull_check(server_key);
+ notnull_check(server_key->negotiated_curve);
+ /* for now we do this tedious loop to find the matching client key selection.
+ * this can be simplified if we get an index or a pointer to a specific key */
+ int selection = -1;
+ for (int i = 0; i < ecc_preferences->count; i++) {
+ if (server_key->negotiated_curve->iana_id == ecc_preferences->ecc_curves[i]->iana_id) {
+ selection = i;
+ break;
+ }
+ }
+
+ S2N_ERROR_IF(selection < 0, S2N_ERR_BAD_KEY_SHARE);
+ struct s2n_ecc_evp_params *client_key = &conn->secure.client_ecc_evp_params[selection];
+ notnull_check(client_key);
+
+ if (conn->mode == S2N_CLIENT) {
+ GUARD(s2n_ecc_evp_compute_shared_secret_from_params(client_key, server_key, shared_secret));
+ } else {
+ GUARD(s2n_ecc_evp_compute_shared_secret_from_params(server_key, client_key, shared_secret));
+ }
+
+ return 0;
+}
+
+/* Computes the ECDHE+PQKEM hybrid shared secret as defined in
+ * https://tools.ietf.org/html/draft-stebila-tls-hybrid-design */
+int s2n_tls13_compute_pq_hybrid_shared_secret(struct s2n_connection *conn, struct s2n_blob *shared_secret) {
+ notnull_check(conn);
+ notnull_check(shared_secret);
+
+ /* conn->secure.server_ecc_evp_params should be set only during a classic/non-hybrid handshake */
+ eq_check(NULL, conn->secure.server_ecc_evp_params.negotiated_curve);
+ eq_check(NULL, conn->secure.server_ecc_evp_params.evp_pkey);
+
+ struct s2n_kem_group_params *server_kem_group_params = &conn->secure.server_kem_group_params;
+ notnull_check(server_kem_group_params);
+ struct s2n_ecc_evp_params *server_ecc_params = &server_kem_group_params->ecc_params;
+ notnull_check(server_ecc_params);
+
+ struct s2n_kem_group_params *client_kem_group_params = conn->secure.chosen_client_kem_group_params;
+ notnull_check(client_kem_group_params);
+ struct s2n_ecc_evp_params *client_ecc_params = &client_kem_group_params->ecc_params;
+ notnull_check(client_ecc_params);
+
+ DEFER_CLEANUP(struct s2n_blob ecdhe_shared_secret = { 0 }, s2n_blob_zeroize_free);
+
+ /* Compute the ECDHE shared secret, and retrieve the PQ shared secret. */
+ if (conn->mode == S2N_CLIENT) {
+ GUARD(s2n_ecc_evp_compute_shared_secret_from_params(client_ecc_params, server_ecc_params, &ecdhe_shared_secret));
+ } else {
+ GUARD(s2n_ecc_evp_compute_shared_secret_from_params(server_ecc_params, client_ecc_params, &ecdhe_shared_secret));
+ }
+
+ struct s2n_blob *pq_shared_secret = &client_kem_group_params->kem_params.shared_secret;
+ notnull_check(pq_shared_secret);
+ notnull_check(pq_shared_secret->data);
+
+ const struct s2n_kem_group *negotiated_kem_group = conn->secure.server_kem_group_params.kem_group;
+ notnull_check(negotiated_kem_group);
+ notnull_check(negotiated_kem_group->kem);
+
+ eq_check(pq_shared_secret->size, negotiated_kem_group->kem->shared_secret_key_length);
+
+ /* Construct the concatenated/hybrid shared secret */
+ uint32_t hybrid_shared_secret_size = ecdhe_shared_secret.size + negotiated_kem_group->kem->shared_secret_key_length;
+ GUARD(s2n_alloc(shared_secret, hybrid_shared_secret_size));
+ struct s2n_stuffer stuffer_combiner = { 0 };
+ GUARD(s2n_stuffer_init(&stuffer_combiner, shared_secret));
+ GUARD(s2n_stuffer_write(&stuffer_combiner, &ecdhe_shared_secret));
+ GUARD(s2n_stuffer_write(&stuffer_combiner, pq_shared_secret));
+
+ /* No longer need PQ shared secret or ECC keys */
+ GUARD(s2n_kem_group_free(server_kem_group_params));
+ GUARD(s2n_kem_group_free(client_kem_group_params));
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_tls13_pq_hybrid_supported(struct s2n_connection *conn) {
+ return conn->secure.server_kem_group_params.kem_group != NULL;
+}
+
+int s2n_tls13_compute_shared_secret(struct s2n_connection *conn, struct s2n_blob *shared_secret)
+{
+ notnull_check(conn);
+
+ if (s2n_tls13_pq_hybrid_supported(conn)) {
+ GUARD(s2n_tls13_compute_pq_hybrid_shared_secret(conn, shared_secret));
+ } else {
+ GUARD(s2n_tls13_compute_ecc_shared_secret(conn, shared_secret));
+ }
+
+ return S2N_SUCCESS;
+}
+
+/*
+ * This function executes after Server Hello is processed
+ * and handshake hashes are computed. It produces and configure
+ * the shared secret, handshake secrets, handshake traffic keys,
+ * and finished keys.
+ */
+int s2n_tls13_handle_handshake_secrets(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+ const struct s2n_ecc_preferences *ecc_preferences = NULL;
+ GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_preferences));
+ notnull_check(ecc_preferences);
+
+ /* get tls13 key context */
+ s2n_tls13_connection_keys(secrets, conn);
+
+ /* get shared secret */
+ DEFER_CLEANUP(struct s2n_blob shared_secret = { 0 }, s2n_free);
+ GUARD(s2n_tls13_compute_shared_secret(conn, &shared_secret));
+
+ /* derive early secrets */
+ GUARD(s2n_tls13_derive_early_secrets(&secrets));
+
+ /* produce handshake secrets */
+ s2n_stack_blob(client_hs_secret, secrets.size, S2N_TLS13_SECRET_MAX_LEN);
+ s2n_stack_blob(server_hs_secret, secrets.size, S2N_TLS13_SECRET_MAX_LEN);
+
+ struct s2n_hash_state hash_state = {0};
+ GUARD(s2n_handshake_get_hash_state(conn, secrets.hash_algorithm, &hash_state));
+ GUARD(s2n_tls13_derive_handshake_secrets(&secrets, &shared_secret, &hash_state, &client_hs_secret, &server_hs_secret));
+
+ /* trigger secret callbacks */
+ if (conn->secret_cb && conn->config->quic_enabled) {
+ GUARD(conn->secret_cb(conn->secret_cb_context, conn, S2N_CLIENT_HANDSHAKE_TRAFFIC_SECRET,
+ client_hs_secret.data, client_hs_secret.size));
+ GUARD(conn->secret_cb(conn->secret_cb_context, conn, S2N_SERVER_HANDSHAKE_TRAFFIC_SECRET,
+ server_hs_secret.data, server_hs_secret.size));
+ }
+
+ /* produce handshake traffic keys and configure record algorithm */
+ s2n_tls13_key_blob(server_hs_key, conn->secure.cipher_suite->record_alg->cipher->key_material_size);
+ struct s2n_blob server_hs_iv = { .data = conn->secure.server_implicit_iv, .size = S2N_TLS13_FIXED_IV_LEN };
+ GUARD(s2n_tls13_derive_traffic_keys(&secrets, &server_hs_secret, &server_hs_key, &server_hs_iv));
+
+ s2n_tls13_key_blob(client_hs_key, conn->secure.cipher_suite->record_alg->cipher->key_material_size);
+ struct s2n_blob client_hs_iv = { .data = conn->secure.client_implicit_iv, .size = S2N_TLS13_FIXED_IV_LEN };
+ GUARD(s2n_tls13_derive_traffic_keys(&secrets, &client_hs_secret, &client_hs_key, &client_hs_iv));
+
+ GUARD(conn->secure.cipher_suite->record_alg->cipher->init(&conn->secure.server_key));
+ GUARD(conn->secure.cipher_suite->record_alg->cipher->init(&conn->secure.client_key));
+
+ if (conn->mode == S2N_CLIENT) {
+ GUARD(conn->secure.cipher_suite->record_alg->cipher->set_decryption_key(&conn->secure.server_key, &server_hs_key));
+ GUARD(conn->secure.cipher_suite->record_alg->cipher->set_encryption_key(&conn->secure.client_key, &client_hs_key));
+ } else {
+ GUARD(conn->secure.cipher_suite->record_alg->cipher->set_encryption_key(&conn->secure.server_key, &server_hs_key));
+ GUARD(conn->secure.cipher_suite->record_alg->cipher->set_decryption_key(&conn->secure.client_key, &client_hs_key));
+ }
+
+ /* calculate server + client finished keys and store them in handshake struct */
+ struct s2n_blob server_finished_key = { .data = conn->handshake.server_finished, .size = secrets.size };
+ struct s2n_blob client_finished_key = { .data = conn->handshake.client_finished, .size = secrets.size };
+ GUARD(s2n_tls13_derive_finished_key(&secrets, &server_hs_secret, &server_finished_key));
+ GUARD(s2n_tls13_derive_finished_key(&secrets, &client_hs_secret, &client_finished_key));
+
+ /* since shared secret has been computed, clean up keys */
+ GUARD(s2n_ecc_evp_params_free(&conn->secure.server_ecc_evp_params));
+ for (int i = 0; i < ecc_preferences->count; i++) {
+ GUARD(s2n_ecc_evp_params_free(&conn->secure.client_ecc_evp_params[i]));
+ }
+
+ /* According to https://tools.ietf.org/html/rfc8446#section-5.3:
+ * Each sequence number is set to zero at the beginning of a connection and
+ * whenever the key is changed
+ */
+ GUARD(s2n_zero_sequence_number(conn, S2N_CLIENT));
+ GUARD(s2n_zero_sequence_number(conn, S2N_SERVER));
+
+ return 0;
+}
+
+static int s2n_tls13_handle_application_secret(struct s2n_connection *conn, s2n_mode mode)
+{
+ /* get tls13 key context */
+ s2n_tls13_connection_keys(keys, conn);
+ bool is_sending_secret = (mode == conn->mode);
+
+ uint8_t *app_secret_data, *implicit_iv_data;
+ struct s2n_session_key *session_key;
+ s2n_secret_type_t secret_type;
+ if (mode == S2N_CLIENT) {
+ app_secret_data = conn->secure.client_app_secret;
+ implicit_iv_data = conn->secure.client_implicit_iv;
+ session_key = &conn->secure.client_key;
+ secret_type = S2N_CLIENT_APPLICATION_TRAFFIC_SECRET;
+ } else {
+ app_secret_data = conn->secure.server_app_secret;
+ implicit_iv_data = conn->secure.server_implicit_iv;
+ session_key = &conn->secure.server_key;
+ secret_type = S2N_SERVER_APPLICATION_TRAFFIC_SECRET;
+ }
+
+ /* use frozen hashes during the server finished state */
+ struct s2n_hash_state *hash_state;
+ GUARD_NONNULL(hash_state = &conn->handshake.server_finished_copy);
+
+ /* calculate secret */
+ struct s2n_blob app_secret = { .data = app_secret_data, .size = keys.size };
+ GUARD(s2n_tls13_derive_application_secret(&keys, hash_state, &app_secret, mode));
+
+ /* trigger secret callback */
+ if (conn->secret_cb && conn->config->quic_enabled) {
+ GUARD(conn->secret_cb(conn->secret_cb_context, conn, secret_type,
+ app_secret.data, app_secret.size));
+ }
+
+ /* derive key from secret */
+ s2n_tls13_key_blob(app_key, conn->secure.cipher_suite->record_alg->cipher->key_material_size);
+ struct s2n_blob app_iv = { .data = implicit_iv_data, .size = S2N_TLS13_FIXED_IV_LEN };
+ GUARD(s2n_tls13_derive_traffic_keys(&keys, &app_secret, &app_key, &app_iv));
+
+ /* update record algorithm secrets */
+ if (is_sending_secret) {
+ GUARD(conn->secure.cipher_suite->record_alg->cipher->set_encryption_key(session_key, &app_key));
+ } else {
+ GUARD(conn->secure.cipher_suite->record_alg->cipher->set_decryption_key(session_key, &app_key));
+ }
+
+ /* According to https://tools.ietf.org/html/rfc8446#section-5.3:
+ * Each sequence number is set to zero at the beginning of a connection and
+ * whenever the key is changed
+ */
+ GUARD(s2n_zero_sequence_number(conn, mode));
+
+ return S2N_SUCCESS;
+}
+
+/* The application secrets are derived from the master secret, so the
+ * master secret must be handled BEFORE the application secrets.
+ */
+static int s2n_tls13_handle_master_secret(struct s2n_connection *conn)
+{
+ s2n_tls13_connection_keys(keys, conn);
+ GUARD(s2n_tls13_extract_master_secret(&keys));
+ return S2N_SUCCESS;
+}
+
+int s2n_tls13_handle_secrets(struct s2n_connection *conn)
+{
+ notnull_check(conn);
+ if (conn->actual_protocol_version < S2N_TLS13) {
+ return S2N_SUCCESS;
+ }
+
+ switch(s2n_conn_get_current_message_type(conn)) {
+ case SERVER_HELLO:
+ GUARD(s2n_tls13_handle_handshake_secrets(conn));
+ /* Set negotiated crypto parameters for encryption */
+ conn->server = &conn->secure;
+ conn->client = &conn->secure;
+ break;
+ case SERVER_FINISHED:
+ if (conn->mode == S2N_SERVER) {
+ GUARD(s2n_tls13_handle_master_secret(conn));
+ GUARD(s2n_tls13_handle_application_secret(conn, S2N_SERVER));
+ }
+ break;
+ case CLIENT_FINISHED:
+ if (conn->mode == S2N_CLIENT) {
+ GUARD(s2n_tls13_handle_master_secret(conn));
+ GUARD(s2n_tls13_handle_application_secret(conn, S2N_SERVER));
+ }
+ GUARD(s2n_tls13_handle_application_secret(conn, S2N_CLIENT));
+ break;
+ default:
+ break;
+ }
+ return S2N_SUCCESS;
+}
+
+int s2n_update_application_traffic_keys(struct s2n_connection *conn, s2n_mode mode, keyupdate_status status)
+{
+ notnull_check(conn);
+
+ /* get tls13 key context */
+ s2n_tls13_connection_keys(keys, conn);
+
+ struct s2n_session_key *old_key;
+ struct s2n_blob old_app_secret;
+ struct s2n_blob app_iv;
+
+ if (mode == S2N_CLIENT) {
+ old_key = &conn->secure.client_key;
+ GUARD(s2n_blob_init(&old_app_secret, conn->secure.client_app_secret, keys.size));
+ GUARD(s2n_blob_init(&app_iv, conn->secure.client_implicit_iv, S2N_TLS13_FIXED_IV_LEN));
+ } else {
+ old_key = &conn->secure.server_key;
+ GUARD(s2n_blob_init(&old_app_secret, conn->secure.server_app_secret, keys.size));
+ GUARD(s2n_blob_init(&app_iv, conn->secure.server_implicit_iv, S2N_TLS13_FIXED_IV_LEN));
+ }
+
+ /* Produce new application secret */
+ s2n_stack_blob(app_secret_update, keys.size, S2N_TLS13_SECRET_MAX_LEN);
+
+ /* Derives next generation of traffic secret */
+ GUARD(s2n_tls13_update_application_traffic_secret(&keys, &old_app_secret, &app_secret_update));
+
+ s2n_tls13_key_blob(app_key, conn->secure.cipher_suite->record_alg->cipher->key_material_size);
+
+ /* Derives next generation of traffic key */
+ GUARD(s2n_tls13_derive_traffic_keys(&keys, &app_secret_update, &app_key, &app_iv));
+ if (status == RECEIVING) {
+ GUARD(conn->secure.cipher_suite->record_alg->cipher->set_decryption_key(old_key, &app_key));
+ } else {
+ GUARD(conn->secure.cipher_suite->record_alg->cipher->set_encryption_key(old_key, &app_key));
+ }
+
+ /* According to https://tools.ietf.org/html/rfc8446#section-5.3:
+ * Each sequence number is set to zero at the beginning of a connection and
+ * whenever the key is changed; the first record transmitted under a particular traffic key
+ * MUST use sequence number 0.
+ */
+ GUARD(s2n_zero_sequence_number(conn, mode));
+
+ /* Save updated secret */
+ struct s2n_stuffer old_secret_stuffer = {0};
+ GUARD(s2n_stuffer_init(&old_secret_stuffer, &old_app_secret));
+ GUARD(s2n_stuffer_write_bytes(&old_secret_stuffer, app_secret_update.data, keys.size));
+
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.h b/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.h
index 68253fa3cb..f496677a09 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.h
@@ -1,40 +1,40 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "crypto/s2n_tls13_keys.h"
-#include "utils/s2n_blob.h"
-#include "utils/s2n_safety.h"
-#include "tls/s2n_connection.h"
-#include "tls/s2n_key_update.h"
-
-int s2n_tls13_mac_verify(struct s2n_tls13_keys *keys, struct s2n_blob *finished_verify, struct s2n_blob *wire_verify);
-
-#define s2n_get_hash_state(hash_state, alg, conn) \
- struct s2n_hash_state hash_state = {0}; \
- GUARD(s2n_handshake_get_hash_state(conn, alg, &hash_state));
-
-/* Creates a reference to tls13_keys from connection */
-#define s2n_tls13_connection_keys(keys, conn) \
- DEFER_CLEANUP(struct s2n_tls13_keys keys = {0}, s2n_tls13_keys_free);\
- GUARD(s2n_tls13_keys_from_conn(&keys, conn));
-
-int s2n_tls13_keys_from_conn(struct s2n_tls13_keys *keys, struct s2n_connection *conn);
-
-int s2n_tls13_handle_secrets(struct s2n_connection *conn);
-int s2n_update_application_traffic_keys(struct s2n_connection *conn, s2n_mode mode, keyupdate_status status);
-
-int s2n_server_hello_retry_recreate_transcript(struct s2n_connection *conn);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "crypto/s2n_tls13_keys.h"
+#include "utils/s2n_blob.h"
+#include "utils/s2n_safety.h"
+#include "tls/s2n_connection.h"
+#include "tls/s2n_key_update.h"
+
+int s2n_tls13_mac_verify(struct s2n_tls13_keys *keys, struct s2n_blob *finished_verify, struct s2n_blob *wire_verify);
+
+#define s2n_get_hash_state(hash_state, alg, conn) \
+ struct s2n_hash_state hash_state = {0}; \
+ GUARD(s2n_handshake_get_hash_state(conn, alg, &hash_state));
+
+/* Creates a reference to tls13_keys from connection */
+#define s2n_tls13_connection_keys(keys, conn) \
+ DEFER_CLEANUP(struct s2n_tls13_keys keys = {0}, s2n_tls13_keys_free);\
+ GUARD(s2n_tls13_keys_from_conn(&keys, conn));
+
+int s2n_tls13_keys_from_conn(struct s2n_tls13_keys *keys, struct s2n_connection *conn);
+
+int s2n_tls13_handle_secrets(struct s2n_connection *conn);
+int s2n_update_application_traffic_keys(struct s2n_connection *conn, s2n_mode mode, keyupdate_status status);
+
+int s2n_server_hello_retry_recreate_transcript(struct s2n_connection *conn);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_tls_digest_preferences.h b/contrib/restricted/aws/s2n/tls/s2n_tls_digest_preferences.h
index e49258d768..9b856cf481 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_tls_digest_preferences.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_tls_digest_preferences.h
@@ -1,38 +1,38 @@
-/*
- * 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.
- */
-#pragma once
-
-#include "tls/s2n_tls_parameters.h"
-
-#include "crypto/s2n_hash.h"
-
-/* Table to translate TLS numbers to s2n algorithms */
-static const s2n_hash_algorithm s2n_hash_tls_to_alg[] = {
- [TLS_HASH_ALGORITHM_MD5] = S2N_HASH_MD5,
- [TLS_HASH_ALGORITHM_SHA1] = S2N_HASH_SHA1,
- [TLS_HASH_ALGORITHM_SHA224] = S2N_HASH_SHA224,
- [TLS_HASH_ALGORITHM_SHA256] = S2N_HASH_SHA256,
- [TLS_HASH_ALGORITHM_SHA384] = S2N_HASH_SHA384,
- [TLS_HASH_ALGORITHM_SHA512] = S2N_HASH_SHA512 };
-
-/* Table to translate from s2n algorithm numbers to TLS numbers */
-static const uint8_t s2n_hash_alg_to_tls[] = {
- [S2N_HASH_MD5] = TLS_HASH_ALGORITHM_MD5,
- [S2N_HASH_SHA1] = TLS_HASH_ALGORITHM_SHA1,
- [S2N_HASH_SHA224] = TLS_HASH_ALGORITHM_SHA224,
- [S2N_HASH_SHA256] = TLS_HASH_ALGORITHM_SHA256,
- [S2N_HASH_SHA384] = TLS_HASH_ALGORITHM_SHA384,
- [S2N_HASH_SHA512] = TLS_HASH_ALGORITHM_SHA512 };
-
+/*
+ * 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.
+ */
+#pragma once
+
+#include "tls/s2n_tls_parameters.h"
+
+#include "crypto/s2n_hash.h"
+
+/* Table to translate TLS numbers to s2n algorithms */
+static const s2n_hash_algorithm s2n_hash_tls_to_alg[] = {
+ [TLS_HASH_ALGORITHM_MD5] = S2N_HASH_MD5,
+ [TLS_HASH_ALGORITHM_SHA1] = S2N_HASH_SHA1,
+ [TLS_HASH_ALGORITHM_SHA224] = S2N_HASH_SHA224,
+ [TLS_HASH_ALGORITHM_SHA256] = S2N_HASH_SHA256,
+ [TLS_HASH_ALGORITHM_SHA384] = S2N_HASH_SHA384,
+ [TLS_HASH_ALGORITHM_SHA512] = S2N_HASH_SHA512 };
+
+/* Table to translate from s2n algorithm numbers to TLS numbers */
+static const uint8_t s2n_hash_alg_to_tls[] = {
+ [S2N_HASH_MD5] = TLS_HASH_ALGORITHM_MD5,
+ [S2N_HASH_SHA1] = TLS_HASH_ALGORITHM_SHA1,
+ [S2N_HASH_SHA224] = TLS_HASH_ALGORITHM_SHA224,
+ [S2N_HASH_SHA256] = TLS_HASH_ALGORITHM_SHA256,
+ [S2N_HASH_SHA384] = TLS_HASH_ALGORITHM_SHA384,
+ [S2N_HASH_SHA512] = TLS_HASH_ALGORITHM_SHA512 };
+
diff --git a/contrib/restricted/aws/s2n/tls/s2n_tls_parameters.h b/contrib/restricted/aws/s2n/tls/s2n_tls_parameters.h
index e42a56ba49..1980a69138 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_tls_parameters.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_tls_parameters.h
@@ -1,268 +1,268 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "crypto/s2n_hash.h"
-
-/* Codes from http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-5 */
-#define TLS_NULL_WITH_NULL_NULL 0x00, 0x00
-#define TLS_RSA_WITH_AES_256_CBC_SHA256 0x00, 0x3D
-#define TLS_RSA_WITH_AES_256_CBC_SHA 0x00, 0x35
-#define TLS_RSA_WITH_AES_128_CBC_SHA256 0x00, 0x3C
-#define TLS_RSA_WITH_AES_128_CBC_SHA 0x00, 0x2F
-#define TLS_RSA_WITH_3DES_EDE_CBC_SHA 0x00, 0x0A
-#define TLS_RSA_WITH_RC4_128_MD5 0x00, 0x04
-#define TLS_RSA_WITH_RC4_128_SHA 0x00, 0x05
-
-#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x00, 0x33
-#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x00, 0x67
-#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x00, 0x39
-#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x00, 0x6B
-#define TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x00, 0x16
-
-#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC0, 0x09
-#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC0, 0x23
-#define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC0, 0x0A
-#define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC0, 0x24
-
-#define TLS_ECDHE_RSA_WITH_RC4_128_SHA 0xC0, 0x11
-#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC0, 0x13
-#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC0, 0x27
-#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC0, 0x14
-#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC0, 0x28
-#define TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC0, 0x12
-
-#define TLS_RSA_WITH_AES_128_GCM_SHA256 0x00, 0x9C
-#define TLS_RSA_WITH_AES_256_GCM_SHA384 0x00, 0x9D
-#define TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x00, 0x9E
-#define TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x00, 0x9F
-#define TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC0, 0x2B
-#define TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC0, 0x2C
-#define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC0, 0x2F
-#define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC0, 0x30
-
-#define TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCC, 0xA8
-#define TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCC, 0xA9
-#define TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCC, 0xAA
-
-/* TLS 1.2 hybrid post-quantum definitions from https://tools.ietf.org/html/draft-campagna-tls-bike-sike-hybrid */
-#define TLS_ECDHE_BIKE_RSA_WITH_AES_256_GCM_SHA384 0xFF, 0x04
-#define TLS_ECDHE_SIKE_RSA_WITH_AES_256_GCM_SHA384 0xFF, 0x08
-#define TLS_ECDHE_KYBER_RSA_WITH_AES_256_GCM_SHA384 0xFF, 0x0C
-#define TLS_EXTENSION_PQ_KEM_PARAMETERS 0xFE01
-#define TLS_PQ_KEM_EXTENSION_ID_BIKE1_L1_R1 1
-#define TLS_PQ_KEM_EXTENSION_ID_BIKE1_L1_R2 13
-#define TLS_PQ_KEM_EXTENSION_ID_SIKE_P503_R1 10
-#define TLS_PQ_KEM_EXTENSION_ID_SIKE_P434_R2 19
-#define TLS_PQ_KEM_EXTENSION_ID_KYBER_512_R2 23
-#define TLS_PQ_KEM_EXTENSION_ID_KYBER_512_90S_R2 24
-
-/* TLS 1.3 hybrid post-quantum definitions are from the proposed reserved range defined
- * in https://tools.ietf.org/html/draft-stebila-tls-hybrid-design. Values for interoperability
- * are defined in https://docs.google.com/spreadsheets/d/12YarzaNv3XQNLnvDsWLlRKwtZFhRrDdWf36YlzwrPeg/edit#gid=0. */
-#define TLS_PQ_KEM_GROUP_ID_X25519_SIKE_P434_R2 0x2F27
-#define TLS_PQ_KEM_GROUP_ID_SECP256R1_SIKE_P434_R2 0x2F1F
-#define TLS_PQ_KEM_GROUP_ID_X25519_BIKE1_L1_R2 0x2F28
-#define TLS_PQ_KEM_GROUP_ID_SECP256R1_BIKE1_L1_R2 0x2F23
-#define TLS_PQ_KEM_GROUP_ID_X25519_KYBER_512_R2 0x2F26
-#define TLS_PQ_KEM_GROUP_ID_SECP256R1_KYBER_512_R2 0x2F0F
-
-/* From https://tools.ietf.org/html/rfc7507 */
-#define TLS_FALLBACK_SCSV 0x56, 0x00
-#define TLS_EMPTY_RENEGOTIATION_INFO_SCSV 0x00, 0xff
-
-/* TLS 1.3 cipher suites from https://tools.ietf.org/html/rfc8446#appendix-B.4 */
-#define TLS_AES_128_GCM_SHA256 0x13, 0x01
-#define TLS_AES_256_GCM_SHA384 0x13, 0x02
-#define TLS_CHACHA20_POLY1305_SHA256 0x13, 0x03
-#define TLS_AES_128_CCM_SHA256 0x13, 0x04
-#define TLS_AES_128_CCM_8_SHA256 0x13, 0x05
-
-/* TLS extensions from https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml */
-#define TLS_EXTENSION_SERVER_NAME 0
-#define TLS_EXTENSION_MAX_FRAG_LEN 1
-#define TLS_EXTENSION_STATUS_REQUEST 5
-#define TLS_EXTENSION_SUPPORTED_GROUPS 10
-#define TLS_EXTENSION_EC_POINT_FORMATS 11
-#define TLS_EXTENSION_SIGNATURE_ALGORITHMS 13
-#define TLS_EXTENSION_ALPN 16
-#define TLS_EXTENSION_SCT_LIST 18
-#define TLS_EXTENSION_SESSION_TICKET 35
-#define TLS_EXTENSION_PRE_SHARED_KEY 41
-#define TLS_EXTENSION_CERT_AUTHORITIES 47
-#define TLS_EXTENSION_RENEGOTIATION_INFO 65281
-
-/* TLS 1.3 extensions from https://tools.ietf.org/html/rfc8446#section-4.2 */
-#define TLS_EXTENSION_SUPPORTED_VERSIONS 43
-#define TLS_EXTENSION_COOKIE 44
-#define TLS_EXTENSION_KEY_SHARE 51
-
-/* QUIC-TLS extension from https://tools.ietf.org/html/draft-ietf-quic-tls-29#section-8.2 */
-#define TLS_QUIC_TRANSPORT_PARAMETERS 65535
-
-/* TLS Signature Algorithms - RFC 5246 7.4.1.4.1 */
-/* https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-16 */
-#define TLS_SIGNATURE_ALGORITHM_ANONYMOUS 0
-#define TLS_SIGNATURE_ALGORITHM_RSA 1
-#define TLS_SIGNATURE_ALGORITHM_DSA 2
-#define TLS_SIGNATURE_ALGORITHM_ECDSA 3
-#define TLS_SIGNATURE_ALGORITHM_PRIVATE 224
-
-#define TLS_SIGNATURE_ALGORITHM_COUNT 4
-
-/* TLS Hash Algorithm - https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
-/* https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-18 */
-#define TLS_HASH_ALGORITHM_ANONYMOUS 0
-#define TLS_HASH_ALGORITHM_MD5 1
-#define TLS_HASH_ALGORITHM_SHA1 2
-#define TLS_HASH_ALGORITHM_SHA224 3
-#define TLS_HASH_ALGORITHM_SHA256 4
-#define TLS_HASH_ALGORITHM_SHA384 5
-#define TLS_HASH_ALGORITHM_SHA512 6
-#define TLS_HASH_ALGORITHM_COUNT 7
-
-/* TLS SignatureScheme (Backwards compatible with SigHash and SigAlg values above) */
-/* Defined here: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-signaturescheme */
-#define TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA1 0x0201
-#define TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA224 0x0301
-#define TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA256 0x0401
-#define TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA384 0x0501
-#define TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA512 0x0601
-
-/* In TLS 1.0 and 1.1 the hard-coded default scheme was RSA_PKCS1_MD5_SHA1, but there's no IANA defined backwards
- * compatible value for that Scheme for TLS 1.2 and 1.3. So we define an internal value in the private range that won't
- * match anything in the valid range so that all TLS Versions can use the same SignatureScheme negotiation abstraction
- * layer. This scheme isn't in any preference list, so it can't be negotiated even if a client sent it in its pref list. */
-#define TLS_SIGNATURE_SCHEME_PRIVATE_INTERNAL_RSA_PKCS1_MD5_SHA1 0xFFFF
-
-/* TLS 1.2 Backwards Compatible ECDSA Schemes */
-#define TLS_SIGNATURE_SCHEME_ECDSA_SHA1 0x0203
-#define TLS_SIGNATURE_SCHEME_ECDSA_SHA224 0x0303
-#define TLS_SIGNATURE_SCHEME_ECDSA_SHA256 0x0403
-#define TLS_SIGNATURE_SCHEME_ECDSA_SHA384 0x0503
-#define TLS_SIGNATURE_SCHEME_ECDSA_SHA512 0x0603
-
-/* TLS 1.3 ECDSA Signature Schemes */
-#define TLS_SIGNATURE_SCHEME_ECDSA_SECP256R1_SHA256 0x0403
-#define TLS_SIGNATURE_SCHEME_ECDSA_SECP384R1_SHA384 0x0503
-#define TLS_SIGNATURE_SCHEME_ECDSA_SECP521R1_SHA512 0x0603
-#define TLS_SIGNATURE_SCHEME_RSA_PSS_RSAE_SHA256 0x0804
-#define TLS_SIGNATURE_SCHEME_RSA_PSS_RSAE_SHA384 0x0805
-#define TLS_SIGNATURE_SCHEME_RSA_PSS_RSAE_SHA512 0x0806
-#define TLS_SIGNATURE_SCHEME_ED25519 0x0807
-#define TLS_SIGNATURE_SCHEME_ED448 0x0808
-#define TLS_SIGNATURE_SCHEME_RSA_PSS_PSS_SHA256 0x0809
-#define TLS_SIGNATURE_SCHEME_RSA_PSS_PSS_SHA384 0x080A
-#define TLS_SIGNATURE_SCHEME_RSA_PSS_PSS_SHA512 0x080B
-
-
-#define TLS_SIGNATURE_SCHEME_LEN 2
-#define TLS_SIGNATURE_SCHEME_LIST_MAX_LEN 64
-
-/* The TLS record types we support */
-#define SSLv2_CLIENT_HELLO 1
-#define TLS_CHANGE_CIPHER_SPEC 20
-#define TLS_ALERT 21
-#define TLS_HANDSHAKE 22
-#define TLS_APPLICATION_DATA 23
-
-/* Elliptic curve formats from http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-9
- * Only uncompressed is supported.
- */
-#define TLS_EC_FORMAT_UNCOMPRESSED 0
-#define TLS_EC_FORMAT_ANSIX962_COMPRESSED_PRIME 1
-#define TLS_EC_FORMAT_ANSIX962_COMPRESSED_CHAR2 2
-
-/* Elliptic curves from https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 */
-#define TLS_EC_CURVE_SECP_256_R1 23
-#define TLS_EC_CURVE_SECP_384_R1 24
-#define TLS_EC_CURVE_SECP_521_R1 25
-#define TLS_EC_CURVE_ECDH_X25519 29
-
-/* Ethernet maximum transmission unit (MTU)
- * MTU is usually associated with the Ethernet protocol,
- * where a 1500-byte packet is the largest allowed in it
- */
-#define ETH_MTU 1500
-
-#define IP_V4_HEADER_LENGTH 20
-#define IP_V6_HEADER_LENGTH 40
-
-#define TCP_HEADER_LENGTH 20
-#define TCP_OPTIONS_LENGTH 40
-
-/* The maximum size of a TLS record is 16389 bytes. This is; 1 byte for content
- * type, 2 bytes for the protocol version, 2 bytes for the length field,
- * and then up to 2^14 for the encrypted+compressed payload data.
- */
-#define S2N_TLS_RECORD_HEADER_LENGTH 5
-#define S2N_TLS_MAXIMUM_FRAGMENT_LENGTH 16384
-/* Maximum TLS record length allows for 2048 octets of compression expansion and padding */
-#define S2N_TLS_MAXIMUM_RECORD_LENGTH (S2N_TLS_MAXIMUM_FRAGMENT_LENGTH + S2N_TLS_RECORD_HEADER_LENGTH + 2048)
-#define S2N_TLS_MAX_FRAG_LEN_EXT_NONE 0
-
-/* TLS1.3 has a max fragment length of 2^14 + 1 byte for the content type */
-#define S2N_TLS13_MAXIMUM_FRAGMENT_LENGTH 16385
-/* Max encryption overhead is 255 for AEAD padding */
-#define S2N_TLS13_MAXIMUM_RECORD_LENGTH (S2N_TLS13_MAXIMUM_FRAGMENT_LENGTH + S2N_TLS_RECORD_HEADER_LENGTH + 255)
-
-/* The maximum size of an SSL2 message is 2^14 - 1, as neither of the first two
- * bits in the length field are usable. Per;
- * http://www-archive.mozilla.org/projects/security/pki/nss/ssl/draft02.html
- * section 1.1
- */
-#define S2N_SSL2_RECORD_HEADER_LENGTH 2
-#define S2N_SSL2_MAXIMUM_MESSAGE_LENGTH 16383
-#define S2N_SSL2_MAXIMUM_RECORD_LENGTH (S2N_SSL2_MAXIMUM_MESSAGE_LENGTH + S2N_SSL2_RECORD_HEADER_LENGTH)
-
-/* s2n can use a "small" record length that is aligned to the dominant internet MTU;
- * 1500 bytes, minus 20 bytes for an IP header, minus 20 bytes for a tcp
- * header and 20 bytes for tcp/ip options (timestamp, sack etc) and a "large" record
- * length that is designed to maximize throughput (fewer MACs per byte transferred
- * and better efficiency of crypto engines).
- */
-#define S2N_SMALL_RECORD_LENGTH (1500 - 20 - 20 - 20)
-#define S2N_SMALL_FRAGMENT_LENGTH (S2N_SMALL_RECORD_LENGTH - S2N_TLS_RECORD_HEADER_LENGTH)
-
-/* Testing in the wild has found 8k max record sizes give a good balance of low latency
- * and throughput.
- */
-#define S2N_DEFAULT_RECORD_LENGTH 8092
-#define S2N_DEFAULT_FRAGMENT_LENGTH (S2N_DEFAULT_RECORD_LENGTH - S2N_TLS_RECORD_HEADER_LENGTH)
-
-/* S2N_LARGE_RECORD_LENGTH is used for initializing output buffers, we use the largest
- * possible value of all supported protocols to avoid branching at runtime
- */
-#define S2N_LARGE_RECORD_LENGTH S2N_TLS_MAXIMUM_RECORD_LENGTH
-#define S2N_LARGE_FRAGMENT_LENGTH S2N_TLS_MAXIMUM_FRAGMENT_LENGTH
-#define S2N_TLS13_LARGE_FRAGMENT_LENGTH S2N_TLS13_MAXIMUM_FRAGMENT_LENGTH
-
-/* Cap dynamic record resize threshold to 8M */
-#define S2N_TLS_MAX_RESIZE_THRESHOLD (1024 * 1024 * 8)
-
-/* Put a 64k cap on the size of any handshake message */
-#define S2N_MAXIMUM_HANDSHAKE_MESSAGE_LENGTH (64 * 1024)
-
-/* Maximum size for full encoded TLSInnerPlaintext (https://tools.ietf.org/html/rfc8446#section-5.4) */
-#define S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH ((1 << 14) + 1)
-
-/* Alert messages are always 2 bytes long */
-#define S2N_ALERT_LENGTH 2
-
-/* Handshake messages have their own header too */
-#define TLS_HANDSHAKE_HEADER_LENGTH 4
-
-#define S2N_MAX_SERVER_NAME 255
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "crypto/s2n_hash.h"
+
+/* Codes from http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-5 */
+#define TLS_NULL_WITH_NULL_NULL 0x00, 0x00
+#define TLS_RSA_WITH_AES_256_CBC_SHA256 0x00, 0x3D
+#define TLS_RSA_WITH_AES_256_CBC_SHA 0x00, 0x35
+#define TLS_RSA_WITH_AES_128_CBC_SHA256 0x00, 0x3C
+#define TLS_RSA_WITH_AES_128_CBC_SHA 0x00, 0x2F
+#define TLS_RSA_WITH_3DES_EDE_CBC_SHA 0x00, 0x0A
+#define TLS_RSA_WITH_RC4_128_MD5 0x00, 0x04
+#define TLS_RSA_WITH_RC4_128_SHA 0x00, 0x05
+
+#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x00, 0x33
+#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x00, 0x67
+#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x00, 0x39
+#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x00, 0x6B
+#define TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x00, 0x16
+
+#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC0, 0x09
+#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC0, 0x23
+#define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC0, 0x0A
+#define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC0, 0x24
+
+#define TLS_ECDHE_RSA_WITH_RC4_128_SHA 0xC0, 0x11
+#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC0, 0x13
+#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC0, 0x27
+#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC0, 0x14
+#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC0, 0x28
+#define TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC0, 0x12
+
+#define TLS_RSA_WITH_AES_128_GCM_SHA256 0x00, 0x9C
+#define TLS_RSA_WITH_AES_256_GCM_SHA384 0x00, 0x9D
+#define TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x00, 0x9E
+#define TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x00, 0x9F
+#define TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC0, 0x2B
+#define TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC0, 0x2C
+#define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC0, 0x2F
+#define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC0, 0x30
+
+#define TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCC, 0xA8
+#define TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCC, 0xA9
+#define TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCC, 0xAA
+
+/* TLS 1.2 hybrid post-quantum definitions from https://tools.ietf.org/html/draft-campagna-tls-bike-sike-hybrid */
+#define TLS_ECDHE_BIKE_RSA_WITH_AES_256_GCM_SHA384 0xFF, 0x04
+#define TLS_ECDHE_SIKE_RSA_WITH_AES_256_GCM_SHA384 0xFF, 0x08
+#define TLS_ECDHE_KYBER_RSA_WITH_AES_256_GCM_SHA384 0xFF, 0x0C
+#define TLS_EXTENSION_PQ_KEM_PARAMETERS 0xFE01
+#define TLS_PQ_KEM_EXTENSION_ID_BIKE1_L1_R1 1
+#define TLS_PQ_KEM_EXTENSION_ID_BIKE1_L1_R2 13
+#define TLS_PQ_KEM_EXTENSION_ID_SIKE_P503_R1 10
+#define TLS_PQ_KEM_EXTENSION_ID_SIKE_P434_R2 19
+#define TLS_PQ_KEM_EXTENSION_ID_KYBER_512_R2 23
+#define TLS_PQ_KEM_EXTENSION_ID_KYBER_512_90S_R2 24
+
+/* TLS 1.3 hybrid post-quantum definitions are from the proposed reserved range defined
+ * in https://tools.ietf.org/html/draft-stebila-tls-hybrid-design. Values for interoperability
+ * are defined in https://docs.google.com/spreadsheets/d/12YarzaNv3XQNLnvDsWLlRKwtZFhRrDdWf36YlzwrPeg/edit#gid=0. */
+#define TLS_PQ_KEM_GROUP_ID_X25519_SIKE_P434_R2 0x2F27
+#define TLS_PQ_KEM_GROUP_ID_SECP256R1_SIKE_P434_R2 0x2F1F
+#define TLS_PQ_KEM_GROUP_ID_X25519_BIKE1_L1_R2 0x2F28
+#define TLS_PQ_KEM_GROUP_ID_SECP256R1_BIKE1_L1_R2 0x2F23
+#define TLS_PQ_KEM_GROUP_ID_X25519_KYBER_512_R2 0x2F26
+#define TLS_PQ_KEM_GROUP_ID_SECP256R1_KYBER_512_R2 0x2F0F
+
+/* From https://tools.ietf.org/html/rfc7507 */
+#define TLS_FALLBACK_SCSV 0x56, 0x00
+#define TLS_EMPTY_RENEGOTIATION_INFO_SCSV 0x00, 0xff
+
+/* TLS 1.3 cipher suites from https://tools.ietf.org/html/rfc8446#appendix-B.4 */
+#define TLS_AES_128_GCM_SHA256 0x13, 0x01
+#define TLS_AES_256_GCM_SHA384 0x13, 0x02
+#define TLS_CHACHA20_POLY1305_SHA256 0x13, 0x03
+#define TLS_AES_128_CCM_SHA256 0x13, 0x04
+#define TLS_AES_128_CCM_8_SHA256 0x13, 0x05
+
+/* TLS extensions from https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml */
+#define TLS_EXTENSION_SERVER_NAME 0
+#define TLS_EXTENSION_MAX_FRAG_LEN 1
+#define TLS_EXTENSION_STATUS_REQUEST 5
+#define TLS_EXTENSION_SUPPORTED_GROUPS 10
+#define TLS_EXTENSION_EC_POINT_FORMATS 11
+#define TLS_EXTENSION_SIGNATURE_ALGORITHMS 13
+#define TLS_EXTENSION_ALPN 16
+#define TLS_EXTENSION_SCT_LIST 18
+#define TLS_EXTENSION_SESSION_TICKET 35
+#define TLS_EXTENSION_PRE_SHARED_KEY 41
+#define TLS_EXTENSION_CERT_AUTHORITIES 47
+#define TLS_EXTENSION_RENEGOTIATION_INFO 65281
+
+/* TLS 1.3 extensions from https://tools.ietf.org/html/rfc8446#section-4.2 */
+#define TLS_EXTENSION_SUPPORTED_VERSIONS 43
+#define TLS_EXTENSION_COOKIE 44
+#define TLS_EXTENSION_KEY_SHARE 51
+
+/* QUIC-TLS extension from https://tools.ietf.org/html/draft-ietf-quic-tls-29#section-8.2 */
+#define TLS_QUIC_TRANSPORT_PARAMETERS 65535
+
+/* TLS Signature Algorithms - RFC 5246 7.4.1.4.1 */
+/* https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-16 */
+#define TLS_SIGNATURE_ALGORITHM_ANONYMOUS 0
+#define TLS_SIGNATURE_ALGORITHM_RSA 1
+#define TLS_SIGNATURE_ALGORITHM_DSA 2
+#define TLS_SIGNATURE_ALGORITHM_ECDSA 3
+#define TLS_SIGNATURE_ALGORITHM_PRIVATE 224
+
+#define TLS_SIGNATURE_ALGORITHM_COUNT 4
+
+/* TLS Hash Algorithm - https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
+/* https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-18 */
+#define TLS_HASH_ALGORITHM_ANONYMOUS 0
+#define TLS_HASH_ALGORITHM_MD5 1
+#define TLS_HASH_ALGORITHM_SHA1 2
+#define TLS_HASH_ALGORITHM_SHA224 3
+#define TLS_HASH_ALGORITHM_SHA256 4
+#define TLS_HASH_ALGORITHM_SHA384 5
+#define TLS_HASH_ALGORITHM_SHA512 6
+#define TLS_HASH_ALGORITHM_COUNT 7
+
+/* TLS SignatureScheme (Backwards compatible with SigHash and SigAlg values above) */
+/* Defined here: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-signaturescheme */
+#define TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA1 0x0201
+#define TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA224 0x0301
+#define TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA256 0x0401
+#define TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA384 0x0501
+#define TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA512 0x0601
+
+/* In TLS 1.0 and 1.1 the hard-coded default scheme was RSA_PKCS1_MD5_SHA1, but there's no IANA defined backwards
+ * compatible value for that Scheme for TLS 1.2 and 1.3. So we define an internal value in the private range that won't
+ * match anything in the valid range so that all TLS Versions can use the same SignatureScheme negotiation abstraction
+ * layer. This scheme isn't in any preference list, so it can't be negotiated even if a client sent it in its pref list. */
+#define TLS_SIGNATURE_SCHEME_PRIVATE_INTERNAL_RSA_PKCS1_MD5_SHA1 0xFFFF
+
+/* TLS 1.2 Backwards Compatible ECDSA Schemes */
+#define TLS_SIGNATURE_SCHEME_ECDSA_SHA1 0x0203
+#define TLS_SIGNATURE_SCHEME_ECDSA_SHA224 0x0303
+#define TLS_SIGNATURE_SCHEME_ECDSA_SHA256 0x0403
+#define TLS_SIGNATURE_SCHEME_ECDSA_SHA384 0x0503
+#define TLS_SIGNATURE_SCHEME_ECDSA_SHA512 0x0603
+
+/* TLS 1.3 ECDSA Signature Schemes */
+#define TLS_SIGNATURE_SCHEME_ECDSA_SECP256R1_SHA256 0x0403
+#define TLS_SIGNATURE_SCHEME_ECDSA_SECP384R1_SHA384 0x0503
+#define TLS_SIGNATURE_SCHEME_ECDSA_SECP521R1_SHA512 0x0603
+#define TLS_SIGNATURE_SCHEME_RSA_PSS_RSAE_SHA256 0x0804
+#define TLS_SIGNATURE_SCHEME_RSA_PSS_RSAE_SHA384 0x0805
+#define TLS_SIGNATURE_SCHEME_RSA_PSS_RSAE_SHA512 0x0806
+#define TLS_SIGNATURE_SCHEME_ED25519 0x0807
+#define TLS_SIGNATURE_SCHEME_ED448 0x0808
+#define TLS_SIGNATURE_SCHEME_RSA_PSS_PSS_SHA256 0x0809
+#define TLS_SIGNATURE_SCHEME_RSA_PSS_PSS_SHA384 0x080A
+#define TLS_SIGNATURE_SCHEME_RSA_PSS_PSS_SHA512 0x080B
+
+
+#define TLS_SIGNATURE_SCHEME_LEN 2
+#define TLS_SIGNATURE_SCHEME_LIST_MAX_LEN 64
+
+/* The TLS record types we support */
+#define SSLv2_CLIENT_HELLO 1
+#define TLS_CHANGE_CIPHER_SPEC 20
+#define TLS_ALERT 21
+#define TLS_HANDSHAKE 22
+#define TLS_APPLICATION_DATA 23
+
+/* Elliptic curve formats from http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-9
+ * Only uncompressed is supported.
+ */
+#define TLS_EC_FORMAT_UNCOMPRESSED 0
+#define TLS_EC_FORMAT_ANSIX962_COMPRESSED_PRIME 1
+#define TLS_EC_FORMAT_ANSIX962_COMPRESSED_CHAR2 2
+
+/* Elliptic curves from https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 */
+#define TLS_EC_CURVE_SECP_256_R1 23
+#define TLS_EC_CURVE_SECP_384_R1 24
+#define TLS_EC_CURVE_SECP_521_R1 25
+#define TLS_EC_CURVE_ECDH_X25519 29
+
+/* Ethernet maximum transmission unit (MTU)
+ * MTU is usually associated with the Ethernet protocol,
+ * where a 1500-byte packet is the largest allowed in it
+ */
+#define ETH_MTU 1500
+
+#define IP_V4_HEADER_LENGTH 20
+#define IP_V6_HEADER_LENGTH 40
+
+#define TCP_HEADER_LENGTH 20
+#define TCP_OPTIONS_LENGTH 40
+
+/* The maximum size of a TLS record is 16389 bytes. This is; 1 byte for content
+ * type, 2 bytes for the protocol version, 2 bytes for the length field,
+ * and then up to 2^14 for the encrypted+compressed payload data.
+ */
+#define S2N_TLS_RECORD_HEADER_LENGTH 5
+#define S2N_TLS_MAXIMUM_FRAGMENT_LENGTH 16384
+/* Maximum TLS record length allows for 2048 octets of compression expansion and padding */
+#define S2N_TLS_MAXIMUM_RECORD_LENGTH (S2N_TLS_MAXIMUM_FRAGMENT_LENGTH + S2N_TLS_RECORD_HEADER_LENGTH + 2048)
+#define S2N_TLS_MAX_FRAG_LEN_EXT_NONE 0
+
+/* TLS1.3 has a max fragment length of 2^14 + 1 byte for the content type */
+#define S2N_TLS13_MAXIMUM_FRAGMENT_LENGTH 16385
+/* Max encryption overhead is 255 for AEAD padding */
+#define S2N_TLS13_MAXIMUM_RECORD_LENGTH (S2N_TLS13_MAXIMUM_FRAGMENT_LENGTH + S2N_TLS_RECORD_HEADER_LENGTH + 255)
+
+/* The maximum size of an SSL2 message is 2^14 - 1, as neither of the first two
+ * bits in the length field are usable. Per;
+ * http://www-archive.mozilla.org/projects/security/pki/nss/ssl/draft02.html
+ * section 1.1
+ */
+#define S2N_SSL2_RECORD_HEADER_LENGTH 2
+#define S2N_SSL2_MAXIMUM_MESSAGE_LENGTH 16383
+#define S2N_SSL2_MAXIMUM_RECORD_LENGTH (S2N_SSL2_MAXIMUM_MESSAGE_LENGTH + S2N_SSL2_RECORD_HEADER_LENGTH)
+
+/* s2n can use a "small" record length that is aligned to the dominant internet MTU;
+ * 1500 bytes, minus 20 bytes for an IP header, minus 20 bytes for a tcp
+ * header and 20 bytes for tcp/ip options (timestamp, sack etc) and a "large" record
+ * length that is designed to maximize throughput (fewer MACs per byte transferred
+ * and better efficiency of crypto engines).
+ */
+#define S2N_SMALL_RECORD_LENGTH (1500 - 20 - 20 - 20)
+#define S2N_SMALL_FRAGMENT_LENGTH (S2N_SMALL_RECORD_LENGTH - S2N_TLS_RECORD_HEADER_LENGTH)
+
+/* Testing in the wild has found 8k max record sizes give a good balance of low latency
+ * and throughput.
+ */
+#define S2N_DEFAULT_RECORD_LENGTH 8092
+#define S2N_DEFAULT_FRAGMENT_LENGTH (S2N_DEFAULT_RECORD_LENGTH - S2N_TLS_RECORD_HEADER_LENGTH)
+
+/* S2N_LARGE_RECORD_LENGTH is used for initializing output buffers, we use the largest
+ * possible value of all supported protocols to avoid branching at runtime
+ */
+#define S2N_LARGE_RECORD_LENGTH S2N_TLS_MAXIMUM_RECORD_LENGTH
+#define S2N_LARGE_FRAGMENT_LENGTH S2N_TLS_MAXIMUM_FRAGMENT_LENGTH
+#define S2N_TLS13_LARGE_FRAGMENT_LENGTH S2N_TLS13_MAXIMUM_FRAGMENT_LENGTH
+
+/* Cap dynamic record resize threshold to 8M */
+#define S2N_TLS_MAX_RESIZE_THRESHOLD (1024 * 1024 * 8)
+
+/* Put a 64k cap on the size of any handshake message */
+#define S2N_MAXIMUM_HANDSHAKE_MESSAGE_LENGTH (64 * 1024)
+
+/* Maximum size for full encoded TLSInnerPlaintext (https://tools.ietf.org/html/rfc8446#section-5.4) */
+#define S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH ((1 << 14) + 1)
+
+/* Alert messages are always 2 bytes long */
+#define S2N_ALERT_LENGTH 2
+
+/* Handshake messages have their own header too */
+#define TLS_HANDSHAKE_HEADER_LENGTH 4
+
+#define S2N_MAX_SERVER_NAME 255
diff --git a/contrib/restricted/aws/s2n/tls/s2n_x509_validator.c b/contrib/restricted/aws/s2n/tls/s2n_x509_validator.c
index be03383648..da2eea8be6 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_x509_validator.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_x509_validator.c
@@ -1,613 +1,613 @@
-/*
- * 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_openssl.h"
-#include "crypto/s2n_openssl_x509.h"
-#include "utils/s2n_asn1_time.h"
-#include "utils/s2n_result.h"
-#include "utils/s2n_safety.h"
-#include "utils/s2n_rfc5952.h"
-#include "tls/extensions/s2n_extension_list.h"
-#include "tls/s2n_config.h"
-#include "tls/s2n_connection.h"
-
-#include <arpa/inet.h>
-#include <sys/socket.h>
-
-#include <openssl/err.h>
-#include <openssl/asn1.h>
-#include <openssl/x509.h>
-
-#if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
-#include <openssl/ocsp.h>
-#endif
-
-#ifndef X509_V_FLAG_PARTIAL_CHAIN
-#define X509_V_FLAG_PARTIAL_CHAIN 0x80000
-#endif
-
-#define DEFAULT_MAX_CHAIN_DEPTH 7
-/* Time used by default for nextUpdate if none provided in OCSP: 1 hour since thisUpdate. */
-#define DEFAULT_OCSP_NEXT_UPDATE_PERIOD 3600000000000
-
-typedef enum {
- UNINIT,
- INIT,
- VALIDATED,
- OCSP_VALIDATED,
-} validator_state;
-
-uint8_t s2n_x509_ocsp_stapling_supported(void) {
- return S2N_OCSP_STAPLING_SUPPORTED;
-}
-
-void s2n_x509_trust_store_init_empty(struct s2n_x509_trust_store *store) {
- store->trust_store = NULL;
-}
-
-uint8_t s2n_x509_trust_store_has_certs(struct s2n_x509_trust_store *store) {
- return store->trust_store ? (uint8_t) 1 : (uint8_t) 0;
-}
-
-int s2n_x509_trust_store_from_system_defaults(struct s2n_x509_trust_store *store) {
- if (!store->trust_store) {
- store->trust_store = X509_STORE_new();
- notnull_check(store->trust_store);
- }
-
- int err_code = X509_STORE_set_default_paths(store->trust_store);
- if (!err_code) {
- s2n_x509_trust_store_wipe(store);
- S2N_ERROR(S2N_ERR_X509_TRUST_STORE);
- }
-
- X509_STORE_set_flags(store->trust_store, X509_VP_FLAG_DEFAULT);
-
- return 0;
-}
-
-int s2n_x509_trust_store_add_pem(struct s2n_x509_trust_store *store, const char *pem)
-{
- notnull_check(store);
- notnull_check(pem);
-
- if (!store->trust_store) {
- store->trust_store = X509_STORE_new();
- }
-
- DEFER_CLEANUP(struct s2n_stuffer pem_in_stuffer = {0}, s2n_stuffer_free);
- DEFER_CLEANUP(struct s2n_stuffer der_out_stuffer = {0}, s2n_stuffer_free);
-
- GUARD(s2n_stuffer_alloc_ro_from_string(&pem_in_stuffer, pem));
- GUARD(s2n_stuffer_growable_alloc(&der_out_stuffer, 2048));
-
- do {
- DEFER_CLEANUP(struct s2n_blob next_cert = {0}, s2n_free);
-
- GUARD(s2n_stuffer_certificate_from_pem(&pem_in_stuffer, &der_out_stuffer));
- GUARD(s2n_alloc(&next_cert, s2n_stuffer_data_available(&der_out_stuffer)));
- GUARD(s2n_stuffer_read(&der_out_stuffer, &next_cert));
-
- const uint8_t *data = next_cert.data;
- DEFER_CLEANUP(X509 *ca_cert = d2i_X509(NULL, &data, next_cert.size), X509_free_pointer);
- S2N_ERROR_IF(ca_cert == NULL, S2N_ERR_DECODE_CERTIFICATE);
-
- GUARD_OSSL(X509_STORE_add_cert(store->trust_store, ca_cert), S2N_ERR_DECODE_CERTIFICATE);
- } while (s2n_stuffer_data_available(&pem_in_stuffer));
-
- return 0;
-}
-
-int s2n_x509_trust_store_from_ca_file(struct s2n_x509_trust_store *store, const char *ca_pem_filename, const char *ca_dir) {
- if (!store->trust_store) {
- store->trust_store = X509_STORE_new();
- notnull_check(store->trust_store);
- }
-
- int err_code = X509_STORE_load_locations(store->trust_store, ca_pem_filename, ca_dir);
- if (!err_code) {
- s2n_x509_trust_store_wipe(store);
- S2N_ERROR(S2N_ERR_X509_TRUST_STORE);
- }
-
- /* It's a likely scenario if this function is called, a self-signed certificate is used, and that is was generated
- * without a trust anchor. However if you call this function, the assumption is you trust ca_file or path and if a certificate
- * is encountered that's in that path, it should be trusted. The following flag tells libcrypto to not care that the cert
- * is missing a root anchor. */
- unsigned long flags = X509_VP_FLAG_DEFAULT;
- flags |= X509_V_FLAG_PARTIAL_CHAIN;
- X509_STORE_set_flags(store->trust_store, flags);
-
- return 0;
-}
-
-void s2n_x509_trust_store_wipe(struct s2n_x509_trust_store *store) {
- if (store->trust_store) {
- X509_STORE_free(store->trust_store);
- store->trust_store = NULL;
- }
-}
-
-int s2n_x509_validator_init_no_x509_validation(struct s2n_x509_validator *validator) {
- notnull_check(validator);
- validator->trust_store = NULL;
- validator->store_ctx = NULL;
- validator->skip_cert_validation = 1;
- validator->check_stapled_ocsp = 0;
- validator->max_chain_depth = DEFAULT_MAX_CHAIN_DEPTH;
- validator->state = INIT;
- validator->cert_chain_from_wire = sk_X509_new_null();
-
- return 0;
-}
-
-int s2n_x509_validator_init(struct s2n_x509_validator *validator, struct s2n_x509_trust_store *trust_store, uint8_t check_ocsp) {
- notnull_check(trust_store);
- validator->trust_store = trust_store;
- validator->skip_cert_validation = 0;
- validator->check_stapled_ocsp = check_ocsp;
- validator->max_chain_depth = DEFAULT_MAX_CHAIN_DEPTH;
- validator->store_ctx = NULL;
- if (validator->trust_store->trust_store) {
- validator->store_ctx = X509_STORE_CTX_new();
- notnull_check(validator->store_ctx);
- }
- validator->cert_chain_from_wire = sk_X509_new_null();
- validator->state = INIT;
-
- return 0;
-}
-
-static inline void wipe_cert_chain(STACK_OF(X509) *cert_chain) {
- if (cert_chain) {
- sk_X509_pop_free(cert_chain, X509_free);
- }
-}
-
-void s2n_x509_validator_wipe(struct s2n_x509_validator *validator) {
- if (validator->store_ctx) {
- X509_STORE_CTX_free(validator->store_ctx);
- validator->store_ctx = NULL;
- }
- wipe_cert_chain(validator->cert_chain_from_wire);
- validator->cert_chain_from_wire = NULL;
- validator->trust_store = NULL;
- validator->skip_cert_validation = 0;
- validator->state = UNINIT;
- validator->max_chain_depth = 0;
-}
-
-int s2n_x509_validator_set_max_chain_depth(struct s2n_x509_validator *validator, uint16_t max_depth) {
- notnull_check(validator);
- S2N_ERROR_IF(max_depth == 0, S2N_ERR_INVALID_ARGUMENT);
-
- validator->max_chain_depth = max_depth;
- return 0;
-}
-
-/*
- * For each name in the cert. Iterate them. Call the callback. If one returns true, then consider it validated,
- * if none of them return true, the cert is considered invalid.
- */
-static uint8_t s2n_verify_host_information(struct s2n_x509_validator *validator, struct s2n_connection *conn, X509 *public_cert) {
- (void)validator;
- uint8_t verified = 0;
- uint8_t san_found = 0;
-
- /* Check SubjectAltNames before CommonName as per RFC 6125 6.4.4 */
- STACK_OF(GENERAL_NAME) *names_list = X509_get_ext_d2i(public_cert, NID_subject_alt_name, NULL, NULL);
- int n = sk_GENERAL_NAME_num(names_list);
- for (int i = 0; i < n && !verified; i++) {
- GENERAL_NAME *current_name = sk_GENERAL_NAME_value(names_list, i);
- if (current_name->type == GEN_DNS) {
- san_found = 1;
-
- const char *name = (const char *) ASN1_STRING_data(current_name->d.ia5);
- size_t name_len = (size_t) ASN1_STRING_length(current_name->d.ia5);
-
- verified = conn->verify_host_fn(name, name_len, conn->data_for_verify_host);
- } else if (current_name->type == GEN_URI) {
- const char *name = (const char *) ASN1_STRING_data(current_name->d.ia5);
- size_t name_len = (size_t) ASN1_STRING_length(current_name->d.ia5);
-
- verified = conn->verify_host_fn(name, name_len, conn->data_for_verify_host);
- } else if (current_name->type == GEN_IPADD) {
- san_found = 1;
- /* try to validate an IP address if it's in the subject alt name. */
- const unsigned char *ip_addr = current_name->d.iPAddress->data;
- size_t ip_addr_len = (size_t)current_name->d.iPAddress->length;
-
- s2n_result parse_result = S2N_RESULT_ERROR;
- s2n_stack_blob(address, INET6_ADDRSTRLEN + 1, INET6_ADDRSTRLEN + 1);
- if (ip_addr_len == 4) {
- parse_result = s2n_inet_ntop(AF_INET, ip_addr, &address);
- } else if (ip_addr_len == 16) {
- parse_result = s2n_inet_ntop(AF_INET6, ip_addr, &address);
- }
-
- /* strlen should be safe here since we made sure we were null terminated AND that inet_ntop succeeded */
- if (s2n_result_is_ok(parse_result)) {
- verified = conn->verify_host_fn(
- (const char *)address.data,
- strlen((const char *)address.data),
- conn->data_for_verify_host);
- }
- }
- }
-
- GENERAL_NAMES_free(names_list);
-
- /* if no SubjectAltNames of type DNS found, go to the common name. */
- if (!verified && !san_found) {
- X509_NAME *subject_name = X509_get_subject_name(public_cert);
- if (subject_name) {
- int next_idx = 0, curr_idx = -1;
- while ((next_idx = X509_NAME_get_index_by_NID(subject_name, NID_commonName, curr_idx)) >= 0) {
- curr_idx = next_idx;
- }
-
- if (curr_idx >= 0) {
- ASN1_STRING *common_name =
- X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject_name, curr_idx));
-
- if (common_name) {
- char peer_cn[255];
- static size_t peer_cn_size = sizeof(peer_cn);
- memset_check(&peer_cn, 0, peer_cn_size);
-
- /* X520CommonName allows the following ANSI string types per RFC 5280 Appendix A.1 */
- if (ASN1_STRING_type(common_name) == V_ASN1_TELETEXSTRING ||
- ASN1_STRING_type(common_name) == V_ASN1_PRINTABLESTRING ||
- ASN1_STRING_type(common_name) == V_ASN1_UNIVERSALSTRING ||
- ASN1_STRING_type(common_name) == V_ASN1_UTF8STRING ||
- ASN1_STRING_type(common_name) == V_ASN1_BMPSTRING ) {
-
- size_t len = (size_t) ASN1_STRING_length(common_name);
-
- lte_check(len, sizeof(peer_cn) - 1);
- memcpy_check(peer_cn, ASN1_STRING_data(common_name), len);
- verified = conn->verify_host_fn(peer_cn, len, conn->data_for_verify_host);
- }
- }
- }
- }
- }
-
- return verified;
-}
-
-s2n_cert_validation_code s2n_x509_validator_validate_cert_chain(struct s2n_x509_validator *validator, struct s2n_connection *conn,
- uint8_t *cert_chain_in, uint32_t cert_chain_len, s2n_pkey_type *pkey_type, struct s2n_pkey *public_key_out) {
- S2N_ERROR_IF(!validator->skip_cert_validation && !s2n_x509_trust_store_has_certs(validator->trust_store), S2N_ERR_CERT_UNTRUSTED);
- S2N_ERROR_IF(validator->state != INIT, S2N_ERR_INVALID_STATE);
-
- struct s2n_blob cert_chain_blob = {.data = cert_chain_in, .size = cert_chain_len};
- DEFER_CLEANUP(struct s2n_stuffer cert_chain_in_stuffer = {0}, s2n_stuffer_free);
-
- S2N_ERROR_IF(s2n_stuffer_init(&cert_chain_in_stuffer, &cert_chain_blob) < 0, S2N_ERR_CERT_UNTRUSTED);
- S2N_ERROR_IF(s2n_stuffer_write(&cert_chain_in_stuffer, &cert_chain_blob) < 0, S2N_ERR_CERT_UNTRUSTED);
-
- s2n_parsed_extensions_list first_certificate_extensions = {0};
-
- X509 *server_cert = NULL;
-
- DEFER_CLEANUP(struct s2n_pkey public_key = {0}, s2n_pkey_free);
- s2n_pkey_zero_init(&public_key);
-
- while (s2n_stuffer_data_available(&cert_chain_in_stuffer) && sk_X509_num(validator->cert_chain_from_wire) < validator->max_chain_depth) {
- uint32_t certificate_size = 0;
-
- S2N_ERROR_IF(s2n_stuffer_read_uint24(&cert_chain_in_stuffer, &certificate_size) < 0, S2N_ERR_CERT_UNTRUSTED);
- S2N_ERROR_IF(certificate_size == 0 || certificate_size > s2n_stuffer_data_available(&cert_chain_in_stuffer), S2N_ERR_CERT_UNTRUSTED);
-
- struct s2n_blob asn1cert = {0};
- asn1cert.size = certificate_size;
- asn1cert.data = s2n_stuffer_raw_read(&cert_chain_in_stuffer, certificate_size);
- notnull_check(asn1cert.data);
-
- const uint8_t *data = asn1cert.data;
-
- /* the cert is der encoded, just convert it. */
- server_cert = d2i_X509(NULL, &data, asn1cert.size);
- S2N_ERROR_IF(!server_cert, S2N_ERR_CERT_UNTRUSTED);
-
- /* add the cert to the chain. */
- if (!sk_X509_push(validator->cert_chain_from_wire, server_cert)) {
- X509_free(server_cert);
- S2N_ERROR(S2N_ERR_CERT_UNTRUSTED);
- }
-
- if (!validator->skip_cert_validation) {
- GUARD_AS_POSIX(s2n_validate_certificate_signature(conn, server_cert));
- }
-
- /* Pull the public key from the first certificate */
- if (sk_X509_num(validator->cert_chain_from_wire) == 1) {
- S2N_ERROR_IF(s2n_asn1der_to_public_key_and_type(&public_key, pkey_type, &asn1cert) < 0, S2N_ERR_CERT_UNTRUSTED);
- }
-
- /* certificate extensions is a field in TLS 1.3 - https://tools.ietf.org/html/rfc8446#section-4.4.2 */
- if (conn->actual_protocol_version >= S2N_TLS13) {
- s2n_parsed_extensions_list parsed_extensions_list = { 0 };
- GUARD(s2n_extension_list_parse(&cert_chain_in_stuffer, &parsed_extensions_list));
-
- /* RFC 8446: if an extension applies to the entire chain, it SHOULD be included in the first CertificateEntry */
- if (sk_X509_num(validator->cert_chain_from_wire) == 1) {
- first_certificate_extensions = parsed_extensions_list;
- }
- }
- }
-
- /* if this occurred we exceeded validator->max_chain_depth */
- S2N_ERROR_IF(!validator->skip_cert_validation && s2n_stuffer_data_available(&cert_chain_in_stuffer), S2N_ERR_CERT_UNTRUSTED);
- S2N_ERROR_IF(sk_X509_num(validator->cert_chain_from_wire) < 1, S2N_ERR_CERT_UNTRUSTED);
-
- if (!validator->skip_cert_validation) {
- X509 *leaf = sk_X509_value(validator->cert_chain_from_wire, 0);
- S2N_ERROR_IF(!leaf, S2N_ERR_CERT_UNTRUSTED);
- S2N_ERROR_IF(conn->verify_host_fn && !s2n_verify_host_information(validator, conn, leaf), S2N_ERR_CERT_UNTRUSTED);
-
- int op_code = X509_STORE_CTX_init(validator->store_ctx, validator->trust_store->trust_store, leaf, validator->cert_chain_from_wire);
- S2N_ERROR_IF(op_code <= 0, S2N_ERR_CERT_UNTRUSTED);
-
- X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(validator->store_ctx);
- X509_VERIFY_PARAM_set_depth(param, validator->max_chain_depth);
-
- uint64_t current_sys_time = 0;
- conn->config->wall_clock(conn->config->sys_clock_ctx, &current_sys_time);
-
- /* this wants seconds not nanoseconds */
- time_t current_time = (time_t)(current_sys_time / 1000000000);
- X509_STORE_CTX_set_time(validator->store_ctx, 0, current_time);
-
- op_code = X509_verify_cert(validator->store_ctx);
-
- S2N_ERROR_IF(op_code <= 0, S2N_ERR_CERT_UNTRUSTED);
- validator->state = VALIDATED;
- }
-
- if (conn->actual_protocol_version >= S2N_TLS13) {
- GUARD(s2n_extension_list_process(S2N_EXTENSION_LIST_CERTIFICATE, conn, &first_certificate_extensions));
- }
-
- *public_key_out = public_key;
-
- /* Reset the old struct, so we don't clean up public_key_out */
- s2n_pkey_zero_init(&public_key);
-
- return S2N_CERT_OK;
-}
-
-s2n_cert_validation_code s2n_x509_validator_validate_cert_stapled_ocsp_response(struct s2n_x509_validator *validator,
- struct s2n_connection *conn, const uint8_t *ocsp_response_raw, uint32_t ocsp_response_length) {
-
- if (validator->skip_cert_validation || !validator->check_stapled_ocsp) {
- validator->state = OCSP_VALIDATED;
- return S2N_CERT_OK;
- }
-
- S2N_ERROR_IF(validator->state != VALIDATED, S2N_ERR_INVALID_STATE);
-
-#if !S2N_OCSP_STAPLING_SUPPORTED
- /* Default to safety */
- return S2N_CERT_ERR_UNTRUSTED;
-#else
-
- OCSP_RESPONSE *ocsp_response = NULL;
- OCSP_BASICRESP *basic_response = NULL;
- STACK_OF(X509) *cert_chain = NULL;
-
- s2n_cert_validation_code ret_val = S2N_CERT_ERR_INVALID;
-
- if (!ocsp_response_raw) {
- return ret_val;
- }
-
- ocsp_response = d2i_OCSP_RESPONSE(NULL, &ocsp_response_raw, ocsp_response_length);
-
- if (!ocsp_response) {
- goto clean_up;
- }
-
- int ocsp_status = OCSP_response_status(ocsp_response);
-
- if (ocsp_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
- goto clean_up;
- }
-
- basic_response = OCSP_response_get1_basic(ocsp_response);
- if (!basic_response) {
- goto clean_up;
- }
-
- /* X509_STORE_CTX_get0_chain() is better because it doesn't return a copy. But it's not available for Openssl 1.0.2.
- * Therefore, we call this variant and clean it up at the end of the function.
- * See the comments here:
- * https://www.openssl.org/docs/man1.0.2/man3/X509_STORE_CTX_get1_chain.html
- */
- cert_chain = X509_STORE_CTX_get1_chain(validator->store_ctx);
- if (!cert_chain) {
- goto clean_up;
- }
-
- const int certs_in_chain = sk_X509_num(cert_chain);
-
- if (!certs_in_chain) {
- goto clean_up;
- }
-
- /* leaf is the top: not the bottom. */
- X509 *subject = sk_X509_value(cert_chain, 0);
- X509 *issuer = NULL;
- /* find the issuer in the chain. If it's not there. Fail everything. */
- for (int i = 0; i < certs_in_chain; ++i) {
- X509 *issuer_candidate = sk_X509_value(cert_chain, i);
- const int issuer_value = X509_check_issued(issuer_candidate, subject);
-
- if (issuer_value == X509_V_OK) {
- issuer = issuer_candidate;
- break;
- }
- }
-
- if (!issuer) {
- goto clean_up;
- }
-
- /* Important: this checks that the stapled ocsp response CAN be verified, not that it has been verified. */
- const int ocsp_verify_err = OCSP_basic_verify(basic_response, cert_chain, validator->trust_store->trust_store, 0);
- /* do the crypto checks on the response.*/
- if (!ocsp_verify_err) {
- ret_val = S2N_CERT_ERR_UNTRUSTED;
- goto clean_up;
- }
-
- int status = 0;
- int reason = 0;
-
- /* sha1 is the only supported OCSP digest */
- OCSP_CERTID *cert_id = OCSP_cert_to_id(EVP_sha1(), subject, issuer);
-
- if (!cert_id) {
- goto clean_up;
- }
-
- ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd;
- /* Actual verification of the response */
- const int ocsp_resp_find_status_res = OCSP_resp_find_status(basic_response, cert_id, &status, &reason, &revtime, &thisupd, &nextupd);
- OCSP_CERTID_free(cert_id);
-
- if (!ocsp_resp_find_status_res) {
- ret_val = S2N_CERT_ERR_UNTRUSTED;
- goto clean_up;
- }
-
- uint64_t this_update = 0;
- s2n_result thisupd_result = s2n_asn1_time_to_nano_since_epoch_ticks((const char *) thisupd->data,
- (uint32_t) thisupd->length, &this_update);
-
- uint64_t next_update = 0;
- s2n_result nextupd_result = S2N_RESULT_OK;
- if (nextupd) {
- nextupd_result = s2n_asn1_time_to_nano_since_epoch_ticks((const char *) nextupd->data,
- (uint32_t) nextupd->length, &next_update);
- } else {
- next_update = this_update + DEFAULT_OCSP_NEXT_UPDATE_PERIOD;
- }
-
- uint64_t current_time = 0;
- const int current_time_err = conn->config->wall_clock(conn->config->sys_clock_ctx, &current_time);
-
- if (current_time_err) {
- goto clean_up;
- }
-
- if (s2n_result_is_error(thisupd_result) || s2n_result_is_error(nextupd_result) || current_time_err) {
- ret_val = S2N_CERT_ERR_UNTRUSTED;
- goto clean_up;
- }
-
- if (current_time < this_update || current_time > next_update) {
- ret_val = S2N_CERT_ERR_EXPIRED;
- goto clean_up;
- }
-
- switch (status) {
- case V_OCSP_CERTSTATUS_GOOD:
- validator->state = OCSP_VALIDATED;
- ret_val = S2N_CERT_OK;
- break;
- case V_OCSP_CERTSTATUS_REVOKED:
- ret_val = S2N_CERT_ERR_REVOKED;
- goto clean_up;
- case V_OCSP_CERTSTATUS_UNKNOWN:
- goto clean_up;
- default:
- goto clean_up;
- }
-
- clean_up:
- if (basic_response) {
- OCSP_BASICRESP_free(basic_response);
- }
-
- if (ocsp_response) {
- OCSP_RESPONSE_free(ocsp_response);
- }
-
- if (cert_chain) {
- wipe_cert_chain(cert_chain);
- }
-
- return ret_val;
-#endif /* S2N_OCSP_STAPLING_SUPPORTED */
-}
-
-S2N_RESULT s2n_validate_certificate_signature(struct s2n_connection *conn, X509 *x509_cert)
-{
- ENSURE_REF(conn);
- ENSURE_REF(x509_cert);
-
- const struct s2n_security_policy *security_policy;
- GUARD_AS_RESULT(s2n_connection_get_security_policy(conn, &security_policy));
-
- if (security_policy->certificate_signature_preferences == NULL) {
- return S2N_RESULT_OK;
- }
-
- X509_NAME *issuer_name = X509_get_issuer_name(x509_cert);
- ENSURE_REF(issuer_name);
-
- X509_NAME *subject_name = X509_get_subject_name(x509_cert);
- ENSURE_REF(subject_name);
-
- /* Do not validate any self-signed certificates */
- if (X509_NAME_cmp(issuer_name, subject_name) == 0) {
- return S2N_RESULT_OK;
- }
-
- GUARD_RESULT(s2n_validate_sig_scheme_supported(conn, x509_cert, security_policy->certificate_signature_preferences));
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_validate_sig_scheme_supported(struct s2n_connection *conn, X509 *x509_cert, const struct s2n_signature_preferences *cert_sig_preferences)
-{
- ENSURE_REF(conn);
- ENSURE_REF(x509_cert);
- ENSURE_REF(cert_sig_preferences);
-
- int nid = 0;
-
- #if defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER < 0x02070000f)
- ENSURE_REF(x509_cert->sig_alg);
- nid = OBJ_obj2nid(x509_cert->sig_alg->algorithm);
- #else
- nid = X509_get_signature_nid(x509_cert);
- #endif
-
- for (size_t i = 0; i < cert_sig_preferences->count; i++) {
-
- if (cert_sig_preferences->signature_schemes[i]->libcrypto_nid == nid) {
- /* SHA-1 algorithms are not supported in certificate signatures in TLS1.3 */
- ENSURE(!(conn->actual_protocol_version >= S2N_TLS13 &&
- cert_sig_preferences->signature_schemes[i]->hash_alg == S2N_HASH_SHA1), S2N_ERR_CERT_UNTRUSTED);
-
- return S2N_RESULT_OK;
- }
- }
-
- BAIL(S2N_ERR_CERT_UNTRUSTED);
-}
+/*
+ * 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_openssl.h"
+#include "crypto/s2n_openssl_x509.h"
+#include "utils/s2n_asn1_time.h"
+#include "utils/s2n_result.h"
+#include "utils/s2n_safety.h"
+#include "utils/s2n_rfc5952.h"
+#include "tls/extensions/s2n_extension_list.h"
+#include "tls/s2n_config.h"
+#include "tls/s2n_connection.h"
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+#include <openssl/err.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+
+#if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
+#include <openssl/ocsp.h>
+#endif
+
+#ifndef X509_V_FLAG_PARTIAL_CHAIN
+#define X509_V_FLAG_PARTIAL_CHAIN 0x80000
+#endif
+
+#define DEFAULT_MAX_CHAIN_DEPTH 7
+/* Time used by default for nextUpdate if none provided in OCSP: 1 hour since thisUpdate. */
+#define DEFAULT_OCSP_NEXT_UPDATE_PERIOD 3600000000000
+
+typedef enum {
+ UNINIT,
+ INIT,
+ VALIDATED,
+ OCSP_VALIDATED,
+} validator_state;
+
+uint8_t s2n_x509_ocsp_stapling_supported(void) {
+ return S2N_OCSP_STAPLING_SUPPORTED;
+}
+
+void s2n_x509_trust_store_init_empty(struct s2n_x509_trust_store *store) {
+ store->trust_store = NULL;
+}
+
+uint8_t s2n_x509_trust_store_has_certs(struct s2n_x509_trust_store *store) {
+ return store->trust_store ? (uint8_t) 1 : (uint8_t) 0;
+}
+
+int s2n_x509_trust_store_from_system_defaults(struct s2n_x509_trust_store *store) {
+ if (!store->trust_store) {
+ store->trust_store = X509_STORE_new();
+ notnull_check(store->trust_store);
+ }
+
+ int err_code = X509_STORE_set_default_paths(store->trust_store);
+ if (!err_code) {
+ s2n_x509_trust_store_wipe(store);
+ S2N_ERROR(S2N_ERR_X509_TRUST_STORE);
+ }
+
+ X509_STORE_set_flags(store->trust_store, X509_VP_FLAG_DEFAULT);
+
+ return 0;
+}
+
+int s2n_x509_trust_store_add_pem(struct s2n_x509_trust_store *store, const char *pem)
+{
+ notnull_check(store);
+ notnull_check(pem);
+
+ if (!store->trust_store) {
+ store->trust_store = X509_STORE_new();
+ }
+
+ DEFER_CLEANUP(struct s2n_stuffer pem_in_stuffer = {0}, s2n_stuffer_free);
+ DEFER_CLEANUP(struct s2n_stuffer der_out_stuffer = {0}, s2n_stuffer_free);
+
+ GUARD(s2n_stuffer_alloc_ro_from_string(&pem_in_stuffer, pem));
+ GUARD(s2n_stuffer_growable_alloc(&der_out_stuffer, 2048));
+
+ do {
+ DEFER_CLEANUP(struct s2n_blob next_cert = {0}, s2n_free);
+
+ GUARD(s2n_stuffer_certificate_from_pem(&pem_in_stuffer, &der_out_stuffer));
+ GUARD(s2n_alloc(&next_cert, s2n_stuffer_data_available(&der_out_stuffer)));
+ GUARD(s2n_stuffer_read(&der_out_stuffer, &next_cert));
+
+ const uint8_t *data = next_cert.data;
+ DEFER_CLEANUP(X509 *ca_cert = d2i_X509(NULL, &data, next_cert.size), X509_free_pointer);
+ S2N_ERROR_IF(ca_cert == NULL, S2N_ERR_DECODE_CERTIFICATE);
+
+ GUARD_OSSL(X509_STORE_add_cert(store->trust_store, ca_cert), S2N_ERR_DECODE_CERTIFICATE);
+ } while (s2n_stuffer_data_available(&pem_in_stuffer));
+
+ return 0;
+}
+
+int s2n_x509_trust_store_from_ca_file(struct s2n_x509_trust_store *store, const char *ca_pem_filename, const char *ca_dir) {
+ if (!store->trust_store) {
+ store->trust_store = X509_STORE_new();
+ notnull_check(store->trust_store);
+ }
+
+ int err_code = X509_STORE_load_locations(store->trust_store, ca_pem_filename, ca_dir);
+ if (!err_code) {
+ s2n_x509_trust_store_wipe(store);
+ S2N_ERROR(S2N_ERR_X509_TRUST_STORE);
+ }
+
+ /* It's a likely scenario if this function is called, a self-signed certificate is used, and that is was generated
+ * without a trust anchor. However if you call this function, the assumption is you trust ca_file or path and if a certificate
+ * is encountered that's in that path, it should be trusted. The following flag tells libcrypto to not care that the cert
+ * is missing a root anchor. */
+ unsigned long flags = X509_VP_FLAG_DEFAULT;
+ flags |= X509_V_FLAG_PARTIAL_CHAIN;
+ X509_STORE_set_flags(store->trust_store, flags);
+
+ return 0;
+}
+
+void s2n_x509_trust_store_wipe(struct s2n_x509_trust_store *store) {
+ if (store->trust_store) {
+ X509_STORE_free(store->trust_store);
+ store->trust_store = NULL;
+ }
+}
+
+int s2n_x509_validator_init_no_x509_validation(struct s2n_x509_validator *validator) {
+ notnull_check(validator);
+ validator->trust_store = NULL;
+ validator->store_ctx = NULL;
+ validator->skip_cert_validation = 1;
+ validator->check_stapled_ocsp = 0;
+ validator->max_chain_depth = DEFAULT_MAX_CHAIN_DEPTH;
+ validator->state = INIT;
+ validator->cert_chain_from_wire = sk_X509_new_null();
+
+ return 0;
+}
+
+int s2n_x509_validator_init(struct s2n_x509_validator *validator, struct s2n_x509_trust_store *trust_store, uint8_t check_ocsp) {
+ notnull_check(trust_store);
+ validator->trust_store = trust_store;
+ validator->skip_cert_validation = 0;
+ validator->check_stapled_ocsp = check_ocsp;
+ validator->max_chain_depth = DEFAULT_MAX_CHAIN_DEPTH;
+ validator->store_ctx = NULL;
+ if (validator->trust_store->trust_store) {
+ validator->store_ctx = X509_STORE_CTX_new();
+ notnull_check(validator->store_ctx);
+ }
+ validator->cert_chain_from_wire = sk_X509_new_null();
+ validator->state = INIT;
+
+ return 0;
+}
+
+static inline void wipe_cert_chain(STACK_OF(X509) *cert_chain) {
+ if (cert_chain) {
+ sk_X509_pop_free(cert_chain, X509_free);
+ }
+}
+
+void s2n_x509_validator_wipe(struct s2n_x509_validator *validator) {
+ if (validator->store_ctx) {
+ X509_STORE_CTX_free(validator->store_ctx);
+ validator->store_ctx = NULL;
+ }
+ wipe_cert_chain(validator->cert_chain_from_wire);
+ validator->cert_chain_from_wire = NULL;
+ validator->trust_store = NULL;
+ validator->skip_cert_validation = 0;
+ validator->state = UNINIT;
+ validator->max_chain_depth = 0;
+}
+
+int s2n_x509_validator_set_max_chain_depth(struct s2n_x509_validator *validator, uint16_t max_depth) {
+ notnull_check(validator);
+ S2N_ERROR_IF(max_depth == 0, S2N_ERR_INVALID_ARGUMENT);
+
+ validator->max_chain_depth = max_depth;
+ return 0;
+}
+
+/*
+ * For each name in the cert. Iterate them. Call the callback. If one returns true, then consider it validated,
+ * if none of them return true, the cert is considered invalid.
+ */
+static uint8_t s2n_verify_host_information(struct s2n_x509_validator *validator, struct s2n_connection *conn, X509 *public_cert) {
+ (void)validator;
+ uint8_t verified = 0;
+ uint8_t san_found = 0;
+
+ /* Check SubjectAltNames before CommonName as per RFC 6125 6.4.4 */
+ STACK_OF(GENERAL_NAME) *names_list = X509_get_ext_d2i(public_cert, NID_subject_alt_name, NULL, NULL);
+ int n = sk_GENERAL_NAME_num(names_list);
+ for (int i = 0; i < n && !verified; i++) {
+ GENERAL_NAME *current_name = sk_GENERAL_NAME_value(names_list, i);
+ if (current_name->type == GEN_DNS) {
+ san_found = 1;
+
+ const char *name = (const char *) ASN1_STRING_data(current_name->d.ia5);
+ size_t name_len = (size_t) ASN1_STRING_length(current_name->d.ia5);
+
+ verified = conn->verify_host_fn(name, name_len, conn->data_for_verify_host);
+ } else if (current_name->type == GEN_URI) {
+ const char *name = (const char *) ASN1_STRING_data(current_name->d.ia5);
+ size_t name_len = (size_t) ASN1_STRING_length(current_name->d.ia5);
+
+ verified = conn->verify_host_fn(name, name_len, conn->data_for_verify_host);
+ } else if (current_name->type == GEN_IPADD) {
+ san_found = 1;
+ /* try to validate an IP address if it's in the subject alt name. */
+ const unsigned char *ip_addr = current_name->d.iPAddress->data;
+ size_t ip_addr_len = (size_t)current_name->d.iPAddress->length;
+
+ s2n_result parse_result = S2N_RESULT_ERROR;
+ s2n_stack_blob(address, INET6_ADDRSTRLEN + 1, INET6_ADDRSTRLEN + 1);
+ if (ip_addr_len == 4) {
+ parse_result = s2n_inet_ntop(AF_INET, ip_addr, &address);
+ } else if (ip_addr_len == 16) {
+ parse_result = s2n_inet_ntop(AF_INET6, ip_addr, &address);
+ }
+
+ /* strlen should be safe here since we made sure we were null terminated AND that inet_ntop succeeded */
+ if (s2n_result_is_ok(parse_result)) {
+ verified = conn->verify_host_fn(
+ (const char *)address.data,
+ strlen((const char *)address.data),
+ conn->data_for_verify_host);
+ }
+ }
+ }
+
+ GENERAL_NAMES_free(names_list);
+
+ /* if no SubjectAltNames of type DNS found, go to the common name. */
+ if (!verified && !san_found) {
+ X509_NAME *subject_name = X509_get_subject_name(public_cert);
+ if (subject_name) {
+ int next_idx = 0, curr_idx = -1;
+ while ((next_idx = X509_NAME_get_index_by_NID(subject_name, NID_commonName, curr_idx)) >= 0) {
+ curr_idx = next_idx;
+ }
+
+ if (curr_idx >= 0) {
+ ASN1_STRING *common_name =
+ X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject_name, curr_idx));
+
+ if (common_name) {
+ char peer_cn[255];
+ static size_t peer_cn_size = sizeof(peer_cn);
+ memset_check(&peer_cn, 0, peer_cn_size);
+
+ /* X520CommonName allows the following ANSI string types per RFC 5280 Appendix A.1 */
+ if (ASN1_STRING_type(common_name) == V_ASN1_TELETEXSTRING ||
+ ASN1_STRING_type(common_name) == V_ASN1_PRINTABLESTRING ||
+ ASN1_STRING_type(common_name) == V_ASN1_UNIVERSALSTRING ||
+ ASN1_STRING_type(common_name) == V_ASN1_UTF8STRING ||
+ ASN1_STRING_type(common_name) == V_ASN1_BMPSTRING ) {
+
+ size_t len = (size_t) ASN1_STRING_length(common_name);
+
+ lte_check(len, sizeof(peer_cn) - 1);
+ memcpy_check(peer_cn, ASN1_STRING_data(common_name), len);
+ verified = conn->verify_host_fn(peer_cn, len, conn->data_for_verify_host);
+ }
+ }
+ }
+ }
+ }
+
+ return verified;
+}
+
+s2n_cert_validation_code s2n_x509_validator_validate_cert_chain(struct s2n_x509_validator *validator, struct s2n_connection *conn,
+ uint8_t *cert_chain_in, uint32_t cert_chain_len, s2n_pkey_type *pkey_type, struct s2n_pkey *public_key_out) {
+ S2N_ERROR_IF(!validator->skip_cert_validation && !s2n_x509_trust_store_has_certs(validator->trust_store), S2N_ERR_CERT_UNTRUSTED);
+ S2N_ERROR_IF(validator->state != INIT, S2N_ERR_INVALID_STATE);
+
+ struct s2n_blob cert_chain_blob = {.data = cert_chain_in, .size = cert_chain_len};
+ DEFER_CLEANUP(struct s2n_stuffer cert_chain_in_stuffer = {0}, s2n_stuffer_free);
+
+ S2N_ERROR_IF(s2n_stuffer_init(&cert_chain_in_stuffer, &cert_chain_blob) < 0, S2N_ERR_CERT_UNTRUSTED);
+ S2N_ERROR_IF(s2n_stuffer_write(&cert_chain_in_stuffer, &cert_chain_blob) < 0, S2N_ERR_CERT_UNTRUSTED);
+
+ s2n_parsed_extensions_list first_certificate_extensions = {0};
+
+ X509 *server_cert = NULL;
+
+ DEFER_CLEANUP(struct s2n_pkey public_key = {0}, s2n_pkey_free);
+ s2n_pkey_zero_init(&public_key);
+
+ while (s2n_stuffer_data_available(&cert_chain_in_stuffer) && sk_X509_num(validator->cert_chain_from_wire) < validator->max_chain_depth) {
+ uint32_t certificate_size = 0;
+
+ S2N_ERROR_IF(s2n_stuffer_read_uint24(&cert_chain_in_stuffer, &certificate_size) < 0, S2N_ERR_CERT_UNTRUSTED);
+ S2N_ERROR_IF(certificate_size == 0 || certificate_size > s2n_stuffer_data_available(&cert_chain_in_stuffer), S2N_ERR_CERT_UNTRUSTED);
+
+ struct s2n_blob asn1cert = {0};
+ asn1cert.size = certificate_size;
+ asn1cert.data = s2n_stuffer_raw_read(&cert_chain_in_stuffer, certificate_size);
+ notnull_check(asn1cert.data);
+
+ const uint8_t *data = asn1cert.data;
+
+ /* the cert is der encoded, just convert it. */
+ server_cert = d2i_X509(NULL, &data, asn1cert.size);
+ S2N_ERROR_IF(!server_cert, S2N_ERR_CERT_UNTRUSTED);
+
+ /* add the cert to the chain. */
+ if (!sk_X509_push(validator->cert_chain_from_wire, server_cert)) {
+ X509_free(server_cert);
+ S2N_ERROR(S2N_ERR_CERT_UNTRUSTED);
+ }
+
+ if (!validator->skip_cert_validation) {
+ GUARD_AS_POSIX(s2n_validate_certificate_signature(conn, server_cert));
+ }
+
+ /* Pull the public key from the first certificate */
+ if (sk_X509_num(validator->cert_chain_from_wire) == 1) {
+ S2N_ERROR_IF(s2n_asn1der_to_public_key_and_type(&public_key, pkey_type, &asn1cert) < 0, S2N_ERR_CERT_UNTRUSTED);
+ }
+
+ /* certificate extensions is a field in TLS 1.3 - https://tools.ietf.org/html/rfc8446#section-4.4.2 */
+ if (conn->actual_protocol_version >= S2N_TLS13) {
+ s2n_parsed_extensions_list parsed_extensions_list = { 0 };
+ GUARD(s2n_extension_list_parse(&cert_chain_in_stuffer, &parsed_extensions_list));
+
+ /* RFC 8446: if an extension applies to the entire chain, it SHOULD be included in the first CertificateEntry */
+ if (sk_X509_num(validator->cert_chain_from_wire) == 1) {
+ first_certificate_extensions = parsed_extensions_list;
+ }
+ }
+ }
+
+ /* if this occurred we exceeded validator->max_chain_depth */
+ S2N_ERROR_IF(!validator->skip_cert_validation && s2n_stuffer_data_available(&cert_chain_in_stuffer), S2N_ERR_CERT_UNTRUSTED);
+ S2N_ERROR_IF(sk_X509_num(validator->cert_chain_from_wire) < 1, S2N_ERR_CERT_UNTRUSTED);
+
+ if (!validator->skip_cert_validation) {
+ X509 *leaf = sk_X509_value(validator->cert_chain_from_wire, 0);
+ S2N_ERROR_IF(!leaf, S2N_ERR_CERT_UNTRUSTED);
+ S2N_ERROR_IF(conn->verify_host_fn && !s2n_verify_host_information(validator, conn, leaf), S2N_ERR_CERT_UNTRUSTED);
+
+ int op_code = X509_STORE_CTX_init(validator->store_ctx, validator->trust_store->trust_store, leaf, validator->cert_chain_from_wire);
+ S2N_ERROR_IF(op_code <= 0, S2N_ERR_CERT_UNTRUSTED);
+
+ X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(validator->store_ctx);
+ X509_VERIFY_PARAM_set_depth(param, validator->max_chain_depth);
+
+ uint64_t current_sys_time = 0;
+ conn->config->wall_clock(conn->config->sys_clock_ctx, &current_sys_time);
+
+ /* this wants seconds not nanoseconds */
+ time_t current_time = (time_t)(current_sys_time / 1000000000);
+ X509_STORE_CTX_set_time(validator->store_ctx, 0, current_time);
+
+ op_code = X509_verify_cert(validator->store_ctx);
+
+ S2N_ERROR_IF(op_code <= 0, S2N_ERR_CERT_UNTRUSTED);
+ validator->state = VALIDATED;
+ }
+
+ if (conn->actual_protocol_version >= S2N_TLS13) {
+ GUARD(s2n_extension_list_process(S2N_EXTENSION_LIST_CERTIFICATE, conn, &first_certificate_extensions));
+ }
+
+ *public_key_out = public_key;
+
+ /* Reset the old struct, so we don't clean up public_key_out */
+ s2n_pkey_zero_init(&public_key);
+
+ return S2N_CERT_OK;
+}
+
+s2n_cert_validation_code s2n_x509_validator_validate_cert_stapled_ocsp_response(struct s2n_x509_validator *validator,
+ struct s2n_connection *conn, const uint8_t *ocsp_response_raw, uint32_t ocsp_response_length) {
+
+ if (validator->skip_cert_validation || !validator->check_stapled_ocsp) {
+ validator->state = OCSP_VALIDATED;
+ return S2N_CERT_OK;
+ }
+
+ S2N_ERROR_IF(validator->state != VALIDATED, S2N_ERR_INVALID_STATE);
+
+#if !S2N_OCSP_STAPLING_SUPPORTED
+ /* Default to safety */
+ return S2N_CERT_ERR_UNTRUSTED;
+#else
+
+ OCSP_RESPONSE *ocsp_response = NULL;
+ OCSP_BASICRESP *basic_response = NULL;
+ STACK_OF(X509) *cert_chain = NULL;
+
+ s2n_cert_validation_code ret_val = S2N_CERT_ERR_INVALID;
+
+ if (!ocsp_response_raw) {
+ return ret_val;
+ }
+
+ ocsp_response = d2i_OCSP_RESPONSE(NULL, &ocsp_response_raw, ocsp_response_length);
+
+ if (!ocsp_response) {
+ goto clean_up;
+ }
+
+ int ocsp_status = OCSP_response_status(ocsp_response);
+
+ if (ocsp_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
+ goto clean_up;
+ }
+
+ basic_response = OCSP_response_get1_basic(ocsp_response);
+ if (!basic_response) {
+ goto clean_up;
+ }
+
+ /* X509_STORE_CTX_get0_chain() is better because it doesn't return a copy. But it's not available for Openssl 1.0.2.
+ * Therefore, we call this variant and clean it up at the end of the function.
+ * See the comments here:
+ * https://www.openssl.org/docs/man1.0.2/man3/X509_STORE_CTX_get1_chain.html
+ */
+ cert_chain = X509_STORE_CTX_get1_chain(validator->store_ctx);
+ if (!cert_chain) {
+ goto clean_up;
+ }
+
+ const int certs_in_chain = sk_X509_num(cert_chain);
+
+ if (!certs_in_chain) {
+ goto clean_up;
+ }
+
+ /* leaf is the top: not the bottom. */
+ X509 *subject = sk_X509_value(cert_chain, 0);
+ X509 *issuer = NULL;
+ /* find the issuer in the chain. If it's not there. Fail everything. */
+ for (int i = 0; i < certs_in_chain; ++i) {
+ X509 *issuer_candidate = sk_X509_value(cert_chain, i);
+ const int issuer_value = X509_check_issued(issuer_candidate, subject);
+
+ if (issuer_value == X509_V_OK) {
+ issuer = issuer_candidate;
+ break;
+ }
+ }
+
+ if (!issuer) {
+ goto clean_up;
+ }
+
+ /* Important: this checks that the stapled ocsp response CAN be verified, not that it has been verified. */
+ const int ocsp_verify_err = OCSP_basic_verify(basic_response, cert_chain, validator->trust_store->trust_store, 0);
+ /* do the crypto checks on the response.*/
+ if (!ocsp_verify_err) {
+ ret_val = S2N_CERT_ERR_UNTRUSTED;
+ goto clean_up;
+ }
+
+ int status = 0;
+ int reason = 0;
+
+ /* sha1 is the only supported OCSP digest */
+ OCSP_CERTID *cert_id = OCSP_cert_to_id(EVP_sha1(), subject, issuer);
+
+ if (!cert_id) {
+ goto clean_up;
+ }
+
+ ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd;
+ /* Actual verification of the response */
+ const int ocsp_resp_find_status_res = OCSP_resp_find_status(basic_response, cert_id, &status, &reason, &revtime, &thisupd, &nextupd);
+ OCSP_CERTID_free(cert_id);
+
+ if (!ocsp_resp_find_status_res) {
+ ret_val = S2N_CERT_ERR_UNTRUSTED;
+ goto clean_up;
+ }
+
+ uint64_t this_update = 0;
+ s2n_result thisupd_result = s2n_asn1_time_to_nano_since_epoch_ticks((const char *) thisupd->data,
+ (uint32_t) thisupd->length, &this_update);
+
+ uint64_t next_update = 0;
+ s2n_result nextupd_result = S2N_RESULT_OK;
+ if (nextupd) {
+ nextupd_result = s2n_asn1_time_to_nano_since_epoch_ticks((const char *) nextupd->data,
+ (uint32_t) nextupd->length, &next_update);
+ } else {
+ next_update = this_update + DEFAULT_OCSP_NEXT_UPDATE_PERIOD;
+ }
+
+ uint64_t current_time = 0;
+ const int current_time_err = conn->config->wall_clock(conn->config->sys_clock_ctx, &current_time);
+
+ if (current_time_err) {
+ goto clean_up;
+ }
+
+ if (s2n_result_is_error(thisupd_result) || s2n_result_is_error(nextupd_result) || current_time_err) {
+ ret_val = S2N_CERT_ERR_UNTRUSTED;
+ goto clean_up;
+ }
+
+ if (current_time < this_update || current_time > next_update) {
+ ret_val = S2N_CERT_ERR_EXPIRED;
+ goto clean_up;
+ }
+
+ switch (status) {
+ case V_OCSP_CERTSTATUS_GOOD:
+ validator->state = OCSP_VALIDATED;
+ ret_val = S2N_CERT_OK;
+ break;
+ case V_OCSP_CERTSTATUS_REVOKED:
+ ret_val = S2N_CERT_ERR_REVOKED;
+ goto clean_up;
+ case V_OCSP_CERTSTATUS_UNKNOWN:
+ goto clean_up;
+ default:
+ goto clean_up;
+ }
+
+ clean_up:
+ if (basic_response) {
+ OCSP_BASICRESP_free(basic_response);
+ }
+
+ if (ocsp_response) {
+ OCSP_RESPONSE_free(ocsp_response);
+ }
+
+ if (cert_chain) {
+ wipe_cert_chain(cert_chain);
+ }
+
+ return ret_val;
+#endif /* S2N_OCSP_STAPLING_SUPPORTED */
+}
+
+S2N_RESULT s2n_validate_certificate_signature(struct s2n_connection *conn, X509 *x509_cert)
+{
+ ENSURE_REF(conn);
+ ENSURE_REF(x509_cert);
+
+ const struct s2n_security_policy *security_policy;
+ GUARD_AS_RESULT(s2n_connection_get_security_policy(conn, &security_policy));
+
+ if (security_policy->certificate_signature_preferences == NULL) {
+ return S2N_RESULT_OK;
+ }
+
+ X509_NAME *issuer_name = X509_get_issuer_name(x509_cert);
+ ENSURE_REF(issuer_name);
+
+ X509_NAME *subject_name = X509_get_subject_name(x509_cert);
+ ENSURE_REF(subject_name);
+
+ /* Do not validate any self-signed certificates */
+ if (X509_NAME_cmp(issuer_name, subject_name) == 0) {
+ return S2N_RESULT_OK;
+ }
+
+ GUARD_RESULT(s2n_validate_sig_scheme_supported(conn, x509_cert, security_policy->certificate_signature_preferences));
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_validate_sig_scheme_supported(struct s2n_connection *conn, X509 *x509_cert, const struct s2n_signature_preferences *cert_sig_preferences)
+{
+ ENSURE_REF(conn);
+ ENSURE_REF(x509_cert);
+ ENSURE_REF(cert_sig_preferences);
+
+ int nid = 0;
+
+ #if defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER < 0x02070000f)
+ ENSURE_REF(x509_cert->sig_alg);
+ nid = OBJ_obj2nid(x509_cert->sig_alg->algorithm);
+ #else
+ nid = X509_get_signature_nid(x509_cert);
+ #endif
+
+ for (size_t i = 0; i < cert_sig_preferences->count; i++) {
+
+ if (cert_sig_preferences->signature_schemes[i]->libcrypto_nid == nid) {
+ /* SHA-1 algorithms are not supported in certificate signatures in TLS1.3 */
+ ENSURE(!(conn->actual_protocol_version >= S2N_TLS13 &&
+ cert_sig_preferences->signature_schemes[i]->hash_alg == S2N_HASH_SHA1), S2N_ERR_CERT_UNTRUSTED);
+
+ return S2N_RESULT_OK;
+ }
+ }
+
+ BAIL(S2N_ERR_CERT_UNTRUSTED);
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_x509_validator.h b/contrib/restricted/aws/s2n/tls/s2n_x509_validator.h
index 5c51858979..9e57bb4d34 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_x509_validator.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_x509_validator.h
@@ -1,134 +1,134 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "api/s2n.h"
-
-#include "tls/s2n_signature_scheme.h"
-
-#include <openssl/x509v3.h>
-
-/* one day, BoringSSL/AWS-LC, may add ocsp stapling support. Let's future proof this a bit by grabbing a definition
- * that would have to be there when they add support */
-#if (defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)) && !defined(OCSP_RESPONSE_STATUS_SUCCESSFUL)
-#define S2N_OCSP_STAPLING_SUPPORTED 0
-#else
-#define S2N_OCSP_STAPLING_SUPPORTED 1
-#endif /* (defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)) && !defined(OCSP_RESPONSE_STATUS_SUCCESSFUL) */
-
-typedef enum {
- S2N_CERT_OK = 0,
- S2N_CERT_ERR_UNTRUSTED = -1,
- S2N_CERT_ERR_REVOKED = -2,
- S2N_CERT_ERR_EXPIRED = -3,
- S2N_CERT_ERR_TYPE_UNSUPPORTED = -4,
- S2N_CERT_ERR_INVALID = -5,
- S2N_CERT_ERR_MAX_CHAIN_DEPTH_EXCEEDED = -6
-} s2n_cert_validation_code;
-
-/** Return TRUE for trusted, FALSE for untrusted **/
-typedef uint8_t (*verify_host) (const char *host_name, size_t host_name_len, void *data);
-struct s2n_connection;
-
-/**
- * Trust store simply contains the trust store each connection should validate certs against.
- * For most use cases, you only need one of these per application.
- */
-struct s2n_x509_trust_store {
- X509_STORE *trust_store;
-};
-
-/**
- * You should have one instance of this per connection.
- */
-struct s2n_x509_validator {
- struct s2n_x509_trust_store *trust_store;
- X509_STORE_CTX *store_ctx;
- uint8_t skip_cert_validation;
- uint8_t check_stapled_ocsp;
- uint16_t max_chain_depth;
- STACK_OF(X509) *cert_chain_from_wire;
- int state;
-};
-
-/** Some libcrypto implementations do not support OCSP validation. Returns 1 if supported, 0 otherwise. */
-uint8_t s2n_x509_ocsp_stapling_supported(void);
-
-/** Initialize the trust store to empty defaults (no allocations happen here) */
-void s2n_x509_trust_store_init_empty(struct s2n_x509_trust_store *store);
-
-/** Returns TRUE if the trust store has certificates installed, FALSE otherwise */
-uint8_t s2n_x509_trust_store_has_certs(struct s2n_x509_trust_store *store);
-
-/** Initializes the trust store to default system paths **/
-int s2n_x509_trust_store_from_system_defaults(struct s2n_x509_trust_store *store);
-
-/** Initialize trust store from a PEM. This will allocate memory, and load PEM into the Trust Store **/
-int s2n_x509_trust_store_add_pem(struct s2n_x509_trust_store *store, const char *pem);
-
-/** Initialize trust store from a CA file. This will allocate memory, and load each cert in the file into the trust store
- * Returns 0 on success, or S2N error codes on failure. */
-int s2n_x509_trust_store_from_ca_file(struct s2n_x509_trust_store *store, const char *ca_pem_filename, const char *ca_dir);
-
-/** Cleans up, and frees any underlying memory in the trust store. */
-void s2n_x509_trust_store_wipe(struct s2n_x509_trust_store *store);
-
-/** Initialize the validator in unsafe mode. No validity checks for OCSP, host checks, or X.509 will be performed. */
-int s2n_x509_validator_init_no_x509_validation(struct s2n_x509_validator *validator);
-
-/** Initialize the validator in safe mode. Will use trust store to validate x.509 certificates, ocsp responses, and will call
- * the verify host callback to determine if a subject name or alternative name from the cert should be trusted.
- * Returns 0 on success, and an S2N_ERR_* on failure.
- */
-int s2n_x509_validator_init(struct s2n_x509_validator *validator, struct s2n_x509_trust_store *trust_store, uint8_t check_ocsp);
-
-/**
- * Sets the maximum depth for a cert chain that can be used at validation.
- */
-int s2n_x509_validator_set_max_chain_depth(struct s2n_x509_validator *validator, uint16_t max_depth);
-
-/** Cleans up underlying memory and data members. Struct can be reused afterwards. */
-void s2n_x509_validator_wipe(struct s2n_x509_validator *validator);
-
-/**
- * Validates a certificate chain against the configured trust store in safe mode. In unsafe mode, it will find the public key
- * and return it but not validate the certificates. Alternative Names and Subject Name will be passed to the host verification callback.
- * The verification callback will be possibly called multiple times depending on how many names are found.
- * If any of those calls return TRUE, that stage of the validation will continue, otherwise once all names are tried and none matched as
- * trusted, the chain will be considered UNTRUSTED.
- *
- * This function can only be called once per instance of an s2n_x509_validator. If must be called prior to calling
- * s2n_x509_validator_validate_cert_stapled_ocsp_response().
- */
-s2n_cert_validation_code s2n_x509_validator_validate_cert_chain(struct s2n_x509_validator *validator, struct s2n_connection *conn,
- uint8_t *cert_chain_in, uint32_t cert_chain_len, s2n_pkey_type *pkey_type,
- struct s2n_pkey *public_key_out);
-
-/**
- * Validates an ocsp response against the most recent certificate chain. Also verifies the timestamps on the response. This function can only be
- * called once per instance of an s2n_x509_validator and only after a successful call to s2n_x509_validator_validate_cert_chain().
- */
-s2n_cert_validation_code s2n_x509_validator_validate_cert_stapled_ocsp_response(struct s2n_x509_validator *validator, struct s2n_connection *conn,
- const uint8_t *ocsp_response, uint32_t size);
-
-/**
- * Validates that each certificate in a peer's cert chain contains only signature algorithms in a security policy's
- * certificate_signatures_preference list.
- */
-S2N_RESULT s2n_validate_certificate_signature(struct s2n_connection *conn, X509 *x509_cert);
-
-/* Checks to see if a certificate has a signature algorithm that's in our certificate_signature_preferences list */
-S2N_RESULT s2n_validate_sig_scheme_supported(struct s2n_connection *conn, X509 *x509_cert, const struct s2n_signature_preferences *cert_sig_preferences);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "api/s2n.h"
+
+#include "tls/s2n_signature_scheme.h"
+
+#include <openssl/x509v3.h>
+
+/* one day, BoringSSL/AWS-LC, may add ocsp stapling support. Let's future proof this a bit by grabbing a definition
+ * that would have to be there when they add support */
+#if (defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)) && !defined(OCSP_RESPONSE_STATUS_SUCCESSFUL)
+#define S2N_OCSP_STAPLING_SUPPORTED 0
+#else
+#define S2N_OCSP_STAPLING_SUPPORTED 1
+#endif /* (defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)) && !defined(OCSP_RESPONSE_STATUS_SUCCESSFUL) */
+
+typedef enum {
+ S2N_CERT_OK = 0,
+ S2N_CERT_ERR_UNTRUSTED = -1,
+ S2N_CERT_ERR_REVOKED = -2,
+ S2N_CERT_ERR_EXPIRED = -3,
+ S2N_CERT_ERR_TYPE_UNSUPPORTED = -4,
+ S2N_CERT_ERR_INVALID = -5,
+ S2N_CERT_ERR_MAX_CHAIN_DEPTH_EXCEEDED = -6
+} s2n_cert_validation_code;
+
+/** Return TRUE for trusted, FALSE for untrusted **/
+typedef uint8_t (*verify_host) (const char *host_name, size_t host_name_len, void *data);
+struct s2n_connection;
+
+/**
+ * Trust store simply contains the trust store each connection should validate certs against.
+ * For most use cases, you only need one of these per application.
+ */
+struct s2n_x509_trust_store {
+ X509_STORE *trust_store;
+};
+
+/**
+ * You should have one instance of this per connection.
+ */
+struct s2n_x509_validator {
+ struct s2n_x509_trust_store *trust_store;
+ X509_STORE_CTX *store_ctx;
+ uint8_t skip_cert_validation;
+ uint8_t check_stapled_ocsp;
+ uint16_t max_chain_depth;
+ STACK_OF(X509) *cert_chain_from_wire;
+ int state;
+};
+
+/** Some libcrypto implementations do not support OCSP validation. Returns 1 if supported, 0 otherwise. */
+uint8_t s2n_x509_ocsp_stapling_supported(void);
+
+/** Initialize the trust store to empty defaults (no allocations happen here) */
+void s2n_x509_trust_store_init_empty(struct s2n_x509_trust_store *store);
+
+/** Returns TRUE if the trust store has certificates installed, FALSE otherwise */
+uint8_t s2n_x509_trust_store_has_certs(struct s2n_x509_trust_store *store);
+
+/** Initializes the trust store to default system paths **/
+int s2n_x509_trust_store_from_system_defaults(struct s2n_x509_trust_store *store);
+
+/** Initialize trust store from a PEM. This will allocate memory, and load PEM into the Trust Store **/
+int s2n_x509_trust_store_add_pem(struct s2n_x509_trust_store *store, const char *pem);
+
+/** Initialize trust store from a CA file. This will allocate memory, and load each cert in the file into the trust store
+ * Returns 0 on success, or S2N error codes on failure. */
+int s2n_x509_trust_store_from_ca_file(struct s2n_x509_trust_store *store, const char *ca_pem_filename, const char *ca_dir);
+
+/** Cleans up, and frees any underlying memory in the trust store. */
+void s2n_x509_trust_store_wipe(struct s2n_x509_trust_store *store);
+
+/** Initialize the validator in unsafe mode. No validity checks for OCSP, host checks, or X.509 will be performed. */
+int s2n_x509_validator_init_no_x509_validation(struct s2n_x509_validator *validator);
+
+/** Initialize the validator in safe mode. Will use trust store to validate x.509 certificates, ocsp responses, and will call
+ * the verify host callback to determine if a subject name or alternative name from the cert should be trusted.
+ * Returns 0 on success, and an S2N_ERR_* on failure.
+ */
+int s2n_x509_validator_init(struct s2n_x509_validator *validator, struct s2n_x509_trust_store *trust_store, uint8_t check_ocsp);
+
+/**
+ * Sets the maximum depth for a cert chain that can be used at validation.
+ */
+int s2n_x509_validator_set_max_chain_depth(struct s2n_x509_validator *validator, uint16_t max_depth);
+
+/** Cleans up underlying memory and data members. Struct can be reused afterwards. */
+void s2n_x509_validator_wipe(struct s2n_x509_validator *validator);
+
+/**
+ * Validates a certificate chain against the configured trust store in safe mode. In unsafe mode, it will find the public key
+ * and return it but not validate the certificates. Alternative Names and Subject Name will be passed to the host verification callback.
+ * The verification callback will be possibly called multiple times depending on how many names are found.
+ * If any of those calls return TRUE, that stage of the validation will continue, otherwise once all names are tried and none matched as
+ * trusted, the chain will be considered UNTRUSTED.
+ *
+ * This function can only be called once per instance of an s2n_x509_validator. If must be called prior to calling
+ * s2n_x509_validator_validate_cert_stapled_ocsp_response().
+ */
+s2n_cert_validation_code s2n_x509_validator_validate_cert_chain(struct s2n_x509_validator *validator, struct s2n_connection *conn,
+ uint8_t *cert_chain_in, uint32_t cert_chain_len, s2n_pkey_type *pkey_type,
+ struct s2n_pkey *public_key_out);
+
+/**
+ * Validates an ocsp response against the most recent certificate chain. Also verifies the timestamps on the response. This function can only be
+ * called once per instance of an s2n_x509_validator and only after a successful call to s2n_x509_validator_validate_cert_chain().
+ */
+s2n_cert_validation_code s2n_x509_validator_validate_cert_stapled_ocsp_response(struct s2n_x509_validator *validator, struct s2n_connection *conn,
+ const uint8_t *ocsp_response, uint32_t size);
+
+/**
+ * Validates that each certificate in a peer's cert chain contains only signature algorithms in a security policy's
+ * certificate_signatures_preference list.
+ */
+S2N_RESULT s2n_validate_certificate_signature(struct s2n_connection *conn, X509 *x509_cert);
+
+/* Checks to see if a certificate has a signature algorithm that's in our certificate_signature_preferences list */
+S2N_RESULT s2n_validate_sig_scheme_supported(struct s2n_connection *conn, X509 *x509_cert, const struct s2n_signature_preferences *cert_sig_preferences);