aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted
diff options
context:
space:
mode:
authorrobot-contrib <robot-contrib@yandex-team.com>2022-09-14 08:47:09 +0300
committerrobot-contrib <robot-contrib@yandex-team.com>2022-09-14 08:47:09 +0300
commitb9de4b17d67a2320369697088b3528b0434f1843 (patch)
treefde557e95170880f4b3154ff66a1671c679d34e8 /contrib/restricted
parent1330c9bc362d84c753ba1c08ce51da6619ead01f (diff)
downloadydb-b9de4b17d67a2320369697088b3528b0434f1843.tar.gz
Update contrib/restricted/aws/s2n to 1.3.21
Diffstat (limited to 'contrib/restricted')
-rw-r--r--contrib/restricted/aws/s2n/CMakeLists.darwin.txt2
-rw-r--r--contrib/restricted/aws/s2n/CMakeLists.linux.txt2
-rw-r--r--contrib/restricted/aws/s2n/api/s2n.h55
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_aes_gcm.c12
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_chacha20_poly1305.c12
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_3des.c11
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_aes.c16
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_composite_cipher_aes_sha.c30
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_drbg.c1
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_ecdsa.c60
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_ecdsa.h11
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_libcrypto.c35
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_libcrypto.h2
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_rsa.c66
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_rsa.h13
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_rsa_pss.c33
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_rsa_signing.c13
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_rc4.c10
-rw-r--r--contrib/restricted/aws/s2n/error/s2n_errno.c1
-rw-r--r--contrib/restricted/aws/s2n/error/s2n_errno.h1
-rw-r--r--contrib/restricted/aws/s2n/stuffer/s2n_stuffer.c18
-rw-r--r--contrib/restricted/aws/s2n/stuffer/s2n_stuffer.h7
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_early_data_indication.c5
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.c7
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_ec_point_format.c4
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_auth_selection.c10
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_change_cipher_spec.c14
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.c16
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.h1
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c18
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_client_finished.c7
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_client_hello.c6
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.c25
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_connection.c185
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_connection.h12
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_connection_evp_digests.c44
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_connection_evp_digests.h34
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_crypto.c97
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_crypto.h4
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_early_data.c3
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_handshake.c5
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_handshake_io.c13
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_key_update.c12
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_prf.c73
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_psk.c3
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_record_read.c5
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_record_write.c5
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_recv.c5
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_resume.c20
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_security_policies.c24
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_send.c6
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_server_finished.c7
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_server_hello.c6
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_server_key_exchange.c29
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.c12
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_signature_scheme.c49
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_signature_scheme.h2
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.c22
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_tls13_key_schedule.c33
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_tls13_secrets.c16
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_init.c10
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_mem.c13
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_mem.h1
63 files changed, 838 insertions, 436 deletions
diff --git a/contrib/restricted/aws/s2n/CMakeLists.darwin.txt b/contrib/restricted/aws/s2n/CMakeLists.darwin.txt
index 01ab97e6c8..f634b97407 100644
--- a/contrib/restricted/aws/s2n/CMakeLists.darwin.txt
+++ b/contrib/restricted/aws/s2n/CMakeLists.darwin.txt
@@ -138,7 +138,7 @@ target_sources(restricted-aws-s2n PRIVATE
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_config.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_connection.c
- ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_connection_evp_digests.c
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_crypto.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_early_data.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_early_data_io.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_ecc_preferences.c
diff --git a/contrib/restricted/aws/s2n/CMakeLists.linux.txt b/contrib/restricted/aws/s2n/CMakeLists.linux.txt
index 2403724ef1..b1364fede1 100644
--- a/contrib/restricted/aws/s2n/CMakeLists.linux.txt
+++ b/contrib/restricted/aws/s2n/CMakeLists.linux.txt
@@ -139,7 +139,7 @@ target_sources(restricted-aws-s2n PRIVATE
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_config.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_connection.c
- ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_connection_evp_digests.c
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_crypto.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_early_data.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_early_data_io.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_ecc_preferences.c
diff --git a/contrib/restricted/aws/s2n/api/s2n.h b/contrib/restricted/aws/s2n/api/s2n.h
index c361dd09bb..bd1d83ba0c 100644
--- a/contrib/restricted/aws/s2n/api/s2n.h
+++ b/contrib/restricted/aws/s2n/api/s2n.h
@@ -1141,6 +1141,9 @@ extern int s2n_config_set_session_tickets_onoff(struct s2n_config *config, uint8
/**
* Enable or disable session caching.
+ *
+ * @note Session caching will not be turned on unless all three session cache callbacks are set
+ * prior to calling this function.
*
* @param config The configuration object being updated
* @param enabled The configuration object being updated. Set to 1 to enable. Set to 0 to disable.
@@ -1617,7 +1620,9 @@ S2N_API
extern int s2n_connection_set_send_cb(struct s2n_connection *conn, s2n_send_fn send);
/**
- * Change the behavior of s2n-tls when sending data to prefer high throughput. Connections preferring throughput will use
+ * Change the behavior of s2n-tls when sending data to prefer high throughput.
+ *
+ * Connections preferring throughput will use
* large record sizes that minimize overhead.
*
* @param conn The connection object being updated
@@ -1627,7 +1632,9 @@ S2N_API
extern int s2n_connection_prefer_throughput(struct s2n_connection *conn);
/**
- * Change the behavior of s2n-tls when sending data to prefer low latency. Connections preferring low latency will be encrypted
+ * Change the behavior of s2n-tls when sending data to prefer low latency.
+ *
+ * Connections preferring low latency will be encrypted
* using small record sizes that can be decrypted sooner by the recipient.
*
* @param conn The connection object being updated
@@ -1637,10 +1644,32 @@ S2N_API
extern int s2n_connection_prefer_low_latency(struct s2n_connection *conn);
/**
- * Provides a smooth transition from s2n_connection_prefer_low_latency() to s2n_connection_prefer_throughput().
+ * Configure the connection to free IO buffers when they are not currently in use.
+ *
+ * This configuration can be used to minimize connection memory footprint size, at the cost
+ * of more calls to alloc and free. Some of these costs can be mitigated by configuring s2n-tls
+ * to use an allocator that includes thread-local caches or lock-free allocation patterns.
+ *
+ * @param conn The connection object being update
+ * @param enabled Set to `true` if dynamic buffers are enabled; `false` if disabled
+ * @returns S2N_SUCCESS on success. S2N_FAILURE on failure
+ */
+S2N_API
+extern int s2n_connection_set_dynamic_buffers(struct s2n_connection *conn, bool enabled);
+
+/**
+ * Changes the behavior of s2n-tls when sending data to initially prefer records
+ * small enough to fit in single ethernet frames.
+ *
+ * When dynamic record sizing is active, the connection sends records small enough
+ * to fit in a single standard 1500 byte ethernet frame. Otherwise, the connection
+ * chooses record sizes according to the configured maximum fragment length.
+ *
+ * Dynamic record sizing is active for the first resize_threshold bytes of a connection,
+ * and is reactivated whenever timeout_threshold seconds pass without sending data.
*
* @param conn The connection object being updated
- * @param resize_threshold The number of bytes to send before changing the record size
+ * @param resize_threshold The number of bytes to send before changing the record size. Maximum 8MiB.
* @param timeout_threshold Reset record size back to a single segment after threshold seconds of inactivity
* @returns S2N_SUCCESS on success. S2N_FAILURE on failure
*/
@@ -1672,7 +1701,7 @@ extern int s2n_connection_set_verify_host_callback(struct s2n_connection *conn,
* Setting the S2N_SELF_SERVICE_BLINDING option with s2n_connection_set_blinding()
* turns off this behavior. This is useful for applications that are handling many connections
* in a single thread. In that case, if s2n_recv() or s2n_negotiate() return an error,
- * self-service applications should call *2n_connection_get_delay() and pause
+ * self-service applications should call s2n_connection_get_delay() and pause
* activity on the connection for the specified number of nanoseconds before calling
* close() or shutdown().
*/
@@ -2114,6 +2143,8 @@ struct s2n_session_ticket;
/**
* Callback function for receiving a session ticket.
*
+ * This function will be called each time a session ticket is received, which may be multiple times for TLS1.3.
+ *
* # Safety
*
* `ctx` is a void pointer and the caller is responsible for ensuring it is cast to the correct type.
@@ -2187,9 +2218,9 @@ extern int s2n_connection_set_session(struct s2n_connection *conn, const uint8_t
/**
* Serializes the session state from connection and copies into the `session` buffer and returns the number of copied bytes
*
- * The output of this function depends on whether session ids or session tickets are being used for resumption.
- *
- * @note This is for < TLS 1.3 session resumption.
+ * @note This function is not recommended for > TLS 1.2 because in TLS1.3
+ * servers can send multiple session tickets and this function will only
+ * return the most recently received ticket.
*
* @param conn A pointer to the s2n_connection object
* @param session A pointer to a buffer of size `max_length`
@@ -2201,7 +2232,11 @@ S2N_API
extern int s2n_connection_get_session(struct s2n_connection *conn, uint8_t *session, size_t max_length);
/**
- * Get the lifetime hint for a session.
+ * Retrieves a hint from the server indicating how long this ticket's lifetime is.
+ *
+ * @note This function is not recommended for > TLS 1.2 because in TLS1.3
+ * servers can send multiple session tickets and this function will only
+ * return the most recently received ticket lifetime hint.
*
* @param conn A pointer to the s2n_connection object
*
@@ -2962,7 +2997,7 @@ extern int s2n_config_set_async_pkey_callback(struct s2n_config *config, s2n_asy
*
* @param op An opaque object representing the private key operation
* @param key The private key used for the operation. It can be extracted from
- * `conn` through the `s2n_connection_get_selected_cert` and `s2n_cert_chain_and_key_get_key` calls
+ * `conn` through the `s2n_connection_get_selected_cert` and `s2n_cert_chain_and_key_get_private_key` calls
*/
S2N_API
extern int s2n_async_pkey_op_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *key);
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_aes_gcm.c b/contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_aes_gcm.c
index 172736ac1e..914a44ceae 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_aes_gcm.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_aes_gcm.c
@@ -62,6 +62,7 @@ static int s2n_aead_cipher_aes_gcm_encrypt(struct s2n_session_key *key, struct s
/* Adjust input length to account for the Tag length */
size_t in_len = in->size - S2N_TLS_GCM_TAG_LEN;
+ /* out_len is set by EVP_AEAD_CTX_seal and checked post operation */
size_t out_len = 0;
POSIX_GUARD_OSSL(EVP_AEAD_CTX_seal(key->evp_aead_ctx, out->data, &out_len, out->size, iv->data, iv->size, in->data, in_len, aad->data, aad->size), S2N_ERR_ENCRYPT);
@@ -83,6 +84,7 @@ static int s2n_aead_cipher_aes_gcm_decrypt(struct s2n_session_key *key, struct s
POSIX_ENSURE_GTE(out->size, in->size - S2N_TLS_GCM_TAG_LEN);
POSIX_ENSURE_EQ(iv->size, S2N_TLS_GCM_IV_LEN);
+ /* out_len is set by EVP_AEAD_CTX_open and checked post operation */
size_t out_len = 0;
POSIX_GUARD_OSSL(EVP_AEAD_CTX_open(key->evp_aead_ctx, out->data, &out_len, out->size, iv->data, iv->size, in->data, in->size, aad->data, aad->size), S2N_ERR_DECRYPT);
@@ -222,7 +224,8 @@ static int s2n_aead_cipher_aes_gcm_encrypt(struct s2n_session_key *key, struct s
int in_len = in->size - S2N_TLS_GCM_TAG_LEN;
uint8_t *tag_data = out->data + out->size - S2N_TLS_GCM_TAG_LEN;
- int out_len;
+ /* out_len is set by EVP_EncryptUpdate and checked post operation */
+ int out_len = 0;
/* Specify the AAD */
POSIX_GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, NULL, &out_len, aad->data, aad->size), S2N_ERR_ENCRYPT);
@@ -260,7 +263,10 @@ static int s2n_aead_cipher_aes_gcm_decrypt(struct s2n_session_key *key, struct s
/* Set the TAG */
POSIX_GUARD_OSSL(EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_SET_TAG, S2N_TLS_GCM_TAG_LEN, tag_data), S2N_ERR_DECRYPT);
- int out_len;
+ /* out_len is set by EVP_DecryptUpdate. While we verify the content of out_len in
+ * s2n_aead_chacha20_poly1305_encrypt, we refrain from this here. This is to avoid
+ * doing any branching before the ciphertext is verified. */
+ int out_len = 0;
/* Specify the AAD */
POSIX_GUARD_OSSL(EVP_DecryptUpdate(key->evp_cipher_ctx, NULL, &out_len, aad->data, aad->size), S2N_ERR_DECRYPT);
@@ -273,8 +279,6 @@ static int s2n_aead_cipher_aes_gcm_decrypt(struct s2n_session_key *key, struct s
S2N_ERROR_IF(evp_decrypt_rc != 1, S2N_ERR_DECRYPT);
- /* While we verify the content of out_len in s2n_aead_cipher_aes_gcm_encrypt, we refrain from this here. This is to avoid doing any branching before the ciphertext is verified. */
-
return S2N_SUCCESS;
}
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_chacha20_poly1305.c b/contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_chacha20_poly1305.c
index a4db7815f2..0768451c1b 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_chacha20_poly1305.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_chacha20_poly1305.c
@@ -61,7 +61,8 @@ static int s2n_aead_chacha20_poly1305_encrypt(struct s2n_session_key *key, struc
int in_len = in->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN;
uint8_t *tag_data = out->data + out->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN;
- int out_len;
+ /* out_len is set by EVP_EncryptUpdate and checked post operation */
+ int out_len = 0;
/* Specify the AAD */
POSIX_GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, NULL, &out_len, aad->data, aad->size), S2N_ERR_ENCRYPT);
@@ -99,7 +100,10 @@ static int s2n_aead_chacha20_poly1305_decrypt(struct s2n_session_key *key, struc
/* Set the TAG */
POSIX_GUARD_OSSL(EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_SET_TAG, S2N_TLS_CHACHA20_POLY1305_TAG_LEN, tag_data), S2N_ERR_DECRYPT);
- int out_len;
+ /* out_len is set by EVP_DecryptUpdate. While we verify the content of out_len in
+ * s2n_aead_chacha20_poly1305_encrypt, we refrain from this here. This is to avoid
+ * doing any branching before the ciphertext is verified. */
+ int out_len = 0;
/* Specify the AAD */
POSIX_GUARD_OSSL(EVP_DecryptUpdate(key->evp_cipher_ctx, NULL, &out_len, aad->data, aad->size), S2N_ERR_DECRYPT);
@@ -112,8 +116,6 @@ static int s2n_aead_chacha20_poly1305_decrypt(struct s2n_session_key *key, struc
S2N_ERROR_IF(evp_decrypt_rc != 1, S2N_ERR_DECRYPT);
- /* While we verify the content of out_len in s2n_aead_chacha20_poly1305_encrypt, we refrain from this here. This is to avoid doing any branching before the ciphertext is verified. */
-
return 0;
}
@@ -168,6 +170,7 @@ static int s2n_aead_chacha20_poly1305_encrypt(struct s2n_session_key *key, struc
/* Adjust input length to account for the Tag length */
size_t in_len = in->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN;
+ /* out_len is set by EVP_AEAD_CTX_seal and checked post operation */
size_t out_len = 0;
POSIX_GUARD_OSSL(EVP_AEAD_CTX_seal(key->evp_aead_ctx, out->data, &out_len, out->size, iv->data, iv->size, in->data, in_len, aad->data, aad->size), S2N_ERR_ENCRYPT);
@@ -183,6 +186,7 @@ static int s2n_aead_chacha20_poly1305_decrypt(struct s2n_session_key *key, struc
POSIX_ENSURE_GTE(out->size, in->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN);
POSIX_ENSURE_EQ(iv->size, S2N_TLS_CHACHA20_POLY1305_IV_LEN);
+ /* out_len is set by EVP_AEAD_CTX_open and checked post operation */
size_t out_len = 0;
POSIX_GUARD_OSSL(EVP_AEAD_CTX_open(key->evp_aead_ctx, out->data, &out_len, out->size, iv->data, iv->size, in->data, in->size, aad->data, aad->size), S2N_ERR_DECRYPT);
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_3des.c b/contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_3des.c
index 9a3e440653..2704a0deb3 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_3des.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_3des.c
@@ -34,7 +34,8 @@ static int s2n_cbc_cipher_3des_encrypt(struct s2n_session_key *key, struct s2n_b
POSIX_GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
- int len = out->size;
+ /* len is set by EVP_EncryptUpdate and checked post operation */
+ int len = 0;
POSIX_GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_ENCRYPT);
S2N_ERROR_IF(len != in->size, S2N_ERR_ENCRYPT);
@@ -47,7 +48,9 @@ static int s2n_cbc_cipher_3des_decrypt(struct s2n_session_key *key, struct s2n_b
POSIX_GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
- int len = out->size;
+ /* len is set by EVP_DecryptUpdate. It is not checked here but padding is manually removed and therefore
+ * the decryption operation is validated. */
+ int len = 0;
POSIX_GUARD_OSSL(EVP_DecryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_DECRYPT);
return 0;
@@ -57,7 +60,7 @@ static int s2n_cbc_cipher_3des_set_decryption_key(struct s2n_session_key *key, s
{
POSIX_ENSURE_EQ(in->size, 192 / 8);
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
POSIX_GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, EVP_des_ede3_cbc(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
return 0;
@@ -67,7 +70,7 @@ static int s2n_cbc_cipher_3des_set_encryption_key(struct s2n_session_key *key, s
{
POSIX_ENSURE_EQ(in->size, 192 / 8);
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
POSIX_GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_des_ede3_cbc(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
return 0;
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_aes.c b/contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_aes.c
index e737242ff0..d4a49940d6 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_aes.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_aes.c
@@ -39,7 +39,8 @@ static int s2n_cbc_cipher_aes_encrypt(struct s2n_session_key *key, struct s2n_bl
POSIX_GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
- int len = out->size;
+ /* len is set by EVP_EncryptUpdate and checked post operation */
+ int len = 0;
POSIX_GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_ENCRYPT);
S2N_ERROR_IF(len != in->size, S2N_ERR_ENCRYPT);
@@ -51,7 +52,10 @@ int s2n_cbc_cipher_aes_decrypt(struct s2n_session_key *key, struct s2n_blob *iv,
POSIX_ENSURE_GTE(out->size, in->size);
POSIX_GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
- int len = out->size;
+
+ /* len is set by EVP_DecryptUpdate. It is not checked here but padding is manually removed and therefore
+ * the decryption operation is validated. */
+ int len = 0;
POSIX_GUARD_OSSL(EVP_DecryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_DECRYPT);
return 0;
@@ -62,7 +66,7 @@ int s2n_cbc_cipher_aes128_set_decryption_key(struct s2n_session_key *key, struct
POSIX_ENSURE_EQ(in->size, 128 / 8);
/* Always returns 1 */
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
POSIX_GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, EVP_aes_128_cbc(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
return 0;
@@ -72,7 +76,7 @@ static int s2n_cbc_cipher_aes128_set_encryption_key(struct s2n_session_key *key,
{
POSIX_ENSURE_EQ(in->size, 128 / 8);
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
POSIX_GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_aes_128_cbc(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
return 0;
@@ -82,7 +86,7 @@ static int s2n_cbc_cipher_aes256_set_decryption_key(struct s2n_session_key *key,
{
POSIX_ENSURE_EQ(in->size, 256 / 8);
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
POSIX_GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, EVP_aes_256_cbc(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
return 0;
@@ -92,7 +96,7 @@ int s2n_cbc_cipher_aes256_set_encryption_key(struct s2n_session_key *key, struct
{
POSIX_ENSURE_EQ(in->size, 256 / 8);
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
POSIX_GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_aes_256_cbc(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
return 0;
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_composite_cipher_aes_sha.c b/contrib/restricted/aws/s2n/crypto/s2n_composite_cipher_aes_sha.c
index 353c841f87..7141f9ccf1 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_composite_cipher_aes_sha.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_composite_cipher_aes_sha.c
@@ -167,7 +167,12 @@ static int s2n_composite_cipher_aes_sha_encrypt(struct s2n_session_key *key, str
POSIX_ENSURE_EQ(out->size, in->size);
POSIX_GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
- POSIX_GUARD_OSSL(EVP_Cipher(key->evp_cipher_ctx, out->data, in->data, in->size), S2N_ERR_ENCRYPT);
+
+ /* len is set by EVP_EncryptUpdate and checked post operation */
+ int len = 0;
+ POSIX_GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_ENCRYPT);
+
+ S2N_ERROR_IF(len != in->size, S2N_ERR_ENCRYPT);
return 0;
}
@@ -175,9 +180,12 @@ static int s2n_composite_cipher_aes_sha_encrypt(struct s2n_session_key *key, str
static int s2n_composite_cipher_aes_sha_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *in, struct s2n_blob *out)
{
POSIX_ENSURE_EQ(out->size, in->size);
-
POSIX_GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
- POSIX_GUARD_OSSL(EVP_Cipher(key->evp_cipher_ctx, out->data, in->data, in->size), S2N_ERR_DECRYPT);
+
+ /* len is set by EVP_DecryptUpdate. It is not checked here but padding is manually removed and therefore
+ * the decryption operation is validated. */
+ int len = 0;
+ POSIX_GUARD_OSSL(EVP_DecryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_DECRYPT);
return 0;
}
@@ -205,7 +213,7 @@ static int s2n_composite_cipher_aes128_sha_set_encryption_key(struct s2n_session
{
POSIX_ENSURE_EQ(in->size, 16);
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
EVP_EncryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_128_cbc_hmac_sha1(), NULL, in->data, NULL);
return 0;
@@ -215,7 +223,7 @@ static int s2n_composite_cipher_aes128_sha_set_decryption_key(struct s2n_session
{
POSIX_ENSURE_EQ(in->size, 16);
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
EVP_DecryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_128_cbc_hmac_sha1(), NULL, in->data, NULL);
return 0;
@@ -225,7 +233,7 @@ static int s2n_composite_cipher_aes256_sha_set_encryption_key(struct s2n_session
{
POSIX_ENSURE_EQ(in->size, 32);
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
EVP_EncryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_256_cbc_hmac_sha1(), NULL, in->data, NULL);
return 0;
@@ -235,7 +243,7 @@ static int s2n_composite_cipher_aes256_sha_set_decryption_key(struct s2n_session
{
POSIX_ENSURE_EQ(in->size, 32);
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
EVP_DecryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_256_cbc_hmac_sha1(), NULL, in->data, NULL);
return 0;
@@ -245,7 +253,7 @@ static int s2n_composite_cipher_aes128_sha256_set_encryption_key(struct s2n_sess
{
POSIX_ENSURE_EQ(in->size, 16);
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
EVP_EncryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_128_cbc_hmac_sha256(), NULL, in->data, NULL);
return 0;
@@ -255,7 +263,7 @@ static int s2n_composite_cipher_aes128_sha256_set_decryption_key(struct s2n_sess
{
POSIX_ENSURE_EQ(in->size, 16);
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
EVP_DecryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_128_cbc_hmac_sha256(), NULL, in->data, NULL);
return 0;
@@ -265,7 +273,7 @@ static int s2n_composite_cipher_aes256_sha256_set_encryption_key(struct s2n_sess
{
POSIX_ENSURE_EQ(in->size, 32);
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
EVP_EncryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_256_cbc_hmac_sha256(), NULL, in->data, NULL);
return 0;
@@ -275,7 +283,7 @@ static int s2n_composite_cipher_aes256_sha256_set_decryption_key(struct s2n_sess
{
POSIX_ENSURE_EQ(in->size, 32);
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, 0);
EVP_DecryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_256_cbc_hmac_sha256(), NULL, in->data, NULL);
return 0;
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_drbg.c b/contrib/restricted/aws/s2n/crypto/s2n_drbg.c
index 242fd5ab9c..9f0acd5bf2 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_drbg.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_drbg.c
@@ -48,6 +48,7 @@ static S2N_RESULT s2n_drbg_block_encrypt(EVP_CIPHER_CTX *ctx, uint8_t in[S2N_DRB
{
RESULT_ENSURE_REF(ctx);
+ /* len is set by EVP_EncryptUpdate and checked post operation */
int len = S2N_DRBG_BLOCK_SIZE;
RESULT_GUARD_OSSL(EVP_EncryptUpdate(ctx, out, &len, in, S2N_DRBG_BLOCK_SIZE), S2N_ERR_DRBG);
RESULT_ENSURE_EQ(len, S2N_DRBG_BLOCK_SIZE);
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.c b/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.c
index 23050ffea4..d775e5b7b9 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.c
@@ -16,10 +16,13 @@
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/x509.h>
-#include "stuffer/s2n_stuffer.h"
#include "error/s2n_errno.h"
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_safety_macros.h"
#include "utils/s2n_blob.h"
+#include "utils/s2n_compiler.h"
#include "utils/s2n_mem.h"
#include "utils/s2n_random.h"
#include "utils/s2n_result.h"
@@ -32,8 +35,25 @@
#include "crypto/s2n_openssl.h"
#include "crypto/s2n_pkey.h"
+
#define S2N_ECDSA_TYPE 0
+EC_KEY *s2n_unsafe_ecdsa_get_non_const(const struct s2n_ecdsa_key *ecdsa_key) {
+ PTR_ENSURE_REF(ecdsa_key);
+
+ /* pragma gcc diagnostic was added in gcc 4.6 */
+#if defined(__clang__) || S2N_GCC_VERSION_AT_LEAST(4,6,0)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
+ EC_KEY *out_ec_key = (EC_KEY *) ecdsa_key->ec_key;
+#if defined(__clang__) || S2N_GCC_VERSION_AT_LEAST(4,6,0)
+#pragma GCC diagnostic pop
+#endif
+
+ return out_ec_key;
+}
+
S2N_RESULT s2n_ecdsa_der_signature_size(const struct s2n_pkey *pkey, uint32_t *size_out)
{
RESULT_ENSURE_REF(pkey);
@@ -59,7 +79,10 @@ int s2n_ecdsa_sign_digest(const struct s2n_pkey *priv, struct s2n_blob *digest,
POSIX_ENSURE_REF(key->ec_key);
unsigned int signature_size = signature->size;
- POSIX_GUARD_OSSL(ECDSA_sign(S2N_ECDSA_TYPE, digest->data, digest->size, signature->data, &signature_size, key->ec_key), S2N_ERR_SIGN);
+
+ /* Safety: ECDSA_sign does not mutate the key */
+ POSIX_GUARD_OSSL(ECDSA_sign(S2N_ECDSA_TYPE, digest->data, digest->size, signature->data, &signature_size,
+ s2n_unsafe_ecdsa_get_non_const(key)), S2N_ERR_SIGN);
POSIX_ENSURE(signature_size <= signature->size, S2N_ERR_SIZE_MISMATCH);
signature->size = signature_size;
@@ -84,7 +107,7 @@ static int s2n_ecdsa_sign(const struct s2n_pkey *priv, s2n_signature_algorithm s
POSIX_GUARD(s2n_ecdsa_sign_digest(priv, &digest_blob, signature));
POSIX_GUARD(s2n_hash_reset(digest));
-
+
return S2N_SUCCESS;
}
@@ -102,16 +125,18 @@ static int s2n_ecdsa_verify(const struct s2n_pkey *pub, s2n_signature_algorithm
uint8_t digest_out[S2N_MAX_DIGEST_LEN];
POSIX_GUARD(s2n_hash_digest(digest, digest_out, digest_length));
-
+
+ /* Safety: ECDSA_verify does not mutate the key */
/* ECDSA_verify ignores the first parameter */
- POSIX_GUARD_OSSL(ECDSA_verify(0, digest_out, digest_length, signature->data, signature->size, key->ec_key), S2N_ERR_VERIFY_SIGNATURE);
+ POSIX_GUARD_OSSL(ECDSA_verify(0, digest_out, digest_length, signature->data, signature->size,
+ s2n_unsafe_ecdsa_get_non_const(key)), S2N_ERR_VERIFY_SIGNATURE);
POSIX_GUARD(s2n_hash_reset(digest));
-
+
return 0;
}
-static int s2n_ecdsa_keys_match(const struct s2n_pkey *pub, const struct s2n_pkey *priv)
+static int s2n_ecdsa_keys_match(const struct s2n_pkey *pub, const struct s2n_pkey *priv)
{
uint8_t input[16] = { 1 };
DEFER_CLEANUP(struct s2n_blob signature = { 0 }, s2n_free);
@@ -139,15 +164,17 @@ static int s2n_ecdsa_keys_match(const struct s2n_pkey *pub, const struct s2n_pke
static int s2n_ecdsa_key_free(struct s2n_pkey *pkey)
{
+ POSIX_ENSURE_REF(pkey);
struct s2n_ecdsa_key *ecdsa_key = &pkey->key.ecdsa_key;
if (ecdsa_key->ec_key == NULL) {
- return 0;
+ return S2N_SUCCESS;
}
-
- EC_KEY_free(ecdsa_key->ec_key);
+
+ /* Safety: freeing the key owned by this object */
+ EC_KEY_free(s2n_unsafe_ecdsa_get_non_const(ecdsa_key));
ecdsa_key->ec_key = NULL;
- return 0;
+ return S2N_SUCCESS;
}
static int s2n_ecdsa_check_key_exists(const struct s2n_pkey *pkey)
@@ -159,18 +186,18 @@ static int s2n_ecdsa_check_key_exists(const struct s2n_pkey *pkey)
int s2n_evp_pkey_to_ecdsa_private_key(s2n_ecdsa_private_key *ecdsa_key, EVP_PKEY *evp_private_key)
{
- EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(evp_private_key);
+ const EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(evp_private_key);
S2N_ERROR_IF(ec_key == NULL, S2N_ERR_DECODE_PRIVATE_KEY);
-
+
ecdsa_key->ec_key = ec_key;
return 0;
}
int s2n_evp_pkey_to_ecdsa_public_key(s2n_ecdsa_public_key *ecdsa_key, EVP_PKEY *evp_public_key)
{
- EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(evp_public_key);
+ const EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(evp_public_key);
S2N_ERROR_IF(ec_key == NULL, S2N_ERR_DECODE_CERTIFICATE);
-
+
ecdsa_key->ec_key = ec_key;
return 0;
}
@@ -194,7 +221,8 @@ int s2n_ecdsa_pkey_matches_curve(const struct s2n_ecdsa_key *ecdsa_key, const st
POSIX_ENSURE_REF(ecdsa_key->ec_key);
POSIX_ENSURE_REF(curve);
- int curve_id = EC_GROUP_get_curve_name(EC_KEY_get0_group(ecdsa_key->ec_key));
+ const EC_KEY *key = ecdsa_key->ec_key;
+ int curve_id = EC_GROUP_get_curve_name(EC_KEY_get0_group(key));
POSIX_ENSURE_EQ(curve_id, curve->libcrypto_nid);
return 0;
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.h b/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.h
index e4ad664349..f6670a7b04 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.h
@@ -30,7 +30,16 @@
struct s2n_pkey;
struct s2n_ecdsa_key {
- EC_KEY *ec_key;
+ /*
+ * Starting in openssl_3, `EVP_PKEY_get1_EC_KEY` and `EVP_PKEY_get0_EC_KEY`
+ * functions return a pre-cached copy of the underlying key. This means that any
+ * mutations are not reflected back onto the underlying key.
+ *
+ * The `const` identifier is present to help ensure that the key is not mutated.
+ * Usecases which require a non-const EC_KEY (some openssl functions), should
+ * use `s2n_unsafe_ecdsa_get_non_const` while ensuring that the usage is safe.
+ */
+ const EC_KEY *ec_key;
};
typedef struct s2n_ecdsa_key s2n_ecdsa_public_key;
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.c b/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.c
index f9ee9d135c..bf85f2773f 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.c
@@ -22,6 +22,10 @@
#include <openssl/crypto.h>
#include <openssl/opensslv.h>
+#if S2N_OPENSSL_VERSION_AT_LEAST(3, 0, 0)
+#error #include <openssl/provider.h>
+#endif
+
#include <string.h>
/* Note: OpenSSL 1.0.2 -> 1.1.0 implemented a new API to get the version number
@@ -134,6 +138,37 @@ bool s2n_libcrypto_is_boringssl()
#endif
}
+S2N_RESULT s2n_libcrypto_init(void)
+{
+#if S2N_OPENSSL_VERSION_AT_LEAST(3, 0, 0)
+ RESULT_ENSURE(OSSL_PROVIDER_load(NULL, "default") != NULL, S2N_ERR_OSSL_PROVIDER);
+ #ifdef S2N_LIBCRYPTO_SUPPORTS_EVP_RC4
+ /* needed to support RC4 algorithm
+ * https://www.openssl.org/docs/man3.0/man7/OSSL_PROVIDER-legacy.html
+ */
+ RESULT_ENSURE(OSSL_PROVIDER_load(NULL, "legacy") != NULL, S2N_ERR_OSSL_PROVIDER);
+ #endif
+#endif
+
+ return S2N_RESULT_OK;
+}
+
+#if S2N_OPENSSL_VERSION_AT_LEAST(3, 0, 0)
+int s2n_libcrypto_cleanup_cb(OSSL_PROVIDER *provider, void *cbdata) {
+ return OSSL_PROVIDER_unload(provider);
+}
+
+S2N_RESULT s2n_libcrypto_cleanup(void) {
+ RESULT_GUARD_OSSL(OSSL_PROVIDER_do_all(NULL, *s2n_libcrypto_cleanup_cb, NULL), S2N_ERR_ATEXIT);
+
+ return S2N_RESULT_OK;
+}
+#else
+S2N_RESULT s2n_libcrypto_cleanup(void) {
+ return S2N_RESULT_OK;
+}
+#endif
+
/* Performs various checks to validate that the libcrypto used at compile-time
* is the same libcrypto being used at run-time.
*/
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.h b/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.h
index 34d9ef2aac..c3b933562f 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.h
@@ -17,4 +17,6 @@
#include "utils/s2n_result.h"
+S2N_RESULT s2n_libcrypto_init(void);
S2N_RESULT s2n_libcrypto_validate_runtime(void);
+S2N_RESULT s2n_libcrypto_cleanup(void);
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_rsa.c b/contrib/restricted/aws/s2n/crypto/s2n_rsa.c
index 164496f93f..27d2f7c32c 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_rsa.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_rsa.c
@@ -13,25 +13,43 @@
* permissions and limitations under the License.
*/
-#include "crypto/s2n_rsa.h"
-
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <stdint.h>
+#include "error/s2n_errno.h"
+#include "stuffer/s2n_stuffer.h"
+
#include "crypto/s2n_drbg.h"
+#include "crypto/s2n_evp_signing.h"
#include "crypto/s2n_hash.h"
#include "crypto/s2n_pkey.h"
-#include "crypto/s2n_evp_signing.h"
+#include "crypto/s2n_rsa.h"
#include "crypto/s2n_rsa_signing.h"
-#include "error/s2n_errno.h"
-#include "stuffer/s2n_stuffer.h"
+
#include "utils/s2n_blob.h"
+#include "utils/s2n_compiler.h"
#include "utils/s2n_random.h"
#include "utils/s2n_result.h"
#include "utils/s2n_safety.h"
-static S2N_RESULT s2n_rsa_modulus_check(RSA *rsa)
+RSA *s2n_unsafe_rsa_get_non_const(const struct s2n_rsa_key *rsa_key) {
+ PTR_ENSURE_REF(rsa_key);
+
+ /* pragma gcc diagnostic was added in gcc 4.6 */
+#if defined(__clang__) || S2N_GCC_VERSION_AT_LEAST(4,6,0)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
+ RSA *out_rsa_key = (RSA *) rsa_key->rsa;
+#if defined(__clang__) || S2N_GCC_VERSION_AT_LEAST(4,6,0)
+#pragma GCC diagnostic pop
+#endif
+
+ return out_rsa_key;
+}
+
+static S2N_RESULT s2n_rsa_modulus_check(const RSA *rsa)
{
/* RSA was made opaque starting in Openssl 1.1.0 */
#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) && !defined(LIBRESSL_VERSION_NUMBER)
@@ -45,13 +63,14 @@ static S2N_RESULT s2n_rsa_modulus_check(RSA *rsa)
return S2N_RESULT_OK;
}
-static S2N_RESULT s2n_rsa_encrypted_size(const struct s2n_pkey *key, uint32_t *size_out)
+static S2N_RESULT s2n_rsa_encrypted_size(const struct s2n_pkey *pkey, uint32_t *size_out)
{
- RESULT_ENSURE_REF(key);
+ RESULT_ENSURE_REF(pkey);
RESULT_ENSURE_REF(size_out);
- const struct s2n_rsa_key *rsa_key = &key->key.rsa_key;
+ const struct s2n_rsa_key *rsa_key = &pkey->key.rsa_key;
RESULT_ENSURE_REF(rsa_key->rsa);
+
RESULT_GUARD(s2n_rsa_modulus_check(rsa_key->rsa));
const int size = RSA_size(rsa_key->rsa);
@@ -97,9 +116,11 @@ static int s2n_rsa_encrypt(const struct s2n_pkey *pub, struct s2n_blob *in, stru
POSIX_GUARD_RESULT(s2n_rsa_encrypted_size(pub, &size));
S2N_ERROR_IF(out->size < size, S2N_ERR_NOMEM);
- const s2n_rsa_public_key *key = &pub->key.rsa_key;
- int r = RSA_public_encrypt(in->size, ( unsigned char * )in->data, ( unsigned char * )out->data, key->rsa,
- RSA_PKCS1_PADDING);
+ const s2n_rsa_public_key *pub_key = &pub->key.rsa_key;
+
+ /* Safety: RSA_public_encrypt does not mutate the key */
+ int r = RSA_public_encrypt(in->size, ( unsigned char * )in->data, ( unsigned char * )out->data,
+ s2n_unsafe_rsa_get_non_const(pub_key), RSA_PKCS1_PADDING);
S2N_ERROR_IF(r != out->size, S2N_ERR_SIZE_MISMATCH);
return 0;
@@ -117,8 +138,11 @@ static int s2n_rsa_decrypt(const struct s2n_pkey *priv, struct s2n_blob *in, str
POSIX_GUARD_RESULT(s2n_get_public_random_data(out));
- const s2n_rsa_private_key *key = &priv->key.rsa_key;
- int r = RSA_private_decrypt(in->size, ( unsigned char * )in->data, intermediate, key->rsa, RSA_NO_PADDING);
+ const s2n_rsa_private_key *priv_key = &priv->key.rsa_key;
+
+ /* Safety: RSA_private_decrypt does not mutate the key */
+ int r = RSA_private_decrypt(in->size, ( unsigned char * )in->data, intermediate,
+ s2n_unsafe_rsa_get_non_const(priv_key), RSA_NO_PADDING);
S2N_ERROR_IF(r != expected_size, S2N_ERR_SIZE_MISMATCH);
s2n_constant_time_pkcs1_unpad_or_dont(out->data, intermediate, r, out->size);
@@ -150,13 +174,17 @@ static int s2n_rsa_keys_match(const struct s2n_pkey *pub, const struct s2n_pkey
static int s2n_rsa_key_free(struct s2n_pkey *pkey)
{
+ POSIX_ENSURE_REF(pkey);
struct s2n_rsa_key *rsa_key = &pkey->key.rsa_key;
- if (rsa_key->rsa == NULL) { return 0; }
+ if (rsa_key->rsa == NULL) {
+ return S2N_SUCCESS;
+ }
- RSA_free(rsa_key->rsa);
+ /* Safety: freeing the key owned by this object */
+ RSA_free(s2n_unsafe_rsa_get_non_const(rsa_key));
rsa_key->rsa = NULL;
- return 0;
+ return S2N_SUCCESS;
}
static int s2n_rsa_check_key_exists(const struct s2n_pkey *pkey)
@@ -168,7 +196,7 @@ static int s2n_rsa_check_key_exists(const struct s2n_pkey *pkey)
int s2n_evp_pkey_to_rsa_public_key(s2n_rsa_public_key *rsa_key, EVP_PKEY *evp_public_key)
{
- RSA *rsa = EVP_PKEY_get1_RSA(evp_public_key);
+ const RSA *rsa = EVP_PKEY_get1_RSA(evp_public_key);
S2N_ERROR_IF(rsa == NULL, S2N_ERR_DECODE_CERTIFICATE);
rsa_key->rsa = rsa;
@@ -177,7 +205,7 @@ int s2n_evp_pkey_to_rsa_public_key(s2n_rsa_public_key *rsa_key, EVP_PKEY *evp_pu
int s2n_evp_pkey_to_rsa_private_key(s2n_rsa_private_key *rsa_key, EVP_PKEY *evp_private_key)
{
- RSA *rsa = EVP_PKEY_get1_RSA(evp_private_key);
+ const RSA *rsa = EVP_PKEY_get1_RSA(evp_private_key);
S2N_ERROR_IF(rsa == NULL, S2N_ERR_DECODE_PRIVATE_KEY);
rsa_key->rsa = rsa;
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_rsa.h b/contrib/restricted/aws/s2n/crypto/s2n_rsa.h
index 3bba4ff863..52724530a1 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_rsa.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_rsa.h
@@ -28,9 +28,20 @@
struct s2n_pkey;
struct s2n_rsa_key {
- RSA *rsa;
+ /*
+ * Starting in openssl_3, `EVP_PKEY_get1_RSA` and `EVP_PKEY_get0_RSA` functions
+ * return a pre-cached copy of the underlying key. This means that any mutations
+ * are not reflected back onto the underlying key.
+ *
+ * The `const` identifier is present to help ensure that the key is not mutated.
+ * Usecases which require a non-const RSA key (some openssl functions), should
+ * use `s2n_unsafe_rsa_get_non_const` while ensuring that the usage is safe.
+ */
+ const RSA *rsa;
};
+RSA *s2n_unsafe_rsa_get_non_const(const struct s2n_rsa_key *rsa_key);
+
typedef struct s2n_rsa_key s2n_rsa_public_key;
typedef struct s2n_rsa_key s2n_rsa_private_key;
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_rsa_pss.c b/contrib/restricted/aws/s2n/crypto/s2n_rsa_pss.c
index da034d6ad3..70be214cf6 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_rsa_pss.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_rsa_pss.c
@@ -18,7 +18,6 @@
#include <stdint.h>
#include "error/s2n_errno.h"
-
#include "stuffer/s2n_stuffer.h"
#include "crypto/s2n_evp_signing.h"
@@ -55,7 +54,7 @@ static S2N_RESULT s2n_rsa_pss_size(const struct s2n_pkey *key, uint32_t *size_ou
return S2N_RESULT_OK;
}
-static int s2n_rsa_is_private_key(RSA *rsa_key)
+static int s2n_rsa_is_private_key(const RSA *rsa_key)
{
const BIGNUM *d = NULL;
RSA_get0_key(rsa_key, NULL, NULL, &d);
@@ -73,7 +72,8 @@ int s2n_rsa_pss_key_sign(const struct s2n_pkey *priv, s2n_signature_algorithm si
sig_alg_check(sig_alg, S2N_SIGNATURE_RSA_PSS_PSS);
/* Not Possible to Sign with Public Key */
- S2N_ERROR_IF(!s2n_rsa_is_private_key(priv->key.rsa_key.rsa), S2N_ERR_KEY_MISMATCH);
+ const RSA *key = priv->key.rsa_key.rsa;
+ POSIX_ENSURE(s2n_rsa_is_private_key(key), S2N_ERR_KEY_MISMATCH);
return s2n_rsa_pss_sign(priv, digest, signature_out);
}
@@ -85,7 +85,8 @@ int s2n_rsa_pss_key_verify(const struct s2n_pkey *pub, s2n_signature_algorithm s
sig_alg_check(sig_alg, S2N_SIGNATURE_RSA_PSS_PSS);
/* Using Private Key to Verify means the public/private keys were likely swapped, and likely indicates a bug. */
- S2N_ERROR_IF(s2n_rsa_is_private_key(pub->key.rsa_key.rsa), S2N_ERR_KEY_MISMATCH);
+ const RSA *key = pub->key.rsa_key.rsa;
+ POSIX_ENSURE(!s2n_rsa_is_private_key(key), S2N_ERR_KEY_MISMATCH);
return s2n_rsa_pss_verify(pub, digest, signature_in);
}
@@ -144,11 +145,11 @@ static int s2n_rsa_validate_params_match(const struct s2n_pkey *pub, const struc
POSIX_ENSURE_REF(priv);
/* OpenSSL Documentation Links:
- * - https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_get0_RSA.html
+ * - https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_get1_RSA.html
* - https://www.openssl.org/docs/manmaster/man3/RSA_get0_key.html
*/
- RSA *pub_rsa_key = pub->key.rsa_key.rsa;
- RSA *priv_rsa_key = priv->key.rsa_key.rsa;
+ const RSA *pub_rsa_key = pub->key.rsa_key.rsa;
+ const RSA *priv_rsa_key = priv->key.rsa_key.rsa;
POSIX_ENSURE_REF(pub_rsa_key);
POSIX_ENSURE_REF(priv_rsa_key);
@@ -176,14 +177,22 @@ static int s2n_rsa_pss_keys_match(const struct s2n_pkey *pub, const struct s2n_p
static int s2n_rsa_pss_key_free(struct s2n_pkey *pkey)
{
- /* This object does not own the reference to the key --
- * s2n_pkey handles it. */
+ POSIX_ENSURE_REF(pkey);
+ struct s2n_rsa_key *rsa_key = &pkey->key.rsa_key;
+ if (rsa_key->rsa == NULL) {
+ return S2N_SUCCESS;
+ }
- return 0;
+ /* Safety: freeing the key owned by this object */
+ RSA_free(s2n_unsafe_rsa_get_non_const(rsa_key));
+ rsa_key->rsa = NULL;
+
+ return S2N_SUCCESS;
}
int s2n_evp_pkey_to_rsa_pss_public_key(struct s2n_rsa_key *rsa_key, EVP_PKEY *pkey) {
- RSA *pub_rsa_key = EVP_PKEY_get0_RSA(pkey);
+ const RSA *pub_rsa_key = EVP_PKEY_get1_RSA(pkey);
+ POSIX_ENSURE_REF(pub_rsa_key);
S2N_ERROR_IF(s2n_rsa_is_private_key(pub_rsa_key), S2N_ERR_KEY_MISMATCH);
@@ -193,7 +202,7 @@ int s2n_evp_pkey_to_rsa_pss_public_key(struct s2n_rsa_key *rsa_key, EVP_PKEY *pk
int s2n_evp_pkey_to_rsa_pss_private_key(struct s2n_rsa_key *rsa_key, EVP_PKEY *pkey)
{
- RSA *priv_rsa_key = EVP_PKEY_get0_RSA(pkey);
+ const RSA *priv_rsa_key = EVP_PKEY_get1_RSA(pkey);
POSIX_ENSURE_REF(priv_rsa_key);
/* Documentation: https://www.openssl.org/docs/man1.1.1/man3/RSA_check_key.html */
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_rsa_signing.c b/contrib/restricted/aws/s2n/crypto/s2n_rsa_signing.c
index 57a31172b7..fc74fa24d3 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_rsa_signing.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_rsa_signing.c
@@ -64,10 +64,13 @@ int s2n_rsa_pkcs1v15_sign_digest(const struct s2n_pkey *priv, s2n_hash_algorithm
int NID_type = 0;
POSIX_GUARD(s2n_hash_NID_type(hash_alg, &NID_type));
- const s2n_rsa_private_key *key = &priv->key.rsa_key;
+ const s2n_rsa_private_key *rsa_key = &priv->key.rsa_key;
unsigned int signature_size = signature->size;
- POSIX_GUARD_OSSL(RSA_sign(NID_type, digest->data, digest->size, signature->data, &signature_size, key->rsa), S2N_ERR_SIGN);
+
+ /* Safety: RSA_sign does not mutate the key */
+ POSIX_GUARD_OSSL(RSA_sign(NID_type, digest->data, digest->size, signature->data, &signature_size,
+ s2n_unsafe_rsa_get_non_const(rsa_key)), S2N_ERR_SIGN);
POSIX_ENSURE(signature_size <= signature->size, S2N_ERR_SIZE_MISMATCH);
signature->size = signature_size;
@@ -100,12 +103,14 @@ int s2n_rsa_pkcs1v15_verify(const struct s2n_pkey *pub, struct s2n_hash_state *d
POSIX_GUARD(s2n_hash_NID_type(digest->alg, &digest_NID_type));
POSIX_ENSURE_LTE(digest_length, S2N_MAX_DIGEST_LEN);
- const s2n_rsa_public_key *key = &pub->key.rsa_key;
+ const s2n_rsa_public_key *rsa_key = &pub->key.rsa_key;
uint8_t digest_out[S2N_MAX_DIGEST_LEN];
POSIX_GUARD(s2n_hash_digest(digest, digest_out, digest_length));
- POSIX_GUARD_OSSL(RSA_verify(digest_NID_type, digest_out, digest_length, signature->data, signature->size, key->rsa), S2N_ERR_VERIFY_SIGNATURE);
+ /* Safety: RSA_verify does not mutate the key */
+ POSIX_GUARD_OSSL(RSA_verify(digest_NID_type, digest_out, digest_length, signature->data, signature->size,
+ s2n_unsafe_rsa_get_non_const(rsa_key)), S2N_ERR_VERIFY_SIGNATURE);
return 0;
}
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_rc4.c b/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_rc4.c
index f5b2695da5..e5eab24391 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_rc4.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_rc4.c
@@ -40,7 +40,8 @@ static int s2n_stream_cipher_rc4_encrypt(struct s2n_session_key *key, struct s2n
{
POSIX_ENSURE_GTE(out->size, in->size);
- int len = out->size;
+ /* len is set by EVP_EncryptUpdate and checked post operation */
+ int len = 0;
POSIX_GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_ENCRYPT);
S2N_ERROR_IF(len != in->size, S2N_ERR_ENCRYPT);
@@ -52,10 +53,11 @@ static int s2n_stream_cipher_rc4_decrypt(struct s2n_session_key *key, struct s2n
{
POSIX_ENSURE_GTE(out->size, in->size);
- int len = out->size;
- POSIX_GUARD_OSSL(EVP_DecryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_ENCRYPT);
+ /* len is set by EVP_DecryptUpdate and checked post operation */
+ int len = 0;
+ POSIX_GUARD_OSSL(EVP_DecryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_DECRYPT);
- S2N_ERROR_IF(len != in->size, S2N_ERR_ENCRYPT);
+ S2N_ERROR_IF(len != in->size, S2N_ERR_DECRYPT);
return 0;
}
diff --git a/contrib/restricted/aws/s2n/error/s2n_errno.c b/contrib/restricted/aws/s2n/error/s2n_errno.c
index f2848af900..15b20d51bd 100644
--- a/contrib/restricted/aws/s2n/error/s2n_errno.c
+++ b/contrib/restricted/aws/s2n/error/s2n_errno.c
@@ -274,6 +274,7 @@ static const char *no_such_error = "Internal s2n error";
ERR_ENTRY(S2N_ERR_SECRET_SCHEDULE_STATE, "Correct inputs to secret calculation not available") \
ERR_ENTRY(S2N_ERR_LIBCRYPTO_VERSION_NUMBER_MISMATCH, "The libcrypto major version number seen at compile-time is different from the major version number seen at run-time") \
ERR_ENTRY(S2N_ERR_LIBCRYPTO_VERSION_NAME_MISMATCH, "The libcrypto major version name seen at compile-time is different from the major version name seen at run-time") \
+ ERR_ENTRY(S2N_ERR_OSSL_PROVIDER, "Failed to load or unload an openssl provider") \
ERR_ENTRY(S2N_ERR_CERT_OWNERSHIP, "The ownership of the certificate chain is incompatible with the operation") \
ERR_ENTRY(S2N_ERR_INTERNAL_LIBCRYPTO_ERROR, "An internal error has occurred in the libcrypto API")
/* clang-format on */
diff --git a/contrib/restricted/aws/s2n/error/s2n_errno.h b/contrib/restricted/aws/s2n/error/s2n_errno.h
index f0901c768b..473daa4fd4 100644
--- a/contrib/restricted/aws/s2n/error/s2n_errno.h
+++ b/contrib/restricted/aws/s2n/error/s2n_errno.h
@@ -215,6 +215,7 @@ typedef enum {
S2N_ERR_RETRIEVE_FORK_GENERATION_NUMBER,
S2N_ERR_LIBCRYPTO_VERSION_NUMBER_MISMATCH,
S2N_ERR_LIBCRYPTO_VERSION_NAME_MISMATCH,
+ S2N_ERR_OSSL_PROVIDER,
S2N_ERR_T_INTERNAL_END,
/* S2N_ERR_T_USAGE */
diff --git a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer.c b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer.c
index a2b1024732..d1727d7fa9 100644
--- a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer.c
+++ b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer.c
@@ -105,12 +105,20 @@ int s2n_stuffer_growable_alloc(struct s2n_stuffer *stuffer, const uint32_t size)
int s2n_stuffer_free(struct s2n_stuffer *stuffer)
{
POSIX_PRECONDITION(s2n_stuffer_validate(stuffer));
- if (stuffer != NULL) {
- if (stuffer->alloced) {
- POSIX_GUARD(s2n_free(&stuffer->blob));
- }
- *stuffer = (struct s2n_stuffer) {0};
+ if (stuffer->alloced) {
+ POSIX_GUARD(s2n_free(&stuffer->blob));
}
+ *stuffer = (struct s2n_stuffer) {0};
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_free_without_wipe(struct s2n_stuffer *stuffer)
+{
+ POSIX_PRECONDITION(s2n_stuffer_validate(stuffer));
+ if (stuffer->alloced) {
+ POSIX_GUARD(s2n_free_without_wipe(&stuffer->blob));
+ }
+ *stuffer = (struct s2n_stuffer) {0};
return S2N_SUCCESS;
}
diff --git a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer.h b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer.h
index 99233e2cde..91de251eaf 100644
--- a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer.h
+++ b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer.h
@@ -68,6 +68,13 @@ extern int s2n_stuffer_init(struct s2n_stuffer *stuffer, struct s2n_blob *in);
extern int s2n_stuffer_alloc(struct s2n_stuffer *stuffer, const uint32_t size);
extern int s2n_stuffer_growable_alloc(struct s2n_stuffer *stuffer, const uint32_t size);
extern int s2n_stuffer_free(struct s2n_stuffer *stuffer);
+/**
+ * Frees the stuffer without zeroizing the contained data.
+ *
+ * This should only be used in scenarios where the data is encrypted or has been
+ * cleared with `s2n_stuffer_erase_and_read`. In most cases, prefer `s2n_stuffer_free`.
+ */
+extern int s2n_stuffer_free_without_wipe(struct s2n_stuffer *stuffer);
extern int s2n_stuffer_resize(struct s2n_stuffer *stuffer, const uint32_t size);
extern int s2n_stuffer_resize_if_empty(struct s2n_stuffer *stuffer, const uint32_t size);
extern int s2n_stuffer_rewind_read(struct s2n_stuffer *stuffer, const uint32_t size);
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_early_data_indication.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_early_data_indication.c
index 3cfea591cd..63de6d52f5 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_early_data_indication.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_early_data_indication.c
@@ -145,6 +145,9 @@ static int s2n_client_early_data_indication_is_missing(struct s2n_connection *co
static int s2n_client_early_data_indication_send(struct s2n_connection *conn, struct s2n_stuffer *out)
{
+ POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
+
POSIX_GUARD_RESULT(s2n_setup_middlebox_compat_for_early_data(conn));
POSIX_GUARD_RESULT(s2n_connection_set_early_data_state(conn, S2N_EARLY_DATA_REQUESTED));
@@ -152,7 +155,7 @@ static int s2n_client_early_data_indication_send(struct s2n_connection *conn, st
struct s2n_psk *first_psk = NULL;
POSIX_GUARD_RESULT(s2n_array_get(&conn->psk_params.psk_list, 0, (void**) &first_psk));
POSIX_ENSURE_REF(first_psk);
- conn->secure.cipher_suite = first_psk->early_data_config.cipher_suite;
+ conn->secure->cipher_suite = first_psk->early_data_config.cipher_suite;
return S2N_SUCCESS;
}
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 f8278f36b4..6abb8bf568 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.c
@@ -66,7 +66,7 @@ int s2n_client_psk_is_missing(struct s2n_connection *conn)
bool s2n_client_psk_should_send(struct s2n_connection *conn)
{
- if (conn == NULL) {
+ if (!conn || !conn->secure) {
return false;
}
@@ -84,7 +84,7 @@ bool s2n_client_psk_should_send(struct s2n_connection *conn)
struct s2n_psk *psk = NULL;
if (s2n_result_is_ok(s2n_array_get(&conn->psk_params.psk_list, i, (void**) &psk))
&& psk != NULL
- && conn->secure.cipher_suite->prf_alg == psk->hmac_alg) {
+ && conn->secure->cipher_suite->prf_alg == psk->hmac_alg) {
return true;
}
}
@@ -134,6 +134,7 @@ static S2N_RESULT s2n_generate_obfuscated_ticket_age(struct s2n_psk *psk, uint64
static int s2n_client_psk_send(struct s2n_connection *conn, struct s2n_stuffer *out)
{
POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
struct s2n_psk_parameters *psk_params = &conn->psk_params;
struct s2n_array *psk_list = &psk_params->psk_list;
@@ -154,7 +155,7 @@ static int s2n_client_psk_send(struct s2n_connection *conn, struct s2n_stuffer *
*# any pre-shared keys associated with a hash other than that of the
*# selected cipher suite.
*/
- if (s2n_is_hello_retry_handshake(conn) && conn->secure.cipher_suite->prf_alg != psk->hmac_alg) {
+ if (s2n_is_hello_retry_handshake(conn) && conn->secure->cipher_suite->prf_alg != psk->hmac_alg) {
continue;
}
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 00d0a240f9..20a3acfa9a 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
@@ -47,8 +47,8 @@ const s2n_extension_type s2n_server_ec_point_format_extension = {
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);
+ return conn && conn->secure && 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)
diff --git a/contrib/restricted/aws/s2n/tls/s2n_auth_selection.c b/contrib/restricted/aws/s2n/tls/s2n_auth_selection.c
index eb132cc642..7d9656d4d4 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_auth_selection.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_auth_selection.c
@@ -175,9 +175,10 @@ int s2n_is_cipher_suite_valid_for_auth(struct s2n_connection *conn, struct s2n_c
int s2n_is_sig_scheme_valid_for_auth(struct s2n_connection *conn, const struct s2n_signature_scheme *sig_scheme)
{
POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
POSIX_ENSURE_REF(sig_scheme);
- struct s2n_cipher_suite *cipher_suite = conn->secure.cipher_suite;
+ struct s2n_cipher_suite *cipher_suite = conn->secure->cipher_suite;
POSIX_ENSURE_REF(cipher_suite);
POSIX_GUARD(s2n_certs_exist_for_sig_scheme(conn, sig_scheme));
@@ -201,13 +202,14 @@ int s2n_is_sig_scheme_valid_for_auth(struct s2n_connection *conn, const struct s
int s2n_is_cert_type_valid_for_auth(struct s2n_connection *conn, s2n_pkey_type cert_type)
{
POSIX_ENSURE_REF(conn);
- POSIX_ENSURE_REF(conn->secure.cipher_suite);
+ POSIX_ENSURE_REF(conn->secure);
+ POSIX_ENSURE_REF(conn->secure->cipher_suite);
s2n_authentication_method auth_method;
POSIX_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);
+ 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;
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 99dfdfb22a..dbdb9dfb78 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_change_cipher_spec.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_change_cipher_spec.c
@@ -40,17 +40,20 @@ int s2n_basic_ccs_recv(struct s2n_connection *conn)
int s2n_client_ccs_recv(struct s2n_connection *conn)
{
+ POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
+
POSIX_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) };
+ struct s2n_blob seq = {.data = conn->secure->client_sequence_number,.size = sizeof(conn->secure->client_sequence_number) };
POSIX_GUARD(s2n_blob_zero(&seq));
/* Compute the finished message */
POSIX_GUARD(s2n_prf_client_finished(conn));
/* Update the client to use the cipher-suite */
- conn->client = &conn->secure;
+ 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
@@ -62,17 +65,20 @@ int s2n_client_ccs_recv(struct s2n_connection *conn)
int s2n_server_ccs_recv(struct s2n_connection *conn)
{
+ POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
+
POSIX_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) };
+ struct s2n_blob seq = {.data = conn->secure->server_sequence_number,.size = sizeof(conn->secure->server_sequence_number) };
POSIX_GUARD(s2n_blob_zero(&seq));
/* Compute the finished message */
POSIX_GUARD(s2n_prf_server_finished(conn));
/* Update the secure state to active, and point the client at the active state */
- conn->server = &conn->secure;
+ 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
diff --git a/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.c b/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.c
index 8d4aee52b2..3690338fd3 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.c
@@ -1768,4 +1768,20 @@ const struct s2n_cipher_preferences cipher_preferences_20210816_gcm = {
.suites = cipher_suites_20210816_gcm,
};
+struct s2n_cipher_suite *cipher_suites_rfc9151[] = {
+ /* TLS1.2 */
+ &s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
+ &s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
+ &s2n_rsa_with_aes_256_gcm_sha384,
+ &s2n_dhe_rsa_with_aes_256_gcm_sha384,
+
+ /* TLS1.3 */
+ &s2n_tls13_aes_256_gcm_sha384,
+};
+
+const struct s2n_cipher_preferences cipher_preferences_rfc9151 = {
+ .count = s2n_array_len(cipher_suites_rfc9151),
+ .suites = cipher_suites_rfc9151,
+};
+
/* 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 c7305a3908..455c8a71f2 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_cipher_preferences.h
@@ -46,6 +46,7 @@ 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_rfc9151;
extern const struct s2n_cipher_preferences cipher_preferences_20210816;
extern const struct s2n_cipher_preferences cipher_preferences_20210816_gcm;
extern const struct s2n_cipher_preferences cipher_preferences_20210825;
diff --git a/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c b/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c
index 99398da903..7e0256524a 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c
@@ -1086,7 +1086,8 @@ S2N_RESULT s2n_cipher_suite_from_iana(const uint8_t iana[static S2N_TLS_CIPHER_S
int s2n_set_cipher_as_client(struct s2n_connection *conn, uint8_t wire[S2N_TLS_CIPHER_SUITE_LEN])
{
POSIX_ENSURE_REF(conn);
- POSIX_ENSURE_REF(conn->secure.cipher_suite);
+ POSIX_ENSURE_REF(conn->secure);
+ POSIX_ENSURE_REF(conn->secure->cipher_suite);
const struct s2n_security_policy *security_policy;
POSIX_GUARD(s2n_connection_get_security_policy(conn, &security_policy));
@@ -1139,16 +1140,16 @@ int s2n_set_cipher_as_client(struct s2n_connection *conn, uint8_t wire[S2N_TLS_C
*# otherwise abort the handshake with an "illegal_parameter" alert.
**/
if (s2n_is_hello_retry_handshake(conn) && !s2n_is_hello_retry_message(conn)) {
- POSIX_ENSURE(conn->secure.cipher_suite->iana_value == cipher_suite->iana_value, S2N_ERR_CIPHER_NOT_SUPPORTED);
+ POSIX_ENSURE(conn->secure->cipher_suite->iana_value == cipher_suite->iana_value, S2N_ERR_CIPHER_NOT_SUPPORTED);
return S2N_SUCCESS;
}
- conn->secure.cipher_suite = cipher_suite;
+ conn->secure->cipher_suite = cipher_suite;
/* For SSLv3 use SSLv3-specific ciphers */
if (conn->actual_protocol_version == S2N_SSLv3) {
- conn->secure.cipher_suite = conn->secure.cipher_suite->sslv3_cipher_suite;
- POSIX_ENSURE_REF(conn->secure.cipher_suite);
+ conn->secure->cipher_suite = conn->secure->cipher_suite->sslv3_cipher_suite;
+ POSIX_ENSURE_REF(conn->secure->cipher_suite);
}
return 0;
@@ -1169,6 +1170,9 @@ static int s2n_wire_ciphers_contain(const uint8_t *match, const uint8_t *wire, u
static int s2n_set_cipher_as_server(struct s2n_connection *conn, uint8_t *wire, uint32_t count, uint32_t cipher_suite_len)
{
+ POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
+
uint8_t renegotiation_info_scsv[S2N_TLS_CIPHER_SUITE_LEN] = { TLS_EMPTY_RENEGOTIATION_INFO_SCSV };
struct s2n_cipher_suite *higher_vers_match = NULL;
@@ -1254,14 +1258,14 @@ static int s2n_set_cipher_as_server(struct s2n_connection *conn, uint8_t *wire,
continue;
}
- conn->secure.cipher_suite = match;
+ 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;
+ conn->secure->cipher_suite = higher_vers_match;
return S2N_SUCCESS;
}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_client_finished.c b/contrib/restricted/aws/s2n/tls/s2n_client_finished.c
index 871e7db15f..5a17228754 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_client_finished.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_client_finished.c
@@ -39,15 +39,18 @@ int s2n_client_finished_recv(struct s2n_connection *conn)
int s2n_client_finished_send(struct s2n_connection *conn)
{
+ POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
+
uint8_t *our_version;
POSIX_GUARD(s2n_prf_client_finished(conn));
- struct s2n_blob seq = {.data = conn->secure.client_sequence_number,.size = sizeof(conn->secure.client_sequence_number) };
+ struct s2n_blob seq = {.data = conn->secure->client_sequence_number,.size = sizeof(conn->secure->client_sequence_number) };
POSIX_GUARD(s2n_blob_zero(&seq));
our_version = conn->handshake.client_finished;
/* Update the server to use the cipher suite */
- conn->client = &conn->secure;
+ conn->client = conn->secure;
if (conn->actual_protocol_version == S2N_SSLv3) {
POSIX_GUARD(s2n_stuffer_write_bytes(&conn->handshake.io, our_version, S2N_SSL_FINISHED_LEN));
diff --git a/contrib/restricted/aws/s2n/tls/s2n_client_hello.c b/contrib/restricted/aws/s2n/tls/s2n_client_hello.c
index 32506f495d..d382cb1ab8 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_client_hello.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_client_hello.c
@@ -392,6 +392,8 @@ int s2n_parse_client_hello(struct s2n_connection *conn)
int s2n_process_client_hello(struct s2n_connection *conn)
{
POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
+ POSIX_ENSURE_REF(conn->secure->cipher_suite);
/* Client hello is parsed and config is finalized.
* Negotiate protocol version, cipher suite, ALPN, select a cert, etc. */
@@ -431,7 +433,7 @@ int s2n_process_client_hello(struct s2n_connection *conn)
/* Save the previous cipher suite */
uint8_t previous_cipher_suite_iana[S2N_TLS_CIPHER_SUITE_LEN] = { 0 };
- POSIX_CHECKED_MEMCPY(previous_cipher_suite_iana, conn->secure.cipher_suite->iana_value, S2N_TLS_CIPHER_SUITE_LEN);
+ POSIX_CHECKED_MEMCPY(previous_cipher_suite_iana, conn->secure->cipher_suite->iana_value, S2N_TLS_CIPHER_SUITE_LEN);
/* Now choose the ciphers we have certs for. */
POSIX_GUARD(s2n_set_cipher_as_tls_server(conn, client_hello->cipher_suites.data, client_hello->cipher_suites.size / 2));
@@ -447,7 +449,7 @@ int s2n_process_client_hello(struct s2n_connection *conn)
*# the server selects the cipher suite as the first step in the
*# negotiation, then this will happen automatically).
**/
- POSIX_ENSURE(s2n_constant_time_equals(previous_cipher_suite_iana, conn->secure.cipher_suite->iana_value,
+ POSIX_ENSURE(s2n_constant_time_equals(previous_cipher_suite_iana, conn->secure->cipher_suite->iana_value,
S2N_TLS_CIPHER_SUITE_LEN),S2N_ERR_BAD_MESSAGE);
}
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 7b669e1ba6..37f4964f91 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.c
@@ -46,11 +46,14 @@ static int s2n_rsa_client_key_recv_complete(struct s2n_connection *conn, bool rs
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)
{
+ POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
POSIX_ENSURE_REF(kex_method);
POSIX_ENSURE_REF(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];
+ 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->kex_params.client_key_exchange_message;
@@ -81,8 +84,12 @@ static int s2n_hybrid_client_action(struct s2n_connection *conn, struct s2n_blob
static int s2n_calculate_keys(struct s2n_connection *conn, struct s2n_blob *shared_key)
{
+ POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
+ POSIX_ENSURE_REF(conn->secure->cipher_suite);
+
/* Turn the pre-master secret into a master secret */
- POSIX_GUARD_RESULT(s2n_kex_tls_prf(conn->secure.cipher_suite->key_exchange_alg, conn, shared_key));
+ POSIX_GUARD_RESULT(s2n_kex_tls_prf(conn->secure->cipher_suite->key_exchange_alg, conn, shared_key));
/* Expand the keys */
POSIX_GUARD(s2n_prf_key_expansion(conn));
@@ -214,7 +221,11 @@ int s2n_hybrid_client_key_recv(struct s2n_connection *conn, struct s2n_blob *com
int s2n_client_key_recv(struct s2n_connection *conn)
{
- const struct s2n_kex *key_exchange = conn->secure.cipher_suite->key_exchange_alg;
+ POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
+ POSIX_ENSURE_REF(conn->secure->cipher_suite);
+
+ const struct s2n_kex *key_exchange = conn->secure->cipher_suite->key_exchange_alg;
DEFER_CLEANUP(struct s2n_blob shared_key = { 0 }, s2n_blob_zeroize_free);
POSIX_GUARD_RESULT(s2n_kex_client_key_recv(key_exchange, conn, &shared_key));
@@ -309,7 +320,11 @@ int s2n_hybrid_client_key_send(struct s2n_connection *conn, struct s2n_blob *com
int s2n_client_key_send(struct s2n_connection *conn)
{
- const struct s2n_kex *key_exchange = conn->secure.cipher_suite->key_exchange_alg;
+ POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
+ POSIX_ENSURE_REF(conn->secure->cipher_suite);
+
+ const struct s2n_kex *key_exchange = conn->secure->cipher_suite->key_exchange_alg;
DEFER_CLEANUP(struct s2n_blob shared_key = { 0 }, s2n_blob_zeroize_free);
POSIX_GUARD_RESULT(s2n_kex_client_key_send(key_exchange, conn, &shared_key));
diff --git a/contrib/restricted/aws/s2n/tls/s2n_connection.c b/contrib/restricted/aws/s2n/tls/s2n_connection.c
index 92b51cdb25..6901a8b95d 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_connection.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_connection.c
@@ -32,7 +32,6 @@
#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_internal.h"
@@ -59,28 +58,6 @@
#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_hmacs(struct s2n_connection *conn)
-{
- /* Allocate long-term memory for the Connection's HMAC states */
- POSIX_GUARD(s2n_hmac_new(&conn->initial.client_record_mac));
- POSIX_GUARD(s2n_hmac_new(&conn->initial.server_record_mac));
- POSIX_GUARD(s2n_hmac_new(&conn->secure.client_record_mac));
- POSIX_GUARD(s2n_hmac_new(&conn->secure.server_record_mac));
-
- return 0;
-}
-
-static int s2n_connection_init_hmacs(struct s2n_connection *conn)
-{
- /* Initialize all of the Connection's HMAC states */
- POSIX_GUARD(s2n_hmac_init(&conn->initial.client_record_mac, S2N_HMAC_NONE, NULL, 0));
- POSIX_GUARD(s2n_hmac_init(&conn->initial.server_record_mac, S2N_HMAC_NONE, NULL, 0));
- POSIX_GUARD(s2n_hmac_init(&conn->secure.client_record_mac, S2N_HMAC_NONE, NULL, 0));
- POSIX_GUARD(s2n_hmac_init(&conn->secure.server_record_mac, S2N_HMAC_NONE, NULL, 0));
-
- return 0;
-}
-
/* Allocates and initializes memory for a new connection.
*
* Since customers can reuse a connection, ensure that values on the connection are
@@ -118,19 +95,10 @@ struct s2n_connection *s2n_connection_new(s2n_mode mode)
PTR_GUARD_POSIX(s2n_blob_init(&blob, conn->ticket_ext_data, S2N_TLS12_TICKET_SIZE_IN_BYTES));
PTR_GUARD_POSIX(s2n_stuffer_init(&conn->client_ticket_to_decrypt, &blob));
- /* Allocate long term key memory */
- PTR_GUARD_POSIX(s2n_session_key_alloc(&conn->secure.client_key));
- PTR_GUARD_POSIX(s2n_session_key_alloc(&conn->secure.server_key));
- PTR_GUARD_POSIX(s2n_session_key_alloc(&conn->initial.client_key));
- PTR_GUARD_POSIX(s2n_session_key_alloc(&conn->initial.server_key));
-
/* Allocate long term hash and HMAC memory */
PTR_GUARD_RESULT(s2n_prf_new(conn));
PTR_GUARD_RESULT(s2n_handshake_hashes_new(&conn->handshake.hashes));
- PTR_GUARD_POSIX(s2n_connection_new_hmacs(conn));
- PTR_GUARD_POSIX(s2n_connection_init_hmacs(conn));
-
/* Initialize the growable stuffers. Zero length at first, but the resize
* in _wipe will fix that
*/
@@ -152,26 +120,12 @@ struct s2n_connection *s2n_connection_new(s2n_mode mode)
return conn;
}
-static int s2n_connection_free_keys(struct s2n_connection *conn)
-{
- POSIX_GUARD(s2n_session_key_free(&conn->secure.client_key));
- POSIX_GUARD(s2n_session_key_free(&conn->secure.server_key));
- POSIX_GUARD(s2n_session_key_free(&conn->initial.client_key));
- POSIX_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 */
POSIX_CHECKED_MEMSET(conn, 0, sizeof(struct s2n_connection));
conn->mode = mode;
- conn->initial.cipher_suite = &s2n_null_cipher_suite;
- conn->secure.cipher_suite = &s2n_null_cipher_suite;
- conn->server = &conn->initial;
- conn->client = &conn->initial;
conn->max_outgoing_fragment_length = S2N_DEFAULT_FRAGMENT_LENGTH;
conn->handshake.end_of_messages = APPLICATION_DATA;
s2n_connection_set_config(conn, config);
@@ -194,16 +148,6 @@ S2N_RESULT s2n_connection_wipe_all_keyshares(struct s2n_connection *conn)
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) {
- POSIX_GUARD(conn->secure.cipher_suite->record_alg->cipher->destroy_key(&conn->secure.client_key));
- POSIX_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) */
POSIX_GUARD(s2n_pkey_free(&conn->handshake_params.server_public_key));
@@ -220,17 +164,6 @@ static int s2n_connection_wipe_keys(struct s2n_connection *conn)
return 0;
}
-static int s2n_connection_reset_hmacs(struct s2n_connection *conn)
-{
- /* Reset all of the Connection's HMAC states */
- POSIX_GUARD(s2n_hmac_reset(&conn->initial.client_record_mac));
- POSIX_GUARD(s2n_hmac_reset(&conn->initial.server_record_mac));
- POSIX_GUARD(s2n_hmac_reset(&conn->secure.client_record_mac));
- POSIX_GUARD(s2n_hmac_reset(&conn->secure.server_record_mac));
-
- return 0;
-}
-
static int s2n_connection_free_managed_recv_io(struct s2n_connection *conn)
{
POSIX_ENSURE_REF(conn);
@@ -277,17 +210,6 @@ static int s2n_connection_wipe_io(struct s2n_connection *conn)
return 0;
}
-static int s2n_connection_free_hmacs(struct s2n_connection *conn)
-{
- /* Free all of the Connection's HMAC states */
- POSIX_GUARD(s2n_hmac_free(&conn->initial.client_record_mac));
- POSIX_GUARD(s2n_hmac_free(&conn->initial.server_record_mac));
- POSIX_GUARD(s2n_hmac_free(&conn->secure.client_record_mac));
- POSIX_GUARD(s2n_hmac_free(&conn->secure.server_record_mac));
-
- 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
@@ -333,15 +255,11 @@ S2N_CLEANUP_RESULT s2n_connection_ptr_free(struct s2n_connection **conn)
int s2n_connection_free(struct s2n_connection *conn)
{
POSIX_GUARD(s2n_connection_wipe_keys(conn));
- POSIX_GUARD(s2n_connection_free_keys(conn));
POSIX_GUARD_RESULT(s2n_psk_parameters_wipe(&conn->psk_params));
POSIX_GUARD_RESULT(s2n_prf_free(conn));
POSIX_GUARD_RESULT(s2n_handshake_hashes_free(&conn->handshake.hashes));
- POSIX_GUARD(s2n_connection_reset_hmacs(conn));
- POSIX_GUARD(s2n_connection_free_hmacs(conn));
-
POSIX_GUARD(s2n_connection_free_managed_io(conn));
POSIX_GUARD(s2n_free(&conn->client_ticket));
@@ -357,6 +275,8 @@ int s2n_connection_free(struct s2n_connection *conn)
POSIX_GUARD(s2n_client_hello_free(&conn->client_hello));
POSIX_GUARD(s2n_free(&conn->application_protocols_overridden));
POSIX_GUARD(s2n_free(&conn->cookie));
+ POSIX_GUARD_RESULT(s2n_crypto_parameters_free(&conn->initial));
+ POSIX_GUARD_RESULT(s2n_crypto_parameters_free(&conn->secure));
POSIX_GUARD(s2n_free_object((uint8_t **)&conn, sizeof(struct s2n_connection)));
return 0;
@@ -488,6 +408,14 @@ int s2n_connection_free_handshake(struct s2n_connection *conn)
POSIX_GUARD_RESULT(s2n_handshake_hashes_free(&conn->handshake.hashes));
POSIX_GUARD_RESULT(s2n_prf_free(conn));
+ /* All IO should use conn->secure after the handshake.
+ * However, if this method is called before the handshake completes,
+ * the connection may still be using conn->initial.
+ */
+ if (conn->client != conn->initial && conn->server != conn->initial) {
+ POSIX_GUARD_RESULT(s2n_crypto_parameters_free(&conn->initial));
+ }
+
/* Wipe the buffers we are going to free */
POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io));
POSIX_GUARD(s2n_blob_zero(&conn->client_hello.raw_message));
@@ -525,13 +453,6 @@ int s2n_connection_wipe(struct s2n_connection *conn)
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 hmac states will be wiped. Preserve structs to avoid reallocation */
- struct s2n_connection_hmac_handles hmac_handles = {0};
/* Some required structures might have been freed to conserve memory between handshakes.
* Restore them.
@@ -546,10 +467,21 @@ int s2n_connection_wipe(struct s2n_connection *conn)
}
POSIX_GUARD_RESULT(s2n_prf_wipe(conn));
struct s2n_prf_working_space *prf_workspace = conn->prf_space;
+ if (!conn->initial) {
+ POSIX_GUARD_RESULT(s2n_crypto_parameters_new(&conn->initial));
+ } else {
+ POSIX_GUARD_RESULT(s2n_crypto_parameters_wipe(conn->initial));
+ }
+ struct s2n_crypto_parameters *initial = conn->initial;
+ if (!conn->secure) {
+ POSIX_GUARD_RESULT(s2n_crypto_parameters_new(&conn->secure));
+ } else {
+ POSIX_GUARD_RESULT(s2n_crypto_parameters_wipe(conn->secure));
+ }
+ struct s2n_crypto_parameters *secure = conn->secure;
/* Wipe all of the sensitive stuff */
POSIX_GUARD(s2n_connection_wipe_keys(conn));
- POSIX_GUARD(s2n_connection_reset_hmacs(conn));
POSIX_GUARD(s2n_stuffer_wipe(&conn->alert_in));
POSIX_GUARD(s2n_stuffer_wipe(&conn->reader_alert_out));
POSIX_GUARD(s2n_stuffer_wipe(&conn->writer_alert_out));
@@ -603,11 +535,6 @@ int s2n_connection_wipe(struct s2n_connection *conn)
POSIX_CHECKED_MEMCPY(&header_in, &conn->header_in, sizeof(struct s2n_stuffer));
POSIX_CHECKED_MEMCPY(&in, &conn->in, sizeof(struct s2n_stuffer));
POSIX_CHECKED_MEMCPY(&out, &conn->out, sizeof(struct s2n_stuffer));
- POSIX_CHECKED_MEMCPY(&initial_client_key, &conn->initial.client_key, sizeof(struct s2n_session_key));
- POSIX_CHECKED_MEMCPY(&initial_server_key, &conn->initial.server_key, sizeof(struct s2n_session_key));
- POSIX_CHECKED_MEMCPY(&secure_client_key, &conn->secure.client_key, sizeof(struct s2n_session_key));
- POSIX_CHECKED_MEMCPY(&secure_server_key, &conn->secure.server_key, sizeof(struct s2n_session_key));
- POSIX_GUARD(s2n_connection_save_hmac_state(&hmac_handles, conn));
#if S2N_GCC_VERSION_AT_LEAST(4,6,0)
#pragma GCC diagnostic pop
#endif
@@ -622,16 +549,13 @@ int s2n_connection_wipe(struct s2n_connection *conn)
POSIX_CHECKED_MEMCPY(&conn->header_in, &header_in, sizeof(struct s2n_stuffer));
POSIX_CHECKED_MEMCPY(&conn->in, &in, sizeof(struct s2n_stuffer));
POSIX_CHECKED_MEMCPY(&conn->out, &out, sizeof(struct s2n_stuffer));
- POSIX_CHECKED_MEMCPY(&conn->initial.client_key, &initial_client_key, sizeof(struct s2n_session_key));
- POSIX_CHECKED_MEMCPY(&conn->initial.server_key, &initial_server_key, sizeof(struct s2n_session_key));
- POSIX_CHECKED_MEMCPY(&conn->secure.client_key, &secure_client_key, sizeof(struct s2n_session_key));
- POSIX_CHECKED_MEMCPY(&conn->secure.server_key, &secure_server_key, sizeof(struct s2n_session_key));
- POSIX_GUARD(s2n_connection_restore_hmac_state(conn, &hmac_handles));
+
conn->handshake.hashes = handshake_hashes;
conn->prf_space = prf_workspace;
-
- /* Re-initialize hash and hmac states */
- POSIX_GUARD(s2n_connection_init_hmacs(conn));
+ conn->initial = initial;
+ conn->secure = secure;
+ conn->client = conn->initial;
+ conn->server = conn->initial;
POSIX_GUARD_RESULT(s2n_psk_parameters_init(&conn->psk_params));
conn->server_keying_material_lifetime = ONE_WEEK_IN_SEC;
@@ -942,29 +866,31 @@ uint64_t s2n_connection_get_wire_bytes_out(struct s2n_connection *conn)
const char *s2n_connection_get_cipher(struct s2n_connection *conn)
{
PTR_ENSURE_REF(conn);
- PTR_ENSURE_REF(conn->secure.cipher_suite);
+ PTR_ENSURE_REF(conn->secure);
+ PTR_ENSURE_REF(conn->secure->cipher_suite);
- return conn->secure.cipher_suite->name;
+ return conn->secure->cipher_suite->name;
}
int s2n_connection_get_cipher_iana_value(struct s2n_connection *conn, uint8_t *first, uint8_t *second)
{
POSIX_ENSURE_REF(conn);
- POSIX_ENSURE_REF(conn->secure.cipher_suite);
+ POSIX_ENSURE_REF(conn->secure);
+ POSIX_ENSURE_REF(conn->secure->cipher_suite);
POSIX_ENSURE_MUT(first);
POSIX_ENSURE_MUT(second);
/* ensure we've negotiated a cipher suite */
POSIX_ENSURE(
memcmp(
- conn->secure.cipher_suite->iana_value,
+ conn->secure->cipher_suite->iana_value,
s2n_null_cipher_suite.iana_value,
sizeof(s2n_null_cipher_suite.iana_value)
) != 0,
S2N_ERR_INVALID_STATE
);
- const uint8_t *iana_value = conn->secure.cipher_suite->iana_value;
+ const uint8_t *iana_value = conn->secure->cipher_suite->iana_value;
*first = iana_value[0];
*second = iana_value[1];
@@ -974,10 +900,12 @@ int s2n_connection_get_cipher_iana_value(struct s2n_connection *conn, uint8_t *f
const char *s2n_connection_get_curve(struct s2n_connection *conn)
{
PTR_ENSURE_REF(conn);
+ PTR_ENSURE_REF(conn->secure);
+ PTR_ENSURE_REF(conn->secure->cipher_suite);
if (conn->kex_params.server_ecc_evp_params.negotiated_curve) {
/* TLS1.3 currently only uses ECC groups. */
- if (conn->actual_protocol_version >= S2N_TLS13 || s2n_kex_includes(conn->secure.cipher_suite->key_exchange_alg, &s2n_ecdhe)) {
+ if (conn->actual_protocol_version >= S2N_TLS13 || s2n_kex_includes(conn->secure->cipher_suite->key_exchange_alg, &s2n_ecdhe)) {
return conn->kex_params.server_ecc_evp_params.negotiated_curve->name;
}
}
@@ -1280,6 +1208,13 @@ int s2n_connection_prefer_low_latency(struct s2n_connection *conn)
return S2N_SUCCESS;
}
+int s2n_connection_set_dynamic_buffers(struct s2n_connection *conn, bool enabled)
+{
+ POSIX_ENSURE_REF(conn);
+ conn->dynamic_buffers = enabled;
+ return S2N_SUCCESS;
+}
+
int s2n_connection_set_dynamic_record_threshold(struct s2n_connection *conn, uint32_t resize_threshold, uint16_t timeout_threshold)
{
POSIX_ENSURE_REF(conn);
@@ -1554,3 +1489,35 @@ int s2n_connection_get_config(struct s2n_connection *conn, struct s2n_config **c
return S2N_SUCCESS;
}
+
+S2N_RESULT s2n_connection_dynamic_free_out_buffer(struct s2n_connection *conn)
+{
+ RESULT_ENSURE_REF(conn);
+
+ /* free the out buffer if we're in dynamic mode and it's completely flushed */
+ if (conn->dynamic_buffers && s2n_stuffer_is_consumed(&conn->out)) {
+ /* since outgoing buffers are already encrypted, the buffers don't need to be zeroed, which saves some overhead */
+ RESULT_GUARD_POSIX(s2n_stuffer_free_without_wipe(&conn->out));
+
+ /* reset the stuffer to its initial state */
+ RESULT_GUARD_POSIX(s2n_stuffer_growable_alloc(&conn->out, 0));
+ }
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_connection_dynamic_free_in_buffer(struct s2n_connection *conn)
+{
+ RESULT_ENSURE_REF(conn);
+
+ /* free the `in` buffer if we're in dynamic mode and it's completely flushed */
+ if (conn->dynamic_buffers && s2n_stuffer_is_consumed(&conn->in)) {
+ /* when copying the buffer into the application, we use `s2n_stuffer_erase_and_read`, which already zeroes the memory */
+ RESULT_GUARD_POSIX(s2n_stuffer_free_without_wipe(&conn->in));
+
+ /* reset the stuffer to its initial state */
+ RESULT_GUARD_POSIX(s2n_stuffer_growable_alloc(&conn->in, 0));
+ }
+
+ return S2N_RESULT_OK;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_connection.h b/contrib/restricted/aws/s2n/tls/s2n_connection.h
index 2965de74e6..9d7d5bdf68 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_connection.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_connection.h
@@ -127,6 +127,10 @@ struct s2n_connection {
* This allows multiple records to be written with one socket send. */
unsigned multirecord_send:1;
+ /* If enabled, this connection will free each of its IO buffers after all data
+ * has been flushed */
+ unsigned dynamic_buffers:1;
+
/* The configuration (cert, key .. etc ) */
struct s2n_config *config;
@@ -193,8 +197,8 @@ struct s2n_connection {
uint8_t actual_protocol_version_established;
/* Our crypto parameters */
- struct s2n_crypto_parameters initial;
- struct s2n_crypto_parameters secure;
+ struct s2n_crypto_parameters *initial;
+ struct s2n_crypto_parameters *secure;
union s2n_secrets secrets;
/* Which set is the client/server actually using? */
@@ -390,6 +394,10 @@ int s2n_connection_recv_stuffer(struct s2n_stuffer *stuffer, struct s2n_connecti
S2N_RESULT s2n_connection_wipe_all_keyshares(struct s2n_connection *conn);
+/* If dynamic buffers are enabled, the IO buffers may be freed if they are completely consumed */
+S2N_RESULT s2n_connection_dynamic_free_in_buffer(struct s2n_connection *conn);
+S2N_RESULT s2n_connection_dynamic_free_out_buffer(struct s2n_connection *conn);
+
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);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_connection_evp_digests.c b/contrib/restricted/aws/s2n/tls/s2n_connection_evp_digests.c
deleted file mode 100644
index 856ca79f89..0000000000
--- a/contrib/restricted/aws/s2n/tls/s2n_connection_evp_digests.c
+++ /dev/null
@@ -1,44 +0,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_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)
-{
- POSIX_GUARD(s2n_hmac_save_evp_hash_state(&hmac_handles->initial_client, &conn->initial.client_record_mac));
- POSIX_GUARD(s2n_hmac_save_evp_hash_state(&hmac_handles->initial_server, &conn->initial.server_record_mac));
- POSIX_GUARD(s2n_hmac_save_evp_hash_state(&hmac_handles->secure_client, &conn->secure.client_record_mac));
- POSIX_GUARD(s2n_hmac_save_evp_hash_state(&hmac_handles->secure_server, &conn->secure.server_record_mac));
- 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)
-{
- POSIX_GUARD(s2n_hmac_restore_evp_hash_state(&hmac_handles->initial_client, &conn->initial.client_record_mac));
- POSIX_GUARD(s2n_hmac_restore_evp_hash_state(&hmac_handles->initial_server, &conn->initial.server_record_mac));
- POSIX_GUARD(s2n_hmac_restore_evp_hash_state(&hmac_handles->secure_client, &conn->secure.client_record_mac));
- POSIX_GUARD(s2n_hmac_restore_evp_hash_state(&hmac_handles->secure_server, &conn->secure.server_record_mac));
- 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
deleted file mode 100644
index e94e19d010..0000000000
--- a/contrib/restricted/aws/s2n/tls/s2n_connection_evp_digests.h
+++ /dev/null
@@ -1,34 +0,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.
- */
-
-#pragma once
-
-#include "tls/s2n_connection.h"
-#include "tls/s2n_prf.h"
-
-#include "crypto/s2n_hash.h"
-
-/* 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_hmac_state(struct s2n_connection_hmac_handles *hmac_handles, struct s2n_connection *conn);
-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.c b/contrib/restricted/aws/s2n/tls/s2n_crypto.c
new file mode 100644
index 0000000000..a5fac27a10
--- /dev/null
+++ b/contrib/restricted/aws/s2n/tls/s2n_crypto.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT 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_crypto.h"
+
+#include "tls/s2n_cipher_suites.h"
+#include "utils/s2n_result.h"
+#include "utils/s2n_safety.h"
+
+S2N_RESULT s2n_crypto_parameters_new(struct s2n_crypto_parameters **new_params)
+{
+ RESULT_ENSURE_REF(new_params);
+ RESULT_ENSURE_EQ(*new_params, NULL);
+
+ DEFER_CLEANUP(struct s2n_blob mem = { 0 }, s2n_free);
+ RESULT_GUARD_POSIX(s2n_alloc(&mem, sizeof(struct s2n_crypto_parameters)));
+ RESULT_GUARD_POSIX(s2n_blob_zero(&mem));
+
+ DEFER_CLEANUP(struct s2n_crypto_parameters *params = (struct s2n_crypto_parameters*)(void*) mem.data,
+ s2n_crypto_parameters_free);
+ ZERO_TO_DISABLE_DEFER_CLEANUP(mem);
+
+ /* Allocate long-term memory for the HMAC states */
+ RESULT_GUARD_POSIX(s2n_hmac_new(&params->client_record_mac));
+ RESULT_GUARD_POSIX(s2n_hmac_new(&params->server_record_mac));
+
+ /* Allocate key memory */
+ RESULT_GUARD_POSIX(s2n_session_key_alloc(&params->client_key));
+ RESULT_GUARD_POSIX(s2n_session_key_alloc(&params->server_key));
+
+ /* Setup */
+ RESULT_GUARD(s2n_crypto_parameters_wipe(params));
+
+ *new_params = params;
+ ZERO_TO_DISABLE_DEFER_CLEANUP(params);
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_crypto_parameters_wipe(struct s2n_crypto_parameters *params)
+{
+ RESULT_ENSURE_REF(params);
+
+ /* Wipe the hmacs for reuse */
+ struct s2n_hmac_state client_state = params->client_record_mac;
+ struct s2n_hmac_state server_state = params->server_record_mac;
+ RESULT_GUARD_POSIX(s2n_hmac_init(&client_state, S2N_HMAC_NONE, NULL, 0));
+ RESULT_GUARD_POSIX(s2n_hmac_init(&server_state, S2N_HMAC_NONE, NULL, 0));
+
+ /* Wipe the keys for reuse */
+ struct s2n_session_key client_key = params->client_key;
+ struct s2n_session_key server_key = params->server_key;
+ if (params->cipher_suite && params->cipher_suite->record_alg &&
+ params->cipher_suite->record_alg->cipher && params->cipher_suite->record_alg->cipher->destroy_key) {
+ RESULT_GUARD_POSIX(params->cipher_suite->record_alg->cipher->destroy_key(&params->client_key));
+ RESULT_GUARD_POSIX(params->cipher_suite->record_alg->cipher->destroy_key(&params->server_key));
+ }
+
+ *params = (struct s2n_crypto_parameters) { 0 };
+
+ params->client_record_mac = client_state;
+ params->server_record_mac = server_state;
+ params->client_key = client_key;
+ params->server_key = server_key;
+ params->cipher_suite = &s2n_null_cipher_suite;
+ return S2N_RESULT_OK;
+}
+
+S2N_CLEANUP_RESULT s2n_crypto_parameters_free(struct s2n_crypto_parameters **params)
+{
+ if (params == NULL || *params == NULL) {
+ return S2N_RESULT_OK;
+ }
+
+ /* Free HMAC states */
+ RESULT_GUARD_POSIX(s2n_hmac_free(&(*params)->client_record_mac));
+ RESULT_GUARD_POSIX(s2n_hmac_free(&(*params)->server_record_mac));
+
+ /* Free session keys */
+ RESULT_GUARD_POSIX(s2n_session_key_free(&(*params)->client_key));
+ RESULT_GUARD_POSIX(s2n_session_key_free(&(*params)->server_key));
+
+ RESULT_GUARD_POSIX(s2n_free_object((uint8_t **) params, sizeof(struct s2n_crypto_parameters)));
+ return S2N_RESULT_OK;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_crypto.h b/contrib/restricted/aws/s2n/tls/s2n_crypto.h
index de6c18b332..37997bb8eb 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_crypto.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_crypto.h
@@ -65,3 +65,7 @@ struct s2n_crypto_parameters {
uint8_t client_sequence_number[S2N_TLS_SEQUENCE_NUM_LEN];
uint8_t server_sequence_number[S2N_TLS_SEQUENCE_NUM_LEN];
};
+
+S2N_RESULT s2n_crypto_parameters_new(struct s2n_crypto_parameters **params);
+S2N_RESULT s2n_crypto_parameters_wipe(struct s2n_crypto_parameters *params);
+S2N_CLEANUP_RESULT s2n_crypto_parameters_free(struct s2n_crypto_parameters **params);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_early_data.c b/contrib/restricted/aws/s2n/tls/s2n_early_data.c
index 102ceed334..309f108f38 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_early_data.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_early_data.c
@@ -61,6 +61,7 @@ int s2n_connection_set_end_of_early_data(struct s2n_connection *conn)
static S2N_RESULT s2n_early_data_validate(struct s2n_connection *conn)
{
RESULT_ENSURE_REF(conn);
+ RESULT_ENSURE_REF(conn->secure);
/**
*= https://tools.ietf.org/rfc/rfc8446#section-4.2.10
@@ -87,7 +88,7 @@ static S2N_RESULT s2n_early_data_validate(struct s2n_connection *conn)
*= https://tools.ietf.org/rfc/rfc8446#section-4.2.10
*# - The selected cipher suite
**/
- RESULT_ENSURE_EQ(config->cipher_suite, conn->secure.cipher_suite);
+ RESULT_ENSURE_EQ(config->cipher_suite, conn->secure->cipher_suite);
/**
*= https://tools.ietf.org/rfc/rfc8446#section-4.2.10
*# - The selected ALPN [RFC7301] protocol, if any
diff --git a/contrib/restricted/aws/s2n/tls/s2n_handshake.c b/contrib/restricted/aws/s2n/tls/s2n_handshake.c
index eb46950ebe..0923c3d9a7 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_handshake.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_handshake.c
@@ -143,6 +143,9 @@ uint8_t s2n_handshake_is_hash_required(struct s2n_handshake *handshake, s2n_hash
*/
int s2n_conn_update_required_handshake_hashes(struct s2n_connection *conn)
{
+ POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
+
/* Clear all of the required hashes */
memset(conn->handshake.required_hash_algs, 0, sizeof(conn->handshake.required_hash_algs));
@@ -170,7 +173,7 @@ int s2n_conn_update_required_handshake_hashes(struct s2n_connection *conn)
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_hmac_algorithm prf_alg = conn->secure->cipher_suite->prf_alg;
s2n_hash_algorithm hash_alg;
POSIX_GUARD(s2n_hmac_hash_alg(prf_alg, &hash_alg));
POSIX_GUARD(s2n_handshake_require_hash(&conn->handshake, hash_alg));
diff --git a/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c b/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c
index a1f5c1215f..641bebe6ca 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c
@@ -62,7 +62,7 @@ static int s2n_always_fail_recv(struct s2n_connection *conn)
POSIX_BAIL(S2N_ERR_HANDSHAKE_UNREACHABLE);
}
-/* Client and Server handlers for each message type we support.
+/* 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[] = {
@@ -811,6 +811,9 @@ static S2N_RESULT s2n_validate_ems_status(struct s2n_connection *conn)
int s2n_conn_set_handshake_type(struct s2n_connection *conn)
{
+ POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
+
if (IS_TLS13_HANDSHAKE(conn)) {
POSIX_GUARD_RESULT(s2n_conn_set_tls13_handshake_type(conn));
return S2N_SUCCESS;
@@ -876,7 +879,7 @@ skip_cache_lookup:
POSIX_GUARD_RESULT(s2n_handshake_type_set_flag(conn, FULL_HANDSHAKE));
bool is_ephemeral = false;
- POSIX_GUARD_RESULT(s2n_kex_is_ephemeral(conn->secure.cipher_suite->key_exchange_alg, &is_ephemeral));
+ POSIX_GUARD_RESULT(s2n_kex_is_ephemeral(conn->secure->cipher_suite->key_exchange_alg, &is_ephemeral));
if (is_ephemeral) {
POSIX_GUARD_RESULT(s2n_handshake_type_set_tls12_flag(conn, TLS12_PERFECT_FORWARD_SECRECY));
}
@@ -1452,7 +1455,13 @@ int s2n_negotiate(struct s2n_connection *conn, s2n_blocked_status *blocked)
POSIX_ENSURE_REF(conn);
POSIX_ENSURE(!conn->negotiate_in_use, S2N_ERR_REENTRANCY);
conn->negotiate_in_use = true;
+
int result = s2n_negotiate_impl(conn, blocked);
+
+ /* finish up sending and receiving */
+ POSIX_GUARD_RESULT(s2n_connection_dynamic_free_in_buffer(conn));
+ POSIX_GUARD_RESULT(s2n_connection_dynamic_free_out_buffer(conn));
+
conn->negotiate_in_use = false;
return result;
}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_key_update.c b/contrib/restricted/aws/s2n/tls/s2n_key_update.c
index 6e8fbaca37..92d5509788 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_key_update.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_key_update.c
@@ -54,12 +54,13 @@ int s2n_key_update_recv(struct s2n_connection *conn, struct s2n_stuffer *request
int s2n_key_update_send(struct s2n_connection *conn, s2n_blocked_status *blocked)
{
POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
struct s2n_blob sequence_number = {0};
if (conn->mode == S2N_CLIENT) {
- POSIX_GUARD(s2n_blob_init(&sequence_number, conn->secure.client_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
+ POSIX_GUARD(s2n_blob_init(&sequence_number, conn->secure->client_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
} else {
- POSIX_GUARD(s2n_blob_init(&sequence_number, conn->secure.server_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
+ POSIX_GUARD(s2n_blob_init(&sequence_number, conn->secure->server_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
}
POSIX_GUARD(s2n_check_record_limit(conn, &sequence_number));
@@ -113,8 +114,9 @@ int s2n_check_record_limit(struct s2n_connection *conn, struct s2n_blob *sequenc
{
POSIX_ENSURE_REF(conn);
POSIX_ENSURE_REF(sequence_number);
- POSIX_ENSURE_REF(conn->secure.cipher_suite);
- POSIX_ENSURE_REF(conn->secure.cipher_suite->record_alg);
+ POSIX_ENSURE_REF(conn->secure);
+ POSIX_ENSURE_REF(conn->secure->cipher_suite);
+ POSIX_ENSURE_REF(conn->secure->cipher_suite->record_alg);
/*
* This is the sequence number that will be used for the next record,
@@ -129,7 +131,7 @@ int s2n_check_record_limit(struct s2n_connection *conn, struct s2n_blob *sequenc
*
* This should always trigger on "==", but we use ">=" just in case.
*/
- if (next_seq_num >= conn->secure.cipher_suite->record_alg->encryption_limit) {
+ if (next_seq_num >= conn->secure->cipher_suite->record_alg->encryption_limit) {
conn->key_update_pending = true;
}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_prf.c b/contrib/restricted/aws/s2n/tls/s2n_prf.c
index 161f28eae1..043778d78a 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_prf.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_prf.c
@@ -466,6 +466,7 @@ static int s2n_prf(struct s2n_connection *conn, struct s2n_blob *secret, struct
POSIX_ENSURE_REF(conn);
POSIX_ENSURE_REF(secret);
POSIX_ENSURE_REF(conn->prf_space);
+ POSIX_ENSURE_REF(conn->secure);
/* 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);
@@ -484,7 +485,7 @@ static int s2n_prf(struct s2n_connection *conn, struct s2n_blob *secret, struct
POSIX_GUARD(s2n_blob_zero(out));
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,
+ return s2n_p_hash(conn->prf_space, conn->secure->cipher_suite->prf_alg, secret, label, seed_a, seed_b,
seed_c, out);
}
@@ -524,6 +525,7 @@ int s2n_hybrid_prf_master_secret(struct s2n_connection *conn, struct s2n_blob *p
int s2n_prf_calculate_master_secret(struct s2n_connection *conn, struct s2n_blob *premaster_secret)
{
POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
POSIX_ENSURE_EQ(s2n_conn_get_current_message_type(conn), CLIENT_KEY);
@@ -553,7 +555,7 @@ int s2n_prf_calculate_master_secret(struct s2n_connection *conn, struct s2n_blob
POSIX_GUARD_RESULT(s2n_prf_get_digest_for_ems(conn, &client_key_blob, S2N_HASH_SHA1, &sha1_digest));
POSIX_GUARD_RESULT(s2n_tls_prf_extended_master_secret(conn, premaster_secret, &digest, &sha1_digest));
} else {
- s2n_hmac_algorithm prf_alg = conn->secure.cipher_suite->prf_alg;
+ s2n_hmac_algorithm prf_alg = conn->secure->cipher_suite->prf_alg;
s2n_hash_algorithm hash_alg = 0;
POSIX_GUARD(s2n_hmac_hash_alg(prf_alg, &hash_alg));
POSIX_GUARD_RESULT(s2n_prf_get_digest_for_ems(conn, &client_key_blob, hash_alg, &digest));
@@ -675,6 +677,7 @@ static int s2n_sslv3_server_finished(struct s2n_connection *conn)
int s2n_prf_client_finished(struct s2n_connection *conn)
{
POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
POSIX_ENSURE_REF(conn->handshake.hashes);
struct s2n_blob master_secret, md5, sha;
@@ -696,7 +699,7 @@ int s2n_prf_client_finished(struct s2n_connection *conn)
master_secret.data = conn->secrets.tls12.master_secret;
master_secret.size = sizeof(conn->secrets.tls12.master_secret);
if (conn->actual_protocol_version == S2N_TLS12) {
- switch (conn->secure.cipher_suite->prf_alg) {
+ switch (conn->secure->cipher_suite->prf_alg) {
case S2N_HMAC_SHA256:
POSIX_GUARD(s2n_hash_copy(&conn->handshake.hashes->hash_workspace, &conn->handshake.hashes->sha256));
POSIX_GUARD(s2n_hash_digest(&conn->handshake.hashes->hash_workspace, sha_digest, SHA256_DIGEST_LENGTH));
@@ -731,6 +734,7 @@ int s2n_prf_client_finished(struct s2n_connection *conn)
int s2n_prf_server_finished(struct s2n_connection *conn)
{
POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
POSIX_ENSURE_REF(conn->handshake.hashes);
struct s2n_blob master_secret, md5, sha;
@@ -752,7 +756,7 @@ int s2n_prf_server_finished(struct s2n_connection *conn)
master_secret.data = conn->secrets.tls12.master_secret;
master_secret.size = sizeof(conn->secrets.tls12.master_secret);
if (conn->actual_protocol_version == S2N_TLS12) {
- switch (conn->secure.cipher_suite->prf_alg) {
+ switch (conn->secure->cipher_suite->prf_alg) {
case S2N_HMAC_SHA256:
POSIX_GUARD(s2n_hash_copy(&conn->handshake.hashes->hash_workspace, &conn->handshake.hashes->sha256));
POSIX_GUARD(s2n_hash_digest(&conn->handshake.hashes->hash_workspace, sha_digest, SHA256_DIGEST_LENGTH));
@@ -786,15 +790,18 @@ int s2n_prf_server_finished(struct s2n_connection *conn)
static int s2n_prf_make_client_key(struct s2n_connection *conn, struct s2n_stuffer *key_material)
{
+ POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
+
struct s2n_blob client_key = {0};
- client_key.size = conn->secure.cipher_suite->record_alg->cipher->key_material_size;
+ 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);
POSIX_ENSURE_REF(client_key.data);
if (conn->mode == S2N_CLIENT) {
- POSIX_GUARD(conn->secure.cipher_suite->record_alg->cipher->set_encryption_key(&conn->secure.client_key, &client_key));
+ POSIX_GUARD(conn->secure->cipher_suite->record_alg->cipher->set_encryption_key(&conn->secure->client_key, &client_key));
} else {
- POSIX_GUARD(conn->secure.cipher_suite->record_alg->cipher->set_decryption_key(&conn->secure.client_key, &client_key));
+ POSIX_GUARD(conn->secure->cipher_suite->record_alg->cipher->set_decryption_key(&conn->secure->client_key, &client_key));
}
return 0;
@@ -802,15 +809,18 @@ static int s2n_prf_make_client_key(struct s2n_connection *conn, struct s2n_stuff
static int s2n_prf_make_server_key(struct s2n_connection *conn, struct s2n_stuffer *key_material)
{
+ POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
+
struct s2n_blob server_key = {0};
- server_key.size = conn->secure.cipher_suite->record_alg->cipher->key_material_size;
+ 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);
POSIX_ENSURE_REF(server_key.data);
if (conn->mode == S2N_SERVER) {
- POSIX_GUARD(conn->secure.cipher_suite->record_alg->cipher->set_encryption_key(&conn->secure.server_key, &server_key));
+ POSIX_GUARD(conn->secure->cipher_suite->record_alg->cipher->set_encryption_key(&conn->secure->server_key, &server_key));
} else {
- POSIX_GUARD(conn->secure.cipher_suite->record_alg->cipher->set_decryption_key(&conn->secure.server_key, &server_key));
+ POSIX_GUARD(conn->secure->cipher_suite->record_alg->cipher->set_decryption_key(&conn->secure->server_key, &server_key));
}
return 0;
@@ -818,6 +828,9 @@ static int s2n_prf_make_server_key(struct s2n_connection *conn, struct s2n_stuff
int s2n_prf_key_expansion(struct s2n_connection *conn)
{
+ POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
+
struct s2n_blob client_random = {.data = conn->handshake_params.client_random,.size = sizeof(conn->handshake_params.client_random) };
struct s2n_blob server_random = {.data = conn->handshake_params.server_random,.size = sizeof(conn->handshake_params.server_random) };
struct s2n_blob master_secret = {.data = conn->secrets.tls12.master_secret,.size = sizeof(conn->secrets.tls12.master_secret) };
@@ -834,29 +847,29 @@ int s2n_prf_key_expansion(struct s2n_connection *conn)
POSIX_GUARD(s2n_stuffer_init(&key_material, &out));
POSIX_GUARD(s2n_stuffer_write(&key_material, &out));
- POSIX_ENSURE(conn->secure.cipher_suite->available, S2N_ERR_PRF_INVALID_ALGORITHM);
- POSIX_GUARD(conn->secure.cipher_suite->record_alg->cipher->init(&conn->secure.client_key));
- POSIX_GUARD(conn->secure.cipher_suite->record_alg->cipher->init(&conn->secure.server_key));
+ POSIX_ENSURE(conn->secure->cipher_suite->available, S2N_ERR_PRF_INVALID_ALGORITHM);
+ POSIX_GUARD(conn->secure->cipher_suite->record_alg->cipher->init(&conn->secure->client_key));
+ POSIX_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;
+ 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 {
- POSIX_GUARD(s2n_hmac_digest_size(conn->secure.cipher_suite->record_alg->hmac_alg, &mac_size));
+ POSIX_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);
POSIX_ENSURE_REF(client_mac_write_key);
- POSIX_GUARD(s2n_hmac_reset(&conn->secure.client_record_mac));
- POSIX_GUARD(s2n_hmac_init(&conn->secure.client_record_mac, conn->secure.cipher_suite->record_alg->hmac_alg, client_mac_write_key, mac_size));
+ POSIX_GUARD(s2n_hmac_reset(&conn->secure->client_record_mac));
+ POSIX_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);
POSIX_ENSURE_REF(server_mac_write_key);
- POSIX_GUARD(s2n_hmac_reset(&conn->secure.server_record_mac));
- POSIX_GUARD(s2n_hmac_init(&conn->secure.server_record_mac, conn->secure.cipher_suite->record_alg->hmac_alg, server_mac_write_key, mac_size));
+ POSIX_GUARD(s2n_hmac_reset(&conn->secure->server_record_mac));
+ POSIX_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 */
POSIX_GUARD(s2n_prf_make_client_key(conn, &key_material));
@@ -867,34 +880,34 @@ int s2n_prf_key_expansion(struct s2n_connection *conn)
/* 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) {
- POSIX_GUARD(conn->secure.cipher_suite->record_alg->cipher->io.comp.set_mac_write_key(&conn->secure.server_key, server_mac_write_key, mac_size));
- POSIX_GUARD(conn->secure.cipher_suite->record_alg->cipher->io.comp.set_mac_write_key(&conn->secure.client_key, client_mac_write_key, mac_size));
+ if (conn->secure->cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
+ POSIX_GUARD(conn->secure->cipher_suite->record_alg->cipher->io.comp.set_mac_write_key(&conn->secure->server_key, server_mac_write_key, mac_size));
+ POSIX_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) {
+ 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) {
+ 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;
+ 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;
+ 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;
+ 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 };
+ 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 };
POSIX_GUARD(s2n_stuffer_read(&key_material, &client_implicit_iv));
POSIX_GUARD(s2n_stuffer_read(&key_material, &server_implicit_iv));
diff --git a/contrib/restricted/aws/s2n/tls/s2n_psk.c b/contrib/restricted/aws/s2n/tls/s2n_psk.c
index 7a42ab28dc..b33071dca5 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_psk.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_psk.c
@@ -478,6 +478,7 @@ static S2N_RESULT s2n_psk_write_binder_list(struct s2n_connection *conn, const s
{
RESULT_ENSURE_REF(conn);
RESULT_ENSURE_REF(partial_client_hello);
+ RESULT_ENSURE_REF(conn->secure);
struct s2n_psk_parameters *psk_params = &conn->psk_params;
struct s2n_array *psk_list = &psk_params->psk_list;
@@ -504,7 +505,7 @@ static S2N_RESULT s2n_psk_write_binder_list(struct s2n_connection *conn, const s
*# compute partial hash transcripts for multiple hashes in the second
*# ClientHello.
*/
- if (s2n_is_hello_retry_handshake(conn) && conn->secure.cipher_suite->prf_alg != psk->hmac_alg) {
+ if (s2n_is_hello_retry_handshake(conn) && conn->secure->cipher_suite->prf_alg != psk->hmac_alg) {
continue;
}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_record_read.c b/contrib/restricted/aws/s2n/tls/s2n_record_read.c
index 8a1bf8836f..42e8bd4603 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_record_read.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_record_read.c
@@ -121,8 +121,9 @@ int s2n_record_parse(struct s2n_connection *conn)
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;
+ POSIX_ENSURE_REF(conn->initial);
+ conn->client = conn->initial;
+ conn->server = conn->initial;
}
const struct s2n_cipher_suite *cipher_suite = conn->client->cipher_suite;
diff --git a/contrib/restricted/aws/s2n/tls/s2n_record_write.c b/contrib/restricted/aws/s2n/tls/s2n_record_write.c
index 323a3ce944..c1ac2b9e78 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_record_write.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_record_write.c
@@ -238,8 +238,9 @@ int s2n_record_writev(struct s2n_connection *conn, uint8_t content_type, const s
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;
+ POSIX_ENSURE_REF(conn->initial);
+ conn->client = conn->initial;
+ conn->server = conn->initial;
}
uint8_t *sequence_number = conn->server->server_sequence_number;
diff --git a/contrib/restricted/aws/s2n/tls/s2n_recv.c b/contrib/restricted/aws/s2n/tls/s2n_recv.c
index bbf48b1ff8..ddd3fa8062 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_recv.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_recv.c
@@ -206,8 +206,13 @@ ssize_t s2n_recv(struct s2n_connection * conn, void *buf, ssize_t size, s2n_bloc
{
POSIX_ENSURE(!conn->recv_in_use, S2N_ERR_REENTRANCY);
conn->recv_in_use = true;
+
ssize_t result = s2n_recv_impl(conn, buf, size, blocked);
POSIX_GUARD_RESULT(s2n_early_data_record_bytes(conn, result));
+
+ /* finish the recv call */
+ POSIX_GUARD_RESULT(s2n_connection_dynamic_free_in_buffer(conn));
+
conn->recv_in_use = false;
return result;
}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_resume.c b/contrib/restricted/aws/s2n/tls/s2n_resume.c
index 952ae9cbde..6f0bd07858 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_resume.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_resume.c
@@ -46,8 +46,9 @@ int s2n_allowed_to_cache_connection(struct s2n_connection *conn)
static int s2n_tls12_serialize_resumption_state(struct s2n_connection *conn, struct s2n_stuffer *to)
{
- POSIX_ENSURE_REF(conn);
POSIX_ENSURE_REF(to);
+ POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
uint64_t now;
@@ -59,7 +60,7 @@ static int s2n_tls12_serialize_resumption_state(struct s2n_connection *conn, str
/* Write the entry */
POSIX_GUARD(s2n_stuffer_write_uint8(to, S2N_SERIALIZED_FORMAT_TLS12_V3));
POSIX_GUARD(s2n_stuffer_write_uint8(to, conn->actual_protocol_version));
- POSIX_GUARD(s2n_stuffer_write_bytes(to, conn->secure.cipher_suite->iana_value, S2N_TLS_CIPHER_SUITE_LEN));
+ POSIX_GUARD(s2n_stuffer_write_bytes(to, conn->secure->cipher_suite->iana_value, S2N_TLS_CIPHER_SUITE_LEN));
POSIX_GUARD(s2n_stuffer_write_uint64(to, now));
POSIX_GUARD(s2n_stuffer_write_bytes(to, conn->secrets.tls12.master_secret, S2N_TLS_SECRET_LEN));
POSIX_GUARD(s2n_stuffer_write_uint8(to, conn->ems_negotiated));
@@ -90,8 +91,9 @@ static S2N_RESULT s2n_tls13_serialize_keying_material_expiration(struct s2n_conn
static S2N_RESULT s2n_tls13_serialize_resumption_state(struct s2n_connection *conn, struct s2n_stuffer *out)
{
- RESULT_ENSURE_REF(conn);
RESULT_ENSURE_REF(out);
+ RESULT_ENSURE_REF(conn);
+ RESULT_ENSURE_REF(conn->secure);
uint64_t current_time = 0;
struct s2n_ticket_fields *ticket_fields = &conn->tls13_ticket_fields;
@@ -101,7 +103,7 @@ static S2N_RESULT s2n_tls13_serialize_resumption_state(struct s2n_connection *co
RESULT_GUARD_POSIX(s2n_stuffer_write_uint8(out, S2N_SERIALIZED_FORMAT_TLS13_V1));
RESULT_GUARD_POSIX(s2n_stuffer_write_uint8(out, conn->actual_protocol_version));
- RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(out, conn->secure.cipher_suite->iana_value, S2N_TLS_CIPHER_SUITE_LEN));
+ RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(out, conn->secure->cipher_suite->iana_value, S2N_TLS_CIPHER_SUITE_LEN));
RESULT_GUARD_POSIX(s2n_stuffer_write_uint64(out, current_time));
RESULT_GUARD_POSIX(s2n_stuffer_write_uint32(out, ticket_fields->ticket_age_add));
RESULT_ENSURE_LTE(ticket_fields->session_secret.size, UINT8_MAX);
@@ -135,6 +137,9 @@ static S2N_RESULT s2n_serialize_resumption_state(struct s2n_connection *conn, st
static int s2n_tls12_deserialize_resumption_state(struct s2n_connection *conn, struct s2n_stuffer *from)
{
+ POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
+
uint8_t protocol_version = 0;
uint8_t cipher_suite[S2N_TLS_CIPHER_SUITE_LEN] = { 0 };
@@ -144,7 +149,7 @@ static int s2n_tls12_deserialize_resumption_state(struct s2n_connection *conn, s
S2N_ERROR_IF(protocol_version != conn->actual_protocol_version, S2N_ERR_INVALID_SERIALIZED_SESSION_STATE);
POSIX_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);
+ 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;
POSIX_GUARD(conn->config->wall_clock(conn->config->sys_clock_ctx, &now));
@@ -497,6 +502,7 @@ int s2n_connection_get_session_ticket_lifetime_hint(struct s2n_connection *conn)
S2N_RESULT s2n_connection_get_session_state_size(struct s2n_connection *conn, size_t *state_size)
{
RESULT_ENSURE_REF(conn);
+ RESULT_ENSURE_REF(conn->secure);
RESULT_ENSURE_REF(state_size);
if (conn->actual_protocol_version < S2N_TLS13) {
@@ -507,8 +513,8 @@ S2N_RESULT s2n_connection_get_session_state_size(struct s2n_connection *conn, si
*state_size = S2N_TLS13_FIXED_STATE_SIZE;
uint8_t secret_size = 0;
- RESULT_ENSURE_REF(conn->secure.cipher_suite);
- RESULT_GUARD_POSIX(s2n_hmac_digest_size(conn->secure.cipher_suite->prf_alg, &secret_size));
+ RESULT_ENSURE_REF(conn->secure->cipher_suite);
+ RESULT_GUARD_POSIX(s2n_hmac_digest_size(conn->secure->cipher_suite->prf_alg, &secret_size));
*state_size += secret_size;
uint32_t server_max_early_data = 0;
diff --git a/contrib/restricted/aws/s2n/tls/s2n_security_policies.c b/contrib/restricted/aws/s2n/tls/s2n_security_policies.c
index 8dd9496de7..9072932670 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_security_policies.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_security_policies.c
@@ -682,6 +682,19 @@ const struct s2n_security_policy security_policy_20210816_gcm = {
.ecc_preferences = &s2n_ecc_preferences_20210816,
};
+/*
+ * This security policy is derived from the following specification:
+ * https://datatracker.ietf.org/doc/html/rfc9151
+ */
+const struct s2n_security_policy security_policy_rfc9151 = {
+ .minimum_protocol_version = S2N_TLS12,
+ .cipher_preferences = &cipher_preferences_rfc9151,
+ .kem_preferences = &kem_preferences_null,
+ .signature_preferences = &s2n_signature_preferences_rfc9151,
+ .certificate_signature_preferences = &s2n_certificate_signature_preferences_rfc9151,
+ .ecc_preferences = &s2n_ecc_preferences_20210816,
+};
+
const struct s2n_security_policy security_policy_test_all = {
.minimum_protocol_version = S2N_SSLv3,
.cipher_preferences = &cipher_preferences_test_all,
@@ -834,6 +847,7 @@ struct s2n_security_policy_selection security_policy_selection[] = {
{ .version="20201021", .security_policy=&security_policy_20201021, .ecc_extension_required=0, .pq_kem_extension_required=0 },
{ .version="20210816", .security_policy=&security_policy_20210816, .ecc_extension_required=0, .pq_kem_extension_required=0 },
{ .version="20210816_GCM", .security_policy=&security_policy_20210816_gcm, .ecc_extension_required=0, .pq_kem_extension_required=0 },
+ { .version="rfc9151", .security_policy=&security_policy_rfc9151, .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 },
@@ -1028,7 +1042,8 @@ int s2n_connection_is_valid_for_cipher_preferences(struct s2n_connection *conn,
{
POSIX_ENSURE_REF(conn);
POSIX_ENSURE_REF(version);
- POSIX_ENSURE_REF(conn->secure.cipher_suite);
+ POSIX_ENSURE_REF(conn->secure);
+ POSIX_ENSURE_REF(conn->secure->cipher_suite);
const struct s2n_security_policy *security_policy = NULL;
POSIX_GUARD(s2n_find_security_policy_from_version(version, &security_policy));
@@ -1039,7 +1054,7 @@ int s2n_connection_is_valid_for_cipher_preferences(struct s2n_connection *conn,
return 0;
}
- struct s2n_cipher_suite *cipher = conn->secure.cipher_suite;
+ struct s2n_cipher_suite *cipher = conn->secure->cipher_suite;
POSIX_ENSURE_REF(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)) {
@@ -1084,7 +1099,10 @@ S2N_RESULT s2n_validate_certificate_signature_preferences(const struct s2n_signa
}
}
- /* The Openssl function used to parse signatures off certificates does not differentiate between any rsa pss
+ /*
+ * https://github.com/aws/s2n-tls/issues/3435
+ *
+ * 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. */
RESULT_ENSURE(rsa_pss_scheme_count == NUM_RSA_PSS_SCHEMES || rsa_pss_scheme_count == 0, S2N_ERR_INVALID_SECURITY_POLICY);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_send.c b/contrib/restricted/aws/s2n/tls/s2n_send.c
index cc7188eb73..6f31935ceb 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_send.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_send.c
@@ -209,7 +209,7 @@ ssize_t s2n_sendv_with_offset_impl(struct s2n_connection *conn, const struct iov
}
POSIX_GUARD(s2n_post_handshake_send(conn, blocked));
-
+
/* Write and encrypt the record */
int written_to_record = s2n_record_writev(conn, TLS_APPLICATION_DATA, bufs, count,
conn->current_user_data_consumed + offs, to_write);
@@ -247,8 +247,12 @@ ssize_t s2n_sendv_with_offset(struct s2n_connection *conn, const struct iovec *b
{
POSIX_ENSURE(!conn->send_in_use, S2N_ERR_REENTRANCY);
conn->send_in_use = true;
+
ssize_t result = s2n_sendv_with_offset_impl(conn, bufs, count, offs, blocked);
POSIX_GUARD_RESULT(s2n_early_data_record_bytes(conn, result));
+
+ POSIX_GUARD_RESULT(s2n_connection_dynamic_free_out_buffer(conn));
+
conn->send_in_use = false;
return result;
}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_server_finished.c b/contrib/restricted/aws/s2n/tls/s2n_server_finished.c
index d7e57a222b..05c553799f 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_server_finished.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_server_finished.c
@@ -46,6 +46,9 @@ int s2n_server_finished_recv(struct s2n_connection *conn)
int s2n_server_finished_send(struct s2n_connection *conn)
{
+ POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
+
uint8_t *our_version;
int length = S2N_TLS_FINISHED_LEN;
@@ -61,11 +64,11 @@ int s2n_server_finished_send(struct s2n_connection *conn)
POSIX_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 };
+ struct s2n_blob seq = {.data = conn->secure->server_sequence_number,.size = S2N_TLS_SEQUENCE_NUM_LEN };
POSIX_GUARD(s2n_blob_zero(&seq));
/* Update the secure state to active, and point the client at the active state */
- conn->server = &conn->secure;
+ conn->server = conn->secure;
if (s2n_connection_is_session_resumed(conn)) {
POSIX_GUARD(s2n_prf_key_expansion(conn));
diff --git a/contrib/restricted/aws/s2n/tls/s2n_server_hello.c b/contrib/restricted/aws/s2n/tls/s2n_server_hello.c
index efe4c08114..4962dfb3b2 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_server_hello.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_server_hello.c
@@ -98,6 +98,7 @@ static int s2n_server_add_downgrade_mechanism(struct s2n_connection *conn) {
static int s2n_server_hello_parse(struct s2n_connection *conn)
{
POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
struct s2n_stuffer *in = &conn->handshake.io;
uint8_t compression_method;
@@ -232,7 +233,7 @@ static int s2n_server_hello_parse(struct s2n_connection *conn)
if (session_ids_match) {
/* 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);
+ 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;
@@ -296,6 +297,7 @@ int s2n_server_hello_recv(struct s2n_connection *conn)
int s2n_server_hello_write_message(struct s2n_connection *conn)
{
POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
/* 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.
@@ -309,7 +311,7 @@ int s2n_server_hello_write_message(struct s2n_connection *conn)
POSIX_GUARD(s2n_stuffer_write_bytes(&conn->handshake.io, conn->handshake_params.server_random, S2N_TLS_RANDOM_DATA_LEN));
POSIX_GUARD(s2n_stuffer_write_uint8(&conn->handshake.io, conn->session_id_len));
POSIX_GUARD(s2n_stuffer_write_bytes(&conn->handshake.io, conn->session_id, conn->session_id_len));
- POSIX_GUARD(s2n_stuffer_write_bytes(&conn->handshake.io, conn->secure.cipher_suite->iana_value, S2N_TLS_CIPHER_SUITE_LEN));
+ POSIX_GUARD(s2n_stuffer_write_bytes(&conn->handshake.io, conn->secure->cipher_suite->iana_value, S2N_TLS_CIPHER_SUITE_LEN));
POSIX_GUARD(s2n_stuffer_write_uint8(&conn->handshake.io, S2N_TLS_COMPRESSION_METHOD_NULL));
return 0;
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 0d3f05b2c9..dc87d4184e 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_server_key_exchange.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_server_key_exchange.c
@@ -39,12 +39,13 @@ static int s2n_server_key_send_write_signature(struct s2n_connection *conn, stru
int s2n_server_key_recv(struct s2n_connection *conn)
{
POSIX_ENSURE_REF(conn);
- POSIX_ENSURE_REF(conn->secure.cipher_suite);
- POSIX_ENSURE_REF(conn->secure.cipher_suite->key_exchange_alg);
+ POSIX_ENSURE_REF(conn->secure);
+ POSIX_ENSURE_REF(conn->secure->cipher_suite);
+ POSIX_ENSURE_REF(conn->secure->cipher_suite->key_exchange_alg);
POSIX_ENSURE_REF(conn->handshake.hashes);
struct s2n_hash_state *signature_hash = &conn->handshake.hashes->hash_workspace;
- const struct s2n_kex *key_exchange = conn->secure.cipher_suite->key_exchange_alg;
+ 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};
@@ -183,6 +184,9 @@ int s2n_kem_server_key_recv_read_data(struct s2n_connection *conn, struct s2n_bl
int s2n_kem_server_key_recv_parse_data(struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data)
{
+ POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
+
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 */
@@ -190,7 +194,7 @@ int s2n_kem_server_key_recv_parse_data(struct s2n_connection *conn, struct s2n_k
POSIX_GUARD(s2n_connection_get_kem_preferences(conn, &kem_preferences));
POSIX_ENSURE_REF(kem_preferences);
- const struct s2n_cipher_suite *cipher_suite = conn->secure.cipher_suite;
+ 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);
@@ -204,8 +208,9 @@ int s2n_kem_server_key_recv_parse_data(struct s2n_connection *conn, struct s2n_k
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)
{
POSIX_ENSURE_REF(conn);
- POSIX_ENSURE_REF(conn->secure.cipher_suite);
- const struct s2n_kex *kex = conn->secure.cipher_suite->key_exchange_alg;
+ POSIX_ENSURE_REF(conn->secure);
+ POSIX_ENSURE_REF(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];
@@ -226,8 +231,9 @@ int s2n_hybrid_server_key_recv_read_data(struct s2n_connection *conn, struct s2n
int s2n_hybrid_server_key_recv_parse_data(struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data)
{
POSIX_ENSURE_REF(conn);
- POSIX_ENSURE_REF(conn->secure.cipher_suite);
- const struct s2n_kex *kex = conn->secure.cipher_suite->key_exchange_alg;
+ POSIX_ENSURE_REF(conn->secure);
+ POSIX_ENSURE_REF(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];
@@ -244,7 +250,7 @@ int s2n_server_key_send(struct s2n_connection *conn)
S2N_ASYNC_PKEY_GUARD(conn);
struct s2n_hash_state *signature_hash = &conn->handshake.hashes->hash_workspace;
- const struct s2n_kex *key_exchange = conn->secure.cipher_suite->key_exchange_alg;
+ 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};
@@ -318,8 +324,9 @@ int s2n_kem_server_key_send(struct s2n_connection *conn, struct s2n_blob *data_t
int s2n_hybrid_server_key_send(struct s2n_connection *conn, struct s2n_blob *total_data_to_sign)
{
POSIX_ENSURE_REF(conn);
- POSIX_ENSURE_REF(conn->secure.cipher_suite);
- const struct s2n_kex *kex = conn->secure.cipher_suite->key_exchange_alg;
+ POSIX_ENSURE_REF(conn->secure);
+ POSIX_ENSURE_REF(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];
diff --git a/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.c b/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.c
index f7775ccee8..3158c0df92 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.c
@@ -75,11 +75,12 @@ static int s2n_choose_sig_scheme(struct s2n_connection *conn, struct s2n_sig_sch
struct s2n_signature_scheme *chosen_scheme_out)
{
POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
const struct s2n_signature_preferences *signature_preferences = NULL;
POSIX_GUARD(s2n_connection_get_signature_preferences(conn, &signature_preferences));
POSIX_ENSURE_REF(signature_preferences);
- struct s2n_cipher_suite *cipher_suite = conn->secure.cipher_suite;
+ struct s2n_cipher_suite *cipher_suite = conn->secure->cipher_suite;
POSIX_ENSURE_REF(cipher_suite);
for (size_t i = 0; i < signature_preferences->count; i++) {
@@ -107,11 +108,13 @@ static int s2n_choose_sig_scheme(struct s2n_connection *conn, struct s2n_sig_sch
int s2n_tls13_default_sig_scheme(struct s2n_connection *conn, struct s2n_signature_scheme *chosen_scheme_out)
{
POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
+
const struct s2n_signature_preferences *signature_preferences = NULL;
POSIX_GUARD(s2n_connection_get_signature_preferences(conn, &signature_preferences));
POSIX_ENSURE_REF(signature_preferences);
- struct s2n_cipher_suite *cipher_suite = conn->secure.cipher_suite;
+ struct s2n_cipher_suite *cipher_suite = conn->secure->cipher_suite;
POSIX_ENSURE_REF(cipher_suite);
for (size_t i = 0; i < signature_preferences->count; i++) {
@@ -171,14 +174,15 @@ int s2n_get_and_validate_negotiated_signature_scheme(struct s2n_connection *conn
int s2n_choose_default_sig_scheme(struct s2n_connection *conn, struct s2n_signature_scheme *sig_scheme_out, s2n_mode signer)
{
POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
POSIX_ENSURE_REF(sig_scheme_out);
s2n_authentication_method auth_method = 0;
if (signer == S2N_CLIENT) {
POSIX_GUARD(s2n_get_auth_method_for_cert_type(conn->handshake_params.client_cert_pkey_type, &auth_method));
} else {
- POSIX_ENSURE_REF(conn->secure.cipher_suite);
- auth_method = conn->secure.cipher_suite->auth_method;
+ POSIX_ENSURE_REF(conn->secure->cipher_suite);
+ auth_method = conn->secure->cipher_suite->auth_method;
}
/* Default our signature digest algorithms.
diff --git a/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.c b/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.c
index 2ccc0fd651..e986013be5 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.c
@@ -377,3 +377,52 @@ const struct s2n_signature_preferences s2n_signature_preferences_20210816 = {
.count = s2n_array_len(s2n_sig_scheme_pref_list_20210816),
.signature_schemes = s2n_sig_scheme_pref_list_20210816
};
+
+const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_rfc9151[] = {
+ /* ECDSA - TLS 1.3 */
+ &s2n_ecdsa_secp384r1_sha384,
+
+ /* RSA PSS - TLS 1.3 */
+ &s2n_rsa_pss_pss_sha384,
+
+ /* ECDSA - TLS 1.2 */
+ &s2n_ecdsa_sha384, /* same iana value as TLS 1.3 s2n_ecdsa_secp384r1_sha384 */
+
+ /* RSA */
+ &s2n_rsa_pss_rsae_sha384,
+
+ &s2n_rsa_pkcs1_sha384,
+};
+
+const struct s2n_signature_scheme* const s2n_cert_sig_scheme_pref_list_rfc9151[] = {
+ /* ECDSA - TLS 1.3 */
+ &s2n_ecdsa_secp384r1_sha384,
+
+ /* RSA PSS
+ * https://github.com/aws/s2n-tls/issues/3435
+ *
+ * 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.
+ *
+ * Since only sha384 is allowed by rfc9151, this certificate signing policy does not
+ * support rsa_pss.
+ */
+
+ /* ECDSA - TLS 1.2 */
+ &s2n_ecdsa_sha384, /* same iana value as TLS 1.3 s2n_ecdsa_secp384r1_sha384 */
+
+ /* RSA */
+ &s2n_rsa_pkcs1_sha384,
+};
+
+
+const struct s2n_signature_preferences s2n_signature_preferences_rfc9151 = {
+ .count = s2n_array_len(s2n_sig_scheme_pref_list_rfc9151),
+ .signature_schemes = s2n_sig_scheme_pref_list_rfc9151
+};
+
+const struct s2n_signature_preferences s2n_certificate_signature_preferences_rfc9151 = {
+ .count = s2n_array_len(s2n_cert_sig_scheme_pref_list_rfc9151),
+ .signature_schemes = s2n_cert_sig_scheme_pref_list_rfc9151
+};
diff --git a/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.h b/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.h
index d8eee975ab..a3259804fe 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.h
@@ -77,6 +77,8 @@ extern const struct s2n_signature_preferences s2n_signature_preferences_20140601
extern const struct s2n_signature_preferences s2n_signature_preferences_20200207;
extern const struct s2n_signature_preferences s2n_signature_preferences_20201021;
extern const struct s2n_signature_preferences s2n_signature_preferences_20210816;
+extern const struct s2n_signature_preferences s2n_signature_preferences_rfc9151;
+extern const struct s2n_signature_preferences s2n_certificate_signature_preferences_rfc9151;
extern const struct s2n_signature_preferences s2n_signature_preferences_default_fips;
extern const struct s2n_signature_preferences s2n_signature_preferences_null;
diff --git a/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.c b/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.c
index e5b2bd3202..91729d3a1e 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.c
@@ -21,11 +21,12 @@
static int s2n_zero_sequence_number(struct s2n_connection *conn, s2n_mode mode)
{
POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
struct s2n_blob sequence_number;
if (mode == S2N_CLIENT) {
- POSIX_GUARD(s2n_blob_init(&sequence_number, conn->secure.client_sequence_number, sizeof(conn->secure.client_sequence_number)));
+ POSIX_GUARD(s2n_blob_init(&sequence_number, conn->secure->client_sequence_number, sizeof(conn->secure->client_sequence_number)));
} else {
- POSIX_GUARD(s2n_blob_init(&sequence_number, conn->secure.server_sequence_number, sizeof(conn->secure.server_sequence_number)));
+ POSIX_GUARD(s2n_blob_init(&sequence_number, conn->secure->server_sequence_number, sizeof(conn->secure->server_sequence_number)));
}
POSIX_GUARD(s2n_blob_zero(&sequence_number));
return S2N_SUCCESS;
@@ -43,7 +44,7 @@ int s2n_tls13_mac_verify(struct s2n_tls13_keys *keys, struct s2n_blob *finished_
int s2n_tls13_keys_from_conn(struct s2n_tls13_keys *keys, struct s2n_connection *conn)
{
- POSIX_GUARD(s2n_tls13_keys_init(keys, conn->secure.cipher_suite->prf_alg));
+ POSIX_GUARD(s2n_tls13_keys_init(keys, conn->secure->cipher_suite->prf_alg));
return S2N_SUCCESS;
}
@@ -152,6 +153,7 @@ int s2n_tls13_compute_shared_secret(struct s2n_connection *conn, struct s2n_blob
int s2n_update_application_traffic_keys(struct s2n_connection *conn, s2n_mode mode, keyupdate_status status)
{
POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE_REF(conn->secure);
/* get tls13 key context */
s2n_tls13_connection_keys(keys, conn);
@@ -161,13 +163,13 @@ int s2n_update_application_traffic_keys(struct s2n_connection *conn, s2n_mode mo
struct s2n_blob app_iv;
if (mode == S2N_CLIENT) {
- old_key = &conn->secure.client_key;
+ old_key = &conn->secure->client_key;
POSIX_GUARD(s2n_blob_init(&old_app_secret, conn->secrets.tls13.client_app_secret, keys.size));
- POSIX_GUARD(s2n_blob_init(&app_iv, conn->secure.client_implicit_iv, S2N_TLS13_FIXED_IV_LEN));
+ POSIX_GUARD(s2n_blob_init(&app_iv, conn->secure->client_implicit_iv, S2N_TLS13_FIXED_IV_LEN));
} else {
- old_key = &conn->secure.server_key;
+ old_key = &conn->secure->server_key;
POSIX_GUARD(s2n_blob_init(&old_app_secret, conn->secrets.tls13.server_app_secret, keys.size));
- POSIX_GUARD(s2n_blob_init(&app_iv, conn->secure.server_implicit_iv, S2N_TLS13_FIXED_IV_LEN));
+ POSIX_GUARD(s2n_blob_init(&app_iv, conn->secure->server_implicit_iv, S2N_TLS13_FIXED_IV_LEN));
}
/* Produce new application secret */
@@ -176,14 +178,14 @@ int s2n_update_application_traffic_keys(struct s2n_connection *conn, s2n_mode mo
/* Derives next generation of traffic secret */
POSIX_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);
+ s2n_tls13_key_blob(app_key, conn->secure->cipher_suite->record_alg->cipher->key_material_size);
/* Derives next generation of traffic key */
POSIX_GUARD(s2n_tls13_derive_traffic_keys(&keys, &app_secret_update, &app_key, &app_iv));
if (status == RECEIVING) {
- POSIX_GUARD(conn->secure.cipher_suite->record_alg->cipher->set_decryption_key(old_key, &app_key));
+ POSIX_GUARD(conn->secure->cipher_suite->record_alg->cipher->set_decryption_key(old_key, &app_key));
} else {
- POSIX_GUARD(conn->secure.cipher_suite->record_alg->cipher->set_encryption_key(old_key, &app_key));
+ POSIX_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:
diff --git a/contrib/restricted/aws/s2n/tls/s2n_tls13_key_schedule.c b/contrib/restricted/aws/s2n/tls/s2n_tls13_key_schedule.c
index 16fd78c042..dbf7608ffe 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_tls13_key_schedule.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_tls13_key_schedule.c
@@ -34,13 +34,14 @@ static const struct s2n_blob s2n_zero_length_context = { 0 };
static S2N_RESULT s2n_zero_sequence_number(struct s2n_connection *conn, s2n_mode mode)
{
RESULT_ENSURE_REF(conn);
+ RESULT_ENSURE_REF(conn->secure);
struct s2n_blob sequence_number;
if (mode == S2N_CLIENT) {
RESULT_GUARD_POSIX(s2n_blob_init(&sequence_number,
- conn->secure.client_sequence_number, sizeof(conn->secure.client_sequence_number)));
+ conn->secure->client_sequence_number, sizeof(conn->secure->client_sequence_number)));
} else {
RESULT_GUARD_POSIX(s2n_blob_init(&sequence_number,
- conn->secure.server_sequence_number, sizeof(conn->secure.server_sequence_number)));
+ conn->secure->server_sequence_number, sizeof(conn->secure->server_sequence_number)));
}
RESULT_GUARD_POSIX(s2n_blob_zero(&sequence_number));
return S2N_RESULT_OK;
@@ -49,22 +50,23 @@ static S2N_RESULT s2n_zero_sequence_number(struct s2n_connection *conn, s2n_mode
static S2N_RESULT s2n_set_key(struct s2n_connection *conn, s2n_extract_secret_type_t secret_type, s2n_mode mode)
{
RESULT_ENSURE_REF(conn);
- RESULT_ENSURE_REF(conn->secure.cipher_suite);
- const struct s2n_cipher_suite *cipher_suite = conn->secure.cipher_suite;
- RESULT_ENSURE_REF(conn->secure.cipher_suite->record_alg);
- RESULT_ENSURE_REF(conn->secure.cipher_suite->record_alg->cipher);
- const struct s2n_cipher *cipher = conn->secure.cipher_suite->record_alg->cipher;
+ RESULT_ENSURE_REF(conn->secure);
+ RESULT_ENSURE_REF(conn->secure->cipher_suite);
+ const struct s2n_cipher_suite *cipher_suite = conn->secure->cipher_suite;
+ RESULT_ENSURE_REF(conn->secure->cipher_suite->record_alg);
+ RESULT_ENSURE_REF(conn->secure->cipher_suite->record_alg->cipher);
+ const struct s2n_cipher *cipher = conn->secure->cipher_suite->record_alg->cipher;
uint8_t *implicit_iv_data = NULL;
struct s2n_session_key *session_key = NULL;
if (mode == S2N_CLIENT) {
- implicit_iv_data = conn->secure.client_implicit_iv;
- session_key = &conn->secure.client_key;
- conn->client = &conn->secure;
+ implicit_iv_data = conn->secure->client_implicit_iv;
+ session_key = &conn->secure->client_key;
+ conn->client = conn->secure;
} else {
- implicit_iv_data = conn->secure.server_implicit_iv;
- session_key = &conn->secure.server_key;
- conn->server = &conn->secure;
+ implicit_iv_data = conn->secure->server_implicit_iv;
+ session_key = &conn->secure->server_key;
+ conn->server = conn->secure;
}
/**
@@ -321,8 +323,9 @@ S2N_RESULT s2n_tls13_key_schedule_update(struct s2n_connection *conn)
S2N_RESULT s2n_tls13_key_schedule_reset(struct s2n_connection *conn)
{
RESULT_ENSURE_REF(conn);
- conn->client = &conn->initial;
- conn->server = &conn->initial;
+ RESULT_ENSURE_REF(conn->initial);
+ conn->client = conn->initial;
+ conn->server = conn->initial;
conn->secrets.tls13.extract_secret_type = S2N_NONE_SECRET;
return S2N_RESULT_OK;
}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_tls13_secrets.c b/contrib/restricted/aws/s2n/tls/s2n_tls13_secrets.c
index 9bbe24ec84..103590c122 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_tls13_secrets.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_tls13_secrets.c
@@ -22,7 +22,7 @@
#define S2N_MAX_HASHLEN SHA384_DIGEST_LENGTH
-#define CONN_HMAC_ALG(conn) ((conn)->secure.cipher_suite->prf_alg)
+#define CONN_HMAC_ALG(conn) ((conn)->secure->cipher_suite->prf_alg)
#define CONN_SECRETS(conn) ((conn)->secrets.tls13)
#define CONN_HASHES(conn) ((conn)->handshake.hashes)
@@ -103,11 +103,12 @@ S2N_RESULT s2n_tls13_empty_transcripts_init()
static S2N_RESULT s2n_calculate_transcript_digest(struct s2n_connection *conn)
{
RESULT_ENSURE_REF(conn);
+ RESULT_ENSURE_REF(conn->secure);
+ RESULT_ENSURE_REF(conn->secure->cipher_suite);
RESULT_ENSURE_REF(conn->handshake.hashes);
s2n_hash_algorithm hash_algorithm = S2N_HASH_NONE;
- RESULT_ENSURE_REF(conn->secure.cipher_suite);
- RESULT_GUARD_POSIX(s2n_hmac_hash_alg(conn->secure.cipher_suite->prf_alg, &hash_algorithm));
+ RESULT_GUARD_POSIX(s2n_hmac_hash_alg(conn->secure->cipher_suite->prf_alg, &hash_algorithm));
uint8_t digest_size = 0;
RESULT_GUARD_POSIX(s2n_hash_digest_size(hash_algorithm, &digest_size));
@@ -494,7 +495,8 @@ static s2n_result (*extract_methods[])(struct s2n_connection *conn) = {
S2N_RESULT s2n_tls13_extract_secret(struct s2n_connection *conn, s2n_extract_secret_type_t secret_type)
{
RESULT_ENSURE_REF(conn);
- RESULT_ENSURE_REF(conn->secure.cipher_suite);
+ RESULT_ENSURE_REF(conn->secure);
+ RESULT_ENSURE_REF(conn->secure->cipher_suite);
RESULT_ENSURE_REF(conn->handshake.hashes);
RESULT_ENSURE_NE(secret_type, S2N_NONE_SECRET);
@@ -522,7 +524,8 @@ S2N_RESULT s2n_tls13_derive_secret(struct s2n_connection *conn, s2n_extract_secr
{
RESULT_ENSURE_REF(conn);
RESULT_ENSURE_REF(secret);
- RESULT_ENSURE_REF(conn->secure.cipher_suite);
+ RESULT_ENSURE_REF(conn->secure);
+ RESULT_ENSURE_REF(conn->secure->cipher_suite);
RESULT_ENSURE_REF(conn->handshake.hashes);
RESULT_ENSURE_NE(secret_type, S2N_NONE_SECRET);
@@ -567,7 +570,8 @@ S2N_RESULT s2n_tls13_secrets_update(struct s2n_connection *conn)
if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
return S2N_RESULT_OK;
}
- RESULT_ENSURE_REF(conn->secure.cipher_suite);
+ RESULT_ENSURE_REF(conn->secure);
+ RESULT_ENSURE_REF(conn->secure->cipher_suite);
message_type_t message_type = s2n_conn_get_current_message_type(conn);
switch(message_type) {
diff --git a/contrib/restricted/aws/s2n/utils/s2n_init.c b/contrib/restricted/aws/s2n/utils/s2n_init.c
index 2b3d78fefd..1195b3b450 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_init.c
+++ b/contrib/restricted/aws/s2n/utils/s2n_init.c
@@ -58,6 +58,7 @@ int s2n_init(void)
POSIX_GUARD(s2n_mem_init());
/* Must run before any init method that calls libcrypto methods. */
POSIX_GUARD_RESULT(s2n_locking_init());
+ POSIX_GUARD_RESULT(s2n_libcrypto_init());
POSIX_GUARD(s2n_fips_init());
POSIX_GUARD_RESULT(s2n_rand_init());
POSIX_GUARD(s2n_cipher_suites_init());
@@ -88,10 +89,11 @@ static bool s2n_cleanup_atexit_impl(void)
/* the configs need to be wiped before resetting the memory callbacks */
s2n_wipe_static_configs();
- return s2n_result_is_ok(s2n_rand_cleanup_thread()) &&
- s2n_result_is_ok(s2n_rand_cleanup()) &&
- s2n_result_is_ok(s2n_locking_cleanup()) &&
- (s2n_mem_cleanup() == S2N_SUCCESS);
+ return s2n_result_is_ok(s2n_libcrypto_cleanup()) &&
+ s2n_result_is_ok(s2n_rand_cleanup_thread()) &&
+ s2n_result_is_ok(s2n_rand_cleanup()) &&
+ s2n_result_is_ok(s2n_locking_cleanup()) &&
+ (s2n_mem_cleanup() == S2N_SUCCESS);
}
int s2n_cleanup(void)
diff --git a/contrib/restricted/aws/s2n/utils/s2n_mem.c b/contrib/restricted/aws/s2n/utils/s2n_mem.c
index fcb848fec4..4d88a52bcc 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_mem.c
+++ b/contrib/restricted/aws/s2n/utils/s2n_mem.c
@@ -218,7 +218,7 @@ int s2n_free_object(uint8_t **p_data, uint32_t size)
if (*p_data == NULL) {
return S2N_SUCCESS;
}
-
+
POSIX_ENSURE(initialized, S2N_ERR_NOT_INITIALIZED);
struct s2n_blob b = {.data = *p_data, .allocated = size, .size = size, .growable = 1};
@@ -275,11 +275,16 @@ int s2n_mem_cleanup(void)
int s2n_free(struct s2n_blob *b)
{
- POSIX_PRECONDITION(s2n_blob_validate(b));
-
/* To avoid memory leaks, don't exit the function until the memory
has been freed */
int zero_rc = s2n_blob_zero(b);
+ POSIX_GUARD(s2n_free_without_wipe(b));
+ return zero_rc;
+}
+
+int s2n_free_without_wipe(struct s2n_blob *b)
+{
+ POSIX_PRECONDITION(s2n_blob_validate(b));
POSIX_ENSURE(initialized, S2N_ERR_NOT_INITIALIZED);
POSIX_ENSURE(s2n_blob_is_growable(b), S2N_ERR_FREE_STATIC_BLOB);
@@ -288,8 +293,6 @@ int s2n_free(struct s2n_blob *b)
*b = (struct s2n_blob) {0};
- POSIX_GUARD(zero_rc);
-
return S2N_SUCCESS;
}
diff --git a/contrib/restricted/aws/s2n/utils/s2n_mem.h b/contrib/restricted/aws/s2n/utils/s2n_mem.h
index 78d600db32..4c0fb76822 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_mem.h
+++ b/contrib/restricted/aws/s2n/utils/s2n_mem.h
@@ -26,6 +26,7 @@ int s2n_mem_cleanup(void);
int s2n_alloc(struct s2n_blob *b, uint32_t size);
int s2n_realloc(struct s2n_blob *b, uint32_t size);
int s2n_free(struct s2n_blob *b);
+int s2n_free_without_wipe(struct s2n_blob *b);
int s2n_blob_zeroize_free(struct s2n_blob *b);
int s2n_free_object(uint8_t **p_data, uint32_t size);
int s2n_dup(struct s2n_blob *from, struct s2n_blob *to);