lsquic_enc_sess.h revision 5392f7a3
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_ID22 ? &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