mirror of
				https://github.com/Mbed-TLS/mbedtls.git
				synced 2025-10-30 10:45:34 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			580 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			580 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /**
 | |
|  *  Constant-time functions
 | |
|  *
 | |
|  *  Copyright The Mbed TLS Contributors
 | |
|  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
 | |
|  */
 | |
| 
 | |
| #ifndef MBEDTLS_CONSTANT_TIME_INTERNAL_H
 | |
| #define MBEDTLS_CONSTANT_TIME_INTERNAL_H
 | |
| 
 | |
| #include <stdint.h>
 | |
| #include <stddef.h>
 | |
| 
 | |
| #include "common.h"
 | |
| 
 | |
| #if defined(MBEDTLS_BIGNUM_C)
 | |
| #include "mbedtls/bignum.h"
 | |
| #endif
 | |
| 
 | |
| /* The constant-time interface provides various operations that are likely
 | |
|  * to result in constant-time code that does not branch or use conditional
 | |
|  * instructions for secret data (for secret pointers, this also applies to
 | |
|  * the data pointed to).
 | |
|  *
 | |
|  * It has three main parts:
 | |
|  *
 | |
|  * - boolean operations
 | |
|  *   These are all named mbedtls_ct_<type>_<operation>.
 | |
|  *   They operate over <type> and return mbedtls_ct_condition_t.
 | |
|  *   All arguments are considered secret.
 | |
|  *   example: bool x = y | z          =>    x = mbedtls_ct_bool_or(y, z)
 | |
|  *   example: bool x = y == z         =>    x = mbedtls_ct_uint_eq(y, z)
 | |
|  *
 | |
|  * - conditional data selection
 | |
|  *   These are all named mbedtls_ct_<type>_if and mbedtls_ct_<type>_if_else_0
 | |
|  *   All arguments are considered secret.
 | |
|  *   example: size_t a = x ? b : c    =>    a = mbedtls_ct_size_if(x, b, c)
 | |
|  *   example: unsigned a = x ? b : 0  =>    a = mbedtls_ct_uint_if_else_0(x, b)
 | |
|  *
 | |
|  * - block memory operations
 | |
|  *   Only some arguments are considered secret, as documented for each
 | |
|  *   function.
 | |
|  *   example: if (x) memcpy(...)      =>    mbedtls_ct_memcpy_if(x, ...)
 | |
|  *
 | |
|  * mbedtls_ct_condition_t must be treated as opaque and only created and
 | |
|  * manipulated via the functions in this header. The compiler should never
 | |
|  * be able to prove anything about its value at compile-time.
 | |
|  *
 | |
|  * mbedtls_ct_uint_t is an unsigned integer type over which constant time
 | |
|  * operations may be performed via the functions in this header. It is as big
 | |
|  * as the larger of size_t and mbedtls_mpi_uint, i.e. it is safe to cast
 | |
|  * to/from "unsigned int", "size_t", and "mbedtls_mpi_uint" (and any other
 | |
|  * not-larger integer types).
 | |
|  *
 | |
|  * For Arm (32-bit, 64-bit and Thumb), x86 and x86-64, assembly implementations
 | |
|  * are used to ensure that the generated code is constant time. For other
 | |
|  * architectures, it uses a plain C fallback designed to yield constant-time code
 | |
|  * (this has been observed to be constant-time on latest gcc, clang and MSVC
 | |
|  * as of May 2023).
 | |
|  *
 | |
|  * For readability, the static inline definitions are separated out into
 | |
|  * constant_time_impl.h.
 | |
|  */
 | |
| 
 | |
| #if (SIZE_MAX > 0xffffffffffffffffULL)
 | |
| /* Pointer size > 64-bit */
 | |
| typedef size_t    mbedtls_ct_condition_t;
 | |
| typedef size_t    mbedtls_ct_uint_t;
 | |
| typedef ptrdiff_t mbedtls_ct_int_t;
 | |
| #define MBEDTLS_CT_TRUE  ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(SIZE_MAX))
 | |
| #elif (SIZE_MAX > 0xffffffff) || defined(MBEDTLS_HAVE_INT64)
 | |
| /* 32-bit < pointer size <= 64-bit, or 64-bit MPI */
 | |
