xref: /openssl/include/internal/quic_wire_pkt.h (revision da1c088f)
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
ossl_quic_pkt_type_to_enc_level(uint32_t pkt_type)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
ossl_quic_enc_level_to_pkt_type(uint32_t enc_level)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
ossl_quic_pkt_type_is_encrypted(uint32_t pkt_type)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
ossl_quic_pkt_type_has_pn(uint32_t pkt_type)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
ossl_quic_pkt_type_can_share_dgram(uint32_t pkt_type)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
ossl_quic_pkt_type_must_be_last(uint32_t pkt_type)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
ossl_quic_pkt_type_has_version(uint32_t pkt_type)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
ossl_quic_pkt_type_has_scid(uint32_t pkt_type)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
630