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/err.h>
11 #include "internal/common.h"
12 #include "internal/quic_wire_pkt.h"
13
ossl_quic_hdr_protector_init(QUIC_HDR_PROTECTOR * hpr,OSSL_LIB_CTX * libctx,const char * propq,uint32_t cipher_id,const unsigned char * quic_hp_key,size_t quic_hp_key_len)14 int ossl_quic_hdr_protector_init(QUIC_HDR_PROTECTOR *hpr,
15 OSSL_LIB_CTX *libctx,
16 const char *propq,
17 uint32_t cipher_id,
18 const unsigned char *quic_hp_key,
19 size_t quic_hp_key_len)
20 {
21 const char *cipher_name = NULL;
22
23 switch (cipher_id) {
24 case QUIC_HDR_PROT_CIPHER_AES_128:
25 cipher_name = "AES-128-ECB";
26 break;
27 case QUIC_HDR_PROT_CIPHER_AES_256:
28 cipher_name = "AES-256-ECB";
29 break;
30 case QUIC_HDR_PROT_CIPHER_CHACHA:
31 cipher_name = "ChaCha20";
32 break;
33 default:
34 ERR_raise(ERR_LIB_SSL, ERR_R_UNSUPPORTED);
35 return 0;
36 }
37
38 hpr->cipher_ctx = EVP_CIPHER_CTX_new();
39 if (hpr->cipher_ctx == NULL) {
40 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB);
41 return 0;
42 }
43
44 hpr->cipher = EVP_CIPHER_fetch(libctx, cipher_name, propq);
45 if (hpr->cipher == NULL
46 || quic_hp_key_len != (size_t)EVP_CIPHER_get_key_length(hpr->cipher)) {
47 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB);
48 goto err;
49 }
50
51 if (!EVP_CipherInit_ex(hpr->cipher_ctx, hpr->cipher, NULL,
52 quic_hp_key, NULL, 1)) {
53 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB);
54 goto err;
55 }
56
57 hpr->libctx = libctx;
58 hpr->propq = propq;
59 hpr->cipher_id = cipher_id;
60 return 1;
61
62 err:
63 ossl_quic_hdr_protector_cleanup(hpr);
64 return 0;
65 }
66
ossl_quic_hdr_protector_cleanup(QUIC_HDR_PROTECTOR * hpr)67 void ossl_quic_hdr_protector_cleanup(QUIC_HDR_PROTECTOR *hpr)
68 {
69 EVP_CIPHER_CTX_free(hpr->cipher_ctx);
70 hpr->cipher_ctx = NULL;
71
72 EVP_CIPHER_free(hpr->cipher);
73 hpr->cipher = NULL;
74 }
75
hdr_generate_mask(QUIC_HDR_PROTECTOR * hpr,const unsigned char * sample,size_t sample_len,unsigned char * mask)76 static int hdr_generate_mask(QUIC_HDR_PROTECTOR *hpr,
77 const unsigned char *sample, size_t sample_len,
78 unsigned char *mask)
79 {
80 int l = 0;
81 unsigned char dst[16];
82 static const unsigned char zeroes[5] = {0};
83 size_t i;
84
85 if (hpr->cipher_id == QUIC_HDR_PROT_CIPHER_AES_128
86 || hpr->cipher_id == QUIC_HDR_PROT_CIPHER_AES_256) {
87 if (sample_len < 16) {
88 ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
89 return 0;
90 }
91
92 if (!EVP_CipherInit_ex(hpr->cipher_ctx, NULL, NULL, NULL, NULL, 1)
93 || !EVP_CipherUpdate(hpr->cipher_ctx, dst, &l, sample, 16)) {
94 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB);
95 return 0;
96 }
97
98 for (i = 0; i < 5; ++i)
99 mask[i] = dst[i];
100 } else if (hpr->cipher_id == QUIC_HDR_PROT_CIPHER_CHACHA) {
101 if (sample_len < 16) {
102 ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
103 return 0;
104 }
105
106 if (!EVP_CipherInit_ex(hpr->cipher_ctx, NULL, NULL, NULL, sample, 1)
107 || !EVP_CipherUpdate(hpr->cipher_ctx, mask, &l,
108 zeroes, sizeof(zeroes))) {
109 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB);
110 return 0;
111 }
112 } else {
113 ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
114 assert(0);
115 return 0;
116 }
117
118 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
119 /* No matter what we did above we use the same mask in fuzzing mode */
120 memset(mask, 0, 5);
121 #endif
122
123 return 1;
124 }
125
ossl_quic_hdr_protector_decrypt(QUIC_HDR_PROTECTOR * hpr,QUIC_PKT_HDR_PTRS * ptrs)126 int ossl_quic_hdr_protector_decrypt(QUIC_HDR_PROTECTOR *hpr,
127 QUIC_PKT_HDR_PTRS *ptrs)
128 {
129 return ossl_quic_hdr_protector_decrypt_fields(hpr,
130 ptrs->raw_sample,
131 ptrs->raw_sample_len,
132 ptrs->raw_start,
133 ptrs->raw_pn);
134 }
135
ossl_quic_hdr_protector_decrypt_fields(QUIC_HDR_PROTECTOR * hpr,const unsigned char * sample,size_t sample_len,unsigned char * first_byte,unsigned char * pn_bytes)136 int ossl_quic_hdr_protector_decrypt_fields(QUIC_HDR_PROTECTOR *hpr,
137 const unsigned char *sample,
138 size_t sample_len,
139 unsigned char *first_byte,
140 unsigned char *pn_bytes)
141 {
142 unsigned char mask[5], pn_len, i;
143
144 if (!hdr_generate_mask(hpr, sample, sample_len, mask))
145 return 0;
146
147 *first_byte ^= mask[0] & ((*first_byte & 0x80) != 0 ? 0xf : 0x1f);
148 pn_len = (*first_byte & 0x3) + 1;
149
150 for (i = 0; i < pn_len; ++i)
151 pn_bytes[i] ^= mask[i + 1];
152
153 return 1;
154 }
155
ossl_quic_hdr_protector_encrypt(QUIC_HDR_PROTECTOR * hpr,QUIC_PKT_HDR_PTRS * ptrs)156 int ossl_quic_hdr_protector_encrypt(QUIC_HDR_PROTECTOR *hpr,
157 QUIC_PKT_HDR_PTRS *ptrs)
158 {
159 return ossl_quic_hdr_protector_encrypt_fields(hpr,
160 ptrs->raw_sample,
161 ptrs->raw_sample_len,
162 ptrs->raw_start,
163 ptrs->raw_pn);
164 }
165
ossl_quic_hdr_protector_encrypt_fields(QUIC_HDR_PROTECTOR * hpr,const unsigned char * sample,size_t sample_len,unsigned char * first_byte,unsigned char * pn_bytes)166 int ossl_quic_hdr_protector_encrypt_fields(QUIC_HDR_PROTECTOR *hpr,
167 const unsigned char *sample,
168 size_t sample_len,
169 unsigned char *first_byte,
170 unsigned char *pn_bytes)
171 {
172 unsigned char mask[5], pn_len, i;
173
174 if (!hdr_generate_mask(hpr, sample, sample_len, mask))
175 return 0;
176
177 pn_len = (*first_byte & 0x3) + 1;
178 for (i = 0; i < pn_len; ++i)
179 pn_bytes[i] ^= mask[i + 1];
180
181 *first_byte ^= mask[0] & ((*first_byte & 0x80) != 0 ? 0xf : 0x1f);
182 return 1;
183 }
184
ossl_quic_wire_decode_pkt_hdr(PACKET * pkt,size_t short_conn_id_len,int partial,int nodata,QUIC_PKT_HDR * hdr,QUIC_PKT_HDR_PTRS * ptrs)185 int ossl_quic_wire_decode_pkt_hdr(PACKET *pkt,
186 size_t short_conn_id_len,
187 int partial,
188 int nodata,
189 QUIC_PKT_HDR *hdr,
190 QUIC_PKT_HDR_PTRS *ptrs)
191 {
192 unsigned int b0;
193 unsigned char *pn = NULL;
194 size_t l = PACKET_remaining(pkt);
195
196 if (ptrs != NULL) {
197 ptrs->raw_start = (unsigned char *)PACKET_data(pkt);
198 ptrs->raw_sample = NULL;
199 ptrs->raw_sample_len = 0;
200 ptrs->raw_pn = NULL;
201 }
202
203 if (l < QUIC_MIN_VALID_PKT_LEN
204 || !PACKET_get_1(pkt, &b0))
205 return 0;
206
207 hdr->partial = partial;
208 hdr->unused = 0;
209 hdr->reserved = 0;
210
211 if ((b0 & 0x80) == 0) {
212 /* Short header. */
213 if (short_conn_id_len > QUIC_MAX_CONN_ID_LEN)
214 return 0;
215
216 if ((b0 & 0x40) == 0 /* fixed bit not set? */
217 || l < QUIC_MIN_VALID_PKT_LEN_CRYPTO)
218 return 0;
219
220 hdr->type = QUIC_PKT_TYPE_1RTT;
221 hdr->fixed = 1;
222 hdr->spin_bit = (b0 & 0x20) != 0;
223 if (partial) {
224 hdr->key_phase = 0; /* protected, zero for now */
225 hdr->pn_len = 0; /* protected, zero for now */
226 hdr->reserved = 0; /* protected, zero for now */
227 } else {
228 hdr->key_phase = (b0 & 0x04) != 0;
229 hdr->pn_len = (b0 & 0x03) + 1;
230 hdr->reserved = (b0 & 0x18) >> 3;
231 }
232
233 /* Copy destination connection ID field to header structure. */
234 if (!PACKET_copy_bytes(pkt, hdr->dst_conn_id.id, short_conn_id_len))
235 return 0;
236
237 hdr->dst_conn_id.id_len = (unsigned char)short_conn_id_len;
238
239 /*
240 * Skip over the PN. If this is a partial decode, the PN length field
241 * currently has header protection applied. Thus we do not know the
242 * length of the PN but we are allowed to assume it is 4 bytes long at
243 * this stage.
244 */
245 memset(hdr->pn, 0, sizeof(hdr->pn));
246 pn = (unsigned char *)PACKET_data(pkt);
247 if (partial) {
248 if (!PACKET_forward(pkt, sizeof(hdr->pn)))
249 return 0;
250 } else {
251 if (!PACKET_copy_bytes(pkt, hdr->pn, hdr->pn_len))
252 return 0;
253 }
254
255 /* Fields not used in short-header packets. */
256 hdr->version = 0;
257 hdr->src_conn_id.id_len = 0;
258 hdr->token = NULL;
259 hdr->token_len = 0;
260
261 /*
262 * Short-header packets always come last in a datagram, the length
263 * is the remainder of the buffer.
264 */
265 hdr->len = PACKET_remaining(pkt);
266 hdr->data = PACKET_data(pkt);
267
268 /*
269 * Skip over payload. Since this is a short header packet, which cannot
270 * be followed by any other kind of packet, this advances us to the end
271 * of the datagram.
272 */
273 if (!PACKET_forward(pkt, hdr->len))
274 return 0;
275 } else {
276 /* Long header. */
277 unsigned long version;
278 unsigned int dst_conn_id_len, src_conn_id_len, raw_type;
279
280 if (!PACKET_get_net_4(pkt, &version))
281 return 0;
282
283 /*
284 * All QUIC packets must have the fixed bit set, except exceptionally
285 * for Version Negotiation packets.
286 */
287 if (version != 0 && (b0 & 0x40) == 0)
288 return 0;
289
290 if (!PACKET_get_1(pkt, &dst_conn_id_len)
291 || dst_conn_id_len > QUIC_MAX_CONN_ID_LEN
292 || !PACKET_copy_bytes(pkt, hdr->dst_conn_id.id, dst_conn_id_len)
293 || !PACKET_get_1(pkt, &src_conn_id_len)
294 || src_conn_id_len > QUIC_MAX_CONN_ID_LEN
295 || !PACKET_copy_bytes(pkt, hdr->src_conn_id.id, src_conn_id_len))
296 return 0;
297
298 hdr->version = (uint32_t)version;
299 hdr->dst_conn_id.id_len = (unsigned char)dst_conn_id_len;
300 hdr->src_conn_id.id_len = (unsigned char)src_conn_id_len;
301
302 if (version == 0) {
303 /*
304 * Version negotiation packet. Version negotiation packets are
305 * identified by a version field of 0 and the type bits in the first
306 * byte are ignored (they may take any value, and we ignore them).
307 */
308 hdr->type = QUIC_PKT_TYPE_VERSION_NEG;
309 hdr->fixed = (b0 & 0x40) != 0;
310
311 hdr->data = PACKET_data(pkt);
312 hdr->len = PACKET_remaining(pkt);
313
314 /*
315 * Version negotiation packets must contain an array of u32s, so it
316 * is invalid for their payload length to not be divisible by 4.
317 */
318 if ((hdr->len % 4) != 0)
319 return 0;
320
321 /* Version negotiation packets are always fully decoded. */
322 hdr->partial = 0;
323
324 /* Fields not used in version negotiation packets. */
325 hdr->pn_len = 0;
326 hdr->spin_bit = 0;
327 hdr->key_phase = 0;
328 hdr->token = NULL;
329 hdr->token_len = 0;
330 memset(hdr->pn, 0, sizeof(hdr->pn));
331
332 if (!PACKET_forward(pkt, hdr->len))
333 return 0;
334 } else if (version != QUIC_VERSION_1) {
335 /* Unknown version, do not decode. */
336 return 0;
337 } else {
338 if (l < QUIC_MIN_VALID_PKT_LEN_CRYPTO)
339 return 0;
340
341 /* Get long packet type and decode to QUIC_PKT_TYPE_*. */
342 raw_type = ((b0 >> 4) & 0x3);
343
344 switch (raw_type) {
345 case 0:
346 hdr->type = QUIC_PKT_TYPE_INITIAL;
347 break;
348 case 1:
349 hdr->type = QUIC_PKT_TYPE_0RTT;
350 break;
351 case 2:
352 hdr->type = QUIC_PKT_TYPE_HANDSHAKE;
353 break;
354 case 3:
355 hdr->type = QUIC_PKT_TYPE_RETRY;
356 break;
357 }
358
359 hdr->pn_len = 0;
360 hdr->fixed = 1;
361
362 /* Fields not used in long-header packets. */
363 hdr->spin_bit = 0;
364 hdr->key_phase = 0;
365
366 if (hdr->type == QUIC_PKT_TYPE_INITIAL) {
367 /* Initial packet. */
368 uint64_t token_len;
369
370 if (!PACKET_get_quic_vlint(pkt, &token_len)
371 || token_len > SIZE_MAX
372 || !PACKET_get_bytes(pkt, &hdr->token, (size_t)token_len))
373 return 0;
374
375 hdr->token_len = (size_t)token_len;
376 if (token_len == 0)
377 hdr->token = NULL;
378 } else {
379 hdr->token = NULL;
380 hdr->token_len = 0;
381 }
382
383 if (hdr->type == QUIC_PKT_TYPE_RETRY) {
384 /* Retry packet. */
385 hdr->data = PACKET_data(pkt);
386 hdr->len = PACKET_remaining(pkt);
387
388 /* Retry packets are always fully decoded. */
389 hdr->partial = 0;
390
391 /* Unused bits in Retry header. */
392 hdr->unused = b0 & 0x0f;
393
394 /* Fields not used in Retry packets. */
395 memset(hdr->pn, 0, sizeof(hdr->pn));
396
397 if (!PACKET_forward(pkt, hdr->len))
398 return 0;
399 } else {
400 /* Initial, 0-RTT or Handshake packet. */
401 uint64_t len;
402
403 hdr->pn_len = partial ? 0 : ((b0 & 0x03) + 1);
404 hdr->reserved = partial ? 0 : ((b0 & 0x0C) >> 2);
405
406 if (!PACKET_get_quic_vlint(pkt, &len)
407 || len < sizeof(hdr->pn))
408 return 0;
409
410 if (!nodata && len > PACKET_remaining(pkt))
411 return 0;
412
413 /*
414 * Skip over the PN. If this is a partial decode, the PN length
415 * field currently has header protection applied. Thus we do not
416 * know the length of the PN but we are allowed to assume it is
417 * 4 bytes long at this stage.
418 */
419 pn = (unsigned char *)PACKET_data(pkt);
420 memset(hdr->pn, 0, sizeof(hdr->pn));
421 if (partial) {
422 if (!PACKET_forward(pkt, sizeof(hdr->pn)))
423 return 0;
424
425 hdr->len = (size_t)(len - sizeof(hdr->pn));
426 } else {
427 if (!PACKET_copy_bytes(pkt, hdr->pn, hdr->pn_len))
428 return 0;
429
430 hdr->len = (size_t)(len - hdr->pn_len);
431 }
432
433 if (nodata) {
434 hdr->data = NULL;
435 } else {
436 hdr->data = PACKET_data(pkt);
437
438 /* Skip over packet body. */
439 if (!PACKET_forward(pkt, hdr->len))
440 return 0;
441 }
442 }
443 }
444 }
445
446 if (ptrs != NULL) {
447 ptrs->raw_pn = pn;
448 if (pn != NULL) {
449 ptrs->raw_sample = pn + 4;
450 ptrs->raw_sample_len = PACKET_end(pkt) - ptrs->raw_sample;
451 }
452 }
453
454 return 1;
455 }
456
ossl_quic_wire_encode_pkt_hdr(WPACKET * pkt,size_t short_conn_id_len,const QUIC_PKT_HDR * hdr,QUIC_PKT_HDR_PTRS * ptrs)457 int ossl_quic_wire_encode_pkt_hdr(WPACKET *pkt,
458 size_t short_conn_id_len,
459 const QUIC_PKT_HDR *hdr,
460 QUIC_PKT_HDR_PTRS *ptrs)
461 {
462 unsigned char b0;
463 size_t off_start, off_sample, off_pn;
464 unsigned char *start = WPACKET_get_curr(pkt);
465
466 if (!WPACKET_get_total_written(pkt, &off_start))
467 return 0;
468
469 if (ptrs != NULL) {
470 /* ptrs would not be stable on non-static WPACKET */
471 if (!ossl_assert(pkt->staticbuf != NULL))
472 return 0;
473 ptrs->raw_start = NULL;
474 ptrs->raw_sample = NULL;
475 ptrs->raw_sample_len = 0;
476 ptrs->raw_pn = 0;
477 }
478
479 /* Cannot serialize a partial header, or one whose DCID length is wrong. */
480 if (hdr->partial
481 || (hdr->type == QUIC_PKT_TYPE_1RTT
482 && hdr->dst_conn_id.id_len != short_conn_id_len))
483 return 0;
484
485 if (hdr->type == QUIC_PKT_TYPE_1RTT) {
486 /* Short header. */
487
488 /*
489 * Cannot serialize a header whose DCID length is wrong, or with an
490 * invalid PN length.
491 */
492 if (hdr->dst_conn_id.id_len != short_conn_id_len
493 || short_conn_id_len > QUIC_MAX_CONN_ID_LEN
494 || hdr->pn_len < 1 || hdr->pn_len > 4)
495 return 0;
496
497 b0 = (hdr->spin_bit << 5)
498 | (hdr->key_phase << 2)
499 | (hdr->pn_len - 1)
500 | (hdr->reserved << 3)
501 | 0x40; /* fixed bit */
502
503 if (!WPACKET_put_bytes_u8(pkt, b0)
504 || !WPACKET_memcpy(pkt, hdr->dst_conn_id.id, short_conn_id_len)
505 || !WPACKET_get_total_written(pkt, &off_pn)
506 || !WPACKET_memcpy(pkt, hdr->pn, hdr->pn_len))
507 return 0;
508 } else {
509 /* Long header. */
510 unsigned int raw_type;
511
512 if (hdr->dst_conn_id.id_len > QUIC_MAX_CONN_ID_LEN
513 || hdr->src_conn_id.id_len > QUIC_MAX_CONN_ID_LEN)
514 return 0;
515
516 if (ossl_quic_pkt_type_has_pn(hdr->type)
517 && (hdr->pn_len < 1 || hdr->pn_len > 4))
518 return 0;
519
520 switch (hdr->type) {
521 case QUIC_PKT_TYPE_VERSION_NEG:
522 if (hdr->version != 0)
523 return 0;
524
525 /* Version negotiation packets use zero for the type bits */
526 raw_type = 0;
527 break;
528
529 case QUIC_PKT_TYPE_INITIAL: raw_type = 0; break;
530 case QUIC_PKT_TYPE_0RTT: raw_type = 1; break;
531 case QUIC_PKT_TYPE_HANDSHAKE: raw_type = 2; break;
532 case QUIC_PKT_TYPE_RETRY: raw_type = 3; break;
533 default:
534 return 0;
535 }
536
537 b0 = (raw_type << 4) | 0x80; /* long */
538 if (hdr->type != QUIC_PKT_TYPE_VERSION_NEG || hdr->fixed)
539 b0 |= 0x40; /* fixed */
540 if (ossl_quic_pkt_type_has_pn(hdr->type)) {
541 b0 |= hdr->pn_len - 1;
542 b0 |= (hdr->reserved << 2);
543 }
544 if (hdr->type == QUIC_PKT_TYPE_RETRY)
545 b0 |= hdr->unused;
546
547 if (!WPACKET_put_bytes_u8(pkt, b0)
548 || !WPACKET_put_bytes_u32(pkt, hdr->version)
549 || !WPACKET_put_bytes_u8(pkt, hdr->dst_conn_id.id_len)
550 || !WPACKET_memcpy(pkt, hdr->dst_conn_id.id,
551 hdr->dst_conn_id.id_len)
552 || !WPACKET_put_bytes_u8(pkt, hdr->src_conn_id.id_len)
553 || !WPACKET_memcpy(pkt, hdr->src_conn_id.id,
554 hdr->src_conn_id.id_len))
555 return 0;
556
557 if (hdr->type == QUIC_PKT_TYPE_VERSION_NEG
558 || hdr->type == QUIC_PKT_TYPE_RETRY) {
559 if (hdr->len > 0 && !WPACKET_reserve_bytes(pkt, hdr->len, NULL))
560 return 0;
561
562 return 1;
563 }
564
565 if (hdr->type == QUIC_PKT_TYPE_INITIAL) {
566 if (!WPACKET_quic_write_vlint(pkt, hdr->token_len)
567 || !WPACKET_memcpy(pkt, hdr->token, hdr->token_len))
568 return 0;
569 }
570
571 if (!WPACKET_quic_write_vlint(pkt, hdr->len + hdr->pn_len)
572 || !WPACKET_get_total_written(pkt, &off_pn)
573 || !WPACKET_memcpy(pkt, hdr->pn, hdr->pn_len))
574 return 0;
575 }
576
577 if (hdr->len > 0 && !WPACKET_reserve_bytes(pkt, hdr->len, NULL))
578 return 0;
579
580 off_sample = off_pn + 4;
581
582 if (ptrs != NULL) {
583 ptrs->raw_start = start;
584 ptrs->raw_sample = start + (off_sample - off_start);
585 ptrs->raw_sample_len
586 = WPACKET_get_curr(pkt) + hdr->len - ptrs->raw_sample;
587 ptrs->raw_pn = start + (off_pn - off_start);
588 }
589
590 return 1;
591 }
592
ossl_quic_wire_get_encoded_pkt_hdr_len(size_t short_conn_id_len,const QUIC_PKT_HDR * hdr)593 int ossl_quic_wire_get_encoded_pkt_hdr_len(size_t short_conn_id_len,
594 const QUIC_PKT_HDR *hdr)
595 {
596 size_t len = 0, enclen;
597
598 /* Cannot serialize a partial header, or one whose DCID length is wrong. */
599 if (hdr->partial
600 || (hdr->type == QUIC_PKT_TYPE_1RTT
601 && hdr->dst_conn_id.id_len != short_conn_id_len))
602 return 0;
603
604 if (hdr->type == QUIC_PKT_TYPE_1RTT) {
605 /* Short header. */
606
607 /*
608 * Cannot serialize a header whose DCID length is wrong, or with an
609 * invalid PN length.
610 */
611 if (hdr->dst_conn_id.id_len != short_conn_id_len
612 || short_conn_id_len > QUIC_MAX_CONN_ID_LEN
613 || hdr->pn_len < 1 || hdr->pn_len > 4)
614 return 0;
615
616 return 1 + short_conn_id_len + hdr->pn_len;
617 } else {
618 /* Long header. */
619 if (hdr->dst_conn_id.id_len > QUIC_MAX_CONN_ID_LEN
620 || hdr->src_conn_id.id_len > QUIC_MAX_CONN_ID_LEN)
621 return 0;
622
623 len += 1 /* Initial byte */ + 4 /* Version */
624 + 1 + hdr->dst_conn_id.id_len /* DCID Len, DCID */
625 + 1 + hdr->src_conn_id.id_len /* SCID Len, SCID */
626 ;
627
628 if (ossl_quic_pkt_type_has_pn(hdr->type)) {
629 if (hdr->pn_len < 1 || hdr->pn_len > 4)
630 return 0;
631
632 len += hdr->pn_len;
633 }
634
635 if (hdr->type == QUIC_PKT_TYPE_INITIAL) {
636 enclen = ossl_quic_vlint_encode_len(hdr->token_len);
637 if (!enclen)
638 return 0;
639
640 len += enclen + hdr->token_len;
641 }
642
643 if (!ossl_quic_pkt_type_must_be_last(hdr->type)) {
644 enclen = ossl_quic_vlint_encode_len(hdr->len + hdr->pn_len);
645 if (!enclen)
646 return 0;
647
648 len += enclen;
649 }
650
651 return len;
652 }
653 }
654
ossl_quic_wire_get_pkt_hdr_dst_conn_id(const unsigned char * buf,size_t buf_len,size_t short_conn_id_len,QUIC_CONN_ID * dst_conn_id)655 int ossl_quic_wire_get_pkt_hdr_dst_conn_id(const unsigned char *buf,
656 size_t buf_len,
657 size_t short_conn_id_len,
658 QUIC_CONN_ID *dst_conn_id)
659 {
660 unsigned char b0;
661 size_t blen;
662
663 if (buf_len < QUIC_MIN_VALID_PKT_LEN
664 || short_conn_id_len > QUIC_MAX_CONN_ID_LEN)
665 return 0;
666
667 b0 = buf[0];
668 if ((b0 & 0x80) != 0) {
669 /*
670 * Long header. We need 6 bytes (initial byte, 4 version bytes, DCID
671 * length byte to begin with). This is covered by the buf_len test
672 * above.
673 */
674
675 /*
676 * If the version field is non-zero (meaning that this is not a Version
677 * Negotiation packet), the fixed bit must be set.
678 */
679 if ((buf[1] || buf[2] || buf[3] || buf[4]) && (b0 & 0x40) == 0)
680 return 0;
681
682 blen = (size_t)buf[5]; /* DCID Length */
683 if (blen > QUIC_MAX_CONN_ID_LEN
684 || buf_len < QUIC_MIN_VALID_PKT_LEN + blen)
685 return 0;
686
687 dst_conn_id->id_len = (unsigned char)blen;
688 memcpy(dst_conn_id->id, buf + 6, blen);
689 return 1;
690 } else {
691 /* Short header. */
692 if ((b0 & 0x40) == 0)
693 /* Fixed bit not set, not a valid QUIC packet header. */
694 return 0;
695
696 if (buf_len < QUIC_MIN_VALID_PKT_LEN_CRYPTO + short_conn_id_len)
697 return 0;
698
699 dst_conn_id->id_len = (unsigned char)short_conn_id_len;
700 memcpy(dst_conn_id->id, buf + 1, short_conn_id_len);
701 return 1;
702 }
703 }
704
ossl_quic_wire_decode_pkt_hdr_pn(const unsigned char * enc_pn,size_t enc_pn_len,QUIC_PN largest_pn,QUIC_PN * res_pn)705 int ossl_quic_wire_decode_pkt_hdr_pn(const unsigned char *enc_pn,
706 size_t enc_pn_len,
707 QUIC_PN largest_pn,
708 QUIC_PN *res_pn)
709 {
710 int64_t expected_pn, truncated_pn, candidate_pn, pn_win, pn_hwin, pn_mask;
711
712 switch (enc_pn_len) {
713 case 1:
714 truncated_pn = enc_pn[0];
715 break;
716 case 2:
717 truncated_pn = ((QUIC_PN)enc_pn[0] << 8)
718 | (QUIC_PN)enc_pn[1];
719 break;
720 case 3:
721 truncated_pn = ((QUIC_PN)enc_pn[0] << 16)
722 | ((QUIC_PN)enc_pn[1] << 8)
723 | (QUIC_PN)enc_pn[2];
724 break;
725 case 4:
726 truncated_pn = ((QUIC_PN)enc_pn[0] << 24)
727 | ((QUIC_PN)enc_pn[1] << 16)
728 | ((QUIC_PN)enc_pn[2] << 8)
729 | (QUIC_PN)enc_pn[3];
730 break;
731 default:
732 return 0;
733 }
734
735 /* Implemented as per RFC 9000 Section A.3. */
736 expected_pn = largest_pn + 1;
737 pn_win = ((int64_t)1) << (enc_pn_len * 8);
738 pn_hwin = pn_win / 2;
739 pn_mask = pn_win - 1;
740 candidate_pn = (expected_pn & ~pn_mask) | truncated_pn;
741 if (candidate_pn <= expected_pn - pn_hwin
742 && candidate_pn < (((int64_t)1) << 62) - pn_win)
743 *res_pn = candidate_pn + pn_win;
744 else if (candidate_pn > expected_pn + pn_hwin
745 && candidate_pn >= pn_win)
746 *res_pn = candidate_pn - pn_win;
747 else
748 *res_pn = candidate_pn;
749 return 1;
750 }
751
752 /* From RFC 9000 Section A.2. Simplified implementation. */
ossl_quic_wire_determine_pn_len(QUIC_PN pn,QUIC_PN largest_acked)753 int ossl_quic_wire_determine_pn_len(QUIC_PN pn,
754 QUIC_PN largest_acked)
755 {
756 uint64_t num_unacked
757 = (largest_acked == QUIC_PN_INVALID) ? pn + 1 : pn - largest_acked;
758
759 /*
760 * num_unacked \in [ 0, 2** 7] -> 1 byte
761 * num_unacked \in (2** 7, 2**15] -> 2 bytes
762 * num_unacked \in (2**15, 2**23] -> 3 bytes
763 * num_unacked \in (2**23, ] -> 4 bytes
764 */
765
766 if (num_unacked <= (1U<<7)) return 1;
767 if (num_unacked <= (1U<<15)) return 2;
768 if (num_unacked <= (1U<<23)) return 3;
769 return 4;
770 }
771
ossl_quic_wire_encode_pkt_hdr_pn(QUIC_PN pn,unsigned char * enc_pn,size_t enc_pn_len)772 int ossl_quic_wire_encode_pkt_hdr_pn(QUIC_PN pn,
773 unsigned char *enc_pn,
774 size_t enc_pn_len)
775 {
776 switch (enc_pn_len) {
777 case 1:
778 enc_pn[0] = (unsigned char)pn;
779 break;
780 case 2:
781 enc_pn[1] = (unsigned char)pn;
782 enc_pn[0] = (unsigned char)(pn >> 8);
783 break;
784 case 3:
785 enc_pn[2] = (unsigned char)pn;
786 enc_pn[1] = (unsigned char)(pn >> 8);
787 enc_pn[0] = (unsigned char)(pn >> 16);
788 break;
789 case 4:
790 enc_pn[3] = (unsigned char)pn;
791 enc_pn[2] = (unsigned char)(pn >> 8);
792 enc_pn[1] = (unsigned char)(pn >> 16);
793 enc_pn[0] = (unsigned char)(pn >> 24);
794 break;
795 default:
796 return 0;
797 }
798
799 return 1;
800 }
801
ossl_quic_validate_retry_integrity_tag(OSSL_LIB_CTX * libctx,const char * propq,const QUIC_PKT_HDR * hdr,const QUIC_CONN_ID * client_initial_dcid)802 int ossl_quic_validate_retry_integrity_tag(OSSL_LIB_CTX *libctx,
803 const char *propq,
804 const QUIC_PKT_HDR *hdr,
805 const QUIC_CONN_ID *client_initial_dcid)
806 {
807 unsigned char expected_tag[QUIC_RETRY_INTEGRITY_TAG_LEN];
808 const unsigned char *actual_tag;
809
810 if (hdr == NULL || hdr->len < QUIC_RETRY_INTEGRITY_TAG_LEN)
811 return 0;
812
813 if (!ossl_quic_calculate_retry_integrity_tag(libctx, propq,
814 hdr, client_initial_dcid,
815 expected_tag))
816 return 0;
817
818 actual_tag = hdr->data + hdr->len - QUIC_RETRY_INTEGRITY_TAG_LEN;
819
820 return !CRYPTO_memcmp(expected_tag, actual_tag,
821 QUIC_RETRY_INTEGRITY_TAG_LEN);
822 }
823
824 /* RFC 9001 s. 5.8 */
825 static const unsigned char retry_integrity_key[] = {
826 0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66, 0x57, 0x5a,
827 0x1d, 0x76, 0x6b, 0x54, 0xe3, 0x68, 0xc8, 0x4e
828 };
829
830 static const unsigned char retry_integrity_nonce[] = {
831 0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2,
832 0x23, 0x98, 0x25, 0xbb
833 };
834
ossl_quic_calculate_retry_integrity_tag(OSSL_LIB_CTX * libctx,const char * propq,const QUIC_PKT_HDR * hdr,const QUIC_CONN_ID * client_initial_dcid,unsigned char * tag)835 int ossl_quic_calculate_retry_integrity_tag(OSSL_LIB_CTX *libctx,
836 const char *propq,
837 const QUIC_PKT_HDR *hdr,
838 const QUIC_CONN_ID *client_initial_dcid,
839 unsigned char *tag)
840 {
841 EVP_CIPHER *cipher = NULL;
842 EVP_CIPHER_CTX *cctx = NULL;
843 int ok = 0, l = 0, l2 = 0, wpkt_valid = 0;
844 WPACKET wpkt;
845 /* Worst case length of the Retry Psuedo-Packet header is 68 bytes. */
846 unsigned char buf[128];
847 QUIC_PKT_HDR hdr2;
848 size_t hdr_enc_len = 0;
849
850 if (hdr->type != QUIC_PKT_TYPE_RETRY || hdr->version == 0
851 || hdr->len < QUIC_RETRY_INTEGRITY_TAG_LEN
852 || hdr->data == NULL
853 || client_initial_dcid == NULL || tag == NULL
854 || client_initial_dcid->id_len > QUIC_MAX_CONN_ID_LEN) {
855 ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
856 goto err;
857 }
858
859 /*
860 * Do not reserve packet body in WPACKET. Retry packet header
861 * does not contain a Length field so this does not affect
862 * the serialized packet header.
863 */
864 hdr2 = *hdr;
865 hdr2.len = 0;
866
867 /* Assemble retry psuedo-packet. */
868 if (!WPACKET_init_static_len(&wpkt, buf, sizeof(buf), 0)) {
869 ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
870 goto err;
871 }
872
873 wpkt_valid = 1;
874
875 /* Prepend original DCID to the packet. */
876 if (!WPACKET_put_bytes_u8(&wpkt, client_initial_dcid->id_len)
877 || !WPACKET_memcpy(&wpkt, client_initial_dcid->id,
878 client_initial_dcid->id_len)) {
879 ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
880 goto err;
881 }
882
883 /* Encode main retry header. */
884 if (!ossl_quic_wire_encode_pkt_hdr(&wpkt, hdr2.dst_conn_id.id_len,
885 &hdr2, NULL))
886 goto err;
887
888 if (!WPACKET_get_total_written(&wpkt, &hdr_enc_len)) {
889 ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
890 goto err;
891 }
892
893 /* Create and initialise cipher context. */
894 /* TODO(QUIC FUTURE): Cipher fetch caching. */
895 if ((cipher = EVP_CIPHER_fetch(libctx, "AES-128-GCM", propq)) == NULL) {
896 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB);
897 goto err;
898 }
899
900 if ((cctx = EVP_CIPHER_CTX_new()) == NULL) {
901 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB);
902 goto err;
903 }
904
905 if (!EVP_CipherInit_ex(cctx, cipher, NULL,
906 retry_integrity_key, retry_integrity_nonce, /*enc=*/1)) {
907 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB);
908 goto err;
909 }
910
911 /* Feed packet header as AAD data. */
912 if (EVP_CipherUpdate(cctx, NULL, &l, buf, hdr_enc_len) != 1) {
913 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB);
914 goto err;
915 }
916
917 /* Feed packet body as AAD data. */
918 if (EVP_CipherUpdate(cctx, NULL, &l, hdr->data,
919 hdr->len - QUIC_RETRY_INTEGRITY_TAG_LEN) != 1) {
920 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB);
921 goto err;
922 }
923
924 /* Finalise and get tag. */
925 if (EVP_CipherFinal_ex(cctx, NULL, &l2) != 1) {
926 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB);
927 goto err;
928 }
929
930 if (EVP_CIPHER_CTX_ctrl(cctx, EVP_CTRL_AEAD_GET_TAG,
931 QUIC_RETRY_INTEGRITY_TAG_LEN,
932 tag) != 1) {
933 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB);
934 goto err;
935 }
936
937 ok = 1;
938 err:
939 EVP_CIPHER_free(cipher);
940 EVP_CIPHER_CTX_free(cctx);
941 if (wpkt_valid)
942 WPACKET_finish(&wpkt);
943
944 return ok;
945 }
946