|  | #ifndef BEDROCK_UNVERIFIED_PLATFORM_INC_H_ | 
|  | #define BEDROCK_UNVERIFIED_PLATFORM_INC_H_ | 
|  |  | 
|  | // This file is a manually maintained and audited replacement for | 
|  | // bedrock_polyfill_platform.c.inc with tests in bedrock_platform_test.cc | 
|  |  | 
|  | #include "../../crypto/internal.h" | 
|  |  | 
|  | #if defined(OPENSSL_64_BIT) | 
|  | #define BR_WORD_MAX UINT64_MAX | 
|  | typedef uint64_t br_word_t; | 
|  | typedef int64_t br_signed_t; | 
|  | #elif defined(OPENSSL_32_BIT) | 
|  | #define BR_WORD_MAX UINT32_MAX | 
|  | typedef uint32_t br_word_t; | 
|  | typedef int32_t br_signed_t; | 
|  | #else | 
|  | #error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT" | 
|  | #endif | 
|  |  | 
|  | static_assert(sizeof(br_word_t) == sizeof(crypto_word_t)); | 
|  |  | 
|  | // Scalar memory operations | 
|  |  | 
|  | #include "../../third_party/fiat/bedrock_unverified_bareminimum.c.inc" | 
|  |  | 
|  | // Bulk memory operations | 
|  |  | 
|  | static inline void br_memcpy(br_word_t d, br_word_t s, br_word_t n) { | 
|  | OPENSSL_memcpy((void *)d, (const void *)s, n); | 
|  | } | 
|  |  | 
|  | static inline void br_memset(br_word_t d, br_word_t v, br_word_t n) { | 
|  | OPENSSL_memset((void *)d, v, n); | 
|  | } | 
|  |  | 
|  | // CPU Arithmetic | 
|  |  | 
|  | static inline br_word_t br_full_add(br_word_t x, br_word_t y, br_word_t carry, | 
|  | br_word_t *_sum) { | 
|  | br_word_t carry_out = 0; | 
|  | static_assert(sizeof(br_word_t) == sizeof(crypto_word_t)); | 
|  | *_sum = CRYPTO_addc_w(x, y, carry, &carry_out); | 
|  | return carry_out; | 
|  | } | 
|  |  | 
|  | static inline br_word_t br_full_sub(br_word_t x, br_word_t y, br_word_t borrow, | 
|  | br_word_t *_diff) { | 
|  | br_word_t borrow_out = 0; | 
|  | static_assert(sizeof(br_word_t) == sizeof(crypto_word_t)); | 
|  | *_diff = CRYPTO_subc_w(x, y, borrow, &borrow_out); | 
|  | return borrow_out; | 
|  | } | 
|  |  | 
|  | static inline br_word_t br_full_mul(br_word_t a, br_word_t b, br_word_t *_low) { | 
|  | #if BR_WORD_MAX == UINT32_MAX | 
|  | uint64_t r = (uint64_t)a * b; | 
|  | *_low = r; | 
|  | return r >> 32; | 
|  | #elif defined(BORINGSSL_HAS_UINT128) | 
|  | uint128_t r = (uint128_t)a * b; | 
|  | *_low = r; | 
|  | return r >> 64; | 
|  | #elif defined(_M_X64) | 
|  | uint64_t hi; | 
|  | *_low = _umul128(a, b, &hi); | 
|  | return hi; | 
|  | #elif defined(_M_ARM64) | 
|  | *_low = a * b; | 
|  | return __umulh(a, b); | 
|  | #else | 
|  | #error "need 64 x 64 -> 128 multiplication" | 
|  | #endif | 
|  | } | 
|  |  | 
|  | // Constant-time computations | 
|  |  | 
|  | static inline br_word_t br_value_barrier(br_word_t a) { | 
|  | static_assert(sizeof(br_word_t) == sizeof(crypto_word_t)); | 
|  | return value_barrier_w(a); | 
|  | } | 
|  |  | 
|  | static inline br_word_t br_declassify(br_word_t a) { | 
|  | static_assert(sizeof(br_word_t) == sizeof(crypto_word_t)); | 
|  | return constant_time_declassify_w(a); | 
|  | } | 
|  |  | 
|  | static inline br_word_t br_broadcast_negative(br_word_t x) { | 
|  | return br_value_barrier((br_signed_t)x >> (sizeof(br_word_t) * 8 - 1)); | 
|  | } | 
|  |  | 
|  | static inline br_word_t br_broadcast_nonzero(br_word_t x) { | 
|  | return br_broadcast_negative(x | (0u - x)); | 
|  | } | 
|  |  | 
|  | static inline br_word_t br_cmov(br_word_t c, br_word_t vnz, br_word_t vz) { | 
|  | #if !defined(OPENSSL_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) && \ | 
|  | defined(__x86_64__) | 
|  | __asm__( | 
|  | "testq %[c], %[c]\n" | 
|  | "cmovzq %[vz], %[vnz]" | 
|  | : [vnz] "+r"(vnz) | 
|  | : [vz] "r"(vz), [c] "r"(c) | 
|  | : "cc"); | 
|  | return vnz; | 
|  | #elif !defined(OPENSSL_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) && \ | 
|  | defined(__i386__) | 
|  | __asm__( | 
|  | "testl %[c], %[c]\n"  // test%z[c] gives "invalid operand" on clang 16.0.6 | 
|  | "cmovzl %[vz], %[vnz]" | 
|  | : [vnz] "+r"(vnz) | 
|  | : [vz] "r"(vz), [c] "r"(c) | 
|  | : "cc"); | 
|  | return vnz; | 
|  | #else | 
|  | br_word_t m = br_broadcast_nonzero(c); | 
|  | return (m & vnz) | (~m & vz); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | #endif  // BEDROCK_UNVERIFIED_PLATFORM_INC_H_ |