Path: blob/master/thirdparty/mbedtls/library/constant_time_internal.h
9903 views
/**1* Constant-time functions2*3* Copyright The Mbed TLS Contributors4* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later5*/67#ifndef MBEDTLS_CONSTANT_TIME_INTERNAL_H8#define MBEDTLS_CONSTANT_TIME_INTERNAL_H910#include <stdint.h>11#include <stddef.h>1213#include "common.h"1415#if defined(MBEDTLS_BIGNUM_C)16#include "mbedtls/bignum.h"17#endif1819/* The constant-time interface provides various operations that are likely20* to result in constant-time code that does not branch or use conditional21* instructions for secret data (for secret pointers, this also applies to22* the data pointed to).23*24* It has three main parts:25*26* - boolean operations27* These are all named mbedtls_ct_<type>_<operation>.28* They operate over <type> and return mbedtls_ct_condition_t.29* All arguments are considered secret.30* example: bool x = y | z => x = mbedtls_ct_bool_or(y, z)31* example: bool x = y == z => x = mbedtls_ct_uint_eq(y, z)32*33* - conditional data selection34* These are all named mbedtls_ct_<type>_if and mbedtls_ct_<type>_if_else_035* All arguments are considered secret.36* example: size_t a = x ? b : c => a = mbedtls_ct_size_if(x, b, c)37* example: unsigned a = x ? b : 0 => a = mbedtls_ct_uint_if_else_0(x, b)38*39* - block memory operations40* Only some arguments are considered secret, as documented for each41* function.42* example: if (x) memcpy(...) => mbedtls_ct_memcpy_if(x, ...)43*44* mbedtls_ct_condition_t must be treated as opaque and only created and45* manipulated via the functions in this header. The compiler should never46* be able to prove anything about its value at compile-time.47*48* mbedtls_ct_uint_t is an unsigned integer type over which constant time49* operations may be performed via the functions in this header. It is as big50* as the larger of size_t and mbedtls_mpi_uint, i.e. it is safe to cast51* to/from "unsigned int", "size_t", and "mbedtls_mpi_uint" (and any other52* not-larger integer types).53*54* For Arm (32-bit, 64-bit and Thumb), x86 and x86-64, assembly implementations55* are used to ensure that the generated code is constant time. For other56* architectures, it uses a plain C fallback designed to yield constant-time code57* (this has been observed to be constant-time on latest gcc, clang and MSVC58* as of May 2023).59*60* For readability, the static inline definitions are separated out into61* constant_time_impl.h.62*/6364#if (SIZE_MAX > 0xffffffffffffffffULL)65/* Pointer size > 64-bit */66typedef size_t mbedtls_ct_condition_t;67typedef size_t mbedtls_ct_uint_t;68typedef ptrdiff_t mbedtls_ct_int_t;69#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(SIZE_MAX))70#elif (SIZE_MAX > 0xffffffff) || defined(MBEDTLS_HAVE_INT64)71/* 32-bit < pointer size <= 64-bit, or 64-bit MPI */72typedef uint64_t mbedtls_ct_condition_t;73typedef uint64_t mbedtls_ct_uint_t;74typedef int64_t mbedtls_ct_int_t;75#define MBEDTLS_CT_SIZE_6476#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT64_MAX))77#else78/* Pointer size <= 32-bit, and no 64-bit MPIs */79typedef uint32_t mbedtls_ct_condition_t;80typedef uint32_t mbedtls_ct_uint_t;81typedef int32_t mbedtls_ct_int_t;82#define MBEDTLS_CT_SIZE_3283#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT32_MAX))84#endif85#define MBEDTLS_CT_FALSE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(0))8687/* ============================================================================88* Boolean operations89*/9091/** Convert a number into a mbedtls_ct_condition_t.92*93* \param x Number to convert.94*95* \return MBEDTLS_CT_TRUE if \p x != 0, or MBEDTLS_CT_FALSE if \p x == 096*97*/98static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x);99100/** Boolean "not equal" operation.101*102* Functionally equivalent to:103*104* \p x != \p y105*106* \param x The first value to analyze.107* \param y The second value to analyze.108*109* \return MBEDTLS_CT_TRUE if \p x != \p y, otherwise MBEDTLS_CT_FALSE.110*/111static inline mbedtls_ct_condition_t mbedtls_ct_uint_ne(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y);112113/** Boolean "equals" operation.114*115* Functionally equivalent to:116*117* \p x == \p y118*119* \param x The first value to analyze.120* \param y The second value to analyze.121*122* \return MBEDTLS_CT_TRUE if \p x == \p y, otherwise MBEDTLS_CT_FALSE.123*/124static inline mbedtls_ct_condition_t mbedtls_ct_uint_eq(mbedtls_ct_uint_t x,125mbedtls_ct_uint_t y);126127/** Boolean "less than" operation.128*129* Functionally equivalent to:130*131* \p x < \p y132*133* \param x The first value to analyze.134* \param y The second value to analyze.135*136* \return MBEDTLS_CT_TRUE if \p x < \p y, otherwise MBEDTLS_CT_FALSE.137*/138static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y);139140/** Boolean "greater than" operation.141*142* Functionally equivalent to:143*144* \p x > \p y145*146* \param x The first value to analyze.147* \param y The second value to analyze.148*149* \return MBEDTLS_CT_TRUE if \p x > \p y, otherwise MBEDTLS_CT_FALSE.150*/151static inline mbedtls_ct_condition_t mbedtls_ct_uint_gt(mbedtls_ct_uint_t x,152mbedtls_ct_uint_t y);153154/** Boolean "greater or equal" operation.155*156* Functionally equivalent to:157*158* \p x >= \p y159*160* \param x The first value to analyze.161* \param y The second value to analyze.162*163* \return MBEDTLS_CT_TRUE if \p x >= \p y,164* otherwise MBEDTLS_CT_FALSE.165*/166static inline mbedtls_ct_condition_t mbedtls_ct_uint_ge(mbedtls_ct_uint_t x,167mbedtls_ct_uint_t y);168169/** Boolean "less than or equal" operation.170*171* Functionally equivalent to:172*173* \p x <= \p y174*175* \param x The first value to analyze.176* \param y The second value to analyze.177*178* \return MBEDTLS_CT_TRUE if \p x <= \p y,179* otherwise MBEDTLS_CT_FALSE.180*/181static inline mbedtls_ct_condition_t mbedtls_ct_uint_le(mbedtls_ct_uint_t x,182mbedtls_ct_uint_t y);183184/** Boolean not-equals operation.185*186* Functionally equivalent to:187*188* \p x != \p y189*190* \param x The first value to analyze.191* \param y The second value to analyze.192*193* \note This is more efficient than mbedtls_ct_uint_ne if both arguments are194* mbedtls_ct_condition_t.195*196* \return MBEDTLS_CT_TRUE if \p x != \p y,197* otherwise MBEDTLS_CT_FALSE.198*/199static inline mbedtls_ct_condition_t mbedtls_ct_bool_ne(mbedtls_ct_condition_t x,200mbedtls_ct_condition_t y);201202/** Boolean "and" operation.203*204* Functionally equivalent to:205*206* \p x && \p y207*208* \param x The first value to analyze.209* \param y The second value to analyze.210*211* \return MBEDTLS_CT_TRUE if \p x && \p y,212* otherwise MBEDTLS_CT_FALSE.213*/214static inline mbedtls_ct_condition_t mbedtls_ct_bool_and(mbedtls_ct_condition_t x,215mbedtls_ct_condition_t y);216217/** Boolean "or" operation.218*219* Functionally equivalent to:220*221* \p x || \p y222*223* \param x The first value to analyze.224* \param y The second value to analyze.225*226* \return MBEDTLS_CT_TRUE if \p x || \p y,227* otherwise MBEDTLS_CT_FALSE.228*/229static inline mbedtls_ct_condition_t mbedtls_ct_bool_or(mbedtls_ct_condition_t x,230mbedtls_ct_condition_t y);231232/** Boolean "not" operation.233*234* Functionally equivalent to:235*236* ! \p x237*238* \param x The value to invert239*240* \return MBEDTLS_CT_FALSE if \p x, otherwise MBEDTLS_CT_TRUE.241*/242static inline mbedtls_ct_condition_t mbedtls_ct_bool_not(mbedtls_ct_condition_t x);243244245/* ============================================================================246* Data selection operations247*/248249/** Choose between two size_t values.250*251* Functionally equivalent to:252*253* condition ? if1 : if0.254*255* \param condition Condition to test.256* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.257* \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.258*259* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.260*/261static inline size_t mbedtls_ct_size_if(mbedtls_ct_condition_t condition,262size_t if1,263size_t if0);264265/** Choose between two unsigned values.266*267* Functionally equivalent to:268*269* condition ? if1 : if0.270*271* \param condition Condition to test.272* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.273* \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.274*275* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.276*/277static inline unsigned mbedtls_ct_uint_if(mbedtls_ct_condition_t condition,278unsigned if1,279unsigned if0);280281/** Choose between two mbedtls_ct_condition_t values.282*283* Functionally equivalent to:284*285* condition ? if1 : if0.286*287* \param condition Condition to test.288* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.289* \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.290*291* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.292*/293static inline mbedtls_ct_condition_t mbedtls_ct_bool_if(mbedtls_ct_condition_t condition,294mbedtls_ct_condition_t if1,295mbedtls_ct_condition_t if0);296297#if defined(MBEDTLS_BIGNUM_C)298299/** Choose between two mbedtls_mpi_uint values.300*301* Functionally equivalent to:302*303* condition ? if1 : if0.304*305* \param condition Condition to test.306* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.307* \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.308*309* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.310*/311static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if(mbedtls_ct_condition_t condition, \312mbedtls_mpi_uint if1, \313mbedtls_mpi_uint if0);314315#endif316317/** Choose between an unsigned value and 0.318*319* Functionally equivalent to:320*321* condition ? if1 : 0.322*323* Functionally equivalent to mbedtls_ct_uint_if(condition, if1, 0) but324* results in smaller code size.325*326* \param condition Condition to test.327* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.328*329* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.330*/331static inline unsigned mbedtls_ct_uint_if_else_0(mbedtls_ct_condition_t condition, unsigned if1);332333/** Choose between an mbedtls_ct_condition_t and 0.334*335* Functionally equivalent to:336*337* condition ? if1 : 0.338*339* Functionally equivalent to mbedtls_ct_bool_if(condition, if1, 0) but340* results in smaller code size.341*342* \param condition Condition to test.343* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.344*345* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.346*/347static inline mbedtls_ct_condition_t mbedtls_ct_bool_if_else_0(mbedtls_ct_condition_t condition,348mbedtls_ct_condition_t if1);349350/** Choose between a size_t value and 0.351*352* Functionally equivalent to:353*354* condition ? if1 : 0.355*356* Functionally equivalent to mbedtls_ct_size_if(condition, if1, 0) but357* results in smaller code size.358*359* \param condition Condition to test.360* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.361*362* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.363*/364static inline size_t mbedtls_ct_size_if_else_0(mbedtls_ct_condition_t condition, size_t if1);365366#if defined(MBEDTLS_BIGNUM_C)367368/** Choose between an mbedtls_mpi_uint value and 0.369*370* Functionally equivalent to:371*372* condition ? if1 : 0.373*374* Functionally equivalent to mbedtls_ct_mpi_uint_if(condition, if1, 0) but375* results in smaller code size.376*377* \param condition Condition to test.378* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.379*380* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.381*/382static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if_else_0(mbedtls_ct_condition_t condition,383mbedtls_mpi_uint if1);384385#endif386387/** Constant-flow char selection388*389* \param low Secret. Bottom of range390* \param high Secret. Top of range391* \param c Secret. Value to compare to range392* \param t Secret. Value to return, if in range393*394* \return \p t if \p low <= \p c <= \p high, 0 otherwise.395*/396static inline unsigned char mbedtls_ct_uchar_in_range_if(unsigned char low,397unsigned char high,398unsigned char c,399unsigned char t);400401/** Choose between two error values. The values must be in the range [-32767..0].402*403* Functionally equivalent to:404*405* condition ? if1 : if0.406*407* \param condition Condition to test.408* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.409* \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.410*411* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.412*/413static inline int mbedtls_ct_error_if(mbedtls_ct_condition_t condition, int if1, int if0);414415/** Choose between an error value and 0. The error value must be in the range [-32767..0].416*417* Functionally equivalent to:418*419* condition ? if1 : 0.420*421* Functionally equivalent to mbedtls_ct_error_if(condition, if1, 0) but422* results in smaller code size.423*424* \param condition Condition to test.425* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.426*427* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.428*/429static inline int mbedtls_ct_error_if_else_0(mbedtls_ct_condition_t condition, int if1);430431/* ============================================================================432* Block memory operations433*/434435#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)436437/** Conditionally set a block of memory to zero.438*439* Regardless of the condition, every byte will be read once and written to440* once.441*442* \param condition Secret. Condition to test.443* \param buf Secret. Pointer to the start of the buffer.444* \param len Number of bytes to set to zero.445*446* \warning Unlike mbedtls_platform_zeroize, this does not have the same guarantees447* about not being optimised away if the memory is never read again.448*/449void mbedtls_ct_zeroize_if(mbedtls_ct_condition_t condition, void *buf, size_t len);450451/** Shift some data towards the left inside a buffer.452*453* Functionally equivalent to:454*455* memmove(start, start + offset, total - offset);456* memset(start + (total - offset), 0, offset);457*458* Timing independence comes at the expense of performance.459*460* \param start Secret. Pointer to the start of the buffer.461* \param total Total size of the buffer.462* \param offset Secret. Offset from which to copy \p total - \p offset bytes.463*/464void mbedtls_ct_memmove_left(void *start,465size_t total,466size_t offset);467468#endif /* defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) */469470/** Conditional memcpy.471*472* Functionally equivalent to:473*474* if (condition) {475* memcpy(dest, src1, len);476* } else {477* if (src2 != NULL)478* memcpy(dest, src2, len);479* }480*481* It will always read len bytes from src1.482* If src2 != NULL, it will always read len bytes from src2.483* If src2 == NULL, it will instead read len bytes from dest (as if src2 == dest).484*485* \param condition The condition486* \param dest Secret. Destination pointer.487* \param src1 Secret. Pointer to copy from (if \p condition == MBEDTLS_CT_TRUE).488* This may be equal to \p dest, but may not overlap in other ways.489* \param src2 Secret (contents only - may branch to determine if this parameter is NULL).490* Pointer to copy from (if \p condition == MBEDTLS_CT_FALSE and \p src2 is not NULL). May be NULL.491* This may be equal to \p dest, but may not overlap it in other ways. It may overlap with \p src1.492* \param len Number of bytes to copy.493*/494void mbedtls_ct_memcpy_if(mbedtls_ct_condition_t condition,495unsigned char *dest,496const unsigned char *src1,497const unsigned char *src2,498size_t len499);500501/** Copy data from a secret position.502*503* Functionally equivalent to:504*505* memcpy(dst, src + offset, len)506*507* This function copies \p len bytes from \p src + \p offset to508* \p dst, with a code flow and memory access pattern that does not depend on509* \p offset, but only on \p offset_min, \p offset_max and \p len.510*511* \note This function reads from \p dest, but the value that512* is read does not influence the result and this513* function's behavior is well-defined regardless of the514* contents of the buffers. This may result in false515* positives from static or dynamic analyzers, especially516* if \p dest is not initialized.517*518* \param dest Secret. The destination buffer. This must point to a writable519* buffer of at least \p len bytes.520* \param src Secret. The base of the source buffer. This must point to a521* readable buffer of at least \p offset_max + \p len522* bytes. Shouldn't overlap with \p dest523* \param offset Secret. The offset in the source buffer from which to copy.524* This must be no less than \p offset_min and no greater525* than \p offset_max.526* \param offset_min The minimal value of \p offset.527* \param offset_max The maximal value of \p offset.528* \param len The number of bytes to copy.529*/530void mbedtls_ct_memcpy_offset(unsigned char *dest,531const unsigned char *src,532size_t offset,533size_t offset_min,534size_t offset_max,535size_t len);536537/* Documented in include/mbedtls/constant_time.h. a and b are secret.538539int mbedtls_ct_memcmp(const void *a,540const void *b,541size_t n);542*/543544#if defined(MBEDTLS_NIST_KW_C)545546/** Constant-time buffer comparison without branches.547*548* Similar to mbedtls_ct_memcmp, except that the result only depends on part of549* the input data - differences in the head or tail are ignored. Functionally equivalent to:550*551* memcmp(a + skip_head, b + skip_head, size - skip_head - skip_tail)552*553* Time taken depends on \p n, but not on \p skip_head or \p skip_tail .554*555* Behaviour is undefined if ( \p skip_head + \p skip_tail) > \p n.556*557* \param a Secret. Pointer to the first buffer, containing at least \p n bytes. May not be NULL.558* \param b Secret. Pointer to the second buffer, containing at least \p n bytes. May not be NULL.559* \param n The number of bytes to examine (total size of the buffers).560* \param skip_head Secret. The number of bytes to treat as non-significant at the start of the buffer.561* These bytes will still be read.562* \param skip_tail Secret. The number of bytes to treat as non-significant at the end of the buffer.563* These bytes will still be read.564*565* \return Zero if the contents of the two buffers are the same, otherwise non-zero.566*/567int mbedtls_ct_memcmp_partial(const void *a,568const void *b,569size_t n,570size_t skip_head,571size_t skip_tail);572573#endif574575/* Include the implementation of static inline functions above. */576#include "constant_time_impl.h"577578#endif /* MBEDTLS_CONSTANT_TIME_INTERNAL_H */579580581