xref: /freebsd/crypto/openssl/include/openssl/byteorder.h (revision e7be843b4a162e68651d3911f0357ed464915629)
1 /*
2  * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #ifndef OPENSSL_BYTEORDER_H
11 # define OPENSSL_BYTEORDER_H
12 # pragma once
13 
14 # include <openssl/e_os2.h>
15 # include <string.h>
16 
17 /*
18  * "Modern" compilers do a decent job of optimising these functions to just a
19  * couple of instruction ([swap +] store, or load [+ swap]) when either no
20  * swapping is required, or a suitable swap instruction is available.
21  */
22 
23 # if defined(_MSC_VER) && _MSC_VER>=1300
24 #  include <stdlib.h>
25 #  pragma intrinsic(_byteswap_ushort)
26 #  pragma intrinsic(_byteswap_ulong)
27 #  pragma intrinsic(_byteswap_uint64)
28 #  define OSSL_HTOBE16(x) _byteswap_ushort(x)
29 #  define OSSL_HTOBE32(x) _byteswap_ulong(x)
30 #  define OSSL_HTOBE64(x) _byteswap_uint64(x)
31 #  define OSSL_BE16TOH(x) _byteswap_ushort(x)
32 #  define OSSL_BE32TOH(x) _byteswap_ulong(x)
33 #  define OSSL_BE64TOH(x) _byteswap_uint64(x)
34 #  define OSSL_HTOLE16(x) (x)
35 #  define OSSL_HTOLE32(x) (x)
36 #  define OSSL_HTOLE64(x) (x)
37 #  define OSSL_LE16TOH(x) (x)
38 #  define OSSL_LE32TOH(x) (x)
39 #  define OSSL_LE64TOH(x) (x)
40 
41 # elif defined(__GLIBC__) && defined(__GLIBC_PREREQ)
42 #  if (__GLIBC_PREREQ(2, 19)) && defined(_DEFAULT_SOURCE)
43 #   include <endian.h>
44 #   define OSSL_HTOBE16(x) htobe16(x)
45 #   define OSSL_HTOBE32(x) htobe32(x)
46 #   define OSSL_HTOBE64(x) htobe64(x)
47 #   define OSSL_BE16TOH(x) be16toh(x)
48 #   define OSSL_BE32TOH(x) be32toh(x)
49 #   define OSSL_BE64TOH(x) be64toh(x)
50 #   define OSSL_HTOLE16(x) htole16(x)
51 #   define OSSL_HTOLE32(x) htole32(x)
52 #   define OSSL_HTOLE64(x) htole64(x)
53 #   define OSSL_LE16TOH(x) le16toh(x)
54 #   define OSSL_LE32TOH(x) le32toh(x)
55 #   define OSSL_LE64TOH(x) le64toh(x)
56 #  endif
57 
58 # elif defined(__FreeBSD__) || defined(__NetBSD__) || defined (__OpenBSD__)
59 #  if defined(__OpenBSD__)
60 #   include <sys/types.h>
61 #  else
62 #   include <sys/endian.h>
63 #  endif
64 #  define OSSL_HTOBE16(x) htobe16(x)
65 #  define OSSL_HTOBE32(x) htobe32(x)
66 #  define OSSL_HTOBE64(x) htobe64(x)
67 #  define OSSL_BE16TOH(x) be16toh(x)
68 #  define OSSL_BE32TOH(x) be32toh(x)
69 #  define OSSL_BE64TOH(x) be64toh(x)
70 #  define OSSL_HTOLE16(x) htole16(x)
71 #  define OSSL_HTOLE32(x) htole32(x)
72 #  define OSSL_HTOLE64(x) htole64(x)
73 #  define OSSL_LE16TOH(x) le16toh(x)
74 #  define OSSL_LE32TOH(x) le32toh(x)
75 #  define OSSL_LE64TOH(x) le64toh(x)
76 
77 # elif defined(__APPLE__)
78 #  include <libkern/OSByteOrder.h>
79 #  define OSSL_HTOBE16(x) OSSwapHostToBigInt16(x)
80 #  define OSSL_HTOBE32(x) OSSwapHostToBigInt32(x)
81 #  define OSSL_HTOBE64(x) OSSwapHostToBigInt64(x)
82 #  define OSSL_BE16TOH(x) OSSwapBigToHostInt16(x)
83 #  define OSSL_BE32TOH(x) OSSwapBigToHostInt32(x)
84 #  define OSSL_BE64TOH(x) OSSwapBigToHostInt64(x)
85 #  define OSSL_HTOLE16(x) OSSwapHostToLittleInt16(x)
86 #  define OSSL_HTOLE32(x) OSSwapHostToLittleInt32(x)
87 #  define OSSL_HTOLE64(x) OSSwapHostToLittleInt64(x)
88 #  define OSSL_LE16TOH(x) OSSwapLittleToHostInt16(x)
89 #  define OSSL_LE32TOH(x) OSSwapLittleToHostInt32(x)
90 #  define OSSL_LE64TOH(x) OSSwapLittleToHostInt64(x)
91 
92 # endif
93 
94 static ossl_inline ossl_unused unsigned char *
OPENSSL_store_u16_le(unsigned char * out,uint16_t val)95 OPENSSL_store_u16_le(unsigned char *out, uint16_t val)
96 {
97 # ifdef OSSL_HTOLE16
98     uint16_t t = OSSL_HTOLE16(val);
99 
100     memcpy(out, (unsigned char *)&t, 2);
101     return out + 2;
102 # else
103     *out++ = (val & 0xff);
104     *out++ = (val >> 8) & 0xff;
105     return out;
106 # endif
107 }
108 
109 static ossl_inline ossl_unused unsigned char *
OPENSSL_store_u16_be(unsigned char * out,uint16_t val)110 OPENSSL_store_u16_be(unsigned char *out, uint16_t val)
111 {
112 # ifdef OSSL_HTOBE16
113     uint16_t t = OSSL_HTOBE16(val);
114 
115     memcpy(out, (unsigned char *)&t, 2);
116     return out + 2;
117 # else
118     *out++ = (val >> 8) & 0xff;
119     *out++ = (val & 0xff);
120     return out;
121 # endif
122 }
123 
124 static ossl_inline ossl_unused unsigned char *
OPENSSL_store_u32_le(unsigned char * out,uint32_t val)125 OPENSSL_store_u32_le(unsigned char *out, uint32_t val)
126 {
127 # ifdef OSSL_HTOLE32
128     uint32_t t = OSSL_HTOLE32(val);
129 
130     memcpy(out, (unsigned char *)&t, 4);
131     return out + 4;
132 # else
133     *out++ = (val & 0xff);
134     *out++ = (val >> 8) & 0xff;
135     *out++ = (val >> 16) & 0xff;
136     *out++ = (val >> 24) & 0xff;
137     return out;
138 # endif
139 }
140 
141 static ossl_inline ossl_unused unsigned char *
OPENSSL_store_u32_be(unsigned char * out,uint32_t val)142 OPENSSL_store_u32_be(unsigned char *out, uint32_t val)
143 {
144 # ifdef OSSL_HTOBE32
145     uint32_t t = OSSL_HTOBE32(val);
146 
147     memcpy(out, (unsigned char *)&t, 4);
148     return out + 4;
149 # else
150     *out++ = (val >> 24) & 0xff;
151     *out++ = (val >> 16) & 0xff;
152     *out++ = (val >> 8) & 0xff;
153     *out++ = (val & 0xff);
154     return out;
155 # endif
156 }
157 
158 static ossl_inline ossl_unused unsigned char *
OPENSSL_store_u64_le(unsigned char * out,uint64_t val)159 OPENSSL_store_u64_le(unsigned char *out, uint64_t val)
160 {
161 # ifdef OSSL_HTOLE64
162     uint64_t t = OSSL_HTOLE64(val);
163 
164     memcpy(out, (unsigned char *)&t, 8);
165     return out + 8;
166 # else
167     *out++ = (val & 0xff);
168     *out++ = (val >> 8) & 0xff;
169     *out++ = (val >> 16) & 0xff;
170     *out++ = (val >> 24) & 0xff;
171     *out++ = (val >> 32) & 0xff;
172     *out++ = (val >> 40) & 0xff;
173     *out++ = (val >> 48) & 0xff;
174     *out++ = (val >> 56) & 0xff;
175     return out;
176 # endif
177 }
178 
179 static ossl_inline ossl_unused unsigned char *
OPENSSL_store_u64_be(unsigned char * out,uint64_t val)180 OPENSSL_store_u64_be(unsigned char *out, uint64_t val)
181 {
182 # ifdef OSSL_HTOLE64
183     uint64_t t = OSSL_HTOBE64(val);
184 
185     memcpy(out, (unsigned char *)&t, 8);
186     return out + 8;
187 # else
188     *out++ = (val >> 56) & 0xff;
189     *out++ = (val >> 48) & 0xff;
190     *out++ = (val >> 40) & 0xff;
191     *out++ = (val >> 32) & 0xff;
192     *out++ = (val >> 24) & 0xff;
193     *out++ = (val >> 16) & 0xff;
194     *out++ = (val >> 8) & 0xff;
195     *out++ = (val & 0xff);
196     return out;
197 # endif
198 }
199 
200 static ossl_inline ossl_unused const unsigned char *
OPENSSL_load_u16_le(uint16_t * val,const unsigned char * in)201 OPENSSL_load_u16_le(uint16_t *val, const unsigned char *in)
202 {
203 # ifdef OSSL_LE16TOH
204     uint16_t t;
205 
206     memcpy((unsigned char *)&t, in, 2);
207     *val = OSSL_LE16TOH(t);
208     return in + 2;
209 # else
210     uint16_t b0 = *in++;
211     uint16_t b1 = *in++;
212 
213     *val = b0 | (b1 << 8);
214     return in;
215 #endif
216 }
217 
218 static ossl_inline ossl_unused const unsigned char *
OPENSSL_load_u16_be(uint16_t * val,const unsigned char * in)219 OPENSSL_load_u16_be(uint16_t *val, const unsigned char *in)
220 {
221 # ifdef OSSL_LE16TOH
222     uint16_t t;
223 
224     memcpy((unsigned char *)&t, in, 2);
225     *val = OSSL_BE16TOH(t);
226     return in + 2;
227 # else
228     uint16_t b1 = *in++;
229     uint16_t b0 = *in++;
230 
231     *val = b0 | (b1 << 8);
232     return in;
233 #endif
234 }
235 
236 static ossl_inline ossl_unused const unsigned char *
OPENSSL_load_u32_le(uint32_t * val,const unsigned char * in)237 OPENSSL_load_u32_le(uint32_t *val, const unsigned char *in)
238 {
239 # ifdef OSSL_LE32TOH
240     uint32_t t;
241 
242     memcpy((unsigned char *)&t, in, 4);
243     *val = OSSL_LE32TOH(t);
244     return in + 4;
245 # else
246     uint32_t b0 = *in++;
247     uint32_t b1 = *in++;
248     uint32_t b2 = *in++;
249     uint32_t b3 = *in++;
250 
251     *val = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
252     return in;
253 #endif
254 }
255 
256 static ossl_inline ossl_unused const unsigned char *
OPENSSL_load_u32_be(uint32_t * val,const unsigned char * in)257 OPENSSL_load_u32_be(uint32_t *val, const unsigned char *in)
258 {
259 # ifdef OSSL_LE32TOH
260     uint32_t t;
261 
262     memcpy((unsigned char *)&t, in, 4);
263     *val = OSSL_BE32TOH(t);
264     return in + 4;
265 # else
266     uint32_t b3 = *in++;
267     uint32_t b2 = *in++;
268     uint32_t b1 = *in++;
269     uint32_t b0 = *in++;
270 
271     *val = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
272     return in;
273 #endif
274 }
275 
276 static ossl_inline ossl_unused const unsigned char *
OPENSSL_load_u64_le(uint64_t * val,const unsigned char * in)277 OPENSSL_load_u64_le(uint64_t *val, const unsigned char *in)
278 {
279 # ifdef OSSL_LE64TOH
280     uint64_t t;
281 
282     memcpy((unsigned char *)&t, in, 8);
283     *val = OSSL_LE64TOH(t);
284     return in + 8;
285 # else
286     uint64_t b0 = *in++;
287     uint64_t b1 = *in++;
288     uint64_t b2 = *in++;
289     uint64_t b3 = *in++;
290     uint64_t b4 = *in++;
291     uint64_t b5 = *in++;
292     uint64_t b6 = *in++;
293     uint64_t b7 = *in++;
294 
295     *val = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24)
296         | (b4 << 32) | (b5 << 40) | (b6 << 48) | (b7 << 56);
297     return in;
298 #endif
299 }
300 
301 static ossl_inline ossl_unused const unsigned char *
OPENSSL_load_u64_be(uint64_t * val,const unsigned char * in)302 OPENSSL_load_u64_be(uint64_t *val, const unsigned char *in)
303 {
304 # ifdef OSSL_LE64TOH
305     uint64_t t;
306 
307     memcpy((unsigned char *)&t, in, 8);
308     *val = OSSL_BE64TOH(t);
309     return in + 8;
310 # else
311     uint64_t b7 = *in++;
312     uint64_t b6 = *in++;
313     uint64_t b5 = *in++;
314     uint64_t b4 = *in++;
315     uint64_t b3 = *in++;
316     uint64_t b2 = *in++;
317     uint64_t b1 = *in++;
318     uint64_t b0 = *in++;
319 
320     *val = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24)
321         | (b4 << 32) | (b5 << 40) | (b6 << 48) | (b7 << 56);
322     return in;
323 #endif
324 }
325 
326 # undef OSSL_HTOBE16
327 # undef OSSL_HTOBE32
328 # undef OSSL_HTOBE64
329 # undef OSSL_BE16TOH
330 # undef OSSL_BE32TOH
331 # undef OSSL_BE64TOH
332 # undef OSSL_HTOLE16
333 # undef OSSL_HTOLE32
334 # undef OSSL_HTOLE64
335 # undef OSSL_LE16TOH
336 # undef OSSL_LE32TOH
337 # undef OSSL_LE64TOH
338 
339 #endif
340