mirror of
https://github.com/openssl/openssl.git
synced 2024-12-21 06:09:35 +08:00
da1c088f59
Reviewed-by: Richard Levitte <levitte@openssl.org> Release: yes
630 lines
23 KiB
C
630 lines
23 KiB
C
/*
|
|
* Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
|
|
*
|
|
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
|
* this file except in compliance with the License. You can obtain a copy
|
|
* in the file LICENSE in the source distribution or at
|
|
* https://www.openssl.org/source/license.html
|
|
*/
|
|
|
|
#ifndef OSSL_QUIC_WIRE_PKT_H
|
|
# define OSSL_QUIC_WIRE_PKT_H
|
|
|
|
# include <openssl/ssl.h>
|
|
# include "internal/packet_quic.h"
|
|
# include "internal/quic_types.h"
|
|
|
|
# ifndef OPENSSL_NO_QUIC
|
|
|
|
# define QUIC_VERSION_NONE ((uint32_t)0) /* Used for version negotiation */
|
|
# define QUIC_VERSION_1 ((uint32_t)1) /* QUIC v1 */
|
|
|
|
/* QUIC logical packet type. These do not match wire values. */
|
|
# define QUIC_PKT_TYPE_INITIAL 1
|
|
# define QUIC_PKT_TYPE_0RTT 2
|
|
# define QUIC_PKT_TYPE_HANDSHAKE 3
|
|
# define QUIC_PKT_TYPE_RETRY 4
|
|
# define QUIC_PKT_TYPE_1RTT 5
|
|
# define QUIC_PKT_TYPE_VERSION_NEG 6
|
|
|
|
/*
|
|
* Determine encryption level from packet type. Returns QUIC_ENC_LEVEL_NUM if
|
|
* the packet is not of a type which is encrypted.
|
|
*/
|
|
static ossl_inline ossl_unused uint32_t
|
|
ossl_quic_pkt_type_to_enc_level(uint32_t pkt_type)
|
|
{
|
|
switch (pkt_type) {
|
|
case QUIC_PKT_TYPE_INITIAL:
|
|
return QUIC_ENC_LEVEL_INITIAL;
|
|
case QUIC_PKT_TYPE_HANDSHAKE:
|
|
return QUIC_ENC_LEVEL_HANDSHAKE;
|
|
case QUIC_PKT_TYPE_0RTT:
|
|
return QUIC_ENC_LEVEL_0RTT;
|
|
case QUIC_PKT_TYPE_1RTT:
|
|
return QUIC_ENC_LEVEL_1RTT;
|
|
default:
|
|
return QUIC_ENC_LEVEL_NUM;
|
|
}
|
|
}
|
|
|
|
static ossl_inline ossl_unused uint32_t
|
|
ossl_quic_enc_level_to_pkt_type(uint32_t enc_level)
|
|
{
|
|
switch (enc_level) {
|
|
case QUIC_ENC_LEVEL_INITIAL:
|
|
return QUIC_PKT_TYPE_INITIAL;
|
|
case QUIC_ENC_LEVEL_HANDSHAKE:
|
|
return QUIC_PKT_TYPE_HANDSHAKE;
|
|
case QUIC_ENC_LEVEL_0RTT:
|
|
return QUIC_PKT_TYPE_0RTT;
|
|
case QUIC_ENC_LEVEL_1RTT:
|
|
return QUIC_PKT_TYPE_1RTT;
|
|
default:
|
|
return UINT32_MAX;
|
|
}
|
|
}
|
|
|
|
/* Determine if a packet type contains an encrypted payload. */
|
|
static ossl_inline ossl_unused int
|
|
ossl_quic_pkt_type_is_encrypted(uint32_t pkt_type)
|
|
{
|
|
switch (pkt_type) {
|
|
case QUIC_PKT_TYPE_RETRY:
|
|
case QUIC_PKT_TYPE_VERSION_NEG:
|
|
return 0;
|
|
default:
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/* Determine if a packet type contains a PN field. */
|
|
static ossl_inline ossl_unused int
|
|
ossl_quic_pkt_type_has_pn(uint32_t pkt_type)
|
|
{
|
|
/*
|
|
* Currently a packet has a PN iff it is encrypted. This could change
|
|
* someday.
|
|
*/
|
|
return ossl_quic_pkt_type_is_encrypted(pkt_type);
|
|
}
|
|
|
|
/*
|
|
* Determine if a packet type can appear with other packets in a datagram. Some
|
|
* packet types must be the sole packet in a datagram.
|
|
*/
|
|
static ossl_inline ossl_unused int
|
|
ossl_quic_pkt_type_can_share_dgram(uint32_t pkt_type)
|
|
{
|
|
/*
|
|
* Currently only the encrypted packet types can share a datagram. This
|
|
* could change someday.
|
|
*/
|
|
return ossl_quic_pkt_type_is_encrypted(pkt_type);
|
|
}
|
|
|
|
/*
|
|
* Determine if the packet type must come at the end of the datagram (due to the
|
|
* lack of a length field).
|
|
*/
|
|
static ossl_inline ossl_unused int
|
|
ossl_quic_pkt_type_must_be_last(uint32_t pkt_type)
|
|
{
|
|
/*
|
|
* Any packet type which cannot share a datagram obviously must come last.
|
|
* 1-RTT also must come last as it lacks a length field.
|
|
*/
|
|
return !ossl_quic_pkt_type_can_share_dgram(pkt_type)
|
|
|| pkt_type == QUIC_PKT_TYPE_1RTT;
|
|
}
|
|
|
|
/*
|
|
* Determine if the packet type has a version field.
|
|
*/
|
|
static ossl_inline ossl_unused int
|
|
ossl_quic_pkt_type_has_version(uint32_t pkt_type)
|
|
{
|
|
return pkt_type != QUIC_PKT_TYPE_1RTT && pkt_type != QUIC_PKT_TYPE_VERSION_NEG;
|
|
}
|
|
|
|
/*
|
|
* Determine if the packet type has a SCID field.
|
|
*/
|
|
static ossl_inline ossl_unused int
|
|
ossl_quic_pkt_type_has_scid(uint32_t pkt_type)
|
|
{
|
|
return pkt_type != QUIC_PKT_TYPE_1RTT;
|
|
}
|
|
|
|
/*
|
|
* Smallest possible QUIC packet size as per RFC (aside from version negotiation
|
|
* packets).
|
|
*/
|
|
# define QUIC_MIN_VALID_PKT_LEN_CRYPTO 21
|
|
# define QUIC_MIN_VALID_PKT_LEN_VERSION_NEG 7
|
|
# define QUIC_MIN_VALID_PKT_LEN QUIC_MIN_VALID_PKT_LEN_VERSION_NEG
|
|
|
|
typedef struct quic_pkt_hdr_ptrs_st QUIC_PKT_HDR_PTRS;
|
|
|
|
/*
|
|
* QUIC Packet Header Protection
|
|
* =============================
|
|
*
|
|
* Functions to apply and remove QUIC packet header protection. A header
|
|
* protector is initialised using ossl_quic_hdr_protector_init and must be
|
|
* destroyed using ossl_quic_hdr_protector_cleanup when no longer needed.
|
|
*/
|
|
typedef struct quic_hdr_protector_st {
|
|
OSSL_LIB_CTX *libctx;
|
|
const char *propq;
|
|
EVP_CIPHER_CTX *cipher_ctx;
|
|
EVP_CIPHER *cipher;
|
|
uint32_t cipher_id;
|
|
} QUIC_HDR_PROTECTOR;
|
|
|
|
# define QUIC_HDR_PROT_CIPHER_AES_128 1
|
|
# define QUIC_HDR_PROT_CIPHER_AES_256 2
|
|
# define QUIC_HDR_PROT_CIPHER_CHACHA 3
|
|
|
|
/*
|
|
* Initialises a header protector.
|
|
*
|
|
* cipher_id:
|
|
* The header protection cipher method to use. One of
|
|
* QUIC_HDR_PROT_CIPHER_*. Must be chosen based on negotiated TLS cipher
|
|
* suite.
|
|
*
|
|
* quic_hp_key:
|
|
* This must be the "quic hp" key derived from a traffic secret.
|
|
*
|
|
* The length of the quic_hp_key must correspond to that expected for the
|
|
* given cipher ID.
|
|
*
|
|
* The header protector performs amortisable initialisation in this function,
|
|
* therefore a header protector should be used for as long as possible.
|
|
*
|
|
* Returns 1 on success and 0 on failure.
|
|
*/
|
|
int ossl_quic_hdr_protector_init(QUIC_HDR_PROTECTOR *hpr,
|
|
OSSL_LIB_CTX *libctx,
|
|
const char *propq,
|
|
uint32_t cipher_id,
|
|
const unsigned char *quic_hp_key,
|
|
size_t quic_hp_key_len);
|
|
|
|
/*
|
|
* Destroys a header protector. This is also safe to call on a zero-initialized
|
|
* OSSL_QUIC_HDR_PROTECTOR structure which has not been initialized, or which
|
|
* has already been destroyed.
|
|
*/
|
|
void ossl_quic_hdr_protector_cleanup(QUIC_HDR_PROTECTOR *hpr);
|
|
|
|
/*
|
|
* Removes header protection from a packet. The packet payload must currently be
|
|
* encrypted (i.e., you must remove header protection before decrypting packets
|
|
* received). The function examines the header buffer to determine which bytes
|
|
* of the header need to be decrypted.
|
|
*
|
|
* If this function fails, no data is modified.
|
|
*
|
|
* This is implemented as a call to ossl_quic_hdr_protector_decrypt_fields().
|
|
*
|
|
* Returns 1 on success and 0 on failure.
|
|
*/
|
|
int ossl_quic_hdr_protector_decrypt(QUIC_HDR_PROTECTOR *hpr,
|
|
QUIC_PKT_HDR_PTRS *ptrs);
|
|
|
|
/*
|
|
* Applies header protection to a packet. The packet payload must already have
|
|
* been encrypted (i.e., you must apply header protection after encrypting
|
|
* a packet). The function examines the header buffer to determine which bytes
|
|
* of the header need to be encrypted.
|
|
*
|
|
* This is implemented as a call to ossl_quic_hdr_protector_encrypt_fields().
|
|
*
|
|
* Returns 1 on success and 0 on failure.
|
|
*/
|
|
int ossl_quic_hdr_protector_encrypt(QUIC_HDR_PROTECTOR *hpr,
|
|
QUIC_PKT_HDR_PTRS *ptrs);
|
|
|
|
/*
|
|
* Removes header protection from a packet. The packet payload must currently
|
|
* be encrypted. This is a low-level function which assumes you have already
|
|
* determined which parts of the packet header need to be decrypted.
|
|
*
|
|
* sample:
|
|
* The range of bytes in the packet to be used to generate the header
|
|
* protection mask. It is permissible to set sample_len to the size of the
|
|
* remainder of the packet; this function will only use as many bytes as
|
|
* needed. If not enough sample bytes are provided, this function fails.
|
|
*
|
|
* first_byte:
|
|
* The first byte of the QUIC packet header to be decrypted.
|
|
*
|
|
* pn:
|
|
* Pointer to the start of the PN field. The caller is responsible
|
|
* for ensuring at least four bytes follow this pointer.
|
|
*
|
|
* Returns 1 on success and 0 on failure.
|
|
*/
|
|
int ossl_quic_hdr_protector_decrypt_fields(QUIC_HDR_PROTECTOR *hpr,
|
|
const unsigned char *sample,
|
|
size_t sample_len,
|
|
unsigned char *first_byte,
|
|
unsigned char *pn_bytes);
|
|
|
|
/*
|
|
* Works analogously to ossl_hdr_protector_decrypt_fields, but applies header
|
|
* protection instead of removing it.
|
|
*/
|
|
int ossl_quic_hdr_protector_encrypt_fields(QUIC_HDR_PROTECTOR *hpr,
|
|
const unsigned char *sample,
|
|
size_t sample_len,
|
|
unsigned char *first_byte,
|
|
unsigned char *pn_bytes);
|
|
|
|
/*
|
|
* QUIC Packet Header
|
|
* ==================
|
|
*
|
|
* This structure provides a logical representation of a QUIC packet header.
|
|
*
|
|
* QUIC packet formats fall into the following categories:
|
|
*
|
|
* Long Packets, which is subdivided into five possible packet types:
|
|
* Version Negotiation (a special case);
|
|
* Initial;
|
|
* 0-RTT;
|
|
* Handshake; and
|
|
* Retry
|
|
*
|
|
* Short Packets, which comprises only a single packet type (1-RTT).
|
|
*
|
|
* The packet formats vary and common fields are found in some packets but
|
|
* not others. The below table indicates which fields are present in which
|
|
* kinds of packet. * indicates header protection is applied.
|
|
*
|
|
* SLLLLL Legend: 1=1-RTT, i=Initial, 0=0-RTT, h=Handshake
|
|
* 1i0hrv r=Retry, v=Version Negotiation
|
|
* ------
|
|
* 1i0hrv Header Form (0=Short, 1=Long)
|
|
* 1i0hr Fixed Bit (always 1)
|
|
* 1 Spin Bit
|
|
* 1 * Reserved Bits
|
|
* 1 * Key Phase
|
|
* 1i0h * Packet Number Length
|
|
* i0hr? Long Packet Type
|
|
* i0h Type-Specific Bits
|
|
* i0hr Version (note: always 0 for Version Negotiation packets)
|
|
* 1i0hrv Destination Connection ID
|
|
* i0hrv Source Connection ID
|
|
* 1i0h * Packet Number
|
|
* i Token
|
|
* i0h Length
|
|
* r Retry Token
|
|
* r Retry Integrity Tag
|
|
*
|
|
* For each field below, the conditions under which the field is valid are
|
|
* specified. If a field is not currently valid, it is initialized to a zero or
|
|
* NULL value.
|
|
*/
|
|
typedef struct quic_pkt_hdr_st {
|
|
/* [ALL] A QUIC_PKT_TYPE_* value. Always valid. */
|
|
unsigned int type :8;
|
|
|
|
/* [S] Value of the spin bit. Valid if (type == 1RTT). */
|
|
unsigned int spin_bit :1;
|
|
|
|
/*
|
|
* [S] Value of the Key Phase bit in the short packet.
|
|
* Valid if (type == 1RTT && !partial).
|
|
*/
|
|
unsigned int key_phase :1;
|
|
|
|
/*
|
|
* [1i0h] Length of packet number in bytes. This is the decoded value.
|
|
* Valid if ((type == 1RTT || (version && type != RETRY)) && !partial).
|
|
*/
|
|
unsigned int pn_len :4;
|
|
|
|
/*
|
|
* [ALL] Set to 1 if this is a partial decode because the packet header
|
|
* has not yet been deprotected. pn_len, pn and key_phase are not valid if
|
|
* this is set.
|
|
*/
|
|
unsigned int partial :1;
|
|
|
|
/*
|
|
* [ALL] Whether the fixed bit was set. Note that only Version Negotiation
|
|
* packets are allowed to have this unset, so this will always be 1 for all
|
|
* other packet types (decode will fail if it is not set). Ignored when
|
|
* encoding unless encoding a Version Negotiation packet.
|
|
*/
|
|
unsigned int fixed :1;
|
|
|
|
/*
|
|
* The unused bits in the low 4 bits of a Retry packet header's first byte.
|
|
* This is used to ensure that Retry packets have the same bit-for-bit
|
|
* representation in their header when decoding and encoding them again.
|
|
* This is necessary to validate Retry packet headers.
|
|
*/
|
|
unsigned int unused :4;
|
|
|
|
/*
|
|
* The 'Reserved' bits in an Initial, Handshake, 0-RTT or 1-RTT packet
|
|
* header's first byte. These are provided so that the caller can validate
|
|
* that they are zero, as this must be done after packet protection is
|
|
* successfully removed to avoid creating a timing channel.
|
|
*/
|
|
unsigned int reserved :2;
|
|
|
|
/* [L] Version field. Valid if (type != 1RTT). */
|
|
uint32_t version;
|
|
|
|
/* [ALL] The destination connection ID. Always valid. */
|
|
QUIC_CONN_ID dst_conn_id;
|
|
|
|
/*
|
|
* [L] The source connection ID.
|
|
* Valid if (type != 1RTT).
|
|
*/
|
|
QUIC_CONN_ID src_conn_id;
|
|
|
|
/*
|
|
* [1i0h] Relatively-encoded packet number in raw, encoded form. The correct
|
|
* decoding of this value is context-dependent. The number of bytes valid in
|
|
* this buffer is determined by pn_len above. If the decode was partial,
|
|
* this field is not valid.
|
|
*
|
|
* Valid if ((type == 1RTT || (version && type != RETRY)) && !partial).
|
|
*/
|
|
unsigned char pn[4];
|
|
|
|
/*
|
|
* [i] Token field in Initial packet. Points to memory inside the decoded
|
|
* PACKET, and therefore is valid for as long as the PACKET's buffer is
|
|
* valid. token_len is the length of the token in bytes.
|
|
*
|
|
* Valid if (type == INITIAL).
|
|
*/
|
|
const unsigned char *token;
|
|
size_t token_len;
|
|
|
|
/*
|
|
* [ALL] Payload length in bytes.
|
|
*
|
|
* Though 1-RTT, Retry and Version Negotiation packets do not contain an
|
|
* explicit length field, this field is always valid and is used by the
|
|
* packet header encoding and decoding routines to describe the payload
|
|
* length, regardless of whether the packet type encoded or decoded uses an
|
|
* explicit length indication.
|
|
*/
|
|
size_t len;
|
|
|
|
/*
|
|
* Pointer to start of payload data in the packet. Points to memory inside
|
|
* the decoded PACKET, and therefore is valid for as long as the PACKET'S
|
|
* buffer is valid. The length of the buffer in bytes is in len above.
|
|
*
|
|
* For Version Negotiation packets, points to the array of supported
|
|
* versions.
|
|
*
|
|
* For Retry packets, points to the Retry packet payload, which comprises
|
|
* the Retry Token followed by a 16-byte Retry Integrity Tag.
|
|
*
|
|
* Regardless of whether a packet is a Version Negotiation packet (where the
|
|
* payload contains a list of supported versions), a Retry packet (where the
|
|
* payload contains a Retry Token and Retry Integrity Tag), or any other
|
|
* packet type (where the payload contains frames), the payload is not
|
|
* validated and the user must parse the payload bearing this in mind.
|
|
*
|
|
* If the decode was partial (partial is set), this points to the start of
|
|
* the packet number field, rather than the protected payload, as the length
|
|
* of the packet number field is unknown. The len field reflects this in
|
|
* this case (i.e., the len field is the number of payload bytes plus the
|
|
* number of bytes comprising the PN).
|
|
*/
|
|
const unsigned char *data;
|
|
} QUIC_PKT_HDR;
|
|
|
|
/*
|
|
* Extra information which can be output by the packet header decode functions
|
|
* for the assistance of the header protector. This avoids the header protector
|
|
* needing to partially re-decode the packet header.
|
|
*/
|
|
struct quic_pkt_hdr_ptrs_st {
|
|
unsigned char *raw_start; /* start of packet */
|
|
unsigned char *raw_sample; /* start of sampling range */
|
|
size_t raw_sample_len; /* maximum length of sampling range */
|
|
|
|
/*
|
|
* Start of PN field. Guaranteed to be NULL unless at least four bytes are
|
|
* available via this pointer.
|
|
*/
|
|
unsigned char *raw_pn;
|
|
};
|
|
|
|
/*
|
|
* If partial is 1, reads the unprotected parts of a protected packet header
|
|
* from a PACKET, performing a partial decode.
|
|
*
|
|
* If partial is 0, the input is assumed to have already had header protection
|
|
* removed, and all header fields are decoded.
|
|
*
|
|
* If nodata is 1, the input is assumed to have no payload data in it. Otherwise
|
|
* payload data must be present.
|
|
*
|
|
* On success, the logical decode of the packet header is written to *hdr.
|
|
* hdr->partial is set or cleared according to whether a partial decode was
|
|
* performed. *ptrs is filled with pointers to various parts of the packet
|
|
* buffer.
|
|
*
|
|
* In order to decode short packets, the connection ID length being used must be
|
|
* known contextually, and should be passed as short_conn_id_len. If
|
|
* short_conn_id_len is set to an invalid value (a value greater than
|
|
* QUIC_MAX_CONN_ID_LEN), this function fails when trying to decode a short
|
|
* packet, but succeeds for long packets.
|
|
*
|
|
* Returns 1 on success and 0 on failure.
|
|
*/
|
|
int ossl_quic_wire_decode_pkt_hdr(PACKET *pkt,
|
|
size_t short_conn_id_len,
|
|
int partial,
|
|
int nodata,
|
|
QUIC_PKT_HDR *hdr,
|
|
QUIC_PKT_HDR_PTRS *ptrs);
|
|
|
|
/*
|
|
* Encodes a packet header. The packet is written to pkt.
|
|
*
|
|
* The length of the (encrypted) packet payload should be written to hdr->len
|
|
* and will be placed in the serialized packet header. The payload data itself
|
|
* is not copied; the caller should write hdr->len bytes of encrypted payload to
|
|
* the WPACKET immediately after the call to this function. However,
|
|
* WPACKET_reserve_bytes is called for the payload size.
|
|
*
|
|
* This function does not apply header protection. You must apply header
|
|
* protection yourself after calling this function. *ptrs is filled with
|
|
* pointers which can be passed to a header protector, but this must be
|
|
* performed after the encrypted payload is written.
|
|
*
|
|
* The pointers in *ptrs are direct pointers into the WPACKET buffer. If more
|
|
* data is written to the WPACKET buffer, WPACKET buffer reallocations may
|
|
* occur, causing these pointers to become invalid. Therefore, you must not call
|
|
* any write WPACKET function between this call and the call to
|
|
* ossl_quic_hdr_protector_encrypt. This function calls WPACKET_reserve_bytes
|
|
* for the payload length, so you may assume hdr->len bytes are already free to
|
|
* write at the WPACKET cursor location once this function returns successfully.
|
|
* It is recommended that you call this function, write the encrypted payload,
|
|
* call ossl_quic_hdr_protector_encrypt, and then call
|
|
* WPACKET_allocate_bytes(hdr->len).
|
|
*
|
|
* Version Negotiation and Retry packets do not use header protection; for these
|
|
* header types, the fields in *ptrs are all written as zero. Version
|
|
* Negotiation, Retry and 1-RTT packets do not contain a Length field, but
|
|
* hdr->len bytes of data are still reserved in the WPACKET.
|
|
*
|
|
* If serializing a short packet and short_conn_id_len does not match the DCID
|
|
* specified in hdr, the function fails.
|
|
*
|
|
* Returns 1 on success and 0 on failure.
|
|
*/
|
|
int ossl_quic_wire_encode_pkt_hdr(WPACKET *pkt,
|
|
size_t short_conn_id_len,
|
|
const QUIC_PKT_HDR *hdr,
|
|
QUIC_PKT_HDR_PTRS *ptrs);
|
|
|
|
/*
|
|
* Retrieves only the DCID from a packet header. This is intended for demuxer
|
|
* use. It avoids the need to parse the rest of the packet header twice.
|
|
*
|
|
* Information on packet length is not decoded, as this only needs to be used on
|
|
* the first packet in a datagram, therefore this takes a buffer and not a
|
|
* PACKET.
|
|
*
|
|
* Returns 1 on success and 0 on failure.
|
|
*/
|
|
int ossl_quic_wire_get_pkt_hdr_dst_conn_id(const unsigned char *buf,
|
|
size_t buf_len,
|
|
size_t short_conn_id_len,
|
|
QUIC_CONN_ID *dst_conn_id);
|
|
|
|
/*
|
|
* Precisely predicts the encoded length of a packet header structure.
|
|
*
|
|
* May return 0 if the packet header is not valid, but the fact that this
|
|
* function returns non-zero does not guarantee that
|
|
* ossl_quic_wire_encode_pkt_hdr() will succeed.
|
|
*/
|
|
int ossl_quic_wire_get_encoded_pkt_hdr_len(size_t short_conn_id_len,
|
|
const QUIC_PKT_HDR *hdr);
|
|
|
|
/*
|
|
* Packet Number Encoding
|
|
* ======================
|
|
*/
|
|
|
|
/*
|
|
* Decode an encoded packet header QUIC PN.
|
|
*
|
|
* enc_pn is the raw encoded PN to decode. enc_pn_len is its length in bytes as
|
|
* indicated by packet headers. largest_pn is the largest PN successfully
|
|
* processed in the relevant PN space.
|
|
*
|
|
* The resulting PN is written to *res_pn.
|
|
*
|
|
* Returns 1 on success or 0 on failure.
|
|
*/
|
|
int ossl_quic_wire_decode_pkt_hdr_pn(const unsigned char *enc_pn,
|
|
size_t enc_pn_len,
|
|
QUIC_PN largest_pn,
|
|
QUIC_PN *res_pn);
|
|
|
|
/*
|
|
* Determine how many bytes should be used to encode a PN. Returns the number of
|
|
* bytes (which will be in range [1, 4]).
|
|
*/
|
|
int ossl_quic_wire_determine_pn_len(QUIC_PN pn, QUIC_PN largest_acked);
|
|
|
|
/*
|
|
* Encode a PN for a packet header using the specified number of bytes, which
|
|
* should have been determined by calling ossl_quic_wire_determine_pn_len. The
|
|
* PN encoding process is done in two parts to allow the caller to override PN
|
|
* encoding length if it wishes.
|
|
*
|
|
* Returns 1 on success and 0 on failure.
|
|
*/
|
|
int ossl_quic_wire_encode_pkt_hdr_pn(QUIC_PN pn,
|
|
unsigned char *enc_pn,
|
|
size_t enc_pn_len);
|
|
|
|
/*
|
|
* Retry Integrity Tags
|
|
* ====================
|
|
*/
|
|
|
|
# define QUIC_RETRY_INTEGRITY_TAG_LEN 16
|
|
|
|
/*
|
|
* Validate a retry integrity tag. Returns 1 if the tag is valid.
|
|
*
|
|
* Must be called on a hdr with a type of QUIC_PKT_TYPE_RETRY with a valid data
|
|
* pointer.
|
|
*
|
|
* client_initial_dcid must be the original DCID used by the client in its first
|
|
* Initial packet, as this is used to calculate the Retry Integrity Tag.
|
|
*
|
|
* Returns 0 if the tag is invalid, if called on any other type of packet or if
|
|
* the body is too short.
|
|
*/
|
|
int ossl_quic_validate_retry_integrity_tag(OSSL_LIB_CTX *libctx,
|
|
const char *propq,
|
|
const QUIC_PKT_HDR *hdr,
|
|
const QUIC_CONN_ID *client_initial_dcid);
|
|
|
|
/*
|
|
* Calculates a retry integrity tag. Returns 0 on error, for example if hdr does
|
|
* not have a type of QUIC_PKT_TYPE_RETRY.
|
|
*
|
|
* client_initial_dcid must be the original DCID used by the client in its first
|
|
* Initial packet, as this is used to calculate the Retry Integrity Tag.
|
|
*
|
|
* tag must point to a buffer of QUIC_RETRY_INTEGRITY_TAG_LEN bytes in size.
|
|
*
|
|
* Note that hdr->data must point to the Retry packet body, and hdr->len must
|
|
* include the space for the Retry Integrity Tag. (This means that you can
|
|
* easily fill in a tag in a Retry packet you are generating by calling this
|
|
* function and passing (hdr->data + hdr->len - QUIC_RETRY_INTEGRITY_TAG_LEN) as
|
|
* the tag argument.) This function fails if hdr->len is too short to contain a
|
|
* Retry Integrity Tag.
|
|
*/
|
|
int ossl_quic_calculate_retry_integrity_tag(OSSL_LIB_CTX *libctx,
|
|
const char *propq,
|
|
const QUIC_PKT_HDR *hdr,
|
|
const QUIC_CONN_ID *client_initial_dcid,
|
|
unsigned char *tag);
|
|
|
|
# endif
|
|
|
|
#endif
|