Skip to content

Commit

Permalink
Integration for QUIC
Browse files Browse the repository at this point in the history
Summary:
* Main goal *
+ Integrate QUIC with TLS1.3 state machine
+ Integrate QUIC with TLS1.3 implementation.
+ Unify code path for TCP TLS1.3 and QUIC so that both can be used in one binary.

* What is not in the QUIC *
+ QUIC doesn't support change of cipher suite
+ QUIC doesn't support legacy session id
+ QUIC doesn't have end of early data

* What is new in the QUIC *
+ transport parameters

Test Plan:
ssl-opt.sh

Reviewers:

Subscribers:

Tasks:

Tags:
  • Loading branch information
lhuang04 committed Mar 16, 2021
1 parent 55900af commit 810b7a3
Show file tree
Hide file tree
Showing 7 changed files with 693 additions and 103 deletions.
8 changes: 8 additions & 0 deletions include/mbedtls/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
#include "mbedtls/ecp.h"
#endif

#if defined(MBEDTLS_DEBUG_C)
#include <assert.h>
#endif

#define MBEDTLS_SSL_DEBUG_QUIC_HS_MSG( level, text, hs_msg ) do { } while ( 0 )
#if defined(MBEDTLS_DEBUG_C)

#define MBEDTLS_DEBUG_STRIP_PARENS( ... ) __VA_ARGS__
Expand Down Expand Up @@ -68,6 +73,8 @@
mbedtls_debug_printf_ecdh( ssl, level, __FILE__, __LINE__, ecdh, attr )
#endif

#define MBEDTLS_ASSERT(cond) assert(cond)

#else /* MBEDTLS_DEBUG_C */

#define MBEDTLS_SSL_DEBUG_MSG( level, args ) do { } while( 0 )
Expand All @@ -77,6 +84,7 @@
#define MBEDTLS_SSL_DEBUG_ECP( level, text, X ) do { } while( 0 )
#define MBEDTLS_SSL_DEBUG_CRT( level, text, crt ) do { } while( 0 )
#define MBEDTLS_SSL_DEBUG_ECDH( level, ecdh, attr ) do { } while( 0 )
#define MBEDTLS_ASSERT(cond) do { } while( 0 )

#endif /* MBEDTLS_DEBUG_C */

Expand Down
66 changes: 65 additions & 1 deletion include/mbedtls/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@
#include "psa/crypto.h"
#endif /* MBEDTLS_USE_PSA_CRYPTO */

#if defined(MBEDTLS_SSL_PROTO_QUIC)
#include "quic.h"
#endif /* MBEDTLS_SSL_PROTO_QUIC */

/*
* SSL Error codes
*/
Expand Down Expand Up @@ -217,6 +221,7 @@

#define MBEDTLS_SSL_TRANSPORT_STREAM 0 /*!< TLS */
#define MBEDTLS_SSL_TRANSPORT_DATAGRAM 1 /*!< DTLS */
#define MBEDTLS_SSL_TRANSPORT_QUIC 2 /*!< QUIC */

#define MBEDTLS_SSL_MAX_HOST_NAME_LEN 255 /*!< Maximum host name defined in RFC 1035 */
#define MBEDTLS_SSL_MAX_ALPN_NAME_LEN 255 /*!< Maximum size in bytes of a protocol name in alpn ext., RFC 7301 */
Expand Down Expand Up @@ -566,6 +571,10 @@

#define MBEDTLS_TLS_EXT_RENEGOTIATION_INFO 0xFF01

#define MBEDTLS_TLS_EXT_QUIC_TRANSPORT_PARAMS 0xFFA5

#define MBEDTLS_QUIC_TRANSPORT_PARAMS_MAX_LEN 65535

/*
* Size defines
*/
Expand Down Expand Up @@ -852,6 +861,28 @@ typedef enum

#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL && MBEDTLS_SSL_NEW_SESSION_TICKET */

#if defined(MBEDTLS_SSL_PROTO_QUIC)
/**
* \brief set the QUIC transport params buffer for this endpoint.
*
* \param ssl SSL context.
* \param params the QUIC transport params buffer.
* \param len length of the the QUIC transport params buffer.
*/
int mbedtls_ssl_set_quic_transport_params(mbedtls_ssl_context *ssl,
const uint8_t *params, size_t len);

