]> git.ipfire.org Git - thirdparty/openssl.git/blob - include/internal/quic_record.h
06284c251bf6324c2f7a00a977d22519424dc680
[thirdparty/openssl.git] / include / internal / quic_record.h
1 /*
2 * Copyright 2022 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_H
11 # define OSSL_QUIC_RECORD_H
12
13 # include <openssl/ssl.h>
14 # include "internal/quic_wire_pkt.h"
15 # include "internal/quic_types.h"
16 # include "internal/quic_record_util.h"
17 # include "internal/quic_demux.h"
18
19 /*
20 * QUIC Record Layer
21 * =================
22 */
23 typedef struct ossl_qrl_st OSSL_QRL;
24
25 typedef struct ossl_qrl_args_st {
26 OSSL_LIB_CTX *libctx;
27 const char *propq;
28
29 /* Demux to receive datagrams from. */
30 QUIC_DEMUX *rx_demux;
31
32 /* Length of connection IDs used in short-header packets in bytes. */
33 size_t short_conn_id_len;
34
35 /* Initial reference PN used for RX. */
36 QUIC_PN rx_init_largest_pn[QUIC_PN_SPACE_NUM];
37 } OSSL_QRL_ARGS;
38
39 /* Instantiates a new QRL. */
40 OSSL_QRL *ossl_qrl_new(const OSSL_QRL_ARGS *args);
41
42 /*
43 * Frees the QRL. All packets obtained using ossl_qrl_read_pkt must already
44 * have been released by calling ossl_qrl_release_pkt.
45 *
46 * You do not need to call ossl_qrl_remove_dst_conn_id first; this function will
47 * unregister the QRL from the demuxer for all registered destination connection
48 * IDs (DCIDs) automatically.
49 */
50 void ossl_qrl_free(OSSL_QRL *qrl);
51
52 /*
53 * DCID Management
54 * ===============
55 */
56
57 /*
58 * Adds a given DCID to the QRL. The QRL will register the DCID with the demuxer
59 * so that incoming packets with that DCID are passed to the given QRL. Multiple
60 * DCIDs may be associated with a QRL at any one time. You will need to add at
61 * least one DCID after instantiating the QRL. A zero-length DCID is a valid
62 * input to this function. This function fails if the DCID is already
63 * registered.
64 *
65 * Returns 1 on success or 0 on error.
66 */
67 int ossl_qrl_add_dst_conn_id(OSSL_QRL *qrl,
68 const QUIC_CONN_ID *dst_conn_id);
69
70 /*
71 * Remove a DCID previously registered with ossl_qrl_add_dst_conn_id. The DCID
72 * is unregistered from the demuxer. Fails if the DCID is not registered with
73 * the demuxer.
74 *
75 * Returns 1 on success or 0 on error.
76 */
77 int ossl_qrl_remove_dst_conn_id(OSSL_QRL *qrl,
78 const QUIC_CONN_ID *dst_conn_id);
79
80 /*
81 * Secret Management
82 * =================
83 *
84 * A QRL has several encryption levels (Initial, Handshake, 0-RTT, 1-RTT) and
85 * two directions (RX, TX). At any given time, key material is managed for each
86 * (EL, RX/TX) combination.
87 *
88 * Broadly, for a given (EL, RX/TX), the following state machine is applicable:
89 *
90 * WAITING_FOR_KEYS --[Provide]--> HAVE_KEYS --[Discard]--> | DISCARDED |
91 * \-------------------------------------[Discard]--> | |
92 *
93 * To transition the RX side of an EL from WAITING_FOR_KEYS to HAVE_KEYS, call
94 * ossl_qrl_provide_rx_secret (or for the INITIAL EL,
95 * ossl_qrl_provide_rx_secret_initial).
96 *
97 * Once keys have been provisioned for an EL, you call
98 * ossl_qrl_discard_enc_level to transition the EL to the DISCARDED state. You
99 * can also call this function to transition directly to the DISCARDED state
100 * even before any keys have been provisioned for that EL.
101 *
102 * The DISCARDED state is terminal for a given EL; you cannot provide a secret
103 * again for that EL after reaching it.
104 *
105 * Incoming packets cannot be processed and decrypted if they target an EL
106 * not in the HAVE_KEYS state. However, there is a distinction between
107 * the WAITING_FOR_KEYS and DISCARDED states:
108 *
109 * - In the WAITING_FOR_KEYS state, the QRL assumes keys for the given
110 * EL will eventually arrive. Therefore, if it receives any packet
111 * for an EL in this state, it buffers it and tries to process it
112 * again once the EL reaches HAVE_KEYS.
113 *
114 * - In the DISCARDED state, the QRL assumes no keys for the given
115 * EL will ever arrive again. If it receives any packet for an EL
116 * in this state, it is simply discarded.
117 *
118 * If the user wishes to instantiate a new QRL to replace an old one for
119 * whatever reason, for example to take over for an already established QUIC
120 * connection, it is important that all ELs no longer being used (i.e., INITIAL,
121 * 0-RTT, 1-RTT) are transitioned to the DISCARDED state. Otherwise, the QRL
122 * will assume that keys for these ELs will arrive in future, and will buffer
123 * any received packets for those ELs perpetually. This can be done by calling
124 * ossl_qrl_discard_enc_level for all non-1-RTT ELs immediately after
125 * instantiating the QRL.
126 *
127 * The INITIAL EL is not setup automatically when the QRL is instantiated. This
128 * allows the caller to instead discard it immediately after instantiation of
129 * the QRL if it is not needed, for example if the QRL is being instantiated to
130 * take over handling of an existing connection which has already passed the
131 * INITIAL phase. This avoids the unnecessary derivation of INITIAL keys where
132 * they are not needed. In the ordinary case, ossl_qrl_provide_rx_secret_initial
133 * should be called immediately after instantiation.
134 */
135
136 /*
137 * A QUIC client sends its first INITIAL packet with a random DCID, which is
138 * used to compute the secret used for INITIAL packet encryption. This function
139 * must be called to provide the DCID used for INITIAL packet secret computation
140 * before the QRL can process any INITIAL response packets.
141 *
142 * It is possible to use the QRL without ever calling this, for example if there
143 * is no desire to handle INITIAL packets (e.g. if the QRL is instantiated to
144 * succeed a previous QRL and handle a connection which is already established.)
145 * However, in this case you should make sure you call
146 * ossl_qrl_discard_enc_level (see above).
147 *
148 * Returns 1 on success or 0 on error.
149 */
150 int ossl_qrl_provide_rx_secret_initial(OSSL_QRL *qrl,
151 const QUIC_CONN_ID *dst_conn_id);
152
153 /*
154 * Provides a secret to the QRL, which arises due to an encryption level change.
155 * enc_level is a QUIC_ENC_LEVEL_* value. This function cannot be used to
156 * initialise the INITIAL encryption level; see
157 * ossl_qrl_provide_rx_secret_initial instead.
158 *
159 * You should seek to call this function for a given EL before packets of that
160 * EL arrive and are processed by the QRL. However, if packets have already
161 * arrived for a given EL, the QRL will defer processing of them and perform
162 * processing of them when this function is eventually called for the EL in
163 * question.
164 *
165 * suite_id is a QRL_SUITE_* value which determines the AEAD function used for
166 * the QRL.
167 *
168 * The secret passed is used directly to derive the "quic key", "quic iv" and
169 * "quic hp" values.
170 *
171 * secret_len is the length of the secret buffer in bytes. The buffer must be
172 * sized correctly to the chosen suite, else the function fails.
173 *
174 * This function can only be called once for a given EL. Subsequent calls fail,
175 * as do calls made after a corresponding call to ossl_qrl_discard_enc_level for
176 * that EL. The secret for a EL cannot be changed after it is set because QUIC
177 * has no facility for introducing additional key material after an EL is setup.
178 * QUIC key updates are managed automatically by the QRL and do not require user
179 * intervention.
180 *
181 * Returns 1 on success or 0 on failure.
182 */
183 int ossl_qrl_provide_rx_secret(OSSL_QRL *qrl,
184 uint32_t enc_level,
185 uint32_t suite_id,
186 const unsigned char *secret,
187 size_t secret_len);
188
189 /*
190 * Informs the QRL that it can now discard key material for a given EL. The QRL
191 * will no longer be able to process incoming packets received at that
192 * encryption level. This function is idempotent and succeeds if the EL has
193 * already been discarded.
194 *
195 * Returns 1 on success and 0 on failure.
196 */
197 int ossl_qrl_discard_enc_level(OSSL_QRL *qrl, uint32_t enc_level);
198
199 /*
200 * Packet Reception
201 * ================
202 */
203
204 /* Information about a received packet. */
205 typedef struct ossl_qrl_rx_pkt_st {
206 /* Opaque handle to be passed to ossl_qrl_release_pkt. */
207 void *handle;
208
209 /*
210 * Points to a logical representation of the decoded QUIC packet header. The
211 * data and len fields point to the decrypted QUIC payload (i.e., to a
212 * sequence of zero or more (potentially malformed) frames to be decoded).
213 */
214 QUIC_PKT_HDR *hdr;
215
216 /*
217 * Address the packet was received from. If this is not available for this
218 * packet, this field is NULL (but this can only occur for manually injected
219 * packets).
220 */
221 const BIO_ADDR *peer;
222
223 /*
224 * Local address the packet was sent to. If this is not available for this
225 * packet, this field is NULL.
226 */
227 const BIO_ADDR *local;
228
229 /*
230 * This is the length of the datagram which contained this packet. Note that
231 * the datagram may have contained other packets than this. The intended use
232 * for this is so that the user can enforce minimum datagram sizes (e.g. for
233 * datagrams containing INITIAL packets), as required by RFC 9000.
234 */
235 size_t datagram_len;
236 } OSSL_QRL_RX_PKT;
237
238 /*
239 * Tries to read a new decrypted packet from the QRL.
240 *
241 * On success, all fields of *pkt are filled and 1 is returned.
242 * Else, returns 0.
243 *
244 * The resources referenced by pkt->hdr, pkt->data and pkt->peer will remain
245 * allocated at least until the user frees them by calling ossl_qrl_release_pkt,
246 * which must be called once you are done with the packet.
247 */
248 int ossl_qrl_read_pkt(OSSL_QRL *qrl, OSSL_QRL_RX_PKT *pkt);
249
250 /*
251 * Release the resources pointed to by an OSSL_QRL_RX_PKT returned by
252 * ossl_qrl_read_pkt. Pass the opaque value pkt->handle returned in the
253 * structure.
254 */
255 void ossl_qrl_release_pkt(OSSL_QRL *qrl, void *handle);
256
257 /*
258 * Returns 1 if there are any already processed (i.e. decrypted) packets waiting
259 * to be read from the QRL.
260 */
261 int ossl_qrl_processed_read_pending(OSSL_QRL *qrl);
262
263 /*
264 * Returns 1 if there arre any unprocessed (i.e. not yet decrypted) packets
265 * waiting to be processed by the QRL. These may or may not result in
266 * successfully decrypted packets once processed. This indicates whether
267 * unprocessed data is buffered by the QRL, not whether any data is available in
268 * a kernel socket buffer.
269 */
270 int ossl_qrl_unprocessed_read_pending(OSSL_QRL *qrl);
271
272 /*
273 * Returns the number of UDP payload bytes received from the network so far
274 * since the last time this counter was cleared. If clear is 1, clears the
275 * counter and returns the old value.
276 *
277 * The intended use of this is to allow callers to determine how much credit to
278 * add to their anti-amplification budgets. This is reported separately instead
279 * of in the OSSL_QRL_RX_PKT structure so that a caller can apply
280 * anti-amplification credit as soon as a datagram is received, before it has
281 * necessarily read all processed packets contained within that datagram from
282 * the QRL.
283 */
284 uint64_t ossl_qrl_get_bytes_received(OSSL_QRL *qrl, int clear);
285
286 /*
287 * Sets a callback which is called when a packet is received and being
288 * validated before being queued in the read queue. This is called before packet
289 * body decryption. pn_space is a QUIC_PN_SPACE_* value denoting which PN space
290 * the PN belongs to.
291 *
292 * If this callback returns 1, processing continues normally.
293 * If this callback returns 0, the packet is discarded.
294 *
295 * Other packets in the same datagram will still be processed where possible.
296 *
297 * The intended use for this function is to allow early validation of whether
298 * a PN is a potential duplicate before spending CPU time decrypting the
299 * packet payload.
300 *
301 * The callback is optional and can be unset by passing NULL for cb.
302 * cb_arg is an opaque value passed to cb.
303 */
304 typedef int (ossl_qrl_early_rx_validation_cb)(QUIC_PN pn, int pn_space,
305 void *arg);
306
307 int ossl_qrl_set_early_rx_validation_cb(OSSL_QRL *qrl,
308 ossl_qrl_early_rx_validation_cb *cb,
309 void *cb_arg);
310
311 #endif