| typedef uint64_t  mbedtls_ct_condition_t;
 | |
| typedef uint64_t  mbedtls_ct_uint_t;
 | |
| typedef int64_t   mbedtls_ct_int_t;
 | |
| #define MBEDTLS_CT_SIZE_64
 | |
| #define MBEDTLS_CT_TRUE  ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT64_MAX))
 | |
| #else
 | |
| /* Pointer size <= 32-bit, and no 64-bit MPIs */
 | |
| typedef uint32_t  mbedtls_ct_condition_t;
 | |
| typedef uint32_t  mbedtls_ct_uint_t;
 | |
| typedef int32_t   mbedtls_ct_int_t;
 | |
| #define MBEDTLS_CT_SIZE_32
 | |
| #define MBEDTLS_CT_TRUE  ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT32_MAX))
 | |
| #endif
 | |
| #define MBEDTLS_CT_FALSE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(0))
 | |
| 
 | |
| /* ============================================================================
 | |
|  * Boolean operations
 | |
|  */
 | |
| 
 | |
| /** Convert a number into a mbedtls_ct_condition_t.
 | |
|  *
 | |
|  * \param x Number to convert.
 | |
|  *
 | |
|  * \return MBEDTLS_CT_TRUE if \p x != 0, or MBEDTLS_CT_FALSE if \p x == 0
 | |
|  *
 | |
|  */
 | |
| static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x);
 | |
| 
 | |
| /** Boolean "not equal" operation.
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * \p x != \p y
 | |
|  *
 | |
|  * \param x     The first value to analyze.
 | |
|  * \param y     The second value to analyze.
 | |
|  *
 | |
|  * \return      MBEDTLS_CT_TRUE if \p x != \p y, otherwise MBEDTLS_CT_FALSE.
 | |
|  */
 | |
| static inline mbedtls_ct_condition_t mbedtls_ct_uint_ne(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y);
 | |
| 
 | |
| /** Boolean "equals" operation.
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * \p x == \p y
 | |
|  *
 | |
|  * \param x     The first value to analyze.
 | |
|  * \param y     The second value to analyze.
 | |
|  *
 | |
|  * \return      MBEDTLS_CT_TRUE if \p x == \p y, otherwise MBEDTLS_CT_FALSE.
 | |
|  */
 | |
| static inline mbedtls_ct_condition_t mbedtls_ct_uint_eq(mbedtls_ct_uint_t x,
 | |
|                                                         mbedtls_ct_uint_t y);
 | |
| 
 | |
| /** Boolean "less than" operation.
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * \p x < \p y
 | |
|  *
 | |
|  * \param x     The first value to analyze.
 | |
|  * \param y     The second value to analyze.
 | |
|  *
 | |
|  * \return      MBEDTLS_CT_TRUE if \p x < \p y, otherwise MBEDTLS_CT_FALSE.
 | |
|  */
 | |
| static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y);
 | |
| 
 | |
| /** Boolean "greater than" operation.
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * \p x > \p y
 | |
|  *
 | |
|  * \param x     The first value to analyze.
 | |
|  * \param y     The second value to analyze.
 | |
|  *
 | |
|  * \return      MBEDTLS_CT_TRUE if \p x > \p y, otherwise MBEDTLS_CT_FALSE.
 | |
|  */
 | |
| static inline mbedtls_ct_condition_t mbedtls_ct_uint_gt(mbedtls_ct_uint_t x,
 | |
|                                                         mbedtls_ct_uint_t y);
 | |
| 
 | |
| /** Boolean "greater or equal" operation.
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * \p x >= \p y
 | |
|  *
 | |
|  * \param x     The first value to analyze.
 | |
|  * \param y     The second value to analyze.
 | |
|  *
 | |
|  * \return      MBEDTLS_CT_TRUE if \p x >= \p y,
 | |
|  *              otherwise MBEDTLS_CT_FALSE.
 | |
|  */
 | |
| static inline mbedtls_ct_condition_t mbedtls_ct_uint_ge(mbedtls_ct_uint_t x,
 | |
|                                                         mbedtls_ct_uint_t y);
 | |
| 
 | |
