lsquic_handshake.h revision 50aadb33
150aadb33SDmitri Tikhonov/* Copyright (c) 2017 LiteSpeed Technologies Inc. See LICENSE. */ 250aadb33SDmitri Tikhonov#ifndef LSQUIC_HANDSHAKE_H 350aadb33SDmitri Tikhonov#define LSQUIC_HANDSHAKE_H 450aadb33SDmitri Tikhonov 550aadb33SDmitri Tikhonov#include <stdint.h> 650aadb33SDmitri Tikhonov#include <openssl/base.h> 750aadb33SDmitri Tikhonov#include <openssl/aead.h> 850aadb33SDmitri Tikhonov 950aadb33SDmitri Tikhonov#include <time.h> 1050aadb33SDmitri Tikhonov#include "lsquic_str.h" 1150aadb33SDmitri Tikhonov 1250aadb33SDmitri Tikhonovstruct lsquic_engine_public; 1350aadb33SDmitri Tikhonovstruct sockaddr; 1450aadb33SDmitri Tikhonov 1550aadb33SDmitri Tikhonov#include "lsquic_qtags.h" 1650aadb33SDmitri Tikhonov 1750aadb33SDmitri Tikhonov#define STK_LENGTH 60 1850aadb33SDmitri Tikhonov#define SNO_LENGTH 56 1950aadb33SDmitri Tikhonov#define SCID_LENGTH 16 2050aadb33SDmitri Tikhonov#define DNONC_LENGTH 32 2150aadb33SDmitri Tikhonov#define aes128_key_len 16 2250aadb33SDmitri Tikhonov#define aes128_iv_len 4 2350aadb33SDmitri Tikhonov 2450aadb33SDmitri Tikhonov/* client side, certs and hashs 2550aadb33SDmitri Tikhonov */ 2650aadb33SDmitri Tikhonovtypedef struct cert_hash_item_st 2750aadb33SDmitri Tikhonov{ 2850aadb33SDmitri Tikhonov struct lsquic_str* domain; /*with port, such as "xyz.com:8088" as the key */ 2950aadb33SDmitri Tikhonov struct lsquic_str* crts; 3050aadb33SDmitri Tikhonov struct lsquic_str* hashs; 3150aadb33SDmitri Tikhonov int count; 3250aadb33SDmitri Tikhonov} cert_hash_item_t; 3350aadb33SDmitri Tikhonov 3450aadb33SDmitri Tikhonovenum handshake_error /* TODO: rename this enum */ 3550aadb33SDmitri Tikhonov{ 3650aadb33SDmitri Tikhonov DATA_NOT_ENOUGH = -2, 3750aadb33SDmitri Tikhonov DATA_FORMAT_ERROR = -1, 3850aadb33SDmitri Tikhonov HS_ERROR = -1, 3950aadb33SDmitri Tikhonov DATA_NO_ERROR = 0, 4050aadb33SDmitri Tikhonov HS_SHLO = 0, 4150aadb33SDmitri Tikhonov HS_1RTT = 1, 4250aadb33SDmitri Tikhonov HS_2RTT = 2, 4350aadb33SDmitri Tikhonov}; 4450aadb33SDmitri Tikhonov 4550aadb33SDmitri Tikhonovenum handshake_state 4650aadb33SDmitri Tikhonov{ 4750aadb33SDmitri Tikhonov HSK_CHLO_REJ = 0, 4850aadb33SDmitri Tikhonov HSK_SHLO, 4950aadb33SDmitri Tikhonov HSK_COMPLETED, 5050aadb33SDmitri Tikhonov N_HSK_STATES 5150aadb33SDmitri Tikhonov}; 5250aadb33SDmitri Tikhonov 5350aadb33SDmitri Tikhonovtypedef struct tag_value_st 5450aadb33SDmitri Tikhonov{ 5550aadb33SDmitri Tikhonov uint32_t tag; 5650aadb33SDmitri Tikhonov const char * value; 5750aadb33SDmitri Tikhonov int len; 5850aadb33SDmitri Tikhonov} tag_value_t; 5950aadb33SDmitri Tikhonov 6050aadb33SDmitri Tikhonovtypedef struct hs_ctx_st 6150aadb33SDmitri Tikhonov{ 6250aadb33SDmitri Tikhonov enum { 6350aadb33SDmitri Tikhonov HSET_TCID = (1 << 0), /* tcid is set */ 6450aadb33SDmitri Tikhonov HSET_SMHL = (1 << 1), /* smhl is set */ 6550aadb33SDmitri Tikhonov HSET_SCID = (1 << 2), 6650aadb33SDmitri Tikhonov } set; 6750aadb33SDmitri Tikhonov enum { 6850aadb33SDmitri Tikhonov HOPT_NSTP = (1 << 0), /* NSTP option present in COPT */ 6950aadb33SDmitri Tikhonov HOPT_SREJ = (1 << 1), /* SREJ option present in COPT */ 7050aadb33SDmitri Tikhonov } opts; 7150aadb33SDmitri Tikhonov uint32_t pdmd; 7250aadb33SDmitri Tikhonov uint32_t aead; 7350aadb33SDmitri Tikhonov uint32_t kexs; 7450aadb33SDmitri Tikhonov 7550aadb33SDmitri Tikhonov uint32_t mids; 7650aadb33SDmitri Tikhonov uint32_t scls; 7750aadb33SDmitri Tikhonov uint32_t cfcw; 7850aadb33SDmitri Tikhonov uint32_t sfcw; 7950aadb33SDmitri Tikhonov uint32_t srbf; 8050aadb33SDmitri Tikhonov uint32_t icsl; 8150aadb33SDmitri Tikhonov 8250aadb33SDmitri Tikhonov uint32_t irtt; 8350aadb33SDmitri Tikhonov uint64_t rcid; 8450aadb33SDmitri Tikhonov uint32_t tcid; 8550aadb33SDmitri Tikhonov uint32_t smhl; 8650aadb33SDmitri Tikhonov uint64_t ctim; /* any usage? */ 8750aadb33SDmitri Tikhonov uint64_t sttl; 8850aadb33SDmitri Tikhonov unsigned char scid[SCID_LENGTH]; 8950aadb33SDmitri Tikhonov //unsigned char chlo_hash[32]; //SHA256 HASH of CHLO 9050aadb33SDmitri Tikhonov unsigned char nonc[DNONC_LENGTH]; /* 4 tm, 8 orbit ---> REJ, 20 rand */ 9150aadb33SDmitri Tikhonov unsigned char pubs[32]; 9250aadb33SDmitri Tikhonov 9350aadb33SDmitri Tikhonov uint32_t rrej; 9450aadb33SDmitri Tikhonov struct lsquic_str ccs; 9550aadb33SDmitri Tikhonov struct lsquic_str sni; /* 0 rtt */ 9650aadb33SDmitri Tikhonov struct lsquic_str ccrt; 9750aadb33SDmitri Tikhonov struct lsquic_str stk; 9850aadb33SDmitri Tikhonov struct lsquic_str sno; 9950aadb33SDmitri Tikhonov struct lsquic_str prof; 10050aadb33SDmitri Tikhonov 10150aadb33SDmitri Tikhonov struct lsquic_str csct; 10250aadb33SDmitri Tikhonov struct lsquic_str crt; /* compressed certs buffer */ 10350aadb33SDmitri Tikhonov} hs_ctx_t; 10450aadb33SDmitri Tikhonov 10550aadb33SDmitri Tikhonov/* client side need to store 0rtt info per STK */ 10650aadb33SDmitri Tikhonovtypedef struct lsquic_session_cache_info_st 10750aadb33SDmitri Tikhonov{ 10850aadb33SDmitri Tikhonov unsigned char sscid[SCID_LENGTH]; 10950aadb33SDmitri Tikhonov unsigned char spubs[32]; /* server pub key for next time 0rtt */ 11050aadb33SDmitri Tikhonov uint32_t ver; /* one VERSION */ 11150aadb33SDmitri Tikhonov uint32_t aead; 11250aadb33SDmitri Tikhonov uint32_t kexs; 11350aadb33SDmitri Tikhonov uint32_t pdmd; 11450aadb33SDmitri Tikhonov uint64_t orbt; 11550aadb33SDmitri Tikhonov uint64_t expy; 11650aadb33SDmitri Tikhonov int scfg_flag; /* 0, no-init, 1, no parse, 2, parsed */ 11750aadb33SDmitri Tikhonov struct lsquic_str sstk; 11850aadb33SDmitri Tikhonov struct lsquic_str scfg; 11950aadb33SDmitri Tikhonov struct lsquic_str sni_key; /* This is only used as key */ 12050aadb33SDmitri Tikhonov 12150aadb33SDmitri Tikhonov} lsquic_session_cache_info_t; 12250aadb33SDmitri Tikhonov 12350aadb33SDmitri Tikhonov#ifndef LSQUIC_KEEP_ENC_SESS_HISTORY 12450aadb33SDmitri Tikhonov# ifndef NDEBUG 12550aadb33SDmitri Tikhonov# define LSQUIC_KEEP_ENC_SESS_HISTORY 1 12650aadb33SDmitri Tikhonov# else 12750aadb33SDmitri Tikhonov# define LSQUIC_KEEP_ENC_SESS_HISTORY 0 12850aadb33SDmitri Tikhonov# endif 12950aadb33SDmitri Tikhonov#endif 13050aadb33SDmitri Tikhonov 13150aadb33SDmitri Tikhonov#if LSQUIC_KEEP_ENC_SESS_HISTORY 13250aadb33SDmitri Tikhonov 13350aadb33SDmitri Tikhonov#define ESHIST_BITS 7 13450aadb33SDmitri Tikhonov#define ESHIST_MASK ((1 << ESHIST_BITS) - 1) 13550aadb33SDmitri Tikhonov#define ESHIST_STR_SIZE ((1 << ESHIST_BITS) + 1) 13650aadb33SDmitri Tikhonovtypedef unsigned char eshist_idx_t; 13750aadb33SDmitri Tikhonov 13850aadb33SDmitri Tikhonovenum enc_sess_history_event 13950aadb33SDmitri Tikhonov{ 14050aadb33SDmitri Tikhonov ESHE_EMPTY = '\0', 14150aadb33SDmitri Tikhonov ESHE_SET_SNI = 'I', 14250aadb33SDmitri Tikhonov ESHE_SET_SNO = 'O', 14350aadb33SDmitri Tikhonov ESHE_SET_STK = 'K', 14450aadb33SDmitri Tikhonov ESHE_SET_SCID = 'D', 14550aadb33SDmitri Tikhonov ESHE_SET_PROF = 'P', 14650aadb33SDmitri Tikhonov}; 14750aadb33SDmitri Tikhonov 14850aadb33SDmitri Tikhonov#endif 14950aadb33SDmitri Tikhonov 15050aadb33SDmitri Tikhonovtypedef struct lsquic_enc_session 15150aadb33SDmitri Tikhonov{ 15250aadb33SDmitri Tikhonov enum handshake_state hsk_state; 15350aadb33SDmitri Tikhonov 15450aadb33SDmitri Tikhonov uint8_t have_key; /* 0, no 1, I, 2, D, 3, F */ 15550aadb33SDmitri Tikhonov uint8_t peer_have_final_key; 15650aadb33SDmitri Tikhonov uint8_t server_start_use_final_key; 15750aadb33SDmitri Tikhonov 15850aadb33SDmitri Tikhonov lsquic_cid_t cid; 15950aadb33SDmitri Tikhonov unsigned char priv_key[32]; 16050aadb33SDmitri Tikhonov EVP_AEAD_CTX *enc_ctx_i; 16150aadb33SDmitri Tikhonov EVP_AEAD_CTX *dec_ctx_i; 16250aadb33SDmitri Tikhonov 16350aadb33SDmitri Tikhonov /* Have to save the initial key for diversification need */ 16450aadb33SDmitri Tikhonov unsigned char enc_key_i[aes128_key_len]; 16550aadb33SDmitri Tikhonov unsigned char dec_key_i[aes128_key_len]; 16650aadb33SDmitri Tikhonov unsigned char enc_key_nonce_i[aes128_iv_len]; 16750aadb33SDmitri Tikhonov unsigned char dec_key_nonce_i[aes128_iv_len]; 16850aadb33SDmitri Tikhonov 16950aadb33SDmitri Tikhonov EVP_AEAD_CTX *enc_ctx_f; 17050aadb33SDmitri Tikhonov EVP_AEAD_CTX *dec_ctx_f; 17150aadb33SDmitri Tikhonov unsigned char enc_key_nonce_f[aes128_iv_len]; 17250aadb33SDmitri Tikhonov unsigned char dec_key_nonce_f[aes128_iv_len]; 17350aadb33SDmitri Tikhonov 17450aadb33SDmitri Tikhonov hs_ctx_t hs_ctx; 17550aadb33SDmitri Tikhonov lsquic_session_cache_info_t *info; 17650aadb33SDmitri Tikhonov SSL_CTX * ssl_ctx; 17750aadb33SDmitri Tikhonov const struct lsquic_engine_public *enpub; 17850aadb33SDmitri Tikhonov struct lsquic_str * cert_ptr; /* pointer to the leaf cert of the server, not real copy */ 17950aadb33SDmitri Tikhonov struct lsquic_str chlo; /* real copy of CHLO message */ 18050aadb33SDmitri Tikhonov struct lsquic_str sstk; 18150aadb33SDmitri Tikhonov struct lsquic_str ssno; 18250aadb33SDmitri Tikhonov 18350aadb33SDmitri Tikhonov#if LSQUIC_KEEP_ENC_SESS_HISTORY 18450aadb33SDmitri Tikhonov eshist_idx_t es_hist_idx; 18550aadb33SDmitri Tikhonov unsigned char es_hist_buf[1 << ESHIST_BITS]; 18650aadb33SDmitri Tikhonov#endif 18750aadb33SDmitri Tikhonov} lsquic_enc_session_t; 18850aadb33SDmitri Tikhonov 18950aadb33SDmitri Tikhonov#if LSQUIC_KEEP_ENC_SESS_HISTORY 19050aadb33SDmitri Tikhonovvoid 19150aadb33SDmitri Tikhonovlsquic_get_enc_hist (const lsquic_enc_session_t *, char buf[ESHIST_STR_SIZE]); 19250aadb33SDmitri Tikhonov#endif 19350aadb33SDmitri Tikhonov 19450aadb33SDmitri Tikhonovint handshake_init(int flags); 19550aadb33SDmitri Tikhonovvoid handshake_cleanup(); 19650aadb33SDmitri Tikhonov 19750aadb33SDmitri Tikhonovlsquic_enc_session_t * 19850aadb33SDmitri Tikhonovnew_enc_session_c(const char *domain, lsquic_cid_t cid, 19950aadb33SDmitri Tikhonov const struct lsquic_engine_public *); 20050aadb33SDmitri Tikhonov 20150aadb33SDmitri Tikhonovvoid free_enc_session(lsquic_enc_session_t *enc_session); 20250aadb33SDmitri Tikhonovvoid free_info(lsquic_session_cache_info_t *info); 20350aadb33SDmitri Tikhonov 20450aadb33SDmitri Tikhonovlsquic_cid_t generate_cid(void); 20550aadb33SDmitri Tikhonov 20650aadb33SDmitri Tikhonov/* save to hash table */ 20750aadb33SDmitri Tikhonovlsquic_session_cache_info_t *retrieve_session_info_entry(const char *key); 20850aadb33SDmitri Tikhonovvoid remove_expire_session_info_entry(); 20950aadb33SDmitri Tikhonovvoid remove_session_info_entry(struct lsquic_str *key); 21050aadb33SDmitri Tikhonov 21150aadb33SDmitri Tikhonovcert_hash_item_t *make_cert_hash_item(struct lsquic_str *domain, struct lsquic_str **certs, int count); 21250aadb33SDmitri Tikhonovvoid c_free_cert_hash_item(cert_hash_item_t *item); 21350aadb33SDmitri Tikhonovcert_hash_item_t* c_find_certs(struct lsquic_str *domain); 21450aadb33SDmitri Tikhonovint c_insert_certs(cert_hash_item_t *item); 21550aadb33SDmitri Tikhonov 21650aadb33SDmitri Tikhonov/* -1 error, 0, OK, response in `buf' */ 21750aadb33SDmitri Tikhonovint gen_chlo(lsquic_enc_session_t *enc_session, enum lsquic_version, 21850aadb33SDmitri Tikhonov uint8_t *buf, size_t *len); 21950aadb33SDmitri Tikhonovint handle_chlo_reply(lsquic_enc_session_t *enc_session, const uint8_t *data, 22050aadb33SDmitri Tikhonov int len); 22150aadb33SDmitri Tikhonov 22250aadb33SDmitri Tikhonovint is_hs_done(lsquic_enc_session_t *enc_session); 22350aadb33SDmitri Tikhonov 22450aadb33SDmitri Tikhonov/** 22550aadb33SDmitri Tikhonov * The belows are global functions 22650aadb33SDmitri Tikhonov */ 22750aadb33SDmitri Tikhonov 22850aadb33SDmitri Tikhonovint lsquic_enc(lsquic_enc_session_t *enc_session, enum lsquic_version, 22950aadb33SDmitri Tikhonov uint8_t path_id, uint64_t pack_num, 23050aadb33SDmitri Tikhonov const unsigned char *header, size_t header_len, 23150aadb33SDmitri Tikhonov const unsigned char *data, size_t data_len, 23250aadb33SDmitri Tikhonov unsigned char *buf_out, size_t max_out_len, size_t *out_len, 23350aadb33SDmitri Tikhonov int is_hello); 23450aadb33SDmitri Tikhonov 23550aadb33SDmitri Tikhonovint lsquic_dec(lsquic_enc_session_t *enc_session, enum lsquic_version, 23650aadb33SDmitri Tikhonov uint8_t path_id, uint64_t pack_num, 23750aadb33SDmitri Tikhonov unsigned char *buf, size_t *header_len, size_t data_len, 23850aadb33SDmitri Tikhonov unsigned char *diversification_nonce, 23950aadb33SDmitri Tikhonov unsigned char *buf_out, size_t max_out_len, size_t *out_len); 24050aadb33SDmitri Tikhonov 24150aadb33SDmitri Tikhonovint 24250aadb33SDmitri Tikhonovget_peer_setting (const lsquic_enc_session_t *, uint32_t tag, uint32_t *val); 24350aadb33SDmitri Tikhonov 24450aadb33SDmitri Tikhonovint 24550aadb33SDmitri Tikhonovget_peer_option (const lsquic_enc_session_t *enc_session, uint32_t tag); 24650aadb33SDmitri Tikhonov 24750aadb33SDmitri Tikhonov#ifdef NDEBUG 24850aadb33SDmitri Tikhonov#define lsquic_enc_session_have_key_gt_one(e) ((e) && (e)->have_key > 1) 24950aadb33SDmitri Tikhonov#else 25050aadb33SDmitri Tikhonovint 25150aadb33SDmitri Tikhonovlsquic_enc_session_have_key_gt_one (const lsquic_enc_session_t *enc_session); 25250aadb33SDmitri Tikhonov#endif 25350aadb33SDmitri Tikhonov 25450aadb33SDmitri Tikhonov#endif 255