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-09-17 04:28:31 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      402237 : #define FD_QUIC_TLS_HS_DATA_CNT 16u
      57             : 
      58             : /* alignment of hs_data
      59             :    must be a power of 2 */
      60       60759 : #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      121518 : #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             : 
     112             : /* structure for organising handshake data */
     113             : struct fd_quic_tls_hs_data {
     114             :   uchar const * data;
     115             :   uint          data_sz;
     116             :   uint          free_data_sz; /* internal use */
     117             :   uint          offset;
     118             :   uint          enc_level;
     119             : 
     120             :   /* internal use */
     121             :   ushort      next_idx; /* next in linked list, ~0 for end */
     122             : };
     123             : 
     124             : struct fd_quic_tls {
     125             :   /* callbacks */
     126             :   fd_quic_tls_cb_secret_t              secret_cb;
     127             :   fd_quic_tls_cb_handshake_complete_t  handshake_complete_cb;
     128             :   fd_quic_tls_cb_peer_params_t         peer_params_cb;
     129             : 
     130             :   /* ssl related */
     131             :   fd_tls_t tls;
     132             : };
     133             : 
     134      728976 : #define FD_QUIC_TLS_HS_DATA_UNUSED ((ushort)~0u)
     135             : 
     136             : struct fd_quic_tls_hs {
     137             :   /* TLS handshake handles are deliberately placed at the start.
     138             :      Allows for type punning between fd_quic_tls_hs_t and
     139             :      fd_tls_estate_{srv,cli}_t.  DO NOT MOVE.
     140             :      Type of handshake object depends on is_server. */
     141             :   fd_tls_estate_t hs;
     142             : 
     143             :   fd_quic_tls_t * quic_tls;
     144             : 
     145             :   int             is_server;
     146             :   int             is_hs_complete;
     147             : 
     148             :   /* user defined context supplied in callbacks */
     149             :   void *          context;
     150             : 
     151             :   ulong           next;      /* alloc pool/cache dlist */
     152             :   ulong           prev;      /* cache dlist */
     153             :   long            birthtime; /* allocation time, used for cache eviction sanity check */
     154             : 
     155             :   /* handshake data
     156             :      this is data that must be sent to the peer
     157             :      it consists of an arbitrary list of tuples of:
     158             :        < "encryption level", array of bytes >
     159             :      these will be encapsulated and sent in order */
     160             :   fd_quic_tls_hs_data_t hs_data[ FD_QUIC_TLS_HS_DATA_CNT ];
     161             : 
     162             :   /* head of hs_data_t free list */
     163             :   ushort hs_data_free_idx;
     164             : 
     165             :   /* head/tail of hs_data_t pending (to be sent) */
     166             :   ushort hs_data_pend_idx[4];
     167             :   ushort hs_data_pend_end_idx[4];
     168             : 
     169             :   /* handshake data buffer
     170             :       allocated in arbitrary chunks
     171             :       and shared between encryption levels */
     172             :   uchar hs_data_buf[ FD_QUIC_TLS_HS_DATA_SZ ];
     173             :   uint  hs_data_buf_ptr;     /* ptr is first unused byte in hs_data_buf */
     174             :   uint  hs_data_offset[ 4 ]; /* one offset per encoding level */
     175             : 
     176             :   /* Handshake message receive buffer
     177             : 
     178             :      rx_hs_buf buffers messages of one encryption level (rx_enc_level).
     179             :      rx_off is the number of bytes processed by fd_tls.  rx_sz is the
     180             :      number of contiguous bytes received from the peer. */
     181             : 
     182             :   ushort rx_off;
     183             :   ushort rx_sz;
     184             :   uchar  rx_enc_level;
     185             : 
     186       60696 : # define FD_QUIC_TLS_RX_DATA_SZ (2048UL)
     187             :   uchar rx_hs_buf[ FD_QUIC_TLS_RX_DATA_SZ ];
     188             : 
     189             :   /* TLS alert code */
     190             :   uint  alert;
     191             : 
     192             :   /* our own QUIC transport params */
     193             :   fd_quic_transport_params_t self_transport_params;
     194             : 
     195             : };
     196             : 
     197             : /* fd_quic_tls_new formats an unused memory region for use as an
     198             :    fd_quic_tls_t object and joins the caller to it */
     199             : 
     200             : fd_quic_tls_t *
     201             : fd_quic_tls_new( fd_quic_tls_t *     mem,
     202             :                  fd_quic_tls_cfg_t * cfg );
     203             : 
     204             : /* fd_quic_delete unformats a memory region used as an fd_quic_tls_t.
     205             :    Returns the given pointer on success and NULL if used obviously in error.
     206             :    Deletes any fd_tls resources. */
     207             : 
     208             : void *
     209             : fd_quic_tls_delete( fd_quic_tls_t * self );
     210             : 
     211             : fd_quic_tls_hs_t *
     212             : fd_quic_tls_hs_new( fd_quic_tls_hs_t * self,
     213             :                     fd_quic_tls_t *    quic_tls,
     214             :                     void *             context,
     215             :                     int                is_server,
     216             :                     fd_quic_transport_params_t const * self_transport_params,
     217             :                     long               now );
     218             : 
     219             : void
     220             : fd_quic_tls_hs_delete( fd_quic_tls_hs_t * hs );
     221             : 
     222             : /* fd_quic_tls_process processes any available TLS handshake messages
     223             :    from previously received CRYPTO frames.  Returns FD_QUIC_SUCCESS if
     224             :    any number of messages were processed (including no messages in there
     225             :    is not enough data).  Returns FD_QUIC_FAILED if the TLS handshake
     226             :    failed (not recoverable). */
     227             : 
     228             : int
     229             : fd_quic_tls_process( fd_quic_tls_hs_t * self );
     230             : 
     231             : 
     232             : /* fd_quic_tls_get_hs_data
     233             : 
     234             :    get oldest queued handshake data from the queue of pending data to sent to peer
     235             : 
     236             :    returns
     237             :      NULL    there is no data available
     238             :      hd_data   a pointer to the fd_quic_tls_hs_data_t structure at the head of the queue
     239             : 
     240             :    the hd_data and data therein are invalidated by the following
     241             :      fd_quic_tls_pop_hs_data
     242             :      fd_quic_tls_hs_delete
     243             : 
     244             :    args
     245             :      self        the handshake in question (fine if NULL)
     246             :      enc_level   a pointer for receiving the encryption level
     247             :      data        a pointer for receiving the pointer to the data buffer
     248             :      data_sz     a pointer for receiving the data size */
     249             : fd_quic_tls_hs_data_t *
     250             : fd_quic_tls_get_hs_data( fd_quic_tls_hs_t *  self, uint enc_level );
     251             : 
     252             : 
     253             : /* fd_quic_tls_get_next_hs_data
     254             : 
     255             :    get the next unit of handshake data from the queue
     256             : 
     257             :    returns NULL if no more available */
     258             : fd_quic_tls_hs_data_t *
     259             : fd_quic_tls_get_next_hs_data( fd_quic_tls_hs_t * self, fd_quic_tls_hs_data_t * hs );
     260             : 
     261             : 
     262             : /* fd_quic_tls_pop_hs_data
     263             : 
     264             :    remove handshake data from head of queue and free associated resources */
     265             : void
     266             : fd_quic_tls_pop_hs_data( fd_quic_tls_hs_t * self, uint enc_level );
     267             : 
     268             : 
     269             : /* fd_quic_tls_clear_hs_data
     270             : 
     271             :    clear all handshake data from a given encryption level. */
     272             : void
     273             : fd_quic_tls_clear_hs_data( fd_quic_tls_hs_t * self, uint enc_level );
     274             : 
     275             : 
     276             : #endif /* HEADER_fd_src_waltz_quic_tls_fd_quic_tls_h */

Generated by: LCOV version 1.14