aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/utils/loadstor.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/utils/loadstor.h')
-rw-r--r--src/lib/utils/loadstor.h100
1 files changed, 63 insertions, 37 deletions
diff --git a/src/lib/utils/loadstor.h b/src/lib/utils/loadstor.h
index 53700fc86..a6c2b7969 100644
--- a/src/lib/utils/loadstor.h
+++ b/src/lib/utils/loadstor.h
@@ -1,6 +1,6 @@
/*
* Load/Store Operators
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2007,2015 Jack Lloyd
* 2007 Yves Jerschow
*
* Botan is released under the Simplified BSD License (see license.txt)
@@ -144,10 +144,13 @@ inline T load_le(const byte in[], size_t off)
template<>
inline u16bit load_be<u16bit>(const byte in[], size_t off)
{
+ in += off * sizeof(u16bit);
+
#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
- return BOTAN_ENDIAN_N2B(*(reinterpret_cast<const u16bit*>(in) + off));
+ u16bit x;
+ std::memcpy(&x, in, sizeof(x));
+ return BOTAN_ENDIAN_N2B(x);
#else
- in += off * sizeof(u16bit);
return make_u16bit(in[0], in[1]);
#endif
}
@@ -161,10 +164,13 @@ inline u16bit load_be<u16bit>(const byte in[], size_t off)
template<>
inline u16bit load_le<u16bit>(const byte in[], size_t off)
{
+ in += off * sizeof(u16bit);
+
#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
- return BOTAN_ENDIAN_N2L(*(reinterpret_cast<const u16bit*>(in) + off));
+ u16bit x;
+ std::memcpy(&x, in, sizeof(x));
+ return BOTAN_ENDIAN_N2L(x);
#else
- in += off * sizeof(u16bit);
return make_u16bit(in[1], in[0]);
#endif
}
@@ -178,10 +184,12 @@ inline u16bit load_le<u16bit>(const byte in[], size_t off)
template<>
inline u32bit load_be<u32bit>(const byte in[], size_t off)
{
+ in += off * sizeof(u32bit);
#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
- return BOTAN_ENDIAN_N2B(*(reinterpret_cast<const u32bit*>(in) + off));
+ u32bit x;
+ std::memcpy(&x, in, sizeof(x));
+ return BOTAN_ENDIAN_N2B(x);
#else
- in += off * sizeof(u32bit);
return make_u32bit(in[0], in[1], in[2], in[3]);
#endif
}
@@ -195,10 +203,12 @@ inline u32bit load_be<u32bit>(const byte in[], size_t off)
template<>
inline u32bit load_le<u32bit>(const byte in[], size_t off)
{
+ in += off * sizeof(u32bit);
#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
- return BOTAN_ENDIAN_N2L(*(reinterpret_cast<const u32bit*>(in) + off));
+ u32bit x;
+ std::memcpy(&x, in, sizeof(x));
+ return BOTAN_ENDIAN_N2L(x);
#else
- in += off * sizeof(u32bit);
return make_u32bit(in[3], in[2], in[1], in[0]);
#endif
}
@@ -212,10 +222,12 @@ inline u32bit load_le<u32bit>(const byte in[], size_t off)
template<>
inline u64bit load_be<u64bit>(const byte in[], size_t off)
{
+ in += off * sizeof(u64bit);
#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
- return BOTAN_ENDIAN_N2B(*(reinterpret_cast<const u64bit*>(in) + off));
+ u64bit x;
+ std::memcpy(&x, in, sizeof(x));
+ return BOTAN_ENDIAN_N2B(x);
#else
- in += off * sizeof(u64bit);
return make_u64bit(in[0], in[1], in[2], in[3],
in[4], in[5], in[6], in[7]);
#endif
@@ -230,10 +242,12 @@ inline u64bit load_be<u64bit>(const byte in[], size_t off)
template<>
inline u64bit load_le<u64bit>(const byte in[], size_t off)
{
+ in += off * sizeof(u64bit);
#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
- return BOTAN_ENDIAN_N2L(*(reinterpret_cast<const u64bit*>(in) + off));
+ u64bit x;
+ std::memcpy(&x, in, sizeof(x));
+ return BOTAN_ENDIAN_N2L(x);
#else
- in += off * sizeof(u64bit);
return make_u64bit(in[7], in[6], in[5], in[4],
in[3], in[2], in[1], in[0]);
#endif
@@ -308,24 +322,27 @@ inline void load_le(T out[],
const byte in[],
size_t count)
{
+ if(count > 0)
+ {
#if defined(BOTAN_TARGET_CPU_HAS_KNOWN_ENDIANNESS)
- std::memcpy(out, in, sizeof(T)*count);
+ std::memcpy(out, in, sizeof(T)*count);
#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
- const size_t blocks = count - (count % 4);
- const size_t left = count - blocks;
+ const size_t blocks = count - (count % 4);
+ const size_t left = count - blocks;
- for(size_t i = 0; i != blocks; i += 4)
- bswap_4(out + i);
+ for(size_t i = 0; i != blocks; i += 4)
+ bswap_4(out + i);
- for(size_t i = 0; i != left; ++i)
- out[blocks+i] = reverse_bytes(out[blocks+i]);
+ for(size_t i = 0; i != left; ++i)
+ out[blocks+i] = reverse_bytes(out[blocks+i]);
#endif
#else
- for(size_t i = 0; i != count; ++i)
- out[i] = load_le<T>(in, i);
+ for(size_t i = 0; i != count; ++i)
+ out[i] = load_le<T>(in, i);
#endif
+ }
}
/**
@@ -397,24 +414,27 @@ inline void load_be(T out[],
const byte in[],
size_t count)
{
+ if(count > 0)
+ {
#if defined(BOTAN_TARGET_CPU_HAS_KNOWN_ENDIANNESS)
- std::memcpy(out, in, sizeof(T)*count);
+ std::memcpy(out, in, sizeof(T)*count);
#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
- const size_t blocks = count - (count % 4);
- const size_t left = count - blocks;
+ const size_t blocks = count - (count % 4);
+ const size_t left = count - blocks;
- for(size_t i = 0; i != blocks; i += 4)
- bswap_4(out + i);
+ for(size_t i = 0; i != blocks; i += 4)
+ bswap_4(out + i);
- for(size_t i = 0; i != left; ++i)
- out[blocks+i] = reverse_bytes(out[blocks+i]);
+ for(size_t i = 0; i != left; ++i)
+ out[blocks+i] = reverse_bytes(out[blocks+i]);
#endif
#else
- for(size_t i = 0; i != count; ++i)
- out[i] = load_be<T>(in, i);
+ for(size_t i = 0; i != count; ++i)
+ out[i] = load_be<T>(in, i);
#endif
+ }
}
/**
@@ -425,7 +445,8 @@ inline void load_be(T out[],
inline void store_be(u16bit in, byte out[2])
{
#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
- *reinterpret_cast<u16bit*>(out) = BOTAN_ENDIAN_B2N(in);
+ u16bit o = BOTAN_ENDIAN_N2B(in);
+ std::memcpy(out, &o, sizeof(o));
#else
out[0] = get_byte(0, in);
out[1] = get_byte(1, in);
@@ -440,7 +461,8 @@ inline void store_be(u16bit in, byte out[2])
inline void store_le(u16bit in, byte out[2])
{
#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
- *reinterpret_cast<u16bit*>(out) = BOTAN_ENDIAN_L2N(in);
+ u16bit o = BOTAN_ENDIAN_N2L(in);
+ std::memcpy(out, &o, sizeof(o));
#else
out[0] = get_byte(1, in);
out[1] = get_byte(0, in);
@@ -455,7 +477,8 @@ inline void store_le(u16bit in, byte out[2])
inline void store_be(u32bit in, byte out[4])
{
#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
- *reinterpret_cast<u32bit*>(out) = BOTAN_ENDIAN_B2N(in);
+ u32bit o = BOTAN_ENDIAN_B2N(in);
+ std::memcpy(out, &o, sizeof(o));
#else
out[0] = get_byte(0, in);
out[1] = get_byte(1, in);
@@ -472,7 +495,8 @@ inline void store_be(u32bit in, byte out[4])
inline void store_le(u32bit in, byte out[4])
{
#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
- *reinterpret_cast<u32bit*>(out) = BOTAN_ENDIAN_L2N(in);
+ u32bit o = BOTAN_ENDIAN_L2N(in);
+ std::memcpy(out, &o, sizeof(o));
#else
out[0] = get_byte(3, in);
out[1] = get_byte(2, in);
@@ -489,7 +513,8 @@ inline void store_le(u32bit in, byte out[4])
inline void store_be(u64bit in, byte out[8])
{
#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
- *reinterpret_cast<u64bit*>(out) = BOTAN_ENDIAN_B2N(in);
+ u64bit o = BOTAN_ENDIAN_B2N(in);
+ std::memcpy(out, &o, sizeof(o));
#else
out[0] = get_byte(0, in);
out[1] = get_byte(1, in);
@@ -510,7 +535,8 @@ inline void store_be(u64bit in, byte out[8])
inline void store_le(u64bit in, byte out[8])
{
#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
- *reinterpret_cast<u64bit*>(out) = BOTAN_ENDIAN_L2N(in);
+ u64bit o = BOTAN_ENDIAN_L2N(in);
+ std::memcpy(out, &o, sizeof(o));
#else
out[0] = get_byte(7, in);
out[1] = get_byte(6, in);