Home | History | Annotate | Line # | Download | only in internal
      1 /*
      2  * Copyright 2022-2025 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  * fail_cause is a bitmask of the reasons decode might have failed
    469  * as defined below, useful when you need to interrogate parts of
    470  * a header even if its otherwise undecodeable.  May be NULL.
    471  *
    472  * Returns 1 on success and 0 on failure.
    473  */
    474 
    475 #define QUIC_PKT_HDR_DECODE_DECODE_ERR (1 << 0)
    476 #define QUIC_PKT_HDR_DECODE_BAD_VERSION (1 << 1)
    477 
    478 int ossl_quic_wire_decode_pkt_hdr(PACKET *pkt,
    479     size_t short_conn_id_len,
    480     int partial,
    481     int nodata,
    482     QUIC_PKT_HDR *hdr,
    483     QUIC_PKT_HDR_PTRS *ptrs,
    484     uint64_t *fail_cause);
    485 
    486 /*
    487  * Encodes a packet header. The packet is written to pkt.
    488  *
    489  * The length of the (encrypted) packet payload should be written to hdr->len
    490  * and will be placed in the serialized packet header. The payload data itself
    491  * is not copied; the caller should write hdr->len bytes of encrypted payload to
    492  * the WPACKET immediately after the call to this function. However,
    493  * WPACKET_reserve_bytes is called for the payload size.
    494  *
    495  * This function does not apply header protection. You must apply header
    496  * protection yourself after calling this function. *ptrs is filled with
    497  * pointers which can be passed to a header protector, but this must be
    498  * performed after the encrypted payload is written.
    499  *
    500  * The pointers in *ptrs are direct pointers into the WPACKET buffer. If more
    501  * data is written to the WPACKET buffer, WPACKET buffer reallocations may
    502  * occur, causing these pointers to become invalid. Therefore, you must not call
    503  * any write WPACKET function between this call and the call to
    504  * ossl_quic_hdr_protector_encrypt. This function calls WPACKET_reserve_bytes
    505  * for the payload length, so you may assume hdr->len bytes are already free to
    506  * write at the WPACKET cursor location once this function returns successfully.
    507  * It is recommended that you call this function, write the encrypted payload,
    508  * call ossl_quic_hdr_protector_encrypt, and then call
    509  * WPACKET_allocate_bytes(hdr->len).
    510  *
    511  * Version Negotiation and Retry packets do not use header protection; for these
    512  * header types, the fields in *ptrs are all written as zero. Version
    513  * Negotiation, Retry and 1-RTT packets do not contain a Length field, but
    514  * hdr->len bytes of data are still reserved in the WPACKET.
    515  *
    516  * If serializing a short packet and short_conn_id_len does not match the DCID
    517  * specified in hdr, the function fails.
    518  *
    519  * Returns 1 on success and 0 on failure.
    520  */
    521 int ossl_quic_wire_encode_pkt_hdr(WPACKET *pkt,
    522     size_t short_conn_id_len,
    523     const QUIC_PKT_HDR *hdr,
    524     QUIC_PKT_HDR_PTRS *ptrs);
    525 
    526 /*
    527  * Retrieves only the DCID from a packet header. This is intended for demuxer
    528  * use. It avoids the need to parse the rest of the packet header twice.
    529  *
    530  * Information on packet length is not decoded, as this only needs to be used on
    531  * the first packet in a datagram, therefore this takes a buffer and not a
    532  * PACKET.
    533  *
    534  * Returns 1 on success and 0 on failure.
    535  */
    536 int ossl_quic_wire_get_pkt_hdr_dst_conn_id(const unsigned char *buf,
    537     size_t buf_len,
    538     size_t short_conn_id_len,
    539     QUIC_CONN_ID *dst_conn_id);
    540 
    541 /*
    542  * Precisely predicts the encoded length of a packet header structure.
    543  *
    544  * May return 0 if the packet header is not valid, but the fact that this
    545  * function returns non-zero does not guarantee that
    546  * ossl_quic_wire_encode_pkt_hdr() will succeed.
    547  */
    548 int ossl_quic_wire_get_encoded_pkt_hdr_len(size_t short_conn_id_len,
    549     const QUIC_PKT_HDR *hdr);
    550 
    551 /*
    552  * Packet Number Encoding
    553  * ======================
    554  */
    555 
    556 /*
    557  * Decode an encoded packet header QUIC PN.
    558  *
    559  * enc_pn is the raw encoded PN to decode. enc_pn_len is its length in bytes as
    560  * indicated by packet headers. largest_pn is the largest PN successfully
    561  * processed in the relevant PN space.
    562  *
    563  * The resulting PN is written to *res_pn.
    564  *
    565  * Returns 1 on success or 0 on failure.
    566  */
    567 int ossl_quic_wire_decode_pkt_hdr_pn(const unsigned char *enc_pn,
    568     size_t enc_pn_len,
    569     QUIC_PN largest_pn,
    570     QUIC_PN *res_pn);
    571 
    572 /*
    573  * Determine how many bytes should be used to encode a PN. Returns the number of
    574  * bytes (which will be in range [1, 4]).
    575  */
    576 int ossl_quic_wire_determine_pn_len(QUIC_PN pn, QUIC_PN largest_acked);
    577 
    578 /*
    579  * Encode a PN for a packet header using the specified number of bytes, which
    580  * should have been determined by calling ossl_quic_wire_determine_pn_len. The
    581  * PN encoding process is done in two parts to allow the caller to override PN
    582  * encoding length if it wishes.
    583  *
    584  * Returns 1 on success and 0 on failure.
    585  */
    586 int ossl_quic_wire_encode_pkt_hdr_pn(QUIC_PN pn,
    587     unsigned char *enc_pn,
    588     size_t enc_pn_len);
    589 
    590 /*
    591  * Retry Integrity Tags
    592  * ====================
    593  */
    594 
    595 #define QUIC_RETRY_INTEGRITY_TAG_LEN 16
    596 
    597 /*
    598  * Validate a retry integrity tag. Returns 1 if the tag is valid.
    599  *
    600  * Must be called on a hdr with a type of QUIC_PKT_TYPE_RETRY with a valid data
    601  * pointer.
    602  *
    603  * client_initial_dcid must be the original DCID used by the client in its first
    604  * Initial packet, as this is used to calculate the Retry Integrity Tag.
    605  *
    606  * Returns 0 if the tag is invalid, if called on any other type of packet or if
    607  * the body is too short.
    608  */
    609 int ossl_quic_validate_retry_integrity_tag(OSSL_LIB_CTX *libctx,
    610     const char *propq,
    611     const QUIC_PKT_HDR *hdr,
    612     const QUIC_CONN_ID *client_initial_dcid);
    613 
    614 /*
    615  * Calculates a retry integrity tag. Returns 0 on error, for example if hdr does
    616  * not have a type of QUIC_PKT_TYPE_RETRY.
    617  *
    618  * client_initial_dcid must be the original DCID used by the client in its first
    619  * Initial packet, as this is used to calculate the Retry Integrity Tag.
    620  *
    621  * tag must point to a buffer of QUIC_RETRY_INTEGRITY_TAG_LEN bytes in size.
    622  *
    623  * Note that hdr->data must point to the Retry packet body, and hdr->len must
    624  * include the space for the Retry Integrity Tag. (This means that you can
    625  * easily fill in a tag in a Retry packet you are generating by calling this
    626  * function and passing (hdr->data + hdr->len - QUIC_RETRY_INTEGRITY_TAG_LEN) as
    627  * the tag argument.) This function fails if hdr->len is too short to contain a
    628  * Retry Integrity Tag.
    629  */
    630 int ossl_quic_calculate_retry_integrity_tag(OSSL_LIB_CTX *libctx,
    631     const char *propq,
    632     const QUIC_PKT_HDR *hdr,
    633     const QUIC_CONN_ID *client_initial_dcid,
    634     unsigned char *tag);
    635 
    636 #endif
    637 
    638 #endif
    639