godot/thirdparty/mbedtls/library/constant_time_impl.h

/**
 *  Constant-time functions
 *
 *  Copyright The Mbed TLS Contributors
 *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
 */

#ifndef MBEDTLS_CONSTANT_TIME_IMPL_H
#define MBEDTLS_CONSTANT_TIME_IMPL_H

#include <stddef.h>

#include "common.h"

#if defined(MBEDTLS_BIGNUM_C)
#include "mbedtls/bignum.h"
#endif

/*
 * To improve readability of constant_time_internal.h, the static inline
 * definitions are here, and constant_time_internal.h has only the declarations.
 *
 * This results in duplicate declarations of the form:
 *     static inline void f();         // from constant_time_internal.h
 *     static inline void f() { ... }  // from constant_time_impl.h
 * when constant_time_internal.h is included.
 *
 * This appears to behave as if the declaration-without-definition was not present
 * (except for warnings if gcc -Wredundant-decls or similar is used).
 *
 * Disable -Wredundant-decls so that gcc does not warn about this. This is re-enabled
 * at the bottom of this file.
 */
#if defined(MBEDTLS_COMPILER_IS_GCC) && (__GNUC__ > 4)
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wredundant-decls"
#endif

/* Disable asm under Memsan because it confuses Memsan and generates false errors.
 *
 * We also disable under Valgrind by default, because it's more useful
 * for Valgrind to test the plain C implementation. MBEDTLS_TEST_CONSTANT_FLOW_ASM //no-check-names
 * may be set to permit building asm under Valgrind.
 */
#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) || \
    (defined(MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND) && !defined(MBEDTLS_TEST_CONSTANT_FLOW_ASM)) //no-check-names
#define MBEDTLS_CT_NO_ASM
#elif defined(__has_feature)
#if __has_feature(memory_sanitizer)
#define MBEDTLS_CT_NO_ASM
#endif
#endif

/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && (!defined(__ARMCC_VERSION) || \
    __ARMCC_VERSION >= 6000000) && !defined(MBEDTLS_CT_NO_ASM)
#define MBEDTLS_CT_ASM
#if (defined(__arm__) || defined(__thumb__) || defined(__thumb2__))
#define MBEDTLS_CT_ARM_ASM
#elif defined(__aarch64__)
#define MBEDTLS_CT_AARCH64_ASM
#elif defined(__amd64__) || defined(__x86_64__)
#define MBEDTLS_CT_X86_64_ASM
#elif defined(__i386__)
#define MBEDTLS_CT_X86_ASM
#endif
#endif

#define MBEDTLS_CT_SIZE


/* ============================================================================
 * Core const-time primitives
 */

/* Ensure that the compiler cannot know the value of x (i.e., cannot optimise
 * based on its value) after this function is called.
 *
 * If we are not using assembly, this will be fairly inefficient, so its use
 * should be minimised.
 */

#if !defined(MBEDTLS_CT_ASM)
extern volatile mbedtls_ct_uint_t mbedtls_ct_zero;
#endif

/**
 * \brief   Ensure that a value cannot be known at compile time.
 *
 * \param x        The value to hide from the compiler.
 * \return         The same value that was passed in, such that the compiler
 *                 cannot prove its value (even for calls of the form
 *                 x = mbedtls_ct_compiler_opaque(1), x will be unknown).
 *
 * \note           This is mainly used in constructing mbedtls_ct_condition_t
 *                 values and performing operations over them, to ensure that
 *                 there is no way for the compiler to ever know anything about
 *                 the value of an mbedtls_ct_condition_t.
 */
static inline mbedtls_ct_uint_t mbedtls_ct_compiler_opaque(mbedtls_ct_uint_t x)
{}

/*
 * Selecting unified syntax is needed for gcc, and harmless on clang.
 *
 * This is needed because on Thumb 1, condition flags are always set, so
 * e.g. "negs" is supported but "neg" is not (on Thumb 2, both exist).
 *
 * Under Thumb 1 unified syntax, only the "negs" form is accepted, and
 * under divided syntax, only the "neg" form is accepted. clang only
 * supports unified syntax.
 *
 * On Thumb 2 and Arm, both compilers are happy with the "s" suffix,
 * although we don't actually care about setting the flags.
 *
 * For old versions of gcc (see #8516 for details), restore divided
 * syntax afterwards - otherwise old versions of gcc seem to apply
 * unified syntax globally, which breaks other asm code.
 */
