]>
Commit | Line | Data |
---|---|---|
19571483 | 1 | /* |
b6461792 | 2 | * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved. |
19571483 HL |
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" | |
ff3a26b2 | 16 | # include "internal/quic_predef.h" |
19571483 | 17 | # include "internal/quic_record_util.h" |
434d52a4 | 18 | # include "internal/qlog.h" |
19571483 | 19 | |
6292519c HL |
20 | # ifndef OPENSSL_NO_QUIC |
21 | ||
19571483 HL |
22 | /* |
23 | * QUIC Record Layer - TX | |
24 | * ====================== | |
25 | */ | |
14e31409 MC |
26 | typedef struct ossl_qtx_iovec_st { |
27 | const unsigned char *buf; | |
28 | size_t buf_len; | |
29 | } OSSL_QTX_IOVEC; | |
30 | ||
19571483 HL |
31 | typedef struct ossl_qtx_st OSSL_QTX; |
32 | ||
14e31409 MC |
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 | ||
19571483 HL |
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; | |
434d52a4 | 51 | |
9f2349ae HL |
52 | /* Callback returning QLOG instance to use, or NULL. */ |
53 | QLOG *(*get_qlog_cb)(void *arg); | |
54 | void *get_qlog_cb_arg; | |
19571483 HL |
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 | ||
14e31409 MC |
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 | ||
5cf99b40 MC |
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, | |
c2786c8e | 69 | SSL *msg_callback_ssl); |
5cf99b40 MC |
70 | void ossl_qtx_set_msg_callback_arg(OSSL_QTX *qtx, void *msg_callback_arg); |
71 | ||
9f2349ae HL |
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); | |
4a3a9257 | 75 | |
19571483 HL |
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 | * | |
b2c94b93 HL |
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.) | |
19571483 HL |
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 | ||
a73078b7 HL |
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 | ||
41d39984 HL |
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 | ||
a73078b7 HL |
153 | uint32_t ossl_qrl_get_suite_cipher_tag_len(uint32_t suite_id); |
154 | ||
19571483 HL |
155 | |
156 | /* | |
157 | * Packet Transmission | |
158 | * ------------------- | |
159 | */ | |
19571483 | 160 | |
ff3a26b2 | 161 | struct ossl_qtx_pkt_st { |
19571483 HL |
162 | /* Logical packet header to be serialized. */ |
163 | QUIC_PKT_HDR *hdr; | |
164 | ||
165 | /* | |
166 | * iovecs expressing the logical packet payload buffer. Zero-length entries | |
167 | * are permitted. | |
168 | */ | |
169 | const OSSL_QTX_IOVEC *iovec; | |
170 | size_t num_iovec; | |
171 | ||
172 | /* Destination address. Will be passed through to the BIO if non-NULL. */ | |
173 | const BIO_ADDR *peer; | |
174 | ||
175 | /* | |
176 | * Local address (optional). Specify as non-NULL only if TX BIO | |
177 | * has local address support enabled. | |
178 | */ | |
179 | const BIO_ADDR *local; | |
180 | ||
181 | /* | |
182 | * Logical PN. Used for encryption. This will automatically be encoded to | |
183 | * hdr->pn, which need not be initialized. | |
184 | */ | |
185 | QUIC_PN pn; | |
186 | ||
187 | /* Packet flags. Zero or more OSSL_QTX_PKT_FLAG_* values. */ | |
188 | uint32_t flags; | |
ff3a26b2 | 189 | }; |
19571483 HL |
190 | |
191 | /* | |
192 | * More packets will be written which should be coalesced into a single | |
193 | * datagram; do not send this packet yet. To use this, set this flag for all | |
194 | * packets but the final packet in a datagram, then send the final packet | |
195 | * without this flag set. | |
196 | * | |
197 | * This flag is not a guarantee and the QTX may transmit immediately anyway if | |
198 | * it is not possible to fit any more packets in the current datagram. | |
199 | * | |
200 | * If the caller change its mind and needs to cause a packet queued with | |
201 | * COALESCE after having passed it to this function but without writing another | |
202 | * packet, it should call ossl_qtx_flush_pkt(). | |
203 | */ | |
204 | #define OSSL_QTX_PKT_FLAG_COALESCE (1U << 0) | |
205 | ||
206 | /* | |
207 | * Writes a packet. | |
208 | * | |
209 | * *pkt need be valid only for the duration of the call to this function. | |
210 | * | |
211 | * pkt->hdr->data and pkt->hdr->len are unused. The payload buffer is specified | |
212 | * via an array of OSSL_QTX_IOVEC structures. The API is designed to support | |
213 | * single-copy transmission; data is copied from the iovecs as it is encrypted | |
214 | * into an internal staging buffer for transmission. | |
215 | * | |
216 | * The function may modify and clobber pkt->hdr->data, pkt->hdr->len, | |
217 | * pkt->hdr->key_phase and pkt->hdr->pn for its own internal use. No other | |
218 | * fields of pkt or pkt->hdr will be modified. | |
219 | * | |
220 | * It is the callers responsibility to determine how long the PN field in the | |
221 | * encoded packet should be by setting pkt->hdr->pn_len. This function takes | |
222 | * care of the PN encoding. Set pkt->pn to the desired PN. | |
223 | * | |
948c656c HL |
224 | * Note that 1-RTT packets do not have a DCID Length field, therefore the DCID |
225 | * length must be understood contextually. This function assumes the caller | |
226 | * knows what it is doing and will serialize a DCID of whatever length is given. | |
227 | * It is the caller's responsibility to ensure it uses a consistent DCID length | |
228 | * for communication with any given set of remote peers. | |
229 | * | |
19571483 | 230 | * The packet is queued regardless of whether it is able to be sent immediately. |
948c656c HL |
231 | * This enables packets to be batched and sent at once on systems which support |
232 | * system calls to send multiple datagrams in a single system call (see | |
233 | * BIO_sendmmsg). To flush queued datagrams to the network, see | |
234 | * ossl_qtx_flush_net(). | |
235 | * | |
19571483 HL |
236 | * Returns 1 on success or 0 on failure. |
237 | */ | |
238 | int ossl_qtx_write_pkt(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt); | |
239 | ||
240 | /* | |
241 | * Finish any incomplete datagrams for transmission which were flagged for | |
242 | * coalescing. If there is no current coalescing datagram, this is a no-op. | |
243 | */ | |
244 | void ossl_qtx_finish_dgram(OSSL_QTX *qtx); | |
245 | ||
246 | /* | |
247 | * (Attempt to) flush any datagrams which are queued for transmission. Note that | |
248 | * this does not cancel coalescing; call ossl_qtx_finish_dgram() first if that | |
249 | * is desired. The queue is drained into the OS's sockets as much as possible. | |
250 | * To determine if there is still data to be sent after calling this function, | |
251 | * use ossl_qtx_get_queue_len_bytes(). | |
0550829f HL |
252 | * |
253 | * Returns one of the following values: | |
254 | * | |
255 | * QTX_FLUSH_NET_RES_OK | |
256 | * Either no packets are currently queued for transmission, | |
257 | * or at least one packet was successfully submitted. | |
258 | * | |
259 | * QTX_FLUSH_NET_RES_TRANSIENT_FAIL | |
260 | * The underlying network write BIO indicated a transient error | |
261 | * (e.g. buffers full). | |
262 | * | |
263 | * QTX_FLUSH_NET_RES_PERMANENT_FAIL | |
264 | * Internal error (e.g. assertion or allocation error) | |
265 | * or the underlying network write BIO indicated a non-transient | |
266 | * error. | |
19571483 | 267 | */ |
0550829f HL |
268 | #define QTX_FLUSH_NET_RES_OK 1 |
269 | #define QTX_FLUSH_NET_RES_TRANSIENT_FAIL (-1) | |
270 | #define QTX_FLUSH_NET_RES_PERMANENT_FAIL (-2) | |
271 | ||
272 | int ossl_qtx_flush_net(OSSL_QTX *qtx); | |
19571483 HL |
273 | |
274 | /* | |
275 | * Diagnostic function. If there is any datagram pending transmission, pops it | |
276 | * and writes the details of the datagram as they would have been passed to | |
277 | * *msg. Returns 1, or 0 if there are no datagrams pending. For test use only. | |
278 | */ | |
279 | int ossl_qtx_pop_net(OSSL_QTX *qtx, BIO_MSG *msg); | |
280 | ||
281 | /* Returns number of datagrams which are fully-formed but not yet sent. */ | |
282 | size_t ossl_qtx_get_queue_len_datagrams(OSSL_QTX *qtx); | |
283 | ||
284 | /* | |
285 | * Returns number of payload bytes across all datagrams which are fully-formed | |
286 | * but not yet sent. Does not count any incomplete coalescing datagram. | |
287 | */ | |
288 | size_t ossl_qtx_get_queue_len_bytes(OSSL_QTX *qtx); | |
289 | ||
290 | /* | |
291 | * Returns number of bytes in the current coalescing datagram, or 0 if there is | |
292 | * no current coalescing datagram. Returns 0 after a call to | |
293 | * ossl_qtx_finish_dgram(). | |
294 | */ | |
295 | size_t ossl_qtx_get_cur_dgram_len_bytes(OSSL_QTX *qtx); | |
296 | ||
297 | /* | |
298 | * Returns number of queued coalesced packets which have not been put into a | |
299 | * datagram yet. If this is non-zero, ossl_qtx_flush_pkt() needs to be called. | |
300 | */ | |
301 | size_t ossl_qtx_get_unflushed_pkt_count(OSSL_QTX *qtx); | |
302 | ||
303 | /* | |
304 | * Change the BIO being used by the QTX. May be NULL if actual transmission is | |
81b6b43c HL |
305 | * not currently required. Does not up-ref the BIO; the caller is responsible |
306 | * for ensuring the lifetime of the BIO exceeds the lifetime of the QTX. | |
19571483 | 307 | */ |
cdd3f732 | 308 | void ossl_qtx_set_bio(OSSL_QTX *qtx, BIO *bio); |
19571483 HL |
309 | |
310 | /* Changes the MDPL. */ | |
311 | int ossl_qtx_set_mdpl(OSSL_QTX *qtx, size_t mdpl); | |
312 | ||
a73078b7 HL |
313 | /* Retrieves the current MDPL. */ |
314 | size_t ossl_qtx_get_mdpl(OSSL_QTX *qtx); | |
315 | ||
19571483 HL |
316 | |
317 | /* | |
318 | * Key Update | |
319 | * ---------- | |
320 | * | |
321 | * For additional discussion of key update considerations, see QRX header file. | |
322 | */ | |
323 | ||
324 | /* | |
325 | * Triggers a key update. The key update will be started by inverting the Key | |
326 | * Phase bit of the next packet transmitted; no key update occurs until the next | |
327 | * packet is transmitted. Thus, this function should generally be called | |
328 | * immediately before queueing the next packet. | |
329 | * | |
330 | * There are substantial requirements imposed by RFC 9001 on under what | |
331 | * circumstances a key update can be initiated. The caller is responsible for | |
332 | * meeting most of these requirements. For example, this function cannot be | |
333 | * called too soon after a previous key update has occurred. Key updates also | |
334 | * cannot be initiated until the 1-RTT encryption level is reached. | |
335 | * | |
336 | * As a sanity check, this function will fail and return 0 if the non-1RTT | |
337 | * encryption levels have not yet been dropped. | |
338 | * | |
339 | * The caller may decide itself to initiate a key update, but it also MUST | |
340 | * initiate a key update where it detects that the peer has initiated a key | |
341 | * update. The caller is responsible for initiating a TX key update by calling | |
342 | * this function in this circumstance; thus, the caller is responsible for | |
343 | * coupling the RX and TX QUIC record layers in this way. | |
344 | */ | |
345 | int ossl_qtx_trigger_key_update(OSSL_QTX *qtx); | |
346 | ||
347 | ||
348 | /* | |
349 | * Key Expiration | |
350 | * -------------- | |
351 | */ | |
352 | ||
353 | /* | |
354 | * Returns the number of packets which have been encrypted for transmission with | |
355 | * the current set of TX keys (the current "TX key epoch"). Reset to zero after | |
356 | * a key update and incremented for each packet queued. If enc_level is not | |
357 | * valid or relates to an EL which is not currently available, returns | |
358 | * UINT64_MAX. | |
359 | */ | |
360 | uint64_t ossl_qtx_get_cur_epoch_pkt_count(OSSL_QTX *qtx, uint32_t enc_level); | |
361 | ||
362 | /* | |
363 | * Returns the maximum number of packets which the record layer will permit to | |
364 | * be encrypted using the current set of TX keys. If this limit is reached (that | |
365 | * is, if the counter returned by ossl_qrx_tx_get_cur_epoch_pkt_count() reaches | |
366 | * this value), as a safety measure, the QTX will not permit any further packets | |
367 | * to be queued. All calls to ossl_qrx_write_pkt that try to send packets of a | |
368 | * kind which need to be encrypted will fail. It is not possible to recover from | |
369 | * this condition and the QTX must then be destroyed; therefore, callers should | |
370 | * ensure they always trigger a key update well in advance of reaching this | |
371 | * limit. | |
372 | * | |
373 | * The value returned by this function is based on the ciphersuite configured | |
374 | * for the given encryption level. If keys have not been provisioned for the | |
375 | * specified enc_level or the enc_level argument is invalid, this function | |
376 | * returns UINT64_MAX, which is not a valid value. Note that it is not possible | |
377 | * to perform a key update at any encryption level other than 1-RTT, therefore | |
378 | * if this limit is reached at earlier encryption levels (which should not be | |
379 | * possible) the connection must be terminated. Since this condition precludes | |
380 | * the transmission of further packets, the only possible signalling of such an | |
381 | * error condition to a peer is a Stateless Reset packet. | |
382 | */ | |
383 | uint64_t ossl_qtx_get_max_epoch_pkt_count(OSSL_QTX *qtx, uint32_t enc_level); | |
384 | ||
16f3b542 HL |
385 | /* |
386 | * Get the 1-RTT EL key epoch number for the QTX. This is intended for | |
387 | * diagnostic purposes. Returns 0 if 1-RTT EL is not provisioned yet. | |
388 | */ | |
389 | uint64_t ossl_qtx_get_key_epoch(OSSL_QTX *qtx); | |
390 | ||
6292519c HL |
391 | # endif |
392 | ||
19571483 | 393 | #endif |