diff --git a/crypto/s2n_hkdf.c b/crypto/s2n_hkdf.c index 22f5f137c18..c5cb1874fd6 100644 --- a/crypto/s2n_hkdf.c +++ b/crypto/s2n_hkdf.c @@ -257,13 +257,7 @@ int s2n_hkdf_expand_label(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, c struct s2n_blob hkdf_label_blob = { 0 }; struct s2n_stuffer hkdf_label = { 0 }; - // Label structure is `opaque label<7..255> = "tls13 " + Label` per RFC8446. - // So, we have 255-sizeof("tls13 ") = 249, the maximum label length. - // - // Note that all labels defined by RFC 8446 are <12 characters, which - // avoids an extra hash iteration. However, the exporter functionality - // (s2n_connection_tls_exporter) allows for longer labels. - POSIX_ENSURE_LTE(label->size, 249); + 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)); diff --git a/crypto/s2n_hkdf.h b/crypto/s2n_hkdf.h index c8072528b35..8dc53636e77 100644 --- a/crypto/s2n_hkdf.h +++ b/crypto/s2n_hkdf.h @@ -20,6 +20,16 @@ #include "crypto/s2n_hmac.h" #include "utils/s2n_blob.h" +/* + * Label structure is `opaque label<7..255> = "tls13 " + Label` per RFC8446. + * So, we have 255-sizeof("tls13 ") = 249, the maximum label length. + * + * Note that all labels defined by RFC 8446 are <12 characters, which + * avoids an extra hash iteration. However, the exporter functionality + * (s2n_connection_tls_exporter) allows for longer labels. + */ +#define S2N_MAX_HKDF_EXPAND_LABEL_LENGTH 249 + 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/tests/unit/s2n_tls13_secrets_test.c b/tests/unit/s2n_tls13_secrets_test.c index 445b96a2873..4dbcf125bc7 100644 --- a/tests/unit/s2n_tls13_secrets_test.c +++ b/tests/unit/s2n_tls13_secrets_test.c @@ -541,7 +541,6 @@ int main(int argc, char **argv) 46 d4 c8 fb 80 1a 93 04 1e ac 59 aa 47"); EXPECT_EQUAL(32, expected.size); EXPECT_BYTEARRAY_EQUAL(output, expected.data, expected.size); - }; }; diff --git a/tls/s2n_tls13_secrets.c b/tls/s2n_tls13_secrets.c index 2054980bec2..08eee891daf 100644 --- a/tls/s2n_tls13_secrets.c +++ b/tls/s2n_tls13_secrets.c @@ -709,6 +709,16 @@ S2N_RESULT s2n_tls13_secrets_get(struct s2n_connection *conn, s2n_extract_secret return S2N_RESULT_OK; } +/* + * Per https://www.rfc-editor.org/rfc/rfc8446#section-7.5 + * + * TLS-Exporter(label, context_value, key_length) = HKDF-Expand-Label( + * Derive-Secret(Secret, label, ""), + * "exporter", + * Hash(context_value), + * key_length + * ) + */ int s2n_connection_tls_exporter(struct s2n_connection *conn, const uint8_t *label_in, uint32_t label_length, const uint8_t *context, uint32_t context_length, @@ -725,7 +735,7 @@ int s2n_connection_tls_exporter(struct s2n_connection *conn, POSIX_ENSURE_REF(conn->secure->cipher_suite); s2n_hmac_algorithm hmac_alg = conn->secure->cipher_suite->prf_alg; - uint8_t label_bytes[249] = { 0 }; + uint8_t label_bytes[S2N_MAX_HKDF_EXPAND_LABEL_LENGTH] = { 0 }; struct s2n_blob label = { 0 }; POSIX_ENSURE_LTE(label_length, sizeof(label_bytes)); POSIX_CHECKED_MEMCPY(label_bytes, label_in, label_length); @@ -734,8 +744,8 @@ int s2n_connection_tls_exporter(struct s2n_connection *conn, uint8_t derived_secret_bytes[S2N_MAX_DIGEST_LEN] = { 0 }; struct s2n_blob derived_secret = { 0 }; POSIX_ENSURE_LTE(s2n_get_hash_len(CONN_HMAC_ALG(conn)), S2N_MAX_DIGEST_LEN); - POSIX_GUARD(s2n_blob_init(&derived_secret, derived_secret_bytes, - s2n_get_hash_len(CONN_HMAC_ALG(conn)))); + POSIX_GUARD(s2n_blob_init(&derived_secret, + derived_secret_bytes, s2n_get_hash_len(CONN_HMAC_ALG(conn)))); POSIX_GUARD_RESULT(s2n_derive_secret(hmac_alg, &CONN_SECRET(conn, exporter_master_secret), &label, &EMPTY_CONTEXT(hmac_alg), &derived_secret));