1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
/* Functions to copy data between possibly-unaligned byte buffers
and machine integers, fixing the endianness.
Written by Zack Weinberg <zackw at panix.com> in 2017.
To the extent possible under law, Zack Weinberg has waived all
copyright and related or neighboring rights to this work.
See https://creativecommons.org/publicdomain/zero/1.0/ for further
details. */
#ifndef _CRYPT_BYTEORDER_H
#define _CRYPT_BYTEORDER_H 1
static inline uint32_t
le32_to_cpu (const unsigned char *buf)
{
return ((((uint32_t)buf[0]) << 0) |
(((uint32_t)buf[1]) << 8) |
(((uint32_t)buf[2]) << 16) |
(((uint32_t)buf[3]) << 24) );
}
static inline uint32_t
be32_to_cpu (const unsigned char *buf)
{
return ((((uint32_t)buf[0]) << 24) |
(((uint32_t)buf[1]) << 16) |
(((uint32_t)buf[2]) << 8) |
(((uint32_t)buf[3]) << 0) );
}
static inline uint64_t
le64_to_cpu (const unsigned char *buf)
{
return ((((uint64_t)buf[0]) << 0) |
(((uint64_t)buf[1]) << 8) |
(((uint64_t)buf[2]) << 16) |
(((uint64_t)buf[3]) << 24) |
(((uint64_t)buf[4]) << 32) |
(((uint64_t)buf[5]) << 40) |
(((uint64_t)buf[6]) << 48) |
(((uint64_t)buf[7]) << 56) );
}
static inline uint64_t
be64_to_cpu (const unsigned char *buf)
{
return ((((uint64_t)buf[0]) << 56) |
(((uint64_t)buf[1]) << 48) |
(((uint64_t)buf[2]) << 40) |
(((uint64_t)buf[3]) << 32) |
(((uint64_t)buf[4]) << 24) |
(((uint64_t)buf[5]) << 16) |
(((uint64_t)buf[6]) << 8) |
(((uint64_t)buf[7]) << 0) );
}
static inline void
cpu_to_le32 (unsigned char *buf, uint32_t n)
{
buf[0] = (unsigned char)((n & 0x000000FFu) >> 0);
buf[1] = (unsigned char)((n & 0x0000FF00u) >> 8);
buf[2] = (unsigned char)((n & 0x00FF0000u) >> 16);
buf[3] = (unsigned char)((n & 0xFF000000u) >> 24);
}
static inline void
cpu_to_be32 (unsigned char *buf, uint32_t n)
{
buf[0] = (unsigned char)((n & 0xFF000000u) >> 24);
buf[1] = (unsigned char)((n & 0x00FF0000u) >> 16);
buf[2] = (unsigned char)((n & 0x0000FF00u) >> 8);
buf[3] = (unsigned char)((n & 0x000000FFu) >> 0);
}
static inline void
cpu_to_le64 (unsigned char *buf, uint64_t n)
{
buf[0] = (unsigned char)((n & 0x00000000000000FFull) >> 0);
buf[1] = (unsigned char)((n & 0x000000000000FF00ull) >> 8);
buf[2] = (unsigned char)((n & 0x0000000000FF0000ull) >> 16);
buf[3] = (unsigned char)((n & 0x00000000FF000000ull) >> 24);
buf[4] = (unsigned char)((n & 0x000000FF00000000ull) >> 32);
buf[5] = (unsigned char)((n & 0x0000FF0000000000ull) >> 40);
buf[6] = (unsigned char)((n & 0x00FF000000000000ull) >> 48);
buf[7] = (unsigned char)((n & 0xFF00000000000000ull) >> 56);
}
static inline void
cpu_to_be64 (unsigned char *buf, uint64_t n)
{
buf[0] = (unsigned char)((n & 0xFF00000000000000ull) >> 56);
buf[1] = (unsigned char)((n & 0x00FF000000000000ull) >> 48);
buf[2] = (unsigned char)((n & 0x0000FF0000000000ull) >> 40);
buf[3] = (unsigned char)((n & 0x000000FF00000000ull) >> 32);
buf[4] = (unsigned char)((n & 0x00000000FF000000ull) >> 24);
buf[5] = (unsigned char)((n & 0x0000000000FF0000ull) >> 16);
buf[6] = (unsigned char)((n & 0x000000000000FF00ull) >> 8);
buf[7] = (unsigned char)((n & 0x00000000000000FFull) >> 0);
}
/* Template: Define a function named cpu_to_<END><BITS>_vect that
takes a vector SRC of LEN integers, each of type uint<BITS>_t, and
writes them to the buffer DST in the endianness defined by END.
Caution: LEN is the number of vector elements, not the total size
of the buffers. */
#define VECTOR_CPU_TO(end, bits) VECTOR_CPU_TO_(end##bits, uint##bits##_t)
#define VECTOR_CPU_TO_(prim, stype) \
static inline void \
cpu_to_##prim##_vect(uint8_t *dst, const stype *src, size_t len) \
{ \
while (len) \
{ \
cpu_to_##prim(dst, *src); \
src += 1; \
dst += sizeof(stype); \
len -= 1; \
} \
} struct _swallow_semicolon
/* Template: Define a function named <END><BITS>_to_cpu_vect that
reads a vector of LEN integers, each of type uint<BITS>_t, from the
buffer SRC, in the endianness defined by END, and writes them to
the vector DST. Caution: LEN is the number of vector elements, not
the total size of the buffers. */
#define VECTOR_TO_CPU(end, bits) VECTOR_TO_CPU_(end##bits, uint##bits##_t)
#define VECTOR_TO_CPU_(prim, dtype) \
static inline void \
prim##_to_cpu_vect(dtype *dst, const uint8_t *src, size_t len) \
{ \
while (len) \
{ \
*dst = prim##_to_cpu(src); \
src += sizeof(dtype); \
dst += 1; \
len -= 1; \
} \
} struct _swallow_semicolon
/* These are the vectorized endianness-conversion functions that are
presently used. Add more as necessary. */
VECTOR_CPU_TO(be,32);
VECTOR_CPU_TO(be,64);
VECTOR_TO_CPU(be,32);
VECTOR_TO_CPU(be,64);
/* Alternative names used in code derived from Colin Percival's
cryptography libraries. */
#define le32enc cpu_to_le32
#define le32dec le32_to_cpu
#define le64enc cpu_to_le64
#define le64dec le64_to_cpu
#define be32enc cpu_to_be32
#define be32dec be32_to_cpu
#define be64enc cpu_to_be64
#define be64dec be64_to_cpu
#define be32enc_vect cpu_to_be32_vect
#define be32dec_vect be32_to_cpu_vect
#define be64enc_vect cpu_to_be64_vect
#define be64dec_vect be64_to_cpu_vect
#endif /* byteorder.h */
|