xref: /openssl/ssl/quic/quic_wire.c (revision b6461792)
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
277                                       : OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI)
278             || !WPACKET_quic_write_vlint(pkt, max_streams))
279         return 0;
280 
281     return 1;
282 }
283 
ossl_quic_wire_encode_frame_data_blocked(WPACKET * pkt,uint64_t max_data)284 int ossl_quic_wire_encode_frame_data_blocked(WPACKET *pkt,
285                                              uint64_t max_data)
286 {
287     if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED)
288             || !WPACKET_quic_write_vlint(pkt, max_data))
289         return 0;
290 
291     return 1;
292 }
293 
294 
ossl_quic_wire_encode_frame_stream_data_blocked(WPACKET * pkt,uint64_t stream_id,uint64_t max_stream_data)295 int ossl_quic_wire_encode_frame_stream_data_blocked(WPACKET *pkt,
296                                                     uint64_t stream_id,
297                                                     uint64_t max_stream_data)
298 {
299     if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED)
300             || !WPACKET_quic_write_vlint(pkt, stream_id)
301             || !WPACKET_quic_write_vlint(pkt, max_stream_data))
302         return 0;
303 
304     return 1;
305 }
306 
ossl_quic_wire_encode_frame_streams_blocked(WPACKET * pkt,char is_uni,uint64_t max_streams)307 int ossl_quic_wire_encode_frame_streams_blocked(WPACKET *pkt,
308                                                 char is_uni,
309                                                 uint64_t max_streams)
310 {
311     if (!encode_frame_hdr(pkt, is_uni ? OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_UNI
312                                       : OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI)
313             || !WPACKET_quic_write_vlint(pkt, max_streams))
314         return 0;
315 
316     return 1;
317 }
318 
ossl_quic_wire_encode_frame_new_conn_id(WPACKET * pkt,const OSSL_QUIC_FRAME_NEW_CONN_ID * f)319 int ossl_quic_wire_encode_frame_new_conn_id(WPACKET *pkt,
320                                             const OSSL_QUIC_FRAME_NEW_CONN_ID *f)
321 {
322     if (f->conn_id.id_len < 1
323         || f->conn_id.id_len > QUIC_MAX_CONN_ID_LEN)
324         return 0;
325 
326     if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID)
327             || !WPACKET_quic_write_vlint(pkt, f->seq_num)
328             || !WPACKET_quic_write_vlint(pkt, f->retire_prior_to)
329             || !WPACKET_put_bytes_u8(pkt, f->conn_id.id_len)
330             || !WPACKET_memcpy(pkt, f->conn_id.id, f->conn_id.id_len)
331             || !WPACKET_memcpy(pkt, f->stateless_reset.token,
332                                sizeof(f->stateless_reset.token)))
333         return 0;
334 
335     return 1;
336 }
337 
ossl_quic_wire_encode_frame_retire_conn_id(WPACKET * pkt,uint64_t seq_num)338 int ossl_quic_wire_encode_frame_retire_conn_id(WPACKET *pkt,
339                                                uint64_t seq_num)
340 {
341     if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID)
342             || !WPACKET_quic_write_vlint(pkt, seq_num))
343         return 0;
344 
345     return 1;
346 }
347 
ossl_quic_wire_encode_frame_path_challenge(WPACKET * pkt,uint64_t data)348 int ossl_quic_wire_encode_frame_path_challenge(WPACKET *pkt,
349                                                uint64_t data)
350 {
351     if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE)
352             || !WPACKET_put_bytes_u64(pkt, data))
353         return 0;
354 
355     return 1;
356 }
357 
ossl_quic_wire_encode_frame_path_response(WPACKET * pkt,uint64_t data)358 int ossl_quic_wire_encode_frame_path_response(WPACKET *pkt,
359                                               uint64_t data)
360 {
361     if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE)
362             || !WPACKET_put_bytes_u64(pkt, data))
363         return 0;
364 
365     return 1;
366 }
367 
ossl_quic_wire_encode_frame_conn_close(WPACKET * pkt,const OSSL_QUIC_FRAME_CONN_CLOSE * f)368 int ossl_quic_wire_encode_frame_conn_close(WPACKET *pkt,
369                                            const OSSL_QUIC_FRAME_CONN_CLOSE *f)
370 {
371     if (!encode_frame_hdr(pkt, f->is_app ? OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP
372                                          : OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT)
373             || !WPACKET_quic_write_vlint(pkt, f->error_code))
374         return 0;
375 
376     /*
377      * RFC 9000 s. 19.19: The application-specific variant of CONNECTION_CLOSE
378      * (type 0x1d) does not include this field.
379      */
380     if (!f->is_app && !WPACKET_quic_write_vlint(pkt, f->frame_type))
381         return 0;
382 
383     if (!WPACKET_quic_write_vlint(pkt, f->reason_len)
384             || !WPACKET_memcpy(pkt, f->reason, f->reason_len))
385         return 0;
386 
387     return 1;
388 }
389 
ossl_quic_wire_encode_frame_handshake_done(WPACKET * pkt)390 int ossl_quic_wire_encode_frame_handshake_done(WPACKET *pkt)
391 {
392     return encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE);
393 }
394 
ossl_quic_wire_encode_transport_param_bytes(WPACKET * pkt,uint64_t id,const unsigned char * value,size_t value_len)395 unsigned char *ossl_quic_wire_encode_transport_param_bytes(WPACKET *pkt,
396                                                            uint64_t id,
397                                                            const unsigned char *value,
398                                                            size_t value_len)
399 {
400     unsigned char *b = NULL;
401 
402     if (!WPACKET_quic_write_vlint(pkt, id)
403         || !WPACKET_quic_write_vlint(pkt, value_len))
404         return NULL;
405 
406     if (value_len == 0)
407         b = WPACKET_get_curr(pkt);
408     else if (!WPACKET_allocate_bytes(pkt, value_len, (unsigned char **)&b))
409         return NULL;
410 
411     if (value != NULL)
412         memcpy(b, value, value_len);
413 
414     return b;
415 }
416 
ossl_quic_wire_encode_transport_param_int(WPACKET * pkt,uint64_t id,uint64_t value)417 int ossl_quic_wire_encode_transport_param_int(WPACKET *pkt,
418                                               uint64_t id,
419                                               uint64_t value)
420 {
421     if (!WPACKET_quic_write_vlint(pkt, id)
422             || !WPACKET_quic_write_vlint(pkt, ossl_quic_vlint_encode_len(value))
423             || !WPACKET_quic_write_vlint(pkt, value))
424         return 0;
425 
426     return 1;
427 }
428 
ossl_quic_wire_encode_transport_param_cid(WPACKET * wpkt,uint64_t id,const QUIC_CONN_ID * cid)429 int ossl_quic_wire_encode_transport_param_cid(WPACKET *wpkt,
430                                               uint64_t id,
431                                               const QUIC_CONN_ID *cid)
432 {
433     if (cid->id_len > QUIC_MAX_CONN_ID_LEN)
434         return 0;
435 
436     if (ossl_quic_wire_encode_transport_param_bytes(wpkt, id,
437                                                     cid->id,
438                                                     cid->id_len) == NULL)
439         return 0;
440 
441     return 1;
442 }
443 
444 /*
445  * QUIC Wire Format Decoding
446  * =========================
447  */
ossl_quic_wire_peek_frame_header(PACKET * pkt,uint64_t * type,int * was_minimal)448 int ossl_quic_wire_peek_frame_header(PACKET *pkt, uint64_t *type,
449                                      int *was_minimal)
450 {
451     return PACKET_peek_quic_vlint_ex(pkt, type, was_minimal);
452 }
453 
ossl_quic_wire_skip_frame_header(PACKET * pkt,uint64_t * type)454 int ossl_quic_wire_skip_frame_header(PACKET *pkt, uint64_t *type)
455 {
456     return PACKET_get_quic_vlint(pkt, type);
457 }
458 
expect_frame_header_mask(PACKET * pkt,uint64_t expected_frame_type,uint64_t mask_bits,uint64_t * actual_frame_type)459 static int expect_frame_header_mask(PACKET *pkt,
460                                     uint64_t expected_frame_type,
461                                     uint64_t mask_bits,
462                                     uint64_t *actual_frame_type)
463 {
464     uint64_t actual_frame_type_;
465 
466     if (!ossl_quic_wire_skip_frame_header(pkt, &actual_frame_type_)
467             || (actual_frame_type_ & ~mask_bits) != expected_frame_type)
468         return 0;
469 
470     if (actual_frame_type != NULL)
471         *actual_frame_type = actual_frame_type_;
472 
473     return 1;
474 }
475 
expect_frame_header(PACKET * pkt,uint64_t expected_frame_type)476 static int expect_frame_header(PACKET *pkt, uint64_t expected_frame_type)
477 {
478     uint64_t actual_frame_type;
479 
480     if (!ossl_quic_wire_skip_frame_header(pkt, &actual_frame_type)
481             || actual_frame_type != expected_frame_type)
482         return 0;
483 
484     return 1;
485 }
486 
ossl_quic_wire_peek_frame_ack_num_ranges(const PACKET * orig_pkt,uint64_t * total_ranges)487 int ossl_quic_wire_peek_frame_ack_num_ranges(const PACKET *orig_pkt,
488                                              uint64_t *total_ranges)
489 {
490     PACKET pkt = *orig_pkt;
491     uint64_t ack_range_count, i;
492 
493     if (!expect_frame_header_mask(&pkt, OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN,
494                                   1, NULL)
495             || !PACKET_skip_quic_vlint(&pkt)
496             || !PACKET_skip_quic_vlint(&pkt)
497             || !PACKET_get_quic_vlint(&pkt, &ack_range_count))
498         return 0;
499 
500     /*
501      * Ensure the specified number of ack ranges listed in the ACK frame header
502      * actually are available in the frame data. This naturally bounds the
503      * number of ACK ranges which can be requested by the MDPL, and therefore by
504      * the MTU. This ensures we do not allocate memory for an excessive number
505      * of ACK ranges.
506      */
507     for (i = 0; i < ack_range_count; ++i)
508         if (!PACKET_skip_quic_vlint(&pkt)
509             || !PACKET_skip_quic_vlint(&pkt))
510             return 0;
511 
512     /* (cannot overflow because QUIC vlints can only encode up to 2**62-1) */
513     *total_ranges = ack_range_count + 1;
514     return 1;
515 }
516 
ossl_quic_wire_decode_frame_ack(PACKET * pkt,uint32_t ack_delay_exponent,OSSL_QUIC_FRAME_ACK * ack,uint64_t * total_ranges)517 int ossl_quic_wire_decode_frame_ack(PACKET *pkt,
518                                     uint32_t ack_delay_exponent,
519                                     OSSL_QUIC_FRAME_ACK *ack,
520                                     uint64_t *total_ranges) {
521     uint64_t frame_type, largest_ackd, ack_delay_raw;
522     uint64_t ack_range_count, first_ack_range, start, end, i;
523 
524     /* This call matches both ACK_WITHOUT_ECN and ACK_WITH_ECN. */
525     if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN,
526                                   1, &frame_type)
527             || !PACKET_get_quic_vlint(pkt, &largest_ackd)
528             || !PACKET_get_quic_vlint(pkt, &ack_delay_raw)
529             || !PACKET_get_quic_vlint(pkt, &ack_range_count)
530             || !PACKET_get_quic_vlint(pkt, &first_ack_range))
531         return 0;
532 
533     if (first_ack_range > largest_ackd)
534         return 0;
535 
536     if (ack_range_count > SIZE_MAX /* sizeof(uint64_t) > sizeof(size_t)? */)
537         return 0;
538 
539     start = largest_ackd - first_ack_range;
540 
541     if (ack != NULL) {
542         int err = 0;
543         ack->delay_time
544             = ossl_time_multiply(ossl_ticks2time(OSSL_TIME_US),
545                                  safe_mul_uint64_t(ack_delay_raw,
546                                                    (uint64_t)1 << ack_delay_exponent,
547                                                    &err));
548         if (err)
549             ack->delay_time = ossl_time_infinite();
550 
551         if (ack->num_ack_ranges > 0) {
552             ack->ack_ranges[0].end   = largest_ackd;
553             ack->ack_ranges[0].start = start;
554         }
555     }
556 
557     for (i = 0; i < ack_range_count; ++i) {
558         uint64_t gap, len;
559 
560         if (!PACKET_get_quic_vlint(pkt, &gap)
561                 || !PACKET_get_quic_vlint(pkt, &len))
562             return 0;
563 
564         end = start - gap - 2;
565         if (start < gap + 2 || len > end)
566             return 0;
567 
568         if (ack != NULL && i + 1 < ack->num_ack_ranges) {
569             ack->ack_ranges[i + 1].start = start = end - len;
570             ack->ack_ranges[i + 1].end   = end;
571         }
572     }
573 
574     if (ack != NULL && ack_range_count + 1 < ack->num_ack_ranges)
575         ack->num_ack_ranges = (size_t)ack_range_count + 1;
576 
577     if (total_ranges != NULL)
578         *total_ranges = ack_range_count + 1;
579 
580     if (frame_type == OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN) {
581         uint64_t ect0, ect1, ecnce;
582 
583         if (!PACKET_get_quic_vlint(pkt, &ect0)
584                 || !PACKET_get_quic_vlint(pkt, &ect1)
585                 || !PACKET_get_quic_vlint(pkt, &ecnce))
586             return 0;
587 
588         if (ack != NULL) {
589             ack->ect0           = ect0;
590             ack->ect1           = ect1;
591             ack->ecnce          = ecnce;
592             ack->ecn_present    = 1;
593         }
594     } else if (ack != NULL) {
595         ack->ecn_present = 0;
596     }
597 
598     return 1;
599 }
600 
ossl_quic_wire_decode_frame_reset_stream(PACKET * pkt,OSSL_QUIC_FRAME_RESET_STREAM * f)601 int ossl_quic_wire_decode_frame_reset_stream(PACKET *pkt,
602                                              OSSL_QUIC_FRAME_RESET_STREAM *f)
603 {
604     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_RESET_STREAM)
605             || !PACKET_get_quic_vlint(pkt, &f->stream_id)
606             || !PACKET_get_quic_vlint(pkt, &f->app_error_code)
607             || !PACKET_get_quic_vlint(pkt, &f->final_size))
608         return 0;
609 
610     return 1;
611 }
612 
ossl_quic_wire_decode_frame_stop_sending(PACKET * pkt,OSSL_QUIC_FRAME_STOP_SENDING * f)613 int ossl_quic_wire_decode_frame_stop_sending(PACKET *pkt,
614                                              OSSL_QUIC_FRAME_STOP_SENDING *f)
615 {
616     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_STOP_SENDING)
617             || !PACKET_get_quic_vlint(pkt, &f->stream_id)
618             || !PACKET_get_quic_vlint(pkt, &f->app_error_code))
619         return 0;
620 
621     return 1;
622 }
623 
ossl_quic_wire_decode_frame_crypto(PACKET * pkt,int nodata,OSSL_QUIC_FRAME_CRYPTO * f)624 int ossl_quic_wire_decode_frame_crypto(PACKET *pkt,
625                                        int nodata,
626                                        OSSL_QUIC_FRAME_CRYPTO *f)
627 {
628     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_CRYPTO)
629             || !PACKET_get_quic_vlint(pkt, &f->offset)
630             || !PACKET_get_quic_vlint(pkt, &f->len)
631             || f->len > SIZE_MAX /* sizeof(uint64_t) > sizeof(size_t)? */)
632         return 0;
633 
634     if (f->offset + f->len > (((uint64_t)1) << 62) - 1)
635         /* RFC 9000 s. 19.6 */
636         return 0;
637 
638     if (nodata) {
639         f->data = NULL;
640     } else {
641         if (PACKET_remaining(pkt) < f->len)
642             return 0;
643 
644         f->data = PACKET_data(pkt);
645 
646         if (!PACKET_forward(pkt, (size_t)f->len))
647             return 0;
648     }
649 
650     return 1;
651 }
652 
ossl_quic_wire_decode_frame_new_token(PACKET * pkt,const unsigned char ** token,size_t * token_len)653 int ossl_quic_wire_decode_frame_new_token(PACKET               *pkt,
654                                           const unsigned char **token,
655                                           size_t               *token_len)
656 {
657     uint64_t token_len_;
658 
659     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_NEW_TOKEN)
660             || !PACKET_get_quic_vlint(pkt, &token_len_))
661         return 0;
662 
663     if (token_len_ > SIZE_MAX)
664         return 0;
665 
666     *token      = PACKET_data(pkt);
667     *token_len  = (size_t)token_len_;
668 
669     if (!PACKET_forward(pkt, (size_t)token_len_))
670         return 0;
671 
672     return 1;
673 }
674 
ossl_quic_wire_decode_frame_stream(PACKET * pkt,int nodata,OSSL_QUIC_FRAME_STREAM * f)675 int ossl_quic_wire_decode_frame_stream(PACKET *pkt,
676                                        int nodata,
677                                        OSSL_QUIC_FRAME_STREAM *f)
678 {
679     uint64_t frame_type;
680 
681     /* This call matches all STREAM values (low 3 bits are masked). */
682     if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_STREAM,
683                                   OSSL_QUIC_FRAME_FLAG_STREAM_MASK,
684                                   &frame_type)
685             || !PACKET_get_quic_vlint(pkt, &f->stream_id))
686         return 0;
687 
688     if ((frame_type & OSSL_QUIC_FRAME_FLAG_STREAM_OFF) != 0) {
689         if (!PACKET_get_quic_vlint(pkt, &f->offset))
690             return 0;
691     } else {
692         f->offset = 0;
693     }
694 
695     f->has_explicit_len = ((frame_type & OSSL_QUIC_FRAME_FLAG_STREAM_LEN) != 0);
696     f->is_fin           = ((frame_type & OSSL_QUIC_FRAME_FLAG_STREAM_FIN) != 0);
697 
698     if (f->has_explicit_len) {
699         if (!PACKET_get_quic_vlint(pkt, &f->len))
700             return 0;
701     } else {
702         if (nodata)
703             f->len = 0;
704         else
705             f->len = PACKET_remaining(pkt);
706     }
707 
708     /*
709      * RFC 9000 s. 19.8: "The largest offset delivered on a stream -- the sum of
710      * the offset and data length -- cannot exceed 2**62 - 1, as it is not
711      * possible to provide flow control credit for that data."
712      */
713     if (f->offset + f->len > (((uint64_t)1) << 62) - 1)
714         return 0;
715 
716     if (nodata) {
717         f->data = NULL;
718     } else {
719         f->data = PACKET_data(pkt);
720 
721         if (f->len > SIZE_MAX /* sizeof(uint64_t) > sizeof(size_t)? */
722             || !PACKET_forward(pkt, (size_t)f->len))
723             return 0;
724     }
725 
726     return 1;
727 }
728 
ossl_quic_wire_decode_frame_max_data(PACKET * pkt,uint64_t * max_data)729 int ossl_quic_wire_decode_frame_max_data(PACKET *pkt,
730                                          uint64_t *max_data)
731 {
732     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_MAX_DATA)
733             || !PACKET_get_quic_vlint(pkt, max_data))
734         return 0;
735 
736     return 1;
737 }
738 
ossl_quic_wire_decode_frame_max_stream_data(PACKET * pkt,uint64_t * stream_id,uint64_t * max_stream_data)739 int ossl_quic_wire_decode_frame_max_stream_data(PACKET *pkt,
740                                                 uint64_t *stream_id,
741                                                 uint64_t *max_stream_data)
742 {
743     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA)
744             || !PACKET_get_quic_vlint(pkt, stream_id)
745             || !PACKET_get_quic_vlint(pkt, max_stream_data))
746         return 0;
747 
748     return 1;
749 }
750 
ossl_quic_wire_decode_frame_max_streams(PACKET * pkt,uint64_t * max_streams)751 int ossl_quic_wire_decode_frame_max_streams(PACKET *pkt,
752                                             uint64_t *max_streams)
753 {
754     /* This call matches both MAX_STREAMS_BIDI and MAX_STREAMS_UNI. */
755     if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI,
756                                   1, NULL)
757             || !PACKET_get_quic_vlint(pkt, max_streams))
758         return 0;
759 
760     return 1;
761 }
762 
ossl_quic_wire_decode_frame_data_blocked(PACKET * pkt,uint64_t * max_data)763 int ossl_quic_wire_decode_frame_data_blocked(PACKET *pkt,
764                                              uint64_t *max_data)
765 {
766     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED)
767             || !PACKET_get_quic_vlint(pkt, max_data))
768         return 0;
769 
770     return 1;
771 }
772 
ossl_quic_wire_decode_frame_stream_data_blocked(PACKET * pkt,uint64_t * stream_id,uint64_t * max_stream_data)773 int ossl_quic_wire_decode_frame_stream_data_blocked(PACKET *pkt,
774                                                     uint64_t *stream_id,
775                                                     uint64_t *max_stream_data)
776 {
777     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED)
778             || !PACKET_get_quic_vlint(pkt, stream_id)
779             || !PACKET_get_quic_vlint(pkt, max_stream_data))
780         return 0;
781 
782     return 1;
783 }
784 
ossl_quic_wire_decode_frame_streams_blocked(PACKET * pkt,uint64_t * max_streams)785 int ossl_quic_wire_decode_frame_streams_blocked(PACKET *pkt,
786                                                 uint64_t *max_streams)
787 {
788     /* This call matches both STREAMS_BLOCKED_BIDI and STREAMS_BLOCKED_UNI. */
789     if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI,
790                                   1, NULL)
791             || !PACKET_get_quic_vlint(pkt, max_streams))
792         return 0;
793 
794     return 1;
795 }
796 
ossl_quic_wire_decode_frame_new_conn_id(PACKET * pkt,OSSL_QUIC_FRAME_NEW_CONN_ID * f)797 int ossl_quic_wire_decode_frame_new_conn_id(PACKET *pkt,
798                                             OSSL_QUIC_FRAME_NEW_CONN_ID *f)
799 {
800     unsigned int len;
801 
802     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID)
803             || !PACKET_get_quic_vlint(pkt, &f->seq_num)
804             || !PACKET_get_quic_vlint(pkt, &f->retire_prior_to)
805             || f->seq_num < f->retire_prior_to
806             || !PACKET_get_1(pkt, &len)
807             || len < 1
808             || len > QUIC_MAX_CONN_ID_LEN)
809         return 0;
810 
811     f->conn_id.id_len = (unsigned char)len;
812     if (!PACKET_copy_bytes(pkt, f->conn_id.id, len))
813         return 0;
814 
815     /* Clear unused bytes to allow consistent memcmp. */
816     if (len < QUIC_MAX_CONN_ID_LEN)
817         memset(f->conn_id.id + len, 0, QUIC_MAX_CONN_ID_LEN - len);
818 
819     if (!PACKET_copy_bytes(pkt, f->stateless_reset.token,
820                            sizeof(f->stateless_reset.token)))
821         return 0;
822 
823     return 1;
824 }
825 
ossl_quic_wire_decode_frame_retire_conn_id(PACKET * pkt,uint64_t * seq_num)826 int ossl_quic_wire_decode_frame_retire_conn_id(PACKET *pkt,
827                                                uint64_t *seq_num)
828 {
829     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID)
830             || !PACKET_get_quic_vlint(pkt, seq_num))
831         return 0;
832 
833     return 1;
834 }
835 
ossl_quic_wire_decode_frame_path_challenge(PACKET * pkt,uint64_t * data)836 int ossl_quic_wire_decode_frame_path_challenge(PACKET *pkt,
837                                                uint64_t *data)
838 {
839     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE)
840             || !PACKET_get_net_8(pkt, data))
841         return 0;
842 
843     return 1;
844 }
845 
ossl_quic_wire_decode_frame_path_response(PACKET * pkt,uint64_t * data)846 int ossl_quic_wire_decode_frame_path_response(PACKET *pkt,
847                                               uint64_t *data)
848 {
849     if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE)
850             || !PACKET_get_net_8(pkt, data))
851         return 0;
852 
853     return 1;
854 }
855 
ossl_quic_wire_decode_frame_conn_close(PACKET * pkt,OSSL_QUIC_FRAME_CONN_CLOSE * f)856 int ossl_quic_wire_decode_frame_conn_close(PACKET *pkt,
857                                            OSSL_QUIC_FRAME_CONN_CLOSE *f)
858 {
859     uint64_t frame_type, reason_len;
860 
861     /* This call matches both CONN_CLOSE_TRANSPORT and CONN_CLOSE_APP. */
862     if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT,
863                                   1, &frame_type)
864             || !PACKET_get_quic_vlint(pkt, &f->error_code))
865         return 0;
866 
867     f->is_app = ((frame_type & 1) != 0);
868 
869     if (!f->is_app) {
870         if (!PACKET_get_quic_vlint(pkt, &f->frame_type))
871             return 0;
872     } else {
873         f->frame_type = 0;
874     }
875 
876     if (!PACKET_get_quic_vlint(pkt, &reason_len)
877             || reason_len > SIZE_MAX)
878         return 0;
879 
880     if (!PACKET_get_bytes(pkt, (const unsigned char **)&f->reason,
881                           (size_t)reason_len))
882         return 0;
883 
884     f->reason_len = (size_t)reason_len;
885     return 1;
886 }
887 
ossl_quic_wire_decode_padding(PACKET * pkt)888 size_t ossl_quic_wire_decode_padding(PACKET *pkt)
889 {
890     const unsigned char *start = PACKET_data(pkt), *end = PACKET_end(pkt),
891                         *p = start;
892 
893     while (p < end && *p == 0)
894         ++p;
895 
896     if (!PACKET_forward(pkt, p - start))
897         return 0;
898 
899     return p - start;
900 }
901 
ossl_quic_wire_decode_frame_ping(PACKET * pkt)902 int ossl_quic_wire_decode_frame_ping(PACKET *pkt)
903 {
904     return expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_PING);
905 }
906 
ossl_quic_wire_decode_frame_handshake_done(PACKET * pkt)907 int ossl_quic_wire_decode_frame_handshake_done(PACKET *pkt)
908 {
909     return expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE);
910 }
911 
ossl_quic_wire_peek_transport_param(PACKET * pkt,uint64_t * id)912 int ossl_quic_wire_peek_transport_param(PACKET *pkt, uint64_t *id)
913 {
914     return PACKET_peek_quic_vlint(pkt, id);
915 }
916 
ossl_quic_wire_decode_transport_param_bytes(PACKET * pkt,uint64_t * id,size_t * len)917 const unsigned char *ossl_quic_wire_decode_transport_param_bytes(PACKET *pkt,
918                                                                  uint64_t *id,
919                                                                  size_t *len)
920 {
921     uint64_t len_;
922     const unsigned char *b = NULL;
923     uint64_t id_;
924 
925     if (!PACKET_get_quic_vlint(pkt, &id_)
926             || !PACKET_get_quic_vlint(pkt, &len_))
927         return NULL;
928 
929     if (len_ > SIZE_MAX
930             || !PACKET_get_bytes(pkt, (const unsigned char **)&b, (size_t)len_))
931         return NULL;
932 
933     *len = (size_t)len_;
934     if (id != NULL)
935         *id = id_;
936     return b;
937 }
938 
ossl_quic_wire_decode_transport_param_int(PACKET * pkt,uint64_t * id,uint64_t * value)939 int ossl_quic_wire_decode_transport_param_int(PACKET *pkt,
940                                               uint64_t *id,
941                                               uint64_t *value)
942 {
943     PACKET sub;
944 
945     sub.curr = ossl_quic_wire_decode_transport_param_bytes(pkt,
946                                                            id, &sub.remaining);
947     if (sub.curr == NULL)
948         return 0;
949 
950     if (!PACKET_get_quic_vlint(&sub, value))
951         return 0;
952 
953     if (PACKET_remaining(&sub) > 0)
954         return 0;
955 
956    return 1;
957 }
958 
ossl_quic_wire_decode_transport_param_cid(PACKET * pkt,uint64_t * id,QUIC_CONN_ID * cid)959 int ossl_quic_wire_decode_transport_param_cid(PACKET *pkt,
960                                               uint64_t *id,
961                                               QUIC_CONN_ID *cid)
962 {
963     const unsigned char *body;
964     size_t len = 0;
965 
966     body = ossl_quic_wire_decode_transport_param_bytes(pkt, id, &len);
967     if (body == NULL || len > QUIC_MAX_CONN_ID_LEN)
968         return 0;
969 
970     cid->id_len = (unsigned char)len;
971     memcpy(cid->id, body, cid->id_len);
972     return 1;
973 }
974 
ossl_quic_wire_decode_transport_param_preferred_addr(PACKET * pkt,QUIC_PREFERRED_ADDR * p)975 int ossl_quic_wire_decode_transport_param_preferred_addr(PACKET *pkt,
976                                                          QUIC_PREFERRED_ADDR *p)
977 {
978     const unsigned char *body;
979     uint64_t id;
980     size_t len = 0;
981     PACKET pkt2;
982     unsigned int ipv4_port, ipv6_port, cidl;
983 
984     body = ossl_quic_wire_decode_transport_param_bytes(pkt, &id, &len);
985     if (body == NULL
986         || len < QUIC_MIN_ENCODED_PREFERRED_ADDR_LEN
987         || len > QUIC_MAX_ENCODED_PREFERRED_ADDR_LEN
988         || id != QUIC_TPARAM_PREFERRED_ADDR)
989         return 0;
990 
991     if (!PACKET_buf_init(&pkt2, body, len))
992         return 0;
993 
994     if (!PACKET_copy_bytes(&pkt2, p->ipv4, sizeof(p->ipv4))
995         || !PACKET_get_net_2(&pkt2, &ipv4_port)
996         || !PACKET_copy_bytes(&pkt2, p->ipv6, sizeof(p->ipv6))
997         || !PACKET_get_net_2(&pkt2, &ipv6_port)
998         || !PACKET_get_1(&pkt2, &cidl)
999         || cidl > QUIC_MAX_CONN_ID_LEN
1000         || !PACKET_copy_bytes(&pkt2, p->cid.id, cidl)
1001         || !PACKET_copy_bytes(&pkt2, p->stateless_reset.token,
1002                               sizeof(p->stateless_reset.token)))
1003         return 0;
1004 
1005     p->ipv4_port    = (uint16_t)ipv4_port;
1006     p->ipv6_port    = (uint16_t)ipv6_port;
1007     p->cid.id_len   = (unsigned char)cidl;
1008     return 1;
1009 }
1010 
1011 const char *
ossl_quic_frame_type_to_string(uint64_t frame_type)1012 ossl_quic_frame_type_to_string(uint64_t frame_type)
1013 {
1014     switch (frame_type) {
1015 #define X(name) case OSSL_QUIC_FRAME_TYPE_##name: 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) case OSSL_QUIC_ERR_##name: return #name;
1057     X(NO_ERROR)
1058     X(INTERNAL_ERROR)
1059     X(CONNECTION_REFUSED)
1060     X(FLOW_CONTROL_ERROR)
1061     X(STREAM_LIMIT_ERROR)
1062     X(STREAM_STATE_ERROR)
1063     X(FINAL_SIZE_ERROR)
1064     X(FRAME_ENCODING_ERROR)
1065     X(TRANSPORT_PARAMETER_ERROR)
1066     X(CONNECTION_ID_LIMIT_ERROR)
1067     X(PROTOCOL_VIOLATION)
1068     X(INVALID_TOKEN)
1069     X(APPLICATION_ERROR)
1070     X(CRYPTO_BUFFER_EXCEEDED)
1071     X(KEY_UPDATE_ERROR)
1072     X(AEAD_LIMIT_REACHED)
1073     X(NO_VIABLE_PATH)
1074 #undef X
1075     default:
1076         return NULL;
1077     }
1078 }
1079