1 /**
2  * \file common.h
3  *
4  * \brief Utility macros for internal use in the library
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_COMMON_H
24 #define MBEDTLS_LIBRARY_COMMON_H
25 
26 #if defined(MBEDTLS_CONFIG_FILE)
27 #include MBEDTLS_CONFIG_FILE
28 #else
29 #include "mbedtls/config.h"
30 #endif
31 
32 #include <stdint.h>
33 
34 /** Helper to define a function as static except when building invasive tests.
35  *
36  * If a function is only used inside its own source file and should be
37  * declared `static` to allow the compiler to optimize for code size,
38  * but that function has unit tests, define it with
39  * ```
40  * MBEDTLS_STATIC_TESTABLE int mbedtls_foo(...) { ... }
41  * ```
42  * and declare it in a header in the `library/` directory with
43  * ```
44  * #if defined(MBEDTLS_TEST_HOOKS)
45  * int mbedtls_foo(...);
46  * #endif
47  * ```
48  */
49 #if defined(MBEDTLS_TEST_HOOKS)
50 #define MBEDTLS_STATIC_TESTABLE
51 #else
52 #define MBEDTLS_STATIC_TESTABLE static
53 #endif
54 
55 /** Byte Reading Macros
56  *
57  * Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th
58  * byte from x, where byte 0 is the least significant byte.
59  */
60 #define MBEDTLS_BYTE_0( x ) ( (uint8_t) (   ( x )         & 0xff ) )
61 #define MBEDTLS_BYTE_1( x ) ( (uint8_t) ( ( ( x ) >> 8  ) & 0xff ) )
62 #define MBEDTLS_BYTE_2( x ) ( (uint8_t) ( ( ( x ) >> 16 ) & 0xff ) )
63 #define MBEDTLS_BYTE_3( x ) ( (uint8_t) ( ( ( x ) >> 24 ) & 0xff ) )
64 #define MBEDTLS_BYTE_4( x ) ( (uint8_t) ( ( ( x ) >> 32 ) & 0xff ) )
65 #define MBEDTLS_BYTE_5( x ) ( (uint8_t) ( ( ( x ) >> 40 ) & 0xff ) )
66 #define MBEDTLS_BYTE_6( x ) ( (uint8_t) ( ( ( x ) >> 48 ) & 0xff ) )
67 #define MBEDTLS_BYTE_7( x ) ( (uint8_t) ( ( ( x ) >> 56 ) & 0xff ) )
68 
69 /**
70  * Get the unsigned 32 bits integer corresponding to four bytes in
71  * big-endian order (MSB first).
72  *
73  * \param   data    Base address of the memory to get the four bytes from.
74  * \param   offset  Offset from \p base of the first and most significant
75  *                  byte of the four bytes to build the 32 bits unsigned
76  *                  integer from.
77  */
78 #ifndef MBEDTLS_GET_UINT32_BE
79 #define MBEDTLS_GET_UINT32_BE( data , offset )                  \
80     (                                                           \
81           ( (uint32_t) ( data )[( offset )    ] << 24 )         \
82         | ( (uint32_t) ( data )[( offset ) + 1] << 16 )         \
83         | ( (uint32_t) ( data )[( offset ) + 2] <<  8 )         \
84         | ( (uint32_t) ( data )[( offset ) + 3]       )         \
85     )
86 #endif
87 
88 /**
89  * Put in memory a 32 bits unsigned integer in big-endian order.
90  *
91  * \param   n       32 bits unsigned integer to put in memory.
92  * \param   data    Base address of the memory where to put the 32
93  *                  bits unsigned integer in.
94  * \param   offset  Offset from \p base where to put the most significant
95  *                  byte of the 32 bits unsigned integer \p n.
96  */
97 #ifndef MBEDTLS_PUT_UINT32_BE
98 #define MBEDTLS_PUT_UINT32_BE( n, data, offset )                \
99 {                                                               \
100     ( data )[( offset )    ] = MBEDTLS_BYTE_3( n );             \
101     ( data )[( offset ) + 1] = MBEDTLS_BYTE_2( n );             \
102     ( data )[( offset ) + 2] = MBEDTLS_BYTE_1( n );             \
103     ( data )[( offset ) + 3] = MBEDTLS_BYTE_0( n );             \
104 }
105 #endif
106 
107 /**
108  * Get the unsigned 32 bits integer corresponding to four bytes in
109  * little-endian order (LSB first).
110  *
111  * \param   data    Base address of the memory to get the four bytes from.
112  * \param   offset  Offset from \p base of the first and least significant
113  *                  byte of the four bytes to build the 32 bits unsigned
114  *                  integer from.
115  */
116 #ifndef MBEDTLS_GET_UINT32_LE
117 #define MBEDTLS_GET_UINT32_LE( data, offset )                   \
118     (                                                           \
119           ( (uint32_t) ( data )[( offset )    ]       )         \
120         | ( (uint32_t) ( data )[( offset ) + 1] <<  8 )         \
121         | ( (uint32_t) ( data )[( offset ) + 2] << 16 )         \
122         | ( (uint32_t) ( data )[( offset ) + 3] << 24 )         \
123     )
124 #endif
125 
126 /**
127  * Put in memory a 32 bits unsigned integer in little-endian order.
128  *
129  * \param   n       32 bits unsigned integer to put in memory.
130  * \param   data    Base address of the memory where to put the 32
131  *                  bits unsigned integer in.
132  * \param   offset  Offset from \p base where to put the least significant
133  *                  byte of the 32 bits unsigned integer \p n.
134  */
135 #ifndef MBEDTLS_PUT_UINT32_LE
136 #define MBEDTLS_PUT_UINT32_LE( n, data, offset )                \
137 {                                                               \
138     ( data )[( offset )    ] = MBEDTLS_BYTE_0( n );             \
139     ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n );             \
140     ( data )[( offset ) + 2] = MBEDTLS_BYTE_2( n );             \
141     ( data )[( offset ) + 3] = MBEDTLS_BYTE_3( n );             \
142 }
143 #endif
144 
145 /**
146  * Get the unsigned 16 bits integer corresponding to two bytes in
147  * little-endian order (LSB first).
148  *
149  * \param   data    Base address of the memory to get the two bytes from.
150  * \param   offset  Offset from \p base of the first and least significant
151  *                  byte of the two bytes to build the 16 bits unsigned
152  *                  integer from.
153  */
154 #ifndef MBEDTLS_GET_UINT16_LE
155 #define MBEDTLS_GET_UINT16_LE( data, offset )                   \
156     (                                                           \
157           ( (uint16_t) ( data )[( offset )    ]       )         \
158         | ( (uint16_t) ( data )[( offset ) + 1] <<  8 )         \
159     )
160 #endif
161 
162 /**
163  * Put in memory a 16 bits unsigned integer in little-endian order.
164  *
165  * \param   n       16 bits unsigned integer to put in memory.
166  * \param   data    Base address of the memory where to put the 16
167  *                  bits unsigned integer in.
168  * \param   offset  Offset from \p base where to put the least significant
169  *                  byte of the 16 bits unsigned integer \p n.
170  */
171 #ifndef MBEDTLS_PUT_UINT16_LE
172 #define MBEDTLS_PUT_UINT16_LE( n, data, offset )                \
173 {                                                               \
174     ( data )[( offset )    ] = MBEDTLS_BYTE_0( n );             \
175     ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n );             \
176 }
177 #endif
178 
179 /**
180  * Get the unsigned 16 bits integer corresponding to two bytes in
181  * big-endian order (MSB first).
182  *
183  * \param   data    Base address of the memory to get the two bytes from.
184  * \param   offset  Offset from \p base of the first and most significant
185  *                  byte of the two bytes to build the 16 bits unsigned
186  *                  integer from.
187  */
188 #ifndef MBEDTLS_GET_UINT16_BE
189 #define MBEDTLS_GET_UINT16_BE( data, offset )                   \
190     (                                                           \
191           ( (uint16_t) ( data )[( offset )    ] << 8 )          \
192         | ( (uint16_t) ( data )[( offset ) + 1]      )          \
193     )
194 #endif
195 
196 /**
197  * Put in memory a 16 bits unsigned integer in big-endian order.
198  *
199  * \param   n       16 bits unsigned integer to put in memory.
200  * \param   data    Base address of the memory where to put the 16
201  *                  bits unsigned integer in.
202  * \param   offset  Offset from \p base where to put the most significant
203  *                  byte of the 16 bits unsigned integer \p n.
204  */
205 #ifndef MBEDTLS_PUT_UINT16_BE
206 #define MBEDTLS_PUT_UINT16_BE( n, data, offset )                \
207 {                                                               \
208     ( data )[( offset )    ] = MBEDTLS_BYTE_1( n );             \
209     ( data )[( offset ) + 1] = MBEDTLS_BYTE_0( n );             \
210 }
211 #endif
212 
213 /**
214  * Get the unsigned 64 bits integer corresponding to eight bytes in
215  * big-endian order (MSB first).
216  *
217  * \param   data    Base address of the memory to get the eight bytes from.
218  * \param   offset  Offset from \p base of the first and most significant
219  *                  byte of the eight bytes to build the 64 bits unsigned
220  *                  integer from.
221  */
222 #ifndef MBEDTLS_GET_UINT64_BE
223 #define MBEDTLS_GET_UINT64_BE( data, offset )                   \
224     (                                                           \
225           ( (uint64_t) ( data )[( offset )    ] << 56 )         \
226         | ( (uint64_t) ( data )[( offset ) + 1] << 48 )         \
227         | ( (uint64_t) ( data )[( offset ) + 2] << 40 )         \
228         | ( (uint64_t) ( data )[( offset ) + 3] << 32 )         \
229         | ( (uint64_t) ( data )[( offset ) + 4] << 24 )         \
230         | ( (uint64_t) ( data )[( offset ) + 5] << 16 )         \
231         | ( (uint64_t) ( data )[( offset ) + 6] <<  8 )         \
232         | ( (uint64_t) ( data )[( offset ) + 7]       )         \
233     )
234 #endif
235 
236 /**
237  * Put in memory a 64 bits unsigned integer in big-endian order.
238  *
239  * \param   n       64 bits unsigned integer to put in memory.
240  * \param   data    Base address of the memory where to put the 64
241  *                  bits unsigned integer in.
242  * \param   offset  Offset from \p base where to put the most significant
243  *                  byte of the 64 bits unsigned integer \p n.
244  */
245 #ifndef MBEDTLS_PUT_UINT64_BE
246 #define MBEDTLS_PUT_UINT64_BE( n, data, offset )                \
247 {                                                               \
248     ( data )[( offset )    ] = MBEDTLS_BYTE_7( n );             \
249     ( data )[( offset ) + 1] = MBEDTLS_BYTE_6( n );             \
250     ( data )[( offset ) + 2] = MBEDTLS_BYTE_5( n );             \
251     ( data )[( offset ) + 3] = MBEDTLS_BYTE_4( n );             \
252     ( data )[( offset ) + 4] = MBEDTLS_BYTE_3( n );             \
253     ( data )[( offset ) + 5] = MBEDTLS_BYTE_2( n );             \
254     ( data )[( offset ) + 6] = MBEDTLS_BYTE_1( n );             \
255     ( data )[( offset ) + 7] = MBEDTLS_BYTE_0( n );             \
256 }
257 #endif
258 
259 /**
260  * Get the unsigned 64 bits integer corresponding to eight bytes in
261  * little-endian order (LSB first).
262  *
263  * \param   data    Base address of the memory to get the eight bytes from.
264  * \param   offset  Offset from \p base of the first and least significant
265  *                  byte of the eight bytes to build the 64 bits unsigned
266  *                  integer from.
267  */
268 #ifndef MBEDTLS_GET_UINT64_LE
269 #define MBEDTLS_GET_UINT64_LE( data, offset )                   \
270     (                                                           \
271           ( (uint64_t) ( data )[( offset ) + 7] << 56 )         \
272         | ( (uint64_t) ( data )[( offset ) + 6] << 48 )         \
273         | ( (uint64_t) ( data )[( offset ) + 5] << 40 )         \
274         | ( (uint64_t) ( data )[( offset ) + 4] << 32 )         \
275         | ( (uint64_t) ( data )[( offset ) + 3] << 24 )         \
276         | ( (uint64_t) ( data )[( offset ) + 2] << 16 )         \
277         | ( (uint64_t) ( data )[( offset ) + 1] <<  8 )         \
278         | ( (uint64_t) ( data )[( offset )    ]       )         \
279     )
280 #endif
281 
282 /**
283  * Put in memory a 64 bits unsigned integer in little-endian order.
284  *
285  * \param   n       64 bits unsigned integer to put in memory.
286  * \param   data    Base address of the memory where to put the 64
287  *                  bits unsigned integer in.
288  * \param   offset  Offset from \p base where to put the least significant
289  *                  byte of the 64 bits unsigned integer \p n.
290  */
291 #ifndef MBEDTLS_PUT_UINT64_LE
292 #define MBEDTLS_PUT_UINT64_LE( n, data, offset )                \
293 {                                                               \
294     ( data )[( offset )    ] = MBEDTLS_BYTE_0( n );             \
295     ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n );             \
296     ( data )[( offset ) + 2] = MBEDTLS_BYTE_2( n );             \
297     ( data )[( offset ) + 3] = MBEDTLS_BYTE_3( n );             \
298     ( data )[( offset ) + 4] = MBEDTLS_BYTE_4( n );             \
299     ( data )[( offset ) + 5] = MBEDTLS_BYTE_5( n );             \
300     ( data )[( offset ) + 6] = MBEDTLS_BYTE_6( n );             \
301     ( data )[( offset ) + 7] = MBEDTLS_BYTE_7( n );             \
302 }
303 #endif
304 
305 #endif /* MBEDTLS_LIBRARY_COMMON_H */
306