1/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ 2#ifndef LSQUIC_ENC_SESS_H 3#define LSQUIC_ENC_SESS_H 1 4 5#include "lsquic_shared_support.h" 6 7struct lsquic_alarmset; 8struct lsquic_engine_public; 9struct lsquic_packet_out; 10struct lsquic_packet_in; 11struct stream_wrapper; 12struct ver_neg; 13struct lsquic_conn; 14struct transport_params; 15struct lsquic_cid; 16struct ssl_stream_method_st; 17struct ssl_st; 18struct sockaddr; 19struct conn_cid_elem; 20struct lsquic_engine_settings; 21enum lsquic_version; 22 23#define DNONC_LENGTH 32 24#define SRST_LENGTH 16 25 26/* From [draft-ietf-quic-tls-14]: 27 * 28 * Data is protected using a number of encryption levels: 29 * 30 * o Plaintext 31 * 32 * o Early Data (0-RTT) Keys 33 * 34 * o Handshake Keys 35 * 36 * o Application Data (1-RTT) Keys 37 */ 38 39/* This enum maps to the list above */ 40enum enc_level 41{ 42 ENC_LEV_CLEAR, 43 ENC_LEV_EARLY, 44 ENC_LEV_INIT, 45 ENC_LEV_FORW, 46 N_ENC_LEVS 47}; 48 49enum handshake_error /* TODO: rename this enum */ 50{ 51 DATA_NOT_ENOUGH = -2, 52 DATA_FORMAT_ERROR = -1, 53 HS_ERROR = -1, 54 DATA_NO_ERROR = 0, 55 HS_SHLO = 0, 56 HS_1RTT = 1, 57 HS_SREJ = 2, 58}; 59 60#ifndef LSQUIC_KEEP_ENC_SESS_HISTORY 61# ifndef NDEBUG 62# define LSQUIC_KEEP_ENC_SESS_HISTORY 1 63# else 64# define LSQUIC_KEEP_ENC_SESS_HISTORY 0 65# endif 66#endif 67 68#if LSQUIC_KEEP_ENC_SESS_HISTORY 69#define ESHIST_BITS 7 70#define ESHIST_MASK ((1 << ESHIST_BITS) - 1) 71#define ESHIST_STR_SIZE ((1 << ESHIST_BITS) + 1) 72#endif 73 74enum enc_packout { ENCPA_OK, ENCPA_NOMEM, ENCPA_BADCRYPT, }; 75 76enum dec_packin { 77 DECPI_OK, 78 DECPI_NOMEM, 79 DECPI_TOO_SHORT, 80 DECPI_NOT_YET, 81 DECPI_BADCRYPT, 82 DECPI_VIOLATION, 83}; 84 85typedef void enc_session_t; 86 87struct enc_session_funcs_common 88{ 89 /* Global initialization: call once per implementation */ 90 int (*esf_global_init)(int flags); 91 92 /* Global cleanup: call once per implementation */ 93 void (*esf_global_cleanup) (void); 94 95 const char * 96 (*esf_cipher) (enc_session_t *); 97 98 int 99 (*esf_keysize) (enc_session_t *); 100 101 int 102 (*esf_alg_keysize) (enc_session_t *); 103 104 const char * 105 (*esf_get_sni) (enc_session_t *); 106 107 /* Need to pass lconn in encrypt and decrypt methods because enc_session 108 * is allowed to be NULL for gQUIC. 109 */ 110 enum enc_packout 111 (*esf_encrypt_packet) (enc_session_t *, const struct lsquic_engine_public *, 112 struct lsquic_conn *, struct lsquic_packet_out *); 113 114 enum dec_packin 115 (*esf_decrypt_packet)(enc_session_t *, struct lsquic_engine_public *, 116 const struct lsquic_conn *, struct lsquic_packet_in *); 117 118 struct stack_st_X509 * 119 (*esf_get_server_cert_chain) (enc_session_t *); 120 121 int 122 (*esf_verify_reset_token) (enc_session_t *, const unsigned char *, size_t); 123 124 int 125 (*esf_did_sess_resume_succeed) (enc_session_t *); 126 127 int 128 (*esf_is_sess_resume_enabled) (enc_session_t *); 129 130 void 131 (*esf_set_conn) (enc_session_t *, struct lsquic_conn *); 132 133 /* Optional. This function gets called after packets are encrypted, 134 * batched, and are about to be sent. 135 */ 136 void 137 (*esf_flush_encryption) (enc_session_t *); 138 139 unsigned 140 esf_tag_len; 141}; 142 143struct enc_session_funcs_gquic 144{ 145#if LSQUIC_KEEP_ENC_SESS_HISTORY 146 /* Grab encryption session history */ 147 void (*esf_get_hist) (enc_session_t *, 148 char buf[ESHIST_STR_SIZE]); 149#endif 150 151 /* Destroy enc session */ 152 void (*esf_destroy)(enc_session_t *enc_session); 153 154 /* Return true if handshake has been completed */ 155 int (*esf_is_hsk_done)(enc_session_t *enc_session); 156 157 /* Get value of setting specified by `tag' */ 158 int (*esf_get_peer_setting) (enc_session_t *, uint32_t tag, 159 uint32_t *val); 160 161 /* Get value of peer option (that from COPT array) */ 162 int (*esf_get_peer_option) (enc_session_t *enc_session, 163 uint32_t tag); 164 165 /* Create server session */ 166 enc_session_t * 167 (*esf_create_server) (struct lsquic_conn *, 168 lsquic_cid_t cid, struct lsquic_engine_public *); 169 170 /* out_len should have init value as the max length of out */ 171 enum handshake_error 172 (*esf_handle_chlo) (enc_session_t *enc_session, enum lsquic_version, 173 const uint8_t *in, int in_len, time_t t, 174 const struct sockaddr *ip_addr, const struct sockaddr *local, 175 uint8_t *out, size_t *out_len, 176 uint8_t nonce[DNONC_LENGTH], int *nonce_set); 177 178 void (*esf_hsk_destroy)(void *hsk_ctx); 179 180#ifndef NDEBUG 181 /* Need to expose this function for testing */ 182 int (*esf_determine_diversification_key) (enc_session_t *, 183 uint8_t *diversification_nonce); 184#endif 185 186 const char * 187 (*esf_get_ua) (enc_session_t *); 188 189 int 190 (*esf_have_key_gt_one) (enc_session_t *enc_session); 191 192#ifndef NDEBUG 193 /* Functions that are only relevant in maintest. We may want to get rid 194 * of them somehow and only use the public API to test. 195 */ 196 197 uint8_t 198 (*esf_have_key) (enc_session_t *); 199 200 void 201 (*esf_set_have_key) (enc_session_t *, uint8_t); 202 203 const unsigned char * 204 (*esf_get_enc_key_i) (enc_session_t *); 205 206 const unsigned char * 207 (*esf_get_dec_key_i) (enc_session_t *); 208 209 const unsigned char * 210 (*esf_get_enc_key_nonce_i) (enc_session_t *); 211 212 const unsigned char * 213 (*esf_get_dec_key_nonce_i) (enc_session_t *); 214 215 const unsigned char * 216 (*esf_get_enc_key_nonce_f) (enc_session_t *); 217 218 const unsigned char * 219 (*esf_get_dec_key_nonce_f) (enc_session_t *); 220#endif /* !defined(NDEBUG) */ 221 222 /* Create client session */ 223 enc_session_t * 224 (*esf_create_client) (struct lsquic_conn *, const char *domain, 225 lsquic_cid_t cid, 226 struct lsquic_engine_public *, 227 const unsigned char *, size_t); 228 229 /* -1 error, 0, OK, response in `buf' */ 230 int 231 (*esf_gen_chlo) (enc_session_t *, enum lsquic_version, 232 uint8_t *buf, size_t *len); 233 234 int 235 (*esf_handle_chlo_reply) (enc_session_t *, 236 const uint8_t *data, int len); 237 238 size_t 239 (*esf_mem_used)(enc_session_t *); 240 241 /* Session resumption serialization needs the knowledge of the QUIC 242 * version, that's why there is a separate method for thus. Plus, we 243 * want to be able to call it after the "handshake is done" callback 244 * is called. 245 */ 246 void (*esf_maybe_dispatch_sess_resume) (enc_session_t *, 247 void (*cb)(struct lsquic_conn *, const unsigned char *, size_t)); 248 249 void (*esf_reset_cid) (enc_session_t *, const lsquic_cid_t *); 250}; 251 252struct crypto_stream_if 253{ 254 ssize_t (*csi_write) (void *stream, const void *buf, size_t len); 255 int (*csi_flush) (void *stream); 256 ssize_t (*csi_readf) (void *stream, 257 size_t (*readf)(void *, const unsigned char *, size_t, int), void *ctx); 258 int (*csi_wantwrite) (void *stream, int is_want); 259 int (*csi_wantread) (void *stream, int is_want); 260 enum enc_level 261 (*csi_enc_level) (void *stream); 262}; 263 264struct enc_session_funcs_iquic 265{ 266 enc_session_t * 267 (*esfi_create_client) (const char *domain, struct lsquic_engine_public *, 268 struct lsquic_conn *, const struct lsquic_cid *, 269 const struct ver_neg *, void *(crypto_streams)[4], 270 const struct crypto_stream_if *, 271 const unsigned char *, size_t, 272 struct lsquic_alarmset *, unsigned, void*); 273 274 void 275 (*esfi_destroy) (enc_session_t *); 276 277 struct ssl_st * 278 (*esfi_get_ssl) (enc_session_t *); 279 280 struct transport_params * 281 (*esfi_get_peer_transport_params) (enc_session_t *); 282 283 int 284 (*esfi_reset_dcid) (enc_session_t *, const struct lsquic_cid *, 285 const struct lsquic_cid *); 286 287 void 288 (*esfi_set_iscid) (enc_session_t *, const struct lsquic_packet_in *); 289 290 int 291 (*esfi_init_server) (enc_session_t *); 292 293 void 294 (*esfi_set_streams) (enc_session_t *, void *(crypto_streams)[4], 295 const struct crypto_stream_if *); 296 297 enc_session_t * 298 (*esfi_create_server) (struct lsquic_engine_public *, struct lsquic_conn *, 299 const struct lsquic_cid *, 300 void *(crypto_streams)[4], 301 const struct crypto_stream_if *, 302 const struct lsquic_cid *odcid, 303 const struct lsquic_cid *iscid); 304 305 void 306 (*esfi_shake_stream)(enc_session_t *, struct lsquic_stream *, 307 const char *); 308 309 void 310 (*esfi_handshake_confirmed)(enc_session_t *); 311 312 int 313 (*esfi_in_init)(enc_session_t *); 314 315 int 316 (*esfi_data_in)(enc_session_t *, enum enc_level, 317 const unsigned char *, size_t); 318}; 319 320LSQUIC_EXTERN 321#ifdef NDEBUG 322const 323#endif 324struct enc_session_funcs_common lsquic_enc_session_common_gquic_1; 325 326LSQUIC_EXTERN 327#ifdef NDEBUG 328const 329#endif 330struct enc_session_funcs_common lsquic_enc_session_common_gquic_2; 331 332LSQUIC_EXTERN const struct enc_session_funcs_common lsquic_enc_session_common_ietf_v1; 333 334LSQUIC_EXTERN 335#ifdef NDEBUG 336const 337#endif 338struct enc_session_funcs_gquic lsquic_enc_session_gquic_gquic_1; 339 340LSQUIC_EXTERN const struct enc_session_funcs_iquic lsquic_enc_session_iquic_ietf_v1; 341 342#define select_esf_common_by_ver(ver) ( \ 343 ver == LSQVER_ID27 ? &lsquic_enc_session_common_ietf_v1 : \ 344 ver == LSQVER_ID29 ? &lsquic_enc_session_common_ietf_v1 : \ 345 ver == LSQVER_I001 ? &lsquic_enc_session_common_ietf_v1 : \ 346 ver == LSQVER_VERNEG ? &lsquic_enc_session_common_ietf_v1 : \ 347 ver == LSQVER_050 ? &lsquic_enc_session_common_gquic_2 : \ 348 &lsquic_enc_session_common_gquic_1 ) 349 350#define select_esf_gquic_by_ver(ver) ( \ 351 ver ? &lsquic_enc_session_gquic_gquic_1 : &lsquic_enc_session_gquic_gquic_1) 352 353#define select_esf_iquic_by_ver(ver) ( \ 354 ver ? &lsquic_enc_session_iquic_ietf_v1 : &lsquic_enc_session_iquic_ietf_v1) 355 356extern const char *const lsquic_enclev2str[]; 357 358LSQUIC_EXTERN const struct lsquic_stream_if lsquic_cry_sm_if; 359 360LSQUIC_EXTERN const struct lsquic_stream_if lsquic_mini_cry_sm_if; 361 362/* RFC 7301, Section 3.2 */ 363#define ALERT_NO_APPLICATION_PROTOCOL 120 364 365enum lsquic_version 366lsquic_sess_resume_version (const unsigned char *, size_t); 367 368/* This is seems to be true for all of the ciphers used by IETF QUIC. 369 * XXX: Perhaps add a check? 370 */ 371#define IQUIC_TAG_LEN 16 372 373/* Return number of bytes written to `buf' or -1 on error */ 374int 375lsquic_enc_sess_ietf_gen_quic_ctx ( 376 const struct lsquic_engine_settings *settings, 377 enum lsquic_version version, unsigned char *buf, size_t bufsz); 378 379#endif 380