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