MINOR: quic: Add quic_tls_key_update() function for Key Update

This function derives the next RX and TX keys and IVs from secrets
for the next key update key phase. We also implement quic_tls_rotate_keys()
which rotate the key update key phase information to be able to continue
to decrypt old key phase packets. Most of these information are pointers
to unsigned char.
This commit is contained in:
Frédéric Lécaille 2021-11-30 11:10:36 +01:00
parent 6e351d6c19
commit a7973a6dce

View File

@ -675,6 +675,97 @@ static inline void qc_set_timer(struct ssl_sock_ctx *ctx)
TRACE_LEAVE(QUIC_EV_CONN_STIMER, ctx->conn, pktns); TRACE_LEAVE(QUIC_EV_CONN_STIMER, ctx->conn, pktns);
} }
/* Derive new keys and ivs required for Key Update feature for <qc> QUIC
* connection.
* Return 1 if succeeded, 0 if not.
*/
static int quic_tls_key_update(struct quic_conn *qc)
{
struct quic_tls_ctx *tls_ctx = &qc->els[QUIC_TLS_ENC_LEVEL_APP].tls_ctx;
struct quic_tls_secrets *rx, *tx;
struct quic_tls_kp *nxt_rx = &qc->ku.nxt_rx;
struct quic_tls_kp *nxt_tx = &qc->ku.nxt_tx;
tls_ctx = &qc->els[QUIC_TLS_ENC_LEVEL_APP].tls_ctx;
rx = &tls_ctx->rx;
tx = &tls_ctx->tx;
nxt_rx = &qc->ku.nxt_rx;
nxt_tx = &qc->ku.nxt_tx;
/* Prepare new RX secrets */
if (!quic_tls_sec_update(rx->md, nxt_rx->secret, nxt_rx->secretlen,
rx->secret, rx->secretlen)) {
TRACE_DEVEL("New RX secret update failed", QUIC_EV_CONN_RWSEC, qc->conn);
return 0;
}
if (!quic_tls_derive_keys(rx->aead, NULL, rx->md,
nxt_rx->key, nxt_rx->keylen,
nxt_rx->iv, nxt_rx->ivlen, NULL, 0,
nxt_rx->secret, nxt_rx->secretlen)) {
TRACE_DEVEL("New RX key derivation failed", QUIC_EV_CONN_RWSEC, qc->conn);
return 0;
}
/* Prepare new TX secrets */
if (!quic_tls_sec_update(tx->md, nxt_tx->secret, nxt_tx->secretlen,
tx->secret, tx->secretlen)) {
TRACE_DEVEL("New TX secret update failed", QUIC_EV_CONN_RWSEC, qc->conn);
return 0;
}
if (!quic_tls_derive_keys(tx->aead, NULL, tx->md,
nxt_tx->key, nxt_tx->keylen,
nxt_tx->iv, nxt_tx->ivlen, NULL, 0,
nxt_tx->secret, nxt_tx->secretlen)) {
TRACE_DEVEL("New TX key derivation failed", QUIC_EV_CONN_RWSEC, qc->conn);
return 0;
}
return 1;
}
/* Rotate the Key Update information for <qc> QUIC connection.
* Must be used after having updated them.
* Always succeeds.
*/
static void quic_tls_rotate_keys(struct quic_conn *qc)
{
struct quic_tls_ctx *tls_ctx = &qc->els[QUIC_TLS_ENC_LEVEL_APP].tls_ctx;
unsigned char *curr_secret, *curr_iv, *curr_key;
/* Rotate the RX secrets */
curr_secret = tls_ctx->rx.secret;
curr_iv = tls_ctx->rx.iv;
curr_key = tls_ctx->rx.key;
tls_ctx->rx.secret = qc->ku.nxt_rx.secret;
tls_ctx->rx.iv = qc->ku.nxt_rx.iv;
tls_ctx->rx.key = qc->ku.nxt_rx.key;
qc->ku.nxt_rx.secret = qc->ku.prv_rx.secret;
qc->ku.nxt_rx.iv = qc->ku.prv_rx.iv;
qc->ku.nxt_rx.key = qc->ku.prv_rx.key;
qc->ku.prv_rx.secret = curr_secret;
qc->ku.prv_rx.iv = curr_iv;
qc->ku.prv_rx.key = curr_key;
qc->ku.prv_rx.pn = tls_ctx->rx.pn;
/* Update the TX secrets */
curr_secret = tls_ctx->tx.secret;
curr_iv = tls_ctx->tx.iv;
curr_key = tls_ctx->tx.key;
tls_ctx->tx.secret = qc->ku.nxt_tx.secret;
tls_ctx->tx.iv = qc->ku.nxt_tx.iv;
tls_ctx->tx.key = qc->ku.nxt_tx.key;
qc->ku.nxt_tx.secret = curr_secret;
qc->ku.nxt_tx.iv = curr_iv;
qc->ku.nxt_tx.key = curr_key;
}
#ifndef OPENSSL_IS_BORINGSSL #ifndef OPENSSL_IS_BORINGSSL
int ha_quic_set_encryption_secrets(SSL *ssl, enum ssl_encryption_level_t level, int ha_quic_set_encryption_secrets(SSL *ssl, enum ssl_encryption_level_t level,
const uint8_t *read_secret, const uint8_t *read_secret,