xref: /freebsd/contrib/libfido2/openbsd-compat/endian_win32.c (revision a03411e84728e9b267056fd31c7d1d9d1dc1b01e)
1 /*
2  * Copyright (c) 2020 Yubico AB. All rights reserved.
3  * Use of this source code is governed by a BSD-style
4  * license that can be found in the LICENSE file.
5  * SPDX-License-Identifier: BSD-2-Clause
6  */
7 
8 #include "openbsd-compat.h"
9 
10 #if defined(_WIN32) && !defined(HAVE_ENDIAN_H)
11 
12 /*
13  * Hopefully, if the endianness differs from the end result, the compiler
14  * optimizes these functions with some type of bswap instruction. Or,
15  * otherwise, to just return the input value unmodified. GCC and clang
16  * both does these optimization at least. This should be preferred over
17  * relying on some BYTE_ORDER macro, which may or may not be defined.
18  */
19 
20 uint32_t
21 htole32(uint32_t in)
22 {
23 	uint32_t	 out = 0;
24 	uint8_t		*b = (uint8_t *)&out;
25 
26 	b[0] = (uint8_t)((in >> 0)  & 0xff);
27 	b[1] = (uint8_t)((in >> 8)  & 0xff);
28 	b[2] = (uint8_t)((in >> 16) & 0xff);
29 	b[3] = (uint8_t)((in >> 24) & 0xff);
30 
31 	return (out);
32 }
33 
34 uint64_t
35 htole64(uint64_t in)
36 {
37 	uint64_t	 out = 0;
38 	uint8_t		*b = (uint8_t *)&out;
39 
40 	b[0] = (uint8_t)((in >> 0)  & 0xff);
41 	b[1] = (uint8_t)((in >> 8)  & 0xff);
42 	b[2] = (uint8_t)((in >> 16) & 0xff);
43 	b[3] = (uint8_t)((in >> 24) & 0xff);
44 	b[4] = (uint8_t)((in >> 32) & 0xff);
45 	b[5] = (uint8_t)((in >> 40) & 0xff);
46 	b[6] = (uint8_t)((in >> 48) & 0xff);
47 	b[7] = (uint8_t)((in >> 56) & 0xff);
48 
49 	return (out);
50 }
51 
52 #endif /* WIN32 && !HAVE_ENDIAN_H */
53