blob: 3c5fa236056e94a8a87285f00db82e80b42cf4fc [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
8 * SPDX-License-Identifier: Apache-2.0
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License"); you may
11 * not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 */
22
23#ifndef MBEDTLS_LIBRARY_ALIGNMENT_H
24#define MBEDTLS_LIBRARY_ALIGNMENT_H
25
26#include <stdint.h>
Dave Rodgman96d61d12022-11-24 19:33:22 +000027#include <string.h>
Dave Rodgmanf7f1f742022-11-28 14:52:45 +000028#include <stdlib.h>
Dave Rodgmanfbc23222022-11-24 18:07:37 +000029
Dave Rodgmana616afe2022-11-25 17:11:45 +000030#include "mbedtls/build_info.h"
Dave Rodgman8f6583d2022-11-25 09:16:41 +000031
Dave Rodgman96d61d12022-11-24 19:33:22 +000032/**
Dave Rodgmana360e192022-11-28 14:44:05 +000033 * Read the unsigned 16 bits integer from the given address, which need not
34 * be aligned.
35 *
36 * \param p pointer to 2 bytes of data
37 * \return Data at the given address
38 */
39inline uint16_t mbedtls_get_unaligned_uint16( const void *p )
40{
41 uint16_t r;
42 memcpy( &r, p, sizeof( r ) );
43 return r;
44}
45
46/**
47 * Write the unsigned 16 bits integer to the given address, which need not
48 * be aligned.
49 *
50 * \param p pointer to 2 bytes of data
51 * \param x data to write
52 */
53inline void mbedtls_put_unaligned_uint16( void *p, uint16_t x )
54{
55 memcpy( p, &x, sizeof( x ) );
56}
57
58/**
Dave Rodgman96d61d12022-11-24 19:33:22 +000059 * Read the unsigned 32 bits integer from the given address, which need not
60 * be aligned.
Dave Rodgmanfbc23222022-11-24 18:07:37 +000061 *
Dave Rodgman96d61d12022-11-24 19:33:22 +000062 * \param p pointer to 4 bytes of data
Dave Rodgman875d2382022-11-24 20:43:15 +000063 * \return Data at the given address
Dave Rodgmanfbc23222022-11-24 18:07:37 +000064 */
Dave Rodgman7a910a82022-11-24 21:17:40 +000065inline uint32_t mbedtls_get_unaligned_uint32( const void *p )
Dave Rodgman96d61d12022-11-24 19:33:22 +000066{
67 uint32_t r;
Dave Rodgman7a910a82022-11-24 21:17:40 +000068 memcpy( &r, p, sizeof( r ) );
Dave Rodgman96d61d12022-11-24 19:33:22 +000069 return r;
70}
Dave Rodgmanfbc23222022-11-24 18:07:37 +000071
Dave Rodgman96d61d12022-11-24 19:33:22 +000072/**
73 * Write the unsigned 32 bits integer to the given address, which need not
74 * be aligned.
75 *
76 * \param p pointer to 4 bytes of data
77 * \param x data to write
78 */
Dave Rodgman66433442022-11-24 20:07:39 +000079inline void mbedtls_put_unaligned_uint32( void *p, uint32_t x )
Dave Rodgman96d61d12022-11-24 19:33:22 +000080{
Dave Rodgman7a910a82022-11-24 21:17:40 +000081 memcpy( p, &x, sizeof( x ) );
Dave Rodgman96d61d12022-11-24 19:33:22 +000082}
Dave Rodgmanfbc23222022-11-24 18:07:37 +000083
Dave Rodgmana360e192022-11-28 14:44:05 +000084/**
85 * Read the unsigned 64 bits integer from the given address, which need not
86 * be aligned.
87 *
88 * \param p pointer to 8 bytes of data
89 * \return Data at the given address
90 */
91inline uint64_t mbedtls_get_unaligned_uint64( const void *p )
92{
93 uint64_t r;
94 memcpy( &r, p, sizeof( r ) );
95 return r;
96}
97
98/**
99 * Write the unsigned 64 bits integer to the given address, which need not
100 * be aligned.
101 *
102 * \param p pointer to 8 bytes of data
103 * \param x data to write
104 */
105inline void mbedtls_put_unaligned_uint64( void *p, uint64_t x )
106{
107 memcpy( p, &x, sizeof( x ) );
108}
109
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000110/** Byte Reading Macros
111 *
112 * Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th
113 * byte from x, where byte 0 is the least significant byte.
114 */
115#define MBEDTLS_BYTE_0( x ) ( (uint8_t) ( ( x ) & 0xff ) )
116#define MBEDTLS_BYTE_1( x ) ( (uint8_t) ( ( ( x ) >> 8 ) & 0xff ) )
117#define MBEDTLS_BYTE_2( x ) ( (uint8_t) ( ( ( x ) >> 16 ) & 0xff ) )
118#define MBEDTLS_BYTE_3( x ) ( (uint8_t) ( ( ( x ) >> 24 ) & 0xff ) )
119#define MBEDTLS_BYTE_4( x ) ( (uint8_t) ( ( ( x ) >> 32 ) & 0xff ) )
120#define MBEDTLS_BYTE_5( x ) ( (uint8_t) ( ( ( x ) >> 40 ) & 0xff ) )
121#define MBEDTLS_BYTE_6( x ) ( (uint8_t) ( ( ( x ) >> 48 ) & 0xff ) )
122#define MBEDTLS_BYTE_7( x ) ( (uint8_t) ( ( ( x ) >> 56 ) & 0xff ) )
123
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000124/*
125 * Detect GCC built-in byteswap routines
126 */
127#if defined(__GNUC__) && defined(__GNUC_PREREQ)
128#if __GNUC_PREREQ(4,8)
129#define MBEDTLS_BSWAP16 __builtin_bswap16
130#endif /* __GNUC_PREREQ(4,8) */
131#if __GNUC_PREREQ(4,3)
132#define MBEDTLS_BSWAP32 __builtin_bswap32
133#define MBEDTLS_BSWAP64 __builtin_bswap64
134#endif /* __GNUC_PREREQ(4,3) */
135#endif /* defined(__GNUC__) && defined(__GNUC_PREREQ) */
136
137/*
138 * Detect Clang built-in byteswap routines
139 */
140#if defined(__clang__) && defined(__has_builtin)
141#if __has_builtin(__builtin_bswap16)
142#define MBEDTLS_BSWAP16 __builtin_bswap16
143#endif /* __has_builtin(__builtin_bswap16) */
144#if __has_builtin(__builtin_bswap32)
145#define MBEDTLS_BSWAP32 __builtin_bswap32
146#endif /* __has_builtin(__builtin_bswap32) */
147#if __has_builtin(__builtin_bswap64)
148#define MBEDTLS_BSWAP64 __builtin_bswap64
149#endif /* __has_builtin(__builtin_bswap64) */
150#endif /* defined(__clang__) && defined(__has_builtin) */
151
152/*
153 * Detect MSVC built-in byteswap routines
154 */
155#if defined(_MSC_VER)
156#define MBEDTLS_BSWAP16 _byteswap_ushort
157#define MBEDTLS_BSWAP32 _byteswap_ulong
158#define MBEDTLS_BSWAP64 _byteswap_uint64
159#endif /* defined(_MSC_VER) */
160
Dave Rodgman2dae4b32022-11-30 12:07:36 +0000161/* Detect armcc built-in byteswap routine */
162#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 410000)
163#define MBEDTLS_BSWAP32 __rev
164#endif
165
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000166/*
167 * Where compiler built-ins are not present, fall back to C code that the
168 * compiler may be able to detect and transform into the relevant bswap or
169 * similar instruction.
170 */
171#if !defined(MBEDTLS_BSWAP16)
Dave Rodgman6298b242022-11-28 14:51:49 +0000172static inline uint16_t mbedtls_bswap16( uint16_t x ) {
173 return
174 ( x & 0x00ff ) << 8 |
175 ( x & 0xff00 ) >> 8;
176}
177#define MBEDTLS_BSWAP16 mbedtls_bswap16
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000178#endif /* !defined(MBEDTLS_BSWAP16) */
Dave Rodgman6298b242022-11-28 14:51:49 +0000179
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000180#if !defined(MBEDTLS_BSWAP32)
Dave Rodgman6298b242022-11-28 14:51:49 +0000181static inline uint32_t mbedtls_bswap32( uint32_t x ) {
182 return
183 ( x & 0x000000ff ) << 24 |
184 ( x & 0x0000ff00 ) << 8 |
185 ( x & 0x00ff0000 ) >> 8 |
186 ( x & 0xff000000 ) >> 24;
187}
188#define MBEDTLS_BSWAP32 mbedtls_bswap32
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000189#endif /* !defined(MBEDTLS_BSWAP32) */
Dave Rodgman6298b242022-11-28 14:51:49 +0000190
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000191#if !defined(MBEDTLS_BSWAP64)
Dave Rodgman6298b242022-11-28 14:51:49 +0000192static inline uint64_t mbedtls_bswap64( uint64_t x ) {
193 return
194 ( x & 0x00000000000000ff ) << 56 |
195 ( x & 0x000000000000ff00 ) << 40 |
196 ( x & 0x0000000000ff0000 ) << 24 |
197 ( x & 0x00000000ff000000 ) << 8 |
198 ( x & 0x000000ff00000000 ) >> 8 |
199 ( x & 0x0000ff0000000000 ) >> 24 |
200 ( x & 0x00ff000000000000 ) >> 40 |
201 ( x & 0xff00000000000000 ) >> 56;
202}
203#define MBEDTLS_BSWAP64 mbedtls_bswap64
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000204#endif /* !defined(MBEDTLS_BSWAP64) */
Dave Rodgman6298b242022-11-28 14:51:49 +0000205
Dave Rodgmane5c42592022-11-28 14:47:46 +0000206#if !defined(__BYTE_ORDER__)
207static const uint16_t mbedtls_byte_order_detector = { 0x100 };
208#define MBEDTLS_IS_BIG_ENDIAN (*((unsigned char *) (&mbedtls_byte_order_detector)) == 0x01)
209#else
210#define MBEDTLS_IS_BIG_ENDIAN ((__BYTE_ORDER__) == (__ORDER_BIG_ENDIAN__))
211#endif /* !defined(__BYTE_ORDER__) */
212
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000213/**
214 * Get the unsigned 32 bits integer corresponding to four bytes in
215 * big-endian order (MSB first).
216 *
217 * \param data Base address of the memory to get the four bytes from.
218 * \param offset Offset from \p data of the first and most significant
219 * byte of the four bytes to build the 32 bits unsigned
220 * integer from.
221 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000222#define MBEDTLS_GET_UINT32_BE( data, offset ) \
223 ( ( MBEDTLS_IS_BIG_ENDIAN ) \
224 ? mbedtls_get_unaligned_uint32((data) + (offset)) \
225 : MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000226 )
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000227
228/**
229 * Put in memory a 32 bits unsigned integer in big-endian order.
230 *
231 * \param n 32 bits unsigned integer to put in memory.
232 * \param data Base address of the memory where to put the 32
233 * bits unsigned integer in.
234 * \param offset Offset from \p data where to put the most significant
235 * byte of the 32 bits unsigned integer \p n.
236 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000237#define MBEDTLS_PUT_UINT32_BE( n, data, offset ) \
238{ \
239 if ( MBEDTLS_IS_BIG_ENDIAN ) \
240 { \
241 mbedtls_put_unaligned_uint32((data) + (offset), (uint32_t)(n)); \
242 } \
243 else \
244 { \
245 mbedtls_put_unaligned_uint32((data) + (offset), MBEDTLS_BSWAP32((uint32_t)(n))); \
246 } \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000247}
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000248
249/**
250 * Get the unsigned 32 bits integer corresponding to four bytes in
251 * little-endian order (LSB first).
252 *
253 * \param data Base address of the memory to get the four bytes from.
254 * \param offset Offset from \p data of the first and least significant
255 * byte of the four bytes to build the 32 bits unsigned
256 * integer from.
257 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000258#define MBEDTLS_GET_UINT32_LE( data, offset ) \
259 ( ( MBEDTLS_IS_BIG_ENDIAN ) \
260 ? MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \
261 : mbedtls_get_unaligned_uint32((data) + (offset)) \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000262 )
Dave Rodgmana5110b02022-11-28 14:48:45 +0000263
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000264
265/**
266 * Put in memory a 32 bits unsigned integer in little-endian order.
267 *
268 * \param n 32 bits unsigned integer to put in memory.
269 * \param data Base address of the memory where to put the 32
270 * bits unsigned integer in.
271 * \param offset Offset from \p data where to put the least significant
272 * byte of the 32 bits unsigned integer \p n.
273 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000274#define MBEDTLS_PUT_UINT32_LE( n, data, offset ) \
275{ \
276 if ( MBEDTLS_IS_BIG_ENDIAN ) \
277 { \
278 mbedtls_put_unaligned_uint32((data) + (offset), MBEDTLS_BSWAP32((uint32_t)(n))); \
279 } \
280 else \
281 { \
282 mbedtls_put_unaligned_uint32((data) + (offset), ((uint32_t)(n))); \
283 } \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000284}
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000285
286/**
287 * Get the unsigned 16 bits integer corresponding to two bytes in
288 * little-endian order (LSB first).
289 *
290 * \param data Base address of the memory to get the two bytes from.
291 * \param offset Offset from \p data of the first and least significant
292 * byte of the two bytes to build the 16 bits unsigned
293 * integer from.
294 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000295#define MBEDTLS_GET_UINT16_LE( data, offset ) \
296 ( ( MBEDTLS_IS_BIG_ENDIAN ) \
297 ? MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \
298 : mbedtls_get_unaligned_uint16((data) + (offset)) \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000299 )
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000300
301/**
302 * Put in memory a 16 bits unsigned integer in little-endian order.
303 *
304 * \param n 16 bits unsigned integer to put in memory.
305 * \param data Base address of the memory where to put the 16
306 * bits unsigned integer in.
307 * \param offset Offset from \p data where to put the least significant
308 * byte of the 16 bits unsigned integer \p n.
309 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000310#define MBEDTLS_PUT_UINT16_LE( n, data, offset ) \
311{ \
312 if ( MBEDTLS_IS_BIG_ENDIAN ) \
313 { \
314 mbedtls_put_unaligned_uint16((data) + (offset), MBEDTLS_BSWAP16((uint16_t)(n))); \
315 } \
316 else \
317 { \
318 mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t)(n)); \
319 } \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000320}
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000321
322/**
323 * Get the unsigned 16 bits integer corresponding to two bytes in
324 * big-endian order (MSB first).
325 *
326 * \param data Base address of the memory to get the two bytes from.
327 * \param offset Offset from \p data of the first and most significant
328 * byte of the two bytes to build the 16 bits unsigned
329 * integer from.
330 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000331#define MBEDTLS_GET_UINT16_BE( data, offset ) \
332 ( ( MBEDTLS_IS_BIG_ENDIAN ) \
333 ? mbedtls_get_unaligned_uint16((data) + (offset)) \
334 : MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000335 )
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000336
337/**
338 * Put in memory a 16 bits unsigned integer in big-endian order.
339 *
340 * \param n 16 bits unsigned integer to put in memory.
341 * \param data Base address of the memory where to put the 16
342 * bits unsigned integer in.
343 * \param offset Offset from \p data where to put the most significant
344 * byte of the 16 bits unsigned integer \p n.
345 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000346#define MBEDTLS_PUT_UINT16_BE( n, data, offset ) \
347{ \
348 if ( MBEDTLS_IS_BIG_ENDIAN ) \
349 { \
350 mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t)(n)); \
351 } \
352 else \
353 { \
354 mbedtls_put_unaligned_uint16((data) + (offset), MBEDTLS_BSWAP16((uint16_t)(n))); \
355 } \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000356}
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000357
358/**
359 * Get the unsigned 24 bits integer corresponding to three bytes in
360 * big-endian order (MSB first).
361 *
362 * \param data Base address of the memory to get the three bytes from.
363 * \param offset Offset from \p data of the first and most significant
364 * byte of the three bytes to build the 24 bits unsigned
365 * integer from.
366 */
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000367#define MBEDTLS_GET_UINT24_BE( data , offset ) \
368 ( \
369 ( (uint32_t) ( data )[( offset ) ] << 16 ) \
370 | ( (uint32_t) ( data )[( offset ) + 1] << 8 ) \
371 | ( (uint32_t) ( data )[( offset ) + 2] ) \
372 )
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000373
374/**
375 * Put in memory a 24 bits unsigned integer in big-endian order.
376 *
377 * \param n 24 bits unsigned integer to put in memory.
378 * \param data Base address of the memory where to put the 24
379 * bits unsigned integer in.
380 * \param offset Offset from \p data where to put the most significant
381 * byte of the 24 bits unsigned integer \p n.
382 */
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000383#define MBEDTLS_PUT_UINT24_BE( n, data, offset ) \
384{ \
385 ( data )[( offset ) ] = MBEDTLS_BYTE_2( n ); \
386 ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n ); \
387 ( data )[( offset ) + 2] = MBEDTLS_BYTE_0( n ); \
388}
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000389
390/**
391 * Get the unsigned 24 bits integer corresponding to three bytes in
392 * little-endian order (LSB first).
393 *
394 * \param data Base address of the memory to get the three bytes from.
395 * \param offset Offset from \p data of the first and least significant
396 * byte of the three bytes to build the 24 bits unsigned
397 * integer from.
398 */
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000399#define MBEDTLS_GET_UINT24_LE( data, offset ) \
400 ( \
401 ( (uint32_t) ( data )[( offset ) ] ) \
402 | ( (uint32_t) ( data )[( offset ) + 1] << 8 ) \
403 | ( (uint32_t) ( data )[( offset ) + 2] << 16 ) \
404 )
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000405
406/**
407 * Put in memory a 24 bits unsigned integer in little-endian order.
408 *
409 * \param n 24 bits unsigned integer to put in memory.
410 * \param data Base address of the memory where to put the 24
411 * bits unsigned integer in.
412 * \param offset Offset from \p data where to put the least significant
413 * byte of the 24 bits unsigned integer \p n.
414 */
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000415#define MBEDTLS_PUT_UINT24_LE( n, data, offset ) \
416{ \
417 ( data )[( offset ) ] = MBEDTLS_BYTE_0( n ); \
418 ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n ); \
419 ( data )[( offset ) + 2] = MBEDTLS_BYTE_2( n ); \
420}
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000421
422/**
423 * Get the unsigned 64 bits integer corresponding to eight bytes in
424 * big-endian order (MSB first).
425 *
426 * \param data Base address of the memory to get the eight bytes from.
427 * \param offset Offset from \p data of the first and most significant
428 * byte of the eight bytes to build the 64 bits unsigned
429 * integer from.
430 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000431#define MBEDTLS_GET_UINT64_BE( data, offset ) \
432 ( ( MBEDTLS_IS_BIG_ENDIAN ) \
433 ? mbedtls_get_unaligned_uint64((data) + (offset)) \
434 : MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000435 )
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000436
437/**
438 * Put in memory a 64 bits unsigned integer in big-endian order.
439 *
440 * \param n 64 bits unsigned integer to put in memory.
441 * \param data Base address of the memory where to put the 64
442 * bits unsigned integer in.
443 * \param offset Offset from \p data where to put the most significant
444 * byte of the 64 bits unsigned integer \p n.
445 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000446#define MBEDTLS_PUT_UINT64_BE( n, data, offset ) \
447{ \
448 if ( MBEDTLS_IS_BIG_ENDIAN ) \
449 { \
450 mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t)(n)); \
451 } \
452 else \
453 { \
454 mbedtls_put_unaligned_uint64((data) + (offset), MBEDTLS_BSWAP64((uint64_t)(n))); \
455 } \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000456}
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000457
458/**
459 * Get the unsigned 64 bits integer corresponding to eight bytes in
460 * little-endian order (LSB first).
461 *
462 * \param data Base address of the memory to get the eight bytes from.
463 * \param offset Offset from \p data of the first and least significant
464 * byte of the eight bytes to build the 64 bits unsigned
465 * integer from.
466 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000467#define MBEDTLS_GET_UINT64_LE( data, offset ) \
468 ( ( MBEDTLS_IS_BIG_ENDIAN ) \
469 ? MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \
470 : mbedtls_get_unaligned_uint64((data) + (offset)) \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000471 )
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000472
473/**
474 * Put in memory a 64 bits unsigned integer in little-endian order.
475 *
476 * \param n 64 bits unsigned integer to put in memory.
477 * \param data Base address of the memory where to put the 64
478 * bits unsigned integer in.
479 * \param offset Offset from \p data where to put the least significant
480 * byte of the 64 bits unsigned integer \p n.
481 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000482#define MBEDTLS_PUT_UINT64_LE( n, data, offset ) \
483{ \
484 if ( MBEDTLS_IS_BIG_ENDIAN ) \
485 { \
486 mbedtls_put_unaligned_uint64((data) + (offset), MBEDTLS_BSWAP64((uint64_t)(n))); \
487 } \
488 else \
489 { \
490 mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t)(n)); \
491 } \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000492}
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000493
494#endif /* MBEDTLS_LIBRARY_ALIGNMENT_H */