From 7f8089b2ecb9c66f66d9e1e717ad41932296dc86 Mon Sep 17 00:00:00 2001 From: Arto Kinnunen Date: Tue, 29 Oct 2019 11:13:33 +0200 Subject: [PATCH] Fix mbedtls_ssl_check_record usage with ext buf Record checking fails if mbedtls_ssl_check_record() is called with external buffer. Received record sequence number is available in the incoming record but it is not available in the ssl contexts `in_ctr`- variable that is used when decoding the sequence number. To fix the problem, temporarily update ssl context `in_ctr` to point to the received record header and restore value later. --- library/ssl_tls.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 4e7c01bc9..dc39a96d7 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -4878,6 +4878,25 @@ static inline uint64_t ssl_load_six_bytes( unsigned char *buf ) ( (uint64_t) buf[5] ) ); } +static int mbedtls_ssl_dtls_record_replay_check( mbedtls_ssl_context *ssl, uint8_t *record_in_ctr ) +{ + int ret; + unsigned char *original_in_ctr; + + // save original in_ctr + original_in_ctr = ssl->in_ctr; + + // use counter from record + ssl->in_ctr = record_in_ctr; + + ret = mbedtls_ssl_dtls_replay_check( (mbedtls_ssl_context const *) ssl ); + + // restore the counter + ssl->in_ctr = original_in_ctr; + + return ret; +} + /* * Return 0 if sequence number is acceptable, -1 otherwise */ @@ -5383,7 +5402,8 @@ static int ssl_parse_record_header( mbedtls_ssl_context const *ssl, #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) /* For records from the correct epoch, check whether their * sequence number has been seen before. */ - else if( mbedtls_ssl_dtls_replay_check( ssl ) != 0 ) + else if( mbedtls_ssl_dtls_record_replay_check( (mbedtls_ssl_context *) ssl, + &rec->ctr[0] ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) ); return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );