1 | /*
|
---|
2 | * Copyright 2022-2023 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_WIRE_PKT_H
|
---|
11 | # define OSSL_QUIC_WIRE_PKT_H
|
---|
12 |
|
---|
13 | # include <openssl/ssl.h>
|
---|
14 | # include "internal/packet_quic.h"
|
---|
15 | # include "internal/quic_types.h"
|
---|
16 |
|
---|
17 | # ifndef OPENSSL_NO_QUIC
|
---|
18 |
|
---|
19 | # define QUIC_VERSION_NONE ((uint32_t)0) /* Used for version negotiation */
|
---|
20 | # define QUIC_VERSION_1 ((uint32_t)1) /* QUIC v1 */
|
---|
21 |
|
---|
22 | /* QUIC logical packet type. These do not match wire values. */
|
---|
23 | # define QUIC_PKT_TYPE_INITIAL 1
|
---|
24 | # define QUIC_PKT_TYPE_0RTT 2
|
---|
25 | # define QUIC_PKT_TYPE_HANDSHAKE 3
|
---|
26 | # define QUIC_PKT_TYPE_RETRY 4
|
---|
27 | # define QUIC_PKT_TYPE_1RTT 5
|
---|
28 | # define QUIC_PKT_TYPE_VERSION_NEG 6
|
---|
29 |
|
---|
30 | /*
|
---|
31 | * Determine encryption level from packet type. Returns QUIC_ENC_LEVEL_NUM if
|
---|
32 | * the packet is not of a type which is encrypted.
|
---|
33 | */
|
---|
34 | static ossl_inline ossl_unused uint32_t
|
---|
35 | ossl_quic_pkt_type_to_enc_level(uint32_t pkt_type)
|
---|
36 | {
|
---|
37 | switch (pkt_type) {
|
---|
38 | case QUIC_PKT_TYPE_INITIAL:
|
---|
39 | return QUIC_ENC_LEVEL_INITIAL;
|
---|
40 | case QUIC_PKT_TYPE_HANDSHAKE:
|
---|
41 | return QUIC_ENC_LEVEL_HANDSHAKE;
|
---|
42 | case QUIC_PKT_TYPE_0RTT:
|
---|
43 | return QUIC_ENC_LEVEL_0RTT;
|
---|
44 | case QUIC_PKT_TYPE_1RTT:
|
---|
45 | return QUIC_ENC_LEVEL_1RTT;
|
---|
46 | default:
|
---|
47 | return QUIC_ENC_LEVEL_NUM;
|
---|
48 | }
|
---|
49 | }
|
---|
50 |
|
---|
51 | static ossl_inline ossl_unused uint32_t
|
---|
52 | ossl_quic_enc_level_to_pkt_type(uint32_t enc_level)
|
---|
53 | {
|
---|
54 | switch (enc_level) {
|
---|
55 | case QUIC_ENC_LEVEL_INITIAL:
|
---|
56 | return QUIC_PKT_TYPE_INITIAL;
|
---|
57 | case QUIC_ENC_LEVEL_HANDSHAKE:
|
---|
58 | return QUIC_PKT_TYPE_HANDSHAKE;
|
---|
59 | case QUIC_ENC_LEVEL_0RTT:
|
---|
60 | return QUIC_PKT_TYPE_0RTT;
|
---|
61 | case QUIC_ENC_LEVEL_1RTT:
|
---|
62 | return QUIC_PKT_TYPE_1RTT;
|
---|
63 | default:
|
---|
64 | return UINT32_MAX;
|
---|
65 | }
|
---|
66 | }
|
---|
67 |
|
---|
68 | /* Determine if a packet type contains an encrypted payload. */
|
---|
69 | static ossl_inline ossl_unused int
|
---|
70 | ossl_quic_pkt_type_is_encrypted(uint32_t pkt_type)
|
---|
71 | {
|
---|
72 | switch (pkt_type) {
|
---|
73 | case QUIC_PKT_TYPE_RETRY:
|
---|
74 | case QUIC_PKT_TYPE_VERSION_NEG:
|
---|
75 | return 0;
|
---|
76 | default:
|
---|
77 | return 1;
|
---|
78 | }
|
---|
79 | }
|
---|
80 |
|
---|
81 | /* Determine if a packet type contains a PN field. */
|
---|
82 | static ossl_inline ossl_unused int
|
---|
83 | ossl_quic_pkt_type_has_pn(uint32_t pkt_type)
|
---|
84 | {
|
---|
85 | /*
|
---|
86 | * Currently a packet has a PN iff it is encrypted. This could change
|
---|
87 | * someday.
|
---|
88 | */
|
---|
89 | return ossl_quic_pkt_type_is_encrypted(pkt_type);
|
---|
90 | }
|
---|
91 |
|
---|
92 | /*
|
---|
93 | * Determine if a packet type can appear with other packets in a datagram. Some
|
---|
94 | * packet types must be the sole packet in a datagram.
|
---|
95 | */
|
---|
96 | static ossl_inline ossl_unused int
|
---|
97 | ossl_quic_pkt_type_can_share_dgram(uint32_t pkt_type)
|
---|
98 | {
|
---|
99 | /*
|
---|
100 | * Currently only the encrypted packet types can share a datagram. This
|
---|
101 | * could change someday.
|
---|
102 | */
|
---|
103 | return ossl_quic_pkt_type_is_encrypted(pkt_type);
|
---|
104 | }
|
---|
105 |
|
---|
106 | /*
|
---|
107 | * Determine if the packet type must come at the end of the datagram (due to the
|
---|
108 | * lack of a length field).
|
---|
109 | */
|
---|
110 | static ossl_inline ossl_unused int
|
---|
111 | ossl_quic_pkt_type_must_be_last(uint32_t pkt_type)
|
---|
112 | {
|
---|
113 | /*
|
---|
114 | * Any packet type which cannot share a datagram obviously must come last.
|
---|
115 | * 1-RTT also must come last as it lacks a length field.
|
---|
116 | */
|
---|
117 | return !ossl_quic_pkt_type_can_share_dgram(pkt_type)
|
---|
118 | || pkt_type == QUIC_PKT_TYPE_1RTT;
|
---|
119 | }
|
---|
120 |
|
---|
121 | /*
|
---|
122 | * Determine if the packet type has a version field.
|
---|
123 | */
|
---|
124 | static ossl_inline ossl_unused int
|
---|
125 | ossl_quic_pkt_type_has_version(uint32_t pkt_type)
|
---|
126 | {
|
---|
127 | return pkt_type != QUIC_PKT_TYPE_1RTT && pkt_type != QUIC_PKT_TYPE_VERSION_NEG;
|
---|
128 | }
|
---|
129 |
|
---|
130 | /*
|
---|
131 | * Determine if the packet type has a SCID field.
|
---|
132 | */
|
---|
133 | static ossl_inline ossl_unused int
|
---|
134 | ossl_quic_pkt_type_has_scid(uint32_t pkt_type)
|
---|
135 | {
|
---|
136 | return pkt_type != QUIC_PKT_TYPE_1RTT;
|
---|
137 | }
|
---|
138 |
|
---|
139 | /*
|
---|
140 | * Smallest possible QUIC packet size as per RFC (aside from version negotiation
|
---|
141 | * packets).
|
---|
142 | */
|
---|
143 | # define QUIC_MIN_VALID_PKT_LEN_CRYPTO 21
|
---|
144 | # define QUIC_MIN_VALID_PKT_LEN_VERSION_NEG 7
|
---|
145 | # define QUIC_MIN_VALID_PKT_LEN QUIC_MIN_VALID_PKT_LEN_VERSION_NEG
|
---|
146 |
|
---|
147 | typedef struct quic_pkt_hdr_ptrs_st QUIC_PKT_HDR_PTRS;
|
---|
148 |
|
---|
149 | /*
|
---|
150 | * QUIC Packet Header Protection
|
---|
151 | * =============================
|
---|
152 | *
|
---|
153 | * Functions to apply and remove QUIC packet header protection. A header
|
---|
154 | * protector is initialised using ossl_quic_hdr_protector_init and must be
|
---|
155 | * destroyed using ossl_quic_hdr_protector_cleanup when no longer needed.
|
---|
156 | */
|
---|
157 | typedef struct quic_hdr_protector_st {
|
---|
158 | OSSL_LIB_CTX *libctx;
|
---|
159 | const char *propq;
|
---|
160 | EVP_CIPHER_CTX *cipher_ctx;
|
---|
161 | EVP_CIPHER *cipher;
|
---|
162 | uint32_t cipher_id;
|
---|
163 | } QUIC_HDR_PROTECTOR;
|
---|
164 |
|
---|
165 | # define QUIC_HDR_PROT_CIPHER_AES_128 1
|
---|
166 | # define QUIC_HDR_PROT_CIPHER_AES_256 2
|
---|
167 | # define QUIC_HDR_PROT_CIPHER_CHACHA 3
|
---|
168 |
|
---|
169 | /*
|
---|
170 | * Initialises a header protector.
|
---|
171 | *
|
---|
172 | * cipher_id:
|
---|
173 | * The header protection cipher method to use. One of
|
---|
174 | * QUIC_HDR_PROT_CIPHER_*. Must be chosen based on negotiated TLS cipher
|
---|
175 | * suite.
|
---|
176 | *
|
---|
177 | * quic_hp_key:
|
---|
178 | * This must be the "quic hp" key derived from a traffic secret.
|
---|
179 | *
|
---|
180 | * The length of the quic_hp_key must correspond to that expected for the
|
---|
181 | * given cipher ID.
|
---|
182 | *
|
---|
183 | * The header protector performs amortisable initialisation in this function,
|
---|
184 | * therefore a header protector should be used for as long as possible.
|
---|
185 | *
|
---|
186 | * Returns 1 on success and 0 on failure.
|
---|
187 | */
|
---|
188 | int ossl_quic_hdr_protector_init(QUIC_HDR_PROTECTOR *hpr,
|
---|
189 | OSSL_LIB_CTX *libctx,
|
---|
190 | const char *propq,
|
---|
191 | uint32_t cipher_id,
|
---|
192 | const unsigned char *quic_hp_key,
|
---|
193 | size_t quic_hp_key_len);
|
---|
194 |
|
---|
195 | /*
|
---|
196 | * Destroys a header protector. This is also safe to call on a zero-initialized
|
---|
197 | * OSSL_QUIC_HDR_PROTECTOR structure which has not been initialized, or which
|
---|
198 | * has already been destroyed.
|
---|
199 | */
|
---|
200 | void ossl_quic_hdr_protector_cleanup(QUIC_HDR_PROTECTOR *hpr);
|
---|
201 |
|
---|
202 | /*
|
---|
203 | * Removes header protection from a packet. The packet payload must currently be
|
---|
204 | * encrypted (i.e., you must remove header protection before decrypting packets
|
---|
205 | * received). The function examines the header buffer to determine which bytes
|
---|
206 | * of the header need to be decrypted.
|
---|
207 | *
|
---|
208 | * If this function fails, no data is modified.
|
---|
209 | *
|
---|
210 | * This is implemented as a call to ossl_quic_hdr_protector_decrypt_fields().
|
---|
211 | *
|
---|
212 | * Returns 1 on success and 0 on failure.
|
---|
213 | */
|
---|
214 | int ossl_quic_hdr_protector_decrypt(QUIC_HDR_PROTECTOR *hpr,
|
---|
215 | QUIC_PKT_HDR_PTRS *ptrs);
|
---|
216 |
|
---|
217 | /*
|
---|
218 | * Applies header protection to a packet. The packet payload must already have
|
---|
219 | * been encrypted (i.e., you must apply header protection after encrypting
|
---|
220 | * a packet). The function examines the header buffer to determine which bytes
|
---|
221 | * of the header need to be encrypted.
|
---|
222 | *
|
---|
223 | * This is implemented as a call to ossl_quic_hdr_protector_encrypt_fields().
|
---|
224 | *
|
---|
225 | * Returns 1 on success and 0 on failure.
|
---|
226 | */
|
---|
227 | int ossl_quic_hdr_protector_encrypt(QUIC_HDR_PROTECTOR *hpr,
|
---|
228 | QUIC_PKT_HDR_PTRS *ptrs);
|
---|
229 |
|
---|
230 | /*
|
---|
231 | * Removes header protection from a packet. The packet payload must currently
|
---|
232 | * be encrypted. This is a low-level function which assumes you have already
|
---|
233 | * determined which parts of the packet header need to be decrypted.
|
---|
234 | *
|
---|
235 | * sample:
|
---|
236 | * The range of bytes in the packet to be used to generate the header
|
---|
237 | * protection mask. It is permissible to set sample_len to the size of the
|
---|
238 | * remainder of the packet; this function will only use as many bytes as
|
---|
239 | * needed. If not enough sample bytes are provided, this function fails.
|
---|
240 | *
|
---|
241 | * first_byte:
|
---|
242 | * The first byte of the QUIC packet header to be decrypted.
|
---|
243 | *
|
---|
244 | * pn:
|
---|
245 | * Pointer to the start of the PN field. The caller is responsible
|
---|
246 | * for ensuring at least four bytes follow this pointer.
|
---|
247 | *
|
---|
248 | * Returns 1 on success and 0 on failure.
|
---|
249 | */
|
---|
250 | int ossl_quic_hdr_protector_decrypt_fields(QUIC_HDR_PROTECTOR *hpr,
|
---|
251 | const unsigned char *sample,
|
---|
252 | size_t sample_len,
|
---|
253 | unsigned char *first_byte,
|
---|
254 | unsigned char *pn_bytes);
|
---|
255 |
|
---|
256 | /*
|
---|
257 | * Works analogously to ossl_hdr_protector_decrypt_fields, but applies header
|
---|
258 | * protection instead of removing it.
|
---|
259 | */
|
---|
260 | int ossl_quic_hdr_protector_encrypt_fields(QUIC_HDR_PROTECTOR *hpr,
|
---|
261 | const unsigned char *sample,
|
---|
262 | size_t sample_len,
|
---|
263 | unsigned char *first_byte,
|
---|
264 | unsigned char *pn_bytes);
|
---|
265 |
|
---|
266 | /*
|
---|
267 | * QUIC Packet Header
|
---|
268 | * ==================
|
---|
269 | *
|
---|
270 | * This structure provides a logical representation of a QUIC packet header.
|
---|
271 | *
|
---|
272 | * QUIC packet formats fall into the following categories:
|
---|
273 | *
|
---|
274 | * Long Packets, which is subdivided into five possible packet types:
|
---|
275 | * Version Negotiation (a special case);
|
---|
276 | * Initial;
|
---|
277 | * 0-RTT;
|
---|
278 | * Handshake; and
|
---|
279 | * Retry
|
---|
280 | *
|
---|
281 | * Short Packets, which comprises only a single packet type (1-RTT).
|
---|
282 | *
|
---|
283 | * The packet formats vary and common fields are found in some packets but
|
---|
284 | * not others. The below table indicates which fields are present in which
|
---|
285 | * kinds of packet. * indicates header protection is applied.
|
---|
286 | *
|
---|
287 | * SLLLLL Legend: 1=1-RTT, i=Initial, 0=0-RTT, h=Handshake
|
---|
288 | * 1i0hrv r=Retry, v=Version Negotiation
|
---|
289 | * ------
|
---|
290 | * 1i0hrv Header Form (0=Short, 1=Long)
|
---|
291 | * 1i0hr Fixed Bit (always 1)
|
---|
292 | * 1 Spin Bit
|
---|
293 | * 1 * Reserved Bits
|
---|
294 | * 1 * Key Phase
|
---|
295 | * 1i0h * Packet Number Length
|
---|
296 | * i0hr? Long Packet Type
|
---|
297 | * i0h Type-Specific Bits
|
---|
298 | * i0hr Version (note: always 0 for Version Negotiation packets)
|
---|
299 | * 1i0hrv Destination Connection ID
|
---|
300 | * i0hrv Source Connection ID
|
---|
301 | * 1i0h * Packet Number
|
---|
302 | * i Token
|
---|
303 | * i0h Length
|
---|
304 | * r Retry Token
|
---|
305 | * r Retry Integrity Tag
|
---|
306 | *
|
---|
307 | * For each field below, the conditions under which the field is valid are
|
---|
308 | * specified. If a field is not currently valid, it is initialized to a zero or
|
---|
309 | * NULL value.
|
---|
310 | */
|
---|
311 | typedef struct quic_pkt_hdr_st {
|
---|
312 | /* [ALL] A QUIC_PKT_TYPE_* value. Always valid. */
|
---|
313 | unsigned int type :8;
|
---|
314 |
|
---|
315 | /* [S] Value of the spin bit. Valid if (type == 1RTT). */
|
---|
316 | unsigned int spin_bit :1;
|
---|
317 |
|
---|
318 | /*
|
---|
319 | * [S] Value of the Key Phase bit in the short packet.
|
---|
320 | * Valid if (type == 1RTT && !partial).
|
---|
321 | */
|
---|
322 | unsigned int key_phase :1;
|
---|
323 |
|
---|
324 | /*
|
---|
325 | * [1i0h] Length of packet number in bytes. This is the decoded value.
|
---|
326 | * Valid if ((type == 1RTT || (version && type != RETRY)) && !partial).
|
---|
327 | */
|
---|
328 | unsigned int pn_len :4;
|
---|
329 |
|
---|
330 | /*
|
---|
331 | * [ALL] Set to 1 if this is a partial decode because the packet header
|
---|
332 | * has not yet been deprotected. pn_len, pn and key_phase are not valid if
|
---|
333 | * this is set.
|
---|
334 | */
|
---|
335 | unsigned int partial :1;
|
---|
336 |
|
---|
337 | /*
|
---|
338 | * [ALL] Whether the fixed bit was set. Note that only Version Negotiation
|
---|
339 | * packets are allowed to have this unset, so this will always be 1 for all
|
---|
340 | * other packet types (decode will fail if it is not set). Ignored when
|
---|
341 | * encoding unless encoding a Version Negotiation packet.
|
---|
342 | */
|
---|
343 | unsigned int fixed :1;
|
---|
344 |
|
---|
345 | /*
|
---|
346 | * The unused bits in the low 4 bits of a Retry packet header's first byte.
|
---|
347 | * This is used to ensure that Retry packets have the same bit-for-bit
|
---|
348 | * representation in their header when decoding and encoding them again.
|
---|
349 | * This is necessary to validate Retry packet headers.
|
---|
350 | */
|
---|
351 | unsigned int unused :4;
|
---|
352 |
|
---|
353 | /*
|
---|
354 | * The 'Reserved' bits in an Initial, Handshake, 0-RTT or 1-RTT packet
|
---|
355 | * header's first byte. These are provided so that the caller can validate
|
---|
356 | * that they are zero, as this must be done after packet protection is
|
---|
357 | * successfully removed to avoid creating a timing channel.
|
---|
358 | */
|
---|
359 | unsigned int reserved :2;
|
---|
360 |
|
---|
361 | /* [L] Version field. Valid if (type != 1RTT). */
|
---|
362 | uint32_t version;
|
---|
363 |
|
---|
364 | /* [ALL] The destination connection ID. Always valid. */
|
---|
365 | QUIC_CONN_ID dst_conn_id;
|
---|
366 |
|
---|
367 | /*
|
---|
368 | * [L] The source connection ID.
|
---|
369 | * Valid if (type != 1RTT).
|
---|
370 | */
|
---|
371 | QUIC_CONN_ID src_conn_id;
|
---|
372 |
|
---|
373 | /*
|
---|
374 | * [1i0h] Relatively-encoded packet number in raw, encoded form. The correct
|
---|
375 | * decoding of this value is context-dependent. The number of bytes valid in
|
---|
376 | * this buffer is determined by pn_len above. If the decode was partial,
|
---|
377 | * this field is not valid.
|
---|
378 | *
|
---|
379 | * Valid if ((type == 1RTT || (version && type != RETRY)) && !partial).
|
---|
380 | */
|
---|
381 | unsigned char pn[4];
|
---|
382 |
|
---|
383 | /*
|
---|
384 | * [i] Token field in Initial packet. Points to memory inside the decoded
|
---|
385 | * PACKET, and therefore is valid for as long as the PACKET's buffer is
|
---|
386 | * valid. token_len is the length of the token in bytes.
|
---|
387 | *
|
---|
388 | * Valid if (type == INITIAL).
|
---|
389 | */
|
---|
390 | const unsigned char *token;
|
---|
391 | size_t token_len;
|
---|
392 |
|
---|
393 | /*
|
---|
394 | * [ALL] Payload length in bytes.
|
---|
395 | *
|
---|
396 | * Though 1-RTT, Retry and Version Negotiation packets do not contain an
|
---|
397 | * explicit length field, this field is always valid and is used by the
|
---|
398 | * packet header encoding and decoding routines to describe the payload
|
---|
399 | * length, regardless of whether the packet type encoded or decoded uses an
|
---|
400 | * explicit length indication.
|
---|
401 | */
|
---|
402 | size_t len;
|
---|
403 |
|
---|
404 | /*
|
---|
405 | * Pointer to start of payload data in the packet. Points to memory inside
|
---|
406 | * the decoded PACKET, and therefore is valid for as long as the PACKET'S
|
---|
407 | * buffer is valid. The length of the buffer in bytes is in len above.
|
---|
408 | *
|
---|
409 | * For Version Negotiation packets, points to the array of supported
|
---|
410 | * versions.
|
---|
411 | *
|
---|
412 | * For Retry packets, points to the Retry packet payload, which comprises
|
---|
413 | * the Retry Token followed by a 16-byte Retry Integrity Tag.
|
---|
414 | *
|
---|
415 | * Regardless of whether a packet is a Version Negotiation packet (where the
|
---|
416 | * payload contains a list of supported versions), a Retry packet (where the
|
---|
417 | * payload contains a Retry Token and Retry Integrity Tag), or any other
|
---|
418 | * packet type (where the payload contains frames), the payload is not
|
---|
419 | * validated and the user must parse the payload bearing this in mind.
|
---|
420 | *
|
---|
421 | * If the decode was partial (partial is set), this points to the start of
|
---|
422 | * the packet number field, rather than the protected payload, as the length
|
---|
423 | * of the packet number field is unknown. The len field reflects this in
|
---|
424 | * this case (i.e., the len field is the number of payload bytes plus the
|
---|
425 | * number of bytes comprising the PN).
|
---|
426 | */
|
---|
427 | const unsigned char *data;
|
---|
428 | } QUIC_PKT_HDR;
|
---|
429 |
|
---|
430 | /*
|
---|
431 | * Extra information which can be output by the packet header decode functions
|
---|
432 | * for the assistance of the header protector. This avoids the header protector
|
---|
433 | * needing to partially re-decode the packet header.
|
---|
434 | */
|
---|
435 | struct quic_pkt_hdr_ptrs_st {
|
---|
436 | unsigned char *raw_start; /* start of packet */
|
---|
437 | unsigned char *raw_sample; /* start of sampling range */
|
---|
438 | size_t raw_sample_len; /* maximum length of sampling range */
|
---|
439 |
|
---|
440 | /*
|
---|
441 | * Start of PN field. Guaranteed to be NULL unless at least four bytes are
|
---|
442 | * available via this pointer.
|
---|
443 | */
|
---|
444 | unsigned char *raw_pn;
|
---|
445 | };
|
---|
446 |
|
---|
447 | /*
|
---|
448 | * If partial is 1, reads the unprotected parts of a protected packet header
|
---|
449 | * from a PACKET, performing a partial decode.
|
---|
450 | *
|
---|
451 | * If partial is 0, the input is assumed to have already had header protection
|
---|
452 | * removed, and all header fields are decoded.
|
---|
453 | *
|
---|
454 | * If nodata is 1, the input is assumed to have no payload data in it. Otherwise
|
---|
455 | * payload data must be present.
|
---|
456 | *
|
---|
457 | * On success, the logical decode of the packet header is written to *hdr.
|
---|
458 | * hdr->partial is set or cleared according to whether a partial decode was
|
---|
459 | * performed. *ptrs is filled with pointers to various parts of the packet
|
---|
460 | * buffer.
|
---|
461 | *
|
---|
462 | * In order to decode short packets, the connection ID length being used must be
|
---|
463 | * known contextually, and should be passed as short_conn_id_len. If
|
---|
464 | * short_conn_id_len is set to an invalid value (a value greater than
|
---|
465 | * QUIC_MAX_CONN_ID_LEN), this function fails when trying to decode a short
|
---|
466 | * packet, but succeeds for long packets.
|
---|
467 | *
|
---|
468 | * Returns 1 on success and 0 on failure.
|
---|
469 | */
|
---|
470 | int ossl_quic_wire_decode_pkt_hdr(PACKET *pkt,
|
---|
471 | size_t short_conn_id_len,
|
---|
472 | int partial,
|
---|
473 | int nodata,
|
---|
474 | QUIC_PKT_HDR *hdr,
|
---|
475 | QUIC_PKT_HDR_PTRS *ptrs);
|
---|
476 |
|
---|
477 | /*
|
---|
478 | * Encodes a packet header. The packet is written to pkt.
|
---|
479 | *
|
---|
480 | * The length of the (encrypted) packet payload should be written to hdr->len
|
---|
481 | * and will be placed in the serialized packet header. The payload data itself
|
---|
482 | * is not copied; the caller should write hdr->len bytes of encrypted payload to
|
---|
483 | * the WPACKET immediately after the call to this function. However,
|
---|
484 | * WPACKET_reserve_bytes is called for the payload size.
|
---|
485 | *
|
---|
486 | * This function does not apply header protection. You must apply header
|
---|
487 | * protection yourself after calling this function. *ptrs is filled with
|
---|
488 | * pointers which can be passed to a header protector, but this must be
|
---|
489 | * performed after the encrypted payload is written.
|
---|
490 | *
|
---|
491 | * The pointers in *ptrs are direct pointers into the WPACKET buffer. If more
|
---|
492 | * data is written to the WPACKET buffer, WPACKET buffer reallocations may
|
---|
493 | * occur, causing these pointers to become invalid. Therefore, you must not call
|
---|
494 | * any write WPACKET function between this call and the call to
|
---|
495 | * ossl_quic_hdr_protector_encrypt. This function calls WPACKET_reserve_bytes
|
---|
496 | * for the payload length, so you may assume hdr->len bytes are already free to
|
---|
497 | * write at the WPACKET cursor location once this function returns successfully.
|
---|
498 | * It is recommended that you call this function, write the encrypted payload,
|
---|
499 | * call ossl_quic_hdr_protector_encrypt, and then call
|
---|
500 | * WPACKET_allocate_bytes(hdr->len).
|
---|
501 | *
|
---|
502 | * Version Negotiation and Retry packets do not use header protection; for these
|
---|
503 | * header types, the fields in *ptrs are all written as zero. Version
|
---|
504 | * Negotiation, Retry and 1-RTT packets do not contain a Length field, but
|
---|
505 | * hdr->len bytes of data are still reserved in the WPACKET.
|
---|
506 | *
|
---|
507 | * If serializing a short packet and short_conn_id_len does not match the DCID
|
---|
508 | * specified in hdr, the function fails.
|
---|
509 | *
|
---|
510 | * Returns 1 on success and 0 on failure.
|
---|
511 | */
|
---|
512 | int ossl_quic_wire_encode_pkt_hdr(WPACKET *pkt,
|
---|
513 | size_t short_conn_id_len,
|
---|
514 | const QUIC_PKT_HDR *hdr,
|
---|
515 | QUIC_PKT_HDR_PTRS *ptrs);
|
---|
516 |
|
---|
517 | /*
|
---|
518 | * Retrieves only the DCID from a packet header. This is intended for demuxer
|
---|
519 | * use. It avoids the need to parse the rest of the packet header twice.
|
---|
520 | *
|
---|
521 | * Information on packet length is not decoded, as this only needs to be used on
|
---|
522 | * the first packet in a datagram, therefore this takes a buffer and not a
|
---|
523 | * PACKET.
|
---|
524 | *
|
---|
525 | * Returns 1 on success and 0 on failure.
|
---|
526 | */
|
---|
527 | int ossl_quic_wire_get_pkt_hdr_dst_conn_id(const unsigned char *buf,
|
---|
528 | size_t buf_len,
|
---|
529 | size_t short_conn_id_len,
|
---|
530 | QUIC_CONN_ID *dst_conn_id);
|
---|
531 |
|
---|
532 | /*
|
---|
533 | * Precisely predicts the encoded length of a packet header structure.
|
---|
534 | *
|
---|
535 | * May return 0 if the packet header is not valid, but the fact that this
|
---|
536 | * function returns non-zero does not guarantee that
|
---|
537 | * ossl_quic_wire_encode_pkt_hdr() will succeed.
|
---|
538 | */
|
---|
539 | int ossl_quic_wire_get_encoded_pkt_hdr_len(size_t short_conn_id_len,
|
---|
540 | const QUIC_PKT_HDR *hdr);
|
---|
541 |
|
---|
542 | /*
|
---|
543 | * Packet Number Encoding
|
---|
544 | * ======================
|
---|
545 | */
|
---|
546 |
|
---|
547 | /*
|
---|
548 | * Decode an encoded packet header QUIC PN.
|
---|
549 | *
|
---|
550 | * enc_pn is the raw encoded PN to decode. enc_pn_len is its length in bytes as
|
---|
551 | * indicated by packet headers. largest_pn is the largest PN successfully
|
---|
552 | * processed in the relevant PN space.
|
---|
553 | *
|
---|
554 | * The resulting PN is written to *res_pn.
|
---|
555 | *
|
---|
556 | * Returns 1 on success or 0 on failure.
|
---|
557 | */
|
---|
558 | int ossl_quic_wire_decode_pkt_hdr_pn(const unsigned char *enc_pn,
|
---|
559 | size_t enc_pn_len,
|
---|
560 | QUIC_PN largest_pn,
|
---|
561 | QUIC_PN *res_pn);
|
---|
562 |
|
---|
563 | /*
|
---|
564 | * Determine how many bytes should be used to encode a PN. Returns the number of
|
---|
565 | * bytes (which will be in range [1, 4]).
|
---|
566 | */
|
---|
567 | int ossl_quic_wire_determine_pn_len(QUIC_PN pn, QUIC_PN largest_acked);
|
---|
568 |
|
---|
569 | /*
|
---|
570 | * Encode a PN for a packet header using the specified number of bytes, which
|
---|
571 | * should have been determined by calling ossl_quic_wire_determine_pn_len. The
|
---|
572 | * PN encoding process is done in two parts to allow the caller to override PN
|
---|
573 | * encoding length if it wishes.
|
---|
574 | *
|
---|
575 | * Returns 1 on success and 0 on failure.
|
---|
576 | */
|
---|
577 | int ossl_quic_wire_encode_pkt_hdr_pn(QUIC_PN pn,
|
---|
578 | unsigned char *enc_pn,
|
---|
579 | size_t enc_pn_len);
|
---|
580 |
|
---|
581 | /*
|
---|
582 | * Retry Integrity Tags
|
---|
583 | * ====================
|
---|
584 | */
|
---|
585 |
|
---|
586 | # define QUIC_RETRY_INTEGRITY_TAG_LEN 16
|
---|
587 |
|
---|
588 | /*
|
---|
589 | * Validate a retry integrity tag. Returns 1 if the tag is valid.
|
---|
590 | *
|
---|
591 | * Must be called on a hdr with a type of QUIC_PKT_TYPE_RETRY with a valid data
|
---|
592 | * pointer.
|
---|
593 | *
|
---|
594 | * client_initial_dcid must be the original DCID used by the client in its first
|
---|
595 | * Initial packet, as this is used to calculate the Retry Integrity Tag.
|
---|
596 | *
|
---|
597 | * Returns 0 if the tag is invalid, if called on any other type of packet or if
|
---|
598 | * the body is too short.
|
---|
599 | */
|
---|
600 | int ossl_quic_validate_retry_integrity_tag(OSSL_LIB_CTX *libctx,
|
---|
601 | const char *propq,
|
---|
602 | const QUIC_PKT_HDR *hdr,
|
---|
603 | const QUIC_CONN_ID *client_initial_dcid);
|
---|
604 |
|
---|
605 | /*
|
---|
606 | * Calculates a retry integrity tag. Returns 0 on error, for example if hdr does
|
---|
607 | * not have a type of QUIC_PKT_TYPE_RETRY.
|
---|
608 | *
|
---|
609 | * client_initial_dcid must be the original DCID used by the client in its first
|
---|
610 | * Initial packet, as this is used to calculate the Retry Integrity Tag.
|
---|
611 | *
|
---|
612 | * tag must point to a buffer of QUIC_RETRY_INTEGRITY_TAG_LEN bytes in size.
|
---|
613 | *
|
---|
614 | * Note that hdr->data must point to the Retry packet body, and hdr->len must
|
---|
615 | * include the space for the Retry Integrity Tag. (This means that you can
|
---|
616 | * easily fill in a tag in a Retry packet you are generating by calling this
|
---|
617 | * function and passing (hdr->data + hdr->len - QUIC_RETRY_INTEGRITY_TAG_LEN) as
|
---|
618 | * the tag argument.) This function fails if hdr->len is too short to contain a
|
---|
619 | * Retry Integrity Tag.
|
---|
620 | */
|
---|
621 | int ossl_quic_calculate_retry_integrity_tag(OSSL_LIB_CTX *libctx,
|
---|
622 | const char *propq,
|
---|
623 | const QUIC_PKT_HDR *hdr,
|
---|
624 | const QUIC_CONN_ID *client_initial_dcid,
|
---|
625 | unsigned char *tag);
|
---|
626 |
|
---|
627 | # endif
|
---|
628 |
|
---|
629 | #endif
|
---|