mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-12-24 03:25:35 +00:00
Add functions for replay protection
This commit is contained in:
parent
ea22ce577e
commit
7a7e140d4e
|
@ -913,6 +913,15 @@
|
||||||
*/
|
*/
|
||||||
#define POLARSSL_SSL_PROTO_DTLS
|
#define POLARSSL_SSL_PROTO_DTLS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_SSL_DTLS_ANTI_REPLAY
|
||||||
|
*
|
||||||
|
* Enable support for the anti-replay mechanism in DTLS.
|
||||||
|
*
|
||||||
|
* Comment this to disable anti-replay in DTLS.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_SSL_DTLS_ANTI_REPLAY
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \def POLARSSL_SSL_ALPN
|
* \def POLARSSL_SSL_ALPN
|
||||||
*
|
*
|
||||||
|
|
|
@ -822,6 +822,10 @@ struct _ssl_context
|
||||||
size_t next_record_offset; /*!< offset of the next record in datagram
|
size_t next_record_offset; /*!< offset of the next record in datagram
|
||||||
(equal to in_left if none) */
|
(equal to in_left if none) */
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(POLARSSL_SSL_DTLS_ANTI_REPLAY)
|
||||||
|
uint64_t in_window_top; /*!< last validated record seq_num */
|
||||||
|
uint64_t in_window; /*!< bitmask for replay detection */
|
||||||
|
#endif
|
||||||
|
|
||||||
size_t in_hslen; /*!< current handshake message length,
|
size_t in_hslen; /*!< current handshake message length,
|
||||||
including the handshake header */
|
including the handshake header */
|
||||||
|
@ -2043,6 +2047,12 @@ void ssl_recv_flight_completed( ssl_context *ssl );
|
||||||
int ssl_resend( ssl_context *ssl );
|
int ssl_resend( ssl_context *ssl );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Visible for testing purposes only */
|
||||||
|
#if defined(POLARSSL_SSL_DTLS_ANTI_REPLAY)
|
||||||
|
int ssl_dtls_replay_check( ssl_context *ssl );
|
||||||
|
void ssl_dtls_replay_update( ssl_context *ssl );
|
||||||
|
#endif
|
||||||
|
|
||||||
/* constant-time buffer comparison */
|
/* constant-time buffer comparison */
|
||||||
static inline int safer_memcmp( const void *a, const void *b, size_t n )
|
static inline int safer_memcmp( const void *a, const void *b, size_t n )
|
||||||
{
|
{
|
||||||
|
|
|
@ -2694,6 +2694,90 @@ static int ssl_prepare_handshake_record( ssl_context *ssl )
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DTLS anti-replay: RFC 6347 4.1.2.6
|
||||||
|
*
|
||||||
|
* - in_window_top is the highest record sequence number seen
|
||||||
|
* - the lsb of in_window is set iff in_window_top - 1 has been seen
|
||||||
|
* ...
|
||||||
|
* the msb of in_window is set iff in_window_top - 64 has been seen
|
||||||
|
*/
|
||||||
|
#if defined(POLARSSL_SSL_DTLS_ANTI_REPLAY)
|
||||||
|
static void ssl_dtls_replay_reset( ssl_context *ssl )
|
||||||
|
{
|
||||||
|
ssl->in_window_top = 0;
|
||||||
|
ssl->in_window = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t ssl_load_six_bytes( unsigned char *buf )
|
||||||
|
{
|
||||||
|
return( ( (uint64_t) buf[0] << 40 ) |
|
||||||
|
( (uint64_t) buf[1] << 32 ) |
|
||||||
|
( (uint64_t) buf[2] << 24 ) |
|
||||||
|
( (uint64_t) buf[3] << 16 ) |
|
||||||
|
( (uint64_t) buf[4] << 8 ) |
|
||||||
|
( (uint64_t) buf[5] ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return 0 if sequence number is acceptable, -1 otherwise
|
||||||
|
*/
|
||||||
|
int ssl_dtls_replay_check( ssl_context *ssl )
|
||||||
|
{
|
||||||
|
uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
|
||||||
|
uint64_t bit;
|
||||||
|
|
||||||
|
if( rec_seqnum > ssl->in_window_top )
|
||||||
|
return( 0 );
|
||||||
|
|
||||||
|
if( rec_seqnum == ssl->in_window_top )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
bit = ssl->in_window_top - rec_seqnum - 1;
|
||||||
|
|
||||||
|
if( bit >= 64 )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
if( ( ssl->in_window & ( (uint64_t) 1 << bit ) ) != 0 )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update replay window on new validated record
|
||||||
|
*/
|
||||||
|
void ssl_dtls_replay_update( ssl_context *ssl )
|
||||||
|
{
|
||||||
|
uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
|
||||||
|
|
||||||
|
if( rec_seqnum > ssl->in_window_top )
|
||||||
|
{
|
||||||
|
/* Update window_top and the contents of the window */
|
||||||
|
uint64_t shift = rec_seqnum - ssl->in_window_top;
|
||||||
|
|
||||||
|
if( shift >= 64 )
|
||||||
|
ssl->in_window = 0;
|
||||||
|
else
|
||||||
|
ssl->in_window <<= shift;
|
||||||
|
|
||||||
|
ssl->in_window_top = rec_seqnum;
|
||||||
|
}
|
||||||
|
else if( rec_seqnum == ssl->in_window_top )
|
||||||
|
{
|
||||||
|
; /* Can't happen, but anyway, nothing to do if it happened */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Mark that number as seen in the current window */
|
||||||
|
uint64_t bit = ssl->in_window_top - rec_seqnum - 1;
|
||||||
|
|
||||||
|
if( bit < 64 ) /* Always true, but be extra sure */
|
||||||
|
ssl->in_window |= (uint64_t) 1 << bit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* POLARSSL_SSL_DTLS_ANTI_REPLAY */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ContentType type;
|
* ContentType type;
|
||||||
* ProtocolVersion version;
|
* ProtocolVersion version;
|
||||||
|
|
Loading…
Reference in a new issue