#if defined(MBEDTLS_COMPILER_IS_GCC) && defined(__thumb__) && !defined(__thumb2__) && \
    (__GNUC__ < 11) && !defined(__ARM_ARCH_2__)
#define RESTORE_ASM_SYNTAX
#else
#define RESTORE_ASM_SYNTAX
#endif

/* Convert a number into a condition in constant time. */
static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x)
{}

static inline mbedtls_ct_uint_t mbedtls_ct_if(mbedtls_ct_condition_t condition,
                                              mbedtls_ct_uint_t if1,
                                              mbedtls_ct_uint_t if0)
{}

static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y)
{}

static inline mbedtls_ct_condition_t mbedtls_ct_uint_ne(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y)
{}

static inline unsigned char mbedtls_ct_uchar_in_range_if(unsigned char low,
                                                         unsigned char high,
                                                         unsigned char c,
                                                         unsigned char t)
{}

/* ============================================================================
 * Everything below here is trivial wrapper functions
 */

static inline size_t mbedtls_ct_size_if(mbedtls_ct_condition_t condition,
                                        size_t if1,
                                        size_t if0)
{}

static inline unsigned mbedtls_ct_uint_if(mbedtls_ct_condition_t condition,
                                          unsigned if1,
                                          unsigned 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)

static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if(mbedtls_ct_condition_t condition,
                                                      mbedtls_mpi_uint if1,
                                                      mbedtls_mpi_uint if0)
{}

#endif

static inline size_t mbedtls_ct_size_if_else_0(mbedtls_ct_condition_t condition, size_t if1)
{}

static inline unsigned mbedtls_ct_uint_if_else_0(mbedtls_ct_condition_t condition, unsigned if1)
{}

static inline mbedtls_ct_condition_t mbedtls_ct_bool_if_else_0(mbedtls_ct_condition_t condition,
                                                               mbedtls_ct_condition_t if1)
{}

#if defined(MBEDTLS_BIGNUM_C)

static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if_else_0(mbedtls_ct_condition_t condition,
                                                             mbedtls_mpi_uint if1)
{}

#endif /* MBEDTLS_BIGNUM_C */

static inline int mbedtls_ct_error_if(mbedtls_ct_condition_t condition, int if1, int if0)
{}

static inline int mbedtls_ct_error_if_else_0(mbedtls_ct_condition_t condition, int if1)
{}

static inline mbedtls_ct_condition_t mbedtls_ct_uint_eq(mbedtls_ct_uint_t x,
                                                        mbedtls_ct_uint_t y)
{}

static inline mbedtls_ct_condition_t mbedtls_ct_uint_gt(mbedtls_ct_uint_t x,
                                                        mbedtls_ct_uint_t y)
{}

static inline mbedtls_ct_condition_t mbedtls_ct_uint_ge(mbedtls_ct_uint_t x,
                                                        mbedtls_ct_uint_t y)
{}

static inline mbedtls_ct_condition_t mbedtls_ct_uint_le(mbedtls_ct_uint_t x,
                                                        mbedtls_ct_uint_t y)
{}

static inline mbedtls_ct_condition_t mbedtls_ct_bool_ne(mbedtls_ct_condition_t x,
                                                        mbedtls_ct_condition_t y)
{}

static inline mbedtls_ct_condition_t mbedtls_ct_bool_and(mbedtls_ct_condition_t x,
                                                         mbedtls_ct_condition_t y)
{}

static inline mbedtls_ct_condition_t mbedtls_ct_bool_or(mbedtls_ct_condition_t x,
                                                        mbedtls_ct_condition_t y)
{}

static inline mbedtls_ct_condition_t mbedtls_ct_bool_not(mbedtls_ct_condition_t x)
{}

#if defined(MBEDTLS_COMPILER_IS_GCC) && (__GNUC__ > 4)
/* Restore warnings for -Wredundant-decls on gcc */
    #pragma GCC diagnostic pop
#endif

#endif /* MBEDTLS_CONSTANT_TIME_IMPL_H */