#ifndef OPENSSL_NO_ECH
#ifndef HEADER_ECH_LOCAL_H
#define HEADER_ECH_LOCAL_H
#include <openssl/ssl.h>
#include <openssl/ech.h>
#include <openssl/hpke.h>
#define OSSL_ECH_SUPERVERBOSE
#define OSSL_ECH_GREASE_UNKNOWN -1
#define OSSL_ECH_NOT_GREASE 0
#define OSSL_ECH_IS_GREASE 1
#define OSSL_ECH_type_unknown 0xffff
#define OSSL_ECH_config_id_unset -1
#define OSSL_ECH_OUTER_CH_TYPE 0
#define OSSL_ECH_INNER_CH_TYPE 1
#define OSSL_ECH_UNKNOWN_CH_TYPE -1
#define OSSL_ECH_CIPHER_LEN 4
#define OSSL_ECH_SIGNAL_LEN 8
#define OSSL_ECH_PBUF_SIZE 8 * 1024
#ifndef CLIENT_VERSION_LEN
#define CLIENT_VERSION_LEN 2
#endif
typedef struct ossl_echext_st {
uint16_t type;
uint16_t len;
unsigned char *val;
} OSSL_ECHEXT;
DEFINE_STACK_OF(OSSL_ECHEXT)
typedef struct ossl_echstore_entry_st {
uint16_t version;
char *public_name;
size_t pub_len;
unsigned char *pub;
unsigned int nsuites;
OSSL_HPKE_SUITE *suites;
uint8_t max_name_length;
uint8_t config_id;
STACK_OF(OSSL_ECHEXT) *exts;
time_t loadtime;
EVP_PKEY *keyshare;
int for_retry;
size_t encoded_len;
unsigned char *encoded;
} OSSL_ECHSTORE_ENTRY;
typedef struct ech_encch_st {
uint16_t kdf_id;
uint16_t aead_id;
uint8_t config_id;
size_t enc_len;
unsigned char *enc;
size_t payload_len;
unsigned char *payload;
} OSSL_ECH_ENCCH;
DEFINE_STACK_OF(OSSL_ECHSTORE_ENTRY)
struct ossl_echstore_st {
STACK_OF(OSSL_ECHSTORE_ENTRY) *entries;
OSSL_LIB_CTX *libctx;
char *propq;
};
typedef struct ossl_ech_ctx_st {
OSSL_ECHSTORE *es;
unsigned char *alpn_outer;
size_t alpn_outer_len;
SSL_ech_cb_func cb;
} OSSL_ECH_CTX;
typedef struct ossl_ech_conn_st {
OSSL_ECHSTORE *es;
int no_outer;
char *outer_hostname;
unsigned char *alpn_outer;
size_t alpn_outer_len;
SSL_ech_cb_func cb;
char *former_inner;
unsigned char *transbuf;
size_t transbuf_len;
unsigned char *innerch;
size_t innerch_len;
unsigned char *encoded_inner;
size_t encoded_inner_len;
size_t clearlen;
size_t cipherlen;
size_t cipher_offset;
uint16_t outer_only[OSSL_ECH_OUTERS_MAX];
size_t n_outer_only;
int ext_ind;
int ch_depth;
int attempted;
int done;
uint16_t attempted_type;
int attempted_cid;
int backend;
int tick_identity;
int success;
int retry_configs_ok;
int inner_ech_seen_ok;
int grease;
char *grease_suite;
unsigned char *sent;
size_t sent_len;
unsigned char *returned;
size_t returned_len;
unsigned char *pub;
size_t pub_len;
OSSL_HPKE_CTX *hpke_ctx;
int ch_offsets_done;
size_t sessid_off;
size_t exts_off;
size_t ech_off;
size_t sni_off;
int echtype;
int inner;
unsigned char *hrrsignal_p;
unsigned char hrrsignal[OSSL_ECH_SIGNAL_LEN];
EVP_PKEY *ks_pkey[OPENSSL_CLIENT_MAX_KEY_SHARES];
uint16_t ks_group_id[OPENSSL_CLIENT_MAX_KEY_SHARES];
size_t num_ks_pkey;
unsigned char client_random[SSL3_RANDOM_SIZE];
} OSSL_ECH_CONN;
#define OSSL_ECH_SAME_EXT_ERR 0
#define OSSL_ECH_SAME_EXT_DONE 1
#define OSSL_ECH_SAME_EXT_CONTINUE 2
#define ECH_SAME_EXT(s, context, pkt) \
if (context == SSL_EXT_CLIENT_HELLO && !s->server \
&& s->ext.ech.es != NULL && s->ext.ech.grease == 0) { \
int ech_iosame_rv = ossl_ech_same_ext(s, pkt); \
\
if (ech_iosame_rv == OSSL_ECH_SAME_EXT_ERR) \
return EXT_RETURN_FAIL; \
if (ech_iosame_rv == OSSL_ECH_SAME_EXT_DONE) \
return EXT_RETURN_SENT; \
\
}
OSSL_ECHSTORE *ossl_echstore_dup(const OSSL_ECHSTORE *old);
void ossl_echstore_entry_free(OSSL_ECHSTORE_ENTRY *ee);
void ossl_ech_ctx_clear(OSSL_ECH_CTX *ce);
int ossl_ech_conn_init(SSL_CONNECTION *s, SSL_CTX *ctx,
const SSL_METHOD *method);
void ossl_ech_conn_clear(OSSL_ECH_CONN *ec);
void ossl_echext_free(OSSL_ECHEXT *e);
OSSL_ECHEXT *ossl_echext_dup(const OSSL_ECHEXT *src);
#ifdef OSSL_ECH_SUPERVERBOSE
void ossl_ech_pbuf(const char *msg,
const unsigned char *buf, const size_t blen);
#endif
int ossl_ech_get_retry_configs(SSL_CONNECTION *s, unsigned char **rcfgs,
size_t *rcfgslen);
int ossl_ech_send_grease(SSL_CONNECTION *s, WPACKET *pkt);
int ossl_ech_pick_matching_cfg(SSL_CONNECTION *s, OSSL_ECHSTORE_ENTRY **ee,
OSSL_HPKE_SUITE *suite);
int ossl_ech_encode_inner(SSL_CONNECTION *s, unsigned char **encoded,
size_t *encoded_len);
int ossl_ech_find_confirm(SSL_CONNECTION *s, int hrr,
unsigned char acbuf[OSSL_ECH_SIGNAL_LEN]);
int ossl_ech_reset_hs_buffer(SSL_CONNECTION *s, const unsigned char *buf,
size_t blen);
int ossl_ech_aad_and_encrypt(SSL_CONNECTION *s, WPACKET *pkt);
int ossl_ech_swaperoo(SSL_CONNECTION *s);
int ossl_ech_calc_confirm(SSL_CONNECTION *s, int for_hrr,
unsigned char acbuf[OSSL_ECH_SIGNAL_LEN],
const size_t shlen);
int ossl_ech_same_ext(SSL_CONNECTION *s, WPACKET *pkt);
int ossl_ech_same_key_share(void);
int ossl_ech_2bcompressed(size_t ind);
int ossl_ech_copy_inner2outer(SSL_CONNECTION *s, uint16_t ext_type, int ind,
WPACKET *pkt);
int ossl_ech_get_ch_offsets(SSL_CONNECTION *s, PACKET *pkt, size_t *sessid,
size_t *exts, size_t *echoffset, uint16_t *echtype,
int *inner, size_t *snioffset);
int ossl_ech_early_decrypt(SSL_CONNECTION *s, PACKET *outerpkt, PACKET *newpkt);
void ossl_ech_status_print(BIO *out, SSL_CONNECTION *s, int selector);
int ossl_ech_intbuf_add(SSL_CONNECTION *s, const unsigned char *buf,
size_t blen, int hash_existing);
int ossl_ech_intbuf_fetch(SSL_CONNECTION *s, unsigned char **buf, size_t *blen);
size_t ossl_ech_calc_padding(SSL_CONNECTION *s, OSSL_ECHSTORE_ENTRY *ee,
size_t encoded_len);
int ossl_ech_stash_keyshares(SSL_CONNECTION *s);
int ossl_ech_unstash_keyshares(SSL_CONNECTION *s);
#endif
#endif