| /** Boolean "less than or equal" operation.
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * \p x <= \p y
 | |
|  *
 | |
|  * \param x     The first value to analyze.
 | |
|  * \param y     The second value to analyze.
 | |
|  *
 | |
|  * \return      MBEDTLS_CT_TRUE if \p x <= \p y,
 | |
|  *              otherwise MBEDTLS_CT_FALSE.
 | |
|  */
 | |
| static inline mbedtls_ct_condition_t mbedtls_ct_uint_le(mbedtls_ct_uint_t x,
 | |
|                                                         mbedtls_ct_uint_t y);
 | |
| 
 | |
| /** Boolean not-equals operation.
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * \p x != \p y
 | |
|  *
 | |
|  * \param x     The first value to analyze.
 | |
|  * \param y     The second value to analyze.
 | |
|  *
 | |
|  * \note        This is more efficient than mbedtls_ct_uint_ne if both arguments are
 | |
|  *              mbedtls_ct_condition_t.
 | |
|  *
 | |
|  * \return      MBEDTLS_CT_TRUE if \p x != \p y,
 | |
|  *              otherwise MBEDTLS_CT_FALSE.
 | |
|  */
 | |
| static inline mbedtls_ct_condition_t mbedtls_ct_bool_ne(mbedtls_ct_condition_t x,
 | |
|                                                         mbedtls_ct_condition_t y);
 | |
| 
 | |
| /** Boolean "and" operation.
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * \p x && \p y
 | |
|  *
 | |
|  * \param x     The first value to analyze.
 | |
|  * \param y     The second value to analyze.
 | |
|  *
 | |
|  * \return      MBEDTLS_CT_TRUE if \p x && \p y,
 | |
|  *              otherwise MBEDTLS_CT_FALSE.
 | |
|  */
 | |
| static inline mbedtls_ct_condition_t mbedtls_ct_bool_and(mbedtls_ct_condition_t x,
 | |
|                                                          mbedtls_ct_condition_t y);
 | |
| 
 | |
| /** Boolean "or" operation.
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * \p x || \p y
 | |
|  *
 | |
|  * \param x     The first value to analyze.
 | |
|  * \param y     The second value to analyze.
 | |
|  *
 | |
|  * \return      MBEDTLS_CT_TRUE if \p x || \p y,
 | |
|  *              otherwise MBEDTLS_CT_FALSE.
 | |
|  */
 | |
| static inline mbedtls_ct_condition_t mbedtls_ct_bool_or(mbedtls_ct_condition_t x,
 | |
|                                                         mbedtls_ct_condition_t y);
 | |
| 
 | |
| /** Boolean "not" operation.
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * ! \p x
 | |
|  *
 | |
|  * \param x     The value to invert
 | |
|  *
 | |
|  * \return      MBEDTLS_CT_FALSE if \p x, otherwise MBEDTLS_CT_TRUE.
 | |
|  */
 | |
| static inline mbedtls_ct_condition_t mbedtls_ct_bool_not(mbedtls_ct_condition_t x);
 | |
| 
 | |
| 
 | |
| /* ============================================================================
 | |
|  * Data selection operations
 | |
|  */
 | |
| 
 | |
| /** Choose between two size_t values.
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * condition ? if1 : if0.
 | |
|  *
 | |
|  * \param condition     Condition to test.
 | |
|  * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
 | |
|  * \param if0           Value to use if \p condition == MBEDTLS_CT_FALSE.
 | |
|  *
 | |
|  * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
 | |
|  */
 | |
| static inline size_t mbedtls_ct_size_if(mbedtls_ct_condition_t condition,
 | |
|                                         size_t if1,
 | |
|                                         size_t if0);
 | |
| 
 | |
| /** Choose between two unsigned values.
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * condition ? if1 : if0.
 | |
|  *
 | |
|  * \param condition     Condition to test.
 | |
|  * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
 | |
|  * \param if0           Value to use if \p condition == MBEDTLS_CT_FALSE.
 | |
|  *
 | |
|  * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
 | |
|  */
 | |
| static inline unsigned mbedtls_ct_uint_if(mbedtls_ct_condition_t condition,
 | |
|                                           unsigned if1,
 | |
|                                           unsigned if0);
 | |
| 
 | |
