From 131f3f2372a8d79be1d4b69b0f852b9f1370390d Mon Sep 17 00:00:00 2001 From: Akshat Sinha Date: Thu, 16 Oct 2025 21:21:27 +0530 Subject: [PATCH 1/3] fix: add const correctness to S2N_BLOB_LABEL macro The S2N_BLOB_LABEL macro creates const blob structures but the underlying data array was not marked const, breaking const-correctness. This allows the data to be modified even though the blob is const. Changes: - Mark the data array as const in S2N_BLOB_LABEL macro - Add explicit cast to maintain compatibility with non-const data pointer This ensures that blobs created with S2N_BLOB_LABEL have truly immutable data, preventing accidental modifications to what should be constant string literals used throughout the TLS 1.3 implementation. File changed: - utils/s2n_blob.h (line 72-75: added const to data array) --- utils/s2n_blob.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/s2n_blob.h b/utils/s2n_blob.h index 8e40bb600fa..bd64210a856 100644 --- a/utils/s2n_blob.h +++ b/utils/s2n_blob.h @@ -69,6 +69,6 @@ int S2N_RESULT_MUST_USE s2n_blob_slice(const struct s2n_blob *b, struct s2n_blob struct s2n_blob name = { 0 }; \ RESULT_GUARD_POSIX(s2n_blob_init(&name, name##_buf, name##_requested_size)) -#define S2N_BLOB_LABEL(name, str) \ - static uint8_t name##_data[] = str; \ - const struct s2n_blob name = { .data = name##_data, .size = sizeof(name##_data) - 1 }; +#define S2N_BLOB_LABEL(name, str) \ + static const uint8_t name##_data[] = str; \ + const struct s2n_blob name = { .data = (uint8_t *) name##_data, .size = sizeof(name##_data) - 1 }; From 92e05eb9aeab7629287dc614d6f7878554c40ad4 Mon Sep 17 00:00:00 2001 From: Akshat Sinha Date: Fri, 24 Oct 2025 11:33:09 +0530 Subject: [PATCH 2/3] fix: use union to cast away const --- utils/s2n_blob.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/utils/s2n_blob.h b/utils/s2n_blob.h index bd64210a856..d53203dfcfe 100644 --- a/utils/s2n_blob.h +++ b/utils/s2n_blob.h @@ -69,6 +69,10 @@ int S2N_RESULT_MUST_USE s2n_blob_slice(const struct s2n_blob *b, struct s2n_blob struct s2n_blob name = { 0 }; \ RESULT_GUARD_POSIX(s2n_blob_init(&name, name##_buf, name##_requested_size)) -#define S2N_BLOB_LABEL(name, str) \ - static const uint8_t name##_data[] = str; \ - const struct s2n_blob name = { .data = (uint8_t *) name##_data, .size = sizeof(name##_data) - 1 }; +#define S2N_BLOB_LABEL(name, str) \ + static const uint8_t name##_data[] = str; \ + static union{ \ + const uint8_t *const_ptr; \ + uint8_t *ptr; \ + } name##_union = { .const_ptr = name##_data }; \ + const struct s2n_blob name = { .data = name##_union.ptr, .size = sizeof(name##_data) - 1 }; From 0d048d68939d529cc14a92c7c4924fe1f331cc4f Mon Sep 17 00:00:00 2001 From: Akshat Sinha Date: Sun, 9 Nov 2025 13:59:19 +0530 Subject: [PATCH 3/3] tls13: added read-only blob API and migrated TLS 1.3 labels I) Introduced struct s2n_ro_blob and S2N_RO_BLOB_LABEL. II) Added s2n_hkdf_expand_label_ro for const labels. III) Migrated TLS 1.3 static labels and call sites to the RO path. IV) Kept S2N_BLOB_LABEL for mutable use cases. Signed-off-by: Akshat Sinha --- crypto/s2n_hkdf.c | 27 +++++++++++++ crypto/s2n_hkdf.h | 4 ++ crypto/s2n_tls13_keys.c | 44 ++++++++++----------- crypto/s2n_tls13_keys.h | 32 ++++++++-------- tests/unit/s2n_tls13_prf_test.c | 4 +- tests/unit/s2n_tls13_record_aead_test.c | 2 +- tls/s2n_tls13_key_schedule.c | 8 ++-- tls/s2n_tls13_secrets.c | 51 +++++++++++++++---------- utils/s2n_blob.h | 22 +++++++---- 9 files changed, 121 insertions(+), 73 deletions(-) diff --git a/crypto/s2n_hkdf.c b/crypto/s2n_hkdf.c index b70a9826b57..a786bee90af 100644 --- a/crypto/s2n_hkdf.c +++ b/crypto/s2n_hkdf.c @@ -376,6 +376,33 @@ int s2n_hkdf_expand_label(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, c return S2N_SUCCESS; } +int s2n_hkdf_expand_label_ro(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s2n_blob *secret, const struct s2n_ro_blob *label, + const struct s2n_blob *context, struct s2n_blob *output) +{ + POSIX_ENSURE_REF(label); + POSIX_ENSURE_REF(context); + POSIX_ENSURE_REF(output); + + uint8_t hkdf_label_buf[2 + 256 + 256]; + struct s2n_blob hkdf_label_blob = { 0 }; + struct s2n_stuffer hkdf_label = { 0 }; + + POSIX_ENSURE_LTE(label->size, S2N_MAX_HKDF_EXPAND_LABEL_LENGTH); + + POSIX_GUARD(s2n_blob_init(&hkdf_label_blob, hkdf_label_buf, sizeof(hkdf_label_buf))); + POSIX_GUARD(s2n_stuffer_init(&hkdf_label, &hkdf_label_blob)); + POSIX_GUARD(s2n_stuffer_write_uint16(&hkdf_label, output->size)); + POSIX_GUARD(s2n_stuffer_write_uint8(&hkdf_label, label->size+sizeof("tls13 ") - 1)); + POSIX_GUARD(s2n_stuffer_write_str(&hkdf_label, "tls13 ")); + POSIX_GUARD(s2n_stuffer_write_bytes(&hkdf_label, label->data,label->size)); + POSIX_GUARD(s2n_stuffer_write_uint8(&hkdf_label, context->size)); + POSIX_GUARD(s2n_stuffer_write(&hkdf_label, context)); + hkdf_label_blob.size = s2n_stuffer_data_available(&hkdf_label); + POSIX_GUARD(s2n_hkdf_expand(hmac, alg, secret, &hkdf_label_blob, output)); + + return S2N_SUCCESS; +} + int s2n_hkdf(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s2n_blob *salt, const struct s2n_blob *key, const struct s2n_blob *info, struct s2n_blob *output) { diff --git a/crypto/s2n_hkdf.h b/crypto/s2n_hkdf.h index 8dc53636e77..ea3a24c7fb1 100644 --- a/crypto/s2n_hkdf.h +++ b/crypto/s2n_hkdf.h @@ -39,4 +39,8 @@ int s2n_hkdf_extract(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const int s2n_hkdf_expand_label(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s2n_blob *secret, const struct s2n_blob *label, const struct s2n_blob *context, struct s2n_blob *output); +/* Read-only label variant to avoid non-const data pointers */ +int s2n_hkdf_expand_label_ro(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s2n_blob *secret, const struct s2n_ro_blob *label, + const struct s2n_blob *context, struct s2n_blob *output); + bool s2n_libcrypto_supports_hkdf(); diff --git a/crypto/s2n_tls13_keys.c b/crypto/s2n_tls13_keys.c index 91d7aae5e00..2bae24ae471 100644 --- a/crypto/s2n_tls13_keys.c +++ b/crypto/s2n_tls13_keys.c @@ -55,44 +55,44 @@ * Define TLS 1.3 HKDF labels as specified in * https://tools.ietf.org/html/rfc8446#section-7.1 */ -S2N_BLOB_LABEL(s2n_tls13_label_derived_secret, "derived") +S2N_RO_BLOB_LABEL(s2n_tls13_label_derived_secret, "derived") -S2N_BLOB_LABEL(s2n_tls13_label_external_psk_binder_key, "ext binder") -S2N_BLOB_LABEL(s2n_tls13_label_resumption_psk_binder_key, "res binder") +S2N_RO_BLOB_LABEL(s2n_tls13_label_external_psk_binder_key, "ext binder") +S2N_RO_BLOB_LABEL(s2n_tls13_label_resumption_psk_binder_key, "res binder") -S2N_BLOB_LABEL(s2n_tls13_label_client_early_traffic_secret, "c e traffic") -S2N_BLOB_LABEL(s2n_tls13_label_early_exporter_master_secret, "e exp master") +S2N_RO_BLOB_LABEL(s2n_tls13_label_client_early_traffic_secret, "c e traffic") +S2N_RO_BLOB_LABEL(s2n_tls13_label_early_exporter_master_secret, "e exp master") -S2N_BLOB_LABEL(s2n_tls13_label_client_handshake_traffic_secret, "c hs traffic") -S2N_BLOB_LABEL(s2n_tls13_label_server_handshake_traffic_secret, "s hs traffic") +S2N_RO_BLOB_LABEL(s2n_tls13_label_client_handshake_traffic_secret, "c hs traffic") +S2N_RO_BLOB_LABEL(s2n_tls13_label_server_handshake_traffic_secret, "s hs traffic") -S2N_BLOB_LABEL(s2n_tls13_label_client_application_traffic_secret, "c ap traffic") -S2N_BLOB_LABEL(s2n_tls13_label_server_application_traffic_secret, "s ap traffic") +S2N_RO_BLOB_LABEL(s2n_tls13_label_client_application_traffic_secret, "c ap traffic") +S2N_RO_BLOB_LABEL(s2n_tls13_label_server_application_traffic_secret, "s ap traffic") -S2N_BLOB_LABEL(s2n_tls13_label_exporter_master_secret, "exp master") -S2N_BLOB_LABEL(s2n_tls13_label_resumption_master_secret, "res master") -S2N_BLOB_LABEL(s2n_tls13_label_session_ticket_secret, "resumption") +S2N_RO_BLOB_LABEL(s2n_tls13_label_exporter_master_secret, "exp master") +S2N_RO_BLOB_LABEL(s2n_tls13_label_resumption_master_secret, "res master") +S2N_RO_BLOB_LABEL(s2n_tls13_label_session_ticket_secret, "resumption") /* * Traffic secret labels */ -S2N_BLOB_LABEL(s2n_tls13_label_traffic_secret_key, "key") -S2N_BLOB_LABEL(s2n_tls13_label_traffic_secret_iv, "iv") +S2N_RO_BLOB_LABEL(s2n_tls13_label_traffic_secret_key, "key") +S2N_RO_BLOB_LABEL(s2n_tls13_label_traffic_secret_iv, "iv") /* * TLS 1.3 Exporter label */ -S2N_BLOB_LABEL(s2n_tls13_label_exporter, "exporter") +S2N_RO_BLOB_LABEL(s2n_tls13_label_exporter, "exporter") /* * TLS 1.3 Finished label */ -S2N_BLOB_LABEL(s2n_tls13_label_finished, "finished") +S2N_RO_BLOB_LABEL(s2n_tls13_label_finished, "finished") /* * TLS 1.3 KeyUpdate label */ -S2N_BLOB_LABEL(s2n_tls13_label_application_traffic_secret_update, "traffic upd") +S2N_RO_BLOB_LABEL(s2n_tls13_label_application_traffic_secret_update, "traffic upd") static const struct s2n_blob zero_length_blob = { .data = NULL, .size = 0 }; @@ -135,9 +135,9 @@ int s2n_tls13_derive_traffic_keys(struct s2n_tls13_keys *keys, struct s2n_blob * POSIX_ENSURE_REF(key); POSIX_ENSURE_REF(iv); - POSIX_GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, secret, +POSIX_GUARD(s2n_hkdf_expand_label_ro(&keys->hmac, keys->hmac_algorithm, secret, &s2n_tls13_label_traffic_secret_key, &zero_length_blob, key)); - POSIX_GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, secret, + POSIX_GUARD(s2n_hkdf_expand_label_ro(&keys->hmac, keys->hmac_algorithm, secret, &s2n_tls13_label_traffic_secret_iv, &zero_length_blob, iv)); return 0; } @@ -148,7 +148,7 @@ int s2n_tls13_derive_traffic_keys(struct s2n_tls13_keys *keys, struct s2n_blob * */ int s2n_tls13_derive_finished_key(struct s2n_tls13_keys *keys, struct s2n_blob *secret_key, struct s2n_blob *output_finish_key) { - POSIX_GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, secret_key, &s2n_tls13_label_finished, &zero_length_blob, output_finish_key)); +POSIX_GUARD(s2n_hkdf_expand_label_ro(&keys->hmac, keys->hmac_algorithm, secret_key, &s2n_tls13_label_finished, &zero_length_blob, output_finish_key)); return 0; } @@ -175,7 +175,7 @@ int s2n_tls13_update_application_traffic_secret(struct s2n_tls13_keys *keys, str POSIX_ENSURE_REF(old_secret); POSIX_ENSURE_REF(new_secret); - POSIX_GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, old_secret, +POSIX_GUARD(s2n_hkdf_expand_label_ro(&keys->hmac, keys->hmac_algorithm, old_secret, &s2n_tls13_label_application_traffic_secret_update, &zero_length_blob, new_secret)); return 0; @@ -190,7 +190,7 @@ S2N_RESULT s2n_tls13_derive_session_ticket_secret(struct s2n_tls13_keys *keys, s RESULT_ENSURE_REF(secret_blob); /* Derive session ticket secret from master session resumption secret */ - RESULT_GUARD_POSIX(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, resumption_secret, + RESULT_GUARD_POSIX(s2n_hkdf_expand_label_ro(&keys->hmac, keys->hmac_algorithm, resumption_secret, &s2n_tls13_label_session_ticket_secret, ticket_nonce, secret_blob)); return S2N_RESULT_OK; diff --git a/crypto/s2n_tls13_keys.h b/crypto/s2n_tls13_keys.h index ac96ceb51fe..6c937565531 100644 --- a/crypto/s2n_tls13_keys.h +++ b/crypto/s2n_tls13_keys.h @@ -51,31 +51,31 @@ struct s2n_tls13_keys { struct s2n_hmac_state hmac; }; -/* Defines TLS 1.3 HKDF Labels */ -extern const struct s2n_blob s2n_tls13_label_derived_secret; -extern const struct s2n_blob s2n_tls13_label_external_psk_binder_key; -extern const struct s2n_blob s2n_tls13_label_resumption_psk_binder_key; +/* Defines TLS 1.3 HKDF Labels (read-only) */ +extern const struct s2n_ro_blob s2n_tls13_label_derived_secret; +extern const struct s2n_ro_blob s2n_tls13_label_external_psk_binder_key; +extern const struct s2n_ro_blob s2n_tls13_label_resumption_psk_binder_key; -extern const struct s2n_blob s2n_tls13_label_client_early_traffic_secret; -extern const struct s2n_blob s2n_tls13_label_early_exporter_master_secret; +extern const struct s2n_ro_blob s2n_tls13_label_client_early_traffic_secret; +extern const struct s2n_ro_blob s2n_tls13_label_early_exporter_master_secret; -extern const struct s2n_blob s2n_tls13_label_client_handshake_traffic_secret; -extern const struct s2n_blob s2n_tls13_label_server_handshake_traffic_secret; +extern const struct s2n_ro_blob s2n_tls13_label_client_handshake_traffic_secret; +extern const struct s2n_ro_blob s2n_tls13_label_server_handshake_traffic_secret; -extern const struct s2n_blob s2n_tls13_label_client_application_traffic_secret; -extern const struct s2n_blob s2n_tls13_label_server_application_traffic_secret; +extern const struct s2n_ro_blob s2n_tls13_label_client_application_traffic_secret; +extern const struct s2n_ro_blob s2n_tls13_label_server_application_traffic_secret; -extern const struct s2n_blob s2n_tls13_label_exporter_master_secret; -extern const struct s2n_blob s2n_tls13_label_resumption_master_secret; +extern const struct s2n_ro_blob s2n_tls13_label_exporter_master_secret; +extern const struct s2n_ro_blob s2n_tls13_label_resumption_master_secret; -extern const struct s2n_blob s2n_tls13_label_finished; +extern const struct s2n_ro_blob s2n_tls13_label_finished; -extern const struct s2n_blob s2n_tls13_label_exporter; +extern const struct s2n_ro_blob s2n_tls13_label_exporter; /* Traffic secret labels */ -extern const struct s2n_blob s2n_tls13_label_traffic_secret_key; -extern const struct s2n_blob s2n_tls13_label_traffic_secret_iv; +extern const struct s2n_ro_blob s2n_tls13_label_traffic_secret_key; +extern const struct s2n_ro_blob s2n_tls13_label_traffic_secret_iv; #define s2n_tls13_key_blob(name, bytes) \ s2n_stack_blob(name, bytes, S2N_TLS13_SECRET_MAX_LEN) diff --git a/tests/unit/s2n_tls13_prf_test.c b/tests/unit/s2n_tls13_prf_test.c index 06de5d34ea7..711c183f3f2 100644 --- a/tests/unit/s2n_tls13_prf_test.c +++ b/tests/unit/s2n_tls13_prf_test.c @@ -127,12 +127,12 @@ int main(int argc, char **argv) EXPECT_EQUAL(memcmp(secret_buf, expected_secret_bytes, sizeof(secret_buf)), 0); /* Validate the derived secret */ - S2N_BLOB_LABEL(label, "derived"); +S2N_RO_BLOB_LABEL(label, "derived"); struct s2n_hmac_state hmac = { 0 }; EXPECT_SUCCESS(s2n_hmac_new(&hmac)); - EXPECT_SUCCESS(s2n_hkdf_expand_label(&hmac, S2N_HMAC_SHA256, &secret, &label, &digest, &output)); +EXPECT_SUCCESS(s2n_hkdf_expand_label_ro(&hmac, S2N_HMAC_SHA256, &secret, &label, &digest, &output)); EXPECT_EQUAL(memcmp(output_buf, expected_expanded_bytes, sizeof(output_buf)), 0); diff --git a/tests/unit/s2n_tls13_record_aead_test.c b/tests/unit/s2n_tls13_record_aead_test.c index afd1e9a24fd..f6b6760f5c7 100644 --- a/tests/unit/s2n_tls13_record_aead_test.c +++ b/tests/unit/s2n_tls13_record_aead_test.c @@ -292,7 +292,7 @@ int main(int argc, char **argv) } /* Test parsing of tls 1.3 aead record */ - S2N_BLOB_LABEL(expect_plaintext, "Hello world"); + S2N_RO_BLOB_LABEL(expect_plaintext, "Hello world"); static uint8_t hello_data[] = "Hello world"; struct s2n_blob plaintext = { 0 }; diff --git a/tls/s2n_tls13_key_schedule.c b/tls/s2n_tls13_key_schedule.c index b1691e7b133..c3cfd625b4e 100644 --- a/tls/s2n_tls13_key_schedule.c +++ b/tls/s2n_tls13_key_schedule.c @@ -75,8 +75,8 @@ static S2N_RESULT s2n_tls13_key_schedule_get_keying_material( *# *# - A purpose value indicating the specific value being generated **/ - const struct s2n_blob *key_purpose = &s2n_tls13_label_traffic_secret_key; - const struct s2n_blob *iv_purpose = &s2n_tls13_label_traffic_secret_iv; + const struct s2n_ro_blob *key_purpose = &s2n_tls13_label_traffic_secret_key; + const struct s2n_ro_blob *iv_purpose = &s2n_tls13_label_traffic_secret_iv; /** *= https://www.rfc-editor.org/rfc/rfc8446#section-7.3 @@ -105,7 +105,7 @@ static S2N_RESULT s2n_tls13_key_schedule_get_keying_material( **/ RESULT_ENSURE_LTE(key_size, key->size); key->size = key_size; - RESULT_GUARD_POSIX(s2n_hkdf_expand_label(&hmac, hmac_alg, +RESULT_GUARD_POSIX(s2n_hkdf_expand_label_ro(&hmac, hmac_alg, &secret, key_purpose, &s2n_zero_length_context, key)); /** *= https://www.rfc-editor.org/rfc/rfc8446#section-7.3 @@ -113,7 +113,7 @@ static S2N_RESULT s2n_tls13_key_schedule_get_keying_material( **/ RESULT_ENSURE_LTE(iv_size, iv->size); iv->size = iv_size; - RESULT_GUARD_POSIX(s2n_hkdf_expand_label(&hmac, hmac_alg, +RESULT_GUARD_POSIX(s2n_hkdf_expand_label_ro(&hmac, hmac_alg, &secret, iv_purpose, &s2n_zero_length_context, iv)); return S2N_RESULT_OK; diff --git a/tls/s2n_tls13_secrets.c b/tls/s2n_tls13_secrets.c index f3272977ba7..5dea6bd1be6 100644 --- a/tls/s2n_tls13_secrets.c +++ b/tls/s2n_tls13_secrets.c @@ -148,11 +148,7 @@ static S2N_RESULT s2n_derive_secret(s2n_hmac_algorithm hmac_alg, const struct s2n_blob *previous_secret_material, const struct s2n_blob *label, const struct s2n_blob *context, struct s2n_blob *output) { - /* - * TODO: We should be able to reuse the prf_work_space rather - * than allocating a new HMAC every time. - * https://github.com/aws/s2n-tls/issues/3206 - */ + /* keep blob-based variant for dynamic labels (e.g. exporter) */ DEFER_CLEANUP(struct s2n_hmac_state hmac_state = { 0 }, s2n_hmac_free); RESULT_GUARD_POSIX(s2n_hmac_new(&hmac_state)); @@ -162,8 +158,21 @@ static S2N_RESULT s2n_derive_secret(s2n_hmac_algorithm hmac_alg, return S2N_RESULT_OK; } +static S2N_RESULT s2n_derive_secret_ro(s2n_hmac_algorithm hmac_alg, + const struct s2n_blob *previous_secret_material, const struct s2n_ro_blob *label, const struct s2n_blob *context, + struct s2n_blob *output) +{ + DEFER_CLEANUP(struct s2n_hmac_state hmac_state = { 0 }, s2n_hmac_free); + RESULT_GUARD_POSIX(s2n_hmac_new(&hmac_state)); + + output->size = s2n_get_hash_len(hmac_alg); + RESULT_GUARD_POSIX(s2n_hkdf_expand_label_ro(&hmac_state, hmac_alg, + previous_secret_material, label, context, output)); + return S2N_RESULT_OK; +} + static S2N_RESULT s2n_derive_secret_with_context(struct s2n_connection *conn, - s2n_extract_secret_type_t input_secret_type, const struct s2n_blob *label, message_type_t transcript_end_msg, + s2n_extract_secret_type_t input_secret_type, const struct s2n_ro_blob *label, message_type_t transcript_end_msg, struct s2n_blob *output) { RESULT_ENSURE_REF(conn); @@ -172,7 +181,7 @@ static S2N_RESULT s2n_derive_secret_with_context(struct s2n_connection *conn, RESULT_ENSURE(conn->secrets.extract_secret_type == input_secret_type, S2N_ERR_SECRET_SCHEDULE_STATE); RESULT_ENSURE(s2n_conn_get_current_message_type(conn) == transcript_end_msg, S2N_ERR_SECRET_SCHEDULE_STATE); - RESULT_GUARD(s2n_derive_secret(CONN_HMAC_ALG(conn), &CONN_SECRET(conn, extract_secret), +RESULT_GUARD(s2n_derive_secret_ro(CONN_HMAC_ALG(conn), &CONN_SECRET(conn, extract_secret), label, &CONN_HASH(conn, transcript_hash_digest), output)); return S2N_RESULT_OK; } @@ -184,8 +193,8 @@ static S2N_RESULT s2n_derive_secret_without_context(struct s2n_connection *conn, RESULT_ENSURE_REF(output); RESULT_ENSURE(conn->secrets.extract_secret_type == input_secret_type, S2N_ERR_SECRET_SCHEDULE_STATE); - RESULT_GUARD(s2n_derive_secret(CONN_HMAC_ALG(conn), &CONN_SECRET(conn, extract_secret), - &s2n_tls13_label_derived_secret, &EMPTY_CONTEXT(CONN_HMAC_ALG(conn)), output)); + RESULT_GUARD(s2n_derive_secret_ro(CONN_HMAC_ALG(conn), &CONN_SECRET(conn, extract_secret), + &s2n_tls13_label_application_traffic_secret_update, &EMPTY_CONTEXT(CONN_HMAC_ALG(conn)), output)); return S2N_RESULT_OK; } @@ -214,7 +223,7 @@ static S2N_RESULT s2n_tls13_compute_finished_key(struct s2n_connection *conn, DEFER_CLEANUP(struct s2n_hmac_state hmac_state = { 0 }, s2n_hmac_free); RESULT_GUARD_POSIX(s2n_hmac_new(&hmac_state)); - RESULT_GUARD_POSIX(s2n_hkdf_expand_label(&hmac_state, CONN_HMAC_ALG(conn), +RESULT_GUARD_POSIX(s2n_hkdf_expand_label_ro(&hmac_state, CONN_HMAC_ALG(conn), base_key, &s2n_tls13_label_finished, &(struct s2n_blob){ 0 }, output)); return S2N_RESULT_OK; } @@ -328,12 +337,12 @@ S2N_RESULT s2n_derive_binder_key(struct s2n_psk *psk, struct s2n_blob *output) RESULT_ENSURE_REF(psk); RESULT_ENSURE_REF(output); - const struct s2n_blob *label = &s2n_tls13_label_resumption_psk_binder_key; + const struct s2n_ro_blob *label = &s2n_tls13_label_resumption_psk_binder_key; if (psk->type == S2N_PSK_TYPE_EXTERNAL) { label = &s2n_tls13_label_external_psk_binder_key; } RESULT_GUARD(s2n_extract_early_secret(psk)); - RESULT_GUARD(s2n_derive_secret(psk->hmac_alg, + RESULT_GUARD(s2n_derive_secret_ro(psk->hmac_alg, &psk->early_secret, label, &EMPTY_CONTEXT(psk->hmac_alg), @@ -349,7 +358,7 @@ S2N_RESULT s2n_derive_binder_key(struct s2n_psk *psk, struct s2n_blob *output) */ static S2N_RESULT s2n_derive_client_early_traffic_secret(struct s2n_connection *conn, struct s2n_blob *output) { - RESULT_GUARD(s2n_derive_secret_with_context(conn, +RESULT_GUARD(s2n_derive_secret_with_context(conn, S2N_EARLY_SECRET, &s2n_tls13_label_client_early_traffic_secret, CLIENT_HELLO, @@ -378,7 +387,7 @@ static S2N_RESULT s2n_extract_handshake_secret(struct s2n_connection *conn) DEFER_CLEANUP(struct s2n_blob shared_secret = { 0 }, s2n_free_or_wipe); RESULT_GUARD_POSIX(s2n_tls13_compute_shared_secret(conn, &shared_secret)); - RESULT_GUARD(s2n_extract_secret(CONN_HMAC_ALG(conn), +RESULT_GUARD(s2n_derive_secret(CONN_HMAC_ALG(conn), &derived_secret, &shared_secret, &CONN_SECRET(conn, extract_secret))); @@ -398,7 +407,7 @@ static S2N_RESULT s2n_derive_client_handshake_traffic_secret(struct s2n_connecti RESULT_ENSURE_REF(conn); RESULT_ENSURE_REF(output); - RESULT_GUARD(s2n_derive_secret_with_context(conn, +RESULT_GUARD(s2n_derive_secret_with_context(conn, S2N_HANDSHAKE_SECRET, &s2n_tls13_label_client_handshake_traffic_secret, SERVER_HELLO, @@ -430,7 +439,7 @@ static S2N_RESULT s2n_derive_server_handshake_traffic_secret(struct s2n_connecti RESULT_ENSURE_REF(conn); RESULT_ENSURE_REF(output); - RESULT_GUARD(s2n_derive_secret_with_context(conn, +RESULT_GUARD(s2n_derive_secret_with_context(conn, S2N_HANDSHAKE_SECRET, &s2n_tls13_label_server_handshake_traffic_secret, SERVER_HELLO, @@ -483,7 +492,7 @@ static S2N_RESULT s2n_extract_master_secret(struct s2n_connection *conn) */ static S2N_RESULT s2n_derive_client_application_traffic_secret(struct s2n_connection *conn, struct s2n_blob *output) { - RESULT_GUARD(s2n_derive_secret_with_context(conn, +RESULT_GUARD(s2n_derive_secret_with_context(conn, S2N_MASTER_SECRET, &s2n_tls13_label_client_application_traffic_secret, SERVER_FINISHED, @@ -500,7 +509,7 @@ static S2N_RESULT s2n_derive_client_application_traffic_secret(struct s2n_connec */ static S2N_RESULT s2n_derive_server_application_traffic_secret(struct s2n_connection *conn, struct s2n_blob *output) { - RESULT_GUARD(s2n_derive_secret_with_context(conn, +RESULT_GUARD(s2n_derive_secret_with_context(conn, S2N_MASTER_SECRET, &s2n_tls13_label_server_application_traffic_secret, SERVER_FINISHED, @@ -522,7 +531,7 @@ S2N_RESULT s2n_derive_resumption_master_secret(struct s2n_connection *conn) RESULT_ENSURE_REF(conn->secure); RESULT_ENSURE_REF(conn->secure->cipher_suite); - RESULT_GUARD(s2n_derive_secret_with_context(conn, +RESULT_GUARD(s2n_derive_secret_with_context(conn, S2N_MASTER_SECRET, &s2n_tls13_label_resumption_master_secret, CLIENT_FINISHED, @@ -544,7 +553,7 @@ S2N_RESULT s2n_derive_exporter_master_secret(struct s2n_connection *conn, struct RESULT_ENSURE_REF(conn->secure); RESULT_ENSURE_REF(conn->secure->cipher_suite); - RESULT_GUARD(s2n_derive_secret_with_context(conn, +RESULT_GUARD(s2n_derive_secret_with_context(conn, S2N_MASTER_SECRET, &s2n_tls13_label_exporter_master_secret, SERVER_FINISHED, @@ -770,7 +779,7 @@ int s2n_connection_tls_exporter(struct s2n_connection *conn, struct s2n_blob output = { 0 }; POSIX_GUARD(s2n_blob_init(&output, output_in, output_length)); - POSIX_GUARD(s2n_hkdf_expand_label(&hmac_state, hmac_alg, + POSIX_GUARD(s2n_hkdf_expand_label_ro(&hmac_state, hmac_alg, &derived_secret, &s2n_tls13_label_exporter, &digest, &output)); return S2N_SUCCESS; diff --git a/utils/s2n_blob.h b/utils/s2n_blob.h index d53203dfcfe..c907f86b36e 100644 --- a/utils/s2n_blob.h +++ b/utils/s2n_blob.h @@ -69,10 +69,18 @@ int S2N_RESULT_MUST_USE s2n_blob_slice(const struct s2n_blob *b, struct s2n_blob struct s2n_blob name = { 0 }; \ RESULT_GUARD_POSIX(s2n_blob_init(&name, name##_buf, name##_requested_size)) -#define S2N_BLOB_LABEL(name, str) \ - static const uint8_t name##_data[] = str; \ - static union{ \ - const uint8_t *const_ptr; \ - uint8_t *ptr; \ - } name##_union = { .const_ptr = name##_data }; \ - const struct s2n_blob name = { .data = name##_union.ptr, .size = sizeof(name##_data) - 1 }; +#define S2N_BLOB_LABEL(name, str) \ + static uint8_t name##_data[] = str; \ + const struct s2n_blob name = { .data = name##_data, .size = sizeof(name##_data) - 1 }; + +/* Read-onl*/ +struct s2n_ro_blob { + const uint8_t *data; + uint32_t size; +}; +#define S2N_RO_BLOB_LABEL(name,str) \ + static const uint8_t name##_data[] = str; \ + const struct s2n_ro_blob name = { \ + .data = name##_data, \ + .size = sizeof(name##_data) - 1 \ + };