MINOR: quic: Add structures to maintain key phase information
When running Key Update process, we must maintain much information especially when the key phase bit has been toggled by the peer as it is possible that it is due to late packets. This patch adds quic_tls_kp new structure to do so. They are used to store previous and next secrets, keys and IVs associated to the previous and next RX key phase. We also need the next TX key phase information to be able to encrypt packets for the next key phase.
This commit is contained in:
parent
39484de813
commit
40df78f116
|
@ -91,6 +91,20 @@ enum quic_tls_pktns {
|
|||
|
||||
extern unsigned char initial_salt[20];
|
||||
|
||||
#define QUIC_FL_TLS_KP_BIT_SET (1 << 0)
|
||||
/* Key phase used for Key Update */
|
||||
struct quic_tls_kp {
|
||||
unsigned char *secret;
|
||||
size_t secretlen;
|
||||
unsigned char *iv;
|
||||
size_t ivlen;
|
||||
unsigned char *key;
|
||||
size_t keylen;
|
||||
uint64_t count;
|
||||
int64_t pn;
|
||||
unsigned char flags;
|
||||
};
|
||||
|
||||
/* Flag to be used when TLS secrets have been set. */
|
||||
#define QUIC_FL_TLS_SECRETS_SET (1 << 0)
|
||||
/* Flag to be used when TLS secrets have been discarded. */
|
||||
|
|
|
@ -520,6 +520,65 @@ static inline int qc_new_isecs(struct quic_conn *qc,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Release the memory allocated for all the key update key phase
|
||||
* structures for <qc> QUIC connection.
|
||||
* Always succeeds.
|
||||
*/
|
||||
static inline void quic_tls_ku_free(struct quic_conn *qc)
|
||||
{
|
||||
pool_free(pool_head_quic_tls_secret, qc->ku.prv_rx.secret);
|
||||
pool_free(pool_head_quic_tls_iv, qc->ku.prv_rx.iv);
|
||||
pool_free(pool_head_quic_tls_key, qc->ku.prv_rx.key);
|
||||
pool_free(pool_head_quic_tls_secret, qc->ku.nxt_rx.secret);
|
||||
pool_free(pool_head_quic_tls_iv, qc->ku.nxt_rx.iv);
|
||||
pool_free(pool_head_quic_tls_key, qc->ku.nxt_rx.key);
|
||||
pool_free(pool_head_quic_tls_secret, qc->ku.nxt_tx.secret);
|
||||
pool_free(pool_head_quic_tls_iv, qc->ku.nxt_tx.iv);
|
||||
pool_free(pool_head_quic_tls_key, qc->ku.nxt_tx.key);
|
||||
}
|
||||
|
||||
/* Initialize <kp> key update secrets, allocating the required memory.
|
||||
* Return 1 if all the secrets could be allocated, 0 if not.
|
||||
* This is the responsability of the caller to release the memory
|
||||
* allocated by this function in case of failure.
|
||||
*/
|
||||
static inline int quic_tls_kp_init(struct quic_tls_kp *kp)
|
||||
{
|
||||
kp->count = 0;
|
||||
kp->pn = 0;
|
||||
kp->flags = 0;
|
||||
kp->secret = pool_alloc(pool_head_quic_tls_secret);
|
||||
kp->secretlen = QUIC_TLS_SECRET_LEN;
|
||||
kp->iv = pool_alloc(pool_head_quic_tls_iv);
|
||||
kp->ivlen = QUIC_TLS_IV_LEN;
|
||||
kp->key = pool_alloc(pool_head_quic_tls_key);
|
||||
kp->keylen = QUIC_TLS_KEY_LEN;
|
||||
|
||||
return kp->secret && kp->iv && kp->key;
|
||||
}
|
||||
|
||||
/* Initialize all the key update key phase structures for <qc>
|
||||
* QUIC connection, allocating the required memory.
|
||||
* Returns 1 if succeeded, 0 if not.
|
||||
*/
|
||||
static inline int quic_tls_ku_init(struct quic_conn *qc)
|
||||
{
|
||||
struct quic_tls_kp *prv_rx = &qc->ku.prv_rx;
|
||||
struct quic_tls_kp *nxt_rx = &qc->ku.nxt_rx;
|
||||
struct quic_tls_kp *nxt_tx = &qc->ku.nxt_tx;
|
||||
|
||||
if (!quic_tls_kp_init(prv_rx) ||
|
||||
!quic_tls_kp_init(nxt_rx) ||
|
||||
!quic_tls_kp_init(nxt_tx))
|
||||
goto err;
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
quic_tls_ku_free(qc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* USE_QUIC */
|
||||
#endif /* _PROTO_QUIC_TLS_H */
|
||||
|
||||
|
|
|
@ -689,6 +689,11 @@ struct quic_conn {
|
|||
__decl_thread(HA_RWLOCK_T buf_rwlock);
|
||||
struct list pkt_list;
|
||||
} rx;
|
||||
struct {
|
||||
struct quic_tls_kp prv_rx;
|
||||
struct quic_tls_kp nxt_rx;
|
||||
struct quic_tls_kp nxt_tx;
|
||||
} ku;
|
||||
unsigned int max_ack_delay;
|
||||
struct quic_path paths[1];
|
||||
struct quic_path *path;
|
||||
|
|
|
@ -3205,6 +3205,10 @@ static struct quic_conn *qc_new_conn(unsigned int version, int ipv4,
|
|||
qc->rx.buf = b_make(buf_area, QUIC_CONN_RX_BUFSZ, 0, 0);
|
||||
HA_RWLOCK_INIT(&qc->rx.buf_rwlock);
|
||||
LIST_INIT(&qc->rx.pkt_list);
|
||||
if (!quic_tls_ku_init(qc)) {
|
||||
TRACE_PROTO("Key update initialization failed", QUIC_EV_CONN_INIT);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* XXX TO DO: Only one path at this time. */
|
||||
qc->path = &qc->paths[0];
|
||||
|
|
Loading…
Reference in New Issue