/**
* \brief get the quic transport params for the peer endpoint.
*
* \param ssl SSL context.
*/
void mbedtls_ssl_get_peer_quic_transport_params(mbedtls_ssl_context *ssl,
const uint8_t **params, size_t *len);

int mbedtls_ssl_quic_post_handshake(mbedtls_ssl_context *ssl);
#endif /* MBEDTLS_SSL_PROTO_QUIC */

#if defined(MBEDTLS_SSL_EXPORT_KEYS) && \
defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
typedef enum
Expand Down Expand Up @@ -1450,7 +1481,7 @@ struct mbedtls_ssl_config
*/

unsigned int endpoint : 1; /*!< 0: client, 1: server */
unsigned int transport : 1; /*!< stream (TLS) or datagram (DTLS) */
unsigned int transport : 2; /*!< 0: TLS, 1: DTLS, 2: QUIC */
unsigned int authmode : 2; /*!< MBEDTLS_SSL_VERIFY_XXX */
/* needed even with renego disabled for LEGACY_BREAK_HANDSHAKE */
unsigned int allow_legacy_renegotiation : 2 ; /*!< MBEDTLS_LEGACY_XXX */
Expand Down Expand Up @@ -1783,6 +1814,39 @@ struct mbedtls_ssl_context
int early_data_status;
#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL && MBEDTLS_ZERO_RTT && MBEDTLS_SSL_CLI_C */

#if defined(MBEDTLS_SSL_PROTO_QUIC)
/*
* QUIC method callbacks and the callback context pointer.
*/
mbedtls_quic_method *quic_method;

/*
* Context parameter for the QUIC method callbacks.
*/
void *p_quic_method;

/*
* QUIC outgoing and incoming crypto levels.
*/
mbedtls_ssl_crypto_level quic_hs_crypto_level;

/*
* The QUIC input data queue.
*/
mbedtls_quic_input quic_input;

/*
* QUIC transport parameters.
*/
uint8_t *quic_transport_params;
size_t quic_transport_params_len;

/*
* QUIC peer transport parameters.
*/
uint8_t *peer_quic_transport_params;
size_t peer_quic_transport_params_len;
#endif /* MBEDTLS_SSL_PROTO_QUIC */
};

#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
Expand Down
8 changes: 8 additions & 0 deletions include/mbedtls/ssl_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1909,4 +1909,12 @@ int mbedtls_ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl );
void mbedtls_ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl );
#endif /* MBEDTLS_SSL_PROTO_DTLS */


#if defined(MBEDTLS_SSL_PROTO_QUIC)
int mbedtls_set_quic_traffic_key(mbedtls_ssl_context *ssl, mbedtls_ssl_crypto_level level);
/* Shared implementation for the QUIC transport params setting */
int ssl_set_quic_transport_params(mbedtls_ssl_context *ssl,
const uint8_t *params, size_t len,
uint8_t **oparams, size_t *olen);
#endif
#endif /* ssl_internal.h */
87 changes: 81 additions & 6 deletions library/ssl_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -2293,6 +2293,12 @@ int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
*/
int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
{
#if defined(MBEDTLS_SSL_PROTO_QUIC)
// In QUIC mode, we do not employ byte-granular I/O. Therefore,
// there is no leftover output to flush.
if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_QUIC)
return 0;
#endif /* MBEDTLS_SSL_PROTO_QUIC */
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *buf;

