byteorder.h 8.2 KB

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