Home | History | Annotate | Line # | Download | only in quic
      1      1.1  christos /*
      2      1.1  christos  * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved.
      3      1.1  christos  *
      4      1.1  christos  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5      1.1  christos  * this file except in compliance with the License.  You can obtain a copy
      6      1.1  christos  * in the file LICENSE in the source distribution or at
      7      1.1  christos  * https://www.openssl.org/source/license.html
      8      1.1  christos  */
      9      1.1  christos 
     10      1.1  christos #include <openssl/macros.h>
     11      1.1  christos #include <openssl/objects.h>
     12      1.1  christos #include "internal/quic_ssl.h"
     13      1.1  christos #include "internal/quic_vlint.h"
     14      1.1  christos #include "internal/quic_wire.h"
     15      1.1  christos #include "internal/quic_error.h"
     16      1.1  christos 
     17      1.1  christos OSSL_SAFE_MATH_UNSIGNED(uint64_t, uint64_t)
     18      1.1  christos 
     19      1.1  christos int ossl_quic_frame_ack_contains_pn(const OSSL_QUIC_FRAME_ACK *ack, QUIC_PN pn)
     20      1.1  christos {
     21      1.1  christos     size_t i;
     22      1.1  christos 
     23      1.1  christos     for (i = 0; i < ack->num_ack_ranges; ++i)
     24      1.1  christos         if (pn >= ack->ack_ranges[i].start
     25      1.1  christos             && pn <= ack->ack_ranges[i].end)
     26      1.1  christos             return 1;
     27      1.1  christos 
     28      1.1  christos     return 0;
     29      1.1  christos }
     30      1.1  christos 
     31      1.1  christos /*
     32      1.1  christos  * QUIC Wire Format Encoding
     33      1.1  christos  * =========================
     34      1.1  christos  */
     35      1.1  christos 
     36      1.1  christos int ossl_quic_wire_encode_padding(WPACKET *pkt, size_t num_bytes)
     37      1.1  christos {
     38      1.1  christos     /*
     39      1.1  christos      * PADDING is frame type zero, which as a variable-length integer is
     40      1.1  christos      * represented as a single zero byte. As an optimisation, just use memset.
     41      1.1  christos      */
     42      1.1  christos     return WPACKET_memset(pkt, 0, num_bytes);
     43      1.1  christos }
     44      1.1  christos 
     45      1.1  christos static int encode_frame_hdr(WPACKET *pkt, uint64_t frame_type)
     46      1.1  christos {
     47      1.1  christos     return WPACKET_quic_write_vlint(pkt, frame_type);
     48      1.1  christos }
     49      1.1  christos 
     50      1.1  christos int ossl_quic_wire_encode_frame_ping(WPACKET *pkt)
     51      1.1  christos {
     52      1.1  christos     return encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_PING);
     53      1.1  christos }
     54      1.1  christos 
     55      1.1  christos int ossl_quic_wire_encode_frame_ack(WPACKET *pkt,
     56  1.1.1.2  christos     uint32_t ack_delay_exponent,
     57  1.1.1.2  christos     const OSSL_QUIC_FRAME_ACK *ack)
     58      1.1  christos {
     59      1.1  christos     uint64_t frame_type = ack->ecn_present ? OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN
     60      1.1  christos                                            : OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN;
     61      1.1  christos 
     62      1.1  christos     uint64_t largest_ackd, first_ack_range, ack_delay_enc;
     63      1.1  christos     uint64_t i, num_ack_ranges = ack->num_ack_ranges;
     64      1.1  christos     OSSL_TIME delay;
     65      1.1  christos 
     66      1.1  christos     if (num_ack_ranges == 0)
     67      1.1  christos         return 0;
     68      1.1  christos 
     69      1.1  christos     delay = ossl_time_divide(ossl_time_divide(ack->delay_time, OSSL_TIME_US),
     70  1.1.1.2  christos         (uint64_t)1 << ack_delay_exponent);
     71  1.1.1.2  christos     ack_delay_enc = ossl_time2ticks(delay);
     72      1.1  christos 
     73  1.1.1.2  christos     largest_ackd = ack->ack_ranges[0].end;
     74      1.1  christos     first_ack_range = ack->ack_ranges[0].end - ack->ack_ranges[0].start;
     75      1.1  christos 
     76      1.1  christos     if (!encode_frame_hdr(pkt, frame_type)
     77  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, largest_ackd)
     78  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, ack_delay_enc)
     79  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, num_ack_ranges - 1)
     80  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, first_ack_range))
     81      1.1  christos         return 0;
     82      1.1  christos 
     83      1.1  christos     for (i = 1; i < num_ack_ranges; ++i) {
     84      1.1  christos         uint64_t gap, range_len;
     85      1.1  christos 
     86  1.1.1.2  christos         gap = ack->ack_ranges[i - 1].start - ack->ack_ranges[i].end - 2;
     87  1.1.1.2  christos         range_len = ack->ack_ranges[i].end - ack->ack_ranges[i].start;
     88      1.1  christos 
     89      1.1  christos         if (!WPACKET_quic_write_vlint(pkt, gap)
     90  1.1.1.2  christos             || !WPACKET_quic_write_vlint(pkt, range_len))
     91      1.1  christos             return 0;
     92      1.1  christos     }
     93      1.1  christos 
     94      1.1  christos     if (ack->ecn_present)
     95      1.1  christos         if (!WPACKET_quic_write_vlint(pkt, ack->ect0)
     96  1.1.1.2  christos             || !WPACKET_quic_write_vlint(pkt, ack->ect1)
     97  1.1.1.2  christos             || !WPACKET_quic_write_vlint(pkt, ack->ecnce))
     98      1.1  christos             return 0;
     99      1.1  christos 
    100      1.1  christos     return 1;
    101      1.1  christos }
    102      1.1  christos 
    103      1.1  christos int ossl_quic_wire_encode_frame_reset_stream(WPACKET *pkt,
    104  1.1.1.2  christos     const OSSL_QUIC_FRAME_RESET_STREAM *f)
    105      1.1  christos {
    106      1.1  christos     if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_RESET_STREAM)
    107  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, f->stream_id)
    108  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, f->app_error_code)
    109  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, f->final_size))
    110      1.1  christos         return 0;
    111      1.1  christos 
    112      1.1  christos     return 1;
    113      1.1  christos }
    114      1.1  christos 
    115      1.1  christos int ossl_quic_wire_encode_frame_stop_sending(WPACKET *pkt,
    116  1.1.1.2  christos     const OSSL_QUIC_FRAME_STOP_SENDING *f)
    117      1.1  christos {
    118      1.1  christos     if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_STOP_SENDING)
    119  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, f->stream_id)
    120  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, f->app_error_code))
    121      1.1  christos         return 0;
    122      1.1  christos 
    123      1.1  christos     return 1;
    124      1.1  christos }
    125      1.1  christos 
    126      1.1  christos int ossl_quic_wire_encode_frame_crypto_hdr(WPACKET *pkt,
    127  1.1.1.2  christos     const OSSL_QUIC_FRAME_CRYPTO *f)
    128      1.1  christos {
    129      1.1  christos     if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_CRYPTO)
    130  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, f->offset)
    131  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, f->len))
    132      1.1  christos         return 0;
    133      1.1  christos 
    134      1.1  christos     return 1;
    135      1.1  christos }
    136      1.1  christos 
    137      1.1  christos size_t ossl_quic_wire_get_encoded_frame_len_crypto_hdr(const OSSL_QUIC_FRAME_CRYPTO *f)
    138      1.1  christos {
    139      1.1  christos     size_t a, b, c;
    140      1.1  christos 
    141      1.1  christos     a = ossl_quic_vlint_encode_len(OSSL_QUIC_FRAME_TYPE_CRYPTO);
    142      1.1  christos     b = ossl_quic_vlint_encode_len(f->offset);
    143      1.1  christos     c = ossl_quic_vlint_encode_len(f->len);
    144      1.1  christos     if (a == 0 || b == 0 || c == 0)
    145      1.1  christos         return 0;
    146      1.1  christos 
    147      1.1  christos     return a + b + c;
    148      1.1  christos }
    149      1.1  christos 
    150      1.1  christos void *ossl_quic_wire_encode_frame_crypto(WPACKET *pkt,
    151  1.1.1.2  christos     const OSSL_QUIC_FRAME_CRYPTO *f)
    152      1.1  christos {
    153      1.1  christos     unsigned char *p = NULL;
    154      1.1  christos 
    155      1.1  christos     if (!ossl_quic_wire_encode_frame_crypto_hdr(pkt, f)
    156  1.1.1.2  christos         || f->len > SIZE_MAX /* sizeof(uint64_t) > sizeof(size_t)? */
    157  1.1.1.2  christos         || !WPACKET_allocate_bytes(pkt, (size_t)f->len, &p))
    158      1.1  christos         return NULL;
    159      1.1  christos 
    160      1.1  christos     if (f->data != NULL)
    161      1.1  christos         memcpy(p, f->data, (size_t)f->len);
    162      1.1  christos 
    163      1.1  christos     return p;
    164      1.1  christos }
    165      1.1  christos 
    166      1.1  christos int ossl_quic_wire_encode_frame_new_token(WPACKET *pkt,
    167  1.1.1.2  christos     const unsigned char *token,
    168  1.1.1.2  christos     size_t token_len)
    169      1.1  christos {
    170      1.1  christos     if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_NEW_TOKEN)
    171  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, token_len)
    172  1.1.1.2  christos         || !WPACKET_memcpy(pkt, token, token_len))
    173      1.1  christos         return 0;
    174      1.1  christos 
    175      1.1  christos     return 1;
    176      1.1  christos }
    177      1.1  christos 
    178      1.1  christos int ossl_quic_wire_encode_frame_stream_hdr(WPACKET *pkt,
    179  1.1.1.2  christos     const OSSL_QUIC_FRAME_STREAM *f)
    180      1.1  christos {
    181      1.1  christos     uint64_t frame_type = OSSL_QUIC_FRAME_TYPE_STREAM;
    182      1.1  christos 
    183      1.1  christos     if (f->offset != 0)
    184      1.1  christos         frame_type |= OSSL_QUIC_FRAME_FLAG_STREAM_OFF;
    185      1.1  christos     if (f->has_explicit_len)
    186      1.1  christos         frame_type |= OSSL_QUIC_FRAME_FLAG_STREAM_LEN;
    187      1.1  christos     if (f->is_fin)
    188      1.1  christos         frame_type |= OSSL_QUIC_FRAME_FLAG_STREAM_FIN;
    189      1.1  christos 
    190      1.1  christos     if (!encode_frame_hdr(pkt, frame_type)
    191  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, f->stream_id))
    192      1.1  christos         return 0;
    193      1.1  christos 
    194      1.1  christos     if (f->offset != 0 && !WPACKET_quic_write_vlint(pkt, f->offset))
    195      1.1  christos         return 0;
    196      1.1  christos 
    197      1.1  christos     if (f->has_explicit_len && !WPACKET_quic_write_vlint(pkt, f->len))
    198      1.1  christos         return 0;
    199      1.1  christos 
    200      1.1  christos     return 1;
    201      1.1  christos }
    202      1.1  christos 
    203      1.1  christos size_t ossl_quic_wire_get_encoded_frame_len_stream_hdr(const OSSL_QUIC_FRAME_STREAM *f)
    204      1.1  christos {
    205      1.1  christos     size_t a, b, c, d;
    206      1.1  christos 
    207      1.1  christos     a = ossl_quic_vlint_encode_len(OSSL_QUIC_FRAME_TYPE_STREAM);
    208      1.1  christos     b = ossl_quic_vlint_encode_len(f->stream_id);
    209      1.1  christos     if (a == 0 || b == 0)
    210      1.1  christos         return 0;
    211      1.1  christos 
    212      1.1  christos     if (f->offset > 0) {
    213      1.1  christos         c = ossl_quic_vlint_encode_len(f->offset);
    214      1.1  christos         if (c == 0)
    215      1.1  christos             return 0;
    216      1.1  christos     } else {
    217      1.1  christos         c = 0;
    218      1.1  christos     }
    219      1.1  christos 
    220      1.1  christos     if (f->has_explicit_len) {
    221      1.1  christos         d = ossl_quic_vlint_encode_len(f->len);
    222      1.1  christos         if (d == 0)
    223      1.1  christos             return 0;
    224      1.1  christos     } else {
    225      1.1  christos         d = 0;
    226      1.1  christos     }
    227      1.1  christos 
    228      1.1  christos     return a + b + c + d;
    229      1.1  christos }
    230      1.1  christos 
    231      1.1  christos void *ossl_quic_wire_encode_frame_stream(WPACKET *pkt,
    232  1.1.1.2  christos     const OSSL_QUIC_FRAME_STREAM *f)
    233      1.1  christos {
    234      1.1  christos 
    235      1.1  christos     unsigned char *p = NULL;
    236      1.1  christos 
    237      1.1  christos     if (!ossl_quic_wire_encode_frame_stream_hdr(pkt, f)
    238  1.1.1.2  christos         || f->len > SIZE_MAX /* sizeof(uint64_t) > sizeof(size_t)? */)
    239      1.1  christos         return NULL;
    240      1.1  christos 
    241      1.1  christos     if (!WPACKET_allocate_bytes(pkt, (size_t)f->len, &p))
    242      1.1  christos         return NULL;
    243      1.1  christos 
    244      1.1  christos     if (f->data != NULL)
    245      1.1  christos         memcpy(p, f->data, (size_t)f->len);
    246      1.1  christos 
    247      1.1  christos     return p;
    248      1.1  christos }
    249      1.1  christos 
    250      1.1  christos int ossl_quic_wire_encode_frame_max_data(WPACKET *pkt,
    251  1.1.1.2  christos     uint64_t max_data)
    252      1.1  christos {
    253      1.1  christos     if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_MAX_DATA)
    254  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, max_data))
    255      1.1  christos         return 0;
    256      1.1  christos 
    257      1.1  christos     return 1;
    258      1.1  christos }
    259      1.1  christos 
    260      1.1  christos int ossl_quic_wire_encode_frame_max_stream_data(WPACKET *pkt,
    261  1.1.1.2  christos     uint64_t stream_id,
    262  1.1.1.2  christos     uint64_t max_data)
    263      1.1  christos {
    264      1.1  christos     if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA)
    265  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, stream_id)
    266  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, max_data))
    267      1.1  christos         return 0;
    268      1.1  christos 
    269      1.1  christos     return 1;
    270      1.1  christos }
    271      1.1  christos 
    272      1.1  christos int ossl_quic_wire_encode_frame_max_streams(WPACKET *pkt,
    273  1.1.1.2  christos     char is_uni,
    274  1.1.1.2  christos     uint64_t max_streams)
    275      1.1  christos {
    276  1.1.1.2  christos     if (!encode_frame_hdr(pkt, is_uni ? OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI : OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI)
    277  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, max_streams))
    278      1.1  christos         return 0;
    279      1.1  christos 
    280      1.1  christos     return 1;
    281      1.1  christos }
    282      1.1  christos 
    283      1.1  christos int ossl_quic_wire_encode_frame_data_blocked(WPACKET *pkt,
    284  1.1.1.2  christos     uint64_t max_data)
    285      1.1  christos {
    286      1.1  christos     if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED)
    287  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, max_data))
    288      1.1  christos         return 0;
    289      1.1  christos 
    290      1.1  christos     return 1;
    291      1.1  christos }
    292      1.1  christos 
    293      1.1  christos int ossl_quic_wire_encode_frame_stream_data_blocked(WPACKET *pkt,
    294  1.1.1.2  christos     uint64_t stream_id,
    295  1.1.1.2  christos     uint64_t max_stream_data)
    296      1.1  christos {
    297      1.1  christos     if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED)
    298  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, stream_id)
    299  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, max_stream_data))
    300      1.1  christos         return 0;
    301      1.1  christos 
    302      1.1  christos     return 1;
    303      1.1  christos }
    304      1.1  christos 
    305      1.1  christos int ossl_quic_wire_encode_frame_streams_blocked(WPACKET *pkt,
    306  1.1.1.2  christos     char is_uni,
    307  1.1.1.2  christos     uint64_t max_streams)
    308      1.1  christos {
    309  1.1.1.2  christos     if (!encode_frame_hdr(pkt, is_uni ? OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_UNI : OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI)
    310  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, max_streams))
    311      1.1  christos         return 0;
    312      1.1  christos 
    313      1.1  christos     return 1;
    314      1.1  christos }
    315      1.1  christos 
    316      1.1  christos int ossl_quic_wire_encode_frame_new_conn_id(WPACKET *pkt,
    317  1.1.1.2  christos     const OSSL_QUIC_FRAME_NEW_CONN_ID *f)
    318      1.1  christos {
    319      1.1  christos     if (f->conn_id.id_len < 1
    320      1.1  christos         || f->conn_id.id_len > QUIC_MAX_CONN_ID_LEN)
    321      1.1  christos         return 0;
    322      1.1  christos 
    323      1.1  christos     if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID)
    324  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, f->seq_num)
    325  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, f->retire_prior_to)
    326  1.1.1.2  christos         || !WPACKET_put_bytes_u8(pkt, f->conn_id.id_len)
    327  1.1.1.2  christos         || !WPACKET_memcpy(pkt, f->conn_id.id, f->conn_id.id_len)
    328  1.1.1.2  christos         || !WPACKET_memcpy(pkt, f->stateless_reset.token,
    329  1.1.1.2  christos             sizeof(f->stateless_reset.token)))
    330      1.1  christos         return 0;
    331      1.1  christos 
    332      1.1  christos     return 1;
    333      1.1  christos }
    334      1.1  christos 
    335      1.1  christos int ossl_quic_wire_encode_frame_retire_conn_id(WPACKET *pkt,
    336  1.1.1.2  christos     uint64_t seq_num)
    337      1.1  christos {
    338      1.1  christos     if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID)
    339  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, seq_num))
    340      1.1  christos         return 0;
    341      1.1  christos 
    342      1.1  christos     return 1;
    343      1.1  christos }
    344      1.1  christos 
    345      1.1  christos int ossl_quic_wire_encode_frame_path_challenge(WPACKET *pkt,
    346  1.1.1.2  christos     uint64_t data)
    347      1.1  christos {
    348      1.1  christos     if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE)
    349  1.1.1.2  christos         || !WPACKET_put_bytes_u64(pkt, data))
    350      1.1  christos         return 0;
    351      1.1  christos 
    352      1.1  christos     return 1;
    353      1.1  christos }
    354      1.1  christos 
    355      1.1  christos int ossl_quic_wire_encode_frame_path_response(WPACKET *pkt,
    356  1.1.1.2  christos     uint64_t data)
    357      1.1  christos {
    358      1.1  christos     if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE)
    359  1.1.1.2  christos         || !WPACKET_put_bytes_u64(pkt, data))
    360      1.1  christos         return 0;
    361      1.1  christos 
    362      1.1  christos     return 1;
    363      1.1  christos }
    364      1.1  christos 
    365      1.1  christos int ossl_quic_wire_encode_frame_conn_close(WPACKET *pkt,
    366  1.1.1.2  christos     const OSSL_QUIC_FRAME_CONN_CLOSE *f)
    367      1.1  christos {
    368  1.1.1.2  christos     if (!encode_frame_hdr(pkt, f->is_app ? OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP : OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT)
    369  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, f->error_code))
    370      1.1  christos         return 0;
    371      1.1  christos 
    372      1.1  christos     /*
    373      1.1  christos      * RFC 9000 s. 19.19: The application-specific variant of CONNECTION_CLOSE
    374      1.1  christos      * (type 0x1d) does not include this field.
    375      1.1  christos      */
    376      1.1  christos     if (!f->is_app && !WPACKET_quic_write_vlint(pkt, f->frame_type))
    377      1.1  christos         return 0;
    378      1.1  christos 
    379      1.1  christos     if (!WPACKET_quic_write_vlint(pkt, f->reason_len)
    380  1.1.1.2  christos         || !WPACKET_memcpy(pkt, f->reason, f->reason_len))
    381      1.1  christos         return 0;
    382      1.1  christos 
    383      1.1  christos     return 1;
    384      1.1  christos }
    385      1.1  christos 
    386      1.1  christos int ossl_quic_wire_encode_frame_handshake_done(WPACKET *pkt)
    387      1.1  christos {
    388      1.1  christos     return encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE);
    389      1.1  christos }
    390      1.1  christos 
    391      1.1  christos unsigned char *ossl_quic_wire_encode_transport_param_bytes(WPACKET *pkt,
    392  1.1.1.2  christos     uint64_t id,
    393  1.1.1.2  christos     const unsigned char *value,
    394  1.1.1.2  christos     size_t value_len)
    395      1.1  christos {
    396      1.1  christos     unsigned char *b = NULL;
    397      1.1  christos 
    398      1.1  christos     if (!WPACKET_quic_write_vlint(pkt, id)
    399      1.1  christos         || !WPACKET_quic_write_vlint(pkt, value_len))
    400      1.1  christos         return NULL;
    401      1.1  christos 
    402      1.1  christos     if (value_len == 0)
    403      1.1  christos         b = WPACKET_get_curr(pkt);
    404      1.1  christos     else if (!WPACKET_allocate_bytes(pkt, value_len, (unsigned char **)&b))
    405      1.1  christos         return NULL;
    406      1.1  christos 
    407      1.1  christos     if (value != NULL)
    408      1.1  christos         memcpy(b, value, value_len);
    409      1.1  christos 
    410      1.1  christos     return b;
    411      1.1  christos }
    412      1.1  christos 
    413      1.1  christos int ossl_quic_wire_encode_transport_param_int(WPACKET *pkt,
    414  1.1.1.2  christos     uint64_t id,
    415  1.1.1.2  christos     uint64_t value)
    416      1.1  christos {
    417      1.1  christos     if (!WPACKET_quic_write_vlint(pkt, id)
    418  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, ossl_quic_vlint_encode_len(value))
    419  1.1.1.2  christos         || !WPACKET_quic_write_vlint(pkt, value))
    420      1.1  christos         return 0;
    421      1.1  christos 
    422      1.1  christos     return 1;
    423      1.1  christos }
    424      1.1  christos 
    425      1.1  christos int ossl_quic_wire_encode_transport_param_cid(WPACKET *wpkt,
    426  1.1.1.2  christos     uint64_t id,
    427  1.1.1.2  christos     const QUIC_CONN_ID *cid)
    428      1.1  christos {
    429      1.1  christos     if (cid->id_len > QUIC_MAX_CONN_ID_LEN)
    430      1.1  christos         return 0;
    431      1.1  christos 
    432      1.1  christos     if (ossl_quic_wire_encode_transport_param_bytes(wpkt, id,
    433  1.1.1.2  christos             cid->id,
    434  1.1.1.2  christos             cid->id_len)
    435  1.1.1.2  christos         == NULL)
    436      1.1  christos         return 0;
    437      1.1  christos 
    438      1.1  christos     return 1;
    439      1.1  christos }
    440      1.1  christos 
    441      1.1  christos /*
    442      1.1  christos  * QUIC Wire Format Decoding
    443      1.1  christos  * =========================
    444      1.1  christos  */
    445      1.1  christos int ossl_quic_wire_peek_frame_header(PACKET *pkt, uint64_t *type,
    446  1.1.1.2  christos     int *was_minimal)
    447      1.1  christos {
    448      1.1  christos     return PACKET_peek_quic_vlint_ex(pkt, type, was_minimal);
    449      1.1  christos }
    450      1.1  christos 
    451      1.1  christos int ossl_quic_wire_skip_frame_header(PACKET *pkt, uint64_t *type)
    452      1.1  christos {
    453      1.1  christos     return PACKET_get_quic_vlint(pkt, type);
    454      1.1  christos }
    455      1.1  christos 
    456      1.1  christos static int expect_frame_header_mask(PACKET *pkt,
    457  1.1.1.2  christos     uint64_t expected_frame_type,
    458  1.1.1.2  christos     uint64_t mask_bits,
    459  1.1.1.2  christos     uint64_t *actual_frame_type)
    460      1.1  christos {
    461      1.1  christos     uint64_t actual_frame_type_;
    462      1.1  christos 
    463      1.1  christos     if (!ossl_quic_wire_skip_frame_header(pkt, &actual_frame_type_)
    464  1.1.1.2  christos         || (actual_frame_type_ & ~mask_bits) != expected_frame_type)
    465      1.1  christos         return 0;
    466      1.1  christos 
    467      1.1  christos     if (actual_frame_type != NULL)
    468      1.1  christos         *actual_frame_type = actual_frame_type_;
    469      1.1  christos 
    470      1.1  christos     return 1;
    471      1.1  christos }
    472      1.1  christos 
    473      1.1  christos static int expect_frame_header(PACKET *pkt, uint64_t expected_frame_type)
    474      1.1  christos {
    475      1.1  christos     uint64_t actual_frame_type;
    476      1.1  christos 
    477      1.1  christos     if (!ossl_quic_wire_skip_frame_header(pkt, &actual_frame_type)
    478  1.1.1.2  christos         || actual_frame_type != expected_frame_type)
    479      1.1  christos         return 0;
    480      1.1  christos 
    481      1.1  christos     return 1;
    482      1.1  christos }
    483      1.1  christos 
    484      1.1  christos int ossl_quic_wire_peek_frame_ack_num_ranges(const PACKET *orig_pkt,
    485  1.1.1.2  christos     uint64_t *total_ranges)
    486      1.1  christos {
    487      1.1  christos     PACKET pkt = *orig_pkt;
    488      1.1  christos     uint64_t ack_range_count, i;
    489      1.1  christos 
    490      1.1  christos     if (!expect_frame_header_mask(&pkt, OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN,
    491  1.1.1.2  christos             1, NULL)
    492  1.1.1.2  christos         || !PACKET_skip_quic_vlint(&pkt)
    493  1.1.1.2  christos         || !PACKET_skip_quic_vlint(&pkt)
    494  1.1.1.2  christos         || !PACKET_get_quic_vlint(&pkt, &ack_range_count))
    495      1.1  christos         return 0;
    496      1.1  christos 
    497      1.1  christos     /*
    498      1.1  christos      * Ensure the specified number of ack ranges listed in the ACK frame header
    499      1.1  christos      * actually are available in the frame data. This naturally bounds the
    500      1.1  christos      * number of ACK ranges which can be requested by the MDPL, and therefore by
    501      1.1  christos      * the MTU. This ensures we do not allocate memory for an excessive number
    502      1.1  christos      * of ACK ranges.
    503      1.1  christos      */
    504      1.1  christos     for (i = 0; i < ack_range_count; ++i)
    505      1.1  christos         if (!PACKET_skip_quic_vlint(&pkt)
    506      1.1  christos             || !PACKET_skip_quic_vlint(&pkt))
    507      1.1  christos             return 0;
    508      1.1  christos 
    509      1.1  christos     /* (cannot overflow because QUIC vlints can only encode up to 2**62-1) */
    510      1.1  christos     *total_ranges = ack_range_count + 1;
    511      1.1  christos     return 1;
    512      1.1  christos }
    513      1.1  christos 
    514      1.1  christos int ossl_quic_wire_decode_frame_ack(PACKET *pkt,
    515  1.1.1.2  christos     uint32_t ack_delay_exponent,
    516  1.1.1.2  christos     OSSL_QUIC_FRAME_ACK *ack,
    517  1.1.1.2  christos     uint64_t *total_ranges)
    518  1.1.1.2  christos {
    519      1.1  christos     uint64_t frame_type, largest_ackd, ack_delay_raw;
    520      1.1  christos     uint64_t ack_range_count, first_ack_range, start, end, i;
    521      1.1  christos 
    522      1.1  christos     /* This call matches both ACK_WITHOUT_ECN and ACK_WITH_ECN. */
    523      1.1  christos     if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN,
    524  1.1.1.2  christos             1, &frame_type)
    525  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, &largest_ackd)
    526  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, &ack_delay_raw)
    527  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, &ack_range_count)
    528  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, &first_ack_range))
    529      1.1  christos         return 0;
    530      1.1  christos 
    531      1.1  christos     if (first_ack_range > largest_ackd)
    532      1.1  christos         return 0;
    533      1.1  christos 
    534      1.1  christos     if (ack_range_count > SIZE_MAX /* sizeof(uint64_t) > sizeof(size_t)? */)
    535      1.1  christos         return 0;
    536      1.1  christos 
    537      1.1  christos     start = largest_ackd - first_ack_range;
    538      1.1  christos 
    539      1.1  christos     if (ack != NULL) {
    540      1.1  christos         int err = 0;
    541      1.1  christos         ack->delay_time
    542      1.1  christos             = ossl_time_multiply(ossl_ticks2time(OSSL_TIME_US),
    543  1.1.1.2  christos                 safe_mul_uint64_t(ack_delay_raw,
    544  1.1.1.2  christos                     (uint64_t)1 << ack_delay_exponent,
    545  1.1.1.2  christos                     &err));
    546      1.1  christos         if (err)
    547      1.1  christos             ack->delay_time = ossl_time_infinite();
    548      1.1  christos 
    549      1.1  christos         if (ack->num_ack_ranges > 0) {
    550  1.1.1.2  christos             ack->ack_ranges[0].end = largest_ackd;
    551      1.1  christos             ack->ack_ranges[0].start = start;
    552      1.1  christos         }
    553      1.1  christos     }
    554      1.1  christos 
    555      1.1  christos     for (i = 0; i < ack_range_count; ++i) {
    556      1.1  christos         uint64_t gap, len;
    557      1.1  christos 
    558      1.1  christos         if (!PACKET_get_quic_vlint(pkt, &gap)
    559  1.1.1.2  christos             || !PACKET_get_quic_vlint(pkt, &len))
    560      1.1  christos             return 0;
    561      1.1  christos 
    562      1.1  christos         end = start - gap - 2;
    563      1.1  christos         if (start < gap + 2 || len > end)
    564      1.1  christos             return 0;
    565      1.1  christos 
    566      1.1  christos         if (ack != NULL && i + 1 < ack->num_ack_ranges) {
    567      1.1  christos             ack->ack_ranges[i + 1].start = start = end - len;
    568  1.1.1.2  christos             ack->ack_ranges[i + 1].end = end;
    569      1.1  christos         }
    570      1.1  christos     }
    571      1.1  christos 
    572      1.1  christos     if (ack != NULL && ack_range_count + 1 < ack->num_ack_ranges)
    573      1.1  christos         ack->num_ack_ranges = (size_t)ack_range_count + 1;
    574      1.1  christos 
    575      1.1  christos     if (total_ranges != NULL)
    576      1.1  christos         *total_ranges = ack_range_count + 1;
    577      1.1  christos 
    578      1.1  christos     if (frame_type == OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN) {
    579      1.1  christos         uint64_t ect0, ect1, ecnce;
    580      1.1  christos 
    581      1.1  christos         if (!PACKET_get_quic_vlint(pkt, &ect0)
    582  1.1.1.2  christos             || !PACKET_get_quic_vlint(pkt, &ect1)
    583  1.1.1.2  christos             || !PACKET_get_quic_vlint(pkt, &ecnce))
    584      1.1  christos             return 0;
    585      1.1  christos 
    586      1.1  christos         if (ack != NULL) {
    587  1.1.1.2  christos             ack->ect0 = ect0;
    588  1.1.1.2  christos             ack->ect1 = ect1;
    589  1.1.1.2  christos             ack->ecnce = ecnce;
    590  1.1.1.2  christos             ack->ecn_present = 1;
    591      1.1  christos         }
    592      1.1  christos     } else if (ack != NULL) {
    593      1.1  christos         ack->ecn_present = 0;
    594      1.1  christos     }
    595      1.1  christos 
    596      1.1  christos     return 1;
    597      1.1  christos }
    598      1.1  christos 
    599      1.1  christos int ossl_quic_wire_decode_frame_reset_stream(PACKET *pkt,
    600  1.1.1.2  christos     OSSL_QUIC_FRAME_RESET_STREAM *f)
    601      1.1  christos {
    602      1.1  christos     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_RESET_STREAM)
    603  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, &f->stream_id)
    604  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, &f->app_error_code)
    605  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, &f->final_size))
    606      1.1  christos         return 0;
    607      1.1  christos 
    608      1.1  christos     return 1;
    609      1.1  christos }
    610      1.1  christos 
    611      1.1  christos int ossl_quic_wire_decode_frame_stop_sending(PACKET *pkt,
    612  1.1.1.2  christos     OSSL_QUIC_FRAME_STOP_SENDING *f)
    613      1.1  christos {
    614      1.1  christos     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_STOP_SENDING)
    615  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, &f->stream_id)
    616  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, &f->app_error_code))
    617      1.1  christos         return 0;
    618      1.1  christos 
    619      1.1  christos     return 1;
    620      1.1  christos }
    621      1.1  christos 
    622      1.1  christos int ossl_quic_wire_decode_frame_crypto(PACKET *pkt,
    623  1.1.1.2  christos     int nodata,
    624  1.1.1.2  christos     OSSL_QUIC_FRAME_CRYPTO *f)
    625      1.1  christos {
    626      1.1  christos     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_CRYPTO)
    627  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, &f->offset)
    628  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, &f->len)
    629  1.1.1.2  christos         || f->len > SIZE_MAX /* sizeof(uint64_t) > sizeof(size_t)? */)
    630      1.1  christos         return 0;
    631      1.1  christos 
    632      1.1  christos     if (f->offset + f->len > (((uint64_t)1) << 62) - 1)
    633      1.1  christos         /* RFC 9000 s. 19.6 */
    634      1.1  christos         return 0;
    635      1.1  christos 
    636      1.1  christos     if (nodata) {
    637      1.1  christos         f->data = NULL;
    638      1.1  christos     } else {
    639      1.1  christos         if (PACKET_remaining(pkt) < f->len)
    640      1.1  christos             return 0;
    641      1.1  christos 
    642      1.1  christos         f->data = PACKET_data(pkt);
    643      1.1  christos 
    644      1.1  christos         if (!PACKET_forward(pkt, (size_t)f->len))
    645      1.1  christos             return 0;
    646      1.1  christos     }
    647      1.1  christos 
    648      1.1  christos     return 1;
    649      1.1  christos }
    650      1.1  christos 
    651  1.1.1.2  christos int ossl_quic_wire_decode_frame_new_token(PACKET *pkt,
    652  1.1.1.2  christos     const unsigned char **token,
    653  1.1.1.2  christos     size_t *token_len)
    654      1.1  christos {
    655      1.1  christos     uint64_t token_len_;
    656      1.1  christos 
    657      1.1  christos     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_NEW_TOKEN)
    658  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, &token_len_))
    659      1.1  christos         return 0;
    660      1.1  christos 
    661      1.1  christos     if (token_len_ > SIZE_MAX)
    662      1.1  christos         return 0;
    663      1.1  christos 
    664  1.1.1.2  christos     *token = PACKET_data(pkt);
    665  1.1.1.2  christos     *token_len = (size_t)token_len_;
    666      1.1  christos 
    667      1.1  christos     if (!PACKET_forward(pkt, (size_t)token_len_))
    668      1.1  christos         return 0;
    669      1.1  christos 
    670      1.1  christos     return 1;
    671      1.1  christos }
    672      1.1  christos 
    673      1.1  christos int ossl_quic_wire_decode_frame_stream(PACKET *pkt,
    674  1.1.1.2  christos     int nodata,
    675  1.1.1.2  christos     OSSL_QUIC_FRAME_STREAM *f)
    676      1.1  christos {
    677      1.1  christos     uint64_t frame_type;
    678      1.1  christos 
    679      1.1  christos     /* This call matches all STREAM values (low 3 bits are masked). */
    680      1.1  christos     if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_STREAM,
    681  1.1.1.2  christos             OSSL_QUIC_FRAME_FLAG_STREAM_MASK,
    682  1.1.1.2  christos             &frame_type)
    683  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, &f->stream_id))
    684      1.1  christos         return 0;
    685      1.1  christos 
    686      1.1  christos     if ((frame_type & OSSL_QUIC_FRAME_FLAG_STREAM_OFF) != 0) {
    687      1.1  christos         if (!PACKET_get_quic_vlint(pkt, &f->offset))
    688      1.1  christos             return 0;
    689      1.1  christos     } else {
    690      1.1  christos         f->offset = 0;
    691      1.1  christos     }
    692      1.1  christos 
    693      1.1  christos     f->has_explicit_len = ((frame_type & OSSL_QUIC_FRAME_FLAG_STREAM_LEN) != 0);
    694  1.1.1.2  christos     f->is_fin = ((frame_type & OSSL_QUIC_FRAME_FLAG_STREAM_FIN) != 0);
    695      1.1  christos 
    696      1.1  christos     if (f->has_explicit_len) {
    697      1.1  christos         if (!PACKET_get_quic_vlint(pkt, &f->len))
    698      1.1  christos             return 0;
    699      1.1  christos     } else {
    700      1.1  christos         if (nodata)
    701      1.1  christos             f->len = 0;
    702      1.1  christos         else
    703      1.1  christos             f->len = PACKET_remaining(pkt);
    704      1.1  christos     }
    705      1.1  christos 
    706      1.1  christos     /*
    707      1.1  christos      * RFC 9000 s. 19.8: "The largest offset delivered on a stream -- the sum of
    708      1.1  christos      * the offset and data length -- cannot exceed 2**62 - 1, as it is not
    709      1.1  christos      * possible to provide flow control credit for that data."
    710      1.1  christos      */
    711      1.1  christos     if (f->offset + f->len > (((uint64_t)1) << 62) - 1)
    712      1.1  christos         return 0;
    713      1.1  christos 
    714      1.1  christos     if (nodata) {
    715      1.1  christos         f->data = NULL;
    716      1.1  christos     } else {
    717      1.1  christos         f->data = PACKET_data(pkt);
    718      1.1  christos 
    719      1.1  christos         if (f->len > SIZE_MAX /* sizeof(uint64_t) > sizeof(size_t)? */
    720      1.1  christos             || !PACKET_forward(pkt, (size_t)f->len))
    721      1.1  christos             return 0;
    722      1.1  christos     }
    723      1.1  christos 
    724      1.1  christos     return 1;
    725      1.1  christos }
    726      1.1  christos 
    727      1.1  christos int ossl_quic_wire_decode_frame_max_data(PACKET *pkt,
    728  1.1.1.2  christos     uint64_t *max_data)
    729      1.1  christos {
    730      1.1  christos     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_MAX_DATA)
    731  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, max_data))
    732      1.1  christos         return 0;
    733      1.1  christos 
    734      1.1  christos     return 1;
    735      1.1  christos }
    736      1.1  christos 
    737      1.1  christos int ossl_quic_wire_decode_frame_max_stream_data(PACKET *pkt,
    738  1.1.1.2  christos     uint64_t *stream_id,
    739  1.1.1.2  christos     uint64_t *max_stream_data)
    740      1.1  christos {
    741      1.1  christos     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA)
    742  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, stream_id)
    743  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, max_stream_data))
    744      1.1  christos         return 0;
    745      1.1  christos 
    746      1.1  christos     return 1;
    747      1.1  christos }
    748      1.1  christos 
    749      1.1  christos int ossl_quic_wire_decode_frame_max_streams(PACKET *pkt,
    750  1.1.1.2  christos     uint64_t *max_streams)
    751      1.1  christos {
    752      1.1  christos     /* This call matches both MAX_STREAMS_BIDI and MAX_STREAMS_UNI. */
    753      1.1  christos     if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI,
    754  1.1.1.2  christos             1, NULL)
    755  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, max_streams))
    756      1.1  christos         return 0;
    757      1.1  christos 
    758      1.1  christos     return 1;
    759      1.1  christos }
    760      1.1  christos 
    761      1.1  christos int ossl_quic_wire_decode_frame_data_blocked(PACKET *pkt,
    762  1.1.1.2  christos     uint64_t *max_data)
    763      1.1  christos {
    764      1.1  christos     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED)
    765  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, max_data))
    766      1.1  christos         return 0;
    767      1.1  christos 
    768      1.1  christos     return 1;
    769      1.1  christos }
    770      1.1  christos 
    771      1.1  christos int ossl_quic_wire_decode_frame_stream_data_blocked(PACKET *pkt,
    772  1.1.1.2  christos     uint64_t *stream_id,
    773  1.1.1.2  christos     uint64_t *max_stream_data)
    774      1.1  christos {
    775      1.1  christos     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED)
    776  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, stream_id)
    777  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, max_stream_data))
    778      1.1  christos         return 0;
    779      1.1  christos 
    780      1.1  christos     return 1;
    781      1.1  christos }
    782      1.1  christos 
    783      1.1  christos int ossl_quic_wire_decode_frame_streams_blocked(PACKET *pkt,
    784  1.1.1.2  christos     uint64_t *max_streams)
    785      1.1  christos {
    786      1.1  christos     /* This call matches both STREAMS_BLOCKED_BIDI and STREAMS_BLOCKED_UNI. */
    787      1.1  christos     if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI,
    788  1.1.1.2  christos             1, NULL)
    789  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, max_streams))
    790      1.1  christos         return 0;
    791      1.1  christos 
    792      1.1  christos     return 1;
    793      1.1  christos }
    794      1.1  christos 
    795      1.1  christos int ossl_quic_wire_decode_frame_new_conn_id(PACKET *pkt,
    796  1.1.1.2  christos     OSSL_QUIC_FRAME_NEW_CONN_ID *f)
    797      1.1  christos {
    798      1.1  christos     unsigned int len;
    799      1.1  christos 
    800      1.1  christos     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID)
    801  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, &f->seq_num)
    802  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, &f->retire_prior_to)
    803  1.1.1.2  christos         || f->seq_num < f->retire_prior_to
    804  1.1.1.2  christos         || !PACKET_get_1(pkt, &len)
    805  1.1.1.2  christos         || len < 1
    806  1.1.1.2  christos         || len > QUIC_MAX_CONN_ID_LEN)
    807      1.1  christos         return 0;
    808      1.1  christos 
    809      1.1  christos     f->conn_id.id_len = (unsigned char)len;
    810      1.1  christos     if (!PACKET_copy_bytes(pkt, f->conn_id.id, len))
    811      1.1  christos         return 0;
    812      1.1  christos 
    813      1.1  christos     /* Clear unused bytes to allow consistent memcmp. */
    814      1.1  christos     if (len < QUIC_MAX_CONN_ID_LEN)
    815      1.1  christos         memset(f->conn_id.id + len, 0, QUIC_MAX_CONN_ID_LEN - len);
    816      1.1  christos 
    817      1.1  christos     if (!PACKET_copy_bytes(pkt, f->stateless_reset.token,
    818  1.1.1.2  christos             sizeof(f->stateless_reset.token)))
    819      1.1  christos         return 0;
    820      1.1  christos 
    821      1.1  christos     return 1;
    822      1.1  christos }
    823      1.1  christos 
    824      1.1  christos int ossl_quic_wire_decode_frame_retire_conn_id(PACKET *pkt,
    825  1.1.1.2  christos     uint64_t *seq_num)
    826      1.1  christos {
    827      1.1  christos     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID)
    828  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, seq_num))
    829      1.1  christos         return 0;
    830      1.1  christos 
    831      1.1  christos     return 1;
    832      1.1  christos }
    833      1.1  christos 
    834      1.1  christos int ossl_quic_wire_decode_frame_path_challenge(PACKET *pkt,
    835  1.1.1.2  christos     uint64_t *data)
    836      1.1  christos {
    837      1.1  christos     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE)
    838  1.1.1.2  christos         || !PACKET_get_net_8(pkt, data))
    839      1.1  christos         return 0;
    840      1.1  christos 
    841      1.1  christos     return 1;
    842      1.1  christos }
    843      1.1  christos 
    844      1.1  christos int ossl_quic_wire_decode_frame_path_response(PACKET *pkt,
    845  1.1.1.2  christos     uint64_t *data)
    846      1.1  christos {
    847      1.1  christos     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE)
    848  1.1.1.2  christos         || !PACKET_get_net_8(pkt, data))
    849      1.1  christos         return 0;
    850      1.1  christos 
    851      1.1  christos     return 1;
    852      1.1  christos }
    853      1.1  christos 
    854      1.1  christos int ossl_quic_wire_decode_frame_conn_close(PACKET *pkt,
    855  1.1.1.2  christos     OSSL_QUIC_FRAME_CONN_CLOSE *f)
    856      1.1  christos {
    857      1.1  christos     uint64_t frame_type, reason_len;
    858      1.1  christos 
    859      1.1  christos     /* This call matches both CONN_CLOSE_TRANSPORT and CONN_CLOSE_APP. */
    860      1.1  christos     if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT,
    861  1.1.1.2  christos             1, &frame_type)
    862  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, &f->error_code))
    863      1.1  christos         return 0;
    864      1.1  christos 
    865      1.1  christos     f->is_app = ((frame_type & 1) != 0);
    866      1.1  christos 
    867      1.1  christos     if (!f->is_app) {
    868      1.1  christos         if (!PACKET_get_quic_vlint(pkt, &f->frame_type))
    869      1.1  christos             return 0;
    870      1.1  christos     } else {
    871      1.1  christos         f->frame_type = 0;
    872      1.1  christos     }
    873      1.1  christos 
    874      1.1  christos     if (!PACKET_get_quic_vlint(pkt, &reason_len)
    875  1.1.1.2  christos         || reason_len > SIZE_MAX)
    876      1.1  christos         return 0;
    877      1.1  christos 
    878      1.1  christos     if (!PACKET_get_bytes(pkt, (const unsigned char **)&f->reason,
    879  1.1.1.2  christos             (size_t)reason_len))
    880      1.1  christos         return 0;
    881      1.1  christos 
    882      1.1  christos     f->reason_len = (size_t)reason_len;
    883      1.1  christos     return 1;
    884      1.1  christos }
    885      1.1  christos 
    886      1.1  christos size_t ossl_quic_wire_decode_padding(PACKET *pkt)
    887      1.1  christos {
    888      1.1  christos     const unsigned char *start = PACKET_data(pkt), *end = PACKET_end(pkt),
    889      1.1  christos                         *p = start;
    890      1.1  christos 
    891      1.1  christos     while (p < end && *p == 0)
    892      1.1  christos         ++p;
    893      1.1  christos 
    894      1.1  christos     if (!PACKET_forward(pkt, p - start))
    895      1.1  christos         return 0;
    896      1.1  christos 
    897      1.1  christos     return p - start;
    898      1.1  christos }
    899      1.1  christos 
    900      1.1  christos int ossl_quic_wire_decode_frame_ping(PACKET *pkt)
    901      1.1  christos {
    902      1.1  christos     return expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_PING);
    903      1.1  christos }
    904      1.1  christos 
    905      1.1  christos int ossl_quic_wire_decode_frame_handshake_done(PACKET *pkt)
    906      1.1  christos {
    907      1.1  christos     return expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE);
    908      1.1  christos }
    909      1.1  christos 
    910      1.1  christos int ossl_quic_wire_peek_transport_param(PACKET *pkt, uint64_t *id)
    911      1.1  christos {
    912      1.1  christos     return PACKET_peek_quic_vlint(pkt, id);
    913      1.1  christos }
    914      1.1  christos 
    915      1.1  christos const unsigned char *ossl_quic_wire_decode_transport_param_bytes(PACKET *pkt,
    916  1.1.1.2  christos     uint64_t *id,
    917  1.1.1.2  christos     size_t *len)
    918      1.1  christos {
    919      1.1  christos     uint64_t len_;
    920      1.1  christos     const unsigned char *b = NULL;
    921      1.1  christos     uint64_t id_;
    922      1.1  christos 
    923      1.1  christos     if (!PACKET_get_quic_vlint(pkt, &id_)
    924  1.1.1.2  christos         || !PACKET_get_quic_vlint(pkt, &len_))
    925      1.1  christos         return NULL;
    926      1.1  christos 
    927      1.1  christos     if (len_ > SIZE_MAX
    928  1.1.1.2  christos         || !PACKET_get_bytes(pkt, (const unsigned char **)&b, (size_t)len_))
    929      1.1  christos         return NULL;
    930      1.1  christos 
    931      1.1  christos     *len = (size_t)len_;
    932      1.1  christos     if (id != NULL)
    933      1.1  christos         *id = id_;
    934      1.1  christos     return b;
    935      1.1  christos }
    936      1.1  christos 
    937      1.1  christos int ossl_quic_wire_decode_transport_param_int(PACKET *pkt,
    938  1.1.1.2  christos     uint64_t *id,
    939  1.1.1.2  christos     uint64_t *value)
    940      1.1  christos {
    941      1.1  christos     PACKET sub;
    942      1.1  christos 
    943      1.1  christos     sub.curr = ossl_quic_wire_decode_transport_param_bytes(pkt,
    944  1.1.1.2  christos         id, &sub.remaining);
    945      1.1  christos     if (sub.curr == NULL)
    946      1.1  christos         return 0;
    947      1.1  christos 
    948      1.1  christos     if (!PACKET_get_quic_vlint(&sub, value))
    949      1.1  christos         return 0;
    950      1.1  christos 
    951      1.1  christos     if (PACKET_remaining(&sub) > 0)
    952      1.1  christos         return 0;
    953      1.1  christos 
    954  1.1.1.2  christos     return 1;
    955      1.1  christos }
    956      1.1  christos 
    957      1.1  christos int ossl_quic_wire_decode_transport_param_cid(PACKET *pkt,
    958  1.1.1.2  christos     uint64_t *id,
    959  1.1.1.2  christos     QUIC_CONN_ID *cid)
    960      1.1  christos {
    961      1.1  christos     const unsigned char *body;
    962      1.1  christos     size_t len = 0;
    963      1.1  christos 
    964      1.1  christos     body = ossl_quic_wire_decode_transport_param_bytes(pkt, id, &len);
    965      1.1  christos     if (body == NULL || len > QUIC_MAX_CONN_ID_LEN)
    966      1.1  christos         return 0;
    967      1.1  christos 
    968      1.1  christos     cid->id_len = (unsigned char)len;
    969      1.1  christos     memcpy(cid->id, body, cid->id_len);
    970      1.1  christos     return 1;
    971      1.1  christos }
    972      1.1  christos 
    973      1.1  christos int ossl_quic_wire_decode_transport_param_preferred_addr(PACKET *pkt,
    974  1.1.1.2  christos     QUIC_PREFERRED_ADDR *p)
    975      1.1  christos {
    976      1.1  christos     const unsigned char *body;
    977      1.1  christos     uint64_t id;
    978      1.1  christos     size_t len = 0;
    979      1.1  christos     PACKET pkt2;
    980      1.1  christos     unsigned int ipv4_port, ipv6_port, cidl;
    981      1.1  christos 
    982      1.1  christos     body = ossl_quic_wire_decode_transport_param_bytes(pkt, &id, &len);
    983      1.1  christos     if (body == NULL
    984      1.1  christos         || len < QUIC_MIN_ENCODED_PREFERRED_ADDR_LEN
    985      1.1  christos         || len > QUIC_MAX_ENCODED_PREFERRED_ADDR_LEN
    986      1.1  christos         || id != QUIC_TPARAM_PREFERRED_ADDR)
    987      1.1  christos         return 0;
    988      1.1  christos 
    989      1.1  christos     if (!PACKET_buf_init(&pkt2, body, len))
    990      1.1  christos         return 0;
    991      1.1  christos 
    992      1.1  christos     if (!PACKET_copy_bytes(&pkt2, p->ipv4, sizeof(p->ipv4))
    993      1.1  christos         || !PACKET_get_net_2(&pkt2, &ipv4_port)
    994      1.1  christos         || !PACKET_copy_bytes(&pkt2, p->ipv6, sizeof(p->ipv6))
    995      1.1  christos         || !PACKET_get_net_2(&pkt2, &ipv6_port)
    996      1.1  christos         || !PACKET_get_1(&pkt2, &cidl)
    997      1.1  christos         || cidl > QUIC_MAX_CONN_ID_LEN
    998      1.1  christos         || !PACKET_copy_bytes(&pkt2, p->cid.id, cidl)
    999      1.1  christos         || !PACKET_copy_bytes(&pkt2, p->stateless_reset.token,
   1000  1.1.1.2  christos             sizeof(p->stateless_reset.token)))
   1001      1.1  christos         return 0;
   1002      1.1  christos 
   1003  1.1.1.2  christos     p->ipv4_port = (uint16_t)ipv4_port;
   1004  1.1.1.2  christos     p->ipv6_port = (uint16_t)ipv6_port;
   1005  1.1.1.2  christos     p->cid.id_len = (unsigned char)cidl;
   1006      1.1  christos     return 1;
   1007      1.1  christos }
   1008      1.1  christos 
   1009      1.1  christos const char *
   1010      1.1  christos ossl_quic_frame_type_to_string(uint64_t frame_type)
   1011      1.1  christos {
   1012      1.1  christos     switch (frame_type) {
   1013  1.1.1.2  christos #define X(name)                       \
   1014  1.1.1.2  christos     case OSSL_QUIC_FRAME_TYPE_##name: \
   1015  1.1.1.2  christos         return #name;
   1016  1.1.1.2  christos         X(PADDING)
   1017  1.1.1.2  christos         X(PING)
   1018  1.1.1.2  christos         X(ACK_WITHOUT_ECN)
   1019  1.1.1.2  christos         X(ACK_WITH_ECN)
   1020  1.1.1.2  christos         X(RESET_STREAM)
   1021  1.1.1.2  christos         X(STOP_SENDING)
   1022  1.1.1.2  christos         X(CRYPTO)
   1023  1.1.1.2  christos         X(NEW_TOKEN)
   1024  1.1.1.2  christos         X(MAX_DATA)
   1025  1.1.1.2  christos         X(MAX_STREAM_DATA)
   1026  1.1.1.2  christos         X(MAX_STREAMS_BIDI)
   1027  1.1.1.2  christos         X(MAX_STREAMS_UNI)
   1028  1.1.1.2  christos         X(DATA_BLOCKED)
   1029  1.1.1.2  christos         X(STREAM_DATA_BLOCKED)
   1030  1.1.1.2  christos         X(STREAMS_BLOCKED_BIDI)
   1031  1.1.1.2  christos         X(STREAMS_BLOCKED_UNI)
   1032  1.1.1.2  christos         X(NEW_CONN_ID)
   1033  1.1.1.2  christos         X(RETIRE_CONN_ID)
   1034  1.1.1.2  christos         X(PATH_CHALLENGE)
   1035  1.1.1.2  christos         X(PATH_RESPONSE)
   1036  1.1.1.2  christos         X(CONN_CLOSE_TRANSPORT)
   1037  1.1.1.2  christos         X(CONN_CLOSE_APP)
   1038  1.1.1.2  christos         X(HANDSHAKE_DONE)
   1039  1.1.1.2  christos         X(STREAM)
   1040  1.1.1.2  christos         X(STREAM_FIN)
   1041  1.1.1.2  christos         X(STREAM_LEN)
   1042  1.1.1.2  christos         X(STREAM_LEN_FIN)
   1043  1.1.1.2  christos         X(STREAM_OFF)
   1044  1.1.1.2  christos         X(STREAM_OFF_FIN)
   1045  1.1.1.2  christos         X(STREAM_OFF_LEN)
   1046  1.1.1.2  christos         X(STREAM_OFF_LEN_FIN)
   1047      1.1  christos #undef X
   1048      1.1  christos     default:
   1049      1.1  christos         return NULL;
   1050      1.1  christos     }
   1051      1.1  christos }
   1052      1.1  christos 
   1053      1.1  christos const char *ossl_quic_err_to_string(uint64_t error_code)
   1054      1.1  christos {
   1055      1.1  christos     switch (error_code) {
   1056  1.1.1.2  christos #define X(name)                \
   1057  1.1.1.2  christos     case OSSL_QUIC_ERR_##name: \
   1058  1.1.1.2  christos         return #name;
   1059  1.1.1.2  christos         X(NO_ERROR)
   1060  1.1.1.2  christos         X(INTERNAL_ERROR)
   1061  1.1.1.2  christos         X(CONNECTION_REFUSED)
   1062  1.1.1.2  christos         X(FLOW_CONTROL_ERROR)
   1063  1.1.1.2  christos         X(STREAM_LIMIT_ERROR)
   1064  1.1.1.2  christos         X(STREAM_STATE_ERROR)
   1065  1.1.1.2  christos         X(FINAL_SIZE_ERROR)
   1066  1.1.1.2  christos         X(FRAME_ENCODING_ERROR)
   1067  1.1.1.2  christos         X(TRANSPORT_PARAMETER_ERROR)
   1068  1.1.1.2  christos         X(CONNECTION_ID_LIMIT_ERROR)
   1069  1.1.1.2  christos         X(PROTOCOL_VIOLATION)
   1070  1.1.1.2  christos         X(INVALID_TOKEN)
   1071  1.1.1.2  christos         X(APPLICATION_ERROR)
   1072  1.1.1.2  christos         X(CRYPTO_BUFFER_EXCEEDED)
   1073  1.1.1.2  christos         X(KEY_UPDATE_ERROR)
   1074  1.1.1.2  christos         X(AEAD_LIMIT_REACHED)
   1075  1.1.1.2  christos         X(NO_VIABLE_PATH)
   1076      1.1  christos #undef X
   1077      1.1  christos     default:
   1078      1.1  christos         return NULL;
   1079      1.1  christos     }
   1080      1.1  christos }
   1081