Expand Down Expand Up @@ -2898,6 +2904,22 @@ int mbedtls_ssl_write_handshake_msg_ext( mbedtls_ssl_context *ssl,
*/
int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush )
{
#if defined(MBEDTLS_SSL_PROTO_QUIC)
if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_QUIC)
{
MBEDTLS_SSL_DEBUG_MSG(5, ("=> write record (quic)"));

ssl->quic_method->add_handshake_data(
ssl->p_quic_method,
ssl->quic_hs_crypto_level,
ssl->out_msg,
ssl->out_msglen);

MBEDTLS_SSL_DEBUG_MSG(5, ("<= write record (quic)"));

return(0);
}
#endif /* MBEDTLS_SSL_PROTO_QUIC */
int ret, done = 0;
size_t len = ssl->out_msglen;
uint8_t flush = force_flush;
Expand Down Expand Up @@ -4148,6 +4170,47 @@ static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl );
int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl,
unsigned update_hs_digest )
{
#if defined(MBEDTLS_SSL_PROTO_QUIC)
if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_QUIC)
{
if( ssl->keep_current_message == 0 )
{
/* Check for sufficient space in the `ssl->in_buf` buffer.
* We can use the entire span of the allocated memory past the `ssl->in_msg`:
*
* *- ssl->in_msg
* /
* v
* ssl->in_buf = [ | ... ]
* | MBEDTLS_SSL_IN_BUFFER_LEN |
*/
size_t available = MBEDTLS_SSL_IN_BUFFER_LEN -
(size_t)( ssl->in_msg - ssl->in_buf );

size_t len = mbedtls_quic_input_read(
ssl, ssl->quic_hs_crypto_level, ssl->in_msg, available);

if ( len == 0 )
{
return (MBEDTLS_ERR_SSL_INTERNAL_ERROR);
}

// Successfully read the message, store the length.
ssl->in_msglen = len;

// Mark the message type as handshake
ssl->in_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;

return mbedtls_ssl_prepare_handshake_record( ssl );
}
else
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "reuse previously read message" ) );
ssl->keep_current_message = 0;
return 0;
}
}
#endif /* MBEDTLS_SSL_PROTO_QUIC */
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read record" ) );
Expand Down Expand Up @@ -5220,15 +5283,27 @@ int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,

#else /* MBEDTLS_SSL_USE_MPS */

ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
ssl->out_msglen = 2;
ssl->out_msg[0] = level;
ssl->out_msg[1] = message;

if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
#if defined(MBEDTLS_SSL_PROTO_QUIC)
if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_QUIC)
{
if ( ( ret = ssl->quic_method->send_alert(ssl->p_quic_method, ssl->quic_hs_crypto_level, message ) ) != 0 )
{
return ret;
}
}
else
#endif /* MBEDTLS_SSL_PROTO_QUIC */
{
ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
ssl->out_msglen = 2;
ssl->out_msg[0] = level;
ssl->out_msg[1] = message;

if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
return( ret );
}
}

#endif /* MBEDTLS_SSL_USE_MPS */
Expand Down
21 changes: 21 additions & 0 deletions library/ssl_tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -4471,6 +4471,18 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
else
#endif /* MBEDTLS_SSL_PROTO_DTLS */
{
#if defined(MBEDTLS_SSL_PROTO_QUIC)
if (conf->transport == MBEDTLS_SSL_TRANSPORT_QUIC)
{
mbedtls_quic_input_init(ssl, &ssl->quic_input);
if ((ret = mbedtls_quic_input_setup(ssl, &ssl->quic_input)) != 0)
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_quic_input_setup", ret );
return ret;
}
ssl->quic_hs_crypto_level = MBEDTLS_SSL_CRYPTO_LEVEL_INITIAL;
}
#endif /* MBEDTLS_SSL_PROTO_QUIC */
ssl->out_ctr = ssl->out_buf;
ssl->out_hdr = ssl->out_buf + 8;
ssl->out_len = ssl->out_buf + 11;
Expand Down Expand Up @@ -7918,6 +7930,15 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl )
mbedtls_free( ssl->cli_id );
#endif

#if defined(MBEDTLS_SSL_PROTO_QUIC)
if (ssl->conf != NULL && ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_QUIC)
{
mbedtls_quic_input_free(ssl, &ssl->quic_input);
mbedtls_free(ssl->quic_transport_params);
mbedtls_free(ssl->peer_quic_transport_params);
}
#endif /* MBEDTLS_SSL_PROTO_QUIC */

MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= free" ) );

/* Actually clear after last debug message */
Expand Down
Loading

0 comments on commit 810b7a3

Please sign in to comment.