lsquic_enc_sess.h revision 03e6b668
1/* Copyright (c) 2017 - 2019 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; 18 19#define DNONC_LENGTH 32 20#define SRST_LENGTH 16 21 22/* From [draft-ietf-quic-tls-14]: 23 * 24 * Data is protected using a number of encryption levels: 25 * 26 * o Plaintext 27 * 28 * o Early Data (0-RTT) Keys 29 * 30 * o Handshake Keys 31 * 32 * o Application Data (1-RTT) Keys 33 */ 34 35/* This enum maps to the list above */ 36enum enc_level 37{ 38 ENC_LEV_CLEAR, 39 ENC_LEV_EARLY, 40 ENC_LEV_INIT, 41 ENC_LEV_FORW, 42 N_ENC_LEVS 43}; 44 45enum handshake_error /* TODO: rename this enum */ 46{ 47 DATA_NOT_ENOUGH = -2, 48 DATA_FORMAT_ERROR = -1, 49 HS_ERROR = -1, 50 DATA_NO_ERROR = 0, 51 HS_SHLO = 0, 52 HS_1RTT = 1, 53 HS_SREJ = 2, 54 HS_DELAYED = 3, 55 HS_PK_OFFLOAD = 4, 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 enum enc_packout 106 (*esf_encrypt_packet) (enc_session_t *, const struct lsquic_engine_public *, 107 struct lsquic_conn *, struct lsquic_packet_out *); 108 109 enum dec_packin 110 (*esf_decrypt_packet)(enc_session_t *, struct lsquic_engine_public *, 111 const struct lsquic_conn *, struct lsquic_packet_in *); 112 113 struct stack_st_X509 * 114 (*esf_get_server_cert_chain) (enc_session_t *); 115 116 int 117 (*esf_verify_reset_token) (enc_session_t *, const unsigned char *, size_t); 118 119 int 120 (*esf_did_zero_rtt_succeed) (enc_session_t *); 121 122 int 123 (*esf_is_zero_rtt_enabled) (enc_session_t *); 124 125 unsigned 126 esf_tag_len; 127}; 128 129struct enc_session_funcs_gquic 130{ 131#if LSQUIC_KEEP_ENC_SESS_HISTORY 132 /* Grab encryption session history */ 133 void (*esf_get_hist) (enc_session_t *, 134 char buf[ESHIST_STR_SIZE]); 135#endif 136 137 /* Destroy enc session */ 138 void (*esf_destroy)(enc_session_t *enc_session); 139 140 /* Return true if handshake has been completed */ 141 int (*esf_is_hsk_done)(enc_session_t *enc_session); 142 143 /* Get value of setting specified by `tag' */ 144 int (*esf_get_peer_setting) (enc_session_t *, uint32_t tag, 145 uint32_t *val); 146 147 /* Get value of peer option (that from COPT array) */ 148 int (*esf_get_peer_option) (enc_session_t *enc_session, 149 uint32_t tag); 150 151 /* Create server session */ 152 enc_session_t * 153 (*esf_create_server) (lsquic_cid_t cid, const struct lsquic_engine_public *); 154 155 /* out_len should have init value as the max length of out */ 156 enum handshake_error 157 (*esf_handle_chlo) (enc_session_t *enc_session, enum lsquic_version, 158 const uint8_t *in, int in_len, time_t t, 159 const struct sockaddr *ip_addr, const struct sockaddr *local, 160 uint8_t *out, size_t *out_len, 161 uint8_t nonce[DNONC_LENGTH], int *nonce_set); 162 163 void (*esf_hsk_destroy)(void *hsk_ctx); 164 165#ifndef NDEBUG 166 /* Need to expose this function for testing */ 167 int (*esf_determine_diversification_key) (enc_session_t *, 168 uint8_t *diversification_nonce, int is_client); 169#endif 170 171 const char * 172 (*esf_get_ua) (enc_session_t *); 173 174 int 175 (*esf_have_key_gt_one) (enc_session_t *enc_session); 176 177#ifndef NDEBUG 178 /* Functions that are only relevant in maintest. We may want to get rid 179 * of them somehow and only use the public API to test. 180 */ 181 182 uint8_t 183 (*esf_have_key) (enc_session_t *); 184 185 void 186 (*esf_set_have_key) (enc_session_t *, uint8_t); 187 188 const unsigned char * 189 (*esf_get_enc_key_i) (enc_session_t *); 190 191 const unsigned char * 192 (*esf_get_dec_key_i) (enc_session_t *); 193 194 const unsigned char * 195 (*esf_get_enc_key_nonce_i) (enc_session_t *); 196 197 const unsigned char * 198 (*esf_get_dec_key_nonce_i) (enc_session_t *); 199 200 const unsigned char * 201 (*esf_get_enc_key_nonce_f) (enc_session_t *); 202 203 const unsigned char * 204 (*esf_get_dec_key_nonce_f) (enc_session_t *); 205#endif /* !defined(NDEBUG) */ 206 207#if LSQUIC_ENABLE_HANDSHAKE_DISABLE 208 void 209 (*esf_set_handshake_completed) (enc_session_t *); 210#endif 211 212 /* Create client session */ 213 enc_session_t * 214 (*esf_create_client) (const char *domain, lsquic_cid_t cid, 215 const struct lsquic_engine_public *, 216 const unsigned char *, size_t); 217 218 /* -1 error, 0, OK, response in `buf' */ 219 int 220 (*esf_gen_chlo) (enc_session_t *, enum lsquic_version, 221 uint8_t *buf, size_t *len); 222 223 int 224 (*esf_handle_chlo_reply) (enc_session_t *, 225 const uint8_t *data, int len); 226 227 size_t 228 (*esf_mem_used)(enc_session_t *); 229 230 /* Zero-rtt serialization needs the knowledge of the QUIC version, that's 231 * why there is a separate method for thus. Plus, we want to be able to 232 * call it after the "handshake is done" callback is called. 233 */ 234 void (*esf_maybe_dispatch_zero_rtt) (enc_session_t *, 235 struct lsquic_conn *conn, 236 void (*cb)(struct lsquic_conn *, const unsigned char *, size_t)); 237 238 void (*esf_reset_cid) (enc_session_t *, const lsquic_cid_t *); 239}; 240 241enum iquic_handshake_status { 242 IHS_WANT_READ, 243 IHS_WANT_WRITE, 244 IHS_STOP, 245}; 246 247struct crypto_stream_if 248{ 249 ssize_t (*csi_write) (void *stream, const void *buf, size_t len); 250 int (*csi_flush) (void *stream); 251 ssize_t (*csi_readf) (void *stream, 252 size_t (*readf)(void *, const unsigned char *, size_t, int), void *ctx); 253 int (*csi_wantwrite) (void *stream, int is_want); 254 int (*csi_wantread) (void *stream, int is_want); 255 enum enc_level 256 (*csi_enc_level) (void *stream); 257}; 258 259struct enc_session_funcs_iquic 260{ 261 enc_session_t * 262 (*esfi_create_client) (const char *domain, struct lsquic_engine_public *, 263 struct lsquic_conn *, const struct lsquic_cid *, 264 const struct ver_neg *, void *(crypto_streams)[4], 265 const struct crypto_stream_if *, 266 const unsigned char *, size_t, 267 struct lsquic_alarmset *, unsigned); 268 269 void 270 (*esfi_destroy) (enc_session_t *); 271 272 struct ssl_st * 273 (*esfi_get_ssl) (enc_session_t *); 274 275 struct transport_params * 276 (*esfi_get_peer_transport_params) (enc_session_t *); 277 278 int 279 (*esfi_reset_dcid) (enc_session_t *, const struct lsquic_cid *, 280 const struct lsquic_cid *); 281 282 int 283 (*esfi_init_server) (enc_session_t *); 284 285 void 286 (*esfi_set_conn) (enc_session_t *, struct lsquic_conn *); 287 288 void 289 (*esfi_set_streams) (enc_session_t *, void *(crypto_streams)[4], 290 const struct crypto_stream_if *); 291 292 enc_session_t * 293 (*esfi_create_server) (struct lsquic_engine_public *, struct lsquic_conn *, 294 const struct lsquic_cid *, 295 void *(crypto_streams)[4], 296 const struct crypto_stream_if *, 297 const struct lsquic_cid *odcid); 298 299 void 300 (*esfi_shake_stream)(enc_session_t *, struct lsquic_stream *, 301 const char *); 302 303 void 304 (*esfi_1rtt_acked)(enc_session_t *); 305}; 306 307extern 308#ifdef NDEBUG 309const 310#endif 311struct enc_session_funcs_common lsquic_enc_session_common_gquic_1; 312extern const struct enc_session_funcs_common lsquic_enc_session_common_ietf_v1; 313 314extern 315#ifdef NDEBUG 316const 317#endif 318struct enc_session_funcs_gquic lsquic_enc_session_gquic_gquic_1; 319 320extern const struct enc_session_funcs_iquic lsquic_enc_session_iquic_ietf_v1; 321 322#define select_esf_common_by_ver(ver) ( \ 323 ver == LSQVER_ID23 ? &lsquic_enc_session_common_ietf_v1 : \ 324 ver == LSQVER_ID24 ? &lsquic_enc_session_common_ietf_v1 : \ 325 ver == LSQVER_VERNEG ? &lsquic_enc_session_common_ietf_v1 : \ 326 &lsquic_enc_session_common_gquic_1 ) 327 328#define select_esf_gquic_by_ver(ver) ( \ 329 ver ? &lsquic_enc_session_gquic_gquic_1 : &lsquic_enc_session_gquic_gquic_1) 330 331#define select_esf_iquic_by_ver(ver) ( \ 332 ver ? &lsquic_enc_session_iquic_ietf_v1 : &lsquic_enc_session_iquic_ietf_v1) 333 334extern const char *const lsquic_enclev2str[]; 335 336extern const struct lsquic_stream_if lsquic_cry_sm_if; 337 338extern const struct lsquic_stream_if lsquic_mini_cry_sm_if; 339 340/* RFC 7301, Section 3.2 */ 341#define ALERT_NO_APPLICATION_PROTOCOL 120 342 343enum lsquic_version 344lsquic_zero_rtt_version (const unsigned char *, size_t); 345 346/* This is seems to be true for all of the ciphers used by IETF QUIC. 347 * XXX: Perhaps add a check? 348 */ 349#define IQUIC_TAG_LEN 16 350 351#endif 352