#ifndef OPENSSL_HEADER_CRYPTO_INTERNAL_H
#define OPENSSL_HEADER_CRYPTO_INTERNAL_H
#include <GFp/base.h>
#if defined(_MSC_VER)
#pragma warning(push, 3)
#endif
#include <assert.h>
#if defined(__clang__) || defined(_MSC_VER)
#include <string.h>
#endif
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#if defined(BORINGSSL_CONSTANT_TIME_VALIDATION)
#include <valgrind/memcheck.h>
#endif
#include <GFp/type_check.h>
#if defined(_MSC_VER)
#pragma warning(push, 3)
#include <intrin.h>
#pragma warning(pop)
#endif
#if defined(__GNUC__) && \
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
#define alignas(x) __attribute__ ((aligned (x)))
#define alignof(x) __alignof__ (x)
#elif defined(_MSC_VER)
#define alignas(x) __declspec(align(x))
#define alignof(x) __alignof(x)
#else
#include <stdalign.h>
#endif
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || defined(OPENSSL_ARM) || \
defined(OPENSSL_AARCH64) || defined(OPENSSL_PPC64LE)
void GFp_cpuid_setup(void);
#endif
#define OPENSSL_LITTLE_ENDIAN 1
#define OPENSSL_BIG_ENDIAN 2
#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86) || \
(defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
#define OPENSSL_ENDIAN OPENSSL_LITTLE_ENDIAN
#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define OPENSSL_ENDIAN OPENSSL_BIG_ENDIAN
#else
#error "Cannot determine endianness"
#endif
#if defined(__GNUC__)
#define bswap_u32(x) __builtin_bswap32(x)
#define bswap_u64(x) __builtin_bswap64(x)
#elif defined(_MSC_VER)
#pragma intrinsic(_byteswap_ulong, _byteswap_uint64)
#define bswap_u32(x) _byteswap_ulong(x)
#define bswap_u64(x) _byteswap_uint64(x)
#endif
#if (!defined(_MSC_VER) || defined(__clang__)) && defined(OPENSSL_64_BIT)
#define BORINGSSL_HAS_UINT128
typedef __int128_t int128_t;
typedef __uint128_t uint128_t;
#endif
typedef unsigned char aliasing_uint8;
#if defined(OPENSSL_64_BIT)
typedef uint64_t crypto_word;
#define CRYPTO_WORD_BITS (64u)
#elif defined(OPENSSL_32_BIT)
typedef uint32_t crypto_word;
#define CRYPTO_WORD_BITS (32u)
#else
#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT"
#endif
#define CONSTTIME_TRUE_W ~((crypto_word)0)
#define CONSTTIME_FALSE_W ((crypto_word)0)
static inline crypto_word constant_time_msb_w(crypto_word a) {
return 0u - (a >> (sizeof(a) * 8 - 1));
}
static inline crypto_word constant_time_is_zero_w(crypto_word a) {
return constant_time_msb_w(~a & (a - 1));
}
static inline crypto_word constant_time_is_nonzero_w(crypto_word a) {
return ~constant_time_is_zero_w(a);
}
static inline crypto_word constant_time_eq_w(crypto_word a,
crypto_word b) {
return constant_time_is_zero_w(a ^ b);
}
static inline crypto_word constant_time_select_w(crypto_word mask,
crypto_word a,
crypto_word b) {
return (mask & a) | (~mask & b);
}
#if defined(BORINGSSL_CONSTANT_TIME_VALIDATION)
#define CONSTTIME_SECRET(x, y) VALGRIND_MAKE_MEM_UNDEFINED(x, y)
#define CONSTTIME_DECLASSIFY(x, y) VALGRIND_MAKE_MEM_DEFINED(x, y)
#else
#define CONSTTIME_SECRET(x, y)
#define CONSTTIME_DECLASSIFY(x, y)
#endif
static inline uint32_t from_be_u32_ptr(const uint8_t *data) {
#if defined(__clang__) || defined(_MSC_VER)
uint32_t value;
memcpy(&value, data, sizeof(value));
#if OPENSSL_ENDIAN != OPENSSL_BIG_ENDIAN
value = bswap_u32(value);
#endif
return value;
#else
return ((uint32_t)data[0] << 24) |
((uint32_t)data[1] << 16) |
((uint32_t)data[2] << 8) |
((uint32_t)data[3]);
#endif
}
static inline void to_be_u32_ptr(uint8_t *out, uint32_t value) {
#if defined(__clang__) || defined(_MSC_VER)
#if OPENSSL_ENDIAN != OPENSSL_BIG_ENDIAN
value = bswap_u32(value);
#endif
memcpy(out, &value, sizeof(value));
#else
out[0] = (uint8_t)(value >> 24);
out[1] = (uint8_t)(value >> 16);
out[2] = (uint8_t)(value >> 8);
out[3] = (uint8_t)value;
#endif
}
static inline void to_be_u64_ptr(uint8_t *out, uint64_t value) {
#if defined(__clang__) || defined(_MSC_VER)
#if OPENSSL_ENDIAN != OPENSSL_BIG_ENDIAN
value = bswap_u64(value);
#endif
memcpy(out, &value, sizeof(value));
#else
out[0] = (uint8_t)(value >> 56);
out[1] = (uint8_t)(value >> 48);
out[2] = (uint8_t)(value >> 40);
out[3] = (uint8_t)(value >> 32);
out[4] = (uint8_t)(value >> 24);
out[5] = (uint8_t)(value >> 16);
out[6] = (uint8_t)(value >> 8);
out[7] = (uint8_t)value;
#endif
}
#endif