blob: 500f125f427ed8c5671761683267142747c093b0 [file] [log] [blame]
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +01001/*
2 * include/proto/quic_tls.h
3 * This file provides definitions for QUIC-TLS.
4 *
5 * Copyright 2019 HAProxy Technologies, Frédéric Lécaille <flecaille@haproxy.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 */
12
13#ifndef _PROTO_QUIC_TLS_H
14#define _PROTO_QUIC_TLS_H
15#ifdef USE_QUIC
16#ifndef USE_OPENSSL
17#error "Must define USE_OPENSSL"
18#endif
19
20#define TRACE_SOURCE &trace_quic
21
22#include <stdlib.h>
23#include <openssl/ssl.h>
24
25#include <haproxy/dynbuf.h>
26#include <haproxy/quic_tls-t.h>
27#include <haproxy/trace.h>
28#include <haproxy/xprt_quic.h>
29
Frédéric Lécaille2fc76cf2021-08-31 19:10:40 +020030/* Initial salt depending on QUIC version to derive client/server initial secrets.
31 * This one is for draft-29 QUIC version.
32 */
33unsigned char initial_salt_draft_29[20] = {
34 0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2, 0x4c,
35 0x9e, 0x97, 0x86, 0xf1, 0x9c, 0x61, 0x11, 0xe0,
36 0x43, 0x90, 0xa8, 0x99
37};
38
39unsigned char initial_salt_v1[20] = {
40 0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3,
41 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8, 0x0c, 0xad,
42 0xcc, 0xbb, 0x7f, 0x0a
43};
44
Amaury Denoyelle4fd53d72021-12-21 14:28:26 +010045void quic_tls_keys_hexdump(struct buffer *buf,
46 const struct quic_tls_secrets *secs);
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +010047
48void quic_tls_secret_hexdump(struct buffer *buf,
49 const unsigned char *secret, size_t secret_len);
50
51int quic_derive_initial_secret(const EVP_MD *md,
Frédéric Lécaille2fc76cf2021-08-31 19:10:40 +020052 const unsigned char *initial_salt, size_t initial_salt_sz,
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +010053 unsigned char *initial_secret, size_t initial_secret_sz,
54 const unsigned char *secret, size_t secret_sz);
55
56int quic_tls_derive_initial_secrets(const EVP_MD *md,
57 unsigned char *rx, size_t rx_sz,
58 unsigned char *tx, size_t tx_sz,
59 const unsigned char *secret, size_t secret_sz,
60 int server);
61
62int quic_tls_encrypt(unsigned char *buf, size_t len,
63 const unsigned char *aad, size_t aad_len,
64 const EVP_CIPHER *aead,
65 const unsigned char *key, const unsigned char *iv);
66
67int quic_tls_decrypt(unsigned char *buf, size_t len,
68 unsigned char *aad, size_t aad_len,
69 const EVP_CIPHER *aead,
70 const unsigned char *key, const unsigned char *iv);
71
72int quic_tls_derive_keys(const EVP_CIPHER *aead, const EVP_CIPHER *hp,
73 const EVP_MD *md,
74 unsigned char *key, size_t keylen,
75 unsigned char *iv, size_t ivlen,
76 unsigned char *hp_key, size_t hp_keylen,
77 const unsigned char *secret, size_t secretlen);
78
Frédéric Lécaille39484de2021-11-30 10:10:24 +010079int quic_tls_sec_update(const EVP_MD *md,
80 unsigned char *new_sec, size_t new_seclen,
81 const unsigned char *sec, size_t seclen);
82
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +010083int quic_aead_iv_build(unsigned char *iv, size_t ivlen,
84 unsigned char *aead_iv, size_t aead_ivlen, uint64_t pn);
85
86static inline const EVP_CIPHER *tls_aead(const SSL_CIPHER *cipher)
87{
88 switch (SSL_CIPHER_get_id(cipher)) {
89 case TLS1_3_CK_AES_128_GCM_SHA256:
90 return EVP_aes_128_gcm();
91 case TLS1_3_CK_AES_256_GCM_SHA384:
92 return EVP_aes_256_gcm();
93#ifndef OPENSSL_IS_BORINGSSL
94 /* XXX TO DO XXX */
95 /* Note that for chacha20_poly1305, there exists EVP_AEAD_chacha20_poly135() function
96 * which returns a pointer to const EVP_AEAD.
97 */
98 case TLS1_3_CK_CHACHA20_POLY1305_SHA256:
99 return EVP_chacha20_poly1305();
100 case TLS1_3_CK_AES_128_CCM_SHA256:
101 return EVP_aes_128_ccm();
102#endif
103 default:
104 return NULL;
105 }
106}
107
108static inline const EVP_MD *tls_md(const SSL_CIPHER *cipher)
109{
110 switch (SSL_CIPHER_get_id(cipher)) {
111 case TLS1_3_CK_AES_128_GCM_SHA256:
112#ifndef OPENSSL_IS_BORINGSSL
113 /* XXX TO DO XXX */
114 /* Note that for chacha20_poly1305, there exists EVP_AEAD_chacha20_poly135() function
115 * which returns a pointer to const EVP_AEAD.
116 */
117 case TLS1_3_CK_AES_128_CCM_SHA256:
118 case TLS1_3_CK_CHACHA20_POLY1305_SHA256:
119#endif
120 return EVP_sha256();
121 case TLS1_3_CK_AES_256_GCM_SHA384:
122 return EVP_sha384();
123 default:
124 return NULL;
125 }
126}
127
128static inline const EVP_CIPHER *tls_hp(const SSL_CIPHER *cipher)
129{
130 switch (SSL_CIPHER_get_id(cipher)) {
131#ifndef OPENSSL_IS_BORINGSSL
132 /* XXX TO DO XXX */
133 /* Note that for chacha20_poly1305, there exists EVP_AEAD_chacha20_poly135() function
134 * which returns a pointer to const EVP_AEAD.
135 */
136 case TLS1_3_CK_CHACHA20_POLY1305_SHA256:
137 return EVP_chacha20();
138 case TLS1_3_CK_AES_128_CCM_SHA256:
139#endif
140 case TLS1_3_CK_AES_128_GCM_SHA256:
141 return EVP_aes_128_ctr();
142 case TLS1_3_CK_AES_256_GCM_SHA384:
143 return EVP_aes_256_ctr();
144 default:
145 return NULL;
146 }
147
148}
149
150/* These following functions map TLS implementation encryption level to ours */
151static inline enum quic_tls_enc_level ssl_to_quic_enc_level(enum ssl_encryption_level_t level)
152{
153 switch (level) {
154 case ssl_encryption_initial:
155 return QUIC_TLS_ENC_LEVEL_INITIAL;
156 case ssl_encryption_early_data:
157 return QUIC_TLS_ENC_LEVEL_EARLY_DATA;
158 case ssl_encryption_handshake:
159 return QUIC_TLS_ENC_LEVEL_HANDSHAKE;
160 case ssl_encryption_application:
161 return QUIC_TLS_ENC_LEVEL_APP;
162 default:
163 return -1;
164 }
165}
166
167/* These two following functions map our encryption level to the TLS implementation ones. */
Frédéric Lécailleb28812a2021-03-02 10:28:04 +0100168static inline enum ssl_encryption_level_t quic_to_ssl_enc_level(enum quic_tls_enc_level level)
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100169{
170 switch (level) {
171 case QUIC_TLS_ENC_LEVEL_INITIAL:
172 return ssl_encryption_initial;
173 case QUIC_TLS_ENC_LEVEL_EARLY_DATA:
174 return ssl_encryption_early_data;
175 case QUIC_TLS_ENC_LEVEL_HANDSHAKE:
176 return ssl_encryption_handshake;
177 case QUIC_TLS_ENC_LEVEL_APP:
178 return ssl_encryption_application;
179 default:
180 return -1;
181 }
182}
183
184/* Return a human readable string from <state> QUIC handshake state of NULL
185 * for unknown state values (for debug purpose).
186 */
187static inline char *quic_hdshk_state_str(const enum quic_handshake_state state)
188{
189 switch (state) {
190 case QUIC_HS_ST_CLIENT_INITIAL:
191 return "CI";
192 case QUIC_HS_ST_CLIENT_HANDSHAKE:
193 return "CH";
194 case QUIC_HS_ST_CLIENT_HANDSHAKE_FAILED:
195 return "CF";
196 case QUIC_HS_ST_SERVER_INITIAL:
197 return "SI";
198 case QUIC_HS_ST_SERVER_HANDSHAKE:
199 return "SH";
200 case QUIC_HS_ST_SERVER_HANDSHAKE_FAILED:
201 return "SF";
202 case QUIC_HS_ST_COMPLETE:
Frédéric Lécailleee574442021-08-18 09:10:48 +0200203 return "HCP";
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100204 case QUIC_HS_ST_CONFIRMED:
Frédéric Lécailleee574442021-08-18 09:10:48 +0200205 return "HCF";
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100206 }
207
208 return NULL;
209}
210
211/* Return a human readable string from <err> SSL error (returned from
212 * SSL_get_error())
213 */
214static inline const char *ssl_error_str(int err)
215{
216 switch (err) {
217 case SSL_ERROR_NONE:
218 return "NONE";
219 case SSL_ERROR_SSL:
220 return "SSL";
221 case SSL_ERROR_WANT_READ:
222 return "WANT_READ";
223 case SSL_ERROR_WANT_WRITE:
224 return "WANT_WRITE";
225 case SSL_ERROR_WANT_X509_LOOKUP:
226 return "X509_LOOKUP";
227 case SSL_ERROR_SYSCALL:
228 return "SYSCALL";
229 case SSL_ERROR_ZERO_RETURN:
230 return "ZERO_RETURN";
231 case SSL_ERROR_WANT_CONNECT:
232 return "WANT_CONNECT";
233 case SSL_ERROR_WANT_ACCEPT:
234 return "WANT_ACCEPT";
235#ifndef OPENSSL_IS_BORINGSSL
236 case SSL_ERROR_WANT_ASYNC:
237 return "WANT_ASYNC";
238 case SSL_ERROR_WANT_ASYNC_JOB:
239 return "WANT_ASYNC_JOB";
240 case SSL_ERROR_WANT_CLIENT_HELLO_CB:
241 return "WANT_CLIENT_HELLO_CB";
242#endif
243 default:
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500244 return "UNKNOWN";
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100245 }
246}
247
248
249/* Return a character identifying the encryption level from <level> QUIC TLS
250 * encryption level (for debug purpose).
251 * Initial -> 'I', Early Data -> 'E', Handshake -> 'H', Application -> 'A' and
252 * '-' if undefined.
253 */
254static inline char quic_enc_level_char(enum quic_tls_enc_level level)
255{
256 switch (level) {
257 case QUIC_TLS_ENC_LEVEL_INITIAL:
258 return 'I';
259 case QUIC_TLS_ENC_LEVEL_EARLY_DATA:
260 return 'E';
261 case QUIC_TLS_ENC_LEVEL_HANDSHAKE:
262 return 'H';
263 case QUIC_TLS_ENC_LEVEL_APP:
264 return 'A';
265 default:
266 return '-';
267 }
268}
269
270/* Return a character identifying <qel> encryption level from <qc> QUIC connection
271 * (for debug purpose).
272 * Initial -> 'I', Early Data -> 'E', Handshake -> 'H', Application -> 'A' and
273 * '-' if undefined.
274 */
275static inline char quic_enc_level_char_from_qel(const struct quic_enc_level *qel,
276 const struct quic_conn *qc)
277{
278 if (qel == &qc->els[QUIC_TLS_ENC_LEVEL_INITIAL])
279 return 'I';
280 else if (qel == &qc->els[QUIC_TLS_ENC_LEVEL_EARLY_DATA])
281 return 'E';
282 else if (qel == &qc->els[QUIC_TLS_ENC_LEVEL_HANDSHAKE])
283 return 'H';
284 else if (qel == &qc->els[QUIC_TLS_ENC_LEVEL_APP])
285 return 'A';
286 return '-';
287}
288
289/* Return a character identifying the encryption level of a packet depending on
290 * its <type> type, and its <long_header> header length (for debug purpose).
291 * Initial -> 'I', ORTT -> '0', Handshake -> 'H', Application -> 'A' and
292 * '-' if undefined.
293 */
294static inline char quic_packet_type_enc_level_char(int packet_type)
295{
296 switch (packet_type) {
297 case QUIC_PACKET_TYPE_INITIAL:
298 return 'I';
299 case QUIC_PACKET_TYPE_0RTT:
300 return '0';
301 case QUIC_PACKET_TYPE_HANDSHAKE:
302 return 'H';
303 case QUIC_PACKET_TYPE_SHORT:
304 return 'A';
305 default:
306 return '-';
307 }
308}
309
310/* Return the TLS encryption level to be used for <packet_type>
311 * QUIC packet type.
312 * Returns -1 if there is no TLS encryption level for <packet_type>
313 * packet type.
314 */
315static inline enum quic_tls_enc_level quic_packet_type_enc_level(enum quic_pkt_type packet_type)
316{
317 switch (packet_type) {
318 case QUIC_PACKET_TYPE_INITIAL:
319 return QUIC_TLS_ENC_LEVEL_INITIAL;
320 case QUIC_PACKET_TYPE_0RTT:
321 return QUIC_TLS_ENC_LEVEL_EARLY_DATA;
322 case QUIC_PACKET_TYPE_HANDSHAKE:
323 return QUIC_TLS_ENC_LEVEL_HANDSHAKE;
324 case QUIC_PACKET_TYPE_RETRY:
325 return QUIC_TLS_ENC_LEVEL_NONE;
326 case QUIC_PACKET_TYPE_SHORT:
327 return QUIC_TLS_ENC_LEVEL_APP;
328 default:
329 return QUIC_TLS_ENC_LEVEL_NONE;
330 }
331}
332
333static inline enum quic_tls_pktns quic_tls_pktns(enum quic_tls_enc_level level)
334{
335 switch (level) {
336 case QUIC_TLS_ENC_LEVEL_INITIAL:
337 return QUIC_TLS_PKTNS_INITIAL;
338 case QUIC_TLS_ENC_LEVEL_EARLY_DATA:
339 case QUIC_TLS_ENC_LEVEL_APP:
340 return QUIC_TLS_PKTNS_01RTT;
341 case QUIC_TLS_ENC_LEVEL_HANDSHAKE:
342 return QUIC_TLS_PKTNS_HANDSHAKE;
343 default:
344 return -1;
345 }
346}
347
Frédéric Lécaillefc768ec2021-11-23 21:02:04 +0100348/* Erase and free the secrets for a QUIC encryption level with <ctx> as
349 * context.
350 * Always succeeds.
351 */
352static inline void quic_tls_ctx_secs_free(struct quic_tls_ctx *ctx)
353{
354 if (ctx->rx.iv) {
355 memset(ctx->rx.iv, 0, ctx->rx.ivlen);
356 ctx->rx.ivlen = 0;
357 }
358 if (ctx->rx.key) {
359 memset(ctx->rx.key, 0, ctx->rx.keylen);
360 ctx->rx.keylen = 0;
361 }
362 if (ctx->tx.iv) {
363 memset(ctx->tx.iv, 0, ctx->tx.ivlen);
364 ctx->tx.ivlen = 0;
365 }
366 if (ctx->tx.key) {
367 memset(ctx->tx.key, 0, ctx->tx.keylen);
368 ctx->tx.keylen = 0;
369 }
370 pool_free(pool_head_quic_tls_iv, ctx->rx.iv);
371 pool_free(pool_head_quic_tls_key, ctx->rx.key);
372 pool_free(pool_head_quic_tls_iv, ctx->tx.iv);
373 pool_free(pool_head_quic_tls_key, ctx->tx.key);
374 ctx->rx.iv = ctx->tx.iv = NULL;
375 ctx->rx.key = ctx->tx.key = NULL;
376}
377
378/* Allocate the secrete keys for a QUIC encryption level with <ctx> as context.
379 * Returns 1 if succeeded, 0 if not.
380 */
381static inline int quic_tls_ctx_keys_alloc(struct quic_tls_ctx *ctx)
382{
383 if (!(ctx->rx.iv = pool_alloc(pool_head_quic_tls_iv)) ||
384 !(ctx->rx.key = pool_alloc(pool_head_quic_tls_key)) ||
385 !(ctx->tx.iv = pool_alloc(pool_head_quic_tls_iv)) ||
386 !(ctx->tx.key = pool_alloc(pool_head_quic_tls_key)))
387 goto err;
388
389 ctx->rx.ivlen = ctx->tx.ivlen = QUIC_TLS_IV_LEN;
390 ctx->rx.keylen = ctx->tx.keylen = QUIC_TLS_KEY_LEN;
391 return 1;
392
393 err:
394 quic_tls_ctx_secs_free(ctx);
395 return 0;
396}
397
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100398/* Initialize a TLS cryptographic context for the Initial encryption level. */
Frédéric Lécaillefc768ec2021-11-23 21:02:04 +0100399static inline int quic_initial_tls_ctx_init(struct quic_tls_ctx *ctx)
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100400{
401 ctx->rx.aead = ctx->tx.aead = EVP_aes_128_gcm();
402 ctx->rx.md = ctx->tx.md = EVP_sha256();
403 ctx->rx.hp = ctx->tx.hp = EVP_aes_128_ctr();
Frédéric Lécaillefc768ec2021-11-23 21:02:04 +0100404
405 return quic_tls_ctx_keys_alloc(ctx);
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100406}
407
408static inline int quic_tls_level_pkt_type(enum quic_tls_enc_level level)
409{
410 switch (level) {
411 case QUIC_TLS_ENC_LEVEL_INITIAL:
412 return QUIC_PACKET_TYPE_INITIAL;
413 case QUIC_TLS_ENC_LEVEL_EARLY_DATA:
414 return QUIC_PACKET_TYPE_0RTT;
415 case QUIC_TLS_ENC_LEVEL_HANDSHAKE:
416 return QUIC_PACKET_TYPE_HANDSHAKE;
Frédéric Lécaille31550af2021-08-19 07:33:08 +0200417 case QUIC_TLS_ENC_LEVEL_APP:
418 return QUIC_PACKET_TYPE_SHORT;
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100419 default:
420 return -1;
421 }
422}
423
424/* Set <*level> and <*next_level> depending on <state> QUIC handshake state. */
425static inline int quic_get_tls_enc_levels(enum quic_tls_enc_level *level,
426 enum quic_tls_enc_level *next_level,
Frédéric Lécaillea5da31d2021-12-14 19:44:14 +0100427 enum quic_handshake_state state, int zero_rtt)
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100428{
429 switch (state) {
430 case QUIC_HS_ST_SERVER_INITIAL:
431 case QUIC_HS_ST_CLIENT_INITIAL:
432 *level = QUIC_TLS_ENC_LEVEL_INITIAL;
Frédéric Lécaillea5da31d2021-12-14 19:44:14 +0100433 if (zero_rtt)
434 *next_level = QUIC_TLS_ENC_LEVEL_EARLY_DATA;
435 else
436 *next_level = QUIC_TLS_ENC_LEVEL_HANDSHAKE;
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100437 break;
438 case QUIC_HS_ST_SERVER_HANDSHAKE:
439 case QUIC_HS_ST_CLIENT_HANDSHAKE:
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100440 *level = QUIC_TLS_ENC_LEVEL_HANDSHAKE;
441 *next_level = QUIC_TLS_ENC_LEVEL_APP;
442 break;
Frédéric Lécaillef7980962021-08-19 17:35:21 +0200443 case QUIC_HS_ST_COMPLETE:
444 case QUIC_HS_ST_CONFIRMED:
445 *level = QUIC_TLS_ENC_LEVEL_APP;
446 *next_level = QUIC_TLS_ENC_LEVEL_NONE;
447 break;
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100448 default:
449 return 0;
450 }
451
452 return 1;
453}
454
Frédéric Lécaillefc768ec2021-11-23 21:02:04 +0100455/* Flag the keys at <qel> encryption level as discarded.
456 * Note that this function is called only for Initial or Handshake encryption levels.
457 */
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100458static inline void quic_tls_discard_keys(struct quic_enc_level *qel)
459{
460 qel->tls_ctx.rx.flags |= QUIC_FL_TLS_SECRETS_DCD;
461 qel->tls_ctx.tx.flags |= QUIC_FL_TLS_SECRETS_DCD;
Frédéric Lécaillefc768ec2021-11-23 21:02:04 +0100462 quic_tls_ctx_secs_free(&qel->tls_ctx);
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100463}
464
465/* Derive the initial secrets with <ctx> as QUIC TLS context which is the
466 * cryptographic context for the first encryption level (Initial) from
467 * <cid> connection ID with <cidlen> as length (in bytes) for a server or not
468 * depending on <server> boolean value.
469 * Return 1 if succeeded or 0 if not.
470 */
Frédéric Lécaille497fa782021-05-31 15:16:13 +0200471static inline int qc_new_isecs(struct quic_conn *qc,
Frédéric Lécaille2fc76cf2021-08-31 19:10:40 +0200472 const unsigned char *salt, size_t salt_len,
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100473 const unsigned char *cid, size_t cidlen, int server)
474{
475 unsigned char initial_secret[32];
476 /* Initial secret to be derived for incoming packets */
477 unsigned char rx_init_sec[32];
478 /* Initial secret to be derived for outgoing packets */
479 unsigned char tx_init_sec[32];
480 struct quic_tls_secrets *rx_ctx, *tx_ctx;
481 struct quic_tls_ctx *ctx;
482
Frédéric Lécaille497fa782021-05-31 15:16:13 +0200483 TRACE_ENTER(QUIC_EV_CONN_ISEC);
484 ctx = &qc->els[QUIC_TLS_ENC_LEVEL_INITIAL].tls_ctx;
Frédéric Lécaillefc768ec2021-11-23 21:02:04 +0100485 if (!quic_initial_tls_ctx_init(ctx))
486 goto err;
487
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100488 if (!quic_derive_initial_secret(ctx->rx.md,
Frédéric Lécaille2fc76cf2021-08-31 19:10:40 +0200489 salt, salt_len,
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100490 initial_secret, sizeof initial_secret,
491 cid, cidlen))
492 goto err;
493
494 if (!quic_tls_derive_initial_secrets(ctx->rx.md,
495 rx_init_sec, sizeof rx_init_sec,
496 tx_init_sec, sizeof tx_init_sec,
497 initial_secret, sizeof initial_secret, server))
498 goto err;
499
500 rx_ctx = &ctx->rx;
501 tx_ctx = &ctx->tx;
502 if (!quic_tls_derive_keys(ctx->rx.aead, ctx->rx.hp, ctx->rx.md,
Frédéric Lécaillefc768ec2021-11-23 21:02:04 +0100503 rx_ctx->key, rx_ctx->keylen,
504 rx_ctx->iv, rx_ctx->ivlen,
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100505 rx_ctx->hp_key, sizeof rx_ctx->hp_key,
506 rx_init_sec, sizeof rx_init_sec))
507 goto err;
508
509 rx_ctx->flags |= QUIC_FL_TLS_SECRETS_SET;
510 if (!quic_tls_derive_keys(ctx->tx.aead, ctx->tx.hp, ctx->tx.md,
Frédéric Lécaillefc768ec2021-11-23 21:02:04 +0100511 tx_ctx->key, tx_ctx->keylen,
512 tx_ctx->iv, tx_ctx->ivlen,
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100513 tx_ctx->hp_key, sizeof tx_ctx->hp_key,
514 tx_init_sec, sizeof tx_init_sec))
515 goto err;
516
517 tx_ctx->flags |= QUIC_FL_TLS_SECRETS_SET;
Frédéric Lécaille497fa782021-05-31 15:16:13 +0200518 TRACE_LEAVE(QUIC_EV_CONN_ISEC, NULL, rx_init_sec, tx_init_sec);
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100519
520 return 1;
521
522 err:
Frédéric Lécaille497fa782021-05-31 15:16:13 +0200523 TRACE_DEVEL("leaving in error", QUIC_EV_CONN_ISEC);
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100524 return 0;
525}
526
Frédéric Lécaille40df78f2021-11-30 10:59:37 +0100527/* Release the memory allocated for all the key update key phase
528 * structures for <qc> QUIC connection.
529 * Always succeeds.
530 */
531static inline void quic_tls_ku_free(struct quic_conn *qc)
532{
533 pool_free(pool_head_quic_tls_secret, qc->ku.prv_rx.secret);
534 pool_free(pool_head_quic_tls_iv, qc->ku.prv_rx.iv);
535 pool_free(pool_head_quic_tls_key, qc->ku.prv_rx.key);
536 pool_free(pool_head_quic_tls_secret, qc->ku.nxt_rx.secret);
537 pool_free(pool_head_quic_tls_iv, qc->ku.nxt_rx.iv);
538 pool_free(pool_head_quic_tls_key, qc->ku.nxt_rx.key);
539 pool_free(pool_head_quic_tls_secret, qc->ku.nxt_tx.secret);
540 pool_free(pool_head_quic_tls_iv, qc->ku.nxt_tx.iv);
541 pool_free(pool_head_quic_tls_key, qc->ku.nxt_tx.key);
542}
543
544/* Initialize <kp> key update secrets, allocating the required memory.
545 * Return 1 if all the secrets could be allocated, 0 if not.
546 * This is the responsability of the caller to release the memory
547 * allocated by this function in case of failure.
548 */
549static inline int quic_tls_kp_init(struct quic_tls_kp *kp)
550{
551 kp->count = 0;
552 kp->pn = 0;
553 kp->flags = 0;
554 kp->secret = pool_alloc(pool_head_quic_tls_secret);
555 kp->secretlen = QUIC_TLS_SECRET_LEN;
556 kp->iv = pool_alloc(pool_head_quic_tls_iv);
557 kp->ivlen = QUIC_TLS_IV_LEN;
558 kp->key = pool_alloc(pool_head_quic_tls_key);
559 kp->keylen = QUIC_TLS_KEY_LEN;
560
561 return kp->secret && kp->iv && kp->key;
562}
563
564/* Initialize all the key update key phase structures for <qc>
565 * QUIC connection, allocating the required memory.
566 * Returns 1 if succeeded, 0 if not.
567 */
568static inline int quic_tls_ku_init(struct quic_conn *qc)
569{
570 struct quic_tls_kp *prv_rx = &qc->ku.prv_rx;
571 struct quic_tls_kp *nxt_rx = &qc->ku.nxt_rx;
572 struct quic_tls_kp *nxt_tx = &qc->ku.nxt_tx;
573
574 if (!quic_tls_kp_init(prv_rx) ||
575 !quic_tls_kp_init(nxt_rx) ||
576 !quic_tls_kp_init(nxt_tx))
577 goto err;
578
579 return 1;
580
581 err:
582 quic_tls_ku_free(qc);
583 return 0;
584}
585
Frédéric Lécaille0c4e3b02020-11-23 14:10:37 +0100586#endif /* USE_QUIC */
587#endif /* _PROTO_QUIC_TLS_H */
588