1 /* 2 * nghttp2 - HTTP/2 C Library 3 * 4 * Copyright (c) 2021 Tatsuhiro Tsujikawa 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sublicense, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be 15 * included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 #ifndef SHRPX_QUIC_H 26 #define SHRPX_QUIC_H 27 28 #include "shrpx.h" 29 30 #include <stdint.h> 31 32 #include <functional> 33 34 #include <ngtcp2/ngtcp2.h> 35 36 #include "network.h" 37 38 using namespace nghttp2; 39 40 namespace std { 41 template <> struct hash<ngtcp2_cid> { 42 std::size_t operator()(const ngtcp2_cid &cid) const noexcept { 43 // FNV-1a 64bits variant 44 constexpr uint64_t basis = 0xCBF29CE484222325ULL; 45 const uint8_t *p = cid.data, *end = cid.data + cid.datalen; 46 uint64_t h = basis; 47 48 for (; p != end;) { 49 h ^= *p++; 50 h *= basis; 51 } 52 53 return static_cast<size_t>(h); 54 } 55 }; 56 } // namespace std 57 58 bool operator==(const ngtcp2_cid &lhs, const ngtcp2_cid &rhs); 59 60 namespace shrpx { 61 62 struct UpstreamAddr; 63 struct QUICKeyingMaterials; 64 struct QUICKeyingMaterial; 65 66 constexpr size_t SHRPX_QUIC_SCIDLEN = 20; 67 constexpr size_t SHRPX_QUIC_SERVER_IDLEN = 4; 68 // SHRPX_QUIC_CID_PREFIXLEN includes SHRPX_QUIC_SERVER_IDLEN. 69 constexpr size_t SHRPX_QUIC_CID_PREFIXLEN = 8; 70 constexpr size_t SHRPX_QUIC_CID_PREFIX_OFFSET = 1; 71 constexpr size_t SHRPX_QUIC_DECRYPTED_DCIDLEN = 16; 72 constexpr size_t SHRPX_QUIC_CID_ENCRYPTION_KEYLEN = 16; 73 constexpr size_t SHRPX_QUIC_MAX_UDP_PAYLOAD_SIZE = 1472; 74 constexpr size_t SHRPX_QUIC_CONN_CLOSE_PKTLEN = 256; 75 constexpr size_t SHRPX_QUIC_STATELESS_RESET_BURST = 100; 76 constexpr size_t SHRPX_QUIC_SECRET_RESERVEDLEN = 4; 77 constexpr size_t SHRPX_QUIC_SECRETLEN = 32; 78 constexpr size_t SHRPX_QUIC_SALTLEN = 32; 79 constexpr uint8_t SHRPX_QUIC_DCID_KM_ID_MASK = 0xc0; 80 81 ngtcp2_tstamp quic_timestamp(); 82 83 int quic_send_packet(const UpstreamAddr *faddr, const sockaddr *remote_sa, 84 size_t remote_salen, const sockaddr *local_sa, 85 size_t local_salen, const ngtcp2_pkt_info &pi, 86 const uint8_t *data, size_t datalen, size_t gso_size); 87 88 int generate_quic_retry_connection_id(ngtcp2_cid &cid, size_t cidlen, 89 const uint8_t *server_id, uint8_t km_id, 90 const uint8_t *key); 91 92 int generate_quic_connection_id(ngtcp2_cid &cid, size_t cidlen, 93 const uint8_t *cid_prefix, uint8_t km_id, 94 const uint8_t *key); 95 96 int encrypt_quic_connection_id(uint8_t *dest, const uint8_t *src, 97 const uint8_t *key); 98 99 int decrypt_quic_connection_id(uint8_t *dest, const uint8_t *src, 100 const uint8_t *key); 101 102 int generate_quic_hashed_connection_id(ngtcp2_cid &dest, 103 const Address &remote_addr, 104 const Address &local_addr, 105 const ngtcp2_cid &cid); 106 107 int generate_quic_stateless_reset_token(uint8_t *token, const ngtcp2_cid &cid, 108 const uint8_t *secret, 109 size_t secretlen); 110 111 int generate_retry_token(uint8_t *token, size_t &tokenlen, uint32_t version, 112 const sockaddr *sa, socklen_t salen, 113 const ngtcp2_cid &retry_scid, const ngtcp2_cid &odcid, 114 const uint8_t *secret, size_t secretlen); 115 116 int verify_retry_token(ngtcp2_cid &odcid, const uint8_t *token, size_t tokenlen, 117 uint32_t version, const ngtcp2_cid &dcid, 118 const sockaddr *sa, socklen_t salen, 119 const uint8_t *secret, size_t secretlen); 120 121 int generate_token(uint8_t *token, size_t &tokenlen, const sockaddr *sa, 122 size_t salen, const uint8_t *secret, size_t secretlen); 123 124 int verify_token(const uint8_t *token, size_t tokenlen, const sockaddr *sa, 125 socklen_t salen, const uint8_t *secret, size_t secretlen); 126 127 int generate_quic_connection_id_encryption_key(uint8_t *key, size_t keylen, 128 const uint8_t *secret, 129 size_t secretlen, 130 const uint8_t *salt, 131 size_t saltlen); 132 133 const QUICKeyingMaterial * 134 select_quic_keying_material(const QUICKeyingMaterials &qkms, uint8_t km_id); 135 136 } // namespace shrpx 137 138 #endif // SHRPX_QUIC_H 139