diff --git a/crypto/fipsmodule/aes/aes_nohw.c b/crypto/fipsmodule/aes/aes_nohw.c index 308c7cca1c..7490ade194 100644 --- a/crypto/fipsmodule/aes/aes_nohw.c +++ b/crypto/fipsmodule/aes/aes_nohw.c @@ -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 @@ -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 @@ -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); @@ -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; diff --git a/crypto/fipsmodule/ec/p256_shared.h b/crypto/fipsmodule/ec/p256_shared.h index 049b138085..0d37ea9cc5 100644 --- a/crypto/fipsmodule/ec/p256_shared.h +++ b/crypto/fipsmodule/ec/p256_shared.h @@ -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; } diff --git a/crypto/internal.h b/crypto/internal.h index dba229c399..22d0cab208 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -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 @@ -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 #endif diff --git a/crypto/poly1305/poly1305.c b/crypto/poly1305/poly1305.c index 5f0ab8d6b3..7f9c7dc0d5 100644 --- a/crypto/poly1305/poly1305.c +++ b/crypto/poly1305/poly1305.c @@ -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)); } diff --git a/include/ring-core/base.h b/include/ring-core/base.h index f1a027d1a4..0f58a9096c 100644 --- a/include/ring-core/base.h +++ b/include/ring-core/base.h @@ -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 diff --git a/mk/cargo.sh b/mk/cargo.sh index 7ddb5dd628..5ff0960a4d 100755 --- a/mk/cargo.sh +++ b/mk/cargo.sh @@ -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 @@ -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 diff --git a/mk/install-build-tools.sh b/mk/install-build-tools.sh index 77b01cdcb8..e30a6c7cbe 100755 --- a/mk/install-build-tools.sh +++ b/mk/install-build-tools.sh @@ -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 diff --git a/src/lib.rs b/src/lib.rs index 644708c828..2fe127e2dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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"));