| /** Choose between two mbedtls_ct_condition_t values.
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * condition ? if1 : if0.
 | |
|  *
 | |
|  * \param condition     Condition to test.
 | |
|  * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
 | |
|  * \param if0           Value to use if \p condition == MBEDTLS_CT_FALSE.
 | |
|  *
 | |
|  * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
 | |
|  */
 | |
| static inline mbedtls_ct_condition_t mbedtls_ct_bool_if(mbedtls_ct_condition_t condition,
 | |
|                                                         mbedtls_ct_condition_t if1,
 | |
|                                                         mbedtls_ct_condition_t if0);
 | |
| 
 | |
| #if defined(MBEDTLS_BIGNUM_C)
 | |
| 
 | |
| /** Choose between two mbedtls_mpi_uint values.
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * condition ? if1 : if0.
 | |
|  *
 | |
|  * \param condition     Condition to test.
 | |
|  * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
 | |
|  * \param if0           Value to use if \p condition == MBEDTLS_CT_FALSE.
 | |
|  *
 | |
|  * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
 | |
|  */
 | |
| static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if(mbedtls_ct_condition_t condition, \
 | |
|                                                       mbedtls_mpi_uint if1, \
 | |
|                                                       mbedtls_mpi_uint if0);
 | |
| 
 | |
| #endif
 | |
| 
 | |
| /** Choose between an unsigned value and 0.
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * condition ? if1 : 0.
 | |
|  *
 | |
|  * Functionally equivalent to mbedtls_ct_uint_if(condition, if1, 0) but
 | |
|  * results in smaller code size.
 | |
|  *
 | |
|  * \param condition     Condition to test.
 | |
|  * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
 | |
|  *
 | |
|  * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
 | |
|  */
 | |
| static inline unsigned mbedtls_ct_uint_if_else_0(mbedtls_ct_condition_t condition, unsigned if1);
 | |
| 
 | |
| /** Choose between an mbedtls_ct_condition_t and 0.
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * condition ? if1 : 0.
 | |
|  *
 | |
|  * Functionally equivalent to mbedtls_ct_bool_if(condition, if1, 0) but
 | |
|  * results in smaller code size.
 | |
|  *
 | |
|  * \param condition     Condition to test.
 | |
|  * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
 | |
|  *
 | |
|  * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
 | |
|  */
 | |
| static inline mbedtls_ct_condition_t mbedtls_ct_bool_if_else_0(mbedtls_ct_condition_t condition,
 | |
|                                                                mbedtls_ct_condition_t if1);
 | |
| 
 | |
| /** Choose between a size_t value and 0.
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * condition ? if1 : 0.
 | |
|  *
 | |
|  * Functionally equivalent to mbedtls_ct_size_if(condition, if1, 0) but
 | |
|  * results in smaller code size.
 | |
|  *
 | |
|  * \param condition     Condition to test.
 | |
|  * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
 | |
|  *
 | |
|  * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
 | |
|  */
 | |
| static inline size_t mbedtls_ct_size_if_else_0(mbedtls_ct_condition_t condition, size_t if1);
 | |
| 
 | |
| #if defined(MBEDTLS_BIGNUM_C)
 | |
| 
 | |
| /** Choose between an mbedtls_mpi_uint value and 0.
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * condition ? if1 : 0.
 | |
|  *
 | |
|  * Functionally equivalent to mbedtls_ct_mpi_uint_if(condition, if1, 0) but
 | |
|  * results in smaller code size.
 | |
|  *
 | |
|  * \param condition     Condition to test.
 | |
|  * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
 | |
|  *
 | |
|  * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
 | |
|  */
 | |
| static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if_else_0(mbedtls_ct_condition_t condition,
 | |
|                                                              mbedtls_mpi_uint if1);
 | |
| 
 | |
| #endif
 | |
| 
 | |
| /** Constant-flow char selection
 | |
|  *
 | |
|  * \param low   Secret. Bottom of range
 | |
|  * \param high  Secret. Top of range
 | |
|  * \param c     Secret. Value to compare to range
 | |
|  * \param t     Secret. Value to return, if in range
 | |
|  *
 | |
|  * \return      \p t if \p low <= \p c <= \p high, 0 otherwise.
 | |
|  */
 | |
| static inline unsigned char mbedtls_ct_uchar_in_range_if(unsigned char low,
 | |
|                                                          unsigned char high,
 | |
|                                                          unsigned char c,
 | |
|                                                          unsigned char t);
 | |
