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