1039e02dfSJerome Forissier /** 2039e02dfSJerome Forissier * Constant-time functions 3039e02dfSJerome Forissier * 4039e02dfSJerome Forissier * Copyright The Mbed TLS Contributors 5*b0563631STom Van Eyck * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 6039e02dfSJerome Forissier */ 7039e02dfSJerome Forissier 8039e02dfSJerome Forissier #ifndef MBEDTLS_CONSTANT_TIME_INTERNAL_H 9039e02dfSJerome Forissier #define MBEDTLS_CONSTANT_TIME_INTERNAL_H 10039e02dfSJerome Forissier 11*b0563631STom Van Eyck #include <stdint.h> 12*b0563631STom Van Eyck #include <stddef.h> 13*b0563631STom Van Eyck 14039e02dfSJerome Forissier #include "common.h" 15039e02dfSJerome Forissier 16039e02dfSJerome Forissier #if defined(MBEDTLS_BIGNUM_C) 17039e02dfSJerome Forissier #include "mbedtls/bignum.h" 18039e02dfSJerome Forissier #endif 19039e02dfSJerome Forissier 20*b0563631STom Van Eyck /* The constant-time interface provides various operations that are likely 21*b0563631STom Van Eyck * to result in constant-time code that does not branch or use conditional 22*b0563631STom Van Eyck * instructions for secret data (for secret pointers, this also applies to 23*b0563631STom Van Eyck * the data pointed to). 24*b0563631STom Van Eyck * 25*b0563631STom Van Eyck * It has three main parts: 26*b0563631STom Van Eyck * 27*b0563631STom Van Eyck * - boolean operations 28*b0563631STom Van Eyck * These are all named mbedtls_ct_<type>_<operation>. 29*b0563631STom Van Eyck * They operate over <type> and return mbedtls_ct_condition_t. 30*b0563631STom Van Eyck * All arguments are considered secret. 31*b0563631STom Van Eyck * example: bool x = y | z => x = mbedtls_ct_bool_or(y, z) 32*b0563631STom Van Eyck * example: bool x = y == z => x = mbedtls_ct_uint_eq(y, z) 33*b0563631STom Van Eyck * 34*b0563631STom Van Eyck * - conditional data selection 35*b0563631STom Van Eyck * These are all named mbedtls_ct_<type>_if and mbedtls_ct_<type>_if_else_0 36*b0563631STom Van Eyck * All arguments are considered secret. 37*b0563631STom Van Eyck * example: size_t a = x ? b : c => a = mbedtls_ct_size_if(x, b, c) 38*b0563631STom Van Eyck * example: unsigned a = x ? b : 0 => a = mbedtls_ct_uint_if_else_0(x, b) 39*b0563631STom Van Eyck * 40*b0563631STom Van Eyck * - block memory operations 41*b0563631STom Van Eyck * Only some arguments are considered secret, as documented for each 42*b0563631STom Van Eyck * function. 43*b0563631STom Van Eyck * example: if (x) memcpy(...) => mbedtls_ct_memcpy_if(x, ...) 44*b0563631STom Van Eyck * 45*b0563631STom Van Eyck * mbedtls_ct_condition_t must be treated as opaque and only created and 46*b0563631STom Van Eyck * manipulated via the functions in this header. The compiler should never 47*b0563631STom Van Eyck * be able to prove anything about its value at compile-time. 48*b0563631STom Van Eyck * 49*b0563631STom Van Eyck * mbedtls_ct_uint_t is an unsigned integer type over which constant time 50*b0563631STom Van Eyck * operations may be performed via the functions in this header. It is as big 51*b0563631STom Van Eyck * as the larger of size_t and mbedtls_mpi_uint, i.e. it is safe to cast 52*b0563631STom Van Eyck * to/from "unsigned int", "size_t", and "mbedtls_mpi_uint" (and any other 53*b0563631STom Van Eyck * not-larger integer types). 54*b0563631STom Van Eyck * 55*b0563631STom Van Eyck * For Arm (32-bit, 64-bit and Thumb), x86 and x86-64, assembly implementations 56*b0563631STom Van Eyck * are used to ensure that the generated code is constant time. For other 57*b0563631STom Van Eyck * architectures, it uses a plain C fallback designed to yield constant-time code 58*b0563631STom Van Eyck * (this has been observed to be constant-time on latest gcc, clang and MSVC 59*b0563631STom Van Eyck * as of May 2023). 60*b0563631STom Van Eyck * 61*b0563631STom Van Eyck * For readability, the static inline definitions are separated out into 62*b0563631STom Van Eyck * constant_time_impl.h. 63*b0563631STom Van Eyck */ 64*b0563631STom Van Eyck 65*b0563631STom Van Eyck #if (SIZE_MAX > 0xffffffffffffffffULL) 66*b0563631STom Van Eyck /* Pointer size > 64-bit */ 67*b0563631STom Van Eyck typedef size_t mbedtls_ct_condition_t; 68*b0563631STom Van Eyck typedef size_t mbedtls_ct_uint_t; 69*b0563631STom Van Eyck typedef ptrdiff_t mbedtls_ct_int_t; 70*b0563631STom Van Eyck #define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(SIZE_MAX)) 71*b0563631STom Van Eyck #elif (SIZE_MAX > 0xffffffff) || defined(MBEDTLS_HAVE_INT64) 72*b0563631STom Van Eyck /* 32-bit < pointer size <= 64-bit, or 64-bit MPI */ 73*b0563631STom Van Eyck typedef uint64_t mbedtls_ct_condition_t; 74*b0563631STom Van Eyck typedef uint64_t mbedtls_ct_uint_t; 75*b0563631STom Van Eyck typedef int64_t mbedtls_ct_int_t; 76*b0563631STom Van Eyck #define MBEDTLS_CT_SIZE_64 77*b0563631STom Van Eyck #define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT64_MAX)) 78*b0563631STom Van Eyck #else 79*b0563631STom Van Eyck /* Pointer size <= 32-bit, and no 64-bit MPIs */ 80*b0563631STom Van Eyck typedef uint32_t mbedtls_ct_condition_t; 81*b0563631STom Van Eyck typedef uint32_t mbedtls_ct_uint_t; 82*b0563631STom Van Eyck typedef int32_t mbedtls_ct_int_t; 83*b0563631STom Van Eyck #define MBEDTLS_CT_SIZE_32 84*b0563631STom Van Eyck #define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT32_MAX)) 85039e02dfSJerome Forissier #endif 86*b0563631STom Van Eyck #define MBEDTLS_CT_FALSE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(0)) 87039e02dfSJerome Forissier 88*b0563631STom Van Eyck /* ============================================================================ 89*b0563631STom Van Eyck * Boolean operations 90039e02dfSJerome Forissier */ 91039e02dfSJerome Forissier 92*b0563631STom Van Eyck /** Convert a number into a mbedtls_ct_condition_t. 93039e02dfSJerome Forissier * 94*b0563631STom Van Eyck * \param x Number to convert. 95039e02dfSJerome Forissier * 96*b0563631STom Van Eyck * \return MBEDTLS_CT_TRUE if \p x != 0, or MBEDTLS_CT_FALSE if \p x == 0 97039e02dfSJerome Forissier * 98039e02dfSJerome Forissier */ 99*b0563631STom Van Eyck static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x); 100039e02dfSJerome Forissier 101*b0563631STom Van Eyck /** Boolean "not equal" operation. 102039e02dfSJerome Forissier * 103*b0563631STom Van Eyck * Functionally equivalent to: 104039e02dfSJerome Forissier * 105*b0563631STom Van Eyck * \p x != \p y 106039e02dfSJerome Forissier * 107039e02dfSJerome Forissier * \param x The first value to analyze. 108039e02dfSJerome Forissier * \param y The second value to analyze. 109039e02dfSJerome Forissier * 110*b0563631STom Van Eyck * \return MBEDTLS_CT_TRUE if \p x != \p y, otherwise MBEDTLS_CT_FALSE. 111039e02dfSJerome Forissier */ 112*b0563631STom Van Eyck static inline mbedtls_ct_condition_t mbedtls_ct_uint_ne(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y); 113039e02dfSJerome Forissier 114*b0563631STom Van Eyck /** Boolean "equals" operation. 115039e02dfSJerome Forissier * 116*b0563631STom Van Eyck * Functionally equivalent to: 117*b0563631STom Van Eyck * 118*b0563631STom Van Eyck * \p x == \p y 119039e02dfSJerome Forissier * 120039e02dfSJerome Forissier * \param x The first value to analyze. 121039e02dfSJerome Forissier * \param y The second value to analyze. 122039e02dfSJerome Forissier * 123*b0563631STom Van Eyck * \return MBEDTLS_CT_TRUE if \p x == \p y, otherwise MBEDTLS_CT_FALSE. 124039e02dfSJerome Forissier */ 125*b0563631STom Van Eyck static inline mbedtls_ct_condition_t mbedtls_ct_uint_eq(mbedtls_ct_uint_t x, 126*b0563631STom Van Eyck mbedtls_ct_uint_t y); 127039e02dfSJerome Forissier 128*b0563631STom Van Eyck /** Boolean "less than" operation. 129039e02dfSJerome Forissier * 130*b0563631STom Van Eyck * Functionally equivalent to: 131*b0563631STom Van Eyck * 132*b0563631STom Van Eyck * \p x < \p y 133039e02dfSJerome Forissier * 134039e02dfSJerome Forissier * \param x The first value to analyze. 135039e02dfSJerome Forissier * \param y The second value to analyze. 136039e02dfSJerome Forissier * 137*b0563631STom Van Eyck * \return MBEDTLS_CT_TRUE if \p x < \p y, otherwise MBEDTLS_CT_FALSE. 138039e02dfSJerome Forissier */ 139*b0563631STom Van Eyck static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y); 140039e02dfSJerome Forissier 141*b0563631STom Van Eyck /** Boolean "greater than" operation. 14232b31808SJens Wiklander * 143*b0563631STom Van Eyck * Functionally equivalent to: 14432b31808SJens Wiklander * 145*b0563631STom Van Eyck * \p x > \p y 146*b0563631STom Van Eyck * 147*b0563631STom Van Eyck * \param x The first value to analyze. 148*b0563631STom Van Eyck * \param y The second value to analyze. 149*b0563631STom Van Eyck * 150*b0563631STom Van Eyck * \return MBEDTLS_CT_TRUE if \p x > \p y, otherwise MBEDTLS_CT_FALSE. 15132b31808SJens Wiklander */ 152*b0563631STom Van Eyck static inline mbedtls_ct_condition_t mbedtls_ct_uint_gt(mbedtls_ct_uint_t x, 153*b0563631STom Van Eyck mbedtls_ct_uint_t y); 154039e02dfSJerome Forissier 155*b0563631STom Van Eyck /** Boolean "greater or equal" operation. 156039e02dfSJerome Forissier * 157*b0563631STom Van Eyck * Functionally equivalent to: 158*b0563631STom Van Eyck * 159*b0563631STom Van Eyck * \p x >= \p y 160*b0563631STom Van Eyck * 161*b0563631STom Van Eyck * \param x The first value to analyze. 162*b0563631STom Van Eyck * \param y The second value to analyze. 163*b0563631STom Van Eyck * 164*b0563631STom Van Eyck * \return MBEDTLS_CT_TRUE if \p x >= \p y, 165*b0563631STom Van Eyck * otherwise MBEDTLS_CT_FALSE. 166*b0563631STom Van Eyck */ 167*b0563631STom Van Eyck static inline mbedtls_ct_condition_t mbedtls_ct_uint_ge(mbedtls_ct_uint_t x, 168*b0563631STom Van Eyck mbedtls_ct_uint_t y); 169*b0563631STom Van Eyck 170*b0563631STom Van Eyck /** Boolean "less than or equal" operation. 171*b0563631STom Van Eyck * 172*b0563631STom Van Eyck * Functionally equivalent to: 173*b0563631STom Van Eyck * 174*b0563631STom Van Eyck * \p x <= \p y 175*b0563631STom Van Eyck * 176*b0563631STom Van Eyck * \param x The first value to analyze. 177*b0563631STom Van Eyck * \param y The second value to analyze. 178*b0563631STom Van Eyck * 179*b0563631STom Van Eyck * \return MBEDTLS_CT_TRUE if \p x <= \p y, 180*b0563631STom Van Eyck * otherwise MBEDTLS_CT_FALSE. 181*b0563631STom Van Eyck */ 182*b0563631STom Van Eyck static inline mbedtls_ct_condition_t mbedtls_ct_uint_le(mbedtls_ct_uint_t x, 183*b0563631STom Van Eyck mbedtls_ct_uint_t y); 184*b0563631STom Van Eyck 185*b0563631STom Van Eyck /** Boolean not-equals operation. 186*b0563631STom Van Eyck * 187*b0563631STom Van Eyck * Functionally equivalent to: 188*b0563631STom Van Eyck * 189*b0563631STom Van Eyck * \p x != \p y 190*b0563631STom Van Eyck * 191*b0563631STom Van Eyck * \param x The first value to analyze. 192*b0563631STom Van Eyck * \param y The second value to analyze. 193*b0563631STom Van Eyck * 194*b0563631STom Van Eyck * \note This is more efficient than mbedtls_ct_uint_ne if both arguments are 195*b0563631STom Van Eyck * mbedtls_ct_condition_t. 196*b0563631STom Van Eyck * 197*b0563631STom Van Eyck * \return MBEDTLS_CT_TRUE if \p x != \p y, 198*b0563631STom Van Eyck * otherwise MBEDTLS_CT_FALSE. 199*b0563631STom Van Eyck */ 200*b0563631STom Van Eyck static inline mbedtls_ct_condition_t mbedtls_ct_bool_ne(mbedtls_ct_condition_t x, 201*b0563631STom Van Eyck mbedtls_ct_condition_t y); 202*b0563631STom Van Eyck 203*b0563631STom Van Eyck /** Boolean "and" operation. 204*b0563631STom Van Eyck * 205*b0563631STom Van Eyck * Functionally equivalent to: 206*b0563631STom Van Eyck * 207*b0563631STom Van Eyck * \p x && \p y 208*b0563631STom Van Eyck * 209*b0563631STom Van Eyck * \param x The first value to analyze. 210*b0563631STom Van Eyck * \param y The second value to analyze. 211*b0563631STom Van Eyck * 212*b0563631STom Van Eyck * \return MBEDTLS_CT_TRUE if \p x && \p y, 213*b0563631STom Van Eyck * otherwise MBEDTLS_CT_FALSE. 214*b0563631STom Van Eyck */ 215*b0563631STom Van Eyck static inline mbedtls_ct_condition_t mbedtls_ct_bool_and(mbedtls_ct_condition_t x, 216*b0563631STom Van Eyck mbedtls_ct_condition_t y); 217*b0563631STom Van Eyck 218*b0563631STom Van Eyck /** Boolean "or" operation. 219*b0563631STom Van Eyck * 220*b0563631STom Van Eyck * Functionally equivalent to: 221*b0563631STom Van Eyck * 222*b0563631STom Van Eyck * \p x || \p y 223*b0563631STom Van Eyck * 224*b0563631STom Van Eyck * \param x The first value to analyze. 225*b0563631STom Van Eyck * \param y The second value to analyze. 226*b0563631STom Van Eyck * 227*b0563631STom Van Eyck * \return MBEDTLS_CT_TRUE if \p x || \p y, 228*b0563631STom Van Eyck * otherwise MBEDTLS_CT_FALSE. 229*b0563631STom Van Eyck */ 230*b0563631STom Van Eyck static inline mbedtls_ct_condition_t mbedtls_ct_bool_or(mbedtls_ct_condition_t x, 231*b0563631STom Van Eyck mbedtls_ct_condition_t y); 232*b0563631STom Van Eyck 233*b0563631STom Van Eyck /** Boolean "not" operation. 234*b0563631STom Van Eyck * 235*b0563631STom Van Eyck * Functionally equivalent to: 236*b0563631STom Van Eyck * 237*b0563631STom Van Eyck * ! \p x 238*b0563631STom Van Eyck * 239*b0563631STom Van Eyck * \param x The value to invert 240*b0563631STom Van Eyck * 241*b0563631STom Van Eyck * \return MBEDTLS_CT_FALSE if \p x, otherwise MBEDTLS_CT_TRUE. 242*b0563631STom Van Eyck */ 243*b0563631STom Van Eyck static inline mbedtls_ct_condition_t mbedtls_ct_bool_not(mbedtls_ct_condition_t x); 244*b0563631STom Van Eyck 245*b0563631STom Van Eyck 246*b0563631STom Van Eyck /* ============================================================================ 247*b0563631STom Van Eyck * Data selection operations 248*b0563631STom Van Eyck */ 249*b0563631STom Van Eyck 250*b0563631STom Van Eyck /** Choose between two size_t values. 251*b0563631STom Van Eyck * 252*b0563631STom Van Eyck * Functionally equivalent to: 253*b0563631STom Van Eyck * 254*b0563631STom Van Eyck * condition ? if1 : if0. 255039e02dfSJerome Forissier * 256039e02dfSJerome Forissier * \param condition Condition to test. 257*b0563631STom Van Eyck * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. 258*b0563631STom Van Eyck * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE. 259039e02dfSJerome Forissier * 260*b0563631STom Van Eyck * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0. 261039e02dfSJerome Forissier */ 262*b0563631STom Van Eyck static inline size_t mbedtls_ct_size_if(mbedtls_ct_condition_t condition, 263*b0563631STom Van Eyck size_t if1, 264*b0563631STom Van Eyck size_t if0); 265*b0563631STom Van Eyck 266*b0563631STom Van Eyck /** Choose between two unsigned values. 267*b0563631STom Van Eyck * 268*b0563631STom Van Eyck * Functionally equivalent to: 269*b0563631STom Van Eyck * 270*b0563631STom Van Eyck * condition ? if1 : if0. 271*b0563631STom Van Eyck * 272*b0563631STom Van Eyck * \param condition Condition to test. 273*b0563631STom Van Eyck * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. 274*b0563631STom Van Eyck * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE. 275*b0563631STom Van Eyck * 276*b0563631STom Van Eyck * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0. 277*b0563631STom Van Eyck */ 278*b0563631STom Van Eyck static inline unsigned mbedtls_ct_uint_if(mbedtls_ct_condition_t condition, 279039e02dfSJerome Forissier unsigned if1, 280039e02dfSJerome Forissier unsigned if0); 281039e02dfSJerome Forissier 282*b0563631STom Van Eyck /** Choose between two mbedtls_ct_condition_t values. 283*b0563631STom Van Eyck * 284*b0563631STom Van Eyck * Functionally equivalent to: 285*b0563631STom Van Eyck * 286*b0563631STom Van Eyck * condition ? if1 : if0. 287*b0563631STom Van Eyck * 288*b0563631STom Van Eyck * \param condition Condition to test. 289*b0563631STom Van Eyck * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. 290*b0563631STom Van Eyck * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE. 291*b0563631STom Van Eyck * 292*b0563631STom Van Eyck * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0. 293*b0563631STom Van Eyck */ 294*b0563631STom Van Eyck static inline mbedtls_ct_condition_t mbedtls_ct_bool_if(mbedtls_ct_condition_t condition, 295*b0563631STom Van Eyck mbedtls_ct_condition_t if1, 296*b0563631STom Van Eyck mbedtls_ct_condition_t if0); 297*b0563631STom Van Eyck 298039e02dfSJerome Forissier #if defined(MBEDTLS_BIGNUM_C) 299039e02dfSJerome Forissier 300*b0563631STom Van Eyck /** Choose between two mbedtls_mpi_uint values. 301039e02dfSJerome Forissier * 302*b0563631STom Van Eyck * Functionally equivalent to: 303039e02dfSJerome Forissier * 304*b0563631STom Van Eyck * condition ? if1 : if0. 305*b0563631STom Van Eyck * 306*b0563631STom Van Eyck * \param condition Condition to test. 307*b0563631STom Van Eyck * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. 308*b0563631STom Van Eyck * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE. 309*b0563631STom Van Eyck * 310*b0563631STom Van Eyck * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0. 311039e02dfSJerome Forissier */ 312*b0563631STom Van Eyck static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if(mbedtls_ct_condition_t condition, \ 313*b0563631STom Van Eyck mbedtls_mpi_uint if1, \ 314*b0563631STom Van Eyck mbedtls_mpi_uint if0); 315039e02dfSJerome Forissier 316*b0563631STom Van Eyck #endif 317039e02dfSJerome Forissier 318*b0563631STom Van Eyck /** Choose between an unsigned value and 0. 319039e02dfSJerome Forissier * 320*b0563631STom Van Eyck * Functionally equivalent to: 321039e02dfSJerome Forissier * 322*b0563631STom Van Eyck * condition ? if1 : 0. 323039e02dfSJerome Forissier * 324*b0563631STom Van Eyck * Functionally equivalent to mbedtls_ct_uint_if(condition, if1, 0) but 325*b0563631STom Van Eyck * results in smaller code size. 326*b0563631STom Van Eyck * 327*b0563631STom Van Eyck * \param condition Condition to test. 328*b0563631STom Van Eyck * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. 329*b0563631STom Van Eyck * 330*b0563631STom Van Eyck * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0. 331039e02dfSJerome Forissier */ 332*b0563631STom Van Eyck static inline unsigned mbedtls_ct_uint_if_else_0(mbedtls_ct_condition_t condition, unsigned if1); 333039e02dfSJerome Forissier 334*b0563631STom Van Eyck /** Choose between an mbedtls_ct_condition_t and 0. 335039e02dfSJerome Forissier * 336*b0563631STom Van Eyck * Functionally equivalent to: 337039e02dfSJerome Forissier * 338*b0563631STom Van Eyck * condition ? if1 : 0. 339039e02dfSJerome Forissier * 340*b0563631STom Van Eyck * Functionally equivalent to mbedtls_ct_bool_if(condition, if1, 0) but 341*b0563631STom Van Eyck * results in smaller code size. 342039e02dfSJerome Forissier * 343*b0563631STom Van Eyck * \param condition Condition to test. 344*b0563631STom Van Eyck * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. 345*b0563631STom Van Eyck * 346*b0563631STom Van Eyck * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0. 347039e02dfSJerome Forissier */ 348*b0563631STom Van Eyck static inline mbedtls_ct_condition_t mbedtls_ct_bool_if_else_0(mbedtls_ct_condition_t condition, 349*b0563631STom Van Eyck mbedtls_ct_condition_t if1); 350039e02dfSJerome Forissier 351*b0563631STom Van Eyck /** Choose between a size_t value and 0. 352039e02dfSJerome Forissier * 353*b0563631STom Van Eyck * Functionally equivalent to: 354039e02dfSJerome Forissier * 355*b0563631STom Van Eyck * condition ? if1 : 0. 356*b0563631STom Van Eyck * 357*b0563631STom Van Eyck * Functionally equivalent to mbedtls_ct_size_if(condition, if1, 0) but 358*b0563631STom Van Eyck * results in smaller code size. 359*b0563631STom Van Eyck * 360*b0563631STom Van Eyck * \param condition Condition to test. 361*b0563631STom Van Eyck * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. 362*b0563631STom Van Eyck * 363*b0563631STom Van Eyck * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0. 364039e02dfSJerome Forissier */ 365*b0563631STom Van Eyck static inline size_t mbedtls_ct_size_if_else_0(mbedtls_ct_condition_t condition, size_t if1); 366039e02dfSJerome Forissier 367*b0563631STom Van Eyck #if defined(MBEDTLS_BIGNUM_C) 368*b0563631STom Van Eyck 369*b0563631STom Van Eyck /** Choose between an mbedtls_mpi_uint value and 0. 370039e02dfSJerome Forissier * 371*b0563631STom Van Eyck * Functionally equivalent to: 372*b0563631STom Van Eyck * 373*b0563631STom Van Eyck * condition ? if1 : 0. 374*b0563631STom Van Eyck * 375*b0563631STom Van Eyck * Functionally equivalent to mbedtls_ct_mpi_uint_if(condition, if1, 0) but 376*b0563631STom Van Eyck * results in smaller code size. 377*b0563631STom Van Eyck * 378*b0563631STom Van Eyck * \param condition Condition to test. 379*b0563631STom Van Eyck * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. 380*b0563631STom Van Eyck * 381*b0563631STom Van Eyck * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0. 382*b0563631STom Van Eyck */ 383*b0563631STom Van Eyck static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if_else_0(mbedtls_ct_condition_t condition, 384*b0563631STom Van Eyck mbedtls_mpi_uint if1); 385*b0563631STom Van Eyck 386*b0563631STom Van Eyck #endif 387*b0563631STom Van Eyck 388*b0563631STom Van Eyck /** Constant-flow char selection 389*b0563631STom Van Eyck * 390*b0563631STom Van Eyck * \param low Secret. Bottom of range 391*b0563631STom Van Eyck * \param high Secret. Top of range 392*b0563631STom Van Eyck * \param c Secret. Value to compare to range 393*b0563631STom Van Eyck * \param t Secret. Value to return, if in range 394*b0563631STom Van Eyck * 395*b0563631STom Van Eyck * \return \p t if \p low <= \p c <= \p high, 0 otherwise. 396*b0563631STom Van Eyck */ 397*b0563631STom Van Eyck static inline unsigned char mbedtls_ct_uchar_in_range_if(unsigned char low, 398*b0563631STom Van Eyck unsigned char high, 399*b0563631STom Van Eyck unsigned char c, 400*b0563631STom Van Eyck unsigned char t); 401*b0563631STom Van Eyck 402*b0563631STom Van Eyck /** Choose between two error values. The values must be in the range [-32767..0]. 403*b0563631STom Van Eyck * 404*b0563631STom Van Eyck * Functionally equivalent to: 405*b0563631STom Van Eyck * 406*b0563631STom Van Eyck * condition ? if1 : if0. 407*b0563631STom Van Eyck * 408*b0563631STom Van Eyck * \param condition Condition to test. 409*b0563631STom Van Eyck * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. 410*b0563631STom Van Eyck * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE. 411*b0563631STom Van Eyck * 412*b0563631STom Van Eyck * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0. 413*b0563631STom Van Eyck */ 414*b0563631STom Van Eyck static inline int mbedtls_ct_error_if(mbedtls_ct_condition_t condition, int if1, int if0); 415*b0563631STom Van Eyck 416*b0563631STom Van Eyck /** Choose between an error value and 0. The error value must be in the range [-32767..0]. 417*b0563631STom Van Eyck * 418*b0563631STom Van Eyck * Functionally equivalent to: 419*b0563631STom Van Eyck * 420*b0563631STom Van Eyck * condition ? if1 : 0. 421*b0563631STom Van Eyck * 422*b0563631STom Van Eyck * Functionally equivalent to mbedtls_ct_error_if(condition, if1, 0) but 423*b0563631STom Van Eyck * results in smaller code size. 424*b0563631STom Van Eyck * 425*b0563631STom Van Eyck * \param condition Condition to test. 426*b0563631STom Van Eyck * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. 427*b0563631STom Van Eyck * 428*b0563631STom Van Eyck * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0. 429*b0563631STom Van Eyck */ 430*b0563631STom Van Eyck static inline int mbedtls_ct_error_if_else_0(mbedtls_ct_condition_t condition, int if1); 431*b0563631STom Van Eyck 432*b0563631STom Van Eyck /* ============================================================================ 433*b0563631STom Van Eyck * Block memory operations 434*b0563631STom Van Eyck */ 435*b0563631STom Van Eyck 436*b0563631STom Van Eyck #if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) 437*b0563631STom Van Eyck 438*b0563631STom Van Eyck /** Conditionally set a block of memory to zero. 439*b0563631STom Van Eyck * 440*b0563631STom Van Eyck * Regardless of the condition, every byte will be read once and written to 441*b0563631STom Van Eyck * once. 442*b0563631STom Van Eyck * 443*b0563631STom Van Eyck * \param condition Secret. Condition to test. 444*b0563631STom Van Eyck * \param buf Secret. Pointer to the start of the buffer. 445*b0563631STom Van Eyck * \param len Number of bytes to set to zero. 446*b0563631STom Van Eyck * 447*b0563631STom Van Eyck * \warning Unlike mbedtls_platform_zeroize, this does not have the same guarantees 448*b0563631STom Van Eyck * about not being optimised away if the memory is never read again. 449*b0563631STom Van Eyck */ 450*b0563631STom Van Eyck void mbedtls_ct_zeroize_if(mbedtls_ct_condition_t condition, void *buf, size_t len); 451*b0563631STom Van Eyck 452*b0563631STom Van Eyck /** Shift some data towards the left inside a buffer. 453*b0563631STom Van Eyck * 454*b0563631STom Van Eyck * Functionally equivalent to: 455*b0563631STom Van Eyck * 456*b0563631STom Van Eyck * memmove(start, start + offset, total - offset); 457*b0563631STom Van Eyck * memset(start + (total - offset), 0, offset); 458*b0563631STom Van Eyck * 459*b0563631STom Van Eyck * Timing independence comes at the expense of performance. 460*b0563631STom Van Eyck * 461*b0563631STom Van Eyck * \param start Secret. Pointer to the start of the buffer. 462*b0563631STom Van Eyck * \param total Total size of the buffer. 463*b0563631STom Van Eyck * \param offset Secret. Offset from which to copy \p total - \p offset bytes. 464*b0563631STom Van Eyck */ 465*b0563631STom Van Eyck void mbedtls_ct_memmove_left(void *start, 466*b0563631STom Van Eyck size_t total, 467*b0563631STom Van Eyck size_t offset); 468*b0563631STom Van Eyck 469*b0563631STom Van Eyck #endif /* defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) */ 470*b0563631STom Van Eyck 471*b0563631STom Van Eyck /** Conditional memcpy. 472*b0563631STom Van Eyck * 473*b0563631STom Van Eyck * Functionally equivalent to: 474*b0563631STom Van Eyck * 475*b0563631STom Van Eyck * if (condition) { 476*b0563631STom Van Eyck * memcpy(dest, src1, len); 477*b0563631STom Van Eyck * } else { 478*b0563631STom Van Eyck * if (src2 != NULL) 479*b0563631STom Van Eyck * memcpy(dest, src2, len); 480*b0563631STom Van Eyck * } 481*b0563631STom Van Eyck * 482*b0563631STom Van Eyck * It will always read len bytes from src1. 483*b0563631STom Van Eyck * If src2 != NULL, it will always read len bytes from src2. 484*b0563631STom Van Eyck * If src2 == NULL, it will instead read len bytes from dest (as if src2 == dest). 485*b0563631STom Van Eyck * 486*b0563631STom Van Eyck * \param condition The condition 487*b0563631STom Van Eyck * \param dest Secret. Destination pointer. 488*b0563631STom Van Eyck * \param src1 Secret. Pointer to copy from (if \p condition == MBEDTLS_CT_TRUE). 489*b0563631STom Van Eyck * This may be equal to \p dest, but may not overlap in other ways. 490*b0563631STom Van Eyck * \param src2 Secret (contents only - may branch to determine if this parameter is NULL). 491*b0563631STom Van Eyck * Pointer to copy from (if \p condition == MBEDTLS_CT_FALSE and \p src2 is not NULL). May be NULL. 492*b0563631STom Van Eyck * This may be equal to \p dest, but may not overlap it in other ways. It may overlap with \p src1. 493*b0563631STom Van Eyck * \param len Number of bytes to copy. 494*b0563631STom Van Eyck */ 495*b0563631STom Van Eyck void mbedtls_ct_memcpy_if(mbedtls_ct_condition_t condition, 496*b0563631STom Van Eyck unsigned char *dest, 497*b0563631STom Van Eyck const unsigned char *src1, 498*b0563631STom Van Eyck const unsigned char *src2, 499*b0563631STom Van Eyck size_t len 500*b0563631STom Van Eyck ); 501*b0563631STom Van Eyck 502*b0563631STom Van Eyck /** Copy data from a secret position. 503*b0563631STom Van Eyck * 504*b0563631STom Van Eyck * Functionally equivalent to: 505*b0563631STom Van Eyck * 506*b0563631STom Van Eyck * memcpy(dst, src + offset, len) 507*b0563631STom Van Eyck * 508*b0563631STom Van Eyck * This function copies \p len bytes from \p src + \p offset to 509*b0563631STom Van Eyck * \p dst, with a code flow and memory access pattern that does not depend on 510*b0563631STom Van Eyck * \p offset, but only on \p offset_min, \p offset_max and \p len. 511039e02dfSJerome Forissier * 512039e02dfSJerome Forissier * \note This function reads from \p dest, but the value that 513039e02dfSJerome Forissier * is read does not influence the result and this 514039e02dfSJerome Forissier * function's behavior is well-defined regardless of the 515039e02dfSJerome Forissier * contents of the buffers. This may result in false 516039e02dfSJerome Forissier * positives from static or dynamic analyzers, especially 517039e02dfSJerome Forissier * if \p dest is not initialized. 518039e02dfSJerome Forissier * 519*b0563631STom Van Eyck * \param dest Secret. The destination buffer. This must point to a writable 520039e02dfSJerome Forissier * buffer of at least \p len bytes. 521*b0563631STom Van Eyck * \param src Secret. The base of the source buffer. This must point to a 522039e02dfSJerome Forissier * readable buffer of at least \p offset_max + \p len 523*b0563631STom Van Eyck * bytes. Shouldn't overlap with \p dest 524*b0563631STom Van Eyck * \param offset Secret. The offset in the source buffer from which to copy. 525039e02dfSJerome Forissier * This must be no less than \p offset_min and no greater 526039e02dfSJerome Forissier * than \p offset_max. 527039e02dfSJerome Forissier * \param offset_min The minimal value of \p offset. 528039e02dfSJerome Forissier * \param offset_max The maximal value of \p offset. 529039e02dfSJerome Forissier * \param len The number of bytes to copy. 530039e02dfSJerome Forissier */ 531039e02dfSJerome Forissier void mbedtls_ct_memcpy_offset(unsigned char *dest, 532039e02dfSJerome Forissier const unsigned char *src, 533039e02dfSJerome Forissier size_t offset, 534039e02dfSJerome Forissier size_t offset_min, 535039e02dfSJerome Forissier size_t offset_max, 536039e02dfSJerome Forissier size_t len); 537039e02dfSJerome Forissier 538*b0563631STom Van Eyck /* Documented in include/mbedtls/constant_time.h. a and b are secret. 539*b0563631STom Van Eyck 540*b0563631STom Van Eyck int mbedtls_ct_memcmp(const void *a, 541*b0563631STom Van Eyck const void *b, 542*b0563631STom Van Eyck size_t n); 543039e02dfSJerome Forissier */ 544039e02dfSJerome Forissier 545*b0563631STom Van Eyck #if defined(MBEDTLS_NIST_KW_C) 546039e02dfSJerome Forissier 547*b0563631STom Van Eyck /** Constant-time buffer comparison without branches. 548039e02dfSJerome Forissier * 549*b0563631STom Van Eyck * Similar to mbedtls_ct_memcmp, except that the result only depends on part of 550*b0563631STom Van Eyck * the input data - differences in the head or tail are ignored. Functionally equivalent to: 551039e02dfSJerome Forissier * 552*b0563631STom Van Eyck * memcmp(a + skip_head, b + skip_head, size - skip_head - skip_tail) 553039e02dfSJerome Forissier * 554*b0563631STom Van Eyck * Time taken depends on \p n, but not on \p skip_head or \p skip_tail . 555*b0563631STom Van Eyck * 556*b0563631STom Van Eyck * Behaviour is undefined if ( \p skip_head + \p skip_tail) > \p n. 557*b0563631STom Van Eyck * 558*b0563631STom Van Eyck * \param a Secret. Pointer to the first buffer, containing at least \p n bytes. May not be NULL. 559*b0563631STom Van Eyck * \param b Secret. Pointer to the second buffer, containing at least \p n bytes. May not be NULL. 560*b0563631STom Van Eyck * \param n The number of bytes to examine (total size of the buffers). 561*b0563631STom Van Eyck * \param skip_head Secret. The number of bytes to treat as non-significant at the start of the buffer. 562*b0563631STom Van Eyck * These bytes will still be read. 563*b0563631STom Van Eyck * \param skip_tail Secret. The number of bytes to treat as non-significant at the end of the buffer. 564*b0563631STom Van Eyck * These bytes will still be read. 565*b0563631STom Van Eyck * 566*b0563631STom Van Eyck * \return Zero if the contents of the two buffers are the same, otherwise non-zero. 567039e02dfSJerome Forissier */ 568*b0563631STom Van Eyck int mbedtls_ct_memcmp_partial(const void *a, 569*b0563631STom Van Eyck const void *b, 570*b0563631STom Van Eyck size_t n, 571*b0563631STom Van Eyck size_t skip_head, 572*b0563631STom Van Eyck size_t skip_tail); 573039e02dfSJerome Forissier 574*b0563631STom Van Eyck #endif 575*b0563631STom Van Eyck 576*b0563631STom Van Eyck /* Include the implementation of static inline functions above. */ 577*b0563631STom Van Eyck #include "constant_time_impl.h" 578039e02dfSJerome Forissier 579039e02dfSJerome Forissier #endif /* MBEDTLS_CONSTANT_TIME_INTERNAL_H */ 580