Add functions for replay protection
diff --git a/include/polarssl/config.h b/include/polarssl/config.h
index b13a407..20f104d 100644
--- a/include/polarssl/config.h
+++ b/include/polarssl/config.h
@@ -914,6 +914,15 @@
 #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
  *
  * Enable support for Application Layer Protocol Negotiation.
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index 63a7528..5946799 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -822,6 +822,10 @@
     size_t next_record_offset;  /*!< offset of the next record in datagram
                                      (equal to in_left if none)       */
 #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,
                                      including the handshake header   */
@@ -2043,6 +2047,12 @@
 int ssl_resend( ssl_context *ssl );
 #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 */
 static inline int safer_memcmp( const void *a, const void *b, size_t n )
 {
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 8546ed0..31be3ca 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -2695,6 +2695,90 @@
 }
 
 /*
+ * 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;
  * ProtocolVersion version;
  * uint16 epoch;            // DTLS only