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.
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 85bcffb..2d340d5 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4918,6 +4918,25 @@
( (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
*/
@@ -5433,7 +5452,8 @@
#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 );