From 1372335d3087728ce622ecc262a88fe79a51b28f Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 22 Jun 2026 17:30:11 +0200 Subject: [PATCH] constant-time: Add 64-bit versions of the helpers While we could use _Generic() C11 expression to let the compiler select between the different versions, this only allows selection based on one of the arguments, which seems a bit fragile. So make this explicit for now. In the future we might consider using the overloadable attribute. --- src/libstrongswan/utils/utils/constant_time.h | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/src/libstrongswan/utils/utils/constant_time.h b/src/libstrongswan/utils/utils/constant_time.h index ea50b69ff..7711d52b9 100644 --- a/src/libstrongswan/utils/utils/constant_time.h +++ b/src/libstrongswan/utils/utils/constant_time.h @@ -36,6 +36,18 @@ 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 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_neq64(uint64_t x, uint64_t y) +{ + return ((x-y) | (y-x)) >> 63; +} + /** * Check if the given values are equal in constant time. * @@ -48,6 +60,18 @@ static inline u_int constant_time_eq(uint32_t x, uint32_t y) return 1 ^ constant_time_neq(x, y); } +/** + * 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_eq64(uint64_t x, uint64_t y) +{ + return 1 ^ constant_time_neq64(x, y); +} + /** * Compare the two values and return 1 if the first argument is lower than * the second in constant time. @@ -61,6 +85,19 @@ 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 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_lt64(uint64_t x, uint64_t y) +{ + return (x ^ ((x^y) | ((x-y) ^ y))) >> 63; +} + /** * Compare the two values and return 1 if the first argument greater or equal to * the second in constant time. @@ -74,6 +111,19 @@ static inline u_int constant_time_ge(uint32_t x, uint32_t y) return 1 ^ constant_time_lt(x, y); } +/** + * 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_ge64(uint64_t x, uint64_t y) +{ + return 1 ^ constant_time_lt64(x, y); +} + /** * Return a 32-bit all bit-set mask if the given value is not 0. * @@ -85,6 +135,17 @@ static inline uint32_t constant_time_mask(uint32_t x) return -(uint32_t)constant_time_neq(x, 0); } +/** + * Return a 64-bit all bit-set mask if the given value is not 0. + * + * @param x value to check + * @return 0xffffffffffffffff if value is != 0, 0 otherwise + */ +static inline uint64_t constant_time_mask64(uint64_t x) +{ + return -(uint64_t)constant_time_neq64(x, 0); +} + /** * Select one of two values depending on whether the condition is != 0 or not. * Basically equivalent to 'c ? x : y'. @@ -100,4 +161,19 @@ static inline uint32_t constant_time_select(uint32_t x, uint32_t y, uint32_t c) return (x & m) | (y & ~m); } +/** + * 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 uint64_t constant_time_select64(uint64_t x, uint64_t y, uint64_t c) +{ + uint64_t m = constant_time_mask64(c); + return (x & m) | (y & ~m); +} + #endif /** CONSTANT_TIME_H_ @} */