From 28a1795515abed3d65a03a7f56a9acb19a75fc45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= Date: Fri, 6 May 2022 15:07:20 +0200 Subject: [PATCH] MINOR: quic: Initialize stateless reset tokens with HKDF secrets Add quic_stateless_reset_token_init() wrapper function around quic_hkdf_extract_and_expand() function to derive the stateless reset tokens attached to the connection IDs from "cluster-secret" configuration setting and call it each time we instantiate a QUIC connection ID. --- src/xprt_quic.c | 48 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/src/xprt_quic.c b/src/xprt_quic.c index 0d598ce46..6605be1d7 100644 --- a/src/xprt_quic.c +++ b/src/xprt_quic.c @@ -3262,6 +3262,46 @@ int qc_send_ppkts(struct qring *qr, struct ssl_sock_ctx *ctx) return 1; } +/* Copy into buffer a stateless reset token depending on the + * salt input. This is the cluster secret which will be derived + * as HKDF input secret to generate this token. + * Return 1 if succeeded, 0 if not. + */ +static int quic_stateless_reset_token_cpy(unsigned char *buf, size_t len, + const unsigned char *salt, size_t saltlen) +{ + /* Input secret */ + const unsigned char *key = (const unsigned char *)global.cluster_secret; + size_t keylen = strlen(global.cluster_secret); + /* Info */ + const unsigned char label[] = "stateless token"; + size_t labellen = sizeof label - 1; + + return quic_hkdf_extract_and_expand(EVP_sha256(), buf, len, + key, keylen, salt, saltlen, label, labellen); +} + +/* Initialize the stateless reset token attached to connection ID. + * Returns 1 if succeeded, 0 if not. + */ +static int quic_stateless_reset_token_init(struct quic_connection_id *quic_cid) +{ + if (global.cluster_secret) { + /* Output secret */ + unsigned char *token = quic_cid->stateless_reset_token; + size_t tokenlen = sizeof quic_cid->stateless_reset_token; + /* Salt */ + const unsigned char *cid = quic_cid->cid.data; + size_t cidlen = quic_cid->cid.len; + + return quic_stateless_reset_token_cpy(token, tokenlen, cid, cidlen); + } + else { + return RAND_bytes(quic_cid->stateless_reset_token, + sizeof quic_cid->stateless_reset_token) == 1; + } +} + /* Allocate a new CID with as sequence number and attach it to * ebtree. * @@ -3282,14 +3322,12 @@ static struct quic_connection_id *new_quic_cid(struct eb_root *root, return NULL; cid->cid.len = QUIC_HAP_CID_LEN; - if (RAND_bytes(cid->cid.data, cid->cid.len) != 1 || - RAND_bytes(cid->stateless_reset_token, - sizeof cid->stateless_reset_token) != 1) { - fprintf(stderr, "Could not generate %d random bytes\n", cid->cid.len); + if (RAND_bytes(cid->cid.data, cid->cid.len) != 1) goto err; - } quic_pin_cid_to_tid(cid->cid.data, tid); + if (quic_stateless_reset_token_init(cid) != 1) + goto err; cid->qc = qc;