quic_wire_pkt.c 31 KB

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