quic_wire_pkt.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
  1. /*
  2. * Copyright 2022 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. #include "internal/quic_wire_pkt.h"
  10. int ossl_quic_hdr_protector_init(QUIC_HDR_PROTECTOR *hpr,
  11. OSSL_LIB_CTX *libctx,
  12. const char *propq,
  13. uint32_t cipher_id,
  14. const unsigned char *quic_hp_key,
  15. size_t quic_hp_key_len)
  16. {
  17. const char *cipher_name = NULL;
  18. switch (cipher_id) {
  19. case QUIC_HDR_PROT_CIPHER_AES_128:
  20. cipher_name = "AES-128-ECB";
  21. break;
  22. case QUIC_HDR_PROT_CIPHER_AES_256:
  23. cipher_name = "AES-256-ECB";
  24. break;
  25. case QUIC_HDR_PROT_CIPHER_CHACHA:
  26. cipher_name = "ChaCha20";
  27. break;
  28. default:
  29. return 0;
  30. }
  31. hpr->cipher_ctx = EVP_CIPHER_CTX_new();
  32. if (hpr->cipher_ctx == NULL)
  33. return 0;
  34. hpr->cipher = EVP_CIPHER_fetch(libctx, cipher_name, propq);
  35. if (hpr->cipher == NULL
  36. || quic_hp_key_len != (size_t)EVP_CIPHER_get_key_length(hpr->cipher))
  37. goto err;
  38. if (!EVP_CipherInit_ex(hpr->cipher_ctx, hpr->cipher, NULL,
  39. quic_hp_key, NULL, 1))
  40. goto err;
  41. hpr->libctx = libctx;
  42. hpr->propq = propq;
  43. hpr->cipher_id = cipher_id;
  44. return 1;
  45. err:
  46. ossl_quic_hdr_protector_cleanup(hpr);
  47. return 0;
  48. }
  49. void ossl_quic_hdr_protector_cleanup(QUIC_HDR_PROTECTOR *hpr)
  50. {
  51. EVP_CIPHER_CTX_free(hpr->cipher_ctx);
  52. hpr->cipher_ctx = NULL;
  53. EVP_CIPHER_free(hpr->cipher);
  54. hpr->cipher = NULL;
  55. }
  56. static int hdr_generate_mask(QUIC_HDR_PROTECTOR *hpr,
  57. const unsigned char *sample, size_t sample_len,
  58. unsigned char *mask)
  59. {
  60. int l = 0;
  61. unsigned char dst[16];
  62. static const unsigned char zeroes[5] = {0};
  63. size_t i;
  64. if (hpr->cipher_id == QUIC_HDR_PROT_CIPHER_AES_128
  65. || hpr->cipher_id == QUIC_HDR_PROT_CIPHER_AES_256) {
  66. if (sample_len < 16)
  67. return 0;
  68. if (!EVP_CipherInit_ex(hpr->cipher_ctx, NULL, NULL, NULL, NULL, 1)
  69. || !EVP_CipherUpdate(hpr->cipher_ctx, dst, &l, sample, 16))
  70. return 0;
  71. for (i = 0; i < 5; ++i)
  72. mask[i] = dst[i];
  73. } else if (hpr->cipher_id == QUIC_HDR_PROT_CIPHER_CHACHA) {
  74. if (sample_len < 16)
  75. return 0;
  76. if (!EVP_CipherInit_ex(hpr->cipher_ctx, NULL, NULL, NULL, sample, 1)
  77. || !EVP_CipherUpdate(hpr->cipher_ctx, mask, &l,
  78. zeroes, sizeof(zeroes)))
  79. return 0;
  80. } else {
  81. assert(0);
  82. return 0;
  83. }
  84. return 1;
  85. }
  86. int ossl_quic_hdr_protector_decrypt(QUIC_HDR_PROTECTOR *hpr,
  87. QUIC_PKT_HDR_PTRS *ptrs)
  88. {
  89. return ossl_quic_hdr_protector_decrypt_fields(hpr,
  90. ptrs->raw_sample,
  91. ptrs->raw_sample_len,
  92. ptrs->raw_start,
  93. ptrs->raw_pn);
  94. }
  95. int ossl_quic_hdr_protector_decrypt_fields(QUIC_HDR_PROTECTOR *hpr,
  96. const unsigned char *sample,
  97. size_t sample_len,
  98. unsigned char *first_byte,
  99. unsigned char *pn_bytes)
  100. {
  101. unsigned char mask[5], pn_len, i;
  102. if (!hdr_generate_mask(hpr, sample, sample_len, mask))
  103. return 0;
  104. *first_byte ^= mask[0] & ((*first_byte & 0x80) != 0 ? 0xf : 0x1f);
  105. pn_len = (*first_byte & 0x3) + 1;
  106. for (i = 0; i < pn_len; ++i)
  107. pn_bytes[i] ^= mask[i + 1];
  108. return 1;
  109. }
  110. int ossl_quic_hdr_protector_encrypt(QUIC_HDR_PROTECTOR *hpr,
  111. QUIC_PKT_HDR_PTRS *ptrs)
  112. {
  113. return ossl_quic_hdr_protector_encrypt_fields(hpr,
  114. ptrs->raw_sample,
  115. ptrs->raw_sample_len,
  116. ptrs->raw_start,
  117. ptrs->raw_pn);
  118. }
  119. int ossl_quic_hdr_protector_encrypt_fields(QUIC_HDR_PROTECTOR *hpr,
  120. const unsigned char *sample,
  121. size_t sample_len,
  122. unsigned char *first_byte,
  123. unsigned char *pn_bytes)
  124. {
  125. unsigned char mask[5], pn_len, i;
  126. if (!hdr_generate_mask(hpr, sample, sample_len, mask))
  127. return 0;
  128. pn_len = (*first_byte & 0x3) + 1;
  129. for (i = 0; i < pn_len; ++i)
  130. pn_bytes[i] ^= mask[i + 1];
  131. *first_byte ^= mask[0] & ((*first_byte & 0x80) != 0 ? 0xf : 0x1f);
  132. return 1;
  133. }
  134. int ossl_quic_wire_decode_pkt_hdr(PACKET *pkt,
  135. size_t short_conn_id_len,
  136. int partial,
  137. QUIC_PKT_HDR *hdr,
  138. QUIC_PKT_HDR_PTRS *ptrs)
  139. {
  140. unsigned int b0;
  141. unsigned char *pn = NULL;
  142. size_t l = PACKET_remaining(pkt);
  143. if (ptrs != NULL) {
  144. ptrs->raw_start = (unsigned char *)PACKET_data(pkt);
  145. ptrs->raw_sample = NULL;
  146. ptrs->raw_sample_len = 0;
  147. ptrs->raw_pn = NULL;
  148. }
  149. if (l < QUIC_MIN_VALID_PKT_LEN
  150. || !PACKET_get_1(pkt, &b0))
  151. return 0;
  152. hdr->partial = partial;
  153. if ((b0 & 0x80) == 0) {
  154. /* Short header. */
  155. if (short_conn_id_len > QUIC_MAX_CONN_ID_LEN)
  156. return 0;
  157. if ((b0 & 0x40) == 0 /* fixed bit not set? */
  158. || l < QUIC_MIN_VALID_PKT_LEN_CRYPTO)
  159. return 0;
  160. hdr->type = QUIC_PKT_TYPE_1RTT;
  161. hdr->fixed = 1;
  162. hdr->spin_bit = (b0 & 0x20) != 0;
  163. if (partial) {
  164. hdr->key_phase = 0; /* protected, zero for now */
  165. hdr->pn_len = 0; /* protected, zero for now */
  166. } else {
  167. hdr->key_phase = (b0 & 0x4) != 0;
  168. hdr->pn_len = (b0 & 0x3) + 1;
  169. }
  170. /* Copy destination connection ID field to header structure. */
  171. if (!PACKET_copy_bytes(pkt, hdr->dst_conn_id.id, short_conn_id_len))
  172. return 0;
  173. hdr->dst_conn_id.id_len = short_conn_id_len;
  174. /*
  175. * Skip over the PN. If this is a partial decode, the PN length field
  176. * currently has header protection applied. Thus we do not know the
  177. * length of the PN but we are allowed to assume it is 4 bytes long at
  178. * this stage.
  179. */
  180. memset(hdr->pn, 0, sizeof(hdr->pn));
  181. pn = (unsigned char *)PACKET_data(pkt);
  182. if (partial) {
  183. if (!PACKET_forward(pkt, sizeof(hdr->pn)))
  184. return 0;
  185. } else {
  186. if (!PACKET_copy_bytes(pkt, hdr->pn, hdr->pn_len))
  187. return 0;
  188. }
  189. /* Fields not used in short-header packets. */
  190. hdr->version = 0;
  191. hdr->src_conn_id.id_len = 0;
  192. hdr->token = NULL;
  193. hdr->token_len = 0;
  194. /*
  195. * Short-header packets always come last in a datagram, the length
  196. * is the remainder of the buffer.
  197. */
  198. hdr->len = PACKET_remaining(pkt);
  199. hdr->data = PACKET_data(pkt);
  200. /*
  201. * Skip over payload. Since this is a short header packet, which cannot
  202. * be followed by any other kind of packet, this advances us to the end
  203. * of the datagram.
  204. */
  205. if (!PACKET_forward(pkt, hdr->len))
  206. return 0;
  207. } else {
  208. /* Long header. */
  209. unsigned long version;
  210. unsigned int dst_conn_id_len, src_conn_id_len, raw_type;
  211. if (!PACKET_get_net_4(pkt, &version))
  212. return 0;
  213. /*
  214. * All QUIC packets must have the fixed bit set, except exceptionally
  215. * for Version Negotiation packets.
  216. */
  217. if (version != 0 && (b0 & 0x40) == 0)
  218. return 0;
  219. if (!PACKET_get_1(pkt, &dst_conn_id_len)
  220. || dst_conn_id_len > QUIC_MAX_CONN_ID_LEN
  221. || !PACKET_copy_bytes(pkt, hdr->dst_conn_id.id, dst_conn_id_len)
  222. || !PACKET_get_1(pkt, &src_conn_id_len)
  223. || src_conn_id_len > QUIC_MAX_CONN_ID_LEN
  224. || !PACKET_copy_bytes(pkt, hdr->src_conn_id.id, src_conn_id_len))
  225. return 0;
  226. hdr->version = (uint32_t)version;
  227. hdr->dst_conn_id.id_len = (unsigned char)dst_conn_id_len;
  228. hdr->src_conn_id.id_len = (unsigned char)src_conn_id_len;
  229. if (version == 0) {
  230. /*
  231. * Version negotiation packet. Version negotiation packets are
  232. * identified by a version field of 0 and the type bits in the first
  233. * byte are ignored (they may take any value, and we ignore them).
  234. */
  235. hdr->type = QUIC_PKT_TYPE_VERSION_NEG;
  236. hdr->fixed = (b0 & 0x40) != 0;
  237. hdr->data = PACKET_data(pkt);
  238. hdr->len = PACKET_remaining(pkt);
  239. /* Version negotiation packets are always fully decoded. */
  240. hdr->partial = 0;
  241. /* Fields not used in version negotiation packets. */
  242. hdr->pn_len = 0;
  243. hdr->spin_bit = 0;
  244. hdr->key_phase = 0;
  245. hdr->token = NULL;
  246. hdr->token_len = 0;
  247. memset(hdr->pn, 0, sizeof(hdr->pn));
  248. if (!PACKET_forward(pkt, hdr->len))
  249. return 0;
  250. } else if (version != QUIC_VERSION_1) {
  251. /* Unknown version, do not decode. */
  252. return 0;
  253. } else {
  254. if (l < QUIC_MIN_VALID_PKT_LEN_CRYPTO)
  255. return 0;
  256. /* Get long packet type and decode to QUIC_PKT_TYPE_*. */
  257. raw_type = ((b0 >> 4) & 0x3);
  258. switch (raw_type) {
  259. case 0:
  260. hdr->type = QUIC_PKT_TYPE_INITIAL;
  261. break;
  262. case 1:
  263. hdr->type = QUIC_PKT_TYPE_0RTT;
  264. break;
  265. case 2:
  266. hdr->type = QUIC_PKT_TYPE_HANDSHAKE;
  267. break;
  268. case 3:
  269. hdr->type = QUIC_PKT_TYPE_RETRY;
  270. break;
  271. }
  272. hdr->pn_len = 0;
  273. hdr->fixed = 1;
  274. /* Fields not used in long-header packets. */
  275. hdr->spin_bit = 0;
  276. hdr->key_phase = 0;
  277. if (hdr->type == QUIC_PKT_TYPE_INITIAL) {
  278. /* Initial packet. */
  279. uint64_t token_len;
  280. if (!PACKET_get_quic_vlint(pkt, &token_len)
  281. || token_len > SIZE_MAX
  282. || !PACKET_get_bytes(pkt, &hdr->token, token_len))
  283. return 0;
  284. hdr->token_len = (size_t)token_len;
  285. if (token_len == 0)
  286. hdr->token = NULL;
  287. } else {
  288. hdr->token = NULL;
  289. hdr->token_len = 0;
  290. }
  291. if (hdr->type == QUIC_PKT_TYPE_RETRY) {
  292. /* Retry packet. */
  293. hdr->data = PACKET_data(pkt);
  294. hdr->len = PACKET_remaining(pkt);
  295. /* Retry packets are always fully decoded. */
  296. hdr->partial = 0;
  297. /* Fields not used in Retry packets. */
  298. memset(hdr->pn, 0, sizeof(hdr->pn));
  299. if (!PACKET_forward(pkt, hdr->len))
  300. return 0;
  301. } else {
  302. /* Initial, 0-RTT or Handshake packet. */
  303. uint64_t len;
  304. hdr->pn_len = partial ? 0 : (b0 & 3) + 1;
  305. if (!PACKET_get_quic_vlint(pkt, &len)
  306. || len < sizeof(hdr->pn)
  307. || len > PACKET_remaining(pkt))
  308. return 0;
  309. /*
  310. * Skip over the PN. If this is a partial decode, the PN length
  311. * field currently has header protection applied. Thus we do not
  312. * know the length of the PN but we are allowed to assume it is
  313. * 4 bytes long at this stage.
  314. */
  315. pn = (unsigned char *)PACKET_data(pkt);
  316. memset(hdr->pn, 0, sizeof(hdr->pn));
  317. if (partial) {
  318. if (!PACKET_forward(pkt, sizeof(hdr->pn)))
  319. return 0;
  320. hdr->len = (size_t)(len - sizeof(hdr->pn));
  321. } else {
  322. if (!PACKET_copy_bytes(pkt, hdr->pn, hdr->pn_len))
  323. return 0;
  324. hdr->len = (size_t)(len - hdr->pn_len);
  325. }
  326. hdr->data = PACKET_data(pkt);
  327. /* Skip over packet body. */
  328. if (!PACKET_forward(pkt, hdr->len))
  329. return 0;
  330. }
  331. }
  332. }
  333. if (ptrs != NULL) {
  334. ptrs->raw_pn = pn;
  335. if (pn != NULL) {
  336. ptrs->raw_sample = pn + 4;
  337. ptrs->raw_sample_len = PACKET_end(pkt) - ptrs->raw_sample;
  338. }
  339. }
  340. return 1;
  341. }
  342. int ossl_quic_wire_encode_pkt_hdr(WPACKET *pkt,
  343. size_t short_conn_id_len,
  344. const QUIC_PKT_HDR *hdr,
  345. QUIC_PKT_HDR_PTRS *ptrs)
  346. {
  347. unsigned char b0;
  348. size_t off_start, off_sample, off_pn;
  349. unsigned char *start = WPACKET_get_curr(pkt);
  350. if (!WPACKET_get_total_written(pkt, &off_start))
  351. return 0;
  352. if (ptrs != NULL) {
  353. ptrs->raw_start = NULL;
  354. ptrs->raw_sample = NULL;
  355. ptrs->raw_sample_len = 0;
  356. ptrs->raw_pn = 0;
  357. }
  358. /* Cannot serialize a partial header, or one whose DCID length is wrong. */
  359. if (hdr->partial
  360. || (hdr->type == QUIC_PKT_TYPE_1RTT
  361. && hdr->dst_conn_id.id_len != short_conn_id_len))
  362. return 0;
  363. if (hdr->type == QUIC_PKT_TYPE_1RTT) {
  364. /* Short header. */
  365. /*
  366. * Cannot serialize a header whose DCID length is wrong, or with an
  367. * invalid PN length.
  368. */
  369. if (hdr->dst_conn_id.id_len != short_conn_id_len
  370. || short_conn_id_len > QUIC_MAX_CONN_ID_LEN
  371. || hdr->pn_len < 1 || hdr->pn_len > 4)
  372. return 0;
  373. b0 = (hdr->spin_bit << 5)
  374. | (hdr->key_phase << 2)
  375. | (hdr->pn_len - 1)
  376. | 0x40; /* fixed bit */
  377. if (!WPACKET_put_bytes_u8(pkt, b0)
  378. || !WPACKET_memcpy(pkt, hdr->dst_conn_id.id, short_conn_id_len)
  379. || !WPACKET_get_total_written(pkt, &off_pn)
  380. || !WPACKET_memcpy(pkt, hdr->pn, hdr->pn_len))
  381. return 0;
  382. } else {
  383. /* Long header. */
  384. unsigned int raw_type;
  385. if (hdr->dst_conn_id.id_len > QUIC_MAX_CONN_ID_LEN
  386. || hdr->src_conn_id.id_len > QUIC_MAX_CONN_ID_LEN)
  387. return 0;
  388. if (ossl_quic_pkt_type_has_pn(hdr->type)
  389. && (hdr->pn_len < 1 || hdr->pn_len > 4))
  390. return 0;
  391. switch (hdr->type) {
  392. case QUIC_PKT_TYPE_VERSION_NEG:
  393. if (hdr->version != 0)
  394. return 0;
  395. /* Version negotiation packets use zero for the type bits */
  396. raw_type = 0;
  397. break;
  398. case QUIC_PKT_TYPE_INITIAL: raw_type = 0; break;
  399. case QUIC_PKT_TYPE_0RTT: raw_type = 1; break;
  400. case QUIC_PKT_TYPE_HANDSHAKE: raw_type = 2; break;
  401. case QUIC_PKT_TYPE_RETRY: raw_type = 3; break;
  402. default:
  403. return 0;
  404. }
  405. b0 = (raw_type << 4) | 0x80; /* long */
  406. if (hdr->type != QUIC_PKT_TYPE_VERSION_NEG || hdr->fixed)
  407. b0 |= 0x40; /* fixed */
  408. if (ossl_quic_pkt_type_has_pn(hdr->type))
  409. b0 |= hdr->pn_len - 1;
  410. if (!WPACKET_put_bytes_u8(pkt, b0)
  411. || !WPACKET_put_bytes_u32(pkt, hdr->version)
  412. || !WPACKET_put_bytes_u8(pkt, hdr->dst_conn_id.id_len)
  413. || !WPACKET_memcpy(pkt, hdr->dst_conn_id.id,
  414. hdr->dst_conn_id.id_len)
  415. || !WPACKET_put_bytes_u8(pkt, hdr->src_conn_id.id_len)
  416. || !WPACKET_memcpy(pkt, hdr->src_conn_id.id,
  417. hdr->src_conn_id.id_len))
  418. return 0;
  419. if (hdr->type == QUIC_PKT_TYPE_VERSION_NEG
  420. || hdr->type == QUIC_PKT_TYPE_RETRY) {
  421. if (!WPACKET_reserve_bytes(pkt, hdr->len, NULL))
  422. return 0;
  423. return 1;
  424. }
  425. if (hdr->type == QUIC_PKT_TYPE_INITIAL) {
  426. if (!WPACKET_quic_write_vlint(pkt, hdr->token_len)
  427. || !WPACKET_memcpy(pkt, hdr->token, hdr->token_len))
  428. return 0;
  429. }
  430. if (!WPACKET_quic_write_vlint(pkt, hdr->len + hdr->pn_len)
  431. || !WPACKET_get_total_written(pkt, &off_pn)
  432. || !WPACKET_memcpy(pkt, hdr->pn, hdr->pn_len))
  433. return 0;
  434. }
  435. if (!WPACKET_reserve_bytes(pkt, hdr->len, NULL))
  436. return 0;
  437. off_sample = off_pn + 4;
  438. if (ptrs != NULL) {
  439. ptrs->raw_start = start;
  440. ptrs->raw_sample = start + (off_sample - off_start);
  441. ptrs->raw_sample_len
  442. = WPACKET_get_curr(pkt) + hdr->len - ptrs->raw_sample;
  443. ptrs->raw_pn = start + (off_pn - off_start);
  444. }
  445. return 1;
  446. }
  447. int ossl_quic_wire_get_encoded_pkt_hdr_len(size_t short_conn_id_len,
  448. const QUIC_PKT_HDR *hdr)
  449. {
  450. size_t len = 0, enclen;
  451. /* Cannot serialize a partial header, or one whose DCID length is wrong. */
  452. if (hdr->partial
  453. || (hdr->type == QUIC_PKT_TYPE_1RTT
  454. && hdr->dst_conn_id.id_len != short_conn_id_len))
  455. return 0;
  456. if (hdr->type == QUIC_PKT_TYPE_1RTT) {
  457. /* Short header. */
  458. /*
  459. * Cannot serialize a header whose DCID length is wrong, or with an
  460. * invalid PN length.
  461. */
  462. if (hdr->dst_conn_id.id_len != short_conn_id_len
  463. || short_conn_id_len > QUIC_MAX_CONN_ID_LEN
  464. || hdr->pn_len < 1 || hdr->pn_len > 4)
  465. return 0;
  466. return 1 + short_conn_id_len + hdr->pn_len;
  467. } else {
  468. /* Long header. */
  469. if (hdr->dst_conn_id.id_len > QUIC_MAX_CONN_ID_LEN
  470. || hdr->src_conn_id.id_len > QUIC_MAX_CONN_ID_LEN)
  471. return 0;
  472. len += 1 /* Initial byte */ + 4 /* Version */
  473. + 1 + hdr->dst_conn_id.id_len /* DCID Len, DCID */
  474. + 1 + hdr->src_conn_id.id_len /* SCID Len, SCID */
  475. ;
  476. if (ossl_quic_pkt_type_has_pn(hdr->type)) {
  477. if (hdr->pn_len < 1 || hdr->pn_len > 4)
  478. return 0;
  479. len += hdr->pn_len;
  480. }
  481. if (hdr->type == QUIC_PKT_TYPE_INITIAL) {
  482. enclen = ossl_quic_vlint_encode_len(hdr->token_len);
  483. if (!enclen)
  484. return 0;
  485. len += enclen;
  486. }
  487. if (!ossl_quic_pkt_type_must_be_last(hdr->type)) {
  488. enclen = ossl_quic_vlint_encode_len(hdr->len);
  489. if (!enclen)
  490. return 0;
  491. len += enclen;
  492. }
  493. return len;
  494. }
  495. }
  496. int ossl_quic_wire_get_pkt_hdr_dst_conn_id(const unsigned char *buf,
  497. size_t buf_len,
  498. size_t short_conn_id_len,
  499. QUIC_CONN_ID *dst_conn_id)
  500. {
  501. unsigned char b0;
  502. size_t blen;
  503. if (buf_len < QUIC_MIN_VALID_PKT_LEN
  504. || short_conn_id_len > QUIC_MAX_CONN_ID_LEN)
  505. return 0;
  506. b0 = buf[0];
  507. if ((b0 & 0x80) != 0) {
  508. /*
  509. * Long header. We need 6 bytes (initial byte, 4 version bytes, DCID
  510. * length byte to begin with). This is covered by the buf_len test
  511. * above.
  512. */
  513. /*
  514. * If the version field is non-zero (meaning that this is not a Version
  515. * Negotiation packet), the fixed bit must be set.
  516. */
  517. if ((buf[1] || buf[2] || buf[3] || buf[4]) && (b0 & 0x40) == 0)
  518. return 0;
  519. blen = (size_t)buf[5]; /* DCID Length */
  520. if (blen > QUIC_MAX_CONN_ID_LEN
  521. || buf_len < QUIC_MIN_VALID_PKT_LEN + blen)
  522. return 0;
  523. dst_conn_id->id_len = (unsigned char)blen;
  524. memcpy(dst_conn_id->id, buf + 6, blen);
  525. return 1;
  526. } else {
  527. /* Short header. */
  528. if ((b0 & 0x40) == 0)
  529. /* Fixed bit not set, not a valid QUIC packet header. */
  530. return 0;
  531. if (buf_len < QUIC_MIN_VALID_PKT_LEN_CRYPTO + short_conn_id_len)
  532. return 0;
  533. dst_conn_id->id_len = short_conn_id_len;
  534. memcpy(dst_conn_id->id, buf + 1, short_conn_id_len);
  535. return 1;
  536. }
  537. }
  538. int ossl_quic_wire_decode_pkt_hdr_pn(const unsigned char *enc_pn,
  539. size_t enc_pn_len,
  540. QUIC_PN largest_pn,
  541. QUIC_PN *res_pn)
  542. {
  543. int64_t expected_pn, truncated_pn, candidate_pn, pn_win, pn_hwin, pn_mask;
  544. switch (enc_pn_len) {
  545. case 1:
  546. truncated_pn = enc_pn[0];
  547. break;
  548. case 2:
  549. truncated_pn = ((QUIC_PN)enc_pn[0] << 8)
  550. | (QUIC_PN)enc_pn[1];
  551. break;
  552. case 3:
  553. truncated_pn = ((QUIC_PN)enc_pn[0] << 16)
  554. | ((QUIC_PN)enc_pn[1] << 8)
  555. | (QUIC_PN)enc_pn[2];
  556. break;
  557. case 4:
  558. truncated_pn = ((QUIC_PN)enc_pn[0] << 24)
  559. | ((QUIC_PN)enc_pn[1] << 16)
  560. | ((QUIC_PN)enc_pn[2] << 8)
  561. | (QUIC_PN)enc_pn[3];
  562. break;
  563. default:
  564. return 0;
  565. }
  566. /* Implemented as per RFC 9000 Section A.3. */
  567. expected_pn = largest_pn + 1;
  568. pn_win = ((int64_t)1) << (enc_pn_len * 8);
  569. pn_hwin = pn_win / 2;
  570. pn_mask = pn_win - 1;
  571. candidate_pn = (expected_pn & ~pn_mask) | truncated_pn;
  572. if (candidate_pn <= expected_pn - pn_hwin
  573. && candidate_pn < (((int64_t)1) << 62) - pn_win)
  574. *res_pn = candidate_pn + pn_win;
  575. else if (candidate_pn > expected_pn + pn_hwin
  576. && candidate_pn >= pn_win)
  577. *res_pn = candidate_pn - pn_win;
  578. else
  579. *res_pn = candidate_pn;
  580. return 1;
  581. }
  582. /* From RFC 9000 Section A.2. Simplified implementation. */
  583. int ossl_quic_wire_determine_pn_len(QUIC_PN pn,
  584. QUIC_PN largest_acked)
  585. {
  586. uint64_t num_unacked
  587. = (largest_acked == QUIC_PN_INVALID) ? pn + 1 : pn - largest_acked;
  588. /*
  589. * num_unacked \in [ 0, 2** 7] -> 1 byte
  590. * num_unacked \in (2** 7, 2**15] -> 2 bytes
  591. * num_unacked \in (2**15, 2**23] -> 3 bytes
  592. * num_unacked \in (2**23, ] -> 4 bytes
  593. */
  594. if (num_unacked <= (1U<<7)) return 1;
  595. if (num_unacked <= (1U<<15)) return 2;
  596. if (num_unacked <= (1U<<23)) return 3;
  597. return 4;
  598. }
  599. int ossl_quic_wire_encode_pkt_hdr_pn(QUIC_PN pn,
  600. unsigned char *enc_pn,
  601. size_t enc_pn_len)
  602. {
  603. switch (enc_pn_len) {
  604. case 1:
  605. enc_pn[0] = (unsigned char)pn;
  606. break;
  607. case 2:
  608. enc_pn[1] = (unsigned char)pn;
  609. enc_pn[0] = (unsigned char)(pn >> 8);
  610. break;
  611. case 3:
  612. enc_pn[2] = (unsigned char)pn;
  613. enc_pn[1] = (unsigned char)(pn >> 8);
  614. enc_pn[0] = (unsigned char)(pn >> 16);
  615. break;
  616. case 4:
  617. enc_pn[3] = (unsigned char)pn;
  618. enc_pn[2] = (unsigned char)(pn >> 8);
  619. enc_pn[1] = (unsigned char)(pn >> 16);
  620. enc_pn[0] = (unsigned char)(pn >> 24);
  621. break;
  622. default:
  623. return 0;
  624. }
  625. return 1;
  626. }