Skip to content

Commit fa831fc

Browse files
committed
CHANGE: updated Mbed-TLS sources to version 3.6.0
1 parent f3060c0 commit fa831fc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+3626
-1795
lines changed

src/core/mbedtls/aes.c

+95-116
Large diffs are not rendered by default.

src/core/mbedtls/alignment.h

+183-8
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,107 @@
2323
* efficient when this is not defined.
2424
*/
2525
#if defined(__ARM_FEATURE_UNALIGNED) \
26-
|| defined(__i386__) || defined(__amd64__) || defined(__x86_64__)
26+
|| defined(MBEDTLS_ARCH_IS_X86) || defined(MBEDTLS_ARCH_IS_X64) \
27+
|| defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
2728
/*
2829
* __ARM_FEATURE_UNALIGNED is defined where appropriate by armcc, gcc 7, clang 9
2930
* (and later versions) for Arm v7 and later; all x86 platforms should have
3031
* 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).
3136
*/
3237
#define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS
3338
#endif
3439

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+
35103
/**
36104
* Read the unsigned 16 bits integer from the given address, which need not
37105
* be aligned.
38106
*
39107
* \param p pointer to 2 bytes of data
40108
* \return Data at the given address
41109
*/
42-
inline uint16_t mbedtls_get_unaligned_uint16(const void *p)
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)
43116
{
44117
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
45125
memcpy(&r, p, sizeof(r));
126+
#endif
46127
return r;
47128
}
48129

@@ -53,9 +134,22 @@ inline uint16_t mbedtls_get_unaligned_uint16(const void *p)
53134
* \param p pointer to 2 bytes of data
54135
* \param x data to write
55136
*/
56-
inline void mbedtls_put_unaligned_uint16(void *p, uint16_t x)
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)
57143
{
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
58151
memcpy(p, &x, sizeof(x));
152+
#endif
59153
}
60154

61155
/**
@@ -65,10 +159,23 @@ inline void mbedtls_put_unaligned_uint16(void *p, uint16_t x)
65159
* \param p pointer to 4 bytes of data
66160
* \return Data at the given address
67161
*/
68-
inline uint32_t mbedtls_get_unaligned_uint32(const void *p)
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)
69168
{
70169
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
71177
memcpy(&r, p, sizeof(r));
178+
#endif
72179
return r;
73180
}
74181

@@ -79,9 +186,22 @@ inline uint32_t mbedtls_get_unaligned_uint32(const void *p)
79186
* \param p pointer to 4 bytes of data
80187
* \param x data to write
81188
*/
82-
inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x)
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)
83195
{
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
84203
memcpy(p, &x, sizeof(x));
204+
#endif
85205
}
86206

87207
/**
@@ -91,10 +211,23 @@ inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x)
91211
* \param p pointer to 8 bytes of data
92212
* \return Data at the given address
93213
*/
94-
inline uint64_t mbedtls_get_unaligned_uint64(const void *p)
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)
95220
{
96221
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
97229
memcpy(&r, p, sizeof(r));
230+
#endif
98231
return r;
99232
}
100233

@@ -105,11 +238,28 @@ inline uint64_t mbedtls_get_unaligned_uint64(const void *p)
105238
* \param p pointer to 8 bytes of data
106239
* \param x data to write
107240
*/
108-
inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x)
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)
109247
{
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
110255
memcpy(p, &x, sizeof(x));
256+
#endif
111257
}
112258

259+
#if defined(MBEDTLS_POP_IAR_LANGUAGE_PRAGMA)
260+
#pragma language=restore
261+
#endif
262+
113263
/** Byte Reading Macros
114264
*
115265
* Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th
@@ -175,6 +325,16 @@ inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x)
175325
#define MBEDTLS_BSWAP32 __rev
176326
#endif
177327

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+
178338
/*
179339
* Where compiler built-ins are not present, fall back to C code that the
180340
* compiler may be able to detect and transform into the relevant bswap or
@@ -219,10 +379,25 @@ static inline uint64_t mbedtls_bswap64(uint64_t x)
219379
#endif /* !defined(MBEDTLS_BSWAP64) */
220380

221381
#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
222389
static const uint16_t mbedtls_byte_order_detector = { 0x100 };
223390
#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
224397
#else
225-
#define MBEDTLS_IS_BIG_ENDIAN ((__BYTE_ORDER__) == (__ORDER_BIG_ENDIAN__))
398+
#define MBEDTLS_IS_BIG_ENDIAN 0
399+
#endif
400+
226401
#endif /* !defined(__BYTE_ORDER__) */
227402

228403
/**

0 commit comments

Comments
 (0)