Commit 90fd268088 for strongswan.org
commit 90fd268088b3774ec38d9be20872d51a295a49d2
Author: Tobias Brunner <tobias@strongswan.org>
Date: Tue Mar 24 18:00:23 2026 +0100
utils: Add constant-time comparison primitives for uint32_t
diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am
index 79d94be9b8..5a3e503016 100644
--- a/src/libstrongswan/Makefile.am
+++ b/src/libstrongswan/Makefile.am
@@ -138,7 +138,8 @@ utils/parser_helper.h utils/test.h utils/integrity_checker.h utils/process.h \
utils/utils/strerror.h utils/compat/windows.h utils/compat/apple.h utils/compat/android.h \
utils/utils/atomics.h utils/utils/types.h utils/utils/byteorder.h \
utils/utils/string.h utils/utils/memory.h utils/utils/tty.h utils/utils/path.h \
-utils/utils/status.h utils/utils/object.h utils/utils/time.h utils/utils/align.h
+utils/utils/status.h utils/utils/object.h utils/utils/time.h utils/utils/align.h \
+utils/utils/constant_time.h
if USE_VM_SOCKETS
nobase_strongswan_include_HEADERS += \
networking/streams/stream_vsock.h \
diff --git a/src/libstrongswan/utils/utils.h b/src/libstrongswan/utils/utils.h
index 42d01144a2..ab0be7206e 100644
--- a/src/libstrongswan/utils/utils.h
+++ b/src/libstrongswan/utils/utils.h
@@ -53,6 +53,7 @@
#include "utils/atomics.h"
#include "utils/align.h"
#include "utils/byteorder.h"
+#include "utils/constant_time.h"
#include "utils/string.h"
#include "utils/memory.h"
#include "utils/strerror.h"
diff --git a/src/libstrongswan/utils/utils/constant_time.h b/src/libstrongswan/utils/utils/constant_time.h
new file mode 100644
index 0000000000..0c2c6a2e04
--- /dev/null
+++ b/src/libstrongswan/utils/utils/constant_time.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2026 Tobias Brunner
+ *
+ * Copyright (C) secunet Security Networks AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup constant_time_i constant_time
+ * @{ @ingroup constant_time_i
+ */
+
+#ifndef CONSTANT_TIME_H_
+#define CONSTANT_TIME_H_
+
+#include <stdint.h>
+
+/**
+ * Check if the given values are not equal in constant time.
+ *
+ * @param x first value to check
+ * @param y second value to check
+ * @return 1 if values are not equal, 0 otherwise
+ */
+static inline u_int constant_time_neq(uint32_t x, uint32_t y)
+{
+ return ((x-y) | (y-x)) >> 31;
+}
+
+/**
+ * Check if the given values are equal in constant time.
+ *
+ * @param x first value to check
+ * @param y second value to check
+ * @return 1 if values are equal, 0 otherwise
+ */
+static inline u_int constant_time_eq(uint32_t x, uint32_t y)
+{
+ return 1 ^ constant_time_neq(x, y);
+}
+
+/**
+ * Compare the two values and return 1 if the first argument is lower than
+ * the second in constant time.
+ *
+ * @param x first value to check
+ * @param y second value to check
+ * @return 1 if first value is lower than second
+ */
+static inline u_int constant_time_lt(uint32_t x, uint32_t y)
+{
+ return (x ^ ((x^y) | ((x-y) ^ y))) >> 31;
+}
+
+/**
+ * Compare the two values and return 1 if the first argument greater or equal to
+ * the second in constant time.
+ *
+ * @param x first value to check
+ * @param y second value to check
+ * @return 1 if first value is greater or equal to the second
+ */
+static inline u_int constant_time_ge(uint32_t x, uint32_t y)
+{
+ return 1 ^ constant_time_lt(x, y);
+}
+
+/**
+ * Return a 32-bit all bit-set mask if the given value is not 0.
+ *
+ * @param x value to check
+ * @return 0xffffffff if value is != 0, 0 otherwise
+ */
+static inline uint32_t constant_time_mask(uint32_t x)
+{
+ return -(uint32_t)constant_time_neq(x, 0);
+}
+
+/**
+ * Select one of two values depending on whether the condition is != 0 or not.
+ * Basically equivalent to 'c ? x : y'.
+ *
+ * @param x first value to select
+ * @param y second value to select
+ * @param c condition
+ * @return x if c is != 0, y otherwise
+ */
+static inline uint32_t constant_time_select(uint32_t x, uint32_t y, uint32_t c)
+{
+ uint32_t m = constant_time_mask(c);
+ return (x & m) | (y & ~m);
+}
+
+#endif /** CONSTANT_TIME_H_ @} */