diff options
author | Matt Caswell <matt@openssl.org> | 2022-11-21 11:00:34 +0000 |
---|---|---|
committer | Hugo Landau <hlandau@openssl.org> | 2023-01-13 13:20:18 +0000 |
commit | 45ecfc9b52b2d1c9a810cefafe0e8bdd403b6b66 (patch) | |
tree | f9a03035b016440fe51be68d2a025a9da56906c9 /ssl | |
parent | 3bf4dc8c2106982d4ae6ada0650383e60f96d6e6 (diff) |
Separate handling of RX and TX enc level
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Hugo Landau <hlandau@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19703)
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/quic/quic_channel.c | 52 | ||||
-rw-r--r-- | ssl/quic/quic_channel_local.h | 1 |
2 files changed, 32 insertions, 21 deletions
diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c index fc42e65ee6..b0752cda79 100644 --- a/ssl/quic/quic_channel.c +++ b/ssl/quic/quic_channel.c @@ -234,6 +234,7 @@ static int ch_init(QUIC_CHANNEL *ch) ch->rx_active_conn_id_limit = QUIC_MIN_ACTIVE_CONN_ID_LIMIT; ch->max_idle_timeout = QUIC_DEFAULT_IDLE_TIMEOUT; ch->tx_enc_level = QUIC_ENC_LEVEL_INITIAL; + ch->rx_enc_level = QUIC_ENC_LEVEL_INITIAL; ch_update_idle(ch); ossl_quic_reactor_init(&ch->rtor, ch_tick, ch, ch_determine_next_tick_deadline(ch)); @@ -463,7 +464,7 @@ static int ch_on_crypto_recv(unsigned char *buf, size_t buf_len, * given EL is available we simply ensure we have not received any further * bytes at a lower EL. */ - for (i = QUIC_ENC_LEVEL_INITIAL; i < ch->tx_enc_level; ++i) + for (i = QUIC_ENC_LEVEL_INITIAL; i < ch->rx_enc_level; ++i) if (i != QUIC_ENC_LEVEL_0RTT && !crypto_ensure_empty(ch->crypto_recv[ossl_quic_enc_level_to_pn_space(i)])) { /* Protocol violation (RFC 9001 s. 4.1.3) */ @@ -473,7 +474,7 @@ static int ch_on_crypto_recv(unsigned char *buf, size_t buf_len, return 0; } - rstream = ch->crypto_recv[ossl_quic_enc_level_to_pn_space(ch->tx_enc_level)]; + rstream = ch->crypto_recv[ossl_quic_enc_level_to_pn_space(ch->rx_enc_level)]; if (rstream == NULL) return 0; @@ -494,28 +495,16 @@ static int ch_on_handshake_yield_secret(uint32_t enc_level, int direction, /* Invalid EL. */ return 0; - if (enc_level <= ch->tx_enc_level) - /* - * Does not make sense for us to try and provision an EL we have already - * attained. - */ - return 0; - - /* - * Ensure all crypto streams for previous ELs are now empty of available - * data. - */ - for (i = QUIC_ENC_LEVEL_INITIAL; i < enc_level; ++i) - if (!crypto_ensure_empty(ch->crypto_recv[i])) { - /* Protocol violation (RFC 9001 s. 4.1.3) */ - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_PROTOCOL_VIOLATION, - OSSL_QUIC_FRAME_TYPE_CRYPTO, - "crypto stream data in wrong EL"); - return 0; - } if (direction) { /* TX */ + if (enc_level <= ch->tx_enc_level) + /* + * Does not make sense for us to try and provision an EL we have already + * attained. + */ + return 0; + if (!ossl_qtx_provide_secret(ch->qtx, enc_level, suite_id, md, secret, secret_len)) @@ -524,12 +513,33 @@ static int ch_on_handshake_yield_secret(uint32_t enc_level, int direction, ch->tx_enc_level = enc_level; } else { /* RX */ + if (enc_level <= ch->rx_enc_level) + /* + * Does not make sense for us to try and provision an EL we have already + * attained. + */ + return 0; + + /* + * Ensure all crypto streams for previous ELs are now empty of available + * data. + */ + for (i = QUIC_ENC_LEVEL_INITIAL; i < enc_level; ++i) + if (!crypto_ensure_empty(ch->crypto_recv[i])) { + /* Protocol violation (RFC 9001 s. 4.1.3) */ + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_FRAME_TYPE_CRYPTO, + "crypto stream data in wrong EL"); + return 0; + } + if (!ossl_qrx_provide_secret(ch->qrx, enc_level, suite_id, md, secret, secret_len)) return 0; ch->have_new_rx_secret = 1; + ch->rx_enc_level = enc_level; } return 1; diff --git a/ssl/quic/quic_channel_local.h b/ssl/quic/quic_channel_local.h index c5edf2a8b0..269781688f 100644 --- a/ssl/quic/quic_channel_local.h +++ b/ssl/quic/quic_channel_local.h @@ -251,6 +251,7 @@ struct quic_channel_st { * current EL simpler and faster. */ unsigned int tx_enc_level : 3; + unsigned int rx_enc_level : 3; /* If bit n is set, EL n has been discarded. */ unsigned int el_discarded : 4; |