LCOV - code coverage report
Current view: top level - os_stub/mbedtlslib/mbedtls/library - alignment.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 66.7 % 12 8
Test Date: 2025-06-29 08:09:00 Functions: - 0 0

            Line data    Source code
       1              : /**
       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 OR GPL-2.0-or-later
       9              :  */
      10              : 
      11              : #ifndef MBEDTLS_LIBRARY_ALIGNMENT_H
      12              : #define MBEDTLS_LIBRARY_ALIGNMENT_H
      13              : 
      14              : #include <stdint.h>
      15              : #include <string.h>
      16              : #include <stdlib.h>
      17              : 
      18              : /*
      19              :  * Define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS for architectures where unaligned memory
      20              :  * 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.
      24              :  */
      25              : #if defined(__ARM_FEATURE_UNALIGNED) \
      26              :     || defined(MBEDTLS_ARCH_IS_X86) || defined(MBEDTLS_ARCH_IS_X64) \
      27              :     || defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
      28              : /*
      29              :  * __ARM_FEATURE_UNALIGNED is defined where appropriate by armcc, gcc 7, clang 9
      30              :  * (and later versions) for Arm v7 and later; all x86 platforms should have
      31              :  * efficient unaligned access.
      32              :  *
      33              :  * https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#alignment
      34              :  * specifies that on Windows-on-Arm64, unaligned access is safe (except for uncached
      35              :  * device memory).
      36              :  */
      37              : #define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS
      38              : #endif
      39              : 
      40              : #if defined(__IAR_SYSTEMS_ICC__) && \
      41              :     (defined(MBEDTLS_ARCH_IS_ARM64) || defined(MBEDTLS_ARCH_IS_ARM32) \
      42              :     || defined(__ICCRX__) || defined(__ICCRL78__) || defined(__ICCRISCV__))
      43              : #pragma language=save
      44              : #pragma language=extended
      45              : #define MBEDTLS_POP_IAR_LANGUAGE_PRAGMA
      46              : /* IAR recommend this technique for accessing unaligned data in
      47              :  * https://www.iar.com/knowledge/support/technical-notes/compiler/accessing-unaligned-data
      48              :  * This results in a single load / store instruction (if unaligned access is supported).
      49              :  * According to that document, this is only supported on certain architectures.
      50              :  */
      51              :     #define UINT_UNALIGNED
      52              : typedef uint16_t __packed mbedtls_uint16_unaligned_t;
      53              : typedef uint32_t __packed mbedtls_uint32_unaligned_t;
      54              : typedef uint64_t __packed mbedtls_uint64_unaligned_t;
      55              : #elif defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 40504) && \
      56              :     ((MBEDTLS_GCC_VERSION < 60300) || (!defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)))
      57              : /*
      58              :  * gcc may generate a branch to memcpy for calls like `memcpy(dest, src, 4)` rather than
      59              :  * generating some LDR or LDRB instructions (similar for stores).
      60              :  *
      61              :  * This is architecture dependent: x86-64 seems fine even with old gcc; 32-bit Arm
      62              :  * is affected. To keep it simple, we enable for all architectures.
      63              :  *
      64              :  * For versions of gcc < 5.4.0 this issue always happens.
      65              :  * For gcc < 6.3.0, this issue happens at -O0
      66              :  * For all versions, this issue happens iff unaligned access is not supported.
      67              :  *
      68              :  * For gcc 4.x, this implementation will generate byte-by-byte loads even if unaligned access is
      69              :  * supported, which is correct but not optimal.
      70              :  *
      71              :  * For performance (and code size, in some cases), we want to avoid the branch and just generate
      72              :  * some inline load/store instructions since the access is small and constant-size.
      73              :  *
      74              :  * The manual states:
      75              :  * "The packed attribute specifies that a variable or structure field should have the smallest
      76              :  *  possible alignment—one byte for a variable"
      77              :  * https://gcc.gnu.org/onlinedocs/gcc-4.5.4/gcc/Variable-Attributes.html
      78              :  *
      79              :  * Previous implementations used __attribute__((__aligned__(1)), but had issues with a gcc bug:
      80              :  * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94662
      81              :  *
      82              :  * Tested with several versions of GCC from 4.5.0 up to 13.2.0
      83              :  * We don't enable for older than 4.5.0 as this has not been tested.
      84              :  */
      85              :  #define UINT_UNALIGNED_STRUCT
      86              : typedef struct {
      87              :     uint16_t x;
      88              : } __attribute__((packed)) mbedtls_uint16_unaligned_t;
      89              : typedef struct {
      90              :     uint32_t x;
      91              : } __attribute__((packed)) mbedtls_uint32_unaligned_t;
      92              : typedef struct {
      93              :     uint64_t x;
      94              : } __attribute__((packed)) mbedtls_uint64_unaligned_t;
      95              :  #endif
      96              : 
      97              : /*
      98              :  * We try to force mbedtls_(get|put)_unaligned_uintXX to be always inline, because this results
      99              :  * in code that is both smaller and faster. IAR and gcc both benefit from this when optimising
     100              :  * for size.
     101              :  */
     102              : 
     103              : /**
     104              :  * Read the unsigned 16 bits integer from the given address, which need not
     105              :  * be aligned.
     106              :  *
     107              :  * \param   p pointer to 2 bytes of data
     108              :  * \return  Data at the given address
     109              :  */
     110              : #if defined(__IAR_SYSTEMS_ICC__)
     111              : #pragma inline = forced
     112              : #elif defined(__GNUC__)
     113              : __attribute__((always_inline))
     114              : #endif
     115              : static inline uint16_t mbedtls_get_unaligned_uint16(const void *p)
     116              : {
     117              :     uint16_t r;
     118              : #if defined(UINT_UNALIGNED)
     119              :     mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;
     120              :     r = *p16;
     121              : #elif defined(UINT_UNALIGNED_STRUCT)
     122              :     mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;
     123              :     r = p16->x;
     124              : #else
     125            0 :     memcpy(&r, p, sizeof(r));
     126              : #endif
     127            0 :     return r;
     128              : }
     129              : 
     130              : /**
     131              :  * Write the unsigned 16 bits integer to the given address, which need not
     132              :  * be aligned.
     133              :  *
     134              :  * \param   p pointer to 2 bytes of data
     135              :  * \param   x data to write
     136              :  */
     137              : #if defined(__IAR_SYSTEMS_ICC__)
     138              : #pragma inline = forced
     139              : #elif defined(__GNUC__)
     140              : __attribute__((always_inline))
     141              : #endif
     142              : static inline void mbedtls_put_unaligned_uint16(void *p, uint16_t x)
     143              : {
     144              : #if defined(UINT_UNALIGNED)
     145              :     mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;
     146              :     *p16 = x;
     147              : #elif defined(UINT_UNALIGNED_STRUCT)
     148              :     mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;
     149              :     p16->x = x;
     150              : #else
     151            0 :     memcpy(p, &x, sizeof(x));
     152              : #endif
     153            0 : }
     154              : 
     155              : /**
     156              :  * Read the unsigned 32 bits integer from the given address, which need not
     157              :  * be aligned.
     158              :  *
     159              :  * \param   p pointer to 4 bytes of data
     160              :  * \return  Data at the given address
     161              :  */
     162              : #if defined(__IAR_SYSTEMS_ICC__)
     163              : #pragma inline = forced
     164              : #elif defined(__GNUC__)
     165              : __attribute__((always_inline))
     166              : #endif
     167              : static inline uint32_t mbedtls_get_unaligned_uint32(const void *p)
     168              : {
     169              :     uint32_t r;
     170              : #if defined(UINT_UNALIGNED)
     171              :     mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
     172              :     r = *p32;
     173              : #elif defined(UINT_UNALIGNED_STRUCT)
     174              :     mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
     175              :     r = p32->x;
     176              : #else
     177       772078 :     memcpy(&r, p, sizeof(r));
     178              : #endif
     179       772078 :     return r;
     180              : }
     181              : 
     182              : /**
     183              :  * Write the unsigned 32 bits integer to the given address, which need not
     184              :  * be aligned.
     185              :  *
     186              :  * \param   p pointer to 4 bytes of data
     187              :  * \param   x data to write
     188              :  */
     189              : #if defined(__IAR_SYSTEMS_ICC__)
     190              : #pragma inline = forced
     191              : #elif defined(__GNUC__)
     192              : __attribute__((always_inline))
     193              : #endif
     194              : static inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x)
     195              : {
     196              : #if defined(UINT_UNALIGNED)
     197              :     mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
     198              :     *p32 = x;
     199              : #elif defined(UINT_UNALIGNED_STRUCT)
     200              :     mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
     201              :     p32->x = x;
     202              : #else
     203        79350 :     memcpy(p, &x, sizeof(x));
     204              : #endif
     205        79350 : }
     206              : 
     207              : /**
     208              :  * Read the unsigned 64 bits integer from the given address, which need not
     209              :  * be aligned.
     210              :  *
     211              :  * \param   p pointer to 8 bytes of data
     212              :  * \return  Data at the given address
     213              :  */
     214              : #if defined(__IAR_SYSTEMS_ICC__)
     215              : #pragma inline = forced
     216              : #elif defined(__GNUC__)
     217              : __attribute__((always_inline))
     218              : #endif
     219              : static inline uint64_t mbedtls_get_unaligned_uint64(const void *p)
     220              : {
     221              :     uint64_t r;
     222              : #if defined(UINT_UNALIGNED)
     223              :     mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;
     224              :     r = *p64;
     225              : #elif defined(UINT_UNALIGNED_STRUCT)
     226              :     mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;
     227              :     r = p64->x;
     228              : #else
     229      7490016 :     memcpy(&r, p, sizeof(r));
     230              : #endif
     231      7490016 :     return r;
     232              : }
     233              : 
     234              : /**
     235              :  * Write the unsigned 64 bits integer to the given address, which need not
     236              :  * be aligned.
     237              :  *
     238              :  * \param   p pointer to 8 bytes of data
     239              :  * \param   x data to write
     240              :  */
     241              : #if defined(__IAR_SYSTEMS_ICC__)
     242              : #pragma inline = forced
     243              : #elif defined(__GNUC__)
     244              : __attribute__((always_inline))
     245              : #endif
     246              : static inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x)
     247              : {
     248              : #if defined(UINT_UNALIGNED)
     249              :     mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;
     250              :     *p64 = x;
     251              : #elif defined(UINT_UNALIGNED_STRUCT)
     252              :     mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;
     253              :     p64->x = x;
     254              : #else
     255      3742916 :     memcpy(p, &x, sizeof(x));
     256              : #endif
     257      3742916 : }
     258              : 
     259              : #if defined(MBEDTLS_POP_IAR_LANGUAGE_PRAGMA)
     260              : #pragma language=restore
     261              : #endif
     262              : 
     263              : /** Byte Reading Macros
     264              :  *
     265              :  * Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th
     266              :  * byte from x, where byte 0 is the least significant byte.
     267              :  */
     268              : #define MBEDTLS_BYTE_0(x) ((uint8_t) ((x)         & 0xff))
     269              : #define MBEDTLS_BYTE_1(x) ((uint8_t) (((x) >>  8) & 0xff))
     270              : #define MBEDTLS_BYTE_2(x) ((uint8_t) (((x) >> 16) & 0xff))
     271              : #define MBEDTLS_BYTE_3(x) ((uint8_t) (((x) >> 24) & 0xff))
     272              : #define MBEDTLS_BYTE_4(x) ((uint8_t) (((x) >> 32) & 0xff))
     273              : #define MBEDTLS_BYTE_5(x) ((uint8_t) (((x) >> 40) & 0xff))
     274              : #define MBEDTLS_BYTE_6(x) ((uint8_t) (((x) >> 48) & 0xff))
     275              : #define MBEDTLS_BYTE_7(x) ((uint8_t) (((x) >> 56) & 0xff))
     276              : 
     277              : /*
     278              :  * Detect GCC built-in byteswap routines
     279              :  */
     280              : #if defined(__GNUC__) && defined(__GNUC_PREREQ)
     281              : #if __GNUC_PREREQ(4, 8)
     282              : #define MBEDTLS_BSWAP16 __builtin_bswap16
     283              : #endif /* __GNUC_PREREQ(4,8) */
     284              : #if __GNUC_PREREQ(4, 3)
     285              : #define MBEDTLS_BSWAP32 __builtin_bswap32
     286              : #define MBEDTLS_BSWAP64 __builtin_bswap64
     287              : #endif /* __GNUC_PREREQ(4,3) */
     288              : #endif /* defined(__GNUC__) && defined(__GNUC_PREREQ) */
     289              : 
     290              : /*
     291              :  * Detect Clang built-in byteswap routines
     292              :  */
     293              : #if defined(__clang__) && defined(__has_builtin)
     294              : #if __has_builtin(__builtin_bswap16) && !defined(MBEDTLS_BSWAP16)
     295              : #define MBEDTLS_BSWAP16 __builtin_bswap16
     296              : #endif /* __has_builtin(__builtin_bswap16) */
     297              : #if __has_builtin(__builtin_bswap32) && !defined(MBEDTLS_BSWAP32)
     298              : #define MBEDTLS_BSWAP32 __builtin_bswap32
     299              : #endif /* __has_builtin(__builtin_bswap32) */
     300              : #if __has_builtin(__builtin_bswap64) && !defined(MBEDTLS_BSWAP64)
     301              : #define MBEDTLS_BSWAP64 __builtin_bswap64
     302              : #endif /* __has_builtin(__builtin_bswap64) */
     303              : #endif /* defined(__clang__) && defined(__has_builtin) */
     304              : 
     305              : /*
     306              :  * Detect MSVC built-in byteswap routines
     307              :  */
     308              : #if defined(_MSC_VER)
     309              : #if !defined(MBEDTLS_BSWAP16)
     310              : #define MBEDTLS_BSWAP16 _byteswap_ushort
     311              : #endif
     312              : #if !defined(MBEDTLS_BSWAP32)
     313              : #define MBEDTLS_BSWAP32 _byteswap_ulong
     314              : #endif
     315              : #if !defined(MBEDTLS_BSWAP64)
     316              : #define MBEDTLS_BSWAP64 _byteswap_uint64
     317              : #endif
     318              : #endif /* defined(_MSC_VER) */
     319              : 
     320              : /* Detect armcc built-in byteswap routine */
     321              : #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 410000) && !defined(MBEDTLS_BSWAP32)
     322              : #if defined(__ARM_ACLE)  /* ARM Compiler 6 - earlier versions don't need a header */
     323              : #include <arm_acle.h>
     324              : #endif
     325              : #define MBEDTLS_BSWAP32 __rev
     326              : #endif
     327              : 
     328              : /* Detect IAR built-in byteswap routine */
     329              : #if defined(__IAR_SYSTEMS_ICC__)
     330              : #if defined(__ARM_ACLE)
     331              : #include <arm_acle.h>
     332              : #define MBEDTLS_BSWAP16(x) ((uint16_t) __rev16((uint32_t) (x)))
     333              : #define MBEDTLS_BSWAP32 __rev
     334              : #define MBEDTLS_BSWAP64 __revll
     335              : #endif
     336              : #endif
     337              : 
     338              : /*
     339              :  * Where compiler built-ins are not present, fall back to C code that the
     340              :  * compiler may be able to detect and transform into the relevant bswap or
     341              :  * similar instruction.
     342              :  */
     343              : #if !defined(MBEDTLS_BSWAP16)
     344              : static inline uint16_t mbedtls_bswap16(uint16_t x)
     345              : {
     346              :     return
     347              :         (x & 0x00ff) << 8 |
     348              :         (x & 0xff00) >> 8;
     349              : }
     350              : #define MBEDTLS_BSWAP16 mbedtls_bswap16
     351              : #endif /* !defined(MBEDTLS_BSWAP16) */
     352              : 
     353              : #if !defined(MBEDTLS_BSWAP32)
     354              : static inline uint32_t mbedtls_bswap32(uint32_t x)
     355              : {
     356              :     return
     357              :         (x & 0x000000ff) << 24 |
     358              :         (x & 0x0000ff00) <<  8 |
     359              :         (x & 0x00ff0000) >>  8 |
     360              :         (x & 0xff000000) >> 24;
     361              : }
     362              : #define MBEDTLS_BSWAP32 mbedtls_bswap32
     363              : #endif /* !defined(MBEDTLS_BSWAP32) */
     364              : 
     365              : #if !defined(MBEDTLS_BSWAP64)
     366              : static inline uint64_t mbedtls_bswap64(uint64_t x)
     367              : {
     368              :     return
     369              :         (x & 0x00000000000000ffULL) << 56 |
     370              :         (x & 0x000000000000ff00ULL) << 40 |
     371              :         (x & 0x0000000000ff0000ULL) << 24 |
     372              :         (x & 0x00000000ff000000ULL) <<  8 |
     373              :         (x & 0x000000ff00000000ULL) >>  8 |
     374              :         (x & 0x0000ff0000000000ULL) >> 24 |
     375              :         (x & 0x00ff000000000000ULL) >> 40 |
     376              :         (x & 0xff00000000000000ULL) >> 56;
     377              : }
     378              : #define MBEDTLS_BSWAP64 mbedtls_bswap64
     379              : #endif /* !defined(MBEDTLS_BSWAP64) */
     380              : 
     381              : #if !defined(__BYTE_ORDER__)
     382              : 
     383              : #if defined(__LITTLE_ENDIAN__)
     384              : /* IAR defines __xxx_ENDIAN__, but not __BYTE_ORDER__ */
     385              : #define MBEDTLS_IS_BIG_ENDIAN 0
     386              : #elif defined(__BIG_ENDIAN__)
     387              : #define MBEDTLS_IS_BIG_ENDIAN 1
     388              : #else
     389              : static const uint16_t mbedtls_byte_order_detector = { 0x100 };
     390              : #define MBEDTLS_IS_BIG_ENDIAN (*((unsigned char *) (&mbedtls_byte_order_detector)) == 0x01)
     391              : #endif
     392              : 
     393              : #else
     394              : 
     395              : #if (__BYTE_ORDER__) == (__ORDER_BIG_ENDIAN__)
     396              : #define MBEDTLS_IS_BIG_ENDIAN 1
     397              : #else
     398              : #define MBEDTLS_IS_BIG_ENDIAN 0
     399              : #endif
     400              : 
     401              : #endif /* !defined(__BYTE_ORDER__) */
     402              : 
     403              : /**
     404              :  * Get the unsigned 32 bits integer corresponding to four bytes in
     405              :  * big-endian order (MSB first).
     406              :  *
     407              :  * \param   data    Base address of the memory to get the four bytes from.
     408              :  * \param   offset  Offset from \p data of the first and most significant
     409              :  *                  byte of the four bytes to build the 32 bits unsigned
     410              :  *                  integer from.
     411              :  */
     412              : #define MBEDTLS_GET_UINT32_BE(data, offset)                                \
     413              :     ((MBEDTLS_IS_BIG_ENDIAN)                                               \
     414              :         ? mbedtls_get_unaligned_uint32((data) + (offset))                  \
     415              :         : MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \
     416              :     )
     417              : 
     418              : /**
     419              :  * Put in memory a 32 bits unsigned integer in big-endian order.
     420              :  *
     421              :  * \param   n       32 bits unsigned integer to put in memory.
     422              :  * \param   data    Base address of the memory where to put the 32
     423              :  *                  bits unsigned integer in.
     424              :  * \param   offset  Offset from \p data where to put the most significant
     425              :  *                  byte of the 32 bits unsigned integer \p n.
     426              :  */
     427              : #define MBEDTLS_PUT_UINT32_BE(n, data, offset)                                   \
     428              :     {                                                                            \
     429              :         if (MBEDTLS_IS_BIG_ENDIAN)                                               \
     430              :         {                                                                        \
     431              :             mbedtls_put_unaligned_uint32((data) + (offset), (uint32_t) (n));     \
     432              :         }                                                                        \
     433              :         else                                                                     \
     434              :         {                                                                        \
     435              :             mbedtls_put_unaligned_uint32((data) + (offset), MBEDTLS_BSWAP32((uint32_t) (n))); \
     436              :         }                                                                        \
     437              :     }
     438              : 
     439              : /**
     440              :  * Get the unsigned 32 bits integer corresponding to four bytes in
     441              :  * little-endian order (LSB first).
     442              :  *
     443              :  * \param   data    Base address of the memory to get the four bytes from.
     444              :  * \param   offset  Offset from \p data of the first and least significant
     445              :  *                  byte of the four bytes to build the 32 bits unsigned
     446              :  *                  integer from.
     447              :  */
     448              : #define MBEDTLS_GET_UINT32_LE(data, offset)                                \
     449              :     ((MBEDTLS_IS_BIG_ENDIAN)                                               \
     450              :         ? MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \
     451              :         : mbedtls_get_unaligned_uint32((data) + (offset))                  \
     452              :     )
     453              : 
     454              : 
     455              : /**
     456              :  * Put in memory a 32 bits unsigned integer in little-endian order.
     457              :  *
     458              :  * \param   n       32 bits unsigned integer to put in memory.
     459              :  * \param   data    Base address of the memory where to put the 32
     460              :  *                  bits unsigned integer in.
     461              :  * \param   offset  Offset from \p data where to put the least significant
     462              :  *                  byte of the 32 bits unsigned integer \p n.
     463              :  */
     464              : #define MBEDTLS_PUT_UINT32_LE(n, data, offset)                                   \
     465              :     {                                                                            \
     466              :         if (MBEDTLS_IS_BIG_ENDIAN)                                               \
     467              :         {                                                                        \
     468              :             mbedtls_put_unaligned_uint32((data) + (offset), MBEDTLS_BSWAP32((uint32_t) (n))); \
     469              :         }                                                                        \
     470              :         else                                                                     \
     471              :         {                                                                        \
     472              :             mbedtls_put_unaligned_uint32((data) + (offset), ((uint32_t) (n)));   \
     473              :         }                                                                        \
     474              :     }
     475              : 
     476              : /**
     477              :  * Get the unsigned 16 bits integer corresponding to two bytes in
     478              :  * little-endian order (LSB first).
     479              :  *
     480              :  * \param   data    Base address of the memory to get the two bytes from.
     481              :  * \param   offset  Offset from \p data of the first and least significant
     482              :  *                  byte of the two bytes to build the 16 bits unsigned
     483              :  *                  integer from.
     484              :  */
     485              : #define MBEDTLS_GET_UINT16_LE(data, offset)                                \
     486              :     ((MBEDTLS_IS_BIG_ENDIAN)                                               \
     487              :         ? MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \
     488              :         : mbedtls_get_unaligned_uint16((data) + (offset))                  \
     489              :     )
     490              : 
     491              : /**
     492              :  * Put in memory a 16 bits unsigned integer in little-endian order.
     493              :  *
     494              :  * \param   n       16 bits unsigned integer to put in memory.
     495              :  * \param   data    Base address of the memory where to put the 16
     496              :  *                  bits unsigned integer in.
     497              :  * \param   offset  Offset from \p data where to put the least significant
     498              :  *                  byte of the 16 bits unsigned integer \p n.
     499              :  */
     500              : #define MBEDTLS_PUT_UINT16_LE(n, data, offset)                                   \
     501              :     {                                                                            \
     502              :         if (MBEDTLS_IS_BIG_ENDIAN)                                               \
     503              :         {                                                                        \
     504              :             mbedtls_put_unaligned_uint16((data) + (offset), MBEDTLS_BSWAP16((uint16_t) (n))); \
     505              :         }                                                                        \
     506              :         else                                                                     \
     507              :         {                                                                        \
     508              :             mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n));     \
     509              :         }                                                                        \
     510              :     }
     511              : 
     512              : /**
     513              :  * Get the unsigned 16 bits integer corresponding to two bytes in
     514              :  * big-endian order (MSB first).
     515              :  *
     516              :  * \param   data    Base address of the memory to get the two bytes from.
     517              :  * \param   offset  Offset from \p data of the first and most significant
     518              :  *                  byte of the two bytes to build the 16 bits unsigned
     519              :  *                  integer from.
     520              :  */
     521              : #define MBEDTLS_GET_UINT16_BE(data, offset)                                \
     522              :     ((MBEDTLS_IS_BIG_ENDIAN)                                               \
     523              :         ? mbedtls_get_unaligned_uint16((data) + (offset))                  \
     524              :         : MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \
     525              :     )
     526              : 
     527              : /**
     528              :  * Put in memory a 16 bits unsigned integer in big-endian order.
     529              :  *
     530              :  * \param   n       16 bits unsigned integer to put in memory.
     531              :  * \param   data    Base address of the memory where to put the 16
     532              :  *                  bits unsigned integer in.
     533              :  * \param   offset  Offset from \p data where to put the most significant
     534              :  *                  byte of the 16 bits unsigned integer \p n.
     535              :  */
     536              : #define MBEDTLS_PUT_UINT16_BE(n, data, offset)                                   \
     537              :     {                                                                            \
     538              :         if (MBEDTLS_IS_BIG_ENDIAN)                                               \
     539              :         {                                                                        \
     540              :             mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n));     \
     541              :         }                                                                        \
     542              :         else                                                                     \
     543              :         {                                                                        \
     544              :             mbedtls_put_unaligned_uint16((data) + (offset), MBEDTLS_BSWAP16((uint16_t) (n))); \
     545              :         }                                                                        \
     546              :     }
     547              : 
     548              : /**
     549              :  * Get the unsigned 24 bits integer corresponding to three bytes in
     550              :  * big-endian order (MSB first).
     551              :  *
     552              :  * \param   data    Base address of the memory to get the three bytes from.
     553              :  * \param   offset  Offset from \p data of the first and most significant
     554              :  *                  byte of the three bytes to build the 24 bits unsigned
     555              :  *                  integer from.
     556              :  */
     557              : #define MBEDTLS_GET_UINT24_BE(data, offset)        \
     558              :     (                                              \
     559              :         ((uint32_t) (data)[(offset)] << 16)        \
     560              :         | ((uint32_t) (data)[(offset) + 1] << 8)   \
     561              :         | ((uint32_t) (data)[(offset) + 2])        \
     562              :     )
     563              : 
     564              : /**
     565              :  * Put in memory a 24 bits unsigned integer in big-endian order.
     566              :  *
     567              :  * \param   n       24 bits unsigned integer to put in memory.
     568              :  * \param   data    Base address of the memory where to put the 24
     569              :  *                  bits unsigned integer in.
     570              :  * \param   offset  Offset from \p data where to put the most significant
     571              :  *                  byte of the 24 bits unsigned integer \p n.
     572              :  */
     573              : #define MBEDTLS_PUT_UINT24_BE(n, data, offset)                \
     574              :     {                                                         \
     575              :         (data)[(offset)] = MBEDTLS_BYTE_2(n);                 \
     576              :         (data)[(offset) + 1] = MBEDTLS_BYTE_1(n);             \
     577              :         (data)[(offset) + 2] = MBEDTLS_BYTE_0(n);             \
     578              :     }
     579              : 
     580              : /**
     581              :  * Get the unsigned 24 bits integer corresponding to three bytes in
     582              :  * little-endian order (LSB first).
     583              :  *
     584              :  * \param   data    Base address of the memory to get the three bytes from.
     585              :  * \param   offset  Offset from \p data of the first and least significant
     586              :  *                  byte of the three bytes to build the 24 bits unsigned
     587              :  *                  integer from.
     588              :  */
     589              : #define MBEDTLS_GET_UINT24_LE(data, offset)               \
     590              :     (                                                     \
     591              :         ((uint32_t) (data)[(offset)])                     \
     592              :         | ((uint32_t) (data)[(offset) + 1] <<  8)         \
     593              :         | ((uint32_t) (data)[(offset) + 2] << 16)         \
     594              :     )
     595              : 
     596              : /**
     597              :  * Put in memory a 24 bits unsigned integer in little-endian order.
     598              :  *
     599              :  * \param   n       24 bits unsigned integer to put in memory.
     600              :  * \param   data    Base address of the memory where to put the 24
     601              :  *                  bits unsigned integer in.
     602              :  * \param   offset  Offset from \p data where to put the least significant
     603              :  *                  byte of the 24 bits unsigned integer \p n.
     604              :  */
     605              : #define MBEDTLS_PUT_UINT24_LE(n, data, offset)                \
     606              :     {                                                         \
     607              :         (data)[(offset)] = MBEDTLS_BYTE_0(n);                 \
     608              :         (data)[(offset) + 1] = MBEDTLS_BYTE_1(n);             \
     609              :         (data)[(offset) + 2] = MBEDTLS_BYTE_2(n);             \
     610              :     }
     611              : 
     612              : /**
     613              :  * Get the unsigned 64 bits integer corresponding to eight bytes in
     614              :  * big-endian order (MSB first).
     615              :  *
     616              :  * \param   data    Base address of the memory to get the eight bytes from.
     617              :  * \param   offset  Offset from \p data of the first and most significant
     618              :  *                  byte of the eight bytes to build the 64 bits unsigned
     619              :  *                  integer from.
     620              :  */
     621              : #define MBEDTLS_GET_UINT64_BE(data, offset)                                \
     622              :     ((MBEDTLS_IS_BIG_ENDIAN)                                               \
     623              :         ? mbedtls_get_unaligned_uint64((data) + (offset))                  \
     624              :         : MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \
     625              :     )
     626              : 
     627              : /**
     628              :  * Put in memory a 64 bits unsigned integer in big-endian order.
     629              :  *
     630              :  * \param   n       64 bits unsigned integer to put in memory.
     631              :  * \param   data    Base address of the memory where to put the 64
     632              :  *                  bits unsigned integer in.
     633              :  * \param   offset  Offset from \p data where to put the most significant
     634              :  *                  byte of the 64 bits unsigned integer \p n.
     635              :  */
     636              : #define MBEDTLS_PUT_UINT64_BE(n, data, offset)                                   \
     637              :     {                                                                            \
     638              :         if (MBEDTLS_IS_BIG_ENDIAN)                                               \
     639              :         {                                                                        \
     640              :             mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n));     \
     641              :         }                                                                        \
     642              :         else                                                                     \
     643              :         {                                                                        \
     644              :             mbedtls_put_unaligned_uint64((data) + (offset), MBEDTLS_BSWAP64((uint64_t) (n))); \
     645              :         }                                                                        \
     646              :     }
     647              : 
     648              : /**
     649              :  * Get the unsigned 64 bits integer corresponding to eight bytes in
     650              :  * little-endian order (LSB first).
     651              :  *
     652              :  * \param   data    Base address of the memory to get the eight bytes from.
     653              :  * \param   offset  Offset from \p data of the first and least significant
     654              :  *                  byte of the eight bytes to build the 64 bits unsigned
     655              :  *                  integer from.
     656              :  */
     657              : #define MBEDTLS_GET_UINT64_LE(data, offset)                                \
     658              :     ((MBEDTLS_IS_BIG_ENDIAN)                                               \
     659              :         ? MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \
     660              :         : mbedtls_get_unaligned_uint64((data) + (offset))                  \
     661              :     )
     662              : 
     663              : /**
     664              :  * Put in memory a 64 bits unsigned integer in little-endian order.
     665              :  *
     666              :  * \param   n       64 bits unsigned integer to put in memory.
     667              :  * \param   data    Base address of the memory where to put the 64
     668              :  *                  bits unsigned integer in.
     669              :  * \param   offset  Offset from \p data where to put the least significant
     670              :  *                  byte of the 64 bits unsigned integer \p n.
     671              :  */
     672              : #define MBEDTLS_PUT_UINT64_LE(n, data, offset)                                   \
     673              :     {                                                                            \
     674              :         if (MBEDTLS_IS_BIG_ENDIAN)                                               \
     675              :         {                                                                        \
     676              :             mbedtls_put_unaligned_uint64((data) + (offset), MBEDTLS_BSWAP64((uint64_t) (n))); \
     677              :         }                                                                        \
     678              :         else                                                                     \
     679              :         {                                                                        \
     680              :             mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n));     \
     681              :         }                                                                        \
     682              :     }
     683              : 
     684              : #endif /* MBEDTLS_LIBRARY_ALIGNMENT_H */
        

Generated by: LCOV version 2.0-1