[PATCH 01/12] Use single constant-time memory comparison implementation

Jussi Kivilinna jussi.kivilinna at iki.fi
Thu Nov 2 19:01:05 CET 2023


* src/const-time.c (ct_not_memequal): Use original 'buf_eq_const'
implementation here.
(ct_memequal): New.
* cipher/bufhelp.h (buf_eq_const): Call to 'ct_memequal'.
--

Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
 cipher/bufhelp.h | 19 +++----------------
 src/const-time.c | 36 +++++++++++++++++++++++-------------
 src/const-time.h | 13 +++++++++++++
 3 files changed, 39 insertions(+), 29 deletions(-)

diff --git a/cipher/bufhelp.h b/cipher/bufhelp.h
index fa5b2e8e..6dcc622a 100644
--- a/cipher/bufhelp.h
+++ b/cipher/bufhelp.h
@@ -22,6 +22,7 @@
 
 #include "g10lib.h"
 #include "bithelp.h"
+#include "const-time.h"
 
 
 #undef BUFHELP_UNALIGNED_ACCESS
@@ -362,23 +363,9 @@ buf_xor_n_copy(void *_dst_xor, void *_srcdst_cpy, const void *_src, size_t len)
 /* Constant-time compare of two buffers.  Returns 1 if buffers are equal,
    and 0 if buffers differ.  */
 static inline int
-buf_eq_const(const void *_a, const void *_b, size_t len)
+buf_eq_const(const void *a, const void *b, size_t len)
 {
-  const byte *a = _a;
-  const byte *b = _b;
-  int ab, ba;
-  size_t i;
-
-  /* Constant-time compare. */
-  for (i = 0, ab = 0, ba = 0; i < len; i++)
-    {
-      /* If a[i] != b[i], either ab or ba will be negative. */
-      ab |= a[i] - b[i];
-      ba |= b[i] - a[i];
-    }
-
-  /* 'ab | ba' is negative when buffers are not equal. */
-  return (ab | ba) >= 0;
+  return ct_memequal (a, b, len);
 }
 
 
diff --git a/src/const-time.c b/src/const-time.c
index 400af993..fb787a02 100644
--- a/src/const-time.c
+++ b/src/const-time.c
@@ -26,25 +26,35 @@
 /*
  * Compare byte arrays of length LEN, return 1 if it's not same,
  * 0, otherwise.
- *
- * Originally in NetBSD as "consttime_memequal" which is:
- *
- *   Written by Matthias Drochner <drochner at NetBSD.org>.
- *   Public domain.
- *
- * Modified the function name, return type to unsigned,
- * and return value (0 <-> 1).
  */
 unsigned int
 ct_not_memequal (const void *b1, const void *b2, size_t len)
 {
-  const unsigned char *c1 = b1, *c2 = b2;
-  unsigned int res = 0;
+  const byte *a = b1;
+  const byte *b = b2;
+  int ab, ba;
+  size_t i;
+
+  /* Constant-time compare. */
+  for (i = 0, ab = 0, ba = 0; i < len; i++)
+    {
+      /* If a[i] != b[i], either ab or ba will be negative. */
+      ab |= a[i] - b[i];
+      ba |= b[i] - a[i];
+    }
 
-  while (len--)
-    res |= *c1++ ^ *c2++;
+  /* 'ab | ba' is negative when buffers are not equal, extract sign bit.  */
+  return ((unsigned int)(ab | ba) >> (sizeof(unsigned int) * 8 - 1)) & 1;
+}
 
-  return ct_not_equal_byte (res, 0);
+/*
+ * Compare byte arrays of length LEN, return 0 if it's not same,
+ * 1, otherwise.
+ */
+unsigned int
+ct_memequal (const void *b1, const void *b2, size_t len)
+{
+  return ct_not_memequal (b1, b2, len) ^ 1;
 }
 
 /*
diff --git a/src/const-time.h b/src/const-time.h
index 53d7dd2a..defe5ff4 100644
--- a/src/const-time.h
+++ b/src/const-time.h
@@ -17,6 +17,12 @@
  * License along with this program; if not, see <https://www.gnu.org/licenses/>.
  */
 
+#ifndef GCRY_CONST_TIME_H
+#define GCRY_CONST_TIME_H
+
+#include "types.h"
+
+
 /*
  * Return 1 if it's not same, 0 if same.
  */
@@ -40,6 +46,11 @@ ct_not_equal_byte (unsigned char b0, unsigned char b1)
    any structure.  */
 unsigned int ct_not_memequal (const void *b1, const void *b2, size_t len);
 
+/* Compare byte-arrays of length LEN, return 0 if it's not same, 1
+   otherwise.  We use pointer of void *, so that it can be used with
+   any structure.  */
+unsigned int ct_memequal (const void *b1, const void *b2, size_t len);
+
 /*
  *  Return NULL when OP_ENABLED=1
  *  otherwise, return W
@@ -60,3 +71,5 @@ sexp_null_cond (gcry_sexp_t w, unsigned long op_enable)
  */
 void ct_memmov_cond (void *dst, const void *src, size_t len,
                      unsigned long op_enable);
+
+#endif /*GCRY_CONST_TIME_H*/
-- 
2.40.1




More information about the Gcrypt-devel mailing list