Coverage Report

Created: 2025-08-28 07:07

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