Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support 64-bit big endian PowerPC target #1594

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions crypto/fipsmodule/aes/aes_nohw.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,15 +338,15 @@ static inline void aes_nohw_compact_block(aes_word_t out[AES_NOHW_BLOCK_WORDS],
#if defined(OPENSSL_SSE2)
// No conversions needed.
#elif defined(OPENSSL_64_BIT)
uint64_t a0 = aes_nohw_compact_word(out[0]);
uint64_t a1 = aes_nohw_compact_word(out[1]);
uint64_t a0 = aes_nohw_compact_word(CRYPTO_bswap8_le(out[0]));
uint64_t a1 = aes_nohw_compact_word(CRYPTO_bswap8_le(out[1]));
out[0] = (a0 & UINT64_C(0x00000000ffffffff)) | (a1 << 32);
out[1] = (a1 & UINT64_C(0xffffffff00000000)) | (a0 >> 32);
#else
uint32_t a0 = aes_nohw_compact_word(out[0]);
uint32_t a1 = aes_nohw_compact_word(out[1]);
uint32_t a2 = aes_nohw_compact_word(out[2]);
uint32_t a3 = aes_nohw_compact_word(out[3]);
uint32_t a0 = aes_nohw_compact_word(CRYPTO_bswap4_le(out[0]));
uint32_t a1 = aes_nohw_compact_word(CRYPTO_bswap4_le(out[1]));
uint32_t a2 = aes_nohw_compact_word(CRYPTO_bswap4_le(out[2]));
uint32_t a3 = aes_nohw_compact_word(CRYPTO_bswap4_le(out[3]));
// Note clang, when building for ARM Thumb2, will sometimes miscompile
// expressions such as (a0 & 0x0000ff00) << 8, particularly when building
// without optimizations. This bug was introduced in
Expand All @@ -370,6 +370,8 @@ static inline void aes_nohw_uncompact_block(
aes_nohw_uncompact_word((a0 & UINT64_C(0x00000000ffffffff)) | (a1 << 32));
uint64_t b1 =
aes_nohw_uncompact_word((a1 & UINT64_C(0xffffffff00000000)) | (a0 >> 32));
b0 = CRYPTO_bswap8_le(b0);
b1 = CRYPTO_bswap8_le(b1);
OPENSSL_memcpy(out, &b0, 8);
OPENSSL_memcpy(out + 8, &b1, 8);
#else
Expand All @@ -392,6 +394,10 @@ static inline void aes_nohw_uncompact_block(
b1 = aes_nohw_uncompact_word(b1);
b2 = aes_nohw_uncompact_word(b2);
b3 = aes_nohw_uncompact_word(b3);
b0 = CRYPTO_bswap4_le(b0);
b1 = CRYPTO_bswap4_le(b1);
b2 = CRYPTO_bswap4_le(b2);
b3 = CRYPTO_bswap4_le(b3);
OPENSSL_memcpy(out, &b0, 4);
OPENSSL_memcpy(out + 4, &b1, 4);
OPENSSL_memcpy(out + 8, &b2, 4);
Expand Down Expand Up @@ -920,11 +926,11 @@ void aes_nohw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
OPENSSL_memcpy(ivs.u8 + 16 * i, ivec, 16);
}

uint32_t ctr = CRYPTO_bswap4(ivs.u32[3]);
uint32_t ctr = CRYPTO_bswap4_be(ivs.u32[3]);
for (;;) {
// Update counters.
for (uint32_t i = 0; i < AES_NOHW_BATCH_SIZE; i++) {
ivs.u32[4 * i + 3] = CRYPTO_bswap4(ctr + i);
ivs.u32[4 * i + 3] = CRYPTO_bswap4_be(ctr + i);
}

size_t todo = blocks >= AES_NOHW_BATCH_SIZE ? AES_NOHW_BATCH_SIZE : blocks;
Expand Down
13 changes: 13 additions & 0 deletions crypto/fipsmodule/ec/p256_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,20 @@ typedef unsigned char P256_SCALAR_BYTES[33];

static inline void p256_scalar_bytes_from_limbs(
P256_SCALAR_BYTES bytes_out, const BN_ULONG limbs[P256_LIMBS]) {
#ifdef RING_BIG_ENDIAN
for (int i = 0; i < P256_LIMBS; i++)
{
#if BN_BITS2 == 64
BN_ULONG limb = CRYPTO_bswap8(limbs[i]);
OPENSSL_memcpy(bytes_out + i * 8, &limb, 8);
#else
BN_ULONG limb = CRYPTO_bswap4(limbs[i]);
OPENSSL_memcpy(bytes_out + i * 4, &limb, 4);
#endif
}
#else
OPENSSL_memcpy(bytes_out, limbs, 32);
#endif
bytes_out[32] = 0;
}

Expand Down
40 changes: 40 additions & 0 deletions crypto/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,10 @@ static inline crypto_word constant_time_select_w(crypto_word mask,
static inline uint32_t CRYPTO_bswap4(uint32_t x) {
return __builtin_bswap32(x);
}

static inline uint64_t CRYPTO_bswap8(uint64_t x) {
return __builtin_bswap64(x);
}
#elif defined(_MSC_VER)
#pragma warning(push, 3)
#include <stdlib.h>
Expand All @@ -272,8 +276,44 @@ static inline uint32_t CRYPTO_bswap4(uint32_t x) {
static inline uint32_t CRYPTO_bswap4(uint32_t x) {
return _byteswap_ulong(x);
}

static inline uint64_t CRYPTO_bswap8(uint64_t x) {
return _byteswap_uint64(x);
}
#else
static inline uint32_t CRYPTO_bswap4(uint32_t x) {
x = (x >> 16) | (x << 16);
x = ((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8);
return x;
}

static inline uint64_t CRYPTO_bswap8(uint64_t x) {
return CRYPTO_bswap4(x >> 32) | (((uint64_t)CRYPTO_bswap4(x)) << 32);
}
#endif


// Convert LE or BE values to/from native endianness.

#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define RING_BIG_ENDIAN
#endif
#endif

#ifdef RING_BIG_ENDIAN
#define CRYPTO_bswap4_le(x) CRYPTO_bswap4((x))
#define CRYPTO_bswap8_le(x) CRYPTO_bswap8((x))
#define CRYPTO_bswap4_be(x) (x)
#define CRYPTO_bswap8_be(x) (x)
#else
#define CRYPTO_bswap4_le(x) (x)
#define CRYPTO_bswap8_le(x) (x)
#define CRYPTO_bswap4_be(x) CRYPTO_bswap4((x))
#define CRYPTO_bswap8_be(x) CRYPTO_bswap8((x))
#endif


#if !defined(RING_CORE_NOSTDLIBINC)
#include <string.h>
#endif
Expand Down
4 changes: 2 additions & 2 deletions crypto/poly1305/poly1305.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@
#pragma GCC diagnostic ignored "-Wconversion"
#endif

// We can assume little-endian.
static uint32_t U8TO32_LE(const uint8_t *m) {
uint32_t r;
OPENSSL_memcpy(&r, m, sizeof(r));
return r;
return CRYPTO_bswap4_le(r);
}

static void U32TO8_LE(uint8_t *m, uint32_t v) {
v = CRYPTO_bswap4_le(v);
OPENSSL_memcpy(m, &v, sizeof(v));
}

Expand Down
6 changes: 6 additions & 0 deletions include/ring-core/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@
#elif defined(__MIPSEL__) && defined(__LP64__)
#define OPENSSL_64_BIT
#define OPENSSL_MIPS64
#elif defined(__s390x__)
#define OPENSSL_64_BIT
#define OPENSSL_S390X
#elif defined(__powerpc64__)
#define OPENSSL_64_BIT
#define OPENSSL_PPC64
#elif defined(__wasm__)
#define OPENSSL_32_BIT
#else
Expand Down
8 changes: 8 additions & 0 deletions mk/cargo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ rustflags_self_contained="-Clink-self-contained=yes -Clinker=rust-lld"
qemu_aarch64="qemu-aarch64 -L /usr/aarch64-linux-gnu"
qemu_arm="qemu-arm -L /usr/arm-linux-gnueabihf"
qemu_mipsel="qemu-mipsel -L /usr/mipsel-linux-gnu"
qemu_s390x="qemu-s390x -L /usr/s390x-linux-gnu"

# Avoid putting the Android tools in `$PATH` because there are tools in this
# directory like `clang` that would conflict with the same-named tools that may
Expand Down Expand Up @@ -109,6 +110,13 @@ case $target in
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_RUSTFLAGS="$rustflags_self_contained"
fi
;;
s390x-unknown-linux-gnu)
export CC_s390x_unknown_linux_gnu=clang-$llvm_version
export AR_s390x_unknown_linux_gnu=llvm-ar-$llvm_version
export CFLAGS_s390x_unknown_linux_gnu="--sysroot=/usr/s390x-linux-gnu"
export CARGO_TARGET_S390X_UNKNOWN_LINUX_GNU_LINKER=s390x-linux-gnu-gcc
export CARGO_TARGET_S390X_UNKNOWN_LINUX_GNU_RUNNER="$qemu_s390x"
;;
wasm32-unknown-unknown)
# The first two are only needed for when the "wasm_c" feature is enabled.
export CC_wasm32_unknown_unknown=clang-$llvm_version
Expand Down
8 changes: 8 additions & 0 deletions mk/install-build-tools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@ case $target in
libc6-dev-mipsel-cross \
qemu-user
;;
--target=s390x-unknown-linux-gnu)
# Clang is needed for code coverage.
use_clang=1
install_packages \
qemu-user \
gcc-s390x-linux-gnu \
libc6-dev-s390x-cross
;;
--target=wasm32-unknown-unknown)
cargo install wasm-bindgen-cli --bin wasm-bindgen-test-runner
use_clang=1
Expand Down
2 changes: 0 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,3 @@ mod sealed {
pub trait Sealed {}
}

// TODO: https://github.com/briansmith/ring/issues/1555.
const _LITTLE_ENDIAN_ONLY: () = assert!(cfg!(target_endian = "little"));