]> WPIA git - cassiopeia.git/blobdiff - lib/openssl/ssl/record/dtls1_bitmap.c
upd: openssl to 1.1.0
[cassiopeia.git] / lib / openssl / ssl / record / dtls1_bitmap.c
diff --git a/lib/openssl/ssl/record/dtls1_bitmap.c b/lib/openssl/ssl/record/dtls1_bitmap.c
new file mode 100644 (file)
index 0000000..5923c53
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "../ssl_locl.h"
+#include "record_locl.h"
+
+/* mod 128 saturating subtract of two 64-bit values in big-endian order */
+static int satsub64be(const unsigned char *v1, const unsigned char *v2)
+{
+    int64_t ret;
+    uint64_t l1, l2;
+
+    n2l8(v1, l1);
+    n2l8(v2, l2);
+
+    ret = l1 - l2;
+
+    /* We do not permit wrap-around */
+    if (l1 > l2 && ret < 0)
+        return 128;
+    else if (l2 > l1 && ret > 0)
+        return -128;
+
+    if (ret > 128)
+        return 128;
+    else if (ret < -128)
+        return -128;
+    else
+        return (int)ret;
+}
+
+int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap)
+{
+    int cmp;
+    unsigned int shift;
+    const unsigned char *seq = s->rlayer.read_sequence;
+
+    cmp = satsub64be(seq, bitmap->max_seq_num);
+    if (cmp > 0) {
+        SSL3_RECORD_set_seq_num(RECORD_LAYER_get_rrec(&s->rlayer), seq);
+        return 1;               /* this record in new */
+    }
+    shift = -cmp;
+    if (shift >= sizeof(bitmap->map) * 8)
+        return 0;               /* stale, outside the window */
+    else if (bitmap->map & (1UL << shift))
+        return 0;               /* record previously received */
+
+    SSL3_RECORD_set_seq_num(RECORD_LAYER_get_rrec(&s->rlayer), seq);
+    return 1;
+}
+
+void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap)
+{
+    int cmp;
+    unsigned int shift;
+    const unsigned char *seq = RECORD_LAYER_get_read_sequence(&s->rlayer);
+
+    cmp = satsub64be(seq, bitmap->max_seq_num);
+    if (cmp > 0) {
+        shift = cmp;
+        if (shift < sizeof(bitmap->map) * 8)
+            bitmap->map <<= shift, bitmap->map |= 1UL;
+        else
+            bitmap->map = 1UL;
+        memcpy(bitmap->max_seq_num, seq, SEQ_NUM_SIZE);
+    } else {
+        shift = -cmp;
+        if (shift < sizeof(bitmap->map) * 8)
+            bitmap->map |= 1UL << shift;
+    }
+}