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