Path: blob/master/thirdparty/mbedtls/library/alignment.h
9898 views
/**1* \file alignment.h2*3* \brief Utility code for dealing with unaligned memory accesses4*/5/*6* Copyright The Mbed TLS Contributors7* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later8*/910#ifndef MBEDTLS_LIBRARY_ALIGNMENT_H11#define MBEDTLS_LIBRARY_ALIGNMENT_H1213#include <stdint.h>14#include <string.h>15#include <stdlib.h>1617/*18* Define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS for architectures where unaligned memory19* accesses are known to be efficient.20*21* All functions defined here will behave correctly regardless, but might be less22* efficient when this is not defined.23*/24#if defined(__ARM_FEATURE_UNALIGNED) \25|| defined(MBEDTLS_ARCH_IS_X86) || defined(MBEDTLS_ARCH_IS_X64) \26|| defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)27/*28* __ARM_FEATURE_UNALIGNED is defined where appropriate by armcc, gcc 7, clang 929* (and later versions) for Arm v7 and later; all x86 platforms should have30* efficient unaligned access.31*32* https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#alignment33* specifies that on Windows-on-Arm64, unaligned access is safe (except for uncached34* device memory).35*/36#define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS37#endif3839#if defined(__IAR_SYSTEMS_ICC__) && \40(defined(MBEDTLS_ARCH_IS_ARM64) || defined(MBEDTLS_ARCH_IS_ARM32) \41|| defined(__ICCRX__) || defined(__ICCRL78__) || defined(__ICCRISCV__))42#pragma language=save43#pragma language=extended44#define MBEDTLS_POP_IAR_LANGUAGE_PRAGMA45/* IAR recommend this technique for accessing unaligned data in46* https://www.iar.com/knowledge/support/technical-notes/compiler/accessing-unaligned-data47* This results in a single load / store instruction (if unaligned access is supported).48* According to that document, this is only supported on certain architectures.49*/50#define UINT_UNALIGNED51typedef uint16_t __packed mbedtls_uint16_unaligned_t;52typedef uint32_t __packed mbedtls_uint32_unaligned_t;53typedef uint64_t __packed mbedtls_uint64_unaligned_t;54#elif defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 40504) && \55((MBEDTLS_GCC_VERSION < 60300) || (!defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)))56/*57* gcc may generate a branch to memcpy for calls like `memcpy(dest, src, 4)` rather than58* generating some LDR or LDRB instructions (similar for stores).59*60* This is architecture dependent: x86-64 seems fine even with old gcc; 32-bit Arm61* is affected. To keep it simple, we enable for all architectures.62*63* For versions of gcc < 5.4.0 this issue always happens.64* For gcc < 6.3.0, this issue happens at -O065* For all versions, this issue happens iff unaligned access is not supported.66*67* For gcc 4.x, this implementation will generate byte-by-byte loads even if unaligned access is68* supported, which is correct but not optimal.69*70* For performance (and code size, in some cases), we want to avoid the branch and just generate71* some inline load/store instructions since the access is small and constant-size.72*73* The manual states:74* "The packed attribute specifies that a variable or structure field should have the smallest75* possible alignment—one byte for a variable"76* https://gcc.gnu.org/onlinedocs/gcc-4.5.4/gcc/Variable-Attributes.html77*78* Previous implementations used __attribute__((__aligned__(1)), but had issues with a gcc bug:79* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=9466280*81* Tested with several versions of GCC from 4.5.0 up to 13.2.082* We don't enable for older than 4.5.0 as this has not been tested.83*/84#define UINT_UNALIGNED_STRUCT85typedef struct {86uint16_t x;87} __attribute__((packed)) mbedtls_uint16_unaligned_t;88typedef struct {89uint32_t x;90} __attribute__((packed)) mbedtls_uint32_unaligned_t;91typedef struct {92uint64_t x;93} __attribute__((packed)) mbedtls_uint64_unaligned_t;94#endif9596/*97* We try to force mbedtls_(get|put)_unaligned_uintXX to be always inline, because this results98* in code that is both smaller and faster. IAR and gcc both benefit from this when optimising99* for size.100*/101102/**103* Read the unsigned 16 bits integer from the given address, which need not104* be aligned.105*106* \param p pointer to 2 bytes of data107* \return Data at the given address108*/109#if defined(__IAR_SYSTEMS_ICC__)110#pragma inline = forced111#elif defined(__GNUC__)112__attribute__((always_inline))113#endif114static inline uint16_t mbedtls_get_unaligned_uint16(const void *p)115{116uint16_t r;117#if defined(UINT_UNALIGNED)118mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;119r = *p16;120#elif defined(UINT_UNALIGNED_STRUCT)121mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;122r = p16->x;123#else124memcpy(&r, p, sizeof(r));125#endif126return r;127}128129/**130* Write the unsigned 16 bits integer to the given address, which need not131* be aligned.132*133* \param p pointer to 2 bytes of data134* \param x data to write135*/136#if defined(__IAR_SYSTEMS_ICC__)137#pragma inline = forced138#elif defined(__GNUC__)139__attribute__((always_inline))140#endif141static inline void mbedtls_put_unaligned_uint16(void *p, uint16_t x)142{143#if defined(UINT_UNALIGNED)144mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;145*p16 = x;146#elif defined(UINT_UNALIGNED_STRUCT)147mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;148p16->x = x;149#else150memcpy(p, &x, sizeof(x));151#endif152}153154/**155* Read the unsigned 32 bits integer from the given address, which need not156* be aligned.157*158* \param p pointer to 4 bytes of data159* \return Data at the given address160*/161#if defined(__IAR_SYSTEMS_ICC__)162#pragma inline = forced163#elif defined(__GNUC__)164__attribute__((always_inline))165#endif166static inline uint32_t mbedtls_get_unaligned_uint32(const void *p)167{168uint32_t r;169#if defined(UINT_UNALIGNED)170mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;171r = *p32;172#elif defined(UINT_UNALIGNED_STRUCT)173mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;174r = p32->x;175#else176memcpy(&r, p, sizeof(r));177#endif178return r;179}180181/**182* Write the unsigned 32 bits integer to the given address, which need not183* be aligned.184*185* \param p pointer to 4 bytes of data186* \param x data to write187*/188#if defined(__IAR_SYSTEMS_ICC__)189#pragma inline = forced190#elif defined(__GNUC__)191__attribute__((always_inline))192#endif193static inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x)194{195#if defined(UINT_UNALIGNED)196mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;197*p32 = x;198#elif defined(UINT_UNALIGNED_STRUCT)199mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;200p32->x = x;201#else202memcpy(p, &x, sizeof(x));203#endif204}205206/**207* Read the unsigned 64 bits integer from the given address, which need not208* be aligned.209*210* \param p pointer to 8 bytes of data211* \return Data at the given address212*/213#if defined(__IAR_SYSTEMS_ICC__)214#pragma inline = forced215#elif defined(__GNUC__)216__attribute__((always_inline))217#endif218static inline uint64_t mbedtls_get_unaligned_uint64(const void *p)219{220uint64_t r;221#if defined(UINT_UNALIGNED)222mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;223r = *p64;224#elif defined(UINT_UNALIGNED_STRUCT)225mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;226r = p64->x;227#else228memcpy(&r, p, sizeof(r));229#endif230return r;231}232233/**234* Write the unsigned 64 bits integer to the given address, which need not235* be aligned.236*237* \param p pointer to 8 bytes of data238* \param x data to write239*/240#if defined(__IAR_SYSTEMS_ICC__)241#pragma inline = forced242#elif defined(__GNUC__)243__attribute__((always_inline))244#endif245static inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x)246{247#if defined(UINT_UNALIGNED)248mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;249*p64 = x;250#elif defined(UINT_UNALIGNED_STRUCT)251mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;252p64->x = x;253#else254memcpy(p, &x, sizeof(x));255#endif256}257258#if defined(MBEDTLS_POP_IAR_LANGUAGE_PRAGMA)259#pragma language=restore260#endif261262/** Byte Reading Macros263*264* Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th265* byte from x, where byte 0 is the least significant byte.266*/267#define MBEDTLS_BYTE_0(x) ((uint8_t) ((x) & 0xff))268#define MBEDTLS_BYTE_1(x) ((uint8_t) (((x) >> 8) & 0xff))269#define MBEDTLS_BYTE_2(x) ((uint8_t) (((x) >> 16) & 0xff))270#define MBEDTLS_BYTE_3(x) ((uint8_t) (((x) >> 24) & 0xff))271#define MBEDTLS_BYTE_4(x) ((uint8_t) (((x) >> 32) & 0xff))272#define MBEDTLS_BYTE_5(x) ((uint8_t) (((x) >> 40) & 0xff))273#define MBEDTLS_BYTE_6(x) ((uint8_t) (((x) >> 48) & 0xff))274#define MBEDTLS_BYTE_7(x) ((uint8_t) (((x) >> 56) & 0xff))275276/*277* Detect GCC built-in byteswap routines278*/279#if defined(__GNUC__) && defined(__GNUC_PREREQ)280#if __GNUC_PREREQ(4, 8)281#define MBEDTLS_BSWAP16 __builtin_bswap16282#endif /* __GNUC_PREREQ(4,8) */283#if __GNUC_PREREQ(4, 3)284#define MBEDTLS_BSWAP32 __builtin_bswap32285#define MBEDTLS_BSWAP64 __builtin_bswap64286#endif /* __GNUC_PREREQ(4,3) */287#endif /* defined(__GNUC__) && defined(__GNUC_PREREQ) */288289/*290* Detect Clang built-in byteswap routines291*/292#if defined(__clang__) && defined(__has_builtin)293#if __has_builtin(__builtin_bswap16) && !defined(MBEDTLS_BSWAP16)294#define MBEDTLS_BSWAP16 __builtin_bswap16295#endif /* __has_builtin(__builtin_bswap16) */296#if __has_builtin(__builtin_bswap32) && !defined(MBEDTLS_BSWAP32)297#define MBEDTLS_BSWAP32 __builtin_bswap32298#endif /* __has_builtin(__builtin_bswap32) */299#if __has_builtin(__builtin_bswap64) && !defined(MBEDTLS_BSWAP64)300#define MBEDTLS_BSWAP64 __builtin_bswap64301#endif /* __has_builtin(__builtin_bswap64) */302#endif /* defined(__clang__) && defined(__has_builtin) */303304/*305* Detect MSVC built-in byteswap routines306*/307#if defined(_MSC_VER)308#if !defined(MBEDTLS_BSWAP16)309#define MBEDTLS_BSWAP16 _byteswap_ushort310#endif311#if !defined(MBEDTLS_BSWAP32)312#define MBEDTLS_BSWAP32 _byteswap_ulong313#endif314#if !defined(MBEDTLS_BSWAP64)315#define MBEDTLS_BSWAP64 _byteswap_uint64316#endif317#endif /* defined(_MSC_VER) */318319/* Detect armcc built-in byteswap routine */320#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 410000) && !defined(MBEDTLS_BSWAP32)321#if defined(__ARM_ACLE) /* ARM Compiler 6 - earlier versions don't need a header */322#include <arm_acle.h>323#endif324#define MBEDTLS_BSWAP32 __rev325#endif326327/* Detect IAR built-in byteswap routine */328#if defined(__IAR_SYSTEMS_ICC__)329#if defined(__ARM_ACLE)330#include <arm_acle.h>331#define MBEDTLS_BSWAP16(x) ((uint16_t) __rev16((uint32_t) (x)))332#define MBEDTLS_BSWAP32 __rev333#define MBEDTLS_BSWAP64 __revll334#endif335#endif336337/*338* Where compiler built-ins are not present, fall back to C code that the339* compiler may be able to detect and transform into the relevant bswap or340* similar instruction.341*/342#if !defined(MBEDTLS_BSWAP16)343static inline uint16_t mbedtls_bswap16(uint16_t x)344{345return346(x & 0x00ff) << 8 |347(x & 0xff00) >> 8;348}349#define MBEDTLS_BSWAP16 mbedtls_bswap16350#endif /* !defined(MBEDTLS_BSWAP16) */351352#if !defined(MBEDTLS_BSWAP32)353static inline uint32_t mbedtls_bswap32(uint32_t x)354{355return356(x & 0x000000ff) << 24 |357(x & 0x0000ff00) << 8 |358(x & 0x00ff0000) >> 8 |359(x & 0xff000000) >> 24;360}361#define MBEDTLS_BSWAP32 mbedtls_bswap32362#endif /* !defined(MBEDTLS_BSWAP32) */363364#if !defined(MBEDTLS_BSWAP64)365static inline uint64_t mbedtls_bswap64(uint64_t x)366{367return368(x & 0x00000000000000ffULL) << 56 |369(x & 0x000000000000ff00ULL) << 40 |370(x & 0x0000000000ff0000ULL) << 24 |371(x & 0x00000000ff000000ULL) << 8 |372(x & 0x000000ff00000000ULL) >> 8 |373(x & 0x0000ff0000000000ULL) >> 24 |374(x & 0x00ff000000000000ULL) >> 40 |375(x & 0xff00000000000000ULL) >> 56;376}377#define MBEDTLS_BSWAP64 mbedtls_bswap64378#endif /* !defined(MBEDTLS_BSWAP64) */379380#if !defined(__BYTE_ORDER__)381382#if defined(__LITTLE_ENDIAN__)383/* IAR defines __xxx_ENDIAN__, but not __BYTE_ORDER__ */384#define MBEDTLS_IS_BIG_ENDIAN 0385#elif defined(__BIG_ENDIAN__)386#define MBEDTLS_IS_BIG_ENDIAN 1387#else388static const uint16_t mbedtls_byte_order_detector = { 0x100 };389#define MBEDTLS_IS_BIG_ENDIAN (*((unsigned char *) (&mbedtls_byte_order_detector)) == 0x01)390#endif391392#else393394#if (__BYTE_ORDER__) == (__ORDER_BIG_ENDIAN__)395#define MBEDTLS_IS_BIG_ENDIAN 1396#else397#define MBEDTLS_IS_BIG_ENDIAN 0398#endif399400#endif /* !defined(__BYTE_ORDER__) */401402/**403* Get the unsigned 32 bits integer corresponding to four bytes in404* big-endian order (MSB first).405*406* \param data Base address of the memory to get the four bytes from.407* \param offset Offset from \p data of the first and most significant408* byte of the four bytes to build the 32 bits unsigned409* integer from.410*/411#define MBEDTLS_GET_UINT32_BE(data, offset) \412((MBEDTLS_IS_BIG_ENDIAN) \413? mbedtls_get_unaligned_uint32((data) + (offset)) \414: MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \415)416417/**418* Put in memory a 32 bits unsigned integer in big-endian order.419*420* \param n 32 bits unsigned integer to put in memory.421* \param data Base address of the memory where to put the 32422* bits unsigned integer in.423* \param offset Offset from \p data where to put the most significant424* byte of the 32 bits unsigned integer \p n.425*/426#define MBEDTLS_PUT_UINT32_BE(n, data, offset) \427{ \428if (MBEDTLS_IS_BIG_ENDIAN) \429{ \430mbedtls_put_unaligned_uint32((data) + (offset), (uint32_t) (n)); \431} \432else \433{ \434mbedtls_put_unaligned_uint32((data) + (offset), MBEDTLS_BSWAP32((uint32_t) (n))); \435} \436}437438/**439* Get the unsigned 32 bits integer corresponding to four bytes in440* little-endian order (LSB first).441*442* \param data Base address of the memory to get the four bytes from.443* \param offset Offset from \p data of the first and least significant444* byte of the four bytes to build the 32 bits unsigned445* integer from.446*/447#define MBEDTLS_GET_UINT32_LE(data, offset) \448((MBEDTLS_IS_BIG_ENDIAN) \449? MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \450: mbedtls_get_unaligned_uint32((data) + (offset)) \451)452453454/**455* Put in memory a 32 bits unsigned integer in little-endian order.456*457* \param n 32 bits unsigned integer to put in memory.458* \param data Base address of the memory where to put the 32459* bits unsigned integer in.460* \param offset Offset from \p data where to put the least significant461* byte of the 32 bits unsigned integer \p n.462*/463#define MBEDTLS_PUT_UINT32_LE(n, data, offset) \464{ \465if (MBEDTLS_IS_BIG_ENDIAN) \466{ \467mbedtls_put_unaligned_uint32((data) + (offset), MBEDTLS_BSWAP32((uint32_t) (n))); \468} \469else \470{ \471mbedtls_put_unaligned_uint32((data) + (offset), ((uint32_t) (n))); \472} \473}474475/**476* Get the unsigned 16 bits integer corresponding to two bytes in477* little-endian order (LSB first).478*479* \param data Base address of the memory to get the two bytes from.480* \param offset Offset from \p data of the first and least significant481* byte of the two bytes to build the 16 bits unsigned482* integer from.483*/484#define MBEDTLS_GET_UINT16_LE(data, offset) \485((MBEDTLS_IS_BIG_ENDIAN) \486? MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \487: mbedtls_get_unaligned_uint16((data) + (offset)) \488)489490/**491* Put in memory a 16 bits unsigned integer in little-endian order.492*493* \param n 16 bits unsigned integer to put in memory.494* \param data Base address of the memory where to put the 16495* bits unsigned integer in.496* \param offset Offset from \p data where to put the least significant497* byte of the 16 bits unsigned integer \p n.498*/499#define MBEDTLS_PUT_UINT16_LE(n, data, offset) \500{ \501if (MBEDTLS_IS_BIG_ENDIAN) \502{ \503mbedtls_put_unaligned_uint16((data) + (offset), MBEDTLS_BSWAP16((uint16_t) (n))); \504} \505else \506{ \507mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n)); \508} \509}510511/**512* Get the unsigned 16 bits integer corresponding to two bytes in513* big-endian order (MSB first).514*515* \param data Base address of the memory to get the two bytes from.516* \param offset Offset from \p data of the first and most significant517* byte of the two bytes to build the 16 bits unsigned518* integer from.519*/520#define MBEDTLS_GET_UINT16_BE(data, offset) \521((MBEDTLS_IS_BIG_ENDIAN) \522? mbedtls_get_unaligned_uint16((data) + (offset)) \523: MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \524)525526/**527* Put in memory a 16 bits unsigned integer in big-endian order.528*529* \param n 16 bits unsigned integer to put in memory.530* \param data Base address of the memory where to put the 16531* bits unsigned integer in.532* \param offset Offset from \p data where to put the most significant533* byte of the 16 bits unsigned integer \p n.534*/535#define MBEDTLS_PUT_UINT16_BE(n, data, offset) \536{ \537if (MBEDTLS_IS_BIG_ENDIAN) \538{ \539mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n)); \540} \541else \542{ \543mbedtls_put_unaligned_uint16((data) + (offset), MBEDTLS_BSWAP16((uint16_t) (n))); \544} \545}546547/**548* Get the unsigned 24 bits integer corresponding to three bytes in549* big-endian order (MSB first).550*551* \param data Base address of the memory to get the three bytes from.552* \param offset Offset from \p data of the first and most significant553* byte of the three bytes to build the 24 bits unsigned554* integer from.555*/556#define MBEDTLS_GET_UINT24_BE(data, offset) \557( \558((uint32_t) (data)[(offset)] << 16) \559| ((uint32_t) (data)[(offset) + 1] << 8) \560| ((uint32_t) (data)[(offset) + 2]) \561)562563/**564* Put in memory a 24 bits unsigned integer in big-endian order.565*566* \param n 24 bits unsigned integer to put in memory.567* \param data Base address of the memory where to put the 24568* bits unsigned integer in.569* \param offset Offset from \p data where to put the most significant570* byte of the 24 bits unsigned integer \p n.571*/572#define MBEDTLS_PUT_UINT24_BE(n, data, offset) \573{ \574(data)[(offset)] = MBEDTLS_BYTE_2(n); \575(data)[(offset) + 1] = MBEDTLS_BYTE_1(n); \576(data)[(offset) + 2] = MBEDTLS_BYTE_0(n); \577}578579/**580* Get the unsigned 24 bits integer corresponding to three bytes in581* little-endian order (LSB first).582*583* \param data Base address of the memory to get the three bytes from.584* \param offset Offset from \p data of the first and least significant585* byte of the three bytes to build the 24 bits unsigned586* integer from.587*/588#define MBEDTLS_GET_UINT24_LE(data, offset) \589( \590((uint32_t) (data)[(offset)]) \591| ((uint32_t) (data)[(offset) + 1] << 8) \592| ((uint32_t) (data)[(offset) + 2] << 16) \593)594595/**596* Put in memory a 24 bits unsigned integer in little-endian order.597*598* \param n 24 bits unsigned integer to put in memory.599* \param data Base address of the memory where to put the 24600* bits unsigned integer in.601* \param offset Offset from \p data where to put the least significant602* byte of the 24 bits unsigned integer \p n.603*/604#define MBEDTLS_PUT_UINT24_LE(n, data, offset) \605{ \606(data)[(offset)] = MBEDTLS_BYTE_0(n); \607(data)[(offset) + 1] = MBEDTLS_BYTE_1(n); \608(data)[(offset) + 2] = MBEDTLS_BYTE_2(n); \609}610611/**612* Get the unsigned 64 bits integer corresponding to eight bytes in613* big-endian order (MSB first).614*615* \param data Base address of the memory to get the eight bytes from.616* \param offset Offset from \p data of the first and most significant617* byte of the eight bytes to build the 64 bits unsigned618* integer from.619*/620#define MBEDTLS_GET_UINT64_BE(data, offset) \621((MBEDTLS_IS_BIG_ENDIAN) \622? mbedtls_get_unaligned_uint64((data) + (offset)) \623: MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \624)625626/**627* Put in memory a 64 bits unsigned integer in big-endian order.628*629* \param n 64 bits unsigned integer to put in memory.630* \param data Base address of the memory where to put the 64631* bits unsigned integer in.632* \param offset Offset from \p data where to put the most significant633* byte of the 64 bits unsigned integer \p n.634*/635#define MBEDTLS_PUT_UINT64_BE(n, data, offset) \636{ \637if (MBEDTLS_IS_BIG_ENDIAN) \638{ \639mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n)); \640} \641else \642{ \643mbedtls_put_unaligned_uint64((data) + (offset), MBEDTLS_BSWAP64((uint64_t) (n))); \644} \645}646647/**648* Get the unsigned 64 bits integer corresponding to eight bytes in649* little-endian order (LSB first).650*651* \param data Base address of the memory to get the eight bytes from.652* \param offset Offset from \p data of the first and least significant653* byte of the eight bytes to build the 64 bits unsigned654* integer from.655*/656#define MBEDTLS_GET_UINT64_LE(data, offset) \657((MBEDTLS_IS_BIG_ENDIAN) \658? MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \659: mbedtls_get_unaligned_uint64((data) + (offset)) \660)661662/**663* Put in memory a 64 bits unsigned integer in little-endian order.664*665* \param n 64 bits unsigned integer to put in memory.666* \param data Base address of the memory where to put the 64667* bits unsigned integer in.668* \param offset Offset from \p data where to put the least significant669* byte of the 64 bits unsigned integer \p n.670*/671#define MBEDTLS_PUT_UINT64_LE(n, data, offset) \672{ \673if (MBEDTLS_IS_BIG_ENDIAN) \674{ \675mbedtls_put_unaligned_uint64((data) + (offset), MBEDTLS_BSWAP64((uint64_t) (n))); \676} \677else \678{ \679mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n)); \680} \681}682683#endif /* MBEDTLS_LIBRARY_ALIGNMENT_H */684685686