summaryrefslogtreecommitdiffstats
path: root/ssl/quic/quic_record_tx.c
diff options
context:
space:
mode:
authorHugo Landau <hlandau@openssl.org>2022-09-26 17:06:59 +0100
committerHugo Landau <hlandau@openssl.org>2022-11-24 08:15:20 +0000
commita73078b79fc6f229b95312dcb20e4f61120a108c (patch)
tree9a66c1046605081c484444eb7eeb5527c934bbe6 /ssl/quic/quic_record_tx.c
parentf5060f9b31654d7ca3b015d2b803e17dda760190 (diff)
QUIC TX Packetiser and Streams Mapper
Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Paul Dale <pauli@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/19346)
Diffstat (limited to 'ssl/quic/quic_record_tx.c')
-rw-r--r--ssl/quic/quic_record_tx.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/ssl/quic/quic_record_tx.c b/ssl/quic/quic_record_tx.c
index 24cae9a44e..14c8b0bd68 100644
--- a/ssl/quic/quic_record_tx.c
+++ b/ssl/quic/quic_record_tx.c
@@ -97,6 +97,9 @@ OSSL_QTX *ossl_qtx_new(const OSSL_QTX_ARGS *args)
{
OSSL_QTX *qtx;
+ if (args->mdpl < QUIC_MIN_INITIAL_DGRAM_LEN)
+ return 0;
+
qtx = OPENSSL_zalloc(sizeof(OSSL_QTX));
if (qtx == NULL)
return 0;
@@ -128,6 +131,9 @@ void ossl_qtx_free(OSSL_QTX *qtx)
{
uint32_t i;
+ if (qtx == NULL)
+ return;
+
/* Free TXE queue data. */
qtx_cleanup_txl(&qtx->pending);
qtx_cleanup_txl(&qtx->free);
@@ -137,6 +143,7 @@ void ossl_qtx_free(OSSL_QTX *qtx)
for (i = 0; i < QUIC_ENC_LEVEL_NUM; ++i)
ossl_qrl_enc_level_set_discard(&qtx->el_set, i);
+ BIO_free(qtx->bio);
OPENSSL_free(qtx);
}
@@ -171,6 +178,11 @@ int ossl_qtx_discard_enc_level(OSSL_QTX *qtx, uint32_t enc_level)
return 1;
}
+int ossl_qtx_is_enc_level_provisioned(OSSL_QTX *qtx, uint32_t enc_level)
+{
+ return ossl_qrl_enc_level_set_get(&qtx->el_set, enc_level, 1) != NULL;
+}
+
/* Allocate a new TXE. */
static TXE *qtx_alloc_txe(size_t alloc_len)
{
@@ -374,6 +386,31 @@ static size_t qtx_inflate_payload_len(OSSL_QTX *qtx, uint32_t enc_level,
return plaintext_len + ossl_qrl_get_suite_cipher_tag_len(el->suite_id);
}
+/* Determines the size of the AEAD input given the output size. */
+int ossl_qtx_calculate_plaintext_payload_len(OSSL_QTX *qtx, uint32_t enc_level,
+ size_t ciphertext_len,
+ size_t *plaintext_len)
+{
+ OSSL_QRL_ENC_LEVEL *el
+ = ossl_qrl_enc_level_set_get(&qtx->el_set, enc_level, 1);
+ size_t tag_len;
+
+ if (el == NULL) {
+ *plaintext_len = 0;
+ return 0;
+ }
+
+ tag_len = ossl_qrl_get_suite_cipher_tag_len(el->suite_id);
+
+ if (ciphertext_len < tag_len) {
+ *plaintext_len = 0;
+ return 0;
+ }
+
+ *plaintext_len = ciphertext_len - tag_len;
+ return 1;
+}
+
/* Any other error (including packet being too big for MDPL). */
#define QTX_FAIL_GENERIC (-1)
@@ -530,6 +567,12 @@ static int qtx_write(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt, TXE *txe,
/* Walk the iovecs to determine actual input payload length. */
iovec_cur_init(&cur, pkt->iovec, pkt->num_iovec);
+ if (cur.bytes_remaining == 0) {
+ /* No zero-length payloads allowed. */
+ ret = QTX_FAIL_GENERIC;
+ goto err;
+ }
+
/* Determine encrypted payload length. */
payload_len = needs_encrypt ? qtx_inflate_payload_len(qtx, enc_level,
cur.bytes_remaining)
@@ -833,10 +876,18 @@ int ossl_qtx_set1_bio(OSSL_QTX *qtx, BIO *bio)
int ossl_qtx_set_mdpl(OSSL_QTX *qtx, size_t mdpl)
{
+ if (mdpl < QUIC_MIN_INITIAL_DGRAM_LEN)
+ return 0;
+
qtx->mdpl = mdpl;
return 1;
}
+size_t ossl_qtx_get_mdpl(OSSL_QTX *qtx)
+{
+ return qtx->mdpl;
+}
+
size_t ossl_qtx_get_queue_len_datagrams(OSSL_QTX *qtx)
{
return qtx->pending_count;