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