Add replay detection
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index d48ccf5..76a7515 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -2104,6 +2104,10 @@
}
}
+#if defined(POLARSSL_SSL_DTLS_ANTI_REPLAY)
+static void ssl_dtls_replay_reset( ssl_context *ssl );
+#endif
+
/*
* Swap transform_out and out_ctr with the alternative ones
*/
@@ -2830,7 +2834,7 @@
return( POLARSSL_ERR_SSL_INVALID_RECORD );
}
- /* Check epoch with DTLS */
+ /* Check epoch (and sequence number) with DTLS */
#if defined(POLARSSL_SSL_PROTO_DTLS)
if( ssl->transport == SSL_TRANSPORT_DATAGRAM )
{
@@ -2839,13 +2843,21 @@
if( exp_epoch != rec_epoch )
{
- SSL_DEBUG_MSG( 1, ( "discarding record from another epoch: "
+ SSL_DEBUG_MSG( 1, ( "record from another epoch: "
"expected %d, received %d",
exp_epoch, rec_epoch ) );
- return( POLARSSL_ERR_NET_WANT_READ );
+ return( POLARSSL_ERR_SSL_INVALID_RECORD );
}
- }
+
+#if defined(POLARSSL_SSL_DTLS_ANTI_REPLAY)
+ if( ssl_dtls_replay_check( ssl ) != 0 )
+ {
+ SSL_DEBUG_MSG( 1, ( "replayed record" ) );
+ return( POLARSSL_ERR_SSL_INVALID_RECORD );
+ }
#endif
+ }
+#endif /* POLARSSL_SSL_PROTO_DTLS */
/* Check length against the size of our buffer */
if( ssl->in_msglen > SSL_BUFFER_LEN
@@ -2959,6 +2971,14 @@
}
#endif /* POLARSSL_ZLIB_SUPPORT */
+#if defined(POLARSSL_SSL_PROTO_DTLS) && \
+ defined(POLARSSL_SSL_DTLS_ANTI_REPLAY)
+ if( ssl->transport == SSL_TRANSPORT_DATAGRAM )
+ {
+ ssl_dtls_replay_update( ssl );
+ }
+#endif
+
return( 0 );
}
@@ -4197,8 +4217,9 @@
{
unsigned char i;
- /* Set sequence_number to zero */
- memset( ssl->in_ctr + 2, 0, 6 );
+#if defined(POLARSSL_SSL_DTLS_ANTI_REPLAY)
+ ssl_dtls_replay_reset( ssl );
+#endif
/* Increment epoch */
for( i = 2; i > 0; i-- )
@@ -4547,6 +4568,9 @@
#if defined(POLARSSL_SSL_PROTO_DTLS)
ssl->next_record_offset = 0;
#endif
+#if defined(POLARSSL_SSL_DTLS_ANTI_REPLAY)
+ ssl_dtls_replay_reset( ssl );
+#endif
ssl->in_hslen = 0;
ssl->nb_zero = 0;