LCOV - code coverage report
Current view: top level - waltz/quic/tls - fd_quic_tls.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 5 5 100.0 %
Date: 2026-10-15 04:28:26 Functions: 0 0 -

          Line data    Source code
       1             : #ifndef HEADER_fd_src_waltz_quic_tls_fd_quic_tls_h
       2             : #define HEADER_fd_src_waltz_quic_tls_fd_quic_tls_h
       3             : 
       4             : #include "../fd_quic_common.h"
       5             : #include "../fd_quic_enum.h"
       6             : #include "../../tls/fd_tls.h"
       7             : #include "../templ/fd_quic_transport_params.h"
       8             : 
       9             : /* QUIC-TLS
      10             : 
      11             :    This defines an API for QUIC-TLS
      12             : 
      13             :    General operation:
      14             :      // seed a CSPRNG
      15             :      static fd_chacha_rng_t _rng[1];
      16             :      fd_chacha_rng_t * rng = fd_chacha_rng_join(
      17             :          fd_chacha_rng_new( _rng, FD_CHACHA_RNG_MODE_SHIFT ) );
      18             :      uchar key[ FD_CHACHA_KEY_SZ ];
      19             :      if( FD_UNLIKELY( !fd_rng_secure( key, sizeof(key) ) ) ) abort();
      20             :      fd_chacha_rng_init( rng, key, FD_CHACHA_RNG_ALGO_CHACHA8 );
      21             :      fd_memzero_explicit( key, sizeof(key) );
      22             : 
      23             :      // set up a quic-tls config object
      24             :      fd_quic_tls_cfg_t quic_tls_cfg = {
      25             :        .secret_cb             = my_secret_cb,        // callback for communicating secrets
      26             : 
      27             :        .handshake_complete_cb = my_hs_complete,      // called when handshake is complete
      28             : 
      29             :        .max_concur_handshakes = 1234,                // number of handshakes this object can
      30             :                                                      // manage concurrently
      31             : 
      32             :        .rng                   = rng,                 // required, see above
      33             :        };
      34             : 
      35             :      // create a quic-tls object to manage handshakes:
      36             :      fd_quic_tls_t * quic_tls = fd_quic_tls_new( quic_tls_cfg );
      37             : 
      38             :      // delete a quic-tls object when it's not needed anymore
      39             :      fd_quic_delete( quic_tls );
      40             : 
      41             :      // create a client or a server handshake object
      42             :      //   call upon a new connection to manage the connection TLS handshake
      43             :      fd_quic_tls_hs_t * hs = fd_quic_tls_hs_new( quic_tls, conn_id, conn_id_sz, is_server, transport_params, now );
      44             : 
      45             :      // delete a handshake object
      46             :      //   NULL is allowed here
      47             :      fd_quic_tls_hs_delete( hs );
      48             : 
      49             :      // call fd_quic_tls_provide_data whenever the peer sends TLS
      50             :      // handshake data.  The peer bootstraps the conversation with a
      51             :      // zero byte input.
      52             : 
      53             : */
      54             : 
      55             : /* each TLS handshake requires a number of fd_quic_tls_hs_data structures */
      56      403524 : #define FD_QUIC_TLS_HS_DATA_CNT 16u
      57             : 
      58             : /* alignment of hs_data
      59             :    must be a power of 2 */
      60       42576 : #define FD_QUIC_TLS_HS_DATA_ALIGN 32u
      61             : 
      62             : /* number of bytes allocated for queued handshake data
      63             :    must be a multiple of FD_QUIC_TLS_HS_DATA_ALIGN */
      64       85152 : #define FD_QUIC_TLS_HS_DATA_SZ  (2048UL)
      65             : 
      66             : /* callback function prototypes */
      67             : 
      68             : typedef void
      69             : (* fd_quic_tls_cb_secret_t)( fd_quic_tls_hs_t *           hs,
      70             :                              void *                       context,
      71             :                              fd_quic_tls_secret_t const * secret );
      72             : 
      73             : typedef void
      74             : (* fd_quic_tls_cb_handshake_complete_t)( fd_quic_tls_hs_t * hs,
      75             :                                          void *             context  );
      76             : 
      77             : typedef void
      78             : (* fd_quic_tls_cb_peer_params_t)( void *        context,
      79             :                                   uchar const * quic_tp,
      80             :                                   ulong         quic_tp_sz );
      81             : 
      82             : struct fd_quic_tls_secret {
      83             :   uint  enc_level;
      84             :   uchar read_secret [ FD_QUIC_SECRET_SZ ];
      85             :   uchar write_secret[ FD_QUIC_SECRET_SZ ];
      86             : };
      87             : 
      88             : struct fd_quic_tls_cfg {
      89             :   // callbacks ../crypto/fd_quic_crypto_suites
      90             :   fd_quic_tls_cb_secret_t              secret_cb;
      91             :   fd_quic_tls_cb_handshake_complete_t  handshake_complete_cb;
      92             :   fd_quic_tls_cb_peer_params_t         peer_params_cb;
      93             : 
      94             :   ulong          max_concur_handshakes;
      95             : 
      96             :   /* Signing callback for TLS 1.3 CertificateVerify. Context of the
      97             :      signer must outlive the tls object. */
      98             :   fd_tls_sign_t signer;
      99             : 
     100             :   /* Ed25519 public key */
     101             :   uchar const * cert_public_key;
     102             : 
     103             :   /* rng is a seeded CSPRNG used to generate the TLS random of every
     104             :      handshake.  caller-managed, outlives quic_tls. */
     105             :   fd_chacha_rng_t * rng;
     106             : 
     107             :   /* alpn: either "solana-tpu" or "alpenglow-v1" */
     108             :   uchar const * alpn;
     109             :   ulong         alpn_sz;
     110             : 
     111             :   /* req_client_cert: see fd_tls_t */
     112             :   int req_client_cert;
     113             : };
     114             : 
     115             : /* structure for organising handshake data */
     116             : struct fd_quic_tls_hs_data {
     117             :   uchar const * data;
     118             :   uint          data_sz;
     119             :   uint          free_data_sz; /* internal use */
     120             :   uint          offset;
     121             :   uint          enc_level;
     122             : 
     123             :   /* internal use */
     124             :   ushort      next_idx; /* next in linked list, ~0 for end */
     125             : };
     126             : 
     127             : struct fd_quic_tls {
     128             :   /* callbacks */
     129             :   fd_quic_tls_cb_secret_t              secret_cb;
     130             :   fd_quic_tls_cb_handshake_complete_t  handshake_complete_cb;
     131             :   fd_quic_tls_cb_peer_params_t         peer_params_cb;
     132             : 
     133             :   /* ssl related */
     134             :   fd_tls_t tls;
     135             : };
     136             : 
     137      620130 : #define FD_QUIC_TLS_HS_DATA_UNUSED ((ushort)~0u)
     138             : 
     139             : struct fd_quic_tls_hs {
     140             :   /* TLS handshake handles are deliberately placed at the start.
     141             :      Allows for type punning between fd_quic_tls_hs_t and
     142             :      fd_tls_estate_{srv,cli}_t.  DO NOT MOVE.
     143             :      Type of handshake object depends on is_server. */
     144             :   fd_tls_estate_t hs;
     145             : 
     146             :   fd_quic_tls_t * quic_tls;
     147             : 
     148             :   int             is_server;
     149             :   int             is_hs_complete;
     150             : 
     151             :   /* user defined context supplied in callbacks */
     152             :   void *          context;
     153             : 
     154             :   ulong           next;      /* alloc pool/cache dlist */
     155             :   ulong           prev;      /* cache dlist */
     156             :   long            birthtime; /* allocation time, used for cache eviction sanity check */
     157             : 
     158             :   /* handshake data
     159             :      this is data that must be sent to the peer
     160             :      it consists of an arbitrary list of tuples of:
     161             :        < "encryption level", array of bytes >
     162             :      these will be encapsulated and sent in order */
     163             :   fd_quic_tls_hs_data_t hs_data[ FD_QUIC_TLS_HS_DATA_CNT ];
     164             : 
     165             :   /* head of hs_data_t free list */
     166             :   ushort hs_data_free_idx;
     167             : 
     168             :   /* head/tail of hs_data_t pending (to be sent) */
     169             :   ushort hs_data_pend_idx[4];
     170             :   ushort hs_data_pend_end_idx[4];
     171             : 
     172             :   /* handshake data buffer
     173             :       allocated in arbitrary chunks
     174             :       and shared between encryption levels */
     175             :   uchar hs_data_buf[ FD_QUIC_TLS_HS_DATA_SZ ];
     176             :   uint  hs_data_buf_ptr;     /* ptr is first unused byte in hs_data_buf */
     177             :   uint  hs_data_offset[ 4 ]; /* one offset per encoding level */
     178             : 
     179             :   /* Handshake message receive buffer
     180             : 
     181             :      rx_hs_buf buffers messages of one encryption level (rx_enc_level).
     182             :      rx_off is the number of bytes processed by fd_tls.  rx_sz is the
     183             :      number of contiguous bytes received from the peer. */
     184             : 
     185             :   ushort rx_off;
     186             :   ushort rx_sz;
     187             :   uchar  rx_enc_level;
     188             : 
     189       42489 : # define FD_QUIC_TLS_RX_DATA_SZ (2048UL)
     190             :   uchar rx_hs_buf[ FD_QUIC_TLS_RX_DATA_SZ ];
     191             : 
     192             :   /* TLS alert code */
     193             :   uint  alert;
     194             : 
     195             :   /* our own QUIC transport params */
     196             :   fd_quic_transport_params_t self_transport_params;
     197             : 
     198             : };
     199             : 
     200             : /* fd_quic_tls_new formats an unused memory region for use as an
     201             :    fd_quic_tls_t object and joins the caller to it */
     202             : 
     203             : fd_quic_tls_t *
     204             : fd_quic_tls_new( fd_quic_tls_t *     mem,
     205             :                  fd_quic_tls_cfg_t * cfg );
     206             : 
     207             : /* fd_quic_delete unformats a memory region used as an fd_quic_tls_t.
     208             :    Returns the given pointer on success and NULL if used obviously in error.
     209             :    Deletes any fd_tls resources. */
     210             : 
     211             : void *
     212             : fd_quic_tls_delete( fd_quic_tls_t * self );
     213             : 
     214             : fd_quic_tls_hs_t *
     215             : fd_quic_tls_hs_new( fd_quic_tls_hs_t * self,
     216             :                     fd_quic_tls_t *    quic_tls,
     217             :                     void *             context,
     218             :                     int                is_server,
     219             :                     fd_quic_transport_params_t const * self_transport_params,
     220             :                     long               now );
     221             : 
     222             : void
     223             : fd_quic_tls_hs_delete( fd_quic_tls_hs_t * hs );
     224             : 
     225             : /* fd_quic_tls_process processes any available TLS handshake messages
     226             :    from previously received CRYPTO frames.  Returns FD_QUIC_SUCCESS if
     227             :    any number of messages were processed (including no messages in there
     228             :    is not enough data).  Returns FD_QUIC_FAILED if the TLS handshake
     229             :    failed (not recoverable). */
     230             : 
     231             : int
     232             : fd_quic_tls_process( fd_quic_tls_hs_t * self );
     233             : 
     234             : 
     235             : /* fd_quic_tls_get_hs_data
     236             : 
     237             :    get oldest queued handshake data from the queue of pending data to sent to peer
     238             : 
     239             :    returns
     240             :      NULL    there is no data available
     241             :      hd_data   a pointer to the fd_quic_tls_hs_data_t structure at the head of the queue
     242             : 
     243             :    the hd_data and data therein are invalidated by the following
     244             :      fd_quic_tls_pop_hs_data
     245             :      fd_quic_tls_hs_delete
     246             : 
     247             :    args
     248             :      self        the handshake in question (fine if NULL)
     249             :      enc_level   a pointer for receiving the encryption level
     250             :      data        a pointer for receiving the pointer to the data buffer
     251             :      data_sz     a pointer for receiving the data size */
     252             : fd_quic_tls_hs_data_t *
     253             : fd_quic_tls_get_hs_data( fd_quic_tls_hs_t *  self, uint enc_level );
     254             : 
     255             : 
     256             : /* fd_quic_tls_get_next_hs_data
     257             : 
     258             :    get the next unit of handshake data from the queue
     259             : 
     260             :    returns NULL if no more available */
     261             : fd_quic_tls_hs_data_t *
     262             : fd_quic_tls_get_next_hs_data( fd_quic_tls_hs_t * self, fd_quic_tls_hs_data_t * hs );
     263             : 
     264             : 
     265             : /* fd_quic_tls_pop_hs_data
     266             : 
     267             :    remove handshake data from head of queue and free associated resources */
     268             : void
     269             : fd_quic_tls_pop_hs_data( fd_quic_tls_hs_t * self, uint enc_level );
     270             : 
     271             : 
     272             : /* fd_quic_tls_clear_hs_data
     273             : 
     274             :    clear all handshake data from a given encryption level. */
     275             : void
     276             : fd_quic_tls_clear_hs_data( fd_quic_tls_hs_t * self, uint enc_level );
     277             : 
     278             : 
     279             : #endif /* HEADER_fd_src_waltz_quic_tls_fd_quic_tls_h */

Generated by: LCOV version 1.14