summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2022-11-21 11:00:34 +0000
committerHugo Landau <hlandau@openssl.org>2023-01-13 13:20:18 +0000
commit45ecfc9b52b2d1c9a810cefafe0e8bdd403b6b66 (patch)
treef9a03035b016440fe51be68d2a025a9da56906c9 /ssl
parent3bf4dc8c2106982d4ae6ada0650383e60f96d6e6 (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.c52
-rw-r--r--ssl/quic/quic_channel_local.h1
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;