1- /*
2- * Perform a QUIC server or client side handshake.
1+ /**
2+ * @file quic.c
3+ * @brief Utility functions for QUIC handshakes
34 *
5+ * @copyright
46 * Copyright (c) 2024 Red Hat, Inc.
5- *
7+ */
8+
9+ /*
610 * ktls-utils is free software; you can redistribute it and/or
711 * modify it under the terms of the GNU General Public License as
812 * published by the Free Software Foundation; version 2.
3135#include "tlshd.h"
3236
3337#ifdef HAVE_GNUTLS_QUIC
38+ /**
39+ * @brief Callback to handle a timer expiry
40+ * @param[in,out] arg user data
41+ */
3442static void quic_timer_handler (union sigval arg )
3543{
3644 struct tlshd_quic_conn * conn = arg .sival_ptr ;
@@ -39,6 +47,13 @@ static void quic_timer_handler(union sigval arg)
3947 conn -> errcode = ETIMEDOUT ;
4048}
4149
50+ /**
51+ * @brief Set a handshake timer
52+ * @param[in,out] conn QUIC handshake context
53+ *
54+ * @retval 0 Timer configured successfully
55+ * @retval -1 Failed to configure timer
56+ */
4257static int quic_conn_setup_timer (struct tlshd_quic_conn * conn )
4358{
4459 uint64_t msec = conn -> parms -> timeout_ms ;
@@ -62,11 +77,21 @@ static int quic_conn_setup_timer(struct tlshd_quic_conn *conn)
6277 return 0 ;
6378}
6479
80+ /**
81+ * @brief Delete a handshake timer
82+ * @param[in,out] conn QUIC handshake context
83+ */
6584static void quic_conn_delete_timer (struct tlshd_quic_conn * conn )
6685{
6786 timer_delete (conn -> timer );
6887}
6988
89+ /**
90+ * @brief Convert a GnuTLS cipher number to a kTLS cipher number
91+ * @param[in] cipher kTLS cipher number to be converted
92+ *
93+ * @returns a kTLS cipher number.
94+ */
7095static uint32_t quic_get_tls_cipher_type (gnutls_cipher_algorithm_t cipher )
7196{
7297 switch (cipher ) {
@@ -84,6 +109,12 @@ static uint32_t quic_get_tls_cipher_type(gnutls_cipher_algorithm_t cipher)
84109 }
85110}
86111
112+ /**
113+ * @brief Convert a GnuTLS encryption level number
114+ * @param[in] level GnuTLS encryption level
115+ *
116+ * @returns a QUIC encryption level number.
117+ */
87118static enum quic_crypto_level quic_get_crypto_level (gnutls_record_encryption_level_t level )
88119{
89120 switch (level ) {
@@ -101,6 +132,17 @@ static enum quic_crypto_level quic_get_crypto_level(gnutls_record_encryption_lev
101132 }
102133}
103134
135+ /**
136+ * @brief Callback to process a new traffic secret
137+ * @param[in,out] session GnuTLS session
138+ * @param[in] level GnuTLS encryption level
139+ * @param[in] rx_secret Receive secret, or NULL
140+ * @param[in] tx_secret Transmit secret, or NULL
141+ * @param[in] secretlen Length of secrets, in bytes
142+ *
143+ * @retval 0 Callback completed successfully
144+ * @retval -1 Callback failed
145+ */
104146static int quic_secret_func (gnutls_session_t session , gnutls_record_encryption_level_t level ,
105147 const void * rx_secret , const void * tx_secret , size_t secretlen )
106148{
@@ -150,6 +192,15 @@ static int quic_secret_func(gnutls_session_t session, gnutls_record_encryption_l
150192 return 0 ;
151193}
152194
195+ /**
196+ * @brief Callback to handle an outgoing alert
197+ * @param[in,out] session GnuTLS session
198+ * @param[in] level GnuTLS encryption level
199+ * @param[in] alert_level TLS alert level number
200+ * @param[in] alert_desc TLS alert description number
201+ *
202+ * @retval 0 Callback completed successfully
203+ */
153204static int quic_alert_read_func (gnutls_session_t session ,
154205 gnutls_record_encryption_level_t gtls_level ,
155206 gnutls_alert_level_t alert_level ,
@@ -160,6 +211,15 @@ static int quic_alert_read_func(gnutls_session_t session,
160211 return 0 ;
161212}
162213
214+ /**
215+ * @brief Callback to receive handshake data
216+ * @param[in,out] session GnuTLS session
217+ * @param[in] buf Buffer containing received data
218+ * @param[in] len Length of content in "buf", in bytes
219+ *
220+ * @retval 0 Callback completed successfully
221+ * @retval -1 Callback failed
222+ */
163223static int quic_tp_recv_func (gnutls_session_t session , const uint8_t * buf , size_t len )
164224{
165225 struct tlshd_quic_conn * conn = gnutls_session_get_ptr (session );
@@ -172,6 +232,14 @@ static int quic_tp_recv_func(gnutls_session_t session, const uint8_t *buf, size_
172232 return 0 ;
173233}
174234
235+ /**
236+ * @brief Callback to send handshake data
237+ * @param[in,out] session GnuTLS session
238+ * @param[in] buf Buffer to be filled in with data to send
239+ *
240+ * @retval 0 Callback completed successfully
241+ * @retval -1 Callback failed
242+ */
175243static int quic_tp_send_func (gnutls_session_t session , gnutls_buffer_t extdata )
176244{
177245 struct tlshd_quic_conn * conn = gnutls_session_get_ptr (session );
@@ -194,6 +262,17 @@ static int quic_tp_send_func(gnutls_session_t session, gnutls_buffer_t extdata)
194262 return 0 ;
195263}
196264
265+ /**
266+ * @brief Callback to handle an outgoing handshake message
267+ * @param[in,out] session GnuTLS session
268+ * @param[in] level GnuTLS encryption level
269+ * @param[in] htype GnuTLS handshake description
270+ * @param[in] data message to be processed
271+ * @param[in] datalen length of "data" in bytes
272+ *
273+ * @retval 0 Callback completed successfully
274+ * @retval -1 Callback failed
275+ */
197276static int quic_read_func (gnutls_session_t session , gnutls_record_encryption_level_t level ,
198277 gnutls_handshake_description_t htype , const void * data , size_t datalen )
199278{
@@ -224,9 +303,21 @@ static int quic_read_func(gnutls_session_t session, gnutls_record_encryption_lev
224303 return 0 ;
225304}
226305
306+ /**
307+ * @var char quic_priority
308+ * Default GnuTLS priority string for QUIC connections
309+ */
227310static char quic_priority [] =
228311 "%DISABLE_TLS13_COMPAT_MODE:NORMAL:-VERS-ALL:+VERS-TLS1.3:+PSK:-CIPHER-ALL:+" ;
229312
313+ /**
314+ * @brief Set the GnuTLS priority string for a session
315+ * @param[in,out] session GnuTLS session
316+ * @param[in] cipher kTLS cipher number to set
317+ *
318+ * @retval 0 GnuTLS priority string set successfully
319+ * @retval -1 Failed to set GnuTLS priority string
320+ */
230321static int quic_session_set_priority (gnutls_session_t session , uint32_t cipher )
231322{
232323 char p [136 ] = {};
@@ -258,6 +349,14 @@ static int quic_session_set_priority(gnutls_session_t session, uint32_t cipher)
258349 return 0 ;
259350}
260351
352+ /**
353+ * @brief Set the ALPN information on a session
354+ * @param[in,out] session GnuTLS session
355+ * @param[in] alpn_data ALPN string to set
356+ *
357+ * @retval 0 ALPN string set successfully
358+ * @retval -1 Failed to set ALPN string
359+ */
261360static int quic_session_set_alpns (gnutls_session_t session , char * alpn_data )
262361{
263362 gnutls_datum_t alpns [TLSHD_QUIC_MAX_ALPNS_LEN / 2 ];
@@ -281,6 +380,12 @@ static int quic_session_set_alpns(gnutls_session_t session, char *alpn_data)
281380 return 0 ;
282381}
283382
383+ /**
384+ * @brief Translate the encryption level value
385+ * @param[in] level QUIC encryption level
386+ *
387+ * @returns an equivalent GNUTLS_ENCRYPTION value
388+ */
284389static gnutls_record_encryption_level_t quic_get_encryption_level (uint8_t level )
285390{
286391 switch (level ) {
@@ -298,6 +403,13 @@ static gnutls_record_encryption_level_t quic_get_encryption_level(uint8_t level)
298403 }
299404}
300405
406+ /**
407+ * @brief Retrieve QUIC connection configuration
408+ * @param[in] conn QUIC handshake context
409+ *
410+ * @retval 0 Connection configuration retrieved successfully
411+ * @retval -1 Failed to retrieve configuration
412+ */
301413static int quic_conn_get_config (struct tlshd_quic_conn * conn )
302414{
303415 int sockfd = conn -> parms -> sockfd ;
@@ -326,6 +438,13 @@ static int quic_conn_get_config(struct tlshd_quic_conn *conn)
326438 return 0 ;
327439}
328440
441+ /**
442+ * @brief Send one QUIC handshake message on a socket
443+ * @param[in] sockfd Socket on which to send
444+ * @param[in] msg Buffer containing message to send
445+ *
446+ * @returns the number of bytes sent, or -1 if an error occurred.
447+ */
329448static int quic_handshake_sendmsg (int sockfd , struct tlshd_quic_msg * msg )
330449{
331450 char outcmsg [CMSG_SPACE (sizeof (struct quic_handshake_info ))];
@@ -359,6 +478,13 @@ static int quic_handshake_sendmsg(int sockfd, struct tlshd_quic_msg *msg)
359478 return sendmsg (sockfd , & outmsg , flags );
360479}
361480
481+ /**
482+ * @brief Receive one QUIC handshake message on a socket
483+ * @param[in] sockfd Socket on which to receive
484+ * @param[in,out] msg Buffer in which to receive a message
485+ *
486+ * @returns the number of bytes received, or -1 if an error occurred.
487+ */
362488static int quic_handshake_recvmsg (int sockfd , struct tlshd_quic_msg * msg )
363489{
364490 char incmsg [CMSG_SPACE (sizeof (struct quic_handshake_info ))];
@@ -397,11 +523,28 @@ static int quic_handshake_recvmsg(int sockfd, struct tlshd_quic_msg *msg)
397523 return ret ;
398524}
399525
400- static int quic_handshake_completed (const struct tlshd_quic_conn * conn )
526+ /**
527+ * @brief Predicate: Has the QUIC handshake completed
528+ * @param[in] conn QUIC handshake context
529+ *
530+ * @retval true The handshake completed
531+ * @retval false The handshake has not completed
532+ */
533+ static bool quic_handshake_completed (const struct tlshd_quic_conn * conn )
401534{
402535 return conn -> completed || conn -> errcode ;
403536}
404537
538+ /**
539+ * @brief Get the generated session data
540+ * @param[in] conn QUIC handshake context
541+ * @param[in] level Encryption level
542+ * @param[in] data Ticket blob
543+ * @param[in] datalen length of "data" in bytes
544+ *
545+ * @retval 0 Session data retrieved successfully
546+ * @retval -1 Session data is not available
547+ */
405548static int quic_handshake_crypto_data (const struct tlshd_quic_conn * conn ,
406549 uint8_t level , const uint8_t * data ,
407550 size_t datalen )
@@ -433,11 +576,11 @@ static int quic_handshake_crypto_data(const struct tlshd_quic_conn *conn,
433576}
434577
435578/**
436- * tlshd_quic_conn_create - Create a context for QUIC handshake
437- * @conn_p: pointer to accept the QUIC handshake context created
438- * @parms: handshake parameters
579+ * @brief Create a context for QUIC handshake
580+ * @param[out] conn_p Pointer to accept the QUIC handshake context created
581+ * @param[in] parms Handshake parameters
439582 *
440- * Returns: % 0 on success, or a negative error code
583+ * @returns 0 on success, or a negative error code
441584 */
442585int tlshd_quic_conn_create (struct tlshd_quic_conn * * conn_p , struct tlshd_handshake_parms * parms )
443586{
@@ -471,9 +614,8 @@ int tlshd_quic_conn_create(struct tlshd_quic_conn **conn_p, struct tlshd_handsha
471614}
472615
473616/**
474- * tlshd_quic_conn_destroy - Destroy a context for QUIC handshake
475- * @conn: QUIC handshake context to destroy
476- *
617+ * @brief Destroy a context for QUIC handshake
618+ * @param[in] conn QUIC handshake context to destroy
477619 */
478620void tlshd_quic_conn_destroy (struct tlshd_quic_conn * conn )
479621{
@@ -492,6 +634,13 @@ void tlshd_quic_conn_destroy(struct tlshd_quic_conn *conn)
492634
493635#define QUIC_TLSEXT_TP_PARAM 0x39u
494636
637+ /**
638+ * @brief Configure a tlshd_quic_conn
639+ * @param[in,out] conn QUIC handshake context
640+ *
641+ * @retval 0 Connection configured successfully
642+ * @retval -1 Failed to configure the connection
643+ */
495644static int tlshd_quic_session_configure (struct tlshd_quic_conn * conn )
496645{
497646 gnutls_session_t session = conn -> session ;
@@ -518,6 +667,10 @@ static int tlshd_quic_session_configure(struct tlshd_quic_conn *conn)
518667 return 0 ;
519668}
520669
670+ /**
671+ * @brief Set up a QUIC receive session ticket
672+ * @param[in,out] conn QUIC handshake context
673+ */
521674static void tlshd_quic_recv_session_ticket (struct tlshd_quic_conn * conn )
522675{
523676 gnutls_session_t session = conn -> session ;
@@ -567,9 +720,8 @@ static void tlshd_quic_recv_session_ticket(struct tlshd_quic_conn *conn)
567720}
568721
569722/**
570- * tlshd_quic_start_handshake - Drive the handshake interaction
571- * @conn: QUIC handshake context
572- *
723+ * @brief Drive a QUIC handshake interaction
724+ * @param[in,out] conn QUIC handshake context
573725 */
574726void tlshd_quic_start_handshake (struct tlshd_quic_conn * conn )
575727{
0 commit comments