From 9d4e06e6bcfcde0eed4c4ef539be30e606cd5ec0 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Mon, 10 Jul 2017 15:54:08 -0400 Subject: [PATCH] Switch some pointer casts to memcpy. This isn't all of our pointer games by far, but for any code which doesn't run on armv6, memcpy and pointer cast compile to the same code. For code with does care about armv6 (do we care?), it'll need a bit more work. armv6 makes memcpy into a function call. Ironically, the one platform where C needs its alignment rules is the one platform that makes it hard to honor C's alignment rules. Change-Id: Ib9775aa4d9df9381995df8698bd11eb260aac58c Reviewed-on: https://boringssl-review.googlesource.com/17707 Reviewed-by: David Benjamin Commit-Queue: David Benjamin CQ-Verified: CQ bot account: commit-bot@chromium.org --- crypto/fipsmodule/bn/exponentiation.c | 9 +++++---- crypto/fipsmodule/ec/p224-64.c | 14 ++++++++++---- crypto/fipsmodule/ec/p256-64.c | 26 ++++++++++++++++++-------- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/crypto/fipsmodule/bn/exponentiation.c b/crypto/fipsmodule/bn/exponentiation.c index e5521d68..187b845c 100644 --- a/crypto/fipsmodule/bn/exponentiation.c +++ b/crypto/fipsmodule/bn/exponentiation.c @@ -1085,11 +1085,12 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, while (bits >= 0) { /* Read five bits from |bits-4| through |bits|, inclusive. */ int first_bit = bits - 4; - wvalue = *(const uint16_t *) (p_bytes + (first_bit >> 3)); - wvalue >>= first_bit & 7; - wvalue &= 0x1f; + uint16_t val; + OPENSSL_memcpy(&val, p_bytes + (first_bit >> 3), sizeof(val)); + val >>= first_bit & 7; + val &= 0x1f; bits -= 5; - bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue); + bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, val); } } diff --git a/crypto/fipsmodule/ec/p224-64.c b/crypto/fipsmodule/ec/p224-64.c index 31097d43..67dfcc85 100644 --- a/crypto/fipsmodule/ec/p224-64.c +++ b/crypto/fipsmodule/ec/p224-64.c @@ -181,12 +181,18 @@ static const p224_felem g_p224_pre_comp[2][16][3] = { {0x32477c61b6e8c6, 0xb46a97570f018b, 0x91176d0a7e95d1, 0x3df90fbc4c7d0e}, {1, 0, 0, 0}}}}; +static uint64_t p224_load_u64(const uint8_t in[8]) { + uint64_t ret; + OPENSSL_memcpy(&ret, in, sizeof(ret)); + return ret; +} + /* Helper functions to convert field elements to/from internal representation */ static void p224_bin28_to_felem(p224_felem out, const uint8_t 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; + out[0] = p224_load_u64(in) & 0x00ffffffffffffff; + out[1] = p224_load_u64(in + 7) & 0x00ffffffffffffff; + out[2] = p224_load_u64(in + 14) & 0x00ffffffffffffff; + out[3] = p224_load_u64(in + 20) >> 8; } static void p224_felem_to_bin28(uint8_t out[28], const p224_felem in) { diff --git a/crypto/fipsmodule/ec/p256-64.c b/crypto/fipsmodule/ec/p256-64.c index de1edc2b..8952aa2e 100644 --- a/crypto/fipsmodule/ec/p256-64.c +++ b/crypto/fipsmodule/ec/p256-64.c @@ -71,22 +71,32 @@ static const uint64_t kPrime[4] = {0xfffffffffffffffful, 0xffffffff, 0, 0xffffffff00000001ul}; static const uint64_t bottom63bits = 0x7ffffffffffffffful; +static uint64_t load_u64(const uint8_t in[8]) { + uint64_t ret; + OPENSSL_memcpy(&ret, in, sizeof(ret)); + return ret; +} + +static void store_u64(uint8_t out[8], uint64_t in) { + OPENSSL_memcpy(out, &in, sizeof(in)); +} + /* bin32_to_felem takes a little-endian byte array and converts it into felem * form. This assumes that the CPU is little-endian. */ static void bin32_to_felem(felem out, const uint8_t in[32]) { - out[0] = *((const uint64_t *)&in[0]); - out[1] = *((const uint64_t *)&in[8]); - out[2] = *((const uint64_t *)&in[16]); - out[3] = *((const uint64_t *)&in[24]); + out[0] = load_u64(&in[0]); + out[1] = load_u64(&in[8]); + out[2] = load_u64(&in[16]); + out[3] = load_u64(&in[24]); } /* smallfelem_to_bin32 takes a smallfelem and serialises into a little endian, * 32 byte array. This assumes that the CPU is little-endian. */ static void smallfelem_to_bin32(uint8_t out[32], const smallfelem in) { - *((uint64_t *)&out[0]) = in[0]; - *((uint64_t *)&out[8]) = in[1]; - *((uint64_t *)&out[16]) = in[2]; - *((uint64_t *)&out[24]) = in[3]; + store_u64(&out[0], in[0]); + store_u64(&out[8], in[1]); + store_u64(&out[16], in[2]); + store_u64(&out[24], in[3]); } /* To preserve endianness when using BN_bn2bin and BN_bin2bn. */