blob: 31d877cdf14926a878540765eebe7b8152d937ad [file] [log] [blame]
Dave Rodgmanfb5fedc2022-11-30 15:20:33 +00001/* BEGIN_HEADER */
2#include "../library/alignment.h"
3
4#include <stdint.h>
5/* END_HEADER */
6
7/* BEGIN_CASE */
8void mbedtls_unaligned_access( int size, int offset )
9{
10 /* Define 64-bit aligned raw byte array */
11 uint64_t raw[2];
12
13 /* Populate with known data */
14 uint8_t *x = (uint8_t *) raw;
15 for ( size_t i = 0; i < sizeof(raw); i++ )
16 x[i] = (uint8_t)i;
17
18 TEST_ASSERT( size == 16 || size == 32 || size == 64 );
19
20 uint64_t r = 0;
21 switch ( size )
22 {
23 case 16:
24 r = mbedtls_get_unaligned_uint16( x + offset );
25 break;
26 case 32:
27 r = mbedtls_get_unaligned_uint32( x + offset );
28 break;
29 case 64:
30 r = mbedtls_get_unaligned_uint64( x + offset );
31 break;
32 }
33
34 /* Generate expected result */
35 uint64_t expected = 0;
36 for ( uint8_t i = 0; i < 8; i++ )
37 {
38 uint8_t shift;
39 if ( MBEDTLS_IS_BIG_ENDIAN )
40 {
41 /*
42 * Similar to little-endian case described below, but the shift needs
43 * to be inverted
44 */
45 shift = 7 - ( i * 8 );
46 } else {
47 /* example for offset == 1:
48 * expected = (( 1 + 0 ) << (0 * 8)) | (( 1 + 1 ) << (1 * 8)) | (( 1 + 2 ) << (2 * 8)))
49 * = (1 << 0) | (2 << 8) | (3 << 16) ...
50 * = 0x0807060504030201
51 * x = { 0, 1, 2, 3, ... }
52 * ie expected is the value that would be read from x on a LE system, when
53 * byte swapping is not performed
54 */
55 shift = i * 8;
56 }
57 uint64_t b = offset + i;
58 expected |= b << shift;
59 }
60
61 /* Mask out excess bits from expected result */
62 switch ( size )
63 {
64 case 16:
65 expected &= 0xffff;
66 break;
67 case 32:
68 expected &= 0xffffffff;
69 break;
70 }
71
72 TEST_EQUAL( r, expected );
73
74 /* Write sentinel to the part of the array we will testing writing to */
75 for ( size_t i = 0; i < (size_t) ( size / 8 ); i++ )
76 {
77 x[i + offset] = 0xff;
78 }
79 /*
80 * Write back to the array with mbedtls_put_unaligned_uint16 and validate
81 * that the array is unchanged as a result.
82 */
83 switch ( size )
84 {
85 case 16:
86 mbedtls_put_unaligned_uint16( x + offset, r );
87 break;
88 case 32:
89 mbedtls_put_unaligned_uint32( x + offset, r );
90 break;
91 case 64:
92 mbedtls_put_unaligned_uint64( x + offset, r );
93 break;
94 }
95 for ( size_t i = 0; i < sizeof(x); i++ )
96 {
97 TEST_EQUAL( x[i], (uint8_t)i );
98 }
99}
100/* END_CASE */
101
102/* BEGIN_CASE */
103void mbedtls_byteswap( unsigned int input_h, unsigned int input_l, int size,
104 unsigned int expected_h, unsigned int expected_l )
105{
106 uint64_t input = ( ((uint64_t)input_h ) << 32 ) | ( (uint64_t)input_l );
107 uint64_t expected = ( ((uint64_t)expected_h) << 32 ) | ( (uint64_t)expected_l );
108
109 /* Check against expected */
110 uint64_t r;
111 switch ( size )
112 {
113 case 16:
114 r = MBEDTLS_BSWAP16( input );
115 break;
116 case 32:
117 r = MBEDTLS_BSWAP32( input );
118 break;
119 case 64:
120 r = MBEDTLS_BSWAP64( input );
121 break;
122 }
123 TEST_EQUAL( r, expected );
124
125 /*
126 * Check byte by byte by extracting bytes from opposite ends of
127 * input and r.
128 */
129 for ( size_t i = 0; i < (size_t)( size / 8 ); i++ )
130 {
131 size_t s1 = i * 8;
132 size_t s2 = ( ( size / 8 - 1 ) - i ) * 8;
133 uint64_t a = ( input & ( (uint64_t)0xff << s1 ) ) >> s1;
134 uint64_t b = ( r & ( (uint64_t)0xff << s2 ) ) >> s2;
135 TEST_EQUAL( a, b );
136 }
137
138 /* Check BSWAP(BSWAP(x)) == x */
139 switch ( size )
140 {
141 case 16:
142 r = MBEDTLS_BSWAP16( r );
143 TEST_EQUAL( r, input & 0xffff );
144 break;
145 case 32:
146 r = MBEDTLS_BSWAP32( r );
147 TEST_EQUAL( r, input & 0xffffffff );
148 break;
149 case 64:
150 r = MBEDTLS_BSWAP64( r );
151 TEST_EQUAL( r, input );
152 break;
153 }
154}
155/* END_CASE */
156
157/* BEGIN_CASE */
158void get_byte()
159{
160 uint8_t data[16];
161
162 for ( size_t i = 0; i < sizeof(data); i++ )
163 data[i] = (uint8_t) i;
164
165 uint64_t u64 = 0x0706050403020100;
166 for ( size_t b = 0; b < 8 ; b++ )
167 {
168 uint8_t actual;
169 switch ( b )
170 {
171 case 0:
172 actual = MBEDTLS_BYTE_0( u64 );
173 break;
174 case 1:
175 actual = MBEDTLS_BYTE_1( u64 );
176 break;
177 case 2:
178 actual = MBEDTLS_BYTE_2( u64 );
179 break;
180 case 3:
181 actual = MBEDTLS_BYTE_3( u64 );
182 break;
183 case 4:
184 actual = MBEDTLS_BYTE_4( u64 );
185 break;
186 case 5:
187 actual = MBEDTLS_BYTE_5( u64 );
188 break;
189 case 6:
190 actual = MBEDTLS_BYTE_6( u64 );
191 break;
192 case 7:
193 actual = MBEDTLS_BYTE_7( u64 );
194 break;
195 }
196 uint8_t expected = b;
197 TEST_EQUAL( actual, expected );
198 }
199
200 uint32_t u32 = 0x03020100;
201 for ( size_t b = 0; b < 4 ; b++ )
202 {
203 uint8_t actual;
204 switch ( b )
205 {
206 case 0:
207 actual = MBEDTLS_BYTE_0( u32 );
208 break;
209 case 1:
210 actual = MBEDTLS_BYTE_1( u32 );
211 break;
212 case 2:
213 actual = MBEDTLS_BYTE_2( u32 );
214 break;
215 case 3:
216 actual = MBEDTLS_BYTE_3( u32 );
217 break;
218 }
219 uint8_t expected = b;
220 TEST_EQUAL( actual, expected );
221 }
222
223 uint16_t u16 = 0x0100;
224 for ( size_t b = 0; b < 2 ; b++ )
225 {
226 uint8_t actual;
227 switch ( b )
228 {
229 case 0:
230 actual = MBEDTLS_BYTE_0( u16 );
231 break;
232 case 1:
233 actual = MBEDTLS_BYTE_1( u16 );
234 break;
235 }
236 uint8_t expected = b;
237 TEST_EQUAL( actual, expected );
238 }
239
240 uint8_t u8 = 0x01;
241 uint8_t actual = MBEDTLS_BYTE_0( u8 );
242 TEST_EQUAL( actual, u8 );
243}
244/* END_CASE */
245
246/* BEGIN_CASE */
247void unaligned_access_endian_aware(int size, int offset, int big_endian )
248{
249 TEST_ASSERT( size == 16 || size == 24 || size == 32 || size == 64 );
250 TEST_ASSERT( offset >= 0 && offset < 8 );
251
252 /* Define 64-bit aligned raw byte array */
253 uint64_t raw[2];
254 /* Populate with known data: x == { 0, 1, 2, ... } */
255 uint8_t *x = (uint8_t *) raw;
256 for ( size_t i = 0; i < sizeof(raw); i++ )
257 x[i] = (uint8_t) i;
258
259 uint64_t read;
260 if ( big_endian )
261 {
262 switch ( size )
263 {
264 case 16:
265 read = MBEDTLS_GET_UINT16_BE( x, offset );
266 break;
267 case 24:
268 read = MBEDTLS_GET_UINT24_BE( x, offset );
269 break;
270 case 32:
271 read = MBEDTLS_GET_UINT32_BE( x, offset );
272 break;
273 case 64:
274 read = MBEDTLS_GET_UINT64_BE( x, offset );
275 break;
276 }
277 }
278 else
279 {
280 switch ( size )
281 {
282 case 16:
283 read = MBEDTLS_GET_UINT16_LE( x, offset );
284 break;
285 case 24:
286 read = MBEDTLS_GET_UINT24_LE( x, offset );
287 break;
288 case 32:
289 read = MBEDTLS_GET_UINT32_LE( x, offset );
290 break;
291 case 64:
292 read = MBEDTLS_GET_UINT64_LE( x, offset );
293 break;
294 }
295 }
296
297 /* Build up expected value byte by byte, in either big or little endian format */
298 uint64_t expected = 0;
299 for ( size_t i = 0; i < (size_t)(size / 8); i++ )
300 {
301 uint64_t b = x[i + offset];
302 uint8_t shift = (big_endian) ? (8 * ((size / 8 - 1) - i)) : (8 * i);
303 expected |= b << shift;
304 }
305
306 /* Verify read */
307 TEST_EQUAL( read, expected );
308
309 /* Test writing back to memory. First write sentiel */
310 for ( size_t i = 0; i < (size_t)(size / 8); i++ )
311 {
312 x[i + offset] = 0xff;
313 }
314 /* Overwrite sentinel with endian-aware write macro */
315 if ( big_endian )
316 {
317 switch ( size )
318 {
319 case 16:
320 MBEDTLS_PUT_UINT16_BE( read, x, offset );
321 break;
322 case 24:
323 MBEDTLS_PUT_UINT24_BE( read, x, offset );
324 break;
325 case 32:
326 MBEDTLS_PUT_UINT32_BE( read, x, offset );
327 break;
328 case 64:
329 MBEDTLS_PUT_UINT64_BE( read, x, offset );
330 break;
331 }
332 }
333 else
334 {
335 switch ( size )
336 {
337 case 16:
338 MBEDTLS_PUT_UINT16_LE( read, x, offset );
339 break;
340 case 24:
341 MBEDTLS_PUT_UINT24_LE( read, x, offset );
342 break;
343 case 32:
344 MBEDTLS_PUT_UINT32_LE( read, x, offset );
345 break;
346 case 64:
347 MBEDTLS_PUT_UINT64_LE( read, x, offset );
348 break;
349 }
350 }
351
352 /* Verify write - check memory is correct */
353 for ( size_t i = 0; i < sizeof(raw); i++ )
354 TEST_EQUAL( x[i], (uint8_t) i );
355}
356/* END_CASE */
357
358/* BEGIN_CASE */
359void mbedtls_is_big_endian()
360{
361 uint16_t check = 0x1234;
362 uint8_t* p = (uint8_t*) &check;
363
364 if ( MBEDTLS_IS_BIG_ENDIAN )
365 {
366 /* Big-endian: data stored MSB first, i.e. p == { 0x12, 0x34 } */
367 TEST_EQUAL( p[0], 0x12 );
368 TEST_EQUAL( p[1], 0x34 );
369 }
370 else
371 {
372 /* Little-endian: data stored LSB first, i.e. p == { 0x34, 0x12 } */
373 TEST_EQUAL( p[0], 0x34 );
374 TEST_EQUAL( p[1], 0x12 );
375 }
376}
377/* END_CASE */