| 
 | |
| /** Choose between two error values. The values must be in the range [-32767..0].
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * condition ? if1 : if0.
 | |
|  *
 | |
|  * \param condition     Condition to test.
 | |
|  * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
 | |
|  * \param if0           Value to use if \p condition == MBEDTLS_CT_FALSE.
 | |
|  *
 | |
|  * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
 | |
|  */
 | |
| static inline int mbedtls_ct_error_if(mbedtls_ct_condition_t condition, int if1, int if0);
 | |
| 
 | |
| /** Choose between an error value and 0. The error value must be in the range [-32767..0].
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * condition ? if1 : 0.
 | |
|  *
 | |
|  * Functionally equivalent to mbedtls_ct_error_if(condition, if1, 0) but
 | |
|  * results in smaller code size.
 | |
|  *
 | |
|  * \param condition     Condition to test.
 | |
|  * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
 | |
|  *
 | |
|  * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
 | |
|  */
 | |
| static inline int mbedtls_ct_error_if_else_0(mbedtls_ct_condition_t condition, int if1);
 | |
| 
 | |
| /* ============================================================================
 | |
|  * Block memory operations
 | |
|  */
 | |
| 
 | |
| #if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
 | |
| 
 | |
| /** Conditionally set a block of memory to zero.
 | |
|  *
 | |
|  * Regardless of the condition, every byte will be read once and written to
 | |
|  * once.
 | |
|  *
 | |
|  * \param condition     Secret. Condition to test.
 | |
|  * \param buf           Secret. Pointer to the start of the buffer.
 | |
|  * \param len           Number of bytes to set to zero.
 | |
|  *
 | |
|  * \warning Unlike mbedtls_platform_zeroize, this does not have the same guarantees
 | |
|  * about not being optimised away if the memory is never read again.
 | |
|  */
 | |
| void mbedtls_ct_zeroize_if(mbedtls_ct_condition_t condition, void *buf, size_t len);
 | |
| 
 | |
| /** Shift some data towards the left inside a buffer.
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * memmove(start, start + offset, total - offset);
 | |
|  * memset(start + (total - offset), 0, offset);
 | |
|  *
 | |
|  * Timing independence comes at the expense of performance.
 | |
|  *
 | |
|  * \param start     Secret. Pointer to the start of the buffer.
 | |
|  * \param total     Total size of the buffer.
 | |
|  * \param offset    Secret. Offset from which to copy \p total - \p offset bytes.
 | |
|  */
 | |
| void mbedtls_ct_memmove_left(void *start,
 | |
|                              size_t total,
 | |
|                              size_t offset);
 | |
| 
 | |
| #endif /* defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) */
 | |
| 
 | |
| /** Conditional memcpy.
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * if (condition) {
 | |
|  *      memcpy(dest, src1, len);
 | |
|  * } else {
 | |
|  *      if (src2 != NULL)
 | |
|  *          memcpy(dest, src2, len);
 | |
|  * }
 | |
|  *
 | |
|  * It will always read len bytes from src1.
 | |
|  * If src2 != NULL, it will always read len bytes from src2.
 | |
|  * If src2 == NULL, it will instead read len bytes from dest (as if src2 == dest).
 | |
|  *
 | |
|  * \param condition The condition
 | |
|  * \param dest      Secret. Destination pointer.
 | |
|  * \param src1      Secret. Pointer to copy from (if \p condition == MBEDTLS_CT_TRUE).
 | |
|  *                  This may be equal to \p dest, but may not overlap in other ways.
 | |
|  * \param src2      Secret (contents only - may branch to determine if this parameter is NULL).
 | |
|  *                  Pointer to copy from (if \p condition == MBEDTLS_CT_FALSE and \p src2 is not NULL). May be NULL.
 | |
|  *                  This may be equal to \p dest, but may not overlap it in other ways. It may overlap with \p src1.
 | |
|  * \param len       Number of bytes to copy.
 | |
|  */
 | |
| void mbedtls_ct_memcpy_if(mbedtls_ct_condition_t condition,
 | |
|                           unsigned char *dest,
 | |
|                           const unsigned char *src1,
 | |
|                           const unsigned char *src2,
 | |
|                           size_t len
 | |
|                           );
 | |
