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