9 #ifndef BOTAN_LOAD_STORE_H__
10 #define BOTAN_LOAD_STORE_H__
12 #include <botan/types.h>
13 #include <botan/bswap.h>
14 #include <botan/mem_ops.h>
17 #if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
19 #if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
21 #define BOTAN_ENDIAN_N2B(x) (x)
22 #define BOTAN_ENDIAN_B2N(x) (x)
24 #define BOTAN_ENDIAN_N2L(x) reverse_bytes(x)
25 #define BOTAN_ENDIAN_L2N(x) reverse_bytes(x)
27 #elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
29 #define BOTAN_ENDIAN_N2L(x) (x)
30 #define BOTAN_ENDIAN_L2N(x) (x)
32 #define BOTAN_ENDIAN_N2B(x) reverse_bytes(x)
33 #define BOTAN_ENDIAN_B2N(x) reverse_bytes(x)
47 template<
typename T>
inline uint8_t
get_byte(
size_t byte_num, T input)
49 return static_cast<uint8_t
>(
50 input >> (((~byte_num)&(
sizeof(T)-1)) << 3)
62 return ((static_cast<uint16_t>(i0) << 8) | i1);
73 inline uint32_t
make_uint32(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3)
75 return ((static_cast<uint32_t>(i0) << 24) |
76 (static_cast<uint32_t>(i1) << 16) |
77 (static_cast<uint32_t>(i2) << 8) |
78 (static_cast<uint32_t>(i3)));
93 inline uint64_t
make_uint64(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3,
94 uint8_t i4, uint8_t i5, uint8_t i6, uint8_t i7)
96 return ((static_cast<uint64_t>(i0) << 56) |
97 (static_cast<uint64_t>(i1) << 48) |
98 (static_cast<uint64_t>(i2) << 40) |
99 (static_cast<uint64_t>(i3) << 32) |
100 (static_cast<uint64_t>(i4) << 24) |
101 (static_cast<uint64_t>(i5) << 16) |
102 (static_cast<uint64_t>(i6) << 8) |
103 (static_cast<uint64_t>(i7)));
113 inline T
load_be(
const uint8_t in[],
size_t off)
115 in += off *
sizeof(T);
117 for(
size_t i = 0; i !=
sizeof(T); ++i)
118 out = (out << 8) | in[i];
129 inline T
load_le(
const uint8_t in[],
size_t off)
131 in += off *
sizeof(T);
133 for(
size_t i = 0; i !=
sizeof(T); ++i)
134 out = (out << 8) | in[
sizeof(T)-1-i];
147 in += off *
sizeof(uint16_t);
149 #if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
151 std::memcpy(&x, in,
sizeof(x));
152 return BOTAN_ENDIAN_N2B(x);
167 in += off *
sizeof(uint16_t);
169 #if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
171 std::memcpy(&x, in,
sizeof(x));
172 return BOTAN_ENDIAN_N2L(x);
187 in += off *
sizeof(uint32_t);
188 #if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
190 std::memcpy(&x, in,
sizeof(x));
191 return BOTAN_ENDIAN_N2B(x);
206 in += off *
sizeof(uint32_t);
207 #if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
209 std::memcpy(&x, in,
sizeof(x));
210 return BOTAN_ENDIAN_N2L(x);
225 in += off *
sizeof(uint64_t);
226 #if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
228 std::memcpy(&x, in,
sizeof(x));
229 return BOTAN_ENDIAN_N2B(x);
232 in[4], in[5], in[6], in[7]);
245 in += off *
sizeof(uint64_t);
246 #if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
248 std::memcpy(&x, in,
sizeof(x));
249 return BOTAN_ENDIAN_N2L(x);
252 in[3], in[2], in[1], in[0]);
263 inline void load_le(
const uint8_t in[], T& x0, T& x1)
265 x0 = load_le<T>(in, 0);
266 x1 = load_le<T>(in, 1);
279 T& x0, T& x1, T& x2, T& x3)
281 x0 = load_le<T>(in, 0);
282 x1 = load_le<T>(in, 1);
283 x2 = load_le<T>(in, 2);
284 x3 = load_le<T>(in, 3);
301 T& x0, T& x1, T& x2, T& x3,
302 T& x4, T& x5, T& x6, T& x7)
304 x0 = load_le<T>(in, 0);
305 x1 = load_le<T>(in, 1);
306 x2 = load_le<T>(in, 2);
307 x3 = load_le<T>(in, 3);
308 x4 = load_le<T>(in, 4);
309 x5 = load_le<T>(in, 5);
310 x6 = load_le<T>(in, 6);
311 x7 = load_le<T>(in, 7);
327 #if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
328 std::memcpy(out, in,
sizeof(T)*count);
329 #elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
330 std::memcpy(out, in,
sizeof(T)*count);
331 const size_t blocks = count - (count % 4);
332 const size_t left = count - blocks;
334 for(
size_t i = 0; i != blocks; i += 4)
337 for(
size_t i = 0; i != left; ++i)
340 for(
size_t i = 0; i != count; ++i)
341 out[i] = load_le<T>(in, i);
353 inline void load_be(
const uint8_t in[], T& x0, T& x1)
355 x0 = load_be<T>(in, 0);
356 x1 = load_be<T>(in, 1);
369 T& x0, T& x1, T& x2, T& x3)
371 x0 = load_be<T>(in, 0);
372 x1 = load_be<T>(in, 1);
373 x2 = load_be<T>(in, 2);
374 x3 = load_be<T>(in, 3);
391 T& x0, T& x1, T& x2, T& x3,
392 T& x4, T& x5, T& x6, T& x7)
394 x0 = load_be<T>(in, 0);
395 x1 = load_be<T>(in, 1);
396 x2 = load_be<T>(in, 2);
397 x3 = load_be<T>(in, 3);
398 x4 = load_be<T>(in, 4);
399 x5 = load_be<T>(in, 5);
400 x6 = load_be<T>(in, 6);
401 x7 = load_be<T>(in, 7);
417 #if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
418 std::memcpy(out, in,
sizeof(T)*count);
419 #elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
420 std::memcpy(out, in,
sizeof(T)*count);
421 const size_t blocks = count - (count % 4);
422 const size_t left = count - blocks;
424 for(
size_t i = 0; i != blocks; i += 4)
427 for(
size_t i = 0; i != left; ++i)
430 for(
size_t i = 0; i != count; ++i)
431 out[i] = load_be<T>(in, i);
443 #if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
444 uint16_t o = BOTAN_ENDIAN_N2B(in);
445 std::memcpy(out, &o,
sizeof(o));
459 #if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
460 uint16_t o = BOTAN_ENDIAN_N2L(in);
461 std::memcpy(out, &o,
sizeof(o));
475 #if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
476 uint32_t o = BOTAN_ENDIAN_B2N(in);
477 std::memcpy(out, &o,
sizeof(o));
493 #if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
494 uint32_t o = BOTAN_ENDIAN_L2N(in);
495 std::memcpy(out, &o,
sizeof(o));
511 #if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
512 uint64_t o = BOTAN_ENDIAN_B2N(in);
513 std::memcpy(out, &o,
sizeof(o));
533 #if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
534 uint64_t o = BOTAN_ENDIAN_L2N(in);
535 std::memcpy(out, &o,
sizeof(o));
557 store_le(x0, out + (0 *
sizeof(T)));
558 store_le(x1, out + (1 *
sizeof(T)));
570 store_be(x0, out + (0 *
sizeof(T)));
571 store_be(x1, out + (1 *
sizeof(T)));
583 inline void store_le(uint8_t out[], T x0, T x1, T x2, T x3)
585 store_le(x0, out + (0 *
sizeof(T)));
586 store_le(x1, out + (1 *
sizeof(T)));
587 store_le(x2, out + (2 *
sizeof(T)));
588 store_le(x3, out + (3 *
sizeof(T)));
600 inline void store_be(uint8_t out[], T x0, T x1, T x2, T x3)
602 store_be(x0, out + (0 *
sizeof(T)));
603 store_be(x1, out + (1 *
sizeof(T)));
604 store_be(x2, out + (2 *
sizeof(T)));
605 store_be(x3, out + (3 *
sizeof(T)));
621 inline void store_le(uint8_t out[], T x0, T x1, T x2, T x3,
622 T x4, T x5, T x6, T x7)
624 store_le(x0, out + (0 *
sizeof(T)));
625 store_le(x1, out + (1 *
sizeof(T)));
626 store_le(x2, out + (2 *
sizeof(T)));
627 store_le(x3, out + (3 *
sizeof(T)));
628 store_le(x4, out + (4 *
sizeof(T)));
629 store_le(x5, out + (5 *
sizeof(T)));
630 store_le(x6, out + (6 *
sizeof(T)));
631 store_le(x7, out + (7 *
sizeof(T)));
647 inline void store_be(uint8_t out[], T x0, T x1, T x2, T x3,
648 T x4, T x5, T x6, T x7)
650 store_be(x0, out + (0 *
sizeof(T)));
651 store_be(x1, out + (1 *
sizeof(T)));
652 store_be(x2, out + (2 *
sizeof(T)));
653 store_be(x3, out + (3 *
sizeof(T)));
654 store_be(x4, out + (4 *
sizeof(T)));
655 store_be(x5, out + (5 *
sizeof(T)));
656 store_be(x6, out + (6 *
sizeof(T)));
657 store_be(x7, out + (7 *
sizeof(T)));
663 while(out_bytes >=
sizeof(T))
667 out_bytes -=
sizeof(T);
671 for(
size_t i = 0; i != out_bytes; ++i)
675 template<
typename T,
typename Alloc>
676 void copy_out_vec_be(uint8_t out[],
size_t out_bytes,
const std::vector<T, Alloc>& in)
684 while(out_bytes >=
sizeof(T))
688 out_bytes -=
sizeof(T);
692 for(
size_t i = 0; i != out_bytes; ++i)
693 out[i] =
get_byte(
sizeof(T) - 1 - (i % 8), in[0]);
696 template<
typename T,
typename Alloc>
697 void copy_out_vec_le(uint8_t out[],
size_t out_bytes,
const std::vector<T, Alloc>& in)
void copy_out_vec_be(uint8_t out[], size_t out_bytes, const std::vector< T, Alloc > &in)
uint16_t load_le< uint16_t >(const uint8_t in[], size_t off)
void store_be(uint16_t in, uint8_t out[2])
void copy_out_le(uint8_t out[], size_t out_bytes, const T in[])
uint16_t load_be< uint16_t >(const uint8_t in[], size_t off)
uint32_t load_be< uint32_t >(const uint8_t in[], size_t off)
uint32_t load_le< uint32_t >(const uint8_t in[], size_t off)
uint64_t load_be< uint64_t >(const uint8_t in[], size_t off)
T load_be(const uint8_t in[], size_t off)
uint64_t load_le< uint64_t >(const uint8_t in[], size_t off)
T load_le(const uint8_t in[], size_t off)
uint16_t reverse_bytes(uint16_t val)
uint64_t make_uint64(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3, uint8_t i4, uint8_t i5, uint8_t i6, uint8_t i7)
uint16_t make_uint16(uint8_t i0, uint8_t i1)
uint8_t get_byte(size_t byte_num, T input)
uint32_t make_uint32(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3)
void copy_out_be(uint8_t out[], size_t out_bytes, const T in[])
void store_le(uint16_t in, uint8_t out[2])
void copy_out_vec_le(uint8_t out[], size_t out_bytes, const std::vector< T, Alloc > &in)