Home | History | Annotate | Line # | Download | only in internal
      1 /*
      2  * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 #ifndef OSSL_QUIC_RECORD_TX_H
     11 #define OSSL_QUIC_RECORD_TX_H
     12 
     13 #include <openssl/ssl.h>
     14 #include "internal/quic_wire_pkt.h"
     15 #include "internal/quic_types.h"
     16 #include "internal/quic_predef.h"
     17 #include "internal/quic_record_util.h"
     18 #include "internal/qlog.h"
     19 
     20 #ifndef OPENSSL_NO_QUIC
     21 
     22 /*
     23  * QUIC Record Layer - TX
     24  * ======================
     25  */
     26 typedef struct ossl_qtx_iovec_st {
     27     const unsigned char *buf;
     28     size_t buf_len;
     29 } OSSL_QTX_IOVEC;
     30 
     31 typedef struct ossl_qtx_st OSSL_QTX;
     32 
     33 typedef int (*ossl_mutate_packet_cb)(const QUIC_PKT_HDR *hdrin,
     34     const OSSL_QTX_IOVEC *iovecin, size_t numin,
     35     QUIC_PKT_HDR **hdrout,
     36     const OSSL_QTX_IOVEC **iovecout,
     37     size_t *numout,
     38     void *arg);
     39 
     40 typedef void (*ossl_finish_mutate_cb)(void *arg);
     41 
     42 typedef struct ossl_qtx_args_st {
     43     OSSL_LIB_CTX *libctx;
     44     const char *propq;
     45 
     46     /* BIO to transmit to. */
     47     BIO *bio;
     48 
     49     /* Maximum datagram payload length (MDPL) for TX purposes. */
     50     size_t mdpl;
     51 
     52     /* Callback returning QLOG instance to use, or NULL. */
     53     QLOG *(*get_qlog_cb)(void *arg);
     54     void *get_qlog_cb_arg;
     55 } OSSL_QTX_ARGS;
     56 
     57 /* Instantiates a new QTX. */
     58 OSSL_QTX *ossl_qtx_new(const OSSL_QTX_ARGS *args);
     59 
     60 /* Frees the QTX. */
     61 void ossl_qtx_free(OSSL_QTX *qtx);
     62 
     63 /* Set mutator callbacks for test framework support */
     64 void ossl_qtx_set_mutator(OSSL_QTX *qtx, ossl_mutate_packet_cb mutatecb,
     65     ossl_finish_mutate_cb finishmutatecb, void *mutatearg);
     66 
     67 /* Setters for the msg_callback and the msg_callback_arg */
     68 void ossl_qtx_set_msg_callback(OSSL_QTX *qtx, ossl_msg_cb msg_callback,
     69     SSL *msg_callback_ssl);
     70 void ossl_qtx_set_msg_callback_arg(OSSL_QTX *qtx, void *msg_callback_arg);
     71 
     72 /* Change QLOG instance retrieval callback in use after instantiation. */
     73 void ossl_qtx_set_qlog_cb(OSSL_QTX *qtx, QLOG *(*get_qlog_cb)(void *arg),
     74     void *get_qlog_cb_arg);
     75 
     76 /*
     77  * Secret Management
     78  * -----------------
     79  */
     80 
     81 /*
     82  * Provides a secret to the QTX, which arises due to an encryption level change.
     83  * enc_level is a QUIC_ENC_LEVEL_* value.
     84  *
     85  * This function can be used to initialise the INITIAL encryption level, but you
     86  * should not do so directly; see the utility function
     87  * ossl_qrl_provide_initial_secret() instead, which can initialise the INITIAL
     88  * encryption level of a QRX and QTX simultaneously without duplicating certain
     89  * key derivation steps.
     90  *
     91  * You must call this function for a given EL before transmitting packets at
     92  * that EL using this QTX, otherwise ossl_qtx_write_pkt will fail.
     93  *
     94  * suite_id is a QRL_SUITE_* value which determines the AEAD function used for
     95  * the QTX.
     96  *
     97  * The secret passed is used directly to derive the "quic key", "quic iv" and
     98  * "quic hp" values.
     99  *
    100  * secret_len is the length of the secret buffer in bytes. The buffer must be
    101  * sized correctly to the chosen suite, else the function fails.
    102  *
    103  * This function can only be called once for a given EL, except for the INITIAL
    104  * EL, as the INITIAL EL can need to be rekeyed if connection retry occurs.
    105  * Subsequent calls for non-INITIAL ELs fail. Calls made after a corresponding
    106  * call to ossl_qtx_discard_enc_level for a given EL also fail, including for
    107  * the INITIAL EL. The secret for a non-INITIAL EL cannot be changed after it is
    108  * set because QUIC has no facility for introducing additional key material
    109  * after an EL is setup. (QUIC key updates generate new keys from existing key
    110  * material and do not introduce new entropy into a connection's key material.)
    111  *
    112  * Returns 1 on success or 0 on failure.
    113  */
    114 int ossl_qtx_provide_secret(OSSL_QTX *qtx,
    115     uint32_t enc_level,
    116     uint32_t suite_id,
    117     EVP_MD *md,
    118     const unsigned char *secret,
    119     size_t secret_len);
    120 
    121 /*
    122  * Informs the QTX that it can now discard key material for a given EL. The QTX
    123  * will no longer be able to generate packets at that EL. This function is
    124  * idempotent and succeeds if the EL has already been discarded.
    125  *
    126  * Returns 1 on success and 0 on failure.
    127  */
    128 int ossl_qtx_discard_enc_level(OSSL_QTX *qtx, uint32_t enc_level);
    129 
    130 /* Returns 1 if the given encryption level is provisioned. */
    131 int ossl_qtx_is_enc_level_provisioned(OSSL_QTX *qtx, uint32_t enc_level);
    132 
    133 /*
    134  * Given the value ciphertext_len representing an encrypted packet payload
    135  * length in bytes, determines how many plaintext bytes it will decrypt to.
    136  * Returns 0 if the specified EL is not provisioned or ciphertext_len is too
    137  * small. The result is written to *plaintext_len.
    138  */
    139 int ossl_qtx_calculate_plaintext_payload_len(OSSL_QTX *qtx, uint32_t enc_level,
    140     size_t ciphertext_len,
    141     size_t *plaintext_len);
    142 
    143 /*
    144  * Given the value plaintext_len represented a plaintext packet payload length
    145  * in bytes, determines how many ciphertext bytes it will encrypt to. The value
    146  * output does not include packet headers. Returns 0 if the specified EL is not
    147  * provisioned. The result is written to *ciphertext_len.
    148  */
    149 int ossl_qtx_calculate_ciphertext_payload_len(OSSL_QTX *qtx, uint32_t enc_level,
    150     size_t plaintext_len,
    151     size_t *ciphertext_len);
    152 
    153 uint32_t ossl_qrl_get_suite_cipher_tag_len(uint32_t suite_id);
    154 
    155 /*
    156  * Packet Transmission
    157  * -------------------
    158  */
    159 
    160 struct ossl_qtx_pkt_st {
    161     /* Logical packet header to be serialized. */
    162     QUIC_PKT_HDR *hdr;
    163 
    164     /*
    165      * iovecs expressing the logical packet payload buffer. Zero-length entries
    166      * are permitted.
    167      */
    168     const OSSL_QTX_IOVEC *iovec;
    169     size_t num_iovec;
    170 
    171     /* Destination address. Will be passed through to the BIO if non-NULL. */
    172     const BIO_ADDR *peer;
    173 
    174     /*
    175      * Local address (optional). Specify as non-NULL only if TX BIO
    176      * has local address support enabled.
    177      */
    178     const BIO_ADDR *local;
    179 
    180     /*
    181      * Logical PN. Used for encryption. This will automatically be encoded to
    182      * hdr->pn, which need not be initialized.
    183      */
    184     QUIC_PN pn;
    185 
    186     /* Packet flags. Zero or more OSSL_QTX_PKT_FLAG_* values. */
    187     uint32_t flags;
    188 };
    189 
    190 /*
    191  * More packets will be written which should be coalesced into a single
    192  * datagram; do not send this packet yet. To use this, set this flag for all
    193  * packets but the final packet in a datagram, then send the final packet
    194  * without this flag set.
    195  *
    196  * This flag is not a guarantee and the QTX may transmit immediately anyway if
    197  * it is not possible to fit any more packets in the current datagram.
    198  *
    199  * If the caller change its mind and needs to cause a packet queued with
    200  * COALESCE after having passed it to this function but without writing another
    201  * packet, it should call ossl_qtx_flush_pkt().
    202  */
    203 #define OSSL_QTX_PKT_FLAG_COALESCE (1U << 0)
    204 
    205 /*
    206  * Writes a packet.
    207  *
    208  * *pkt need be valid only for the duration of the call to this function.
    209  *
    210  * pkt->hdr->data and pkt->hdr->len are unused. The payload buffer is specified
    211  * via an array of OSSL_QTX_IOVEC structures. The API is designed to support
    212  * single-copy transmission; data is copied from the iovecs as it is encrypted
    213  * into an internal staging buffer for transmission.
    214  *
    215  * The function may modify and clobber pkt->hdr->data, pkt->hdr->len,
    216  * pkt->hdr->key_phase and pkt->hdr->pn for its own internal use. No other
    217  * fields of pkt or pkt->hdr will be modified.
    218  *
    219  * It is the callers responsibility to determine how long the PN field in the
    220  * encoded packet should be by setting pkt->hdr->pn_len. This function takes
    221  * care of the PN encoding. Set pkt->pn to the desired PN.
    222  *
    223  * Note that 1-RTT packets do not have a DCID Length field, therefore the DCID
    224  * length must be understood contextually. This function assumes the caller
    225  * knows what it is doing and will serialize a DCID of whatever length is given.
    226  * It is the caller's responsibility to ensure it uses a consistent DCID length
    227  * for communication with any given set of remote peers.
    228  *
    229  * The packet is queued regardless of whether it is able to be sent immediately.
    230  * This enables packets to be batched and sent at once on systems which support
    231  * system calls to send multiple datagrams in a single system call (see
    232  * BIO_sendmmsg). To flush queued datagrams to the network, see
    233  * ossl_qtx_flush_net().
    234  *
    235  * Returns 1 on success or 0 on failure.
    236  */
    237 int ossl_qtx_write_pkt(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt);
    238 
    239 /*
    240  * Finish any incomplete datagrams for transmission which were flagged for
    241  * coalescing. If there is no current coalescing datagram, this is a no-op.
    242  */
    243 void ossl_qtx_finish_dgram(OSSL_QTX *qtx);
    244 
    245 /*
    246  * (Attempt to) flush any datagrams which are queued for transmission. Note that
    247  * this does not cancel coalescing; call ossl_qtx_finish_dgram() first if that
    248  * is desired. The queue is drained into the OS's sockets as much as possible.
    249  * To determine if there is still data to be sent after calling this function,
    250  * use ossl_qtx_get_queue_len_bytes().
    251  *
    252  * Returns one of the following values:
    253  *
    254  *   QTX_FLUSH_NET_RES_OK
    255  *      Either no packets are currently queued for transmission,
    256  *      or at least one packet was successfully submitted.
    257  *
    258  *   QTX_FLUSH_NET_RES_TRANSIENT_FAIL
    259  *      The underlying network write BIO indicated a transient error
    260  *      (e.g. buffers full).
    261  *
    262  *   QTX_FLUSH_NET_RES_PERMANENT_FAIL
    263  *      Internal error (e.g. assertion or allocation error)
    264  *      or the underlying network write BIO indicated a non-transient
    265  *      error.
    266  */
    267 #define QTX_FLUSH_NET_RES_OK 1
    268 #define QTX_FLUSH_NET_RES_TRANSIENT_FAIL (-1)
    269 #define QTX_FLUSH_NET_RES_PERMANENT_FAIL (-2)
    270 
    271 int ossl_qtx_flush_net(OSSL_QTX *qtx);
    272 
    273 /*
    274  * Diagnostic function. If there is any datagram pending transmission, pops it
    275  * and writes the details of the datagram as they would have been passed to
    276  * *msg. Returns 1, or 0 if there are no datagrams pending. For test use only.
    277  */
    278 int ossl_qtx_pop_net(OSSL_QTX *qtx, BIO_MSG *msg);
    279 
    280 /* Returns number of datagrams which are fully-formed but not yet sent. */
    281 size_t ossl_qtx_get_queue_len_datagrams(OSSL_QTX *qtx);
    282 
    283 /*
    284  * Returns number of payload bytes across all datagrams which are fully-formed
    285  * but not yet sent. Does not count any incomplete coalescing datagram.
    286  */
    287 size_t ossl_qtx_get_queue_len_bytes(OSSL_QTX *qtx);
    288 
    289 /*
    290  * Returns number of bytes in the current coalescing datagram, or 0 if there is
    291  * no current coalescing datagram. Returns 0 after a call to
    292  * ossl_qtx_finish_dgram().
    293  */
    294 size_t ossl_qtx_get_cur_dgram_len_bytes(OSSL_QTX *qtx);
    295 
    296 /*
    297  * Returns number of queued coalesced packets which have not been put into a
    298  * datagram yet. If this is non-zero, ossl_qtx_flush_pkt() needs to be called.
    299  */
    300 size_t ossl_qtx_get_unflushed_pkt_count(OSSL_QTX *qtx);
    301 
    302 /*
    303  * Change the BIO being used by the QTX. May be NULL if actual transmission is
    304  * not currently required. Does not up-ref the BIO; the caller is responsible
    305  * for ensuring the lifetime of the BIO exceeds the lifetime of the QTX.
    306  */
    307 void ossl_qtx_set_bio(OSSL_QTX *qtx, BIO *bio);
    308 
    309 /* Changes the MDPL. */
    310 int ossl_qtx_set_mdpl(OSSL_QTX *qtx, size_t mdpl);
    311 
    312 /* Retrieves the current MDPL. */
    313 size_t ossl_qtx_get_mdpl(OSSL_QTX *qtx);
    314 
    315 /*
    316  * Key Update
    317  * ----------
    318  *
    319  * For additional discussion of key update considerations, see QRX header file.
    320  */
    321 
    322 /*
    323  * Triggers a key update. The key update will be started by inverting the Key
    324  * Phase bit of the next packet transmitted; no key update occurs until the next
    325  * packet is transmitted. Thus, this function should generally be called
    326  * immediately before queueing the next packet.
    327  *
    328  * There are substantial requirements imposed by RFC 9001 on under what
    329  * circumstances a key update can be initiated. The caller is responsible for
    330  * meeting most of these requirements. For example, this function cannot be
    331  * called too soon after a previous key update has occurred. Key updates also
    332  * cannot be initiated until the 1-RTT encryption level is reached.
    333  *
    334  * As a sanity check, this function will fail and return 0 if the non-1RTT
    335  * encryption levels have not yet been dropped.
    336  *
    337  * The caller may decide itself to initiate a key update, but it also MUST
    338  * initiate a key update where it detects that the peer has initiated a key
    339  * update. The caller is responsible for initiating a TX key update by calling
    340  * this function in this circumstance; thus, the caller is responsible for
    341  * coupling the RX and TX QUIC record layers in this way.
    342  */
    343 int ossl_qtx_trigger_key_update(OSSL_QTX *qtx);
    344 
    345 /*
    346  * Key Expiration
    347  * --------------
    348  */
    349 
    350 /*
    351  * Returns the number of packets which have been encrypted for transmission with
    352  * the current set of TX keys (the current "TX key epoch"). Reset to zero after
    353  * a key update and incremented for each packet queued. If enc_level is not
    354  * valid or relates to an EL which is not currently available, returns
    355  * UINT64_MAX.
    356  */
    357 uint64_t ossl_qtx_get_cur_epoch_pkt_count(OSSL_QTX *qtx, uint32_t enc_level);
    358 
    359 /*
    360  * Returns the maximum number of packets which the record layer will permit to
    361  * be encrypted using the current set of TX keys. If this limit is reached (that
    362  * is, if the counter returned by ossl_qrx_tx_get_cur_epoch_pkt_count() reaches
    363  * this value), as a safety measure, the QTX will not permit any further packets
    364  * to be queued. All calls to ossl_qrx_write_pkt that try to send packets of a
    365  * kind which need to be encrypted will fail. It is not possible to recover from
    366  * this condition and the QTX must then be destroyed; therefore, callers should
    367  * ensure they always trigger a key update well in advance of reaching this
    368  * limit.
    369  *
    370  * The value returned by this function is based on the ciphersuite configured
    371  * for the given encryption level. If keys have not been provisioned for the
    372  * specified enc_level or the enc_level argument is invalid, this function
    373  * returns UINT64_MAX, which is not a valid value. Note that it is not possible
    374  * to perform a key update at any encryption level other than 1-RTT, therefore
    375  * if this limit is reached at earlier encryption levels (which should not be
    376  * possible) the connection must be terminated. Since this condition precludes
    377  * the transmission of further packets, the only possible signalling of such an
    378  * error condition to a peer is a Stateless Reset packet.
    379  */
    380 uint64_t ossl_qtx_get_max_epoch_pkt_count(OSSL_QTX *qtx, uint32_t enc_level);
    381 
    382 /*
    383  * Get the 1-RTT EL key epoch number for the QTX. This is intended for
    384  * diagnostic purposes. Returns 0 if 1-RTT EL is not provisioned yet.
    385  */
    386 uint64_t ossl_qtx_get_key_epoch(OSSL_QTX *qtx);
    387 
    388 #endif
    389 
    390 #endif
    391