diff options
author | Neale Ferguson <neale@sinenomine.net> | 2018-02-02 20:04:13 +0300 |
---|---|---|
committer | Alexander Köplinger <alex.koeplinger@outlook.com> | 2018-02-02 20:04:13 +0300 |
commit | fdf7b47ef7e2088727f1f46dd528b31bad403136 (patch) | |
tree | 8b852ebd0190579f6605d79ae0b614cea3f5a989 | |
parent | 44f3e23c484279f3f14b90b869b9d54785fecc39 (diff) |
Add s390x (Big Endian) support (#4)
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | crypto/ec/p224-64.c | 35 | ||||
-rw-r--r-- | crypto/ec/p256-64.c | 31 |
3 files changed, 60 insertions, 8 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 296d0106..2ba98c0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,6 +164,8 @@ elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "armv7-a") set(ARCH "arm") elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64") set(ARCH "aarch64") +elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "s390x") + set(ARCH "s390x") else() message(FATAL_ERROR "Unknown processor:" ${CMAKE_SYSTEM_PROCESSOR}) endif() diff --git a/crypto/ec/p224-64.c b/crypto/ec/p224-64.c index 7bf889c9..d424a475 100644 --- a/crypto/ec/p224-64.c +++ b/crypto/ec/p224-64.c @@ -17,6 +17,7 @@ * Inspired by Daniel J. Bernstein's public domain nistp224 implementation * and Adam Langley's public domain 64-bit C implementation of curve25519. */ +#include <endian.h> #include <openssl/base.h> #if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS) && \ @@ -185,19 +186,33 @@ static const felem g_pre_comp[2][16][3] = { /* Helper functions to convert field elements to/from internal representation */ static void bin28_to_felem(felem out, const u8 in[28]) { - out[0] = *((const uint64_t *)(in)) & 0x00ffffffffffffff; - out[1] = (*((const uint64_t *)(in + 7))) & 0x00ffffffffffffff; - out[2] = (*((const uint64_t *)(in + 14))) & 0x00ffffffffffffff; - out[3] = (*((const uint64_t *)(in + 20))) >> 8; +#if __BYTE_ORDER == __LITTLE_ENDIAN + out[0] = *((const uint64_t *)(in)) & 0x00ffffffffffffff; + out[1] = (*((const uint64_t *)(in + 7))) & 0x00ffffffffffffff; + out[2] = (*((const uint64_t *)(in + 14))) & 0x00ffffffffffffff; + out[3] = (*((const uint64_t *)(in + 20))) >> 8; +#else + out[0] = (*((const uint64_t *)(in + 20))) << 8 >> 8; + out[1] = (*((const uint64_t *)(in + 14))) >> 8; + out[2] = (*((const uint64_t *)(in + 7))) >> 8; + out[3] = *((const uint64_t *)(in)) >>8; +#endif } static void felem_to_bin28(u8 out[28], const felem in) { size_t i; for (i = 0; i < 7; ++i) { +#if __BYTE_ORDER == __LITTLE_ENDIAN out[i] = in[0] >> (8 * i); out[i + 7] = in[1] >> (8 * i); out[i + 14] = in[2] >> (8 * i); out[i + 21] = in[3] >> (8 * i); +#else + out[i] = *((u8 *)&in[3] + i + 1); + out[i + 7] = *((u8 *)&in[2] + i + 1); + out[i + 14] = *((u8 *)&in[1] + i + 1); + out[i + 21] = *((u8 *)&in[0] + i + 1); +#endif } } @@ -223,16 +238,26 @@ static int BN_to_felem(felem out, const BIGNUM *bn) { felem_bytearray b_in; num_bytes = BN_bn2bin(bn, b_in); +#if __BYTE_ORDER == __LITTLE_ENDIAN flip_endian(b_out, b_in, num_bytes); +#else + memcpy(b_out+sizeof(b_out)-num_bytes, b_in, num_bytes); + memset(b_out, 0, sizeof(b_out)-num_bytes); +#endif bin28_to_felem(out, b_out); return 1; } /* From internal representation to OpenSSL BIGNUM */ static BIGNUM *felem_to_BN(BIGNUM *out, const felem in) { - felem_bytearray b_in, b_out; + felem_bytearray b_out; +#if __BYTE_ORDER == __LITTLE_ENDIAN + felem_bytearray b_in; felem_to_bin28(b_in, in); flip_endian(b_out, b_in, sizeof(b_out)); +#else + felem_to_bin28(b_out, in); +#endif return BN_bin2bn(b_out, sizeof(b_out), out); } diff --git a/crypto/ec/p256-64.c b/crypto/ec/p256-64.c index c4259b62..9ee2bb84 100644 --- a/crypto/ec/p256-64.c +++ b/crypto/ec/p256-64.c @@ -19,6 +19,7 @@ * Otherwise based on Emilia's P224 work, which was inspired by my curve25519 * work which got its smarts from Daniel J. Bernstein's work on the same. */ +#include <endian.h> #include <openssl/base.h> #if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS) @@ -75,21 +76,35 @@ static const u64 kPrime[4] = {0xfffffffffffffffful, 0xffffffff, 0, static const u64 bottom63bits = 0x7ffffffffffffffful; /* bin32_to_felem takes a little-endian byte array and converts it into felem - * form. This assumes that the CPU is little-endian. */ + * form. This assumes no particular CPU endianess. */ static void bin32_to_felem(felem out, const u8 in[32]) { +#if __BYTE_ORDER == __LITTLE_ENDIAN out[0] = *((const u64 *)&in[0]); out[1] = *((const u64 *)&in[8]); out[2] = *((const u64 *)&in[16]); out[3] = *((const u64 *)&in[24]); +#else + out[0] = *((const u64 *)&in[24]); + out[1] = *((const u64 *)&in[16]); + out[2] = *((const u64 *)&in[8]); + out[3] = *((const u64 *)&in[0]); +#endif } /* smallfelem_to_bin32 takes a smallfelem and serialises into a little endian, - * 32 byte array. This assumes that the CPU is little-endian. */ + * 32 byte array. This assumes no particular CPU endianess. */ static void smallfelem_to_bin32(u8 out[32], const smallfelem in) { +#if __BYTE_ORDER == __LITTLE_ENDIAN *((u64 *)&out[0]) = in[0]; *((u64 *)&out[8]) = in[1]; *((u64 *)&out[16]) = in[2]; *((u64 *)&out[24]) = in[3]; +#else + *((u64 *)&out[0]) = in[3]; + *((u64 *)&out[8]) = in[2]; + *((u64 *)&out[16]) = in[1]; + *((u64 *)&out[24]) = in[0]; +#endif } /* To preserve endianness when using BN_bn2bin and BN_bin2bn. */ @@ -118,16 +133,26 @@ static int BN_to_felem(felem out, const BIGNUM *bn) { felem_bytearray b_in; num_bytes = BN_bn2bin(bn, b_in); +#if __BYTE_ORDER == __LITTLE_ENDIAN flip_endian(b_out, b_in, num_bytes); bin32_to_felem(out, b_out); +#else + memcpy(b_out+sizeof(b_out)-num_bytes, b_in, num_bytes); + memset(b_out, 0, sizeof(b_out)-num_bytes); +#endif return 1; } /* felem_to_BN converts an felem into an OpenSSL BIGNUM. */ static BIGNUM *smallfelem_to_BN(BIGNUM *out, const smallfelem in) { - felem_bytearray b_in, b_out; + felem_bytearray b_out; +#if __BYTE_ORDER == __LITTLE_ENDIAN + felem_bytearray b_in; smallfelem_to_bin32(b_in, in); flip_endian(b_out, b_in, sizeof(b_out)); +#else + smallfelem_to_bin32(b_out, in); +#endif return BN_bin2bn(b_out, sizeof(b_out), out); } |