| 
 | |
| /** Copy data from a secret position.
 | |
|  *
 | |
|  * Functionally equivalent to:
 | |
|  *
 | |
|  * memcpy(dst, src + offset, len)
 | |
|  *
 | |
|  * This function copies \p len bytes from \p src + \p offset to
 | |
|  * \p dst, with a code flow and memory access pattern that does not depend on
 | |
|  * \p offset, but only on \p offset_min, \p offset_max and \p len.
 | |
|  *
 | |
|  * \note                This function reads from \p dest, but the value that
 | |
|  *                      is read does not influence the result and this
 | |
|  *                      function's behavior is well-defined regardless of the
 | |
|  *                      contents of the buffers. This may result in false
 | |
|  *                      positives from static or dynamic analyzers, especially
 | |
|  *                      if \p dest is not initialized.
 | |
|  *
 | |
|  * \param dest          Secret. The destination buffer. This must point to a writable
 | |
|  *                      buffer of at least \p len bytes.
 | |
|  * \param src           Secret. The base of the source buffer. This must point to a
 | |
|  *                      readable buffer of at least \p offset_max + \p len
 | |
|  *                      bytes. Shouldn't overlap with \p dest
 | |
|  * \param offset        Secret. The offset in the source buffer from which to copy.
 | |
|  *                      This must be no less than \p offset_min and no greater
 | |
|  *                      than \p offset_max.
 | |
|  * \param offset_min    The minimal value of \p offset.
 | |
|  * \param offset_max    The maximal value of \p offset.
 | |
|  * \param len           The number of bytes to copy.
 | |
|  */
 | |
| void mbedtls_ct_memcpy_offset(unsigned char *dest,
 | |
|                               const unsigned char *src,
 | |
|                               size_t offset,
 | |
|                               size_t offset_min,
 | |
|                               size_t offset_max,
 | |
|                               size_t len);
 | |
| 
 | |
| /* Documented in include/mbedtls/constant_time.h. a and b are secret.
 | |
| 
 | |
|    int mbedtls_ct_memcmp(const void *a,
 | |
|                          const void *b,
 | |
|                          size_t n);
 | |
|  */
 | |
| 
 | |
| #if defined(MBEDTLS_NIST_KW_C)
 | |
| 
 | |
| /** Constant-time buffer comparison without branches.
 | |
|  *
 | |
|  * Similar to mbedtls_ct_memcmp, except that the result only depends on part of
 | |
|  * the input data - differences in the head or tail are ignored. Functionally equivalent to:
 | |
|  *
 | |
|  * memcmp(a + skip_head, b + skip_head, size - skip_head - skip_tail)
 | |
|  *
 | |
|  * Time taken depends on \p n, but not on \p skip_head or \p skip_tail .
 | |
|  *
 | |
|  * Behaviour is undefined if ( \p skip_head + \p skip_tail) > \p n.
 | |
|  *
 | |
|  * \param a         Secret. Pointer to the first buffer, containing at least \p n bytes. May not be NULL.
 | |
|  * \param b         Secret. Pointer to the second buffer, containing at least \p n bytes. May not be NULL.
 | |
|  * \param n         The number of bytes to examine (total size of the buffers).
 | |
|  * \param skip_head Secret. The number of bytes to treat as non-significant at the start of the buffer.
 | |
|  *                  These bytes will still be read.
 | |
|  * \param skip_tail Secret. The number of bytes to treat as non-significant at the end of the buffer.
 | |
|  *                  These bytes will still be read.
 | |
|  *
 | |
|  * \return          Zero if the contents of the two buffers are the same, otherwise non-zero.
 | |
|  */
 | |
| int mbedtls_ct_memcmp_partial(const void *a,
 | |
|                               const void *b,
 | |
|                               size_t n,
 | |
|                               size_t skip_head,
 | |
|                               size_t skip_tail);
 | |
| 
 | |
| #endif
 | |
| 
 | |
| /* Include the implementation of static inline functions above. */
 | |
| #include "constant_time_impl.h"
 | |
| 
 | |
| #endif /* MBEDTLS_CONSTANT_TIME_INTERNAL_H */
 |