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