LCOV - code coverage report
Current view: top level - waltz/quic/tls - fd_quic_tls.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 7 7 100.0 %
Date: 2024-11-13 11:58:15 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 <stdlib.h>
       5             : #include <stdio.h>
       6             : 
       7             : #include "../fd_quic_common.h"
       8             : #include "../fd_quic_enum.h"
       9             : #include "../../tls/fd_tls.h"
      10             : #include "../templ/fd_quic_transport_params.h"
      11             : 
      12             : /* QUIC-TLS
      13             : 
      14             :    This defines an API for QUIC-TLS
      15             : 
      16             :    General operation:
      17             :      // set up a quic-tls config object
      18             :      fd_quic_tls_cfg_t quic_tls_cfg = {
      19             :        .secret_cb             = my_secret_cb,        // callback for communicating secrets
      20             : 
      21             :        .handshake_complete_cb = my_hs_complete,      // called when handshake is complete
      22             : 
      23             :        .max_concur_handshakes = 1234,                // number of handshakes this object can
      24             :                                                      // manage concurrently
      25             :        };
      26             : 
      27             :      // create a quic-tls object to manage handshakes:
      28             :      fd_quic_tls_t * quic_tls = fd_quic_tls_new( quic_tls_cfg );
      29             : 
      30             :      // delete a quic-tls object when it's not needed anymore
      31             :      fd_quic_delete( quic_tls );
      32             : 
      33             :      // create a client or a server handshake object
      34             :      //   call upon a new connection to manage the connection TLS handshake
      35             :      // hostname may be null for servers
      36             :      fd_quic_tls_hs_t * hs = fd_quic_tls_hs_new( quic_tls, conn_id, conn_id_sz, is_server, hostname );
      37             : 
      38             :      // delete a handshake object
      39             :      //   NULL is allowed here
      40             :      fd_quic_tls_hs_delete( hs );
      41             : 
      42             :      // call fd_quic_tls_provide_data whenever the peer sends TLS
      43             :      // handshake data.  The peer bootstraps the conversation with a
      44             :      // zero byte input.
      45             : 
      46             : */
      47             : 
      48             : /* each TLS handshake requires a number of fd_quic_tls_hs_data structures */
      49      409068 : #define FD_QUIC_TLS_HS_DATA_CNT 16u
      50             : 
      51             : /* alignment of hs_data
      52             :    must be a power of 2 */
      53       42105 : #define FD_QUIC_TLS_HS_DATA_ALIGN 32u
      54             : 
      55             : /* number of bytes allocated for queued handshake data
      56             :    must be a multiple of FD_QUIC_TLS_HS_DATA_ALIGN */
      57       84210 : #define FD_QUIC_TLS_HS_DATA_SZ  (2048UL)
      58             : 
      59             : /* callback function prototypes */
      60             : 
      61             : typedef void
      62             : (* fd_quic_tls_cb_secret_t)( fd_quic_tls_hs_t *           hs,
      63             :                              void *                       context,
      64             :                              fd_quic_tls_secret_t const * secret );
      65             : 
      66             : typedef void
      67             : (* fd_quic_tls_cb_handshake_complete_t)( fd_quic_tls_hs_t * hs,
      68             :                                          void *             context  );
      69             : 
      70             : typedef void
      71             : (* fd_quic_tls_cb_peer_params_t)( void *        context,
      72             :                                   uchar const * quic_tp,
      73             :                                   ulong         quic_tp_sz );
      74             : 
      75             : struct fd_quic_tls_secret {
      76             :   uint  enc_level;
      77             :   uchar read_secret [ FD_QUIC_SECRET_SZ ];
      78             :   uchar write_secret[ FD_QUIC_SECRET_SZ ];
      79             : };
      80             : 
      81             : struct fd_quic_tls_cfg {
      82             :   // callbacks ../crypto/fd_quic_crypto_suites
      83             :   fd_quic_tls_cb_secret_t              secret_cb;
      84             :   fd_quic_tls_cb_handshake_complete_t  handshake_complete_cb;
      85             :   fd_quic_tls_cb_peer_params_t         peer_params_cb;
      86             : 
      87             :   ulong          max_concur_handshakes;
      88             : 
      89             :   /* Signing callback for TLS 1.3 CertificateVerify. Context of the
      90             :      signer must outlive the tls object. */
      91             :   fd_tls_sign_t signer;
      92             : 
      93             :   /* Ed25519 public key */
      94             :   uchar const * cert_public_key;
      95             : };
      96             : 
      97             : /* structure for organising handshake data */
      98             : struct fd_quic_tls_hs_data {
      99             :   uchar const * data;
     100             :   uint          data_sz;
     101             :   uint          free_data_sz; /* internal use */
     102             :   uint          offset;
     103             :   uint          enc_level;
     104             : 
     105             :   /* internal use */
     106             :   ushort      next_idx; /* next in linked list, ~0 for end */
     107             : };
     108             : 
     109             : struct __attribute__((aligned(128))) fd_quic_tls {
     110             :   /* callbacks */
     111             :   fd_quic_tls_cb_secret_t              secret_cb;
     112             :   fd_quic_tls_cb_handshake_complete_t  handshake_complete_cb;
     113             :   fd_quic_tls_cb_peer_params_t         peer_params_cb;
     114             : 
     115             :   ulong                                max_concur_handshakes;
     116             : 
     117             :   /* array of (max_concur_handshakes) pre-allocated handshakes */
     118             :   fd_quic_tls_hs_t *                   handshakes;
     119             :   uchar *                              used_handshakes;
     120             : 
     121             :   /* ssl related */
     122             :   fd_tls_t tls;
     123             : };
     124             : 
     125      533793 : #define FD_QUIC_TLS_HS_DATA_UNUSED ((ushort)~0u)
     126             : 
     127             : struct fd_quic_tls_hs {
     128             :   /* TLS handshake handles are deliberately placed at the start.
     129             :      Allows for type punning between fd_quic_tls_hs_t and
     130             :      fd_tls_estate_{srv,cli}_t.  DO NOT MOVE.
     131             :      Type of handshake object depends on is_server. */
     132             :   fd_tls_estate_t hs;
     133             : 
     134             :   fd_quic_tls_t * quic_tls;
     135             : 
     136             :   int             is_server;
     137             :   int             is_flush;
     138             :   int             is_hs_complete;
     139             :   int             state;
     140       12396 : # define FD_QUIC_TLS_HS_STATE_DEAD         0
     141       42471 : # define FD_QUIC_TLS_HS_STATE_NEED_INPUT   1
     142       12030 : # define FD_QUIC_TLS_HS_STATE_COMPLETE     3
     143             : 
     144             :   /* user defined context supplied in callbacks */
     145             :   void *          context;
     146             : 
     147             :   /* handshake data
     148             :      this is data that must be sent to the peer
     149             :      it consists of an arbitrary list of tuples of:
     150             :        < "encryption level", array of bytes >
     151             :      these will be encapsulated and sent in order */
     152             :   fd_quic_tls_hs_data_t hs_data[ FD_QUIC_TLS_HS_DATA_CNT ];
     153             : 
     154             :   /* head of handshake data free list */
     155             :   ushort hs_data_free_idx;
     156             : 
     157             :   /* head of handshake data pending (to be sent) */
     158             :   ushort hs_data_pend_idx[4];
     159             :   ushort hs_data_pend_end_idx[4];
     160             : 
     161             :   /* handshake data buffer
     162             :      allocated in arbitrary chunks in a circular queue manner */
     163             :   uchar  hs_data_buf[ FD_QUIC_TLS_HS_DATA_SZ ];
     164             : 
     165             :   /* head and tail of unused hs_data_buf data
     166             :        head % buf_sz is first used byte
     167             :        tail % buf_sz is first unused byte
     168             :        invariants
     169             :          0 <= head < 2 * buf_sz
     170             :          0 <= tail <     buf_sz
     171             :          head >= tail
     172             :          head <  tail + buf_sz
     173             :          head -  tail == unused size */
     174             : 
     175             :   /* buffer space is shared between encryption levels */
     176             :   uint  hs_data_buf_head;
     177             :   uint  hs_data_buf_tail;
     178             :   uint  hs_data_offset[ 4 ]; /* one offset per encoding level */
     179             : 
     180             :   /* TLS alert code */
     181             :   uint  alert;
     182             : 
     183             :   /* our own QUIC transport params */
     184             :   fd_quic_transport_params_t self_transport_params;
     185             : };
     186             : 
     187             : ulong
     188             : fd_quic_tls_align( void );
     189             : 
     190             : ulong
     191             : fd_quic_tls_footprint( ulong handshake_cnt );
     192             : 
     193             : /* fd_quic_tls_new formats an unused memory region for use as an
     194             :    fd_quic_tls_t object and joins the caller to it */
     195             : 
     196             : fd_quic_tls_t *
     197             : fd_quic_tls_new( void *              mem,
     198             :                  fd_quic_tls_cfg_t * cfg );
     199             : 
     200             : /* fd_quic_delete unformats a memory region used as an fd_quic_tls_t.
     201             :    Returns the given pointer on success and NULL if used obviously in error.
     202             :    Deletes any fd_tls resources. */
     203             : 
     204             : void *
     205             : fd_quic_tls_delete( fd_quic_tls_t * self );
     206             : 
     207             : /* create a quic-tls handshake object for managing
     208             :    the handshakes for a single connection */
     209             : fd_quic_tls_hs_t *
     210             : fd_quic_tls_hs_new( fd_quic_tls_t * quic_tls,
     211             :                     void *          context,
     212             :                     int             is_server,
     213             :                     char const *    hostname,
     214             :                     fd_quic_transport_params_t const * self_transport_params );
     215             : 
     216             : /* fd_quic_tls_hs_delete frees a handshake object and its resources.
     217             :    Fine if hs is NULL. */
     218             : void
     219             : fd_quic_tls_hs_delete( fd_quic_tls_hs_t * hs );
     220             : 
     221             : /* fd_quic_tls_provide_data forwards an incoming QUIC CRYPTO frame
     222             :    containing TLS handshake message data to the underlying TLS
     223             :    implementation.
     224             : 
     225             :    In the case of a failure, errors will be stored in the fd_quic_tls_t object
     226             : 
     227             :    args
     228             :      hs             the fd_quic_tls_hs_t object to operate on
     229             :      enc_level      the encryption level specified in the quic packet
     230             :      data           the data from the quic CRYPTO frame
     231             :      data_sz        the length of the data from the quic CRYPTO frame
     232             : 
     233             :    returns
     234             :      FD_QUIC_SUCCESS
     235             :      FD_QUIC_FAILED
     236             :    */
     237             : int
     238             : fd_quic_tls_provide_data( fd_quic_tls_hs_t * self,
     239             :                           uint               enc_level,
     240             :                           uchar const *      data,
     241             :                           ulong              data_sz );
     242             : 
     243             : 
     244             : /* fd_quic_tls_get_hs_data
     245             : 
     246             :    get oldest queued handshake data from the queue of pending data to sent to peer
     247             : 
     248             :    returns
     249             :      NULL    there is no data available
     250             :      hd_data   a pointer to the fd_quic_tls_hs_data_t structure at the head of the queue
     251             : 
     252             :    the hd_data and data therein are invalidated by the following
     253             :      fd_quic_tls_pop_hs_data
     254             :      fd_quic_tls_delete
     255             :      fd_quic_tls_hs_delete
     256             : 
     257             :    args
     258             :      self        the handshake in question (fine if NULL)
     259             :      enc_level   a pointer for receiving the encryption level
     260             :      data        a pointer for receiving the pointer to the data buffer
     261             :      data_sz     a pointer for receiving the data size */
     262             : fd_quic_tls_hs_data_t *
     263             : fd_quic_tls_get_hs_data( fd_quic_tls_hs_t *  self, uint enc_level );
     264             : 
     265             : 
     266             : /* fd_quic_tls_get_next_hs_data
     267             : 
     268             :    get the next unit of handshake data from the queue
     269             : 
     270             :    returns NULL if no more available */
     271             : fd_quic_tls_hs_data_t *
     272             : fd_quic_tls_get_next_hs_data( fd_quic_tls_hs_t * self, fd_quic_tls_hs_data_t * hs );
     273             : 
     274             : 
     275             : /* fd_quic_tls_pop_hs_data
     276             : 
     277             :    remove handshake data from head of queue and free associated resources */
     278             : void
     279             : fd_quic_tls_pop_hs_data( fd_quic_tls_hs_t * self, uint enc_level );
     280             : 
     281             : 
     282             : #endif /* HEADER_fd_src_waltz_quic_tls_fd_quic_tls_h */
     283             : 

Generated by: LCOV version 1.14