1a8e1175bSopenharmony_ci/** 2a8e1175bSopenharmony_ci * Constant-time functions 3a8e1175bSopenharmony_ci * 4a8e1175bSopenharmony_ci * Copyright The Mbed TLS Contributors 5a8e1175bSopenharmony_ci * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 6a8e1175bSopenharmony_ci */ 7a8e1175bSopenharmony_ci 8a8e1175bSopenharmony_ci#ifndef MBEDTLS_CONSTANT_TIME_INTERNAL_H 9a8e1175bSopenharmony_ci#define MBEDTLS_CONSTANT_TIME_INTERNAL_H 10a8e1175bSopenharmony_ci 11a8e1175bSopenharmony_ci#include <stdint.h> 12a8e1175bSopenharmony_ci#include <stddef.h> 13a8e1175bSopenharmony_ci 14a8e1175bSopenharmony_ci#include "common.h" 15a8e1175bSopenharmony_ci 16a8e1175bSopenharmony_ci#if defined(MBEDTLS_BIGNUM_C) 17a8e1175bSopenharmony_ci#include "mbedtls/bignum.h" 18a8e1175bSopenharmony_ci#endif 19a8e1175bSopenharmony_ci 20a8e1175bSopenharmony_ci/* The constant-time interface provides various operations that are likely 21a8e1175bSopenharmony_ci * to result in constant-time code that does not branch or use conditional 22a8e1175bSopenharmony_ci * instructions for secret data (for secret pointers, this also applies to 23a8e1175bSopenharmony_ci * the data pointed to). 24a8e1175bSopenharmony_ci * 25a8e1175bSopenharmony_ci * It has three main parts: 26a8e1175bSopenharmony_ci * 27a8e1175bSopenharmony_ci * - boolean operations 28a8e1175bSopenharmony_ci * These are all named mbedtls_ct_<type>_<operation>. 29a8e1175bSopenharmony_ci * They operate over <type> and return mbedtls_ct_condition_t. 30a8e1175bSopenharmony_ci * All arguments are considered secret. 31a8e1175bSopenharmony_ci * example: bool x = y | z => x = mbedtls_ct_bool_or(y, z) 32a8e1175bSopenharmony_ci * example: bool x = y == z => x = mbedtls_ct_uint_eq(y, z) 33a8e1175bSopenharmony_ci * 34a8e1175bSopenharmony_ci * - conditional data selection 35a8e1175bSopenharmony_ci * These are all named mbedtls_ct_<type>_if and mbedtls_ct_<type>_if_else_0 36a8e1175bSopenharmony_ci * All arguments are considered secret. 37a8e1175bSopenharmony_ci * example: size_t a = x ? b : c => a = mbedtls_ct_size_if(x, b, c) 38a8e1175bSopenharmony_ci * example: unsigned a = x ? b : 0 => a = mbedtls_ct_uint_if_else_0(x, b) 39a8e1175bSopenharmony_ci * 40a8e1175bSopenharmony_ci * - block memory operations 41a8e1175bSopenharmony_ci * Only some arguments are considered secret, as documented for each 42a8e1175bSopenharmony_ci * function. 43a8e1175bSopenharmony_ci * example: if (x) memcpy(...) => mbedtls_ct_memcpy_if(x, ...) 44a8e1175bSopenharmony_ci * 45a8e1175bSopenharmony_ci * mbedtls_ct_condition_t must be treated as opaque and only created and 46a8e1175bSopenharmony_ci * manipulated via the functions in this header. The compiler should never 47a8e1175bSopenharmony_ci * be able to prove anything about its value at compile-time. 48a8e1175bSopenharmony_ci * 49a8e1175bSopenharmony_ci * mbedtls_ct_uint_t is an unsigned integer type over which constant time 50a8e1175bSopenharmony_ci * operations may be performed via the functions in this header. It is as big 51a8e1175bSopenharmony_ci * as the larger of size_t and mbedtls_mpi_uint, i.e. it is safe to cast 52a8e1175bSopenharmony_ci * to/from "unsigned int", "size_t", and "mbedtls_mpi_uint" (and any other 53a8e1175bSopenharmony_ci * not-larger integer types). 54a8e1175bSopenharmony_ci * 55a8e1175bSopenharmony_ci * For Arm (32-bit, 64-bit and Thumb), x86 and x86-64, assembly implementations 56a8e1175bSopenharmony_ci * are used to ensure that the generated code is constant time. For other 57a8e1175bSopenharmony_ci * architectures, it uses a plain C fallback designed to yield constant-time code 58a8e1175bSopenharmony_ci * (this has been observed to be constant-time on latest gcc, clang and MSVC 59a8e1175bSopenharmony_ci * as of May 2023). 60a8e1175bSopenharmony_ci * 61a8e1175bSopenharmony_ci * For readability, the static inline definitions are separated out into 62a8e1175bSopenharmony_ci * constant_time_impl.h. 63a8e1175bSopenharmony_ci */ 64a8e1175bSopenharmony_ci 65a8e1175bSopenharmony_ci#if (SIZE_MAX > 0xffffffffffffffffULL) 66a8e1175bSopenharmony_ci/* Pointer size > 64-bit */ 67a8e1175bSopenharmony_citypedef size_t mbedtls_ct_condition_t; 68a8e1175bSopenharmony_citypedef size_t mbedtls_ct_uint_t; 69a8e1175bSopenharmony_citypedef ptrdiff_t mbedtls_ct_int_t; 70a8e1175bSopenharmony_ci#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(SIZE_MAX)) 71a8e1175bSopenharmony_ci#elif (SIZE_MAX > 0xffffffff) || defined(MBEDTLS_HAVE_INT64) 72a8e1175bSopenharmony_ci/* 32-bit < pointer size <= 64-bit, or 64-bit MPI */ 73a8e1175bSopenharmony_citypedef uint64_t mbedtls_ct_condition_t; 74a8e1175bSopenharmony_citypedef uint64_t mbedtls_ct_uint_t; 75a8e1175bSopenharmony_citypedef int64_t mbedtls_ct_int_t; 76a8e1175bSopenharmony_ci#define MBEDTLS_CT_SIZE_64 77a8e1175bSopenharmony_ci#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT64_MAX)) 78a8e1175bSopenharmony_ci#else 79a8e1175bSopenharmony_ci/* Pointer size <= 32-bit, and no 64-bit MPIs */ 80a8e1175bSopenharmony_citypedef uint32_t mbedtls_ct_condition_t; 81a8e1175bSopenharmony_citypedef uint32_t mbedtls_ct_uint_t; 82a8e1175bSopenharmony_citypedef int32_t mbedtls_ct_int_t; 83a8e1175bSopenharmony_ci#define MBEDTLS_CT_SIZE_32 84a8e1175bSopenharmony_ci#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT32_MAX)) 85a8e1175bSopenharmony_ci#endif 86a8e1175bSopenharmony_ci#define MBEDTLS_CT_FALSE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(0)) 87a8e1175bSopenharmony_ci 88a8e1175bSopenharmony_ci/* ============================================================================ 89a8e1175bSopenharmony_ci * Boolean operations 90a8e1175bSopenharmony_ci */ 91a8e1175bSopenharmony_ci 92a8e1175bSopenharmony_ci/** Convert a number into a mbedtls_ct_condition_t. 93a8e1175bSopenharmony_ci * 94a8e1175bSopenharmony_ci * \param x Number to convert. 95a8e1175bSopenharmony_ci * 96a8e1175bSopenharmony_ci * \return MBEDTLS_CT_TRUE if \p x != 0, or MBEDTLS_CT_FALSE if \p x == 0 97a8e1175bSopenharmony_ci * 98a8e1175bSopenharmony_ci */ 99a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x); 100a8e1175bSopenharmony_ci 101a8e1175bSopenharmony_ci/** Boolean "not equal" operation. 102a8e1175bSopenharmony_ci * 103a8e1175bSopenharmony_ci * Functionally equivalent to: 104a8e1175bSopenharmony_ci * 105a8e1175bSopenharmony_ci * \p x != \p y 106a8e1175bSopenharmony_ci * 107a8e1175bSopenharmony_ci * \param x The first value to analyze. 108a8e1175bSopenharmony_ci * \param y The second value to analyze. 109a8e1175bSopenharmony_ci * 110a8e1175bSopenharmony_ci * \return MBEDTLS_CT_TRUE if \p x != \p y, otherwise MBEDTLS_CT_FALSE. 111a8e1175bSopenharmony_ci */ 112a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_uint_ne(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y); 113a8e1175bSopenharmony_ci 114a8e1175bSopenharmony_ci/** Boolean "equals" operation. 115a8e1175bSopenharmony_ci * 116a8e1175bSopenharmony_ci * Functionally equivalent to: 117a8e1175bSopenharmony_ci * 118a8e1175bSopenharmony_ci * \p x == \p y 119a8e1175bSopenharmony_ci * 120a8e1175bSopenharmony_ci * \param x The first value to analyze. 121a8e1175bSopenharmony_ci * \param y The second value to analyze. 122a8e1175bSopenharmony_ci * 123a8e1175bSopenharmony_ci * \return MBEDTLS_CT_TRUE if \p x == \p y, otherwise MBEDTLS_CT_FALSE. 124a8e1175bSopenharmony_ci */ 125a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_uint_eq(mbedtls_ct_uint_t x, 126a8e1175bSopenharmony_ci mbedtls_ct_uint_t y); 127a8e1175bSopenharmony_ci 128a8e1175bSopenharmony_ci/** Boolean "less than" operation. 129a8e1175bSopenharmony_ci * 130a8e1175bSopenharmony_ci * Functionally equivalent to: 131a8e1175bSopenharmony_ci * 132a8e1175bSopenharmony_ci * \p x < \p y 133a8e1175bSopenharmony_ci * 134a8e1175bSopenharmony_ci * \param x The first value to analyze. 135a8e1175bSopenharmony_ci * \param y The second value to analyze. 136a8e1175bSopenharmony_ci * 137a8e1175bSopenharmony_ci * \return MBEDTLS_CT_TRUE if \p x < \p y, otherwise MBEDTLS_CT_FALSE. 138a8e1175bSopenharmony_ci */ 139a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y); 140a8e1175bSopenharmony_ci 141a8e1175bSopenharmony_ci/** Boolean "greater than" operation. 142a8e1175bSopenharmony_ci * 143a8e1175bSopenharmony_ci * Functionally equivalent to: 144a8e1175bSopenharmony_ci * 145a8e1175bSopenharmony_ci * \p x > \p y 146a8e1175bSopenharmony_ci * 147a8e1175bSopenharmony_ci * \param x The first value to analyze. 148a8e1175bSopenharmony_ci * \param y The second value to analyze. 149a8e1175bSopenharmony_ci * 150a8e1175bSopenharmony_ci * \return MBEDTLS_CT_TRUE if \p x > \p y, otherwise MBEDTLS_CT_FALSE. 151a8e1175bSopenharmony_ci */ 152a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_uint_gt(mbedtls_ct_uint_t x, 153a8e1175bSopenharmony_ci mbedtls_ct_uint_t y); 154a8e1175bSopenharmony_ci 155a8e1175bSopenharmony_ci/** Boolean "greater or equal" operation. 156a8e1175bSopenharmony_ci * 157a8e1175bSopenharmony_ci * Functionally equivalent to: 158a8e1175bSopenharmony_ci * 159a8e1175bSopenharmony_ci * \p x >= \p y 160a8e1175bSopenharmony_ci * 161a8e1175bSopenharmony_ci * \param x The first value to analyze. 162a8e1175bSopenharmony_ci * \param y The second value to analyze. 163a8e1175bSopenharmony_ci * 164a8e1175bSopenharmony_ci * \return MBEDTLS_CT_TRUE if \p x >= \p y, 165a8e1175bSopenharmony_ci * otherwise MBEDTLS_CT_FALSE. 166a8e1175bSopenharmony_ci */ 167a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_uint_ge(mbedtls_ct_uint_t x, 168a8e1175bSopenharmony_ci mbedtls_ct_uint_t y); 169a8e1175bSopenharmony_ci 170a8e1175bSopenharmony_ci/** Boolean "less than or equal" operation. 171a8e1175bSopenharmony_ci * 172a8e1175bSopenharmony_ci * Functionally equivalent to: 173a8e1175bSopenharmony_ci * 174a8e1175bSopenharmony_ci * \p x <= \p y 175a8e1175bSopenharmony_ci * 176a8e1175bSopenharmony_ci * \param x The first value to analyze. 177a8e1175bSopenharmony_ci * \param y The second value to analyze. 178a8e1175bSopenharmony_ci * 179a8e1175bSopenharmony_ci * \return MBEDTLS_CT_TRUE if \p x <= \p y, 180a8e1175bSopenharmony_ci * otherwise MBEDTLS_CT_FALSE. 181a8e1175bSopenharmony_ci */ 182a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_uint_le(mbedtls_ct_uint_t x, 183a8e1175bSopenharmony_ci mbedtls_ct_uint_t y); 184a8e1175bSopenharmony_ci 185a8e1175bSopenharmony_ci/** Boolean not-equals operation. 186a8e1175bSopenharmony_ci * 187a8e1175bSopenharmony_ci * Functionally equivalent to: 188a8e1175bSopenharmony_ci * 189a8e1175bSopenharmony_ci * \p x != \p y 190a8e1175bSopenharmony_ci * 191a8e1175bSopenharmony_ci * \param x The first value to analyze. 192a8e1175bSopenharmony_ci * \param y The second value to analyze. 193a8e1175bSopenharmony_ci * 194a8e1175bSopenharmony_ci * \note This is more efficient than mbedtls_ct_uint_ne if both arguments are 195a8e1175bSopenharmony_ci * mbedtls_ct_condition_t. 196a8e1175bSopenharmony_ci * 197a8e1175bSopenharmony_ci * \return MBEDTLS_CT_TRUE if \p x != \p y, 198a8e1175bSopenharmony_ci * otherwise MBEDTLS_CT_FALSE. 199a8e1175bSopenharmony_ci */ 200a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_bool_ne(mbedtls_ct_condition_t x, 201a8e1175bSopenharmony_ci mbedtls_ct_condition_t y); 202a8e1175bSopenharmony_ci 203a8e1175bSopenharmony_ci/** Boolean "and" operation. 204a8e1175bSopenharmony_ci * 205a8e1175bSopenharmony_ci * Functionally equivalent to: 206a8e1175bSopenharmony_ci * 207a8e1175bSopenharmony_ci * \p x && \p y 208a8e1175bSopenharmony_ci * 209a8e1175bSopenharmony_ci * \param x The first value to analyze. 210a8e1175bSopenharmony_ci * \param y The second value to analyze. 211a8e1175bSopenharmony_ci * 212a8e1175bSopenharmony_ci * \return MBEDTLS_CT_TRUE if \p x && \p y, 213a8e1175bSopenharmony_ci * otherwise MBEDTLS_CT_FALSE. 214a8e1175bSopenharmony_ci */ 215a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_bool_and(mbedtls_ct_condition_t x, 216a8e1175bSopenharmony_ci mbedtls_ct_condition_t y); 217a8e1175bSopenharmony_ci 218a8e1175bSopenharmony_ci/** Boolean "or" operation. 219a8e1175bSopenharmony_ci * 220a8e1175bSopenharmony_ci * Functionally equivalent to: 221a8e1175bSopenharmony_ci * 222a8e1175bSopenharmony_ci * \p x || \p y 223a8e1175bSopenharmony_ci * 224a8e1175bSopenharmony_ci * \param x The first value to analyze. 225a8e1175bSopenharmony_ci * \param y The second value to analyze. 226a8e1175bSopenharmony_ci * 227a8e1175bSopenharmony_ci * \return MBEDTLS_CT_TRUE if \p x || \p y, 228a8e1175bSopenharmony_ci * otherwise MBEDTLS_CT_FALSE. 229a8e1175bSopenharmony_ci */ 230a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_bool_or(mbedtls_ct_condition_t x, 231a8e1175bSopenharmony_ci mbedtls_ct_condition_t y); 232a8e1175bSopenharmony_ci 233a8e1175bSopenharmony_ci/** Boolean "not" operation. 234a8e1175bSopenharmony_ci * 235a8e1175bSopenharmony_ci * Functionally equivalent to: 236a8e1175bSopenharmony_ci * 237a8e1175bSopenharmony_ci * ! \p x 238a8e1175bSopenharmony_ci * 239a8e1175bSopenharmony_ci * \param x The value to invert 240a8e1175bSopenharmony_ci * 241a8e1175bSopenharmony_ci * \return MBEDTLS_CT_FALSE if \p x, otherwise MBEDTLS_CT_TRUE. 242a8e1175bSopenharmony_ci */ 243a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_bool_not(mbedtls_ct_condition_t x); 244a8e1175bSopenharmony_ci 245a8e1175bSopenharmony_ci 246a8e1175bSopenharmony_ci/* ============================================================================ 247a8e1175bSopenharmony_ci * Data selection operations 248a8e1175bSopenharmony_ci */ 249a8e1175bSopenharmony_ci 250a8e1175bSopenharmony_ci/** Choose between two size_t values. 251a8e1175bSopenharmony_ci * 252a8e1175bSopenharmony_ci * Functionally equivalent to: 253a8e1175bSopenharmony_ci * 254a8e1175bSopenharmony_ci * condition ? if1 : if0. 255a8e1175bSopenharmony_ci * 256a8e1175bSopenharmony_ci * \param condition Condition to test. 257a8e1175bSopenharmony_ci * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. 258a8e1175bSopenharmony_ci * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE. 259a8e1175bSopenharmony_ci * 260a8e1175bSopenharmony_ci * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0. 261a8e1175bSopenharmony_ci */ 262a8e1175bSopenharmony_cistatic inline size_t mbedtls_ct_size_if(mbedtls_ct_condition_t condition, 263a8e1175bSopenharmony_ci size_t if1, 264a8e1175bSopenharmony_ci size_t if0); 265a8e1175bSopenharmony_ci 266a8e1175bSopenharmony_ci/** Choose between two unsigned values. 267a8e1175bSopenharmony_ci * 268a8e1175bSopenharmony_ci * Functionally equivalent to: 269a8e1175bSopenharmony_ci * 270a8e1175bSopenharmony_ci * condition ? if1 : if0. 271a8e1175bSopenharmony_ci * 272a8e1175bSopenharmony_ci * \param condition Condition to test. 273a8e1175bSopenharmony_ci * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. 274a8e1175bSopenharmony_ci * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE. 275a8e1175bSopenharmony_ci * 276a8e1175bSopenharmony_ci * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0. 277a8e1175bSopenharmony_ci */ 278a8e1175bSopenharmony_cistatic inline unsigned mbedtls_ct_uint_if(mbedtls_ct_condition_t condition, 279a8e1175bSopenharmony_ci unsigned if1, 280a8e1175bSopenharmony_ci unsigned if0); 281a8e1175bSopenharmony_ci 282a8e1175bSopenharmony_ci/** Choose between two mbedtls_ct_condition_t values. 283a8e1175bSopenharmony_ci * 284a8e1175bSopenharmony_ci * Functionally equivalent to: 285a8e1175bSopenharmony_ci * 286a8e1175bSopenharmony_ci * condition ? if1 : if0. 287a8e1175bSopenharmony_ci * 288a8e1175bSopenharmony_ci * \param condition Condition to test. 289a8e1175bSopenharmony_ci * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. 290a8e1175bSopenharmony_ci * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE. 291a8e1175bSopenharmony_ci * 292a8e1175bSopenharmony_ci * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0. 293a8e1175bSopenharmony_ci */ 294a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_bool_if(mbedtls_ct_condition_t condition, 295a8e1175bSopenharmony_ci mbedtls_ct_condition_t if1, 296a8e1175bSopenharmony_ci mbedtls_ct_condition_t if0); 297a8e1175bSopenharmony_ci 298a8e1175bSopenharmony_ci#if defined(MBEDTLS_BIGNUM_C) 299a8e1175bSopenharmony_ci 300a8e1175bSopenharmony_ci/** Choose between two mbedtls_mpi_uint values. 301a8e1175bSopenharmony_ci * 302a8e1175bSopenharmony_ci * Functionally equivalent to: 303a8e1175bSopenharmony_ci * 304a8e1175bSopenharmony_ci * condition ? if1 : if0. 305a8e1175bSopenharmony_ci * 306a8e1175bSopenharmony_ci * \param condition Condition to test. 307a8e1175bSopenharmony_ci * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. 308a8e1175bSopenharmony_ci * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE. 309a8e1175bSopenharmony_ci * 310a8e1175bSopenharmony_ci * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0. 311a8e1175bSopenharmony_ci */ 312a8e1175bSopenharmony_cistatic inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if(mbedtls_ct_condition_t condition, \ 313a8e1175bSopenharmony_ci mbedtls_mpi_uint if1, \ 314a8e1175bSopenharmony_ci mbedtls_mpi_uint if0); 315a8e1175bSopenharmony_ci 316a8e1175bSopenharmony_ci#endif 317a8e1175bSopenharmony_ci 318a8e1175bSopenharmony_ci/** Choose between an unsigned value and 0. 319a8e1175bSopenharmony_ci * 320a8e1175bSopenharmony_ci * Functionally equivalent to: 321a8e1175bSopenharmony_ci * 322a8e1175bSopenharmony_ci * condition ? if1 : 0. 323a8e1175bSopenharmony_ci * 324a8e1175bSopenharmony_ci * Functionally equivalent to mbedtls_ct_uint_if(condition, if1, 0) but 325a8e1175bSopenharmony_ci * results in smaller code size. 326a8e1175bSopenharmony_ci * 327a8e1175bSopenharmony_ci * \param condition Condition to test. 328a8e1175bSopenharmony_ci * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. 329a8e1175bSopenharmony_ci * 330a8e1175bSopenharmony_ci * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0. 331a8e1175bSopenharmony_ci */ 332a8e1175bSopenharmony_cistatic inline unsigned mbedtls_ct_uint_if_else_0(mbedtls_ct_condition_t condition, unsigned if1); 333a8e1175bSopenharmony_ci 334a8e1175bSopenharmony_ci/** Choose between an mbedtls_ct_condition_t and 0. 335a8e1175bSopenharmony_ci * 336a8e1175bSopenharmony_ci * Functionally equivalent to: 337a8e1175bSopenharmony_ci * 338a8e1175bSopenharmony_ci * condition ? if1 : 0. 339a8e1175bSopenharmony_ci * 340a8e1175bSopenharmony_ci * Functionally equivalent to mbedtls_ct_bool_if(condition, if1, 0) but 341a8e1175bSopenharmony_ci * results in smaller code size. 342a8e1175bSopenharmony_ci * 343a8e1175bSopenharmony_ci * \param condition Condition to test. 344a8e1175bSopenharmony_ci * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. 345a8e1175bSopenharmony_ci * 346a8e1175bSopenharmony_ci * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0. 347a8e1175bSopenharmony_ci */ 348a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_bool_if_else_0(mbedtls_ct_condition_t condition, 349a8e1175bSopenharmony_ci mbedtls_ct_condition_t if1); 350a8e1175bSopenharmony_ci 351a8e1175bSopenharmony_ci/** Choose between a size_t value and 0. 352a8e1175bSopenharmony_ci * 353a8e1175bSopenharmony_ci * Functionally equivalent to: 354a8e1175bSopenharmony_ci * 355a8e1175bSopenharmony_ci * condition ? if1 : 0. 356a8e1175bSopenharmony_ci * 357a8e1175bSopenharmony_ci * Functionally equivalent to mbedtls_ct_size_if(condition, if1, 0) but 358a8e1175bSopenharmony_ci * results in smaller code size. 359a8e1175bSopenharmony_ci * 360a8e1175bSopenharmony_ci * \param condition Condition to test. 361a8e1175bSopenharmony_ci * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. 362a8e1175bSopenharmony_ci * 363a8e1175bSopenharmony_ci * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0. 364a8e1175bSopenharmony_ci */ 365a8e1175bSopenharmony_cistatic inline size_t mbedtls_ct_size_if_else_0(mbedtls_ct_condition_t condition, size_t if1); 366a8e1175bSopenharmony_ci 367a8e1175bSopenharmony_ci#if defined(MBEDTLS_BIGNUM_C) 368a8e1175bSopenharmony_ci 369a8e1175bSopenharmony_ci/** Choose between an mbedtls_mpi_uint value and 0. 370a8e1175bSopenharmony_ci * 371a8e1175bSopenharmony_ci * Functionally equivalent to: 372a8e1175bSopenharmony_ci * 373a8e1175bSopenharmony_ci * condition ? if1 : 0. 374a8e1175bSopenharmony_ci * 375a8e1175bSopenharmony_ci * Functionally equivalent to mbedtls_ct_mpi_uint_if(condition, if1, 0) but 376a8e1175bSopenharmony_ci * results in smaller code size. 377a8e1175bSopenharmony_ci * 378a8e1175bSopenharmony_ci * \param condition Condition to test. 379a8e1175bSopenharmony_ci * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. 380a8e1175bSopenharmony_ci * 381a8e1175bSopenharmony_ci * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0. 382a8e1175bSopenharmony_ci */ 383a8e1175bSopenharmony_cistatic inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if_else_0(mbedtls_ct_condition_t condition, 384a8e1175bSopenharmony_ci mbedtls_mpi_uint if1); 385a8e1175bSopenharmony_ci 386a8e1175bSopenharmony_ci#endif 387a8e1175bSopenharmony_ci 388a8e1175bSopenharmony_ci/** Constant-flow char selection 389a8e1175bSopenharmony_ci * 390a8e1175bSopenharmony_ci * \param low Secret. Bottom of range 391a8e1175bSopenharmony_ci * \param high Secret. Top of range 392a8e1175bSopenharmony_ci * \param c Secret. Value to compare to range 393a8e1175bSopenharmony_ci * \param t Secret. Value to return, if in range 394a8e1175bSopenharmony_ci * 395a8e1175bSopenharmony_ci * \return \p t if \p low <= \p c <= \p high, 0 otherwise. 396a8e1175bSopenharmony_ci */ 397a8e1175bSopenharmony_cistatic inline unsigned char mbedtls_ct_uchar_in_range_if(unsigned char low, 398a8e1175bSopenharmony_ci unsigned char high, 399a8e1175bSopenharmony_ci unsigned char c, 400a8e1175bSopenharmony_ci unsigned char t); 401a8e1175bSopenharmony_ci 402a8e1175bSopenharmony_ci/** Choose between two error values. The values must be in the range [-32767..0]. 403a8e1175bSopenharmony_ci * 404a8e1175bSopenharmony_ci * Functionally equivalent to: 405a8e1175bSopenharmony_ci * 406a8e1175bSopenharmony_ci * condition ? if1 : if0. 407a8e1175bSopenharmony_ci * 408a8e1175bSopenharmony_ci * \param condition Condition to test. 409a8e1175bSopenharmony_ci * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. 410a8e1175bSopenharmony_ci * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE. 411a8e1175bSopenharmony_ci * 412a8e1175bSopenharmony_ci * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0. 413a8e1175bSopenharmony_ci */ 414a8e1175bSopenharmony_cistatic inline int mbedtls_ct_error_if(mbedtls_ct_condition_t condition, int if1, int if0); 415a8e1175bSopenharmony_ci 416a8e1175bSopenharmony_ci/** Choose between an error value and 0. The error value must be in the range [-32767..0]. 417a8e1175bSopenharmony_ci * 418a8e1175bSopenharmony_ci * Functionally equivalent to: 419a8e1175bSopenharmony_ci * 420a8e1175bSopenharmony_ci * condition ? if1 : 0. 421a8e1175bSopenharmony_ci * 422a8e1175bSopenharmony_ci * Functionally equivalent to mbedtls_ct_error_if(condition, if1, 0) but 423a8e1175bSopenharmony_ci * results in smaller code size. 424a8e1175bSopenharmony_ci * 425a8e1175bSopenharmony_ci * \param condition Condition to test. 426a8e1175bSopenharmony_ci * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. 427a8e1175bSopenharmony_ci * 428a8e1175bSopenharmony_ci * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0. 429a8e1175bSopenharmony_ci */ 430a8e1175bSopenharmony_cistatic inline int mbedtls_ct_error_if_else_0(mbedtls_ct_condition_t condition, int if1); 431a8e1175bSopenharmony_ci 432a8e1175bSopenharmony_ci/* ============================================================================ 433a8e1175bSopenharmony_ci * Block memory operations 434a8e1175bSopenharmony_ci */ 435a8e1175bSopenharmony_ci 436a8e1175bSopenharmony_ci#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) 437a8e1175bSopenharmony_ci 438a8e1175bSopenharmony_ci/** Conditionally set a block of memory to zero. 439a8e1175bSopenharmony_ci * 440a8e1175bSopenharmony_ci * Regardless of the condition, every byte will be read once and written to 441a8e1175bSopenharmony_ci * once. 442a8e1175bSopenharmony_ci * 443a8e1175bSopenharmony_ci * \param condition Secret. Condition to test. 444a8e1175bSopenharmony_ci * \param buf Secret. Pointer to the start of the buffer. 445a8e1175bSopenharmony_ci * \param len Number of bytes to set to zero. 446a8e1175bSopenharmony_ci * 447a8e1175bSopenharmony_ci * \warning Unlike mbedtls_platform_zeroize, this does not have the same guarantees 448a8e1175bSopenharmony_ci * about not being optimised away if the memory is never read again. 449a8e1175bSopenharmony_ci */ 450a8e1175bSopenharmony_civoid mbedtls_ct_zeroize_if(mbedtls_ct_condition_t condition, void *buf, size_t len); 451a8e1175bSopenharmony_ci 452a8e1175bSopenharmony_ci/** Shift some data towards the left inside a buffer. 453a8e1175bSopenharmony_ci * 454a8e1175bSopenharmony_ci * Functionally equivalent to: 455a8e1175bSopenharmony_ci * 456a8e1175bSopenharmony_ci * memmove(start, start + offset, total - offset); 457a8e1175bSopenharmony_ci * memset(start + (total - offset), 0, offset); 458a8e1175bSopenharmony_ci * 459a8e1175bSopenharmony_ci * Timing independence comes at the expense of performance. 460a8e1175bSopenharmony_ci * 461a8e1175bSopenharmony_ci * \param start Secret. Pointer to the start of the buffer. 462a8e1175bSopenharmony_ci * \param total Total size of the buffer. 463a8e1175bSopenharmony_ci * \param offset Secret. Offset from which to copy \p total - \p offset bytes. 464a8e1175bSopenharmony_ci */ 465a8e1175bSopenharmony_civoid mbedtls_ct_memmove_left(void *start, 466a8e1175bSopenharmony_ci size_t total, 467a8e1175bSopenharmony_ci size_t offset); 468a8e1175bSopenharmony_ci 469a8e1175bSopenharmony_ci#endif /* defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) */ 470a8e1175bSopenharmony_ci 471a8e1175bSopenharmony_ci/** Conditional memcpy. 472a8e1175bSopenharmony_ci * 473a8e1175bSopenharmony_ci * Functionally equivalent to: 474a8e1175bSopenharmony_ci * 475a8e1175bSopenharmony_ci * if (condition) { 476a8e1175bSopenharmony_ci * memcpy(dest, src1, len); 477a8e1175bSopenharmony_ci * } else { 478a8e1175bSopenharmony_ci * if (src2 != NULL) 479a8e1175bSopenharmony_ci * memcpy(dest, src2, len); 480a8e1175bSopenharmony_ci * } 481a8e1175bSopenharmony_ci * 482a8e1175bSopenharmony_ci * It will always read len bytes from src1. 483a8e1175bSopenharmony_ci * If src2 != NULL, it will always read len bytes from src2. 484a8e1175bSopenharmony_ci * If src2 == NULL, it will instead read len bytes from dest (as if src2 == dest). 485a8e1175bSopenharmony_ci * 486a8e1175bSopenharmony_ci * \param condition The condition 487a8e1175bSopenharmony_ci * \param dest Secret. Destination pointer. 488a8e1175bSopenharmony_ci * \param src1 Secret. Pointer to copy from (if \p condition == MBEDTLS_CT_TRUE). 489a8e1175bSopenharmony_ci * This may be equal to \p dest, but may not overlap in other ways. 490a8e1175bSopenharmony_ci * \param src2 Secret (contents only - may branch to determine if this parameter is NULL). 491a8e1175bSopenharmony_ci * Pointer to copy from (if \p condition == MBEDTLS_CT_FALSE and \p src2 is not NULL). May be NULL. 492a8e1175bSopenharmony_ci * This may be equal to \p dest, but may not overlap it in other ways. It may overlap with \p src1. 493a8e1175bSopenharmony_ci * \param len Number of bytes to copy. 494a8e1175bSopenharmony_ci */ 495a8e1175bSopenharmony_civoid mbedtls_ct_memcpy_if(mbedtls_ct_condition_t condition, 496a8e1175bSopenharmony_ci unsigned char *dest, 497a8e1175bSopenharmony_ci const unsigned char *src1, 498a8e1175bSopenharmony_ci const unsigned char *src2, 499a8e1175bSopenharmony_ci size_t len 500a8e1175bSopenharmony_ci ); 501a8e1175bSopenharmony_ci 502a8e1175bSopenharmony_ci/** Copy data from a secret position. 503a8e1175bSopenharmony_ci * 504a8e1175bSopenharmony_ci * Functionally equivalent to: 505a8e1175bSopenharmony_ci * 506a8e1175bSopenharmony_ci * memcpy(dst, src + offset, len) 507a8e1175bSopenharmony_ci * 508a8e1175bSopenharmony_ci * This function copies \p len bytes from \p src + \p offset to 509a8e1175bSopenharmony_ci * \p dst, with a code flow and memory access pattern that does not depend on 510a8e1175bSopenharmony_ci * \p offset, but only on \p offset_min, \p offset_max and \p len. 511a8e1175bSopenharmony_ci * 512a8e1175bSopenharmony_ci * \note This function reads from \p dest, but the value that 513a8e1175bSopenharmony_ci * is read does not influence the result and this 514a8e1175bSopenharmony_ci * function's behavior is well-defined regardless of the 515a8e1175bSopenharmony_ci * contents of the buffers. This may result in false 516a8e1175bSopenharmony_ci * positives from static or dynamic analyzers, especially 517a8e1175bSopenharmony_ci * if \p dest is not initialized. 518a8e1175bSopenharmony_ci * 519a8e1175bSopenharmony_ci * \param dest Secret. The destination buffer. This must point to a writable 520a8e1175bSopenharmony_ci * buffer of at least \p len bytes. 521a8e1175bSopenharmony_ci * \param src Secret. The base of the source buffer. This must point to a 522a8e1175bSopenharmony_ci * readable buffer of at least \p offset_max + \p len 523a8e1175bSopenharmony_ci * bytes. Shouldn't overlap with \p dest 524a8e1175bSopenharmony_ci * \param offset Secret. The offset in the source buffer from which to copy. 525a8e1175bSopenharmony_ci * This must be no less than \p offset_min and no greater 526a8e1175bSopenharmony_ci * than \p offset_max. 527a8e1175bSopenharmony_ci * \param offset_min The minimal value of \p offset. 528a8e1175bSopenharmony_ci * \param offset_max The maximal value of \p offset. 529a8e1175bSopenharmony_ci * \param len The number of bytes to copy. 530a8e1175bSopenharmony_ci */ 531a8e1175bSopenharmony_civoid mbedtls_ct_memcpy_offset(unsigned char *dest, 532a8e1175bSopenharmony_ci const unsigned char *src, 533a8e1175bSopenharmony_ci size_t offset, 534a8e1175bSopenharmony_ci size_t offset_min, 535a8e1175bSopenharmony_ci size_t offset_max, 536a8e1175bSopenharmony_ci size_t len); 537a8e1175bSopenharmony_ci 538a8e1175bSopenharmony_ci/* Documented in include/mbedtls/constant_time.h. a and b are secret. 539a8e1175bSopenharmony_ci 540a8e1175bSopenharmony_ci int mbedtls_ct_memcmp(const void *a, 541a8e1175bSopenharmony_ci const void *b, 542a8e1175bSopenharmony_ci size_t n); 543a8e1175bSopenharmony_ci */ 544a8e1175bSopenharmony_ci 545a8e1175bSopenharmony_ci#if defined(MBEDTLS_NIST_KW_C) 546a8e1175bSopenharmony_ci 547a8e1175bSopenharmony_ci/** Constant-time buffer comparison without branches. 548a8e1175bSopenharmony_ci * 549a8e1175bSopenharmony_ci * Similar to mbedtls_ct_memcmp, except that the result only depends on part of 550a8e1175bSopenharmony_ci * the input data - differences in the head or tail are ignored. Functionally equivalent to: 551a8e1175bSopenharmony_ci * 552a8e1175bSopenharmony_ci * memcmp(a + skip_head, b + skip_head, size - skip_head - skip_tail) 553a8e1175bSopenharmony_ci * 554a8e1175bSopenharmony_ci * Time taken depends on \p n, but not on \p skip_head or \p skip_tail . 555a8e1175bSopenharmony_ci * 556a8e1175bSopenharmony_ci * Behaviour is undefined if ( \p skip_head + \p skip_tail) > \p n. 557a8e1175bSopenharmony_ci * 558a8e1175bSopenharmony_ci * \param a Secret. Pointer to the first buffer, containing at least \p n bytes. May not be NULL. 559a8e1175bSopenharmony_ci * \param b Secret. Pointer to the second buffer, containing at least \p n bytes. May not be NULL. 560a8e1175bSopenharmony_ci * \param n The number of bytes to examine (total size of the buffers). 561a8e1175bSopenharmony_ci * \param skip_head Secret. The number of bytes to treat as non-significant at the start of the buffer. 562a8e1175bSopenharmony_ci * These bytes will still be read. 563a8e1175bSopenharmony_ci * \param skip_tail Secret. The number of bytes to treat as non-significant at the end of the buffer. 564a8e1175bSopenharmony_ci * These bytes will still be read. 565a8e1175bSopenharmony_ci * 566a8e1175bSopenharmony_ci * \return Zero if the contents of the two buffers are the same, otherwise non-zero. 567a8e1175bSopenharmony_ci */ 568a8e1175bSopenharmony_ciint mbedtls_ct_memcmp_partial(const void *a, 569a8e1175bSopenharmony_ci const void *b, 570a8e1175bSopenharmony_ci size_t n, 571a8e1175bSopenharmony_ci size_t skip_head, 572a8e1175bSopenharmony_ci size_t skip_tail); 573a8e1175bSopenharmony_ci 574a8e1175bSopenharmony_ci#endif 575a8e1175bSopenharmony_ci 576a8e1175bSopenharmony_ci/* Include the implementation of static inline functions above. */ 577a8e1175bSopenharmony_ci#include "constant_time_impl.h" 578a8e1175bSopenharmony_ci 579a8e1175bSopenharmony_ci#endif /* MBEDTLS_CONSTANT_TIME_INTERNAL_H */ 580