blob: 4bca10e8f51316e27102f655e9f2f86aa1e93b4c [file] [log] [blame]
Dave Rodgmanfbc23222022-11-24 18:07:37 +00001/**
2 * \file alignment.h
3 *
4 * \brief Utility code for dealing with unaligned memory accesses
5 */
6/*
7 * Copyright The Mbed TLS Contributors
Dave Rodgman16799db2023-11-02 19:47:20 +00008 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Dave Rodgmanfbc23222022-11-24 18:07:37 +00009 */
10
11#ifndef MBEDTLS_LIBRARY_ALIGNMENT_H
12#define MBEDTLS_LIBRARY_ALIGNMENT_H
13
14#include <stdint.h>
Dave Rodgman96d61d12022-11-24 19:33:22 +000015#include <string.h>
Dave Rodgmanf7f1f742022-11-28 14:52:45 +000016#include <stdlib.h>
Dave Rodgmanfbc23222022-11-24 18:07:37 +000017
Dave Rodgmanb9cd19b2022-12-30 21:32:03 +000018/*
19 * Define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS for architectures where unaligned memory
Dave Rodgman7f376fa2023-01-05 12:25:15 +000020 * accesses are known to be efficient.
21 *
22 * All functions defined here will behave correctly regardless, but might be less
23 * efficient when this is not defined.
Dave Rodgmanb9cd19b2022-12-30 21:32:03 +000024 */
25#if defined(__ARM_FEATURE_UNALIGNED) \
26 || defined(__i386__) || defined(__amd64__) || defined(__x86_64__)
27/*
28 * __ARM_FEATURE_UNALIGNED is defined where appropriate by armcc, gcc 7, clang 9
Dave Rodgman7f376fa2023-01-05 12:25:15 +000029 * (and later versions) for Arm v7 and later; all x86 platforms should have
30 * efficient unaligned access.
Dave Rodgmanb9cd19b2022-12-30 21:32:03 +000031 */
32#define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS
33#endif
34
Dave Rodgman96d61d12022-11-24 19:33:22 +000035/**
Dave Rodgmana360e192022-11-28 14:44:05 +000036 * Read the unsigned 16 bits integer from the given address, which need not
37 * be aligned.
38 *
39 * \param p pointer to 2 bytes of data
40 * \return Data at the given address
41 */
Gilles Peskine449bd832023-01-11 14:50:10 +010042inline uint16_t mbedtls_get_unaligned_uint16(const void *p)
Dave Rodgmana360e192022-11-28 14:44:05 +000043{
44 uint16_t r;
Gilles Peskine449bd832023-01-11 14:50:10 +010045 memcpy(&r, p, sizeof(r));
Dave Rodgmana360e192022-11-28 14:44:05 +000046 return r;
47}
48
49/**
50 * Write the unsigned 16 bits integer to the given address, which need not
51 * be aligned.
52 *
53 * \param p pointer to 2 bytes of data
54 * \param x data to write
55 */
Gilles Peskine449bd832023-01-11 14:50:10 +010056inline void mbedtls_put_unaligned_uint16(void *p, uint16_t x)
Dave Rodgmana360e192022-11-28 14:44:05 +000057{
Gilles Peskine449bd832023-01-11 14:50:10 +010058 memcpy(p, &x, sizeof(x));
Dave Rodgmana360e192022-11-28 14:44:05 +000059}
60
61/**
Dave Rodgman96d61d12022-11-24 19:33:22 +000062 * Read the unsigned 32 bits integer from the given address, which need not
63 * be aligned.
Dave Rodgmanfbc23222022-11-24 18:07:37 +000064 *
Dave Rodgman96d61d12022-11-24 19:33:22 +000065 * \param p pointer to 4 bytes of data
Dave Rodgman875d2382022-11-24 20:43:15 +000066 * \return Data at the given address
Dave Rodgmanfbc23222022-11-24 18:07:37 +000067 */
Gilles Peskine449bd832023-01-11 14:50:10 +010068inline uint32_t mbedtls_get_unaligned_uint32(const void *p)
Dave Rodgman96d61d12022-11-24 19:33:22 +000069{
70 uint32_t r;
Gilles Peskine449bd832023-01-11 14:50:10 +010071 memcpy(&r, p, sizeof(r));
Dave Rodgman96d61d12022-11-24 19:33:22 +000072 return r;
73}
Dave Rodgmanfbc23222022-11-24 18:07:37 +000074
Dave Rodgman96d61d12022-11-24 19:33:22 +000075/**
76 * Write the unsigned 32 bits integer to the given address, which need not
77 * be aligned.
78 *
79 * \param p pointer to 4 bytes of data
80 * \param x data to write
81 */
Gilles Peskine449bd832023-01-11 14:50:10 +010082inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x)
Dave Rodgman96d61d12022-11-24 19:33:22 +000083{
Gilles Peskine449bd832023-01-11 14:50:10 +010084 memcpy(p, &x, sizeof(x));
Dave Rodgman96d61d12022-11-24 19:33:22 +000085}
Dave Rodgmanfbc23222022-11-24 18:07:37 +000086
Dave Rodgmana360e192022-11-28 14:44:05 +000087/**
88 * Read the unsigned 64 bits integer from the given address, which need not
89 * be aligned.
90 *
91 * \param p pointer to 8 bytes of data
92 * \return Data at the given address
93 */
Gilles Peskine449bd832023-01-11 14:50:10 +010094inline uint64_t mbedtls_get_unaligned_uint64(const void *p)
Dave Rodgmana360e192022-11-28 14:44:05 +000095{
96 uint64_t r;
Gilles Peskine449bd832023-01-11 14:50:10 +010097 memcpy(&r, p, sizeof(r));
Dave Rodgmana360e192022-11-28 14:44:05 +000098 return r;
99}
100
101/**
102 * Write the unsigned 64 bits integer to the given address, which need not
103 * be aligned.
104 *
105 * \param p pointer to 8 bytes of data
106 * \param x data to write
107 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100108inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x)
Dave Rodgmana360e192022-11-28 14:44:05 +0000109{
Gilles Peskine449bd832023-01-11 14:50:10 +0100110 memcpy(p, &x, sizeof(x));
Dave Rodgmana360e192022-11-28 14:44:05 +0000111}
112
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000113/** Byte Reading Macros
114 *
115 * Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th
116 * byte from x, where byte 0 is the least significant byte.
117 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100118#define MBEDTLS_BYTE_0(x) ((uint8_t) ((x) & 0xff))
Dave Rodgman914c6322023-03-01 09:30:14 +0000119#define MBEDTLS_BYTE_1(x) ((uint8_t) (((x) >> 8) & 0xff))
Gilles Peskine449bd832023-01-11 14:50:10 +0100120#define MBEDTLS_BYTE_2(x) ((uint8_t) (((x) >> 16) & 0xff))
121#define MBEDTLS_BYTE_3(x) ((uint8_t) (((x) >> 24) & 0xff))
122#define MBEDTLS_BYTE_4(x) ((uint8_t) (((x) >> 32) & 0xff))
123#define MBEDTLS_BYTE_5(x) ((uint8_t) (((x) >> 40) & 0xff))
124#define MBEDTLS_BYTE_6(x) ((uint8_t) (((x) >> 48) & 0xff))
125#define MBEDTLS_BYTE_7(x) ((uint8_t) (((x) >> 56) & 0xff))
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000126
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000127/*
128 * Detect GCC built-in byteswap routines
129 */
130#if defined(__GNUC__) && defined(__GNUC_PREREQ)
Gilles Peskine449bd832023-01-11 14:50:10 +0100131#if __GNUC_PREREQ(4, 8)
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000132#define MBEDTLS_BSWAP16 __builtin_bswap16
133#endif /* __GNUC_PREREQ(4,8) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100134#if __GNUC_PREREQ(4, 3)
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000135#define MBEDTLS_BSWAP32 __builtin_bswap32
136#define MBEDTLS_BSWAP64 __builtin_bswap64
137#endif /* __GNUC_PREREQ(4,3) */
138#endif /* defined(__GNUC__) && defined(__GNUC_PREREQ) */
139
140/*
141 * Detect Clang built-in byteswap routines
142 */
143#if defined(__clang__) && defined(__has_builtin)
Dave Rodgmane47899d2023-02-28 17:39:03 +0000144#if __has_builtin(__builtin_bswap16) && !defined(MBEDTLS_BSWAP16)
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000145#define MBEDTLS_BSWAP16 __builtin_bswap16
146#endif /* __has_builtin(__builtin_bswap16) */
Dave Rodgmane47899d2023-02-28 17:39:03 +0000147#if __has_builtin(__builtin_bswap32) && !defined(MBEDTLS_BSWAP32)
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000148#define MBEDTLS_BSWAP32 __builtin_bswap32
149#endif /* __has_builtin(__builtin_bswap32) */
Dave Rodgmane47899d2023-02-28 17:39:03 +0000150#if __has_builtin(__builtin_bswap64) && !defined(MBEDTLS_BSWAP64)
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000151#define MBEDTLS_BSWAP64 __builtin_bswap64
152#endif /* __has_builtin(__builtin_bswap64) */
153#endif /* defined(__clang__) && defined(__has_builtin) */
154
155/*
156 * Detect MSVC built-in byteswap routines
157 */
158#if defined(_MSC_VER)
Dave Rodgmane47899d2023-02-28 17:39:03 +0000159#if !defined(MBEDTLS_BSWAP16)
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000160#define MBEDTLS_BSWAP16 _byteswap_ushort
Dave Rodgmane47899d2023-02-28 17:39:03 +0000161#endif
162#if !defined(MBEDTLS_BSWAP32)
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000163#define MBEDTLS_BSWAP32 _byteswap_ulong
Dave Rodgmane47899d2023-02-28 17:39:03 +0000164#endif
165#if !defined(MBEDTLS_BSWAP64)
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000166#define MBEDTLS_BSWAP64 _byteswap_uint64
Dave Rodgmane47899d2023-02-28 17:39:03 +0000167#endif
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000168#endif /* defined(_MSC_VER) */
169
Dave Rodgman2dae4b32022-11-30 12:07:36 +0000170/* Detect armcc built-in byteswap routine */
Dave Rodgmane47899d2023-02-28 17:39:03 +0000171#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 410000) && !defined(MBEDTLS_BSWAP32)
Tom Cosgrovef2b5a132023-04-26 17:00:12 +0100172#if defined(__ARM_ACLE) /* ARM Compiler 6 - earlier versions don't need a header */
173#include <arm_acle.h>
174#endif
Dave Rodgman2dae4b32022-11-30 12:07:36 +0000175#define MBEDTLS_BSWAP32 __rev
176#endif
177
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000178/*
179 * Where compiler built-ins are not present, fall back to C code that the
180 * compiler may be able to detect and transform into the relevant bswap or
181 * similar instruction.
182 */
183#if !defined(MBEDTLS_BSWAP16)
Gilles Peskine449bd832023-01-11 14:50:10 +0100184static inline uint16_t mbedtls_bswap16(uint16_t x)
185{
Dave Rodgman6298b242022-11-28 14:51:49 +0000186 return
Gilles Peskine449bd832023-01-11 14:50:10 +0100187 (x & 0x00ff) << 8 |
188 (x & 0xff00) >> 8;
Dave Rodgman6298b242022-11-28 14:51:49 +0000189}
190#define MBEDTLS_BSWAP16 mbedtls_bswap16
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000191#endif /* !defined(MBEDTLS_BSWAP16) */
Dave Rodgman6298b242022-11-28 14:51:49 +0000192
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000193#if !defined(MBEDTLS_BSWAP32)
Gilles Peskine449bd832023-01-11 14:50:10 +0100194static inline uint32_t mbedtls_bswap32(uint32_t x)
195{
Dave Rodgman6298b242022-11-28 14:51:49 +0000196 return
Gilles Peskine449bd832023-01-11 14:50:10 +0100197 (x & 0x000000ff) << 24 |
198 (x & 0x0000ff00) << 8 |
199 (x & 0x00ff0000) >> 8 |
200 (x & 0xff000000) >> 24;
Dave Rodgman6298b242022-11-28 14:51:49 +0000201}
202#define MBEDTLS_BSWAP32 mbedtls_bswap32
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000203#endif /* !defined(MBEDTLS_BSWAP32) */
Dave Rodgman6298b242022-11-28 14:51:49 +0000204
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000205#if !defined(MBEDTLS_BSWAP64)
Gilles Peskine449bd832023-01-11 14:50:10 +0100206static inline uint64_t mbedtls_bswap64(uint64_t x)
207{
Dave Rodgman6298b242022-11-28 14:51:49 +0000208 return
Tom Cosgrovebbe166e2023-03-08 13:23:24 +0000209 (x & 0x00000000000000ffULL) << 56 |
210 (x & 0x000000000000ff00ULL) << 40 |
211 (x & 0x0000000000ff0000ULL) << 24 |
212 (x & 0x00000000ff000000ULL) << 8 |
213 (x & 0x000000ff00000000ULL) >> 8 |
214 (x & 0x0000ff0000000000ULL) >> 24 |
215 (x & 0x00ff000000000000ULL) >> 40 |
216 (x & 0xff00000000000000ULL) >> 56;
Dave Rodgman6298b242022-11-28 14:51:49 +0000217}
218#define MBEDTLS_BSWAP64 mbedtls_bswap64
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000219#endif /* !defined(MBEDTLS_BSWAP64) */
Dave Rodgman6298b242022-11-28 14:51:49 +0000220
Dave Rodgmane5c42592022-11-28 14:47:46 +0000221#if !defined(__BYTE_ORDER__)
222static const uint16_t mbedtls_byte_order_detector = { 0x100 };
223#define MBEDTLS_IS_BIG_ENDIAN (*((unsigned char *) (&mbedtls_byte_order_detector)) == 0x01)
224#else
225#define MBEDTLS_IS_BIG_ENDIAN ((__BYTE_ORDER__) == (__ORDER_BIG_ENDIAN__))
226#endif /* !defined(__BYTE_ORDER__) */
227
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000228/**
229 * Get the unsigned 32 bits integer corresponding to four bytes in
230 * big-endian order (MSB first).
231 *
232 * \param data Base address of the memory to get the four bytes from.
233 * \param offset Offset from \p data of the first and most significant
234 * byte of the four bytes to build the 32 bits unsigned
235 * integer from.
236 */
Dave Rodgman914c6322023-03-01 09:30:14 +0000237#define MBEDTLS_GET_UINT32_BE(data, offset) \
238 ((MBEDTLS_IS_BIG_ENDIAN) \
Dave Rodgmana5110b02022-11-28 14:48:45 +0000239 ? mbedtls_get_unaligned_uint32((data) + (offset)) \
240 : MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000241 )
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000242
243/**
244 * Put in memory a 32 bits unsigned integer in big-endian order.
245 *
246 * \param n 32 bits unsigned integer to put in memory.
247 * \param data Base address of the memory where to put the 32
248 * bits unsigned integer in.
249 * \param offset Offset from \p data where to put the most significant
250 * byte of the 32 bits unsigned integer \p n.
251 */
Dave Rodgman914c6322023-03-01 09:30:14 +0000252#define MBEDTLS_PUT_UINT32_BE(n, data, offset) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100253 { \
Dave Rodgman914c6322023-03-01 09:30:14 +0000254 if (MBEDTLS_IS_BIG_ENDIAN) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 { \
Dave Rodgman914c6322023-03-01 09:30:14 +0000256 mbedtls_put_unaligned_uint32((data) + (offset), (uint32_t) (n)); \
Gilles Peskine449bd832023-01-11 14:50:10 +0100257 } \
258 else \
259 { \
260 mbedtls_put_unaligned_uint32((data) + (offset), MBEDTLS_BSWAP32((uint32_t) (n))); \
261 } \
262 }
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000263
264/**
265 * Get the unsigned 32 bits integer corresponding to four bytes in
266 * little-endian order (LSB first).
267 *
268 * \param data Base address of the memory to get the four bytes from.
269 * \param offset Offset from \p data of the first and least significant
270 * byte of the four bytes to build the 32 bits unsigned
271 * integer from.
272 */
Dave Rodgman914c6322023-03-01 09:30:14 +0000273#define MBEDTLS_GET_UINT32_LE(data, offset) \
274 ((MBEDTLS_IS_BIG_ENDIAN) \
Dave Rodgmana5110b02022-11-28 14:48:45 +0000275 ? MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \
276 : mbedtls_get_unaligned_uint32((data) + (offset)) \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000277 )
Dave Rodgmana5110b02022-11-28 14:48:45 +0000278
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000279
280/**
281 * Put in memory a 32 bits unsigned integer in little-endian order.
282 *
283 * \param n 32 bits unsigned integer to put in memory.
284 * \param data Base address of the memory where to put the 32
285 * bits unsigned integer in.
286 * \param offset Offset from \p data where to put the least significant
287 * byte of the 32 bits unsigned integer \p n.
288 */
Dave Rodgman914c6322023-03-01 09:30:14 +0000289#define MBEDTLS_PUT_UINT32_LE(n, data, offset) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100290 { \
Dave Rodgman914c6322023-03-01 09:30:14 +0000291 if (MBEDTLS_IS_BIG_ENDIAN) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100292 { \
293 mbedtls_put_unaligned_uint32((data) + (offset), MBEDTLS_BSWAP32((uint32_t) (n))); \
294 } \
295 else \
296 { \
Dave Rodgman914c6322023-03-01 09:30:14 +0000297 mbedtls_put_unaligned_uint32((data) + (offset), ((uint32_t) (n))); \
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 } \
299 }
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000300
301/**
302 * Get the unsigned 16 bits integer corresponding to two bytes in
303 * little-endian order (LSB first).
304 *
305 * \param data Base address of the memory to get the two bytes from.
306 * \param offset Offset from \p data of the first and least significant
307 * byte of the two bytes to build the 16 bits unsigned
308 * integer from.
309 */
Dave Rodgman914c6322023-03-01 09:30:14 +0000310#define MBEDTLS_GET_UINT16_LE(data, offset) \
311 ((MBEDTLS_IS_BIG_ENDIAN) \
Dave Rodgmana5110b02022-11-28 14:48:45 +0000312 ? MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \
313 : mbedtls_get_unaligned_uint16((data) + (offset)) \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000314 )
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000315
316/**
317 * Put in memory a 16 bits unsigned integer in little-endian order.
318 *
319 * \param n 16 bits unsigned integer to put in memory.
320 * \param data Base address of the memory where to put the 16
321 * bits unsigned integer in.
322 * \param offset Offset from \p data where to put the least significant
323 * byte of the 16 bits unsigned integer \p n.
324 */
Dave Rodgman914c6322023-03-01 09:30:14 +0000325#define MBEDTLS_PUT_UINT16_LE(n, data, offset) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100326 { \
Dave Rodgman914c6322023-03-01 09:30:14 +0000327 if (MBEDTLS_IS_BIG_ENDIAN) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100328 { \
329 mbedtls_put_unaligned_uint16((data) + (offset), MBEDTLS_BSWAP16((uint16_t) (n))); \
330 } \
331 else \
332 { \
Dave Rodgman914c6322023-03-01 09:30:14 +0000333 mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n)); \
Gilles Peskine449bd832023-01-11 14:50:10 +0100334 } \
335 }
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000336
337/**
338 * Get the unsigned 16 bits integer corresponding to two bytes in
339 * big-endian order (MSB first).
340 *
341 * \param data Base address of the memory to get the two bytes from.
342 * \param offset Offset from \p data of the first and most significant
343 * byte of the two bytes to build the 16 bits unsigned
344 * integer from.
345 */
Dave Rodgman914c6322023-03-01 09:30:14 +0000346#define MBEDTLS_GET_UINT16_BE(data, offset) \
347 ((MBEDTLS_IS_BIG_ENDIAN) \
Dave Rodgmana5110b02022-11-28 14:48:45 +0000348 ? mbedtls_get_unaligned_uint16((data) + (offset)) \
349 : MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000350 )
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000351
352/**
353 * Put in memory a 16 bits unsigned integer in big-endian order.
354 *
355 * \param n 16 bits unsigned integer to put in memory.
356 * \param data Base address of the memory where to put the 16
357 * bits unsigned integer in.
358 * \param offset Offset from \p data where to put the most significant
359 * byte of the 16 bits unsigned integer \p n.
360 */
Dave Rodgman914c6322023-03-01 09:30:14 +0000361#define MBEDTLS_PUT_UINT16_BE(n, data, offset) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100362 { \
Dave Rodgman914c6322023-03-01 09:30:14 +0000363 if (MBEDTLS_IS_BIG_ENDIAN) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100364 { \
Dave Rodgman914c6322023-03-01 09:30:14 +0000365 mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n)); \
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 } \
367 else \
368 { \
369 mbedtls_put_unaligned_uint16((data) + (offset), MBEDTLS_BSWAP16((uint16_t) (n))); \
370 } \
371 }
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000372
373/**
374 * Get the unsigned 24 bits integer corresponding to three bytes in
375 * big-endian order (MSB first).
376 *
377 * \param data Base address of the memory to get the three bytes from.
378 * \param offset Offset from \p data of the first and most significant
379 * byte of the three bytes to build the 24 bits unsigned
380 * integer from.
381 */
Dave Rodgman914c6322023-03-01 09:30:14 +0000382#define MBEDTLS_GET_UINT24_BE(data, offset) \
383 ( \
384 ((uint32_t) (data)[(offset)] << 16) \
385 | ((uint32_t) (data)[(offset) + 1] << 8) \
386 | ((uint32_t) (data)[(offset) + 2]) \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000387 )
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000388
389/**
390 * Put in memory a 24 bits unsigned integer in big-endian order.
391 *
392 * \param n 24 bits unsigned integer to put in memory.
393 * \param data Base address of the memory where to put the 24
394 * bits unsigned integer in.
395 * \param offset Offset from \p data where to put the most significant
396 * byte of the 24 bits unsigned integer \p n.
397 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100398#define MBEDTLS_PUT_UINT24_BE(n, data, offset) \
Dave Rodgman914c6322023-03-01 09:30:14 +0000399 { \
400 (data)[(offset)] = MBEDTLS_BYTE_2(n); \
Gilles Peskine449bd832023-01-11 14:50:10 +0100401 (data)[(offset) + 1] = MBEDTLS_BYTE_1(n); \
402 (data)[(offset) + 2] = MBEDTLS_BYTE_0(n); \
403 }
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000404
405/**
406 * Get the unsigned 24 bits integer corresponding to three bytes in
407 * little-endian order (LSB first).
408 *
409 * \param data Base address of the memory to get the three bytes from.
410 * \param offset Offset from \p data of the first and least significant
411 * byte of the three bytes to build the 24 bits unsigned
412 * integer from.
413 */
Dave Rodgman914c6322023-03-01 09:30:14 +0000414#define MBEDTLS_GET_UINT24_LE(data, offset) \
415 ( \
416 ((uint32_t) (data)[(offset)]) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100417 | ((uint32_t) (data)[(offset) + 1] << 8) \
418 | ((uint32_t) (data)[(offset) + 2] << 16) \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000419 )
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000420
421/**
422 * Put in memory a 24 bits unsigned integer in little-endian order.
423 *
424 * \param n 24 bits unsigned integer to put in memory.
425 * \param data Base address of the memory where to put the 24
426 * bits unsigned integer in.
427 * \param offset Offset from \p data where to put the least significant
428 * byte of the 24 bits unsigned integer \p n.
429 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100430#define MBEDTLS_PUT_UINT24_LE(n, data, offset) \
Dave Rodgman914c6322023-03-01 09:30:14 +0000431 { \
432 (data)[(offset)] = MBEDTLS_BYTE_0(n); \
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 (data)[(offset) + 1] = MBEDTLS_BYTE_1(n); \
434 (data)[(offset) + 2] = MBEDTLS_BYTE_2(n); \
435 }
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000436
437/**
438 * Get the unsigned 64 bits integer corresponding to eight bytes in
439 * big-endian order (MSB first).
440 *
441 * \param data Base address of the memory to get the eight bytes from.
442 * \param offset Offset from \p data of the first and most significant
443 * byte of the eight bytes to build the 64 bits unsigned
444 * integer from.
445 */
Dave Rodgman914c6322023-03-01 09:30:14 +0000446#define MBEDTLS_GET_UINT64_BE(data, offset) \
447 ((MBEDTLS_IS_BIG_ENDIAN) \
Dave Rodgmana5110b02022-11-28 14:48:45 +0000448 ? mbedtls_get_unaligned_uint64((data) + (offset)) \
449 : MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000450 )
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000451
452/**
453 * Put in memory a 64 bits unsigned integer in big-endian order.
454 *
455 * \param n 64 bits unsigned integer to put in memory.
456 * \param data Base address of the memory where to put the 64
457 * bits unsigned integer in.
458 * \param offset Offset from \p data where to put the most significant
459 * byte of the 64 bits unsigned integer \p n.
460 */
Dave Rodgman914c6322023-03-01 09:30:14 +0000461#define MBEDTLS_PUT_UINT64_BE(n, data, offset) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 { \
Dave Rodgman914c6322023-03-01 09:30:14 +0000463 if (MBEDTLS_IS_BIG_ENDIAN) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 { \
Dave Rodgman914c6322023-03-01 09:30:14 +0000465 mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n)); \
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 } \
467 else \
468 { \
469 mbedtls_put_unaligned_uint64((data) + (offset), MBEDTLS_BSWAP64((uint64_t) (n))); \
470 } \
471 }
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000472
473/**
474 * Get the unsigned 64 bits integer corresponding to eight bytes in
475 * little-endian order (LSB first).
476 *
477 * \param data Base address of the memory to get the eight bytes from.
478 * \param offset Offset from \p data of the first and least significant
479 * byte of the eight bytes to build the 64 bits unsigned
480 * integer from.
481 */
Dave Rodgman914c6322023-03-01 09:30:14 +0000482#define MBEDTLS_GET_UINT64_LE(data, offset) \
483 ((MBEDTLS_IS_BIG_ENDIAN) \
Dave Rodgmana5110b02022-11-28 14:48:45 +0000484 ? MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \
485 : mbedtls_get_unaligned_uint64((data) + (offset)) \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000486 )
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000487
488/**
489 * Put in memory a 64 bits unsigned integer in little-endian order.
490 *
491 * \param n 64 bits unsigned integer to put in memory.
492 * \param data Base address of the memory where to put the 64
493 * bits unsigned integer in.
494 * \param offset Offset from \p data where to put the least significant
495 * byte of the 64 bits unsigned integer \p n.
496 */
Dave Rodgman914c6322023-03-01 09:30:14 +0000497#define MBEDTLS_PUT_UINT64_LE(n, data, offset) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100498 { \
Dave Rodgman914c6322023-03-01 09:30:14 +0000499 if (MBEDTLS_IS_BIG_ENDIAN) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100500 { \
501 mbedtls_put_unaligned_uint64((data) + (offset), MBEDTLS_BSWAP64((uint64_t) (n))); \
502 } \
503 else \
504 { \
Dave Rodgman914c6322023-03-01 09:30:14 +0000505 mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n)); \
Gilles Peskine449bd832023-01-11 14:50:10 +0100506 } \
507 }
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000508
509#endif /* MBEDTLS_LIBRARY_ALIGNMENT_H */