mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
Update BoringSSL to later version, need this for ID-28
In ID-28, using TLS middlebox compatibility mode is forbidden and we need a later version of BoringSSL for it to do the right thing. This also means we had to update our code, because BoringSSL's QUIC API has changed.
This commit is contained in:
parent
6dd81c92df
commit
2c252f915b
5 changed files with 125 additions and 98 deletions
|
@ -8,7 +8,7 @@ task:
|
||||||
- cd boringssl
|
- cd boringssl
|
||||||
# This is so that both GQUIC and IETF branches build. Just picking
|
# This is so that both GQUIC and IETF branches build. Just picking
|
||||||
# a known good revision:
|
# a known good revision:
|
||||||
- git checkout 49de1fc2910524c888866c7e2b0db1ba8af2a530
|
- git checkout 251b5169fd44345f455438312ec4e18ae07fd58c
|
||||||
- cmake .
|
- cmake .
|
||||||
- make
|
- make
|
||||||
- cd -
|
- cd -
|
||||||
|
|
|
@ -31,7 +31,7 @@ before_script:
|
||||||
- cd boringssl
|
- cd boringssl
|
||||||
# This is so that both GQUIC and IETF branches build. Just picking
|
# This is so that both GQUIC and IETF branches build. Just picking
|
||||||
# a known good revision:
|
# a known good revision:
|
||||||
- git checkout 49de1fc2910524c888866c7e2b0db1ba8af2a530
|
- git checkout 251b5169fd44345f455438312ec4e18ae07fd58c
|
||||||
- cmake .
|
- cmake .
|
||||||
- make
|
- make
|
||||||
- cd -
|
- cd -
|
||||||
|
|
|
@ -17,7 +17,7 @@ COPY ./ /src/lsquic/
|
||||||
|
|
||||||
RUN git clone https://boringssl.googlesource.com/boringssl && \
|
RUN git clone https://boringssl.googlesource.com/boringssl && \
|
||||||
cd boringssl && \
|
cd boringssl && \
|
||||||
git checkout 49de1fc2910524c888866c7e2b0db1ba8af2a530 && \
|
git checkout 251b5169fd44345f455438312ec4e18ae07fd58c && \
|
||||||
cmake . && \
|
cmake . && \
|
||||||
make
|
make
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ You may need to install pre-requisites like zlib and libevent.
|
||||||
2. Use specific BoringSSL version
|
2. Use specific BoringSSL version
|
||||||
|
|
||||||
```
|
```
|
||||||
git checkout 49de1fc2910524c888866c7e2b0db1ba8af2a530
|
git checkout 251b5169fd44345f455438312ec4e18ae07fd58c
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Compile the library
|
3. Compile the library
|
||||||
|
|
|
@ -106,7 +106,7 @@ no_sess_ticket (enum alarm_id alarm_id, void *ctx,
|
||||||
|
|
||||||
|
|
||||||
typedef void (*gen_hp_mask_f)(struct enc_sess_iquic *,
|
typedef void (*gen_hp_mask_f)(struct enc_sess_iquic *,
|
||||||
const struct header_prot *, unsigned cliser,
|
const struct header_prot *, unsigned rw,
|
||||||
const unsigned char *sample, unsigned char mask[16]);
|
const unsigned char *sample, unsigned char mask[16]);
|
||||||
|
|
||||||
|
|
||||||
|
@ -238,8 +238,6 @@ struct enc_sess_iquic
|
||||||
ESI_RECV_QL_BITS = 1 << 12,
|
ESI_RECV_QL_BITS = 1 << 12,
|
||||||
ESI_SEND_QL_BITS = 1 << 13,
|
ESI_SEND_QL_BITS = 1 << 13,
|
||||||
} esi_flags;
|
} esi_flags;
|
||||||
enum evp_aead_direction_t
|
|
||||||
esi_dir[2]; /* client, server */
|
|
||||||
enum enc_level esi_last_w;
|
enum enc_level esi_last_w;
|
||||||
unsigned esi_trasec_sz;
|
unsigned esi_trasec_sz;
|
||||||
char *esi_hostname;
|
char *esi_hostname;
|
||||||
|
@ -273,14 +271,14 @@ struct enc_sess_iquic
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gen_hp_mask_aes (struct enc_sess_iquic *enc_sess,
|
gen_hp_mask_aes (struct enc_sess_iquic *enc_sess,
|
||||||
const struct header_prot *hp, unsigned cliser,
|
const struct header_prot *hp, unsigned rw,
|
||||||
const unsigned char *sample, unsigned char mask[EVP_MAX_BLOCK_LENGTH])
|
const unsigned char *sample, unsigned char mask[EVP_MAX_BLOCK_LENGTH])
|
||||||
{
|
{
|
||||||
EVP_CIPHER_CTX hp_ctx;
|
EVP_CIPHER_CTX hp_ctx;
|
||||||
int out_len;
|
int out_len;
|
||||||
|
|
||||||
EVP_CIPHER_CTX_init(&hp_ctx);
|
EVP_CIPHER_CTX_init(&hp_ctx);
|
||||||
if (EVP_EncryptInit_ex(&hp_ctx, hp->hp_cipher, NULL, hp->hp_buf[cliser], 0)
|
if (EVP_EncryptInit_ex(&hp_ctx, hp->hp_cipher, NULL, hp->hp_buf[rw], 0)
|
||||||
&& EVP_EncryptUpdate(&hp_ctx, mask, &out_len, sample, 16))
|
&& EVP_EncryptUpdate(&hp_ctx, mask, &out_len, sample, 16))
|
||||||
{
|
{
|
||||||
assert(out_len >= 5);
|
assert(out_len >= 5);
|
||||||
|
@ -299,7 +297,7 @@ gen_hp_mask_aes (struct enc_sess_iquic *enc_sess,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gen_hp_mask_chacha20 (struct enc_sess_iquic *enc_sess,
|
gen_hp_mask_chacha20 (struct enc_sess_iquic *enc_sess,
|
||||||
const struct header_prot *hp, unsigned cliser,
|
const struct header_prot *hp, unsigned rw,
|
||||||
const unsigned char *sample, unsigned char mask[EVP_MAX_BLOCK_LENGTH])
|
const unsigned char *sample, unsigned char mask[EVP_MAX_BLOCK_LENGTH])
|
||||||
{
|
{
|
||||||
const uint8_t *nonce;
|
const uint8_t *nonce;
|
||||||
|
@ -312,19 +310,19 @@ gen_hp_mask_chacha20 (struct enc_sess_iquic *enc_sess,
|
||||||
#endif
|
#endif
|
||||||
nonce = sample + sizeof(counter);
|
nonce = sample + sizeof(counter);
|
||||||
CRYPTO_chacha_20(mask, (unsigned char [5]) { 0, 0, 0, 0, 0, }, 5,
|
CRYPTO_chacha_20(mask, (unsigned char [5]) { 0, 0, 0, 0, 0, }, 5,
|
||||||
hp->hp_buf[cliser], nonce, counter);
|
hp->hp_buf[rw], nonce, counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
apply_hp (struct enc_sess_iquic *enc_sess,
|
apply_hp (struct enc_sess_iquic *enc_sess,
|
||||||
const struct header_prot *hp, unsigned cliser,
|
const struct header_prot *hp,
|
||||||
unsigned char *dst, unsigned packno_off, unsigned packno_len)
|
unsigned char *dst, unsigned packno_off, unsigned packno_len)
|
||||||
{
|
{
|
||||||
unsigned char mask[EVP_MAX_BLOCK_LENGTH];
|
unsigned char mask[EVP_MAX_BLOCK_LENGTH];
|
||||||
char mask_str[5 * 2 + 1];
|
char mask_str[5 * 2 + 1];
|
||||||
|
|
||||||
hp->hp_gen_mask(enc_sess, hp, cliser, dst + packno_off + 4, mask);
|
hp->hp_gen_mask(enc_sess, hp, 1, dst + packno_off + 4, mask);
|
||||||
LSQ_DEBUG("apply header protection using mask %s",
|
LSQ_DEBUG("apply header protection using mask %s",
|
||||||
HEXSTR(mask, 5, mask_str));
|
HEXSTR(mask, 5, mask_str));
|
||||||
if (enc_sess->esi_flags & ESI_SEND_QL_BITS)
|
if (enc_sess->esi_flags & ESI_SEND_QL_BITS)
|
||||||
|
@ -375,7 +373,7 @@ decode_packno (lsquic_packno_t max_packno, lsquic_packno_t packno,
|
||||||
|
|
||||||
static lsquic_packno_t
|
static lsquic_packno_t
|
||||||
strip_hp (struct enc_sess_iquic *enc_sess,
|
strip_hp (struct enc_sess_iquic *enc_sess,
|
||||||
const struct header_prot *hp, unsigned cliser,
|
const struct header_prot *hp,
|
||||||
const unsigned char *iv, unsigned char *dst, unsigned packno_off,
|
const unsigned char *iv, unsigned char *dst, unsigned packno_off,
|
||||||
unsigned *packno_len)
|
unsigned *packno_len)
|
||||||
{
|
{
|
||||||
|
@ -385,7 +383,7 @@ strip_hp (struct enc_sess_iquic *enc_sess,
|
||||||
unsigned char mask[EVP_MAX_BLOCK_LENGTH];
|
unsigned char mask[EVP_MAX_BLOCK_LENGTH];
|
||||||
char mask_str[5 * 2 + 1];
|
char mask_str[5 * 2 + 1];
|
||||||
|
|
||||||
hp->hp_gen_mask(enc_sess, hp, cliser, iv, mask);
|
hp->hp_gen_mask(enc_sess, hp, 0, iv, mask);
|
||||||
LSQ_DEBUG("strip header protection using mask %s",
|
LSQ_DEBUG("strip header protection using mask %s",
|
||||||
HEXSTR(mask, 5, mask_str));
|
HEXSTR(mask, 5, mask_str));
|
||||||
if (enc_sess->esi_flags & ESI_RECV_QL_BITS)
|
if (enc_sess->esi_flags & ESI_RECV_QL_BITS)
|
||||||
|
@ -723,9 +721,6 @@ iquic_esfi_create_client (const char *hostname,
|
||||||
enc_sess->esi_conn = lconn;
|
enc_sess->esi_conn = lconn;
|
||||||
enc_sess->esi_ver_neg = ver_neg;
|
enc_sess->esi_ver_neg = ver_neg;
|
||||||
|
|
||||||
enc_sess->esi_dir[0] = evp_aead_seal;
|
|
||||||
enc_sess->esi_dir[1] = evp_aead_open;
|
|
||||||
|
|
||||||
LSQ_DEBUGC("created client, DCID: %"CID_FMT, CID_BITS(dcid));
|
LSQ_DEBUGC("created client, DCID: %"CID_FMT, CID_BITS(dcid));
|
||||||
{
|
{
|
||||||
const char *log;
|
const char *log;
|
||||||
|
@ -811,9 +806,6 @@ iquic_esfi_create_server (struct lsquic_engine_public *enpub,
|
||||||
enc_sess->esi_enpub = enpub;
|
enc_sess->esi_enpub = enpub;
|
||||||
enc_sess->esi_conn = lconn;
|
enc_sess->esi_conn = lconn;
|
||||||
|
|
||||||
enc_sess->esi_dir[0] = evp_aead_open;
|
|
||||||
enc_sess->esi_dir[1] = evp_aead_seal;
|
|
||||||
|
|
||||||
if (odcid)
|
if (odcid)
|
||||||
{
|
{
|
||||||
enc_sess->esi_odcid = *odcid;
|
enc_sess->esi_odcid = *odcid;
|
||||||
|
@ -846,23 +838,31 @@ iquic_esfi_create_server (struct lsquic_engine_public *enpub,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char *const rw2str[] = { "read", "write", };
|
||||||
|
|
||||||
|
typedef char evp_aead_enum_has_expected_values[
|
||||||
|
(int) evp_aead_open == 0 && (int) evp_aead_seal == 1 ? 1 : -1];
|
||||||
|
#define rw2dir(rw_) ((enum evp_aead_direction_t) (rw_))
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
log_crypto_ctx (const struct enc_sess_iquic *enc_sess,
|
||||||
|
const struct crypto_ctx *ctx, const char *name, int rw)
|
||||||
|
{
|
||||||
|
char hexbuf[EVP_MAX_MD_SIZE * 2 + 1];
|
||||||
|
LSQ_DEBUG("%s %s key: %s", name, rw2str[rw],
|
||||||
|
HEXSTR(ctx->yk_key_buf, ctx->yk_key_sz, hexbuf));
|
||||||
|
LSQ_DEBUG("%s %s iv: %s", name, rw2str[rw],
|
||||||
|
HEXSTR(ctx->yk_iv_buf, ctx->yk_iv_sz, hexbuf));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
log_crypto_pair (const struct enc_sess_iquic *enc_sess,
|
log_crypto_pair (const struct enc_sess_iquic *enc_sess,
|
||||||
const struct crypto_ctx_pair *pair, const char *name)
|
const struct crypto_ctx_pair *pair, const char *name)
|
||||||
{
|
{
|
||||||
char hexbuf[EVP_MAX_MD_SIZE * 2 + 1];
|
log_crypto_ctx(enc_sess, &pair->ykp_ctx[0], name, 0);
|
||||||
LSQ_DEBUG("client %s key: %s", name,
|
log_crypto_ctx(enc_sess, &pair->ykp_ctx[1], name, 1);
|
||||||
HEXSTR(pair->ykp_ctx[0].yk_key_buf, pair->ykp_ctx[0].yk_key_sz,
|
|
||||||
hexbuf));
|
|
||||||
LSQ_DEBUG("client %s iv: %s", name,
|
|
||||||
HEXSTR(pair->ykp_ctx[0].yk_iv_buf, pair->ykp_ctx[0].yk_iv_sz,
|
|
||||||
hexbuf));
|
|
||||||
LSQ_DEBUG("server %s key: %s", name,
|
|
||||||
HEXSTR(pair->ykp_ctx[1].yk_key_buf, pair->ykp_ctx[1].yk_key_sz,
|
|
||||||
hexbuf));
|
|
||||||
LSQ_DEBUG("server %s iv: %s", name,
|
|
||||||
HEXSTR(pair->ykp_ctx[1].yk_iv_buf, pair->ykp_ctx[1].yk_iv_sz,
|
|
||||||
hexbuf));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -871,9 +871,9 @@ log_hp (const struct enc_sess_iquic *enc_sess,
|
||||||
const struct header_prot *hp, const char *name)
|
const struct header_prot *hp, const char *name)
|
||||||
{
|
{
|
||||||
char hexbuf[EVP_MAX_MD_SIZE * 2 + 1];
|
char hexbuf[EVP_MAX_MD_SIZE * 2 + 1];
|
||||||
LSQ_DEBUG("client %s hp: %s", name,
|
LSQ_DEBUG("read %s hp: %s", name,
|
||||||
HEXSTR(hp->hp_buf[0], hp->hp_sz, hexbuf));
|
HEXSTR(hp->hp_buf[0], hp->hp_sz, hexbuf));
|
||||||
LSQ_DEBUG("server %s hp: %s", name,
|
LSQ_DEBUG("write %s hp: %s", name,
|
||||||
HEXSTR(hp->hp_buf[1], hp->hp_sz, hexbuf));
|
HEXSTR(hp->hp_buf[1], hp->hp_sz, hexbuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -887,6 +887,7 @@ setup_handshake_keys (struct enc_sess_iquic *enc_sess, const lsquic_cid_t *cid)
|
||||||
struct crypto_ctx_pair *pair;
|
struct crypto_ctx_pair *pair;
|
||||||
struct header_prot *hp;
|
struct header_prot *hp;
|
||||||
size_t hsk_secret_sz;
|
size_t hsk_secret_sz;
|
||||||
|
unsigned cliser;
|
||||||
unsigned char hsk_secret[EVP_MAX_MD_SIZE];
|
unsigned char hsk_secret[EVP_MAX_MD_SIZE];
|
||||||
unsigned char secret[2][SHA256_DIGEST_LENGTH]; /* client, server */
|
unsigned char secret[2][SHA256_DIGEST_LENGTH]; /* client, server */
|
||||||
char hexbuf[EVP_MAX_MD_SIZE * 2 + 1];
|
char hexbuf[EVP_MAX_MD_SIZE * 2 + 1];
|
||||||
|
@ -919,17 +920,22 @@ setup_handshake_keys (struct enc_sess_iquic *enc_sess, const lsquic_cid_t *cid)
|
||||||
|
|
||||||
lsquic_qhkdf_expand(md, hsk_secret, hsk_secret_sz, CLIENT_LABEL,
|
lsquic_qhkdf_expand(md, hsk_secret, hsk_secret_sz, CLIENT_LABEL,
|
||||||
CLIENT_LABEL_SZ, secret[0], sizeof(secret[0]));
|
CLIENT_LABEL_SZ, secret[0], sizeof(secret[0]));
|
||||||
LSQ_DEBUG("client handshake secret: %s",
|
|
||||||
HEXSTR(secret[0], sizeof(secret[0]), hexbuf));
|
|
||||||
if (0 != init_crypto_ctx(&pair->ykp_ctx[0], md, aead, secret[0],
|
|
||||||
sizeof(secret[0]), enc_sess->esi_dir[0]))
|
|
||||||
goto err;
|
|
||||||
lsquic_qhkdf_expand(md, hsk_secret, hsk_secret_sz, SERVER_LABEL,
|
lsquic_qhkdf_expand(md, hsk_secret, hsk_secret_sz, SERVER_LABEL,
|
||||||
SERVER_LABEL_SZ, secret[1], sizeof(secret[1]));
|
SERVER_LABEL_SZ, secret[1], sizeof(secret[1]));
|
||||||
|
if (enc_sess->esi_flags & ESI_LOG_SECRETS)
|
||||||
|
{
|
||||||
|
LSQ_DEBUG("client handshake secret: %s",
|
||||||
|
HEXSTR(secret[0], sizeof(secret[0]), hexbuf));
|
||||||
LSQ_DEBUG("server handshake secret: %s",
|
LSQ_DEBUG("server handshake secret: %s",
|
||||||
HEXSTR(secret[1], sizeof(secret[1]), hexbuf));
|
HEXSTR(secret[1], sizeof(secret[1]), hexbuf));
|
||||||
if (0 != init_crypto_ctx(&pair->ykp_ctx[1], md, aead, secret[1],
|
}
|
||||||
sizeof(secret[1]), enc_sess->esi_dir[1]))
|
|
||||||
|
cliser = !!(enc_sess->esi_flags & ESI_SERVER);
|
||||||
|
if (0 != init_crypto_ctx(&pair->ykp_ctx[!cliser], md, aead, secret[0],
|
||||||
|
sizeof(secret[0]), rw2dir(!cliser)))
|
||||||
|
goto err;
|
||||||
|
if (0 != init_crypto_ctx(&pair->ykp_ctx[cliser], md, aead, secret[1],
|
||||||
|
sizeof(secret[1]), rw2dir(cliser)))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
/* [draft-ietf-quic-tls-12] Section 5.6.1: AEAD_AES_128_GCM implies
|
/* [draft-ietf-quic-tls-12] Section 5.6.1: AEAD_AES_128_GCM implies
|
||||||
|
@ -938,7 +944,7 @@ setup_handshake_keys (struct enc_sess_iquic *enc_sess, const lsquic_cid_t *cid)
|
||||||
hp->hp_cipher = EVP_aes_128_ecb();
|
hp->hp_cipher = EVP_aes_128_ecb();
|
||||||
hp->hp_gen_mask = gen_hp_mask_aes;
|
hp->hp_gen_mask = gen_hp_mask_aes;
|
||||||
hp->hp_enc_level = ENC_LEV_CLEAR;
|
hp->hp_enc_level = ENC_LEV_CLEAR;
|
||||||
derive_hp_secrets(hp, md, aead, sizeof(secret[0]), secret[0], secret[1]);
|
derive_hp_secrets(hp, md, aead, sizeof(secret[0]), secret[!cliser], secret[cliser]);
|
||||||
|
|
||||||
if (enc_sess->esi_flags & ESI_LOG_SECRETS)
|
if (enc_sess->esi_flags & ESI_LOG_SECRETS)
|
||||||
{
|
{
|
||||||
|
@ -1389,13 +1395,11 @@ struct crypto_params
|
||||||
|
|
||||||
static int
|
static int
|
||||||
get_crypto_params (const struct enc_sess_iquic *enc_sess,
|
get_crypto_params (const struct enc_sess_iquic *enc_sess,
|
||||||
struct crypto_params *params)
|
const SSL_CIPHER *cipher, struct crypto_params *params)
|
||||||
{
|
{
|
||||||
const SSL_CIPHER *cipher;
|
|
||||||
unsigned key_sz, iv_sz;
|
unsigned key_sz, iv_sz;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
|
||||||
cipher = SSL_get_current_cipher(enc_sess->esi_ssl);
|
|
||||||
id = SSL_CIPHER_get_id(cipher);
|
id = SSL_CIPHER_get_id(cipher);
|
||||||
|
|
||||||
LSQ_DEBUG("Negotiated cipher ID is 0x%"PRIX32, id);
|
LSQ_DEBUG("Negotiated cipher ID is 0x%"PRIX32, id);
|
||||||
|
@ -1445,6 +1449,9 @@ get_crypto_params (const struct enc_sess_iquic *enc_sess,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: figure out why this duplicate check is here and either fix it
|
||||||
|
* or get rid of it.
|
||||||
|
*/
|
||||||
if (key_sz > EVP_MAX_KEY_LENGTH)
|
if (key_sz > EVP_MAX_KEY_LENGTH)
|
||||||
{
|
{
|
||||||
LSQ_DEBUG("PN size %u is too large", key_sz);
|
LSQ_DEBUG("PN size %u is too large", key_sz);
|
||||||
|
@ -1729,7 +1736,7 @@ iquic_esf_encrypt_packet (enc_session_t *enc_session_p,
|
||||||
size_t out_sz, dst_sz;
|
size_t out_sz, dst_sz;
|
||||||
int header_sz;
|
int header_sz;
|
||||||
int ipv6;
|
int ipv6;
|
||||||
unsigned packno_off, packno_len, cliser;
|
unsigned packno_off, packno_len;
|
||||||
enum packnum_space pns;
|
enum packnum_space pns;
|
||||||
char errbuf[ERR_ERROR_STRING_BUF_LEN];
|
char errbuf[ERR_ERROR_STRING_BUF_LEN];
|
||||||
|
|
||||||
|
@ -1737,17 +1744,16 @@ iquic_esf_encrypt_packet (enc_session_t *enc_session_p,
|
||||||
/* TODO Obviously, will need more logic for 0-RTT */
|
/* TODO Obviously, will need more logic for 0-RTT */
|
||||||
enc_level = pns2enc_level[ pns ];
|
enc_level = pns2enc_level[ pns ];
|
||||||
|
|
||||||
cliser = !!(enc_sess->esi_flags & ESI_SERVER);
|
|
||||||
if (enc_level == ENC_LEV_FORW)
|
if (enc_level == ENC_LEV_FORW)
|
||||||
{
|
{
|
||||||
pair = &enc_sess->esi_pairs[ enc_sess->esi_key_phase ];
|
pair = &enc_sess->esi_pairs[ enc_sess->esi_key_phase ];
|
||||||
crypto_ctx = &pair->ykp_ctx[ cliser ];
|
crypto_ctx = &pair->ykp_ctx[ 1 ];
|
||||||
hp = &enc_sess->esi_hp;
|
hp = &enc_sess->esi_hp;
|
||||||
}
|
}
|
||||||
else if (enc_sess->esi_hsk_pairs)
|
else if (enc_sess->esi_hsk_pairs)
|
||||||
{
|
{
|
||||||
pair = &enc_sess->esi_hsk_pairs[ enc_level ];
|
pair = &enc_sess->esi_hsk_pairs[ enc_level ];
|
||||||
crypto_ctx = &pair->ykp_ctx[ cliser ];
|
crypto_ctx = &pair->ykp_ctx[ 1 ];
|
||||||
hp = &enc_sess->esi_hsk_hps[ enc_level ];
|
hp = &enc_sess->esi_hsk_hps[ enc_level ];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1836,7 +1842,7 @@ iquic_esf_encrypt_packet (enc_session_t *enc_session_p,
|
||||||
const unsigned sample_off = packno_off + 4;
|
const unsigned sample_off = packno_off + 4;
|
||||||
assert(sample_off + IQUIC_TAG_LEN <= dst_sz);
|
assert(sample_off + IQUIC_TAG_LEN <= dst_sz);
|
||||||
#endif
|
#endif
|
||||||
apply_hp(enc_sess, hp, cliser, dst, packno_off, packno_len);
|
apply_hp(enc_sess, hp, dst, packno_off, packno_len);
|
||||||
|
|
||||||
packet_out->po_enc_data = dst;
|
packet_out->po_enc_data = dst;
|
||||||
packet_out->po_enc_data_sz = dst_sz;
|
packet_out->po_enc_data_sz = dst_sz;
|
||||||
|
@ -1879,7 +1885,7 @@ iquic_esf_decrypt_packet (enc_session_t *enc_session_p,
|
||||||
struct crypto_ctx *crypto_ctx = NULL;
|
struct crypto_ctx *crypto_ctx = NULL;
|
||||||
unsigned char nonce_buf[ sizeof(crypto_ctx->yk_iv_buf) + 8 ];
|
unsigned char nonce_buf[ sizeof(crypto_ctx->yk_iv_buf) + 8 ];
|
||||||
unsigned char *nonce, *begin_xor;
|
unsigned char *nonce, *begin_xor;
|
||||||
unsigned sample_off, packno_len, cliser, key_phase;
|
unsigned sample_off, packno_len, key_phase;
|
||||||
enum enc_level enc_level;
|
enum enc_level enc_level;
|
||||||
enum packnum_space pns;
|
enum packnum_space pns;
|
||||||
lsquic_packno_t packno;
|
lsquic_packno_t packno;
|
||||||
|
@ -1927,10 +1933,9 @@ iquic_esf_decrypt_packet (enc_session_t *enc_session_p,
|
||||||
dec_packin = DECPI_TOO_SHORT;
|
dec_packin = DECPI_TOO_SHORT;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
cliser = !(enc_sess->esi_flags & ESI_SERVER);
|
|
||||||
memcpy(dst, packet_in->pi_data, sample_off);
|
memcpy(dst, packet_in->pi_data, sample_off);
|
||||||
packet_in->pi_packno =
|
packet_in->pi_packno =
|
||||||
packno = strip_hp(enc_sess, hp, cliser,
|
packno = strip_hp(enc_sess, hp,
|
||||||
packet_in->pi_data + sample_off,
|
packet_in->pi_data + sample_off,
|
||||||
dst, packet_in->pi_header_sz, &packno_len);
|
dst, packet_in->pi_header_sz, &packno_len);
|
||||||
|
|
||||||
|
@ -1939,7 +1944,7 @@ iquic_esf_decrypt_packet (enc_session_t *enc_session_p,
|
||||||
key_phase = (dst[0] & 0x04) > 0;
|
key_phase = (dst[0] & 0x04) > 0;
|
||||||
pair = &enc_sess->esi_pairs[ key_phase ];
|
pair = &enc_sess->esi_pairs[ key_phase ];
|
||||||
if (key_phase == enc_sess->esi_key_phase)
|
if (key_phase == enc_sess->esi_key_phase)
|
||||||
crypto_ctx = &pair->ykp_ctx[ cliser ];
|
crypto_ctx = &pair->ykp_ctx[ 0 ];
|
||||||
else if (!is_valid_packno(
|
else if (!is_valid_packno(
|
||||||
enc_sess->esi_pairs[enc_sess->esi_key_phase].ykp_thresh)
|
enc_sess->esi_pairs[enc_sess->esi_key_phase].ykp_thresh)
|
||||||
|| packet_in->pi_packno
|
|| packet_in->pi_packno
|
||||||
|
@ -1947,7 +1952,7 @@ iquic_esf_decrypt_packet (enc_session_t *enc_session_p,
|
||||||
{
|
{
|
||||||
const struct ku_label kl = select_ku_label(enc_sess);
|
const struct ku_label kl = select_ku_label(enc_sess);
|
||||||
lsquic_qhkdf_expand(enc_sess->esi_md,
|
lsquic_qhkdf_expand(enc_sess->esi_md,
|
||||||
enc_sess->esi_traffic_secrets[cliser], enc_sess->esi_trasec_sz,
|
enc_sess->esi_traffic_secrets[0], enc_sess->esi_trasec_sz,
|
||||||
kl.str, kl.len, new_secret, enc_sess->esi_trasec_sz);
|
kl.str, kl.len, new_secret, enc_sess->esi_trasec_sz);
|
||||||
if (enc_sess->esi_flags & ESI_LOG_SECRETS)
|
if (enc_sess->esi_flags & ESI_LOG_SECRETS)
|
||||||
LSQ_DEBUG("key phase changed to %u, will try decrypting using "
|
LSQ_DEBUG("key phase changed to %u, will try decrypting using "
|
||||||
|
@ -1970,7 +1975,7 @@ iquic_esf_decrypt_packet (enc_session_t *enc_session_p,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
crypto_ctx = &pair->ykp_ctx[ cliser ];
|
crypto_ctx = &pair->ykp_ctx[ 0 ];
|
||||||
if (UNLIKELY(0 == (crypto_ctx->yk_flags & YK_INITED)))
|
if (UNLIKELY(0 == (crypto_ctx->yk_flags & YK_INITED)))
|
||||||
{
|
{
|
||||||
LSQ_DEBUG("supposedly older context is not initialized (key "
|
LSQ_DEBUG("supposedly older context is not initialized (key "
|
||||||
|
@ -1985,7 +1990,7 @@ iquic_esf_decrypt_packet (enc_session_t *enc_session_p,
|
||||||
key_phase = 0;
|
key_phase = 0;
|
||||||
assert(enc_sess->esi_hsk_pairs);
|
assert(enc_sess->esi_hsk_pairs);
|
||||||
pair = &enc_sess->esi_hsk_pairs[ enc_level ];
|
pair = &enc_sess->esi_hsk_pairs[ enc_level ];
|
||||||
crypto_ctx = &pair->ykp_ctx[ cliser ];
|
crypto_ctx = &pair->ykp_ctx[ 0 ];
|
||||||
if (UNLIKELY(0 == (crypto_ctx->yk_flags & YK_INITED)))
|
if (UNLIKELY(0 == (crypto_ctx->yk_flags & YK_INITED)))
|
||||||
{
|
{
|
||||||
LSQ_WARN("decrypt crypto context at level %s not initialized",
|
LSQ_WARN("decrypt crypto context at level %s not initialized",
|
||||||
|
@ -2055,21 +2060,21 @@ iquic_esf_decrypt_packet (enc_session_t *enc_session_p,
|
||||||
"keys", key_phase);
|
"keys", key_phase);
|
||||||
const struct ku_label kl = select_ku_label(enc_sess);
|
const struct ku_label kl = select_ku_label(enc_sess);
|
||||||
pair->ykp_thresh = packet_in->pi_packno;
|
pair->ykp_thresh = packet_in->pi_packno;
|
||||||
pair->ykp_ctx[ cliser ] = crypto_ctx_buf;
|
pair->ykp_ctx[ 0 ] = crypto_ctx_buf;
|
||||||
memcpy(enc_sess->esi_traffic_secrets[ cliser ], new_secret,
|
memcpy(enc_sess->esi_traffic_secrets[ 0 ], new_secret,
|
||||||
enc_sess->esi_trasec_sz);
|
enc_sess->esi_trasec_sz);
|
||||||
lsquic_qhkdf_expand(enc_sess->esi_md,
|
lsquic_qhkdf_expand(enc_sess->esi_md,
|
||||||
enc_sess->esi_traffic_secrets[!cliser], enc_sess->esi_trasec_sz,
|
enc_sess->esi_traffic_secrets[1], enc_sess->esi_trasec_sz,
|
||||||
kl.str, kl.len, new_secret, enc_sess->esi_trasec_sz);
|
kl.str, kl.len, new_secret, enc_sess->esi_trasec_sz);
|
||||||
memcpy(enc_sess->esi_traffic_secrets[ !cliser ], new_secret,
|
memcpy(enc_sess->esi_traffic_secrets[1], new_secret,
|
||||||
enc_sess->esi_trasec_sz);
|
enc_sess->esi_trasec_sz);
|
||||||
s = init_crypto_ctx(&pair->ykp_ctx[ !cliser ], enc_sess->esi_md,
|
s = init_crypto_ctx(&pair->ykp_ctx[1], enc_sess->esi_md,
|
||||||
enc_sess->esi_aead, new_secret, enc_sess->esi_trasec_sz,
|
enc_sess->esi_aead, new_secret, enc_sess->esi_trasec_sz,
|
||||||
evp_aead_seal);
|
evp_aead_seal);
|
||||||
if (s != 0)
|
if (s != 0)
|
||||||
{
|
{
|
||||||
LSQ_ERROR("could not init seal crypto ctx (key phase)");
|
LSQ_ERROR("could not init seal crypto ctx (key phase)");
|
||||||
cleanup_crypto_ctx(&pair->ykp_ctx[ !cliser ]);
|
cleanup_crypto_ctx(&pair->ykp_ctx[1]);
|
||||||
/* This is a severe error, abort connection */
|
/* This is a severe error, abort connection */
|
||||||
enc_sess->esi_conn->cn_if->ci_internal_error(enc_sess->esi_conn,
|
enc_sess->esi_conn->cn_if->ci_internal_error(enc_sess->esi_conn,
|
||||||
"crypto ctx failure during key phase shift");
|
"crypto ctx failure during key phase shift");
|
||||||
|
@ -2432,20 +2437,17 @@ typedef char enums_have_the_same_value[
|
||||||
(int) ssl_encryption_application == (int) ENC_LEV_FORW ? 1 : -1];
|
(int) ssl_encryption_application == (int) ENC_LEV_FORW ? 1 : -1];
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cry_sm_set_encryption_secret (SSL *ssl, enum ssl_encryption_level_t level,
|
set_secret (SSL *ssl, enum ssl_encryption_level_t level,
|
||||||
const uint8_t *read_secret, const uint8_t *write_secret,
|
const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len, int rw)
|
||||||
size_t secret_len)
|
|
||||||
{
|
{
|
||||||
struct enc_sess_iquic *enc_sess;
|
struct enc_sess_iquic *enc_sess;
|
||||||
struct crypto_ctx_pair *pair;
|
struct crypto_ctx_pair *pair;
|
||||||
struct header_prot *hp;
|
struct header_prot *hp;
|
||||||
struct crypto_params crypa;
|
struct crypto_params crypa;
|
||||||
int i;
|
|
||||||
int have_alpn;
|
int have_alpn;
|
||||||
const unsigned char *alpn;
|
const unsigned char *alpn;
|
||||||
unsigned alpn_len;
|
unsigned alpn_len;
|
||||||
const enum enc_level enc_level = (enum enc_level) level;
|
const enum enc_level enc_level = (enum enc_level) level;
|
||||||
const uint8_t *secrets[2];
|
|
||||||
char errbuf[ERR_ERROR_STRING_BUF_LEN];
|
char errbuf[ERR_ERROR_STRING_BUF_LEN];
|
||||||
#define hexbuf errbuf
|
#define hexbuf errbuf
|
||||||
|
|
||||||
|
@ -2470,13 +2472,15 @@ cry_sm_set_encryption_secret (SSL *ssl, enum ssl_encryption_level_t level,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != get_crypto_params(enc_sess, &crypa))
|
if (0 != get_crypto_params(enc_sess, cipher, &crypa))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
if (enc_sess->esi_flags & ESI_SERVER)
|
if (enc_sess->esi_flags & ESI_SERVER)
|
||||||
secrets[0] = read_secret, secrets[1] = write_secret;
|
secrets[0] = read_secret, secrets[1] = write_secret;
|
||||||
else
|
else
|
||||||
secrets[0] = write_secret, secrets[1] = read_secret;
|
secrets[0] = write_secret, secrets[1] = read_secret;
|
||||||
|
*/
|
||||||
|
|
||||||
if (enc_level < ENC_LEV_FORW)
|
if (enc_level < ENC_LEV_FORW)
|
||||||
{
|
{
|
||||||
|
@ -2489,39 +2493,45 @@ cry_sm_set_encryption_secret (SSL *ssl, enum ssl_encryption_level_t level,
|
||||||
pair = &enc_sess->esi_pairs[0];
|
pair = &enc_sess->esi_pairs[0];
|
||||||
hp = &enc_sess->esi_hp;
|
hp = &enc_sess->esi_hp;
|
||||||
enc_sess->esi_trasec_sz = secret_len;
|
enc_sess->esi_trasec_sz = secret_len;
|
||||||
memcpy(enc_sess->esi_traffic_secrets[0], secrets[0], secret_len);
|
memcpy(enc_sess->esi_traffic_secrets[rw], secret, secret_len);
|
||||||
memcpy(enc_sess->esi_traffic_secrets[1], secrets[1], secret_len);
|
|
||||||
enc_sess->esi_md = crypa.md;
|
enc_sess->esi_md = crypa.md;
|
||||||
enc_sess->esi_aead = crypa.aead;
|
enc_sess->esi_aead = crypa.aead;
|
||||||
}
|
}
|
||||||
pair->ykp_thresh = IQUIC_INVALID_PACKNO;
|
pair->ykp_thresh = IQUIC_INVALID_PACKNO;
|
||||||
|
|
||||||
LSQ_DEBUG("set encryption for level %u", enc_level);
|
|
||||||
for (i = 1; i >= 0; --i)
|
|
||||||
{
|
|
||||||
if (secrets[i])
|
|
||||||
{
|
|
||||||
if (enc_sess->esi_flags & ESI_LOG_SECRETS)
|
if (enc_sess->esi_flags & ESI_LOG_SECRETS)
|
||||||
LSQ_DEBUG("new %s secret: %s", i ? "server" : "client",
|
LSQ_DEBUG("set %s secret for level %u: %s", rw2str[rw], enc_level,
|
||||||
HEXSTR(secrets[i], secret_len, hexbuf));
|
HEXSTR(secret, secret_len, hexbuf));
|
||||||
if (0 != init_crypto_ctx(&pair->ykp_ctx[i], crypa.md,
|
else
|
||||||
crypa.aead, secrets[i], secret_len, enc_sess->esi_dir[i]))
|
LSQ_DEBUG("set %s for level %u", rw2str[rw], enc_level);
|
||||||
|
|
||||||
|
if (0 != init_crypto_ctx(&pair->ykp_ctx[rw], crypa.md,
|
||||||
|
crypa.aead, secret, secret_len, rw2dir(rw)))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
if (pair->ykp_ctx[!rw].yk_flags & YK_INITED)
|
||||||
|
{
|
||||||
|
/* Sanity check that the two sides end up with the same header
|
||||||
|
* protection logic, as they should.
|
||||||
|
*/
|
||||||
|
assert(hp->hp_cipher == crypa.hp);
|
||||||
|
assert(hp->hp_gen_mask == crypa.gen_hp_mask);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
assert(level == ssl_encryption_early_data);
|
{
|
||||||
}
|
|
||||||
|
|
||||||
hp->hp_enc_level = enc_level;
|
hp->hp_enc_level = enc_level;
|
||||||
hp->hp_cipher = crypa.hp;
|
hp->hp_cipher = crypa.hp;
|
||||||
hp->hp_gen_mask = crypa.gen_hp_mask;
|
hp->hp_gen_mask = crypa.gen_hp_mask;
|
||||||
derive_hp_secrets(hp, crypa.md, crypa.aead, secret_len, secrets[0],
|
hp->hp_sz = EVP_AEAD_key_length(crypa.aead);
|
||||||
secrets[1]);
|
}
|
||||||
|
lsquic_qhkdf_expand(crypa.md, secret, secret_len, PN_LABEL, PN_LABEL_SZ,
|
||||||
|
hp->hp_buf[rw], hp->hp_sz);
|
||||||
|
|
||||||
if (enc_sess->esi_flags & ESI_LOG_SECRETS)
|
if (enc_sess->esi_flags & ESI_LOG_SECRETS)
|
||||||
{
|
{
|
||||||
log_crypto_pair(enc_sess, pair, "new");
|
log_crypto_ctx(enc_sess, &pair->ykp_ctx[rw], "new", rw);
|
||||||
log_hp(enc_sess, hp, "new");
|
LSQ_DEBUG("%s hp: %s", rw2str[rw],
|
||||||
|
HEXSTR(hp->hp_buf[rw], hp->hp_sz, hexbuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -2534,6 +2544,22 @@ cry_sm_set_encryption_secret (SSL *ssl, enum ssl_encryption_level_t level,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
cry_sm_set_read_secret (SSL *ssl, enum ssl_encryption_level_t level,
|
||||||
|
const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len)
|
||||||
|
{
|
||||||
|
return set_secret(ssl, level, cipher, secret, secret_len, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
cry_sm_set_write_secret (SSL *ssl, enum ssl_encryption_level_t level,
|
||||||
|
const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len)
|
||||||
|
{
|
||||||
|
return set_secret(ssl, level, cipher, secret, secret_len, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cry_sm_write_message (SSL *ssl, enum ssl_encryption_level_t level,
|
cry_sm_write_message (SSL *ssl, enum ssl_encryption_level_t level,
|
||||||
const uint8_t *data, size_t len)
|
const uint8_t *data, size_t len)
|
||||||
|
@ -2631,7 +2657,8 @@ cry_sm_send_alert (SSL *ssl, enum ssl_encryption_level_t level, uint8_t alert)
|
||||||
|
|
||||||
static const SSL_QUIC_METHOD cry_quic_method =
|
static const SSL_QUIC_METHOD cry_quic_method =
|
||||||
{
|
{
|
||||||
.set_encryption_secrets = cry_sm_set_encryption_secret,
|
.set_read_secret = cry_sm_set_read_secret,
|
||||||
|
.set_write_secret = cry_sm_set_write_secret,
|
||||||
.add_handshake_data = cry_sm_write_message,
|
.add_handshake_data = cry_sm_write_message,
|
||||||
.flush_flight = cry_sm_flush_flight,
|
.flush_flight = cry_sm_flush_flight,
|
||||||
.send_alert = cry_sm_send_alert,
|
.send_alert = cry_sm_send_alert,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue