blob: 86e78217b47a29840d0002f1752c6276b346eb12 [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
161/*
162 * Where compiler built-ins are not present, fall back to C code that the
163 * compiler may be able to detect and transform into the relevant bswap or
164 * similar instruction.
165 */
166#if !defined(MBEDTLS_BSWAP16)
Dave Rodgman6298b242022-11-28 14:51:49 +0000167static inline uint16_t mbedtls_bswap16( uint16_t x ) {
168 return
169 ( x & 0x00ff ) << 8 |
170 ( x & 0xff00 ) >> 8;
171}
172#define MBEDTLS_BSWAP16 mbedtls_bswap16
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000173#endif /* !defined(MBEDTLS_BSWAP16) */
Dave Rodgman6298b242022-11-28 14:51:49 +0000174
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000175#if !defined(MBEDTLS_BSWAP32)
Dave Rodgman6298b242022-11-28 14:51:49 +0000176static inline uint32_t mbedtls_bswap32( uint32_t x ) {
177 return
178 ( x & 0x000000ff ) << 24 |
179 ( x & 0x0000ff00 ) << 8 |
180 ( x & 0x00ff0000 ) >> 8 |
181 ( x & 0xff000000 ) >> 24;
182}
183#define MBEDTLS_BSWAP32 mbedtls_bswap32
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000184#endif /* !defined(MBEDTLS_BSWAP32) */
Dave Rodgman6298b242022-11-28 14:51:49 +0000185
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000186#if !defined(MBEDTLS_BSWAP64)
Dave Rodgman6298b242022-11-28 14:51:49 +0000187static inline uint64_t mbedtls_bswap64( uint64_t x ) {
188 return
189 ( x & 0x00000000000000ff ) << 56 |
190 ( x & 0x000000000000ff00 ) << 40 |
191 ( x & 0x0000000000ff0000 ) << 24 |
192 ( x & 0x00000000ff000000 ) << 8 |
193 ( x & 0x000000ff00000000 ) >> 8 |
194 ( x & 0x0000ff0000000000 ) >> 24 |
195 ( x & 0x00ff000000000000 ) >> 40 |
196 ( x & 0xff00000000000000 ) >> 56;
197}
198#define MBEDTLS_BSWAP64 mbedtls_bswap64
Dave Rodgmanf7f1f742022-11-28 14:52:45 +0000199#endif /* !defined(MBEDTLS_BSWAP64) */
Dave Rodgman6298b242022-11-28 14:51:49 +0000200
Dave Rodgmane5c42592022-11-28 14:47:46 +0000201#if !defined(__BYTE_ORDER__)
202static const uint16_t mbedtls_byte_order_detector = { 0x100 };
203#define MBEDTLS_IS_BIG_ENDIAN (*((unsigned char *) (&mbedtls_byte_order_detector)) == 0x01)
204#else
205#define MBEDTLS_IS_BIG_ENDIAN ((__BYTE_ORDER__) == (__ORDER_BIG_ENDIAN__))
206#endif /* !defined(__BYTE_ORDER__) */
207
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000208/**
209 * Get the unsigned 32 bits integer corresponding to four bytes in
210 * big-endian order (MSB first).
211 *
212 * \param data Base address of the memory to get the four bytes from.
213 * \param offset Offset from \p data of the first and most significant
214 * byte of the four bytes to build the 32 bits unsigned
215 * integer from.
216 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000217#define MBEDTLS_GET_UINT32_BE( data, offset ) \
218 ( ( MBEDTLS_IS_BIG_ENDIAN ) \
219 ? mbedtls_get_unaligned_uint32((data) + (offset)) \
220 : MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000221 )
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000222
223/**
224 * Put in memory a 32 bits unsigned integer in big-endian order.
225 *
226 * \param n 32 bits unsigned integer to put in memory.
227 * \param data Base address of the memory where to put the 32
228 * bits unsigned integer in.
229 * \param offset Offset from \p data where to put the most significant
230 * byte of the 32 bits unsigned integer \p n.
231 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000232#define MBEDTLS_PUT_UINT32_BE( n, data, offset ) \
233{ \
234 if ( MBEDTLS_IS_BIG_ENDIAN ) \
235 { \
236 mbedtls_put_unaligned_uint32((data) + (offset), (uint32_t)(n)); \
237 } \
238 else \
239 { \
240 mbedtls_put_unaligned_uint32((data) + (offset), MBEDTLS_BSWAP32((uint32_t)(n))); \
241 } \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000242}
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000243
244/**
245 * Get the unsigned 32 bits integer corresponding to four bytes in
246 * little-endian order (LSB first).
247 *
248 * \param data Base address of the memory to get the four bytes from.
249 * \param offset Offset from \p data of the first and least significant
250 * byte of the four bytes to build the 32 bits unsigned
251 * integer from.
252 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000253#define MBEDTLS_GET_UINT32_LE( data, offset ) \
254 ( ( MBEDTLS_IS_BIG_ENDIAN ) \
255 ? MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \
256 : mbedtls_get_unaligned_uint32((data) + (offset)) \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000257 )
Dave Rodgmana5110b02022-11-28 14:48:45 +0000258
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000259
260/**
261 * Put in memory a 32 bits unsigned integer in little-endian order.
262 *
263 * \param n 32 bits unsigned integer to put in memory.
264 * \param data Base address of the memory where to put the 32
265 * bits unsigned integer in.
266 * \param offset Offset from \p data where to put the least significant
267 * byte of the 32 bits unsigned integer \p n.
268 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000269#define MBEDTLS_PUT_UINT32_LE( n, data, offset ) \
270{ \
271 if ( MBEDTLS_IS_BIG_ENDIAN ) \
272 { \
273 mbedtls_put_unaligned_uint32((data) + (offset), MBEDTLS_BSWAP32((uint32_t)(n))); \
274 } \
275 else \
276 { \
277 mbedtls_put_unaligned_uint32((data) + (offset), ((uint32_t)(n))); \
278 } \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000279}
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000280
281/**
282 * Get the unsigned 16 bits integer corresponding to two bytes in
283 * little-endian order (LSB first).
284 *
285 * \param data Base address of the memory to get the two bytes from.
286 * \param offset Offset from \p data of the first and least significant
287 * byte of the two bytes to build the 16 bits unsigned
288 * integer from.
289 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000290#define MBEDTLS_GET_UINT16_LE( data, offset ) \
291 ( ( MBEDTLS_IS_BIG_ENDIAN ) \
292 ? MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \
293 : mbedtls_get_unaligned_uint16((data) + (offset)) \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000294 )
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000295
296/**
297 * Put in memory a 16 bits unsigned integer in little-endian order.
298 *
299 * \param n 16 bits unsigned integer to put in memory.
300 * \param data Base address of the memory where to put the 16
301 * bits unsigned integer in.
302 * \param offset Offset from \p data where to put the least significant
303 * byte of the 16 bits unsigned integer \p n.
304 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000305#define MBEDTLS_PUT_UINT16_LE( n, data, offset ) \
306{ \
307 if ( MBEDTLS_IS_BIG_ENDIAN ) \
308 { \
309 mbedtls_put_unaligned_uint16((data) + (offset), MBEDTLS_BSWAP16((uint16_t)(n))); \
310 } \
311 else \
312 { \
313 mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t)(n)); \
314 } \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000315}
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000316
317/**
318 * Get the unsigned 16 bits integer corresponding to two bytes in
319 * big-endian order (MSB first).
320 *
321 * \param data Base address of the memory to get the two bytes from.
322 * \param offset Offset from \p data of the first and most significant
323 * byte of the two bytes to build the 16 bits unsigned
324 * integer from.
325 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000326#define MBEDTLS_GET_UINT16_BE( data, offset ) \
327 ( ( MBEDTLS_IS_BIG_ENDIAN ) \
328 ? mbedtls_get_unaligned_uint16((data) + (offset)) \
329 : MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000330 )
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000331
332/**
333 * Put in memory a 16 bits unsigned integer in big-endian order.
334 *
335 * \param n 16 bits unsigned integer to put in memory.
336 * \param data Base address of the memory where to put the 16
337 * bits unsigned integer in.
338 * \param offset Offset from \p data where to put the most significant
339 * byte of the 16 bits unsigned integer \p n.
340 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000341#define MBEDTLS_PUT_UINT16_BE( n, data, offset ) \
342{ \
343 if ( MBEDTLS_IS_BIG_ENDIAN ) \
344 { \
345 mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t)(n)); \
346 } \
347 else \
348 { \
349 mbedtls_put_unaligned_uint16((data) + (offset), MBEDTLS_BSWAP16((uint16_t)(n))); \
350 } \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000351}
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000352
353/**
354 * Get the unsigned 24 bits integer corresponding to three bytes in
355 * big-endian order (MSB first).
356 *
357 * \param data Base address of the memory to get the three bytes from.
358 * \param offset Offset from \p data of the first and most significant
359 * byte of the three bytes to build the 24 bits unsigned
360 * integer from.
361 */
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000362#define MBEDTLS_GET_UINT24_BE( data , offset ) \
363 ( \
364 ( (uint32_t) ( data )[( offset ) ] << 16 ) \
365 | ( (uint32_t) ( data )[( offset ) + 1] << 8 ) \
366 | ( (uint32_t) ( data )[( offset ) + 2] ) \
367 )
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000368
369/**
370 * Put in memory a 24 bits unsigned integer in big-endian order.
371 *
372 * \param n 24 bits unsigned integer to put in memory.
373 * \param data Base address of the memory where to put the 24
374 * bits unsigned integer in.
375 * \param offset Offset from \p data where to put the most significant
376 * byte of the 24 bits unsigned integer \p n.
377 */
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000378#define MBEDTLS_PUT_UINT24_BE( n, data, offset ) \
379{ \
380 ( data )[( offset ) ] = MBEDTLS_BYTE_2( n ); \
381 ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n ); \
382 ( data )[( offset ) + 2] = MBEDTLS_BYTE_0( n ); \
383}
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000384
385/**
386 * Get the unsigned 24 bits integer corresponding to three bytes in
387 * little-endian order (LSB first).
388 *
389 * \param data Base address of the memory to get the three bytes from.
390 * \param offset Offset from \p data of the first and least significant
391 * byte of the three bytes to build the 24 bits unsigned
392 * integer from.
393 */
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000394#define MBEDTLS_GET_UINT24_LE( data, offset ) \
395 ( \
396 ( (uint32_t) ( data )[( offset ) ] ) \
397 | ( (uint32_t) ( data )[( offset ) + 1] << 8 ) \
398 | ( (uint32_t) ( data )[( offset ) + 2] << 16 ) \
399 )
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000400
401/**
402 * Put in memory a 24 bits unsigned integer in little-endian order.
403 *
404 * \param n 24 bits unsigned integer to put in memory.
405 * \param data Base address of the memory where to put the 24
406 * bits unsigned integer in.
407 * \param offset Offset from \p data where to put the least significant
408 * byte of the 24 bits unsigned integer \p n.
409 */
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000410#define MBEDTLS_PUT_UINT24_LE( n, data, offset ) \
411{ \
412 ( data )[( offset ) ] = MBEDTLS_BYTE_0( n ); \
413 ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n ); \
414 ( data )[( offset ) + 2] = MBEDTLS_BYTE_2( n ); \
415}
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000416
417/**
418 * Get the unsigned 64 bits integer corresponding to eight bytes in
419 * big-endian order (MSB first).
420 *
421 * \param data Base address of the memory to get the eight bytes from.
422 * \param offset Offset from \p data of the first and most significant
423 * byte of the eight bytes to build the 64 bits unsigned
424 * integer from.
425 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000426#define MBEDTLS_GET_UINT64_BE( data, offset ) \
427 ( ( MBEDTLS_IS_BIG_ENDIAN ) \
428 ? mbedtls_get_unaligned_uint64((data) + (offset)) \
429 : MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000430 )
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000431
432/**
433 * Put in memory a 64 bits unsigned integer in big-endian order.
434 *
435 * \param n 64 bits unsigned integer to put in memory.
436 * \param data Base address of the memory where to put the 64
437 * bits unsigned integer in.
438 * \param offset Offset from \p data where to put the most significant
439 * byte of the 64 bits unsigned integer \p n.
440 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000441#define MBEDTLS_PUT_UINT64_BE( n, data, offset ) \
442{ \
443 if ( MBEDTLS_IS_BIG_ENDIAN ) \
444 { \
445 mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t)(n)); \
446 } \
447 else \
448 { \
449 mbedtls_put_unaligned_uint64((data) + (offset), MBEDTLS_BSWAP64((uint64_t)(n))); \
450 } \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000451}
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000452
453/**
454 * Get the unsigned 64 bits integer corresponding to eight bytes in
455 * little-endian order (LSB first).
456 *
457 * \param data Base address of the memory to get the eight bytes from.
458 * \param offset Offset from \p data of the first and least significant
459 * byte of the eight bytes to build the 64 bits unsigned
460 * integer from.
461 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000462#define MBEDTLS_GET_UINT64_LE( data, offset ) \
463 ( ( MBEDTLS_IS_BIG_ENDIAN ) \
464 ? MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \
465 : mbedtls_get_unaligned_uint64((data) + (offset)) \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000466 )
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000467
468/**
469 * Put in memory a 64 bits unsigned integer in little-endian order.
470 *
471 * \param n 64 bits unsigned integer to put in memory.
472 * \param data Base address of the memory where to put the 64
473 * bits unsigned integer in.
474 * \param offset Offset from \p data where to put the least significant
475 * byte of the 64 bits unsigned integer \p n.
476 */
Dave Rodgmana5110b02022-11-28 14:48:45 +0000477#define MBEDTLS_PUT_UINT64_LE( n, data, offset ) \
478{ \
479 if ( MBEDTLS_IS_BIG_ENDIAN ) \
480 { \
481 mbedtls_put_unaligned_uint64((data) + (offset), MBEDTLS_BSWAP64((uint64_t)(n))); \
482 } \
483 else \
484 { \
485 mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t)(n)); \
486 } \
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000487}
Dave Rodgmanfbc23222022-11-24 18:07:37 +0000488
489#endif /* MBEDTLS_LIBRARY_ALIGNMENT_H */