aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/3rdparty/botan/src/lib/utils/loadstor.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/3rdparty/botan/src/lib/utils/loadstor.h')
-rw-r--r--src/libs/3rdparty/botan/src/lib/utils/loadstor.h697
1 files changed, 697 insertions, 0 deletions
diff --git a/src/libs/3rdparty/botan/src/lib/utils/loadstor.h b/src/libs/3rdparty/botan/src/lib/utils/loadstor.h
new file mode 100644
index 0000000000..70ad20591c
--- /dev/null
+++ b/src/libs/3rdparty/botan/src/lib/utils/loadstor.h
@@ -0,0 +1,697 @@
+/*
+* Load/Store Operators
+* (C) 1999-2007,2015,2017 Jack Lloyd
+* 2007 Yves Jerschow
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_LOAD_STORE_H_
+#define BOTAN_LOAD_STORE_H_
+
+#include <botan/types.h>
+#include <botan/bswap.h>
+#include <botan/mem_ops.h>
+#include <vector>
+
+#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
+ #define BOTAN_ENDIAN_N2L(x) reverse_bytes(x)
+ #define BOTAN_ENDIAN_L2N(x) reverse_bytes(x)
+ #define BOTAN_ENDIAN_N2B(x) (x)
+ #define BOTAN_ENDIAN_B2N(x) (x)
+
+#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
+ #define BOTAN_ENDIAN_N2L(x) (x)
+ #define BOTAN_ENDIAN_L2N(x) (x)
+ #define BOTAN_ENDIAN_N2B(x) reverse_bytes(x)
+ #define BOTAN_ENDIAN_B2N(x) reverse_bytes(x)
+
+#endif
+
+namespace Botan {
+
+/**
+* Byte extraction
+* @param byte_num which byte to extract, 0 == highest byte
+* @param input the value to extract from
+* @return byte byte_num of input
+*/
+template<typename T> inline uint8_t get_byte(size_t byte_num, T input)
+ {
+ return static_cast<uint8_t>(
+ input >> (((~byte_num)&(sizeof(T)-1)) << 3)
+ );
+ }
+
+/**
+* Make a uint16_t from two bytes
+* @param i0 the first byte
+* @param i1 the second byte
+* @return i0 || i1
+*/
+inline uint16_t make_uint16(uint8_t i0, uint8_t i1)
+ {
+ return static_cast<uint16_t>((static_cast<uint16_t>(i0) << 8) | i1);
+ }
+
+/**
+* Make a uint32_t from four bytes
+* @param i0 the first byte
+* @param i1 the second byte
+* @param i2 the third byte
+* @param i3 the fourth byte
+* @return i0 || i1 || i2 || i3
+*/
+inline uint32_t make_uint32(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3)
+ {
+ return ((static_cast<uint32_t>(i0) << 24) |
+ (static_cast<uint32_t>(i1) << 16) |
+ (static_cast<uint32_t>(i2) << 8) |
+ (static_cast<uint32_t>(i3)));
+ }
+
+/**
+* Make a uint32_t from eight bytes
+* @param i0 the first byte
+* @param i1 the second byte
+* @param i2 the third byte
+* @param i3 the fourth byte
+* @param i4 the fifth byte
+* @param i5 the sixth byte
+* @param i6 the seventh byte
+* @param i7 the eighth byte
+* @return i0 || i1 || i2 || i3 || i4 || i5 || i6 || i7
+*/
+inline 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)
+ {
+ return ((static_cast<uint64_t>(i0) << 56) |
+ (static_cast<uint64_t>(i1) << 48) |
+ (static_cast<uint64_t>(i2) << 40) |
+ (static_cast<uint64_t>(i3) << 32) |
+ (static_cast<uint64_t>(i4) << 24) |
+ (static_cast<uint64_t>(i5) << 16) |
+ (static_cast<uint64_t>(i6) << 8) |
+ (static_cast<uint64_t>(i7)));
+ }
+
+/**
+* Load a big-endian word
+* @param in a pointer to some bytes
+* @param off an offset into the array
+* @return off'th T of in, as a big-endian value
+*/
+template<typename T>
+inline T load_be(const uint8_t in[], size_t off)
+ {
+ in += off * sizeof(T);
+ T out = 0;
+ for(size_t i = 0; i != sizeof(T); ++i)
+ out = static_cast<T>((out << 8) | in[i]);
+ return out;
+ }
+
+/**
+* Load a little-endian word
+* @param in a pointer to some bytes
+* @param off an offset into the array
+* @return off'th T of in, as a litte-endian value
+*/
+template<typename T>
+inline T load_le(const uint8_t in[], size_t off)
+ {
+ in += off * sizeof(T);
+ T out = 0;
+ for(size_t i = 0; i != sizeof(T); ++i)
+ out = (out << 8) | in[sizeof(T)-1-i];
+ return out;
+ }
+
+/**
+* Load a big-endian uint16_t
+* @param in a pointer to some bytes
+* @param off an offset into the array
+* @return off'th uint16_t of in, as a big-endian value
+*/
+template<>
+inline uint16_t load_be<uint16_t>(const uint8_t in[], size_t off)
+ {
+ in += off * sizeof(uint16_t);
+
+#if defined(BOTAN_ENDIAN_N2B)
+ uint16_t x;
+ std::memcpy(&x, in, sizeof(x));
+ return BOTAN_ENDIAN_N2B(x);
+#else
+ return make_uint16(in[0], in[1]);
+#endif
+ }
+
+/**
+* Load a little-endian uint16_t
+* @param in a pointer to some bytes
+* @param off an offset into the array
+* @return off'th uint16_t of in, as a little-endian value
+*/
+template<>
+inline uint16_t load_le<uint16_t>(const uint8_t in[], size_t off)
+ {
+ in += off * sizeof(uint16_t);
+
+#if defined(BOTAN_ENDIAN_N2L)
+ uint16_t x;
+ std::memcpy(&x, in, sizeof(x));
+ return BOTAN_ENDIAN_N2L(x);
+#else
+ return make_uint16(in[1], in[0]);
+#endif
+ }
+
+/**
+* Load a big-endian uint32_t
+* @param in a pointer to some bytes
+* @param off an offset into the array
+* @return off'th uint32_t of in, as a big-endian value
+*/
+template<>
+inline uint32_t load_be<uint32_t>(const uint8_t in[], size_t off)
+ {
+ in += off * sizeof(uint32_t);
+#if defined(BOTAN_ENDIAN_N2B)
+ uint32_t x;
+ std::memcpy(&x, in, sizeof(x));
+ return BOTAN_ENDIAN_N2B(x);
+#else
+ return make_uint32(in[0], in[1], in[2], in[3]);
+#endif
+ }
+
+/**
+* Load a little-endian uint32_t
+* @param in a pointer to some bytes
+* @param off an offset into the array
+* @return off'th uint32_t of in, as a little-endian value
+*/
+template<>
+inline uint32_t load_le<uint32_t>(const uint8_t in[], size_t off)
+ {
+ in += off * sizeof(uint32_t);
+#if defined(BOTAN_ENDIAN_N2L)
+ uint32_t x;
+ std::memcpy(&x, in, sizeof(x));
+ return BOTAN_ENDIAN_N2L(x);
+#else
+ return make_uint32(in[3], in[2], in[1], in[0]);
+#endif
+ }
+
+/**
+* Load a big-endian uint64_t
+* @param in a pointer to some bytes
+* @param off an offset into the array
+* @return off'th uint64_t of in, as a big-endian value
+*/
+template<>
+inline uint64_t load_be<uint64_t>(const uint8_t in[], size_t off)
+ {
+ in += off * sizeof(uint64_t);
+#if defined(BOTAN_ENDIAN_N2B)
+ uint64_t x;
+ std::memcpy(&x, in, sizeof(x));
+ return BOTAN_ENDIAN_N2B(x);
+#else
+ return make_uint64(in[0], in[1], in[2], in[3],
+ in[4], in[5], in[6], in[7]);
+#endif
+ }
+
+/**
+* Load a little-endian uint64_t
+* @param in a pointer to some bytes
+* @param off an offset into the array
+* @return off'th uint64_t of in, as a little-endian value
+*/
+template<>
+inline uint64_t load_le<uint64_t>(const uint8_t in[], size_t off)
+ {
+ in += off * sizeof(uint64_t);
+#if defined(BOTAN_ENDIAN_N2L)
+ uint64_t x;
+ std::memcpy(&x, in, sizeof(x));
+ return BOTAN_ENDIAN_N2L(x);
+#else
+ return make_uint64(in[7], in[6], in[5], in[4],
+ in[3], in[2], in[1], in[0]);
+#endif
+ }
+
+/**
+* Load two little-endian words
+* @param in a pointer to some bytes
+* @param x0 where the first word will be written
+* @param x1 where the second word will be written
+*/
+template<typename T>
+inline void load_le(const uint8_t in[], T& x0, T& x1)
+ {
+ x0 = load_le<T>(in, 0);
+ x1 = load_le<T>(in, 1);
+ }
+
+/**
+* Load four little-endian words
+* @param in a pointer to some bytes
+* @param x0 where the first word will be written
+* @param x1 where the second word will be written
+* @param x2 where the third word will be written
+* @param x3 where the fourth word will be written
+*/
+template<typename T>
+inline void load_le(const uint8_t in[],
+ T& x0, T& x1, T& x2, T& x3)
+ {
+ x0 = load_le<T>(in, 0);
+ x1 = load_le<T>(in, 1);
+ x2 = load_le<T>(in, 2);
+ x3 = load_le<T>(in, 3);
+ }
+
+/**
+* Load eight little-endian words
+* @param in a pointer to some bytes
+* @param x0 where the first word will be written
+* @param x1 where the second word will be written
+* @param x2 where the third word will be written
+* @param x3 where the fourth word will be written
+* @param x4 where the fifth word will be written
+* @param x5 where the sixth word will be written
+* @param x6 where the seventh word will be written
+* @param x7 where the eighth word will be written
+*/
+template<typename T>
+inline void load_le(const uint8_t in[],
+ T& x0, T& x1, T& x2, T& x3,
+ T& x4, T& x5, T& x6, T& x7)
+ {
+ x0 = load_le<T>(in, 0);
+ x1 = load_le<T>(in, 1);
+ x2 = load_le<T>(in, 2);
+ x3 = load_le<T>(in, 3);
+ x4 = load_le<T>(in, 4);
+ x5 = load_le<T>(in, 5);
+ x6 = load_le<T>(in, 6);
+ x7 = load_le<T>(in, 7);
+ }
+
+/**
+* Load a variable number of little-endian words
+* @param out the output array of words
+* @param in the input array of bytes
+* @param count how many words are in in
+*/
+template<typename T>
+inline void load_le(T out[],
+ const uint8_t in[],
+ size_t count)
+ {
+ if(count > 0)
+ {
+#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
+ std::memcpy(out, in, sizeof(T)*count);
+#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
+ std::memcpy(out, in, sizeof(T)*count);
+ 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 != left; ++i)
+ out[blocks+i] = reverse_bytes(out[blocks+i]);
+#else
+ for(size_t i = 0; i != count; ++i)
+ out[i] = load_le<T>(in, i);
+#endif
+ }
+ }
+
+/**
+* Load two big-endian words
+* @param in a pointer to some bytes
+* @param x0 where the first word will be written
+* @param x1 where the second word will be written
+*/
+template<typename T>
+inline void load_be(const uint8_t in[], T& x0, T& x1)
+ {
+ x0 = load_be<T>(in, 0);
+ x1 = load_be<T>(in, 1);
+ }
+
+/**
+* Load four big-endian words
+* @param in a pointer to some bytes
+* @param x0 where the first word will be written
+* @param x1 where the second word will be written
+* @param x2 where the third word will be written
+* @param x3 where the fourth word will be written
+*/
+template<typename T>
+inline void load_be(const uint8_t in[],
+ T& x0, T& x1, T& x2, T& x3)
+ {
+ x0 = load_be<T>(in, 0);
+ x1 = load_be<T>(in, 1);
+ x2 = load_be<T>(in, 2);
+ x3 = load_be<T>(in, 3);
+ }
+
+/**
+* Load eight big-endian words
+* @param in a pointer to some bytes
+* @param x0 where the first word will be written
+* @param x1 where the second word will be written
+* @param x2 where the third word will be written
+* @param x3 where the fourth word will be written
+* @param x4 where the fifth word will be written
+* @param x5 where the sixth word will be written
+* @param x6 where the seventh word will be written
+* @param x7 where the eighth word will be written
+*/
+template<typename T>
+inline void load_be(const uint8_t in[],
+ T& x0, T& x1, T& x2, T& x3,
+ T& x4, T& x5, T& x6, T& x7)
+ {
+ x0 = load_be<T>(in, 0);
+ x1 = load_be<T>(in, 1);
+ x2 = load_be<T>(in, 2);
+ x3 = load_be<T>(in, 3);
+ x4 = load_be<T>(in, 4);
+ x5 = load_be<T>(in, 5);
+ x6 = load_be<T>(in, 6);
+ x7 = load_be<T>(in, 7);
+ }
+
+/**
+* Load a variable number of big-endian words
+* @param out the output array of words
+* @param in the input array of bytes
+* @param count how many words are in in
+*/
+template<typename T>
+inline void load_be(T out[],
+ const uint8_t in[],
+ size_t count)
+ {
+ if(count > 0)
+ {
+#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
+ std::memcpy(out, in, sizeof(T)*count);
+
+#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
+ std::memcpy(out, in, sizeof(T)*count);
+ 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 != left; ++i)
+ out[blocks+i] = reverse_bytes(out[blocks+i]);
+#else
+ for(size_t i = 0; i != count; ++i)
+ out[i] = load_be<T>(in, i);
+#endif
+ }
+ }
+
+/**
+* Store a big-endian uint16_t
+* @param in the input uint16_t
+* @param out the byte array to write to
+*/
+inline void store_be(uint16_t in, uint8_t out[2])
+ {
+#if defined(BOTAN_ENDIAN_N2B)
+ uint16_t o = BOTAN_ENDIAN_N2B(in);
+ std::memcpy(out, &o, sizeof(o));
+#else
+ out[0] = get_byte(0, in);
+ out[1] = get_byte(1, in);
+#endif
+ }
+
+/**
+* Store a little-endian uint16_t
+* @param in the input uint16_t
+* @param out the byte array to write to
+*/
+inline void store_le(uint16_t in, uint8_t out[2])
+ {
+#if defined(BOTAN_ENDIAN_N2L)
+ uint16_t o = BOTAN_ENDIAN_N2L(in);
+ std::memcpy(out, &o, sizeof(o));
+#else
+ out[0] = get_byte(1, in);
+ out[1] = get_byte(0, in);
+#endif
+ }
+
+/**
+* Store a big-endian uint32_t
+* @param in the input uint32_t
+* @param out the byte array to write to
+*/
+inline void store_be(uint32_t in, uint8_t out[4])
+ {
+#if defined(BOTAN_ENDIAN_B2N)
+ uint32_t o = BOTAN_ENDIAN_B2N(in);
+ std::memcpy(out, &o, sizeof(o));
+#else
+ out[0] = get_byte(0, in);
+ out[1] = get_byte(1, in);
+ out[2] = get_byte(2, in);
+ out[3] = get_byte(3, in);
+#endif
+ }
+
+/**
+* Store a little-endian uint32_t
+* @param in the input uint32_t
+* @param out the byte array to write to
+*/
+inline void store_le(uint32_t in, uint8_t out[4])
+ {
+#if defined(BOTAN_ENDIAN_L2N)
+ uint32_t o = BOTAN_ENDIAN_L2N(in);
+ std::memcpy(out, &o, sizeof(o));
+#else
+ out[0] = get_byte(3, in);
+ out[1] = get_byte(2, in);
+ out[2] = get_byte(1, in);
+ out[3] = get_byte(0, in);
+#endif
+ }
+
+/**
+* Store a big-endian uint64_t
+* @param in the input uint64_t
+* @param out the byte array to write to
+*/
+inline void store_be(uint64_t in, uint8_t out[8])
+ {
+#if defined(BOTAN_ENDIAN_B2N)
+ uint64_t o = BOTAN_ENDIAN_B2N(in);
+ std::memcpy(out, &o, sizeof(o));
+#else
+ out[0] = get_byte(0, in);
+ out[1] = get_byte(1, in);
+ out[2] = get_byte(2, in);
+ out[3] = get_byte(3, in);
+ out[4] = get_byte(4, in);
+ out[5] = get_byte(5, in);
+ out[6] = get_byte(6, in);
+ out[7] = get_byte(7, in);
+#endif
+ }
+
+/**
+* Store a little-endian uint64_t
+* @param in the input uint64_t
+* @param out the byte array to write to
+*/
+inline void store_le(uint64_t in, uint8_t out[8])
+ {
+#if defined(BOTAN_ENDIAN_L2N)
+ uint64_t o = BOTAN_ENDIAN_L2N(in);
+ std::memcpy(out, &o, sizeof(o));
+#else
+ out[0] = get_byte(7, in);
+ out[1] = get_byte(6, in);
+ out[2] = get_byte(5, in);
+ out[3] = get_byte(4, in);
+ out[4] = get_byte(3, in);
+ out[5] = get_byte(2, in);
+ out[6] = get_byte(1, in);
+ out[7] = get_byte(0, in);
+#endif
+ }
+
+/**
+* Store two little-endian words
+* @param out the output byte array
+* @param x0 the first word
+* @param x1 the second word
+*/
+template<typename T>
+inline void store_le(uint8_t out[], T x0, T x1)
+ {
+ store_le(x0, out + (0 * sizeof(T)));
+ store_le(x1, out + (1 * sizeof(T)));
+ }
+
+/**
+* Store two big-endian words
+* @param out the output byte array
+* @param x0 the first word
+* @param x1 the second word
+*/
+template<typename T>
+inline void store_be(uint8_t out[], T x0, T x1)
+ {
+ store_be(x0, out + (0 * sizeof(T)));
+ store_be(x1, out + (1 * sizeof(T)));
+ }
+
+/**
+* Store four little-endian words
+* @param out the output byte array
+* @param x0 the first word
+* @param x1 the second word
+* @param x2 the third word
+* @param x3 the fourth word
+*/
+template<typename T>
+inline void store_le(uint8_t out[], T x0, T x1, T x2, T x3)
+ {
+ store_le(x0, out + (0 * sizeof(T)));
+ store_le(x1, out + (1 * sizeof(T)));
+ store_le(x2, out + (2 * sizeof(T)));
+ store_le(x3, out + (3 * sizeof(T)));
+ }
+
+/**
+* Store four big-endian words
+* @param out the output byte array
+* @param x0 the first word
+* @param x1 the second word
+* @param x2 the third word
+* @param x3 the fourth word
+*/
+template<typename T>
+inline void store_be(uint8_t out[], T x0, T x1, T x2, T x3)
+ {
+ store_be(x0, out + (0 * sizeof(T)));
+ store_be(x1, out + (1 * sizeof(T)));
+ store_be(x2, out + (2 * sizeof(T)));
+ store_be(x3, out + (3 * sizeof(T)));
+ }
+
+/**
+* Store eight little-endian words
+* @param out the output byte array
+* @param x0 the first word
+* @param x1 the second word
+* @param x2 the third word
+* @param x3 the fourth word
+* @param x4 the fifth word
+* @param x5 the sixth word
+* @param x6 the seventh word
+* @param x7 the eighth word
+*/
+template<typename T>
+inline void store_le(uint8_t out[], T x0, T x1, T x2, T x3,
+ T x4, T x5, T x6, T x7)
+ {
+ store_le(x0, out + (0 * sizeof(T)));
+ store_le(x1, out + (1 * sizeof(T)));
+ store_le(x2, out + (2 * sizeof(T)));
+ store_le(x3, out + (3 * sizeof(T)));
+ store_le(x4, out + (4 * sizeof(T)));
+ store_le(x5, out + (5 * sizeof(T)));
+ store_le(x6, out + (6 * sizeof(T)));
+ store_le(x7, out + (7 * sizeof(T)));
+ }
+
+/**
+* Store eight big-endian words
+* @param out the output byte array
+* @param x0 the first word
+* @param x1 the second word
+* @param x2 the third word
+* @param x3 the fourth word
+* @param x4 the fifth word
+* @param x5 the sixth word
+* @param x6 the seventh word
+* @param x7 the eighth word
+*/
+template<typename T>
+inline void store_be(uint8_t out[], T x0, T x1, T x2, T x3,
+ T x4, T x5, T x6, T x7)
+ {
+ store_be(x0, out + (0 * sizeof(T)));
+ store_be(x1, out + (1 * sizeof(T)));
+ store_be(x2, out + (2 * sizeof(T)));
+ store_be(x3, out + (3 * sizeof(T)));
+ store_be(x4, out + (4 * sizeof(T)));
+ store_be(x5, out + (5 * sizeof(T)));
+ store_be(x6, out + (6 * sizeof(T)));
+ store_be(x7, out + (7 * sizeof(T)));
+ }
+
+template<typename T>
+void copy_out_be(uint8_t out[], size_t out_bytes, const T in[])
+ {
+ while(out_bytes >= sizeof(T))
+ {
+ store_be(in[0], out);
+ out += sizeof(T);
+ out_bytes -= sizeof(T);
+ in += 1;
+ }
+
+ for(size_t i = 0; i != out_bytes; ++i)
+ out[i] = get_byte(i%8, in[0]);
+ }
+
+template<typename T, typename Alloc>
+void copy_out_vec_be(uint8_t out[], size_t out_bytes, const std::vector<T, Alloc>& in)
+ {
+ copy_out_be(out, out_bytes, in.data());
+ }
+
+template<typename T>
+void copy_out_le(uint8_t out[], size_t out_bytes, const T in[])
+ {
+ while(out_bytes >= sizeof(T))
+ {
+ store_le(in[0], out);
+ out += sizeof(T);
+ out_bytes -= sizeof(T);
+ in += 1;
+ }
+
+ for(size_t i = 0; i != out_bytes; ++i)
+ out[i] = get_byte(sizeof(T) - 1 - (i % 8), in[0]);
+ }
+
+template<typename T, typename Alloc>
+void copy_out_vec_le(uint8_t out[], size_t out_bytes, const std::vector<T, Alloc>& in)
+ {
+ copy_out_le(out, out_bytes, in.data());
+ }
+
+}
+
+#endif