From c3d8041fe7d5dd189ab0bd7bf96d8261b062a238 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 22 Nov 2022 15:01:39 +0000 Subject: [PATCH 01/40] Introduce mbedtls_xor Signed-off-by: Dave Rodgman --- library/common.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/library/common.h b/library/common.h index a630fcc456..d1af48eb28 100644 --- a/library/common.h +++ b/library/common.h @@ -26,6 +26,7 @@ #include "mbedtls/build_info.h" #include +#include /** Helper to define a function as static except when building invasive tests. * @@ -390,6 +391,32 @@ extern void (*mbedtls_test_hook_test_fail)( const char * test, int line, const c } #endif +/** + * Perform a fast block XOR operation, such that + * r[i] = a[i] ^ b[i] where 0 <= i < n + * + * \param r Pointer to result (buffer of at least \p n bytes). \p r + * may be equal to either \p a or \p b, but behaviour when + * it overlaps in other ways is undefined. + * \param a Pointer to input (buffer of at least \p n bytes) + * \param b Pointer to input (buffer of at least \p n bytes) + * \param n Number of bytes to process. + */ +static inline void mbedtls_xor( unsigned char* r, unsigned char const *a, unsigned char const *b, size_t n ) +{ + uint32_t *a32 = (uint32_t*)a; + uint32_t *b32 = (uint32_t*)b; + uint32_t *r32 = (uint32_t*)r; + for ( size_t i = 0; i < (n >> 2); i++ ) + { + r32[i] = a32[i] ^ b32[i]; + } + for ( size_t i = n - (n % 4) ; i < n; i++ ) + { + r[i] = a[i] ^ b[i]; + } +} + /* Fix MSVC C99 compatible issue * MSVC support __func__ from visual studio 2015( 1900 ) * Use MSVC predefine macro to avoid name check fail. From 4413b6690f00621313cee70601e68be76ddebd13 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 22 Nov 2022 17:31:50 +0000 Subject: [PATCH 02/40] Add tests for mbedtls_xor Signed-off-by: Dave Rodgman --- tests/suites/test_suite_common.data | 20 +++++++ tests/suites/test_suite_common.function | 76 +++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 tests/suites/test_suite_common.data create mode 100644 tests/suites/test_suite_common.function diff --git a/tests/suites/test_suite_common.data b/tests/suites/test_suite_common.data new file mode 100644 index 0000000000..500852d540 --- /dev/null +++ b/tests/suites/test_suite_common.data @@ -0,0 +1,20 @@ +Block xor, length 0 +mbedtls_xor:0 + +Block xor, length 1 +mbedtls_xor:1 + +Block xor, length 3 +mbedtls_xor:3 + +Block xor, length 4 +mbedtls_xor:4 + +Block xor, length 7 +mbedtls_xor:7 + +Block xor, length 8 +mbedtls_xor:8 + +Block xor, length 16 +mbedtls_xor:16 diff --git a/tests/suites/test_suite_common.function b/tests/suites/test_suite_common.function new file mode 100644 index 0000000000..17eae27c4b --- /dev/null +++ b/tests/suites/test_suite_common.function @@ -0,0 +1,76 @@ +/* BEGIN_HEADER */ +#include "../library/common.h" + +void fill_arrays( unsigned char *a, unsigned char *b, unsigned char *r1, unsigned char *r2, size_t n ) +{ + for ( size_t i = 0; i < n; i++ ) + { + a[i] = (unsigned char) i * 3; + b[i] = (unsigned char) i * 3 + 1; + r1[i] = (unsigned char) i * 3 + 2; + r2[i] = r1[i]; + } +} +/* END_HEADER */ + +/* BEGIN_CASE */ +void mbedtls_xor( int len ) +{ + size_t n = (size_t) len; + unsigned char *a = NULL, *b = NULL, *r1 = NULL, *r2 = NULL; + ASSERT_ALLOC( a, n ); + ASSERT_ALLOC( b, n ); + ASSERT_ALLOC( r1, n ); + ASSERT_ALLOC( r2, n ); + + /* Test non-overlapping */ + fill_arrays( a, b, r1, r2, n ); + for ( size_t i = 0; i < n; i++ ) + { + r1[i] = a[i] ^ b[i]; + } + mbedtls_xor( r2, a, b, n ); + ASSERT_COMPARE( r1, n, r2, n ); + + /* Test r == a */ + fill_arrays( a, b, r1, r2, n ); + for ( size_t i = 0; i < n; i++ ) + { + r1[i] = r1[i] ^ b[i]; + } + mbedtls_xor( r2, r2, b, n ); + ASSERT_COMPARE( r1, n, r2, n ); + + /* Test r == b */ + fill_arrays( a, b, r1, r2, n ); + for ( size_t i = 0; i < n; i++ ) + { + r1[i] = a[i] ^ r1[i]; + } + mbedtls_xor( r2, a, r2, n ); + ASSERT_COMPARE( r1, n, r2, n ); + + /* Test a == b */ + fill_arrays( a, b, r1, r2, n ); + for ( size_t i = 0; i < n; i++ ) + { + r1[i] = a[i] ^ a[i]; + } + mbedtls_xor( r2, a, a, n ); + ASSERT_COMPARE( r1, n, r2, n ); + + /* Test a == b == r */ + fill_arrays( a, b, r1, r2, n ); + for ( size_t i = 0; i < n; i++ ) + { + r1[i] = r1[i] ^ r1[i]; + } + mbedtls_xor( r2, r2, r2, n ); + ASSERT_COMPARE( r1, n, r2, n ); +exit: + if ( a != NULL ) mbedtls_free( a ); + if ( a != NULL ) mbedtls_free( b ); + if ( r1 != NULL ) mbedtls_free( r1 ); + if ( r2 != NULL ) mbedtls_free( r2 ); +} +/* END_CASE */ From a8cf607458dfda284ceaabdf033e5a7a99a45807 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 22 Nov 2022 15:02:54 +0000 Subject: [PATCH 03/40] Use mbedtls_xor in AES Signed-off-by: Dave Rodgman --- library/aes.c | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/library/aes.c b/library/aes.c index 7d035246f7..4f7c888599 100644 --- a/library/aes.c +++ b/library/aes.c @@ -978,7 +978,6 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, const unsigned char *input, unsigned char *output ) { - int i; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char temp[16]; @@ -1009,8 +1008,7 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, if( ret != 0 ) goto exit; - for( i = 0; i < 16; i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); + mbedtls_xor( output, output, iv, 16 ); memcpy( iv, temp, 16 ); @@ -1023,8 +1021,7 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, { while( length > 0 ) { - for( i = 0; i < 16; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); + mbedtls_xor( output, input, iv, 16 ); ret = mbedtls_aes_crypt_ecb( ctx, mode, output, output ); if( ret != 0 ) @@ -1106,8 +1103,6 @@ int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, while( blocks-- ) { - size_t i; - if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 ) { /* We are on the last block in a decrypt operation that has @@ -1119,15 +1114,13 @@ int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, mbedtls_gf128mul_x_ble( tweak, tweak ); } - for( i = 0; i < 16; i++ ) - tmp[i] = input[i] ^ tweak[i]; + mbedtls_xor( tmp, input, tweak, 16 ); ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp ); if( ret != 0 ) return( ret ); - for( i = 0; i < 16; i++ ) - output[i] = tmp[i] ^ tweak[i]; + mbedtls_xor( output, tmp, tweak, 16 ); /* Update the tweak for the next block. */ mbedtls_gf128mul_x_ble( tweak, tweak ); @@ -1147,20 +1140,19 @@ int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, size_t i; unsigned char *prev_output = output - 16; - /* Copy ciphertext bytes from the previous block to our output for each - * byte of ciphertext we won't steal. At the same time, copy the - * remainder of the input for this final round (since the loop bounds - * are the same). */ + /* Copy the remainder of the input for this final round. */ for( i = 0; i < leftover; i++ ) { output[i] = prev_output[i]; - tmp[i] = input[i] ^ t[i]; } + /* Copy ciphertext bytes from the previous block to our output for each + * byte of ciphertext we won't steal. */ + mbedtls_xor( tmp, input, t, leftover ); + /* Copy ciphertext bytes from the previous block for input in this * round. */ - for( ; i < 16; i++ ) - tmp[i] = prev_output[i] ^ t[i]; + mbedtls_xor( tmp + i, prev_output + i, t + i, 16 - i ); ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp ); if( ret != 0 ) @@ -1168,8 +1160,7 @@ int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, /* Write the result back to the previous block, overriding the previous * output we copied. */ - for( i = 0; i < 16; i++ ) - prev_output[i] = tmp[i] ^ t[i]; + mbedtls_xor( prev_output, tmp, t, 16 ); } return( 0 ); From 7bb6b84b293d7c621dc7a3f15bc1b13976bcf912 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 22 Nov 2022 16:18:55 +0000 Subject: [PATCH 04/40] Use mbedtls_xor in ARIA Signed-off-by: Dave Rodgman --- library/aria.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/library/aria.c b/library/aria.c index 924f952834..a1876b7763 100644 --- a/library/aria.c +++ b/library/aria.c @@ -588,7 +588,6 @@ int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx, const unsigned char *input, unsigned char *output ) { - int i; unsigned char temp[MBEDTLS_ARIA_BLOCKSIZE]; ARIA_VALIDATE_RET( ctx != NULL ); @@ -608,8 +607,7 @@ int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx, memcpy( temp, input, MBEDTLS_ARIA_BLOCKSIZE ); mbedtls_aria_crypt_ecb( ctx, input, output ); - for( i = 0; i < MBEDTLS_ARIA_BLOCKSIZE; i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); + mbedtls_xor( output, output, iv, MBEDTLS_ARIA_BLOCKSIZE ); memcpy( iv, temp, MBEDTLS_ARIA_BLOCKSIZE ); @@ -622,8 +620,7 @@ int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx, { while( length > 0 ) { - for( i = 0; i < MBEDTLS_ARIA_BLOCKSIZE; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); + mbedtls_xor( output, input, iv, MBEDTLS_ARIA_BLOCKSIZE ); mbedtls_aria_crypt_ecb( ctx, output, output ); memcpy( iv, output, MBEDTLS_ARIA_BLOCKSIZE ); From d23399eb699f2533f62779ac629b943c99a4c479 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 22 Nov 2022 16:23:11 +0000 Subject: [PATCH 05/40] Use mbedtls_xor in Camellia Signed-off-by: Dave Rodgman --- library/camellia.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/library/camellia.c b/library/camellia.c index 5dd6c56157..6e781c72b8 100644 --- a/library/camellia.c +++ b/library/camellia.c @@ -526,7 +526,6 @@ int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx, const unsigned char *input, unsigned char *output ) { - int i; unsigned char temp[16]; if( mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT ) return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA; @@ -541,8 +540,7 @@ int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx, memcpy( temp, input, 16 ); mbedtls_camellia_crypt_ecb( ctx, mode, input, output ); - for( i = 0; i < 16; i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); + mbedtls_xor( output, output, iv, 16 ); memcpy( iv, temp, 16 ); @@ -555,8 +553,7 @@ int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx, { while( length > 0 ) { - for( i = 0; i < 16; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); + mbedtls_xor( output, input, iv, 16 ); mbedtls_camellia_crypt_ecb( ctx, mode, output, output ); memcpy( iv, output, 16 ); From 0d3b55bca8c3325f8c00ae558a0e8e63c34bd91d Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 22 Nov 2022 16:30:35 +0000 Subject: [PATCH 06/40] Use mbedtls_xor in ccm Signed-off-by: Dave Rodgman --- library/ccm.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/library/ccm.c b/library/ccm.c index 3edfba3669..7bf9e9f5fd 100644 --- a/library/ccm.c +++ b/library/ccm.c @@ -112,7 +112,6 @@ static int mbedtls_ccm_crypt( mbedtls_ccm_context *ctx, const unsigned char *input, unsigned char *output ) { - size_t i; size_t olen = 0; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char tmp_buf[16] = {0}; @@ -125,8 +124,7 @@ static int mbedtls_ccm_crypt( mbedtls_ccm_context *ctx, return ret; } - for( i = 0; i < use_len; i++ ) - output[i] = input[i] ^ tmp_buf[offset + i]; + mbedtls_xor( output, input, tmp_buf + offset, use_len ); mbedtls_platform_zeroize(tmp_buf, sizeof(tmp_buf)); return ret; @@ -269,7 +267,6 @@ int mbedtls_ccm_update_ad( mbedtls_ccm_context *ctx, size_t add_len ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char i; size_t olen, use_len, offset; if( ctx->state & CCM_STATE__ERROR ) @@ -310,8 +307,7 @@ int mbedtls_ccm_update_ad( mbedtls_ccm_context *ctx, if( use_len > add_len ) use_len = add_len; - for( i = 0; i < use_len; i++ ) - ctx->y[i + offset] ^= add[i]; + mbedtls_xor( ctx->y + offset, ctx->y + offset, add, use_len ); ctx->processed += use_len; add_len -= use_len; @@ -381,8 +377,7 @@ int mbedtls_ccm_update( mbedtls_ccm_context *ctx, if( ctx->mode == MBEDTLS_CCM_ENCRYPT || \ ctx->mode == MBEDTLS_CCM_STAR_ENCRYPT ) { - for( i = 0; i < use_len; i++ ) - ctx->y[i + offset] ^= input[i]; + mbedtls_xor( ctx->y + offset, ctx->y + offset, input, use_len ); if( use_len + offset == 16 || ctx->processed == ctx->plaintext_len ) { @@ -411,8 +406,7 @@ int mbedtls_ccm_update( mbedtls_ccm_context *ctx, if( ret != 0 ) goto exit; - for( i = 0; i < use_len; i++ ) - ctx->y[i + offset] ^= local_output[i]; + mbedtls_xor( ctx->y + offset, ctx->y + offset, local_output, use_len ); memcpy( output, local_output, use_len ); mbedtls_platform_zeroize( local_output, 16 ); From c1d9022bab918ff4b9791759e726a374ce802ea8 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 22 Nov 2022 16:35:42 +0000 Subject: [PATCH 07/40] Use mbedtls_xor in ChaCha20 Signed-off-by: Dave Rodgman --- library/chacha20.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/library/chacha20.c b/library/chacha20.c index e53eb82f54..28751043ab 100644 --- a/library/chacha20.c +++ b/library/chacha20.c @@ -222,7 +222,6 @@ int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, unsigned char *output ) { size_t offset = 0U; - size_t i; /* Use leftover keystream bytes, if available */ while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES ) @@ -242,17 +241,7 @@ int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, chacha20_block( ctx->state, ctx->keystream8 ); ctx->state[CHACHA20_CTR_INDEX]++; - for( i = 0U; i < 64U; i += 8U ) - { - output[offset + i ] = input[offset + i ] ^ ctx->keystream8[i ]; - output[offset + i+1] = input[offset + i+1] ^ ctx->keystream8[i+1]; - output[offset + i+2] = input[offset + i+2] ^ ctx->keystream8[i+2]; - output[offset + i+3] = input[offset + i+3] ^ ctx->keystream8[i+3]; - output[offset + i+4] = input[offset + i+4] ^ ctx->keystream8[i+4]; - output[offset + i+5] = input[offset + i+5] ^ ctx->keystream8[i+5]; - output[offset + i+6] = input[offset + i+6] ^ ctx->keystream8[i+6]; - output[offset + i+7] = input[offset + i+7] ^ ctx->keystream8[i+7]; - } + mbedtls_xor( output + offset, input + offset, ctx->keystream8, 64U ); offset += CHACHA20_BLOCK_SIZE_BYTES; size -= CHACHA20_BLOCK_SIZE_BYTES; @@ -265,10 +254,7 @@ int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, chacha20_block( ctx->state, ctx->keystream8 ); ctx->state[CHACHA20_CTR_INDEX]++; - for( i = 0U; i < size; i++) - { - output[offset + i] = input[offset + i] ^ ctx->keystream8[i]; - } + mbedtls_xor( output + offset, input + offset, ctx->keystream8, size ); ctx->keystream_bytes_used = size; From 8c0ff81ce713f84f6c70c92195d0a06a8bea442b Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 22 Nov 2022 16:38:44 +0000 Subject: [PATCH 08/40] Use mbedtls_xor in CMAC Signed-off-by: Dave Rodgman --- library/cmac.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/library/cmac.c b/library/cmac.c index 3cc49d10cc..9870856861 100644 --- a/library/cmac.c +++ b/library/cmac.c @@ -148,15 +148,6 @@ exit: #endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */ #if !defined(MBEDTLS_CMAC_ALT) -static void cmac_xor_block( unsigned char *output, const unsigned char *input1, - const unsigned char *input2, - const size_t block_size ) -{ - size_t idx; - - for( idx = 0; idx < block_size; idx++ ) - output[ idx ] = input1[ idx ] ^ input2[ idx ]; -} /* * Create padded last block from (partial) last block. @@ -247,7 +238,7 @@ int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx, input, block_size - cmac_ctx->unprocessed_len ); - cmac_xor_block( state, cmac_ctx->unprocessed_block, state, block_size ); + mbedtls_xor( state, cmac_ctx->unprocessed_block, state, block_size ); if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state, &olen ) ) != 0 ) @@ -267,7 +258,7 @@ int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx, * final partial or complete block */ for( j = 1; j < n; j++ ) { - cmac_xor_block( state, input, state, block_size ); + mbedtls_xor( state, input, state, block_size ); if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state, &olen ) ) != 0 ) @@ -319,16 +310,16 @@ int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx, if( cmac_ctx->unprocessed_len < block_size ) { cmac_pad( M_last, block_size, last_block, cmac_ctx->unprocessed_len ); - cmac_xor_block( M_last, M_last, K2, block_size ); + mbedtls_xor( M_last, M_last, K2, block_size ); } else { /* Last block is complete block */ - cmac_xor_block( M_last, last_block, K1, block_size ); + mbedtls_xor( M_last, last_block, K1, block_size ); } - cmac_xor_block( state, M_last, state, block_size ); + mbedtls_xor( state, M_last, state, block_size ); if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state, &olen ) ) != 0 ) { From ffb5499988f7a2cd1d908a7c542e3daad22d72c7 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 22 Nov 2022 16:40:58 +0000 Subject: [PATCH 09/40] Use mbedtls_xor in CTR_DRBG Signed-off-by: Dave Rodgman --- library/ctr_drbg.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c index 71c48afd28..f5c5e7b612 100644 --- a/library/ctr_drbg.c +++ b/library/ctr_drbg.c @@ -174,8 +174,7 @@ static int block_cipher_df( unsigned char *output, while( use_len > 0 ) { - for( i = 0; i < MBEDTLS_CTR_DRBG_BLOCKSIZE; i++ ) - chain[i] ^= p[i]; + mbedtls_xor( chain, chain, p, MBEDTLS_CTR_DRBG_BLOCKSIZE ); p += MBEDTLS_CTR_DRBG_BLOCKSIZE; use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len; From 2e9db8e9bf54f734c441cd07b10b880cfcb2f7da Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 22 Nov 2022 16:43:29 +0000 Subject: [PATCH 10/40] Use mbedtls_xor in DES Signed-off-by: Dave Rodgman --- library/des.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/library/des.c b/library/des.c index 65f5681cf1..c56d4d4fe3 100644 --- a/library/des.c +++ b/library/des.c @@ -635,7 +635,6 @@ int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx, const unsigned char *input, unsigned char *output ) { - int i; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char temp[8]; @@ -646,8 +645,7 @@ int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx, { while( length > 0 ) { - for( i = 0; i < 8; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); + mbedtls_xor( output, input, iv, 8 ); ret = mbedtls_des_crypt_ecb( ctx, output, output ); if( ret != 0 ) @@ -668,8 +666,7 @@ int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx, if( ret != 0 ) goto exit; - for( i = 0; i < 8; i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); + mbedtls_xor( output, output, iv, 8 ); memcpy( iv, temp, 8 ); @@ -741,7 +738,6 @@ int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx, const unsigned char *input, unsigned char *output ) { - int i; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char temp[8]; @@ -752,8 +748,7 @@ int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx, { while( length > 0 ) { - for( i = 0; i < 8; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); + mbedtls_xor( output, input, iv, 8 ); ret = mbedtls_des3_crypt_ecb( ctx, output, output ); if( ret != 0 ) @@ -774,8 +769,7 @@ int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx, if( ret != 0 ) goto exit; - for( i = 0; i < 8; i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); + mbedtls_xor( output, output, iv, 8 ); memcpy( iv, temp, 8 ); From d22fb73e3ed52812e4c474df148064cd4abb9b71 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 22 Nov 2022 16:53:25 +0000 Subject: [PATCH 11/40] Use mbedtls_xor in GCM Signed-off-by: Dave Rodgman --- library/gcm.c | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/library/gcm.c b/library/gcm.c index f004a73c75..0178b5ba75 100644 --- a/library/gcm.c +++ b/library/gcm.c @@ -235,7 +235,6 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char work_buf[16]; - size_t i; const unsigned char *p; size_t use_len, olen = 0; uint64_t iv_bits; @@ -268,8 +267,7 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, { use_len = ( iv_len < 16 ) ? iv_len : 16; - for( i = 0; i < use_len; i++ ) - ctx->y[i] ^= p[i]; + mbedtls_xor( ctx->y, ctx->y, p, use_len ); gcm_mult( ctx, ctx->y, ctx->y ); @@ -277,8 +275,7 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, p += use_len; } - for( i = 0; i < 16; i++ ) - ctx->y[i] ^= work_buf[i]; + mbedtls_xor( ctx->y, ctx->y, work_buf, 16); gcm_mult( ctx, ctx->y, ctx->y ); } @@ -313,7 +310,7 @@ int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx, const unsigned char *add, size_t add_len ) { const unsigned char *p; - size_t use_len, i, offset; + size_t use_len, offset; /* IV is limited to 2^64 bits, so 2^61 bytes */ if( (uint64_t) add_len >> 61 != 0 ) @@ -328,8 +325,7 @@ int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx, if( use_len > add_len ) use_len = add_len; - for( i = 0; i < use_len; i++ ) - ctx->buf[i+offset] ^= p[i]; + mbedtls_xor( ctx->buf + offset, ctx->buf + offset, p, use_len ); if( offset + use_len == 16 ) gcm_mult( ctx, ctx->buf, ctx->buf ); @@ -343,8 +339,7 @@ int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx, while( add_len >= 16 ) { - for( i = 0; i < 16; i++ ) - ctx->buf[i] ^= p[i]; + mbedtls_xor( ctx->buf, ctx->buf, p, 16 ); gcm_mult( ctx, ctx->buf, ctx->buf ); @@ -354,8 +349,7 @@ int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx, if( add_len > 0 ) { - for( i = 0; i < add_len; i++ ) - ctx->buf[i] ^= p[i]; + mbedtls_xor( ctx->buf, ctx->buf, p, add_len ); } return( 0 ); @@ -378,7 +372,6 @@ static int gcm_mask( mbedtls_gcm_context *ctx, const unsigned char *input, unsigned char *output ) { - size_t i; size_t olen = 0; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; @@ -389,14 +382,12 @@ static int gcm_mask( mbedtls_gcm_context *ctx, return( ret ); } - for( i = 0; i < use_len; i++ ) - { - if( ctx->mode == MBEDTLS_GCM_DECRYPT ) - ctx->buf[offset + i] ^= input[i]; - output[i] = ectr[offset + i] ^ input[i]; - if( ctx->mode == MBEDTLS_GCM_ENCRYPT ) - ctx->buf[offset + i] ^= output[i]; - } + if( ctx->mode == MBEDTLS_GCM_DECRYPT ) + mbedtls_xor( ctx->buf + offset, ctx->buf + offset, input, use_len ); + mbedtls_xor( output, ectr + offset, input, use_len ); + if( ctx->mode == MBEDTLS_GCM_ENCRYPT ) + mbedtls_xor( ctx->buf + offset, ctx->buf + offset, output, use_len ); + return( 0 ); } @@ -489,7 +480,6 @@ int mbedtls_gcm_finish( mbedtls_gcm_context *ctx, unsigned char *tag, size_t tag_len ) { unsigned char work_buf[16]; - size_t i; uint64_t orig_len; uint64_t orig_add_len; @@ -524,13 +514,11 @@ int mbedtls_gcm_finish( mbedtls_gcm_context *ctx, MBEDTLS_PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 ); MBEDTLS_PUT_UINT32_BE( ( orig_len ), work_buf, 12 ); - for( i = 0; i < 16; i++ ) - ctx->buf[i] ^= work_buf[i]; + mbedtls_xor( ctx->buf, ctx->buf, work_buf, 16 ); gcm_mult( ctx, ctx->buf, ctx->buf ); - for( i = 0; i < tag_len; i++ ) - tag[i] ^= ctx->buf[i]; + mbedtls_xor( tag, tag, ctx->buf, tag_len ); } return( 0 ); From 99a507ee55e0969ee49c33584f0a6eeaf68c2f4c Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 22 Nov 2022 16:54:54 +0000 Subject: [PATCH 12/40] Use mbedtls_xor in md Signed-off-by: Dave Rodgman --- library/md.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/library/md.c b/library/md.c index 8efcf105b4..9c161a53f5 100644 --- a/library/md.c +++ b/library/md.c @@ -633,7 +633,6 @@ int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char sum[MBEDTLS_MD_MAX_SIZE]; unsigned char *ipad, *opad; - size_t i; if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); @@ -657,11 +656,8 @@ int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, memset( ipad, 0x36, ctx->md_info->block_size ); memset( opad, 0x5C, ctx->md_info->block_size ); - for( i = 0; i < keylen; i++ ) - { - ipad[i] = (unsigned char)( ipad[i] ^ key[i] ); - opad[i] = (unsigned char)( opad[i] ^ key[i] ); - } + mbedtls_xor( ipad, ipad, key, keylen ); + mbedtls_xor( opad, opad, key, keylen ); if( ( ret = mbedtls_md_starts( ctx ) ) != 0 ) goto cleanup; From 74b345f2821231b6a979aa3c19c0d80d377d5bb9 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 22 Nov 2022 16:56:59 +0000 Subject: [PATCH 13/40] Use mbedtls_xor in PKCS #5 Signed-off-by: Dave Rodgman --- library/pkcs5.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/library/pkcs5.c b/library/pkcs5.c index ac5945a114..a6bc1b55c7 100644 --- a/library/pkcs5.c +++ b/library/pkcs5.c @@ -211,7 +211,6 @@ static int pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, uint32_t key_length, unsigned char *output ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - int j; unsigned int i; unsigned char md1[MBEDTLS_MD_MAX_SIZE]; unsigned char work[MBEDTLS_MD_MAX_SIZE]; @@ -263,8 +262,7 @@ static int pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, // U1 xor U2 // - for( j = 0; j < md_size; j++ ) - work[j] ^= md1[j]; + mbedtls_xor( work, work, md1, md_size ); } use_len = ( key_length < md_size ) ? key_length : md_size; @@ -396,8 +394,7 @@ exit: // U1 xor U2 // - for( j = 0; j < md_size; j++ ) - work[j] ^= md1[j]; + mbedtls_xor( work, work, md1, md_size ); } use_len = ( key_length < md_size ) ? key_length : md_size; From c36a56e8907f6295515f7374dd0a1666085ebdad Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 22 Nov 2022 17:00:26 +0000 Subject: [PATCH 14/40] Use mbedtls_xor in TLS messaging layer Signed-off-by: Dave Rodgman --- library/ssl_msg.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/library/ssl_msg.c b/library/ssl_msg.c index dbc6391885..085233c151 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -511,15 +511,12 @@ static void ssl_build_record_nonce( unsigned char *dst_iv, unsigned char const *dynamic_iv, size_t dynamic_iv_len ) { - size_t i; - /* Start with Fixed IV || 0 */ memset( dst_iv, 0, dst_iv_len ); memcpy( dst_iv, fixed_iv, fixed_iv_len ); dst_iv += dst_iv_len - dynamic_iv_len; - for( i = 0; i < dynamic_iv_len; i++ ) - dst_iv[i] ^= dynamic_iv[i]; + mbedtls_xor( dst_iv, dst_iv, dynamic_iv, dynamic_iv_len ); } #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */ From 8c18baf8c1ef8c2ed24981e2298d0e730eaa1e1b Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 22 Nov 2022 18:15:55 +0000 Subject: [PATCH 15/40] Add test for unaligned buffers Signed-off-by: Dave Rodgman --- tests/suites/test_suite_common.function | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/suites/test_suite_common.function b/tests/suites/test_suite_common.function index 17eae27c4b..8412e60f3b 100644 --- a/tests/suites/test_suite_common.function +++ b/tests/suites/test_suite_common.function @@ -18,10 +18,10 @@ void mbedtls_xor( int len ) { size_t n = (size_t) len; unsigned char *a = NULL, *b = NULL, *r1 = NULL, *r2 = NULL; - ASSERT_ALLOC( a, n ); - ASSERT_ALLOC( b, n ); - ASSERT_ALLOC( r1, n ); - ASSERT_ALLOC( r2, n ); + ASSERT_ALLOC( a, n + 1 ); + ASSERT_ALLOC( b, n + 1 ); + ASSERT_ALLOC( r1, n + 1 ); + ASSERT_ALLOC( r2, n + 1 ); /* Test non-overlapping */ fill_arrays( a, b, r1, r2, n ); @@ -67,6 +67,15 @@ void mbedtls_xor( int len ) } mbedtls_xor( r2, r2, r2, n ); ASSERT_COMPARE( r1, n, r2, n ); + + /* Test non-word-aligned buffers */ + fill_arrays( a + 1, b + 1, r1 + 1, r2 + 1, n ); + for ( size_t i = 0; i < n; i++ ) + { + r1[i + 1] = a[i + 1] ^ b[i + 1]; + } + mbedtls_xor( r2 + 1, a + 1, b + 1, n ); + ASSERT_COMPARE( r1 + 1, n, r2 + 1, n ); exit: if ( a != NULL ) mbedtls_free( a ); if ( a != NULL ) mbedtls_free( b ); From fdd967ebdc53c1d3947f3fc145087579e32011ff Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 22 Nov 2022 18:55:17 +0000 Subject: [PATCH 16/40] Detect support for unaligned memory access Signed-off-by: Dave Rodgman --- library/common.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/library/common.h b/library/common.h index d1af48eb28..bcb99f752d 100644 --- a/library/common.h +++ b/library/common.h @@ -69,6 +69,18 @@ extern void (*mbedtls_test_hook_test_fail)( const char * test, int line, const c */ #define MBEDTLS_ALLOW_PRIVATE_ACCESS +/** Detect architectures where unaligned memory accesses are safe and performant. + * + * This list is incomplete. + */ +#if defined(__i386__) || defined(__amd64__) || defined( __x86_64__) \ + || defined(__ARM_FEATURE_UNALIGNED) \ + || defined(__aarch64__) \ + || defined(__ARM_ARCH_8__) || defined(__ARM_ARCH_8A__) || defined(__ARM_ARCH_8M__) \ + || defined(__ARM_ARCH_7A__) +#define MBEDTLS_ALLOW_UNALIGNED_ACCESS +#endif + /** Byte Reading Macros * * Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th @@ -404,6 +416,7 @@ extern void (*mbedtls_test_hook_test_fail)( const char * test, int line, const c */ static inline void mbedtls_xor( unsigned char* r, unsigned char const *a, unsigned char const *b, size_t n ) { +#if defined(MBEDTLS_ALLOW_UNALIGNED_ACCESS) uint32_t *a32 = (uint32_t*)a; uint32_t *b32 = (uint32_t*)b; uint32_t *r32 = (uint32_t*)r; @@ -415,6 +428,12 @@ static inline void mbedtls_xor( unsigned char* r, unsigned char const *a, unsign { r[i] = a[i] ^ b[i]; } +#else + for ( size_t i = 0; i < n; i++ ) + { + r[i] = a[i] ^ b[i]; + } +#endif } /* Fix MSVC C99 compatible issue From f9a1c37bc8dd54d90ea706ed11a73e4b32a3e974 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 23 Nov 2022 14:02:00 +0000 Subject: [PATCH 17/40] Whitespace cleanup Signed-off-by: Dave Rodgman --- library/common.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/common.h b/library/common.h index bcb99f752d..94bf7b9d68 100644 --- a/library/common.h +++ b/library/common.h @@ -417,14 +417,14 @@ extern void (*mbedtls_test_hook_test_fail)( const char * test, int line, const c static inline void mbedtls_xor( unsigned char* r, unsigned char const *a, unsigned char const *b, size_t n ) { #if defined(MBEDTLS_ALLOW_UNALIGNED_ACCESS) - uint32_t *a32 = (uint32_t*)a; - uint32_t *b32 = (uint32_t*)b; - uint32_t *r32 = (uint32_t*)r; - for ( size_t i = 0; i < (n >> 2); i++ ) + uint32_t *a32 = (uint32_t *)a; + uint32_t *b32 = (uint32_t *)b; + uint32_t *r32 = (uint32_t *)r; + for ( size_t i = 0; i < ( n >> 2 ); i++ ) { r32[i] = a32[i] ^ b32[i]; } - for ( size_t i = n - (n % 4) ; i < n; i++ ) + for ( size_t i = n - ( n % 4 ) ; i < n; i++ ) { r[i] = a[i] ^ b[i]; } From 63d114305f1c46fd9cdf1903d7b520fb77a4b655 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 23 Nov 2022 14:03:30 +0000 Subject: [PATCH 18/40] Whitespace cleanup Signed-off-by: Dave Rodgman --- library/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/common.h b/library/common.h index 94bf7b9d68..c3847cdbf6 100644 --- a/library/common.h +++ b/library/common.h @@ -414,7 +414,7 @@ extern void (*mbedtls_test_hook_test_fail)( const char * test, int line, const c * \param b Pointer to input (buffer of at least \p n bytes) * \param n Number of bytes to process. */ -static inline void mbedtls_xor( unsigned char* r, unsigned char const *a, unsigned char const *b, size_t n ) +static inline void mbedtls_xor( unsigned char *r, unsigned char const *a, unsigned char const *b, size_t n ) { #if defined(MBEDTLS_ALLOW_UNALIGNED_ACCESS) uint32_t *a32 = (uint32_t *)a; From 3c8eb7e9909dcfb05523d3c1c21f59687588bbfa Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 23 Nov 2022 14:50:03 +0000 Subject: [PATCH 19/40] Provide external definition of mbedtls_xor Signed-off-by: Dave Rodgman --- library/common.h | 2 +- library/platform_util.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/library/common.h b/library/common.h index c3847cdbf6..e502b5de13 100644 --- a/library/common.h +++ b/library/common.h @@ -414,7 +414,7 @@ extern void (*mbedtls_test_hook_test_fail)( const char * test, int line, const c * \param b Pointer to input (buffer of at least \p n bytes) * \param n Number of bytes to process. */ -static inline void mbedtls_xor( unsigned char *r, unsigned char const *a, unsigned char const *b, size_t n ) +inline void mbedtls_xor( unsigned char *r, unsigned char const *a, unsigned char const *b, size_t n ) { #if defined(MBEDTLS_ALLOW_UNALIGNED_ACCESS) uint32_t *a32 = (uint32_t *)a; diff --git a/library/platform_util.c b/library/platform_util.c index 916a7f444c..8fba664d27 100644 --- a/library/platform_util.c +++ b/library/platform_util.c @@ -143,3 +143,8 @@ struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt, void (*mbedtls_test_hook_test_fail)( const char *, int, const char *); #endif /* MBEDTLS_TEST_HOOKS */ +/* + * Provide an external definition of mbedtls_xor so that the compiler + * has the option to not inline it + */ +extern inline void mbedtls_xor( unsigned char *r, unsigned char const *a, unsigned char const *b, size_t n ); From 15531bc6d2e3c5e68229cd38baf59f382d238c89 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 23 Nov 2022 16:11:04 +0000 Subject: [PATCH 20/40] Test for all alignment combinations Signed-off-by: Dave Rodgman --- tests/suites/test_suite_common.function | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/tests/suites/test_suite_common.function b/tests/suites/test_suite_common.function index 8412e60f3b..6c0d4afc4d 100644 --- a/tests/suites/test_suite_common.function +++ b/tests/suites/test_suite_common.function @@ -68,14 +68,19 @@ void mbedtls_xor( int len ) mbedtls_xor( r2, r2, r2, n ); ASSERT_COMPARE( r1, n, r2, n ); - /* Test non-word-aligned buffers */ - fill_arrays( a + 1, b + 1, r1 + 1, r2 + 1, n ); - for ( size_t i = 0; i < n; i++ ) + /* Test non-word-aligned buffers, for all combinations of alignedness */ + for ( int i = 0; i < 7; i++ ) { - r1[i + 1] = a[i + 1] ^ b[i + 1]; + int r_off = i & 1, a_off = (i & 2) >> 1, b_off = (i & 4) >> 2; + fill_arrays( a, b, r1, r2, n + 1 ); + + for ( size_t i = 0; i < n; i++ ) + { + r1[i + r_off] = a[i + a_off] ^ b[i + b_off]; + } + mbedtls_xor( r2 + r_off, a + a_off, b + b_off, n ); + ASSERT_COMPARE( r1 + r_off, n, r2 + r_off, n ); } - mbedtls_xor( r2 + 1, a + 1, b + 1, n ); - ASSERT_COMPARE( r1 + 1, n, r2 + 1, n ); exit: if ( a != NULL ) mbedtls_free( a ); if ( a != NULL ) mbedtls_free( b ); From 1bab27f9831c3258716d09ef9702dabcb6dca703 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 23 Nov 2022 16:51:59 +0000 Subject: [PATCH 21/40] Prevent unaligned access under ASan builds Signed-off-by: Dave Rodgman --- library/common.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/common.h b/library/common.h index e502b5de13..3925a79ce5 100644 --- a/library/common.h +++ b/library/common.h @@ -73,11 +73,12 @@ extern void (*mbedtls_test_hook_test_fail)( const char * test, int line, const c * * This list is incomplete. */ -#if defined(__i386__) || defined(__amd64__) || defined( __x86_64__) \ +#if (defined(__i386__) || defined(__amd64__) || defined( __x86_64__) \ || defined(__ARM_FEATURE_UNALIGNED) \ || defined(__aarch64__) \ || defined(__ARM_ARCH_8__) || defined(__ARM_ARCH_8A__) || defined(__ARM_ARCH_8M__) \ - || defined(__ARM_ARCH_7A__) + || defined(__ARM_ARCH_7A__)) \ + && (!(defined(__has_feature) && __has_feature(undefined_behavior_sanitizer))) #define MBEDTLS_ALLOW_UNALIGNED_ACCESS #endif From 468df317bfea56a90eaf983b26fa8e9541c04aff Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 23 Nov 2022 16:56:35 +0000 Subject: [PATCH 22/40] Fix MSVC support for inline keyword Signed-off-by: Dave Rodgman --- library/common.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/common.h b/library/common.h index 3925a79ce5..808d13de2a 100644 --- a/library/common.h +++ b/library/common.h @@ -28,6 +28,11 @@ #include #include +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + /** Helper to define a function as static except when building invasive tests. * * If a function is only used inside its own source file and should be From a6778013b4dd7bc3d60d57e0b87aa674d0b0ea76 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 23 Nov 2022 17:16:57 +0000 Subject: [PATCH 23/40] Tidy up UBSan detection Signed-off-by: Dave Rodgman --- library/common.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/library/common.h b/library/common.h index 808d13de2a..49c5826aa1 100644 --- a/library/common.h +++ b/library/common.h @@ -78,12 +78,17 @@ extern void (*mbedtls_test_hook_test_fail)( const char * test, int line, const c * * This list is incomplete. */ +#if defined(__has_feature) +#if __has_feature(undefined_behavior_sanitizer) +#define MBEDTLS_HAVE_UBSAN +#endif +#endif + #if (defined(__i386__) || defined(__amd64__) || defined( __x86_64__) \ || defined(__ARM_FEATURE_UNALIGNED) \ || defined(__aarch64__) \ || defined(__ARM_ARCH_8__) || defined(__ARM_ARCH_8A__) || defined(__ARM_ARCH_8M__) \ - || defined(__ARM_ARCH_7A__)) \ - && (!(defined(__has_feature) && __has_feature(undefined_behavior_sanitizer))) + || defined(__ARM_ARCH_7A__)) && !defined(MBEDTLS_HAVE_UBSAN) #define MBEDTLS_ALLOW_UNALIGNED_ACCESS #endif From e7cd137606437755acf6e2236d1913bf0efaee35 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 23 Nov 2022 19:14:26 +0000 Subject: [PATCH 24/40] Define UNALIGNED_UINT32_PTR for unaligned access Signed-off-by: Dave Rodgman --- library/common.h | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/library/common.h b/library/common.h index 49c5826aa1..75d28ff1f2 100644 --- a/library/common.h +++ b/library/common.h @@ -74,22 +74,29 @@ extern void (*mbedtls_test_hook_test_fail)( const char * test, int line, const c */ #define MBEDTLS_ALLOW_PRIVATE_ACCESS -/** Detect architectures where unaligned memory accesses are safe and performant. +/** MBEDTLS_ALLOW_UNALIGNED_ACCESS is defined for architectures where unaligned + * memory accesses are safe and performant. + * + * Unaligned accesses must be made via the UNALIGNED_UINT32_PTR type + * defined here. * * This list is incomplete. */ -#if defined(__has_feature) -#if __has_feature(undefined_behavior_sanitizer) -#define MBEDTLS_HAVE_UBSAN -#endif -#endif - -#if (defined(__i386__) || defined(__amd64__) || defined( __x86_64__) \ +#if defined(__i386__) || defined(__amd64__) || defined( __x86_64__) \ || defined(__ARM_FEATURE_UNALIGNED) \ || defined(__aarch64__) \ || defined(__ARM_ARCH_8__) || defined(__ARM_ARCH_8A__) || defined(__ARM_ARCH_8M__) \ - || defined(__ARM_ARCH_7A__)) && !defined(MBEDTLS_HAVE_UBSAN) + || defined(__ARM_ARCH_7A__) +#if (defined(__GNUC__) && __GNUC__ >= 4) \ + || (defined(__clang__) && __has_attribute(aligned)) \ + || (defined(__ARMCC_VERSION) && __ARMCC_VERSION >= 5000000 ) #define MBEDTLS_ALLOW_UNALIGNED_ACCESS +__attribute__((aligned(1))) typedef uint32_t unaligned_uint32_t; +#define UNALIGNED_UINT32_PTR unaligned_uint32_t +#elif defined(_MSC_VER) +#define MBEDTLS_ALLOW_UNALIGNED_ACCESS +#define UNALIGNED_UINT32_PTR __declspec(align(1)) uint32_t +#endif #endif /** Byte Reading Macros @@ -428,9 +435,9 @@ extern void (*mbedtls_test_hook_test_fail)( const char * test, int line, const c inline void mbedtls_xor( unsigned char *r, unsigned char const *a, unsigned char const *b, size_t n ) { #if defined(MBEDTLS_ALLOW_UNALIGNED_ACCESS) - uint32_t *a32 = (uint32_t *)a; - uint32_t *b32 = (uint32_t *)b; - uint32_t *r32 = (uint32_t *)r; + UNALIGNED_UINT32_PTR *a32 = (uint32_t *)a; + UNALIGNED_UINT32_PTR *b32 = (uint32_t *)b; + UNALIGNED_UINT32_PTR *r32 = (uint32_t *)r; for ( size_t i = 0; i < ( n >> 2 ); i++ ) { r32[i] = a32[i] ^ b32[i]; From 3172e4e1c992ebdab7552fe822b2f35c6b5a83b8 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 23 Nov 2022 19:38:13 +0000 Subject: [PATCH 25/40] Fix typo in test_suite_common Signed-off-by: Dave Rodgman --- tests/suites/test_suite_common.function | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_common.function b/tests/suites/test_suite_common.function index 6c0d4afc4d..c8a7a52abc 100644 --- a/tests/suites/test_suite_common.function +++ b/tests/suites/test_suite_common.function @@ -74,9 +74,9 @@ void mbedtls_xor( int len ) int r_off = i & 1, a_off = (i & 2) >> 1, b_off = (i & 4) >> 2; fill_arrays( a, b, r1, r2, n + 1 ); - for ( size_t i = 0; i < n; i++ ) + for ( size_t j = 0; j < n; j++ ) { - r1[i + r_off] = a[i + a_off] ^ b[i + b_off]; + r1[j + r_off] = a[j + a_off] ^ b[j + b_off]; } mbedtls_xor( r2 + r_off, a + a_off, b + b_off, n ); ASSERT_COMPARE( r1 + r_off, n, r2 + r_off, n ); From dd3103e9e7ece8173e8a8212e1c00b8078a99963 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 23 Nov 2022 19:42:13 +0000 Subject: [PATCH 26/40] Tidy up UNALIGNED_UINT32_T macro Signed-off-by: Dave Rodgman --- library/common.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/library/common.h b/library/common.h index 75d28ff1f2..affec10bf3 100644 --- a/library/common.h +++ b/library/common.h @@ -77,7 +77,7 @@ extern void (*mbedtls_test_hook_test_fail)( const char * test, int line, const c /** MBEDTLS_ALLOW_UNALIGNED_ACCESS is defined for architectures where unaligned * memory accesses are safe and performant. * - * Unaligned accesses must be made via the UNALIGNED_UINT32_PTR type + * Unaligned accesses must be made via the UNALIGNED_UINT32_T type * defined here. * * This list is incomplete. @@ -92,10 +92,10 @@ extern void (*mbedtls_test_hook_test_fail)( const char * test, int line, const c || (defined(__ARMCC_VERSION) && __ARMCC_VERSION >= 5000000 ) #define MBEDTLS_ALLOW_UNALIGNED_ACCESS __attribute__((aligned(1))) typedef uint32_t unaligned_uint32_t; -#define UNALIGNED_UINT32_PTR unaligned_uint32_t +#define UNALIGNED_UINT32_T unaligned_uint32_t #elif defined(_MSC_VER) #define MBEDTLS_ALLOW_UNALIGNED_ACCESS -#define UNALIGNED_UINT32_PTR __declspec(align(1)) uint32_t +#define UNALIGNED_UINT32_T __declspec(align(1)) uint32_t #endif #endif @@ -435,9 +435,9 @@ __attribute__((aligned(1))) typedef uint32_t unaligned_uint32_t; inline void mbedtls_xor( unsigned char *r, unsigned char const *a, unsigned char const *b, size_t n ) { #if defined(MBEDTLS_ALLOW_UNALIGNED_ACCESS) - UNALIGNED_UINT32_PTR *a32 = (uint32_t *)a; - UNALIGNED_UINT32_PTR *b32 = (uint32_t *)b; - UNALIGNED_UINT32_PTR *r32 = (uint32_t *)r; + UNALIGNED_UINT32_T *a32 = (uint32_t *)a; + UNALIGNED_UINT32_T *b32 = (uint32_t *)b; + UNALIGNED_UINT32_T *r32 = (uint32_t *)r; for ( size_t i = 0; i < ( n >> 2 ); i++ ) { r32[i] = a32[i] ^ b32[i]; From 358c7d6eb07906368a960f8aa47639bbe0560237 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 23 Nov 2022 20:29:03 +0000 Subject: [PATCH 27/40] Fix naming inconsistency Signed-off-by: Dave Rodgman --- library/common.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/common.h b/library/common.h index affec10bf3..6ea89789b7 100644 --- a/library/common.h +++ b/library/common.h @@ -91,8 +91,8 @@ extern void (*mbedtls_test_hook_test_fail)( const char * test, int line, const c || (defined(__clang__) && __has_attribute(aligned)) \ || (defined(__ARMCC_VERSION) && __ARMCC_VERSION >= 5000000 ) #define MBEDTLS_ALLOW_UNALIGNED_ACCESS -__attribute__((aligned(1))) typedef uint32_t unaligned_uint32_t; -#define UNALIGNED_UINT32_T unaligned_uint32_t +__attribute__((aligned(1))) typedef uint32_t mbedtls_unaligned_uint32_t; +#define UNALIGNED_UINT32_T mbedtls_unaligned_uint32_t #elif defined(_MSC_VER) #define MBEDTLS_ALLOW_UNALIGNED_ACCESS #define UNALIGNED_UINT32_T __declspec(align(1)) uint32_t From 6921959b83abb43003bdc99603783a6a7cc9f88f Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 24 Nov 2022 09:27:15 +0000 Subject: [PATCH 28/40] Remove unused variable Signed-off-by: Dave Rodgman --- library/pkcs5.c | 1 - 1 file changed, 1 deletion(-) diff --git a/library/pkcs5.c b/library/pkcs5.c index a6bc1b55c7..1e3b17e644 100644 --- a/library/pkcs5.c +++ b/library/pkcs5.c @@ -322,7 +322,6 @@ exit: mbedtls_md_free( &md_ctx ); return( ret ); #else - int j; unsigned int i; unsigned char md1[PSA_HASH_MAX_SIZE]; unsigned char work[PSA_HASH_MAX_SIZE]; From fbc23225d62acd5443e9c616871e611d1800f3e5 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 24 Nov 2022 18:07:37 +0000 Subject: [PATCH 29/40] Tidy up alignment-related code into separate header Signed-off-by: Dave Rodgman --- library/alignment.h | 382 ++++++++++++++++++++++++++++++++++++++++++++ library/common.h | 348 +--------------------------------------- 2 files changed, 383 insertions(+), 347 deletions(-) create mode 100644 library/alignment.h diff --git a/library/alignment.h b/library/alignment.h new file mode 100644 index 0000000000..60e5dba138 --- /dev/null +++ b/library/alignment.h @@ -0,0 +1,382 @@ +/** + * \file alignment.h + * + * \brief Utility code for dealing with unaligned memory accesses + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_LIBRARY_ALIGNMENT_H +#define MBEDTLS_LIBRARY_ALIGNMENT_H + +#include + +/** MBEDTLS_ALLOW_UNALIGNED_ACCESS is defined for architectures where unaligned + * memory accesses are safe and performant. + * + * Unaligned accesses must be made via the UNALIGNED_UINT32_T type + * defined here. + * + * This list is incomplete. + */ +#if defined(__i386__) || defined(__amd64__) || defined( __x86_64__) \ + || defined(__ARM_FEATURE_UNALIGNED) \ + || defined(__aarch64__) \ + || defined(__ARM_ARCH_8__) || defined(__ARM_ARCH_8A__) || defined(__ARM_ARCH_8M__) \ + || defined(__ARM_ARCH_7A__) +#if (defined(__GNUC__) && __GNUC__ >= 4) \ + || (defined(__clang__) && __has_attribute(aligned)) \ + || (defined(__ARMCC_VERSION) && __ARMCC_VERSION >= 5000000 ) + /* GCC, Clang and armcc */ +#define MBEDTLS_ALLOW_UNALIGNED_ACCESS +__attribute__((aligned(1))) typedef uint32_t mbedtls_unaligned_uint32_t; +#define UNALIGNED_UINT32_T mbedtls_unaligned_uint32_t +#elif defined(_MSC_VER) + /* MSVC */ +#define MBEDTLS_ALLOW_UNALIGNED_ACCESS +#define UNALIGNED_UINT32_T __declspec(align(1)) uint32_t +#elif (defined __ICCARM__) + /* IAR - this is disabled until we have the opportunity to test it */ +#undef MBEDTLS_ALLOW_UNALIGNED_ACCESS +#define UNALIGNED_UINT32_T _Pragma("data_alignment = 1") uint32_t +#endif +#endif + + +/** Byte Reading Macros + * + * Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th + * byte from x, where byte 0 is the least significant byte. + */ +#define MBEDTLS_BYTE_0( x ) ( (uint8_t) ( ( x ) & 0xff ) ) +#define MBEDTLS_BYTE_1( x ) ( (uint8_t) ( ( ( x ) >> 8 ) & 0xff ) ) +#define MBEDTLS_BYTE_2( x ) ( (uint8_t) ( ( ( x ) >> 16 ) & 0xff ) ) +#define MBEDTLS_BYTE_3( x ) ( (uint8_t) ( ( ( x ) >> 24 ) & 0xff ) ) +#define MBEDTLS_BYTE_4( x ) ( (uint8_t) ( ( ( x ) >> 32 ) & 0xff ) ) +#define MBEDTLS_BYTE_5( x ) ( (uint8_t) ( ( ( x ) >> 40 ) & 0xff ) ) +#define MBEDTLS_BYTE_6( x ) ( (uint8_t) ( ( ( x ) >> 48 ) & 0xff ) ) +#define MBEDTLS_BYTE_7( x ) ( (uint8_t) ( ( ( x ) >> 56 ) & 0xff ) ) + +/** + * Get the unsigned 32 bits integer corresponding to four bytes in + * big-endian order (MSB first). + * + * \param data Base address of the memory to get the four bytes from. + * \param offset Offset from \p data of the first and most significant + * byte of the four bytes to build the 32 bits unsigned + * integer from. + */ +#ifndef MBEDTLS_GET_UINT32_BE +#define MBEDTLS_GET_UINT32_BE( data , offset ) \ + ( \ + ( (uint32_t) ( data )[( offset ) ] << 24 ) \ + | ( (uint32_t) ( data )[( offset ) + 1] << 16 ) \ + | ( (uint32_t) ( data )[( offset ) + 2] << 8 ) \ + | ( (uint32_t) ( data )[( offset ) + 3] ) \ + ) +#endif + +/** + * Put in memory a 32 bits unsigned integer in big-endian order. + * + * \param n 32 bits unsigned integer to put in memory. + * \param data Base address of the memory where to put the 32 + * bits unsigned integer in. + * \param offset Offset from \p data where to put the most significant + * byte of the 32 bits unsigned integer \p n. + */ +#ifndef MBEDTLS_PUT_UINT32_BE +#define MBEDTLS_PUT_UINT32_BE( n, data, offset ) \ +{ \ + ( data )[( offset ) ] = MBEDTLS_BYTE_3( n ); \ + ( data )[( offset ) + 1] = MBEDTLS_BYTE_2( n ); \ + ( data )[( offset ) + 2] = MBEDTLS_BYTE_1( n ); \ + ( data )[( offset ) + 3] = MBEDTLS_BYTE_0( n ); \ +} +#endif + +/** + * Get the unsigned 32 bits integer corresponding to four bytes in + * little-endian order (LSB first). + * + * \param data Base address of the memory to get the four bytes from. + * \param offset Offset from \p data of the first and least significant + * byte of the four bytes to build the 32 bits unsigned + * integer from. + */ +#ifndef MBEDTLS_GET_UINT32_LE +#define MBEDTLS_GET_UINT32_LE( data, offset ) \ + ( \ + ( (uint32_t) ( data )[( offset ) ] ) \ + | ( (uint32_t) ( data )[( offset ) + 1] << 8 ) \ + | ( (uint32_t) ( data )[( offset ) + 2] << 16 ) \ + | ( (uint32_t) ( data )[( offset ) + 3] << 24 ) \ + ) +#endif + +/** + * Put in memory a 32 bits unsigned integer in little-endian order. + * + * \param n 32 bits unsigned integer to put in memory. + * \param data Base address of the memory where to put the 32 + * bits unsigned integer in. + * \param offset Offset from \p data where to put the least significant + * byte of the 32 bits unsigned integer \p n. + */ +#ifndef MBEDTLS_PUT_UINT32_LE +#define MBEDTLS_PUT_UINT32_LE( n, data, offset ) \ +{ \ + ( data )[( offset ) ] = MBEDTLS_BYTE_0( n ); \ + ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n ); \ + ( data )[( offset ) + 2] = MBEDTLS_BYTE_2( n ); \ + ( data )[( offset ) + 3] = MBEDTLS_BYTE_3( n ); \ +} +#endif + +/** + * Get the unsigned 16 bits integer corresponding to two bytes in + * little-endian order (LSB first). + * + * \param data Base address of the memory to get the two bytes from. + * \param offset Offset from \p data of the first and least significant + * byte of the two bytes to build the 16 bits unsigned + * integer from. + */ +#ifndef MBEDTLS_GET_UINT16_LE +#define MBEDTLS_GET_UINT16_LE( data, offset ) \ + ( \ + ( (uint16_t) ( data )[( offset ) ] ) \ + | ( (uint16_t) ( data )[( offset ) + 1] << 8 ) \ + ) +#endif + +/** + * Put in memory a 16 bits unsigned integer in little-endian order. + * + * \param n 16 bits unsigned integer to put in memory. + * \param data Base address of the memory where to put the 16 + * bits unsigned integer in. + * \param offset Offset from \p data where to put the least significant + * byte of the 16 bits unsigned integer \p n. + */ +#ifndef MBEDTLS_PUT_UINT16_LE +#define MBEDTLS_PUT_UINT16_LE( n, data, offset ) \ +{ \ + ( data )[( offset ) ] = MBEDTLS_BYTE_0( n ); \ + ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n ); \ +} +#endif + +/** + * Get the unsigned 16 bits integer corresponding to two bytes in + * big-endian order (MSB first). + * + * \param data Base address of the memory to get the two bytes from. + * \param offset Offset from \p data of the first and most significant + * byte of the two bytes to build the 16 bits unsigned + * integer from. + */ +#ifndef MBEDTLS_GET_UINT16_BE +#define MBEDTLS_GET_UINT16_BE( data, offset ) \ + ( \ + ( (uint16_t) ( data )[( offset ) ] << 8 ) \ + | ( (uint16_t) ( data )[( offset ) + 1] ) \ + ) +#endif + +/** + * Put in memory a 16 bits unsigned integer in big-endian order. + * + * \param n 16 bits unsigned integer to put in memory. + * \param data Base address of the memory where to put the 16 + * bits unsigned integer in. + * \param offset Offset from \p data where to put the most significant + * byte of the 16 bits unsigned integer \p n. + */ +#ifndef MBEDTLS_PUT_UINT16_BE +#define MBEDTLS_PUT_UINT16_BE( n, data, offset ) \ +{ \ + ( data )[( offset ) ] = MBEDTLS_BYTE_1( n ); \ + ( data )[( offset ) + 1] = MBEDTLS_BYTE_0( n ); \ +} +#endif + +/** + * Get the unsigned 24 bits integer corresponding to three bytes in + * big-endian order (MSB first). + * + * \param data Base address of the memory to get the three bytes from. + * \param offset Offset from \p data of the first and most significant + * byte of the three bytes to build the 24 bits unsigned + * integer from. + */ +#ifndef MBEDTLS_GET_UINT24_BE +#define MBEDTLS_GET_UINT24_BE( data , offset ) \ + ( \ + ( (uint32_t) ( data )[( offset ) ] << 16 ) \ + | ( (uint32_t) ( data )[( offset ) + 1] << 8 ) \ + | ( (uint32_t) ( data )[( offset ) + 2] ) \ + ) +#endif + +/** + * Put in memory a 24 bits unsigned integer in big-endian order. + * + * \param n 24 bits unsigned integer to put in memory. + * \param data Base address of the memory where to put the 24 + * bits unsigned integer in. + * \param offset Offset from \p data where to put the most significant + * byte of the 24 bits unsigned integer \p n. + */ +#ifndef MBEDTLS_PUT_UINT24_BE +#define MBEDTLS_PUT_UINT24_BE( n, data, offset ) \ +{ \ + ( data )[( offset ) ] = MBEDTLS_BYTE_2( n ); \ + ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n ); \ + ( data )[( offset ) + 2] = MBEDTLS_BYTE_0( n ); \ +} +#endif + +/** + * Get the unsigned 24 bits integer corresponding to three bytes in + * little-endian order (LSB first). + * + * \param data Base address of the memory to get the three bytes from. + * \param offset Offset from \p data of the first and least significant + * byte of the three bytes to build the 24 bits unsigned + * integer from. + */ +#ifndef MBEDTLS_GET_UINT24_LE +#define MBEDTLS_GET_UINT24_LE( data, offset ) \ + ( \ + ( (uint32_t) ( data )[( offset ) ] ) \ + | ( (uint32_t) ( data )[( offset ) + 1] << 8 ) \ + | ( (uint32_t) ( data )[( offset ) + 2] << 16 ) \ + ) +#endif + +/** + * Put in memory a 24 bits unsigned integer in little-endian order. + * + * \param n 24 bits unsigned integer to put in memory. + * \param data Base address of the memory where to put the 24 + * bits unsigned integer in. + * \param offset Offset from \p data where to put the least significant + * byte of the 24 bits unsigned integer \p n. + */ +#ifndef MBEDTLS_PUT_UINT24_LE +#define MBEDTLS_PUT_UINT24_LE( n, data, offset ) \ +{ \ + ( data )[( offset ) ] = MBEDTLS_BYTE_0( n ); \ + ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n ); \ + ( data )[( offset ) + 2] = MBEDTLS_BYTE_2( n ); \ +} +#endif + +/** + * Get the unsigned 64 bits integer corresponding to eight bytes in + * big-endian order (MSB first). + * + * \param data Base address of the memory to get the eight bytes from. + * \param offset Offset from \p data of the first and most significant + * byte of the eight bytes to build the 64 bits unsigned + * integer from. + */ +#ifndef MBEDTLS_GET_UINT64_BE +#define MBEDTLS_GET_UINT64_BE( data, offset ) \ + ( \ + ( (uint64_t) ( data )[( offset ) ] << 56 ) \ + | ( (uint64_t) ( data )[( offset ) + 1] << 48 ) \ + | ( (uint64_t) ( data )[( offset ) + 2] << 40 ) \ + | ( (uint64_t) ( data )[( offset ) + 3] << 32 ) \ + | ( (uint64_t) ( data )[( offset ) + 4] << 24 ) \ + | ( (uint64_t) ( data )[( offset ) + 5] << 16 ) \ + | ( (uint64_t) ( data )[( offset ) + 6] << 8 ) \ + | ( (uint64_t) ( data )[( offset ) + 7] ) \ + ) +#endif + +/** + * Put in memory a 64 bits unsigned integer in big-endian order. + * + * \param n 64 bits unsigned integer to put in memory. + * \param data Base address of the memory where to put the 64 + * bits unsigned integer in. + * \param offset Offset from \p data where to put the most significant + * byte of the 64 bits unsigned integer \p n. + */ +#ifndef MBEDTLS_PUT_UINT64_BE +#define MBEDTLS_PUT_UINT64_BE( n, data, offset ) \ +{ \ + ( data )[( offset ) ] = MBEDTLS_BYTE_7( n ); \ + ( data )[( offset ) + 1] = MBEDTLS_BYTE_6( n ); \ + ( data )[( offset ) + 2] = MBEDTLS_BYTE_5( n ); \ + ( data )[( offset ) + 3] = MBEDTLS_BYTE_4( n ); \ + ( data )[( offset ) + 4] = MBEDTLS_BYTE_3( n ); \ + ( data )[( offset ) + 5] = MBEDTLS_BYTE_2( n ); \ + ( data )[( offset ) + 6] = MBEDTLS_BYTE_1( n ); \ + ( data )[( offset ) + 7] = MBEDTLS_BYTE_0( n ); \ +} +#endif + +/** + * Get the unsigned 64 bits integer corresponding to eight bytes in + * little-endian order (LSB first). + * + * \param data Base address of the memory to get the eight bytes from. + * \param offset Offset from \p data of the first and least significant + * byte of the eight bytes to build the 64 bits unsigned + * integer from. + */ +#ifndef MBEDTLS_GET_UINT64_LE +#define MBEDTLS_GET_UINT64_LE( data, offset ) \ + ( \ + ( (uint64_t) ( data )[( offset ) + 7] << 56 ) \ + | ( (uint64_t) ( data )[( offset ) + 6] << 48 ) \ + | ( (uint64_t) ( data )[( offset ) + 5] << 40 ) \ + | ( (uint64_t) ( data )[( offset ) + 4] << 32 ) \ + | ( (uint64_t) ( data )[( offset ) + 3] << 24 ) \ + | ( (uint64_t) ( data )[( offset ) + 2] << 16 ) \ + | ( (uint64_t) ( data )[( offset ) + 1] << 8 ) \ + | ( (uint64_t) ( data )[( offset ) ] ) \ + ) +#endif + +/** + * Put in memory a 64 bits unsigned integer in little-endian order. + * + * \param n 64 bits unsigned integer to put in memory. + * \param data Base address of the memory where to put the 64 + * bits unsigned integer in. + * \param offset Offset from \p data where to put the least significant + * byte of the 64 bits unsigned integer \p n. + */ +#ifndef MBEDTLS_PUT_UINT64_LE +#define MBEDTLS_PUT_UINT64_LE( n, data, offset ) \ +{ \ + ( data )[( offset ) ] = MBEDTLS_BYTE_0( n ); \ + ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n ); \ + ( data )[( offset ) + 2] = MBEDTLS_BYTE_2( n ); \ + ( data )[( offset ) + 3] = MBEDTLS_BYTE_3( n ); \ + ( data )[( offset ) + 4] = MBEDTLS_BYTE_4( n ); \ + ( data )[( offset ) + 5] = MBEDTLS_BYTE_5( n ); \ + ( data )[( offset ) + 6] = MBEDTLS_BYTE_6( n ); \ + ( data )[( offset ) + 7] = MBEDTLS_BYTE_7( n ); \ +} +#endif + +#endif /* MBEDTLS_LIBRARY_ALIGNMENT_H */ diff --git a/library/common.h b/library/common.h index 6ea89789b7..63c936fe5d 100644 --- a/library/common.h +++ b/library/common.h @@ -24,6 +24,7 @@ #define MBEDTLS_LIBRARY_COMMON_H #include "mbedtls/build_info.h" +#include "alignment.h" #include #include @@ -74,353 +75,6 @@ extern void (*mbedtls_test_hook_test_fail)( const char * test, int line, const c */ #define MBEDTLS_ALLOW_PRIVATE_ACCESS -/** MBEDTLS_ALLOW_UNALIGNED_ACCESS is defined for architectures where unaligned - * memory accesses are safe and performant. - * - * Unaligned accesses must be made via the UNALIGNED_UINT32_T type - * defined here. - * - * This list is incomplete. - */ -#if defined(__i386__) || defined(__amd64__) || defined( __x86_64__) \ - || defined(__ARM_FEATURE_UNALIGNED) \ - || defined(__aarch64__) \ - || defined(__ARM_ARCH_8__) || defined(__ARM_ARCH_8A__) || defined(__ARM_ARCH_8M__) \ - || defined(__ARM_ARCH_7A__) -#if (defined(__GNUC__) && __GNUC__ >= 4) \ - || (defined(__clang__) && __has_attribute(aligned)) \ - || (defined(__ARMCC_VERSION) && __ARMCC_VERSION >= 5000000 ) -#define MBEDTLS_ALLOW_UNALIGNED_ACCESS -__attribute__((aligned(1))) typedef uint32_t mbedtls_unaligned_uint32_t; -#define UNALIGNED_UINT32_T mbedtls_unaligned_uint32_t -#elif defined(_MSC_VER) -#define MBEDTLS_ALLOW_UNALIGNED_ACCESS -#define UNALIGNED_UINT32_T __declspec(align(1)) uint32_t -#endif -#endif - -/** Byte Reading Macros - * - * Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th - * byte from x, where byte 0 is the least significant byte. - */ -#define MBEDTLS_BYTE_0( x ) ( (uint8_t) ( ( x ) & 0xff ) ) -#define MBEDTLS_BYTE_1( x ) ( (uint8_t) ( ( ( x ) >> 8 ) & 0xff ) ) -#define MBEDTLS_BYTE_2( x ) ( (uint8_t) ( ( ( x ) >> 16 ) & 0xff ) ) -#define MBEDTLS_BYTE_3( x ) ( (uint8_t) ( ( ( x ) >> 24 ) & 0xff ) ) -#define MBEDTLS_BYTE_4( x ) ( (uint8_t) ( ( ( x ) >> 32 ) & 0xff ) ) -#define MBEDTLS_BYTE_5( x ) ( (uint8_t) ( ( ( x ) >> 40 ) & 0xff ) ) -#define MBEDTLS_BYTE_6( x ) ( (uint8_t) ( ( ( x ) >> 48 ) & 0xff ) ) -#define MBEDTLS_BYTE_7( x ) ( (uint8_t) ( ( ( x ) >> 56 ) & 0xff ) ) - -/** - * Get the unsigned 32 bits integer corresponding to four bytes in - * big-endian order (MSB first). - * - * \param data Base address of the memory to get the four bytes from. - * \param offset Offset from \p data of the first and most significant - * byte of the four bytes to build the 32 bits unsigned - * integer from. - */ -#ifndef MBEDTLS_GET_UINT32_BE -#define MBEDTLS_GET_UINT32_BE( data , offset ) \ - ( \ - ( (uint32_t) ( data )[( offset ) ] << 24 ) \ - | ( (uint32_t) ( data )[( offset ) + 1] << 16 ) \ - | ( (uint32_t) ( data )[( offset ) + 2] << 8 ) \ - | ( (uint32_t) ( data )[( offset ) + 3] ) \ - ) -#endif - -/** - * Put in memory a 32 bits unsigned integer in big-endian order. - * - * \param n 32 bits unsigned integer to put in memory. - * \param data Base address of the memory where to put the 32 - * bits unsigned integer in. - * \param offset Offset from \p data where to put the most significant - * byte of the 32 bits unsigned integer \p n. - */ -#ifndef MBEDTLS_PUT_UINT32_BE -#define MBEDTLS_PUT_UINT32_BE( n, data, offset ) \ -{ \ - ( data )[( offset ) ] = MBEDTLS_BYTE_3( n ); \ - ( data )[( offset ) + 1] = MBEDTLS_BYTE_2( n ); \ - ( data )[( offset ) + 2] = MBEDTLS_BYTE_1( n ); \ - ( data )[( offset ) + 3] = MBEDTLS_BYTE_0( n ); \ -} -#endif - -/** - * Get the unsigned 32 bits integer corresponding to four bytes in - * little-endian order (LSB first). - * - * \param data Base address of the memory to get the four bytes from. - * \param offset Offset from \p data of the first and least significant - * byte of the four bytes to build the 32 bits unsigned - * integer from. - */ -#ifndef MBEDTLS_GET_UINT32_LE -#define MBEDTLS_GET_UINT32_LE( data, offset ) \ - ( \ - ( (uint32_t) ( data )[( offset ) ] ) \ - | ( (uint32_t) ( data )[( offset ) + 1] << 8 ) \ - | ( (uint32_t) ( data )[( offset ) + 2] << 16 ) \ - | ( (uint32_t) ( data )[( offset ) + 3] << 24 ) \ - ) -#endif - -/** - * Put in memory a 32 bits unsigned integer in little-endian order. - * - * \param n 32 bits unsigned integer to put in memory. - * \param data Base address of the memory where to put the 32 - * bits unsigned integer in. - * \param offset Offset from \p data where to put the least significant - * byte of the 32 bits unsigned integer \p n. - */ -#ifndef MBEDTLS_PUT_UINT32_LE -#define MBEDTLS_PUT_UINT32_LE( n, data, offset ) \ -{ \ - ( data )[( offset ) ] = MBEDTLS_BYTE_0( n ); \ - ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n ); \ - ( data )[( offset ) + 2] = MBEDTLS_BYTE_2( n ); \ - ( data )[( offset ) + 3] = MBEDTLS_BYTE_3( n ); \ -} -#endif - -/** - * Get the unsigned 16 bits integer corresponding to two bytes in - * little-endian order (LSB first). - * - * \param data Base address of the memory to get the two bytes from. - * \param offset Offset from \p data of the first and least significant - * byte of the two bytes to build the 16 bits unsigned - * integer from. - */ -#ifndef MBEDTLS_GET_UINT16_LE -#define MBEDTLS_GET_UINT16_LE( data, offset ) \ - ( \ - ( (uint16_t) ( data )[( offset ) ] ) \ - | ( (uint16_t) ( data )[( offset ) + 1] << 8 ) \ - ) -#endif - -/** - * Put in memory a 16 bits unsigned integer in little-endian order. - * - * \param n 16 bits unsigned integer to put in memory. - * \param data Base address of the memory where to put the 16 - * bits unsigned integer in. - * \param offset Offset from \p data where to put the least significant - * byte of the 16 bits unsigned integer \p n. - */ -#ifndef MBEDTLS_PUT_UINT16_LE -#define MBEDTLS_PUT_UINT16_LE( n, data, offset ) \ -{ \ - ( data )[( offset ) ] = MBEDTLS_BYTE_0( n ); \ - ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n ); \ -} -#endif - -/** - * Get the unsigned 16 bits integer corresponding to two bytes in - * big-endian order (MSB first). - * - * \param data Base address of the memory to get the two bytes from. - * \param offset Offset from \p data of the first and most significant - * byte of the two bytes to build the 16 bits unsigned - * integer from. - */ -#ifndef MBEDTLS_GET_UINT16_BE -#define MBEDTLS_GET_UINT16_BE( data, offset ) \ - ( \ - ( (uint16_t) ( data )[( offset ) ] << 8 ) \ - | ( (uint16_t) ( data )[( offset ) + 1] ) \ - ) -#endif - -/** - * Put in memory a 16 bits unsigned integer in big-endian order. - * - * \param n 16 bits unsigned integer to put in memory. - * \param data Base address of the memory where to put the 16 - * bits unsigned integer in. - * \param offset Offset from \p data where to put the most significant - * byte of the 16 bits unsigned integer \p n. - */ -#ifndef MBEDTLS_PUT_UINT16_BE -#define MBEDTLS_PUT_UINT16_BE( n, data, offset ) \ -{ \ - ( data )[( offset ) ] = MBEDTLS_BYTE_1( n ); \ - ( data )[( offset ) + 1] = MBEDTLS_BYTE_0( n ); \ -} -#endif - -/** - * Get the unsigned 24 bits integer corresponding to three bytes in - * big-endian order (MSB first). - * - * \param data Base address of the memory to get the three bytes from. - * \param offset Offset from \p data of the first and most significant - * byte of the three bytes to build the 24 bits unsigned - * integer from. - */ -#ifndef MBEDTLS_GET_UINT24_BE -#define MBEDTLS_GET_UINT24_BE( data , offset ) \ - ( \ - ( (uint32_t) ( data )[( offset ) ] << 16 ) \ - | ( (uint32_t) ( data )[( offset ) + 1] << 8 ) \ - | ( (uint32_t) ( data )[( offset ) + 2] ) \ - ) -#endif - -/** - * Put in memory a 24 bits unsigned integer in big-endian order. - * - * \param n 24 bits unsigned integer to put in memory. - * \param data Base address of the memory where to put the 24 - * bits unsigned integer in. - * \param offset Offset from \p data where to put the most significant - * byte of the 24 bits unsigned integer \p n. - */ -#ifndef MBEDTLS_PUT_UINT24_BE -#define MBEDTLS_PUT_UINT24_BE( n, data, offset ) \ -{ \ - ( data )[( offset ) ] = MBEDTLS_BYTE_2( n ); \ - ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n ); \ - ( data )[( offset ) + 2] = MBEDTLS_BYTE_0( n ); \ -} -#endif - -/** - * Get the unsigned 24 bits integer corresponding to three bytes in - * little-endian order (LSB first). - * - * \param data Base address of the memory to get the three bytes from. - * \param offset Offset from \p data of the first and least significant - * byte of the three bytes to build the 24 bits unsigned - * integer from. - */ -#ifndef MBEDTLS_GET_UINT24_LE -#define MBEDTLS_GET_UINT24_LE( data, offset ) \ - ( \ - ( (uint32_t) ( data )[( offset ) ] ) \ - | ( (uint32_t) ( data )[( offset ) + 1] << 8 ) \ - | ( (uint32_t) ( data )[( offset ) + 2] << 16 ) \ - ) -#endif - -/** - * Put in memory a 24 bits unsigned integer in little-endian order. - * - * \param n 24 bits unsigned integer to put in memory. - * \param data Base address of the memory where to put the 24 - * bits unsigned integer in. - * \param offset Offset from \p data where to put the least significant - * byte of the 24 bits unsigned integer \p n. - */ -#ifndef MBEDTLS_PUT_UINT24_LE -#define MBEDTLS_PUT_UINT24_LE( n, data, offset ) \ -{ \ - ( data )[( offset ) ] = MBEDTLS_BYTE_0( n ); \ - ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n ); \ - ( data )[( offset ) + 2] = MBEDTLS_BYTE_2( n ); \ -} -#endif - -/** - * Get the unsigned 64 bits integer corresponding to eight bytes in - * big-endian order (MSB first). - * - * \param data Base address of the memory to get the eight bytes from. - * \param offset Offset from \p data of the first and most significant - * byte of the eight bytes to build the 64 bits unsigned - * integer from. - */ -#ifndef MBEDTLS_GET_UINT64_BE -#define MBEDTLS_GET_UINT64_BE( data, offset ) \ - ( \ - ( (uint64_t) ( data )[( offset ) ] << 56 ) \ - | ( (uint64_t) ( data )[( offset ) + 1] << 48 ) \ - | ( (uint64_t) ( data )[( offset ) + 2] << 40 ) \ - | ( (uint64_t) ( data )[( offset ) + 3] << 32 ) \ - | ( (uint64_t) ( data )[( offset ) + 4] << 24 ) \ - | ( (uint64_t) ( data )[( offset ) + 5] << 16 ) \ - | ( (uint64_t) ( data )[( offset ) + 6] << 8 ) \ - | ( (uint64_t) ( data )[( offset ) + 7] ) \ - ) -#endif - -/** - * Put in memory a 64 bits unsigned integer in big-endian order. - * - * \param n 64 bits unsigned integer to put in memory. - * \param data Base address of the memory where to put the 64 - * bits unsigned integer in. - * \param offset Offset from \p data where to put the most significant - * byte of the 64 bits unsigned integer \p n. - */ -#ifndef MBEDTLS_PUT_UINT64_BE -#define MBEDTLS_PUT_UINT64_BE( n, data, offset ) \ -{ \ - ( data )[( offset ) ] = MBEDTLS_BYTE_7( n ); \ - ( data )[( offset ) + 1] = MBEDTLS_BYTE_6( n ); \ - ( data )[( offset ) + 2] = MBEDTLS_BYTE_5( n ); \ - ( data )[( offset ) + 3] = MBEDTLS_BYTE_4( n ); \ - ( data )[( offset ) + 4] = MBEDTLS_BYTE_3( n ); \ - ( data )[( offset ) + 5] = MBEDTLS_BYTE_2( n ); \ - ( data )[( offset ) + 6] = MBEDTLS_BYTE_1( n ); \ - ( data )[( offset ) + 7] = MBEDTLS_BYTE_0( n ); \ -} -#endif - -/** - * Get the unsigned 64 bits integer corresponding to eight bytes in - * little-endian order (LSB first). - * - * \param data Base address of the memory to get the eight bytes from. - * \param offset Offset from \p data of the first and least significant - * byte of the eight bytes to build the 64 bits unsigned - * integer from. - */ -#ifndef MBEDTLS_GET_UINT64_LE -#define MBEDTLS_GET_UINT64_LE( data, offset ) \ - ( \ - ( (uint64_t) ( data )[( offset ) + 7] << 56 ) \ - | ( (uint64_t) ( data )[( offset ) + 6] << 48 ) \ - | ( (uint64_t) ( data )[( offset ) + 5] << 40 ) \ - | ( (uint64_t) ( data )[( offset ) + 4] << 32 ) \ - | ( (uint64_t) ( data )[( offset ) + 3] << 24 ) \ - | ( (uint64_t) ( data )[( offset ) + 2] << 16 ) \ - | ( (uint64_t) ( data )[( offset ) + 1] << 8 ) \ - | ( (uint64_t) ( data )[( offset ) ] ) \ - ) -#endif - -/** - * Put in memory a 64 bits unsigned integer in little-endian order. - * - * \param n 64 bits unsigned integer to put in memory. - * \param data Base address of the memory where to put the 64 - * bits unsigned integer in. - * \param offset Offset from \p data where to put the least significant - * byte of the 64 bits unsigned integer \p n. - */ -#ifndef MBEDTLS_PUT_UINT64_LE -#define MBEDTLS_PUT_UINT64_LE( n, data, offset ) \ -{ \ - ( data )[( offset ) ] = MBEDTLS_BYTE_0( n ); \ - ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n ); \ - ( data )[( offset ) + 2] = MBEDTLS_BYTE_2( n ); \ - ( data )[( offset ) + 3] = MBEDTLS_BYTE_3( n ); \ - ( data )[( offset ) + 4] = MBEDTLS_BYTE_4( n ); \ - ( data )[( offset ) + 5] = MBEDTLS_BYTE_5( n ); \ - ( data )[( offset ) + 6] = MBEDTLS_BYTE_6( n ); \ - ( data )[( offset ) + 7] = MBEDTLS_BYTE_7( n ); \ -} -#endif - /** * Perform a fast block XOR operation, such that * r[i] = a[i] ^ b[i] where 0 <= i < n From 96d61d14d85fa2b7492b2738ee417a5e8fce0961 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 24 Nov 2022 19:33:22 +0000 Subject: [PATCH 30/40] Use memcpy for unaligned accesses Signed-off-by: Dave Rodgman --- library/alignment.h | 50 ++++++++++++++++++++------------------------- library/common.h | 18 +++++----------- 2 files changed, 27 insertions(+), 41 deletions(-) diff --git a/library/alignment.h b/library/alignment.h index 60e5dba138..6394be2f36 100644 --- a/library/alignment.h +++ b/library/alignment.h @@ -24,38 +24,32 @@ #define MBEDTLS_LIBRARY_ALIGNMENT_H #include +#include -/** MBEDTLS_ALLOW_UNALIGNED_ACCESS is defined for architectures where unaligned - * memory accesses are safe and performant. +/** + * Read the unsigned 32 bits integer from the given address, which need not + * be aligned. * - * Unaligned accesses must be made via the UNALIGNED_UINT32_T type - * defined here. - * - * This list is incomplete. + * \param p pointer to 4 bytes of data */ -#if defined(__i386__) || defined(__amd64__) || defined( __x86_64__) \ - || defined(__ARM_FEATURE_UNALIGNED) \ - || defined(__aarch64__) \ - || defined(__ARM_ARCH_8__) || defined(__ARM_ARCH_8A__) || defined(__ARM_ARCH_8M__) \ - || defined(__ARM_ARCH_7A__) -#if (defined(__GNUC__) && __GNUC__ >= 4) \ - || (defined(__clang__) && __has_attribute(aligned)) \ - || (defined(__ARMCC_VERSION) && __ARMCC_VERSION >= 5000000 ) - /* GCC, Clang and armcc */ -#define MBEDTLS_ALLOW_UNALIGNED_ACCESS -__attribute__((aligned(1))) typedef uint32_t mbedtls_unaligned_uint32_t; -#define UNALIGNED_UINT32_T mbedtls_unaligned_uint32_t -#elif defined(_MSC_VER) - /* MSVC */ -#define MBEDTLS_ALLOW_UNALIGNED_ACCESS -#define UNALIGNED_UINT32_T __declspec(align(1)) uint32_t -#elif (defined __ICCARM__) - /* IAR - this is disabled until we have the opportunity to test it */ -#undef MBEDTLS_ALLOW_UNALIGNED_ACCESS -#define UNALIGNED_UINT32_T _Pragma("data_alignment = 1") uint32_t -#endif -#endif +static inline uint32_t mbedtls_get_unaligned_uint32( void const *p ) +{ + uint32_t r; + memcpy( &r, p, 4 ); + return r; +} +/** + * Write the unsigned 32 bits integer to the given address, which need not + * be aligned. + * + * \param p pointer to 4 bytes of data + * \param x data to write + */ +static inline void mbedtls_put_unaligned_uint32( void *p, uint32_t x ) +{ + memcpy(p, &x, 4); +} /** Byte Reading Macros * diff --git a/library/common.h b/library/common.h index 63c936fe5d..9dbe21b880 100644 --- a/library/common.h +++ b/library/common.h @@ -88,24 +88,16 @@ extern void (*mbedtls_test_hook_test_fail)( const char * test, int line, const c */ inline void mbedtls_xor( unsigned char *r, unsigned char const *a, unsigned char const *b, size_t n ) { -#if defined(MBEDTLS_ALLOW_UNALIGNED_ACCESS) - UNALIGNED_UINT32_T *a32 = (uint32_t *)a; - UNALIGNED_UINT32_T *b32 = (uint32_t *)b; - UNALIGNED_UINT32_T *r32 = (uint32_t *)r; - for ( size_t i = 0; i < ( n >> 2 ); i++ ) + size_t i; + for ( i = 0; (i + 4) < n; i+= 4 ) { - r32[i] = a32[i] ^ b32[i]; + uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i); + mbedtls_put_unaligned_uint32(r + i, x); } - for ( size_t i = n - ( n % 4 ) ; i < n; i++ ) + for ( ; i < n; i++ ) { r[i] = a[i] ^ b[i]; } -#else - for ( size_t i = 0; i < n; i++ ) - { - r[i] = a[i] ^ b[i]; - } -#endif } /* Fix MSVC C99 compatible issue From 069e7f462a426795301aaaa79e811721427447df Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 24 Nov 2022 19:37:26 +0000 Subject: [PATCH 31/40] Correct mixed up comments Signed-off-by: Dave Rodgman --- library/aes.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/aes.c b/library/aes.c index 4f7c888599..6e1bcd2be8 100644 --- a/library/aes.c +++ b/library/aes.c @@ -1140,14 +1140,14 @@ int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, size_t i; unsigned char *prev_output = output - 16; - /* Copy the remainder of the input for this final round. */ + /* Copy ciphertext bytes from the previous block to our output for each + * byte of ciphertext we won't steal. */ for( i = 0; i < leftover; i++ ) { output[i] = prev_output[i]; } - /* Copy ciphertext bytes from the previous block to our output for each - * byte of ciphertext we won't steal. */ + /* Copy the remainder of the input for this final round. */ mbedtls_xor( tmp, input, t, leftover ); /* Copy ciphertext bytes from the previous block for input in this From 4b910c1ed1313678ab894222cd2a4e05a5641b5e Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 24 Nov 2022 19:44:52 +0000 Subject: [PATCH 32/40] Fix whitespace Signed-off-by: Dave Rodgman --- library/alignment.h | 2 +- library/common.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/alignment.h b/library/alignment.h index 6394be2f36..a5b71d306f 100644 --- a/library/alignment.h +++ b/library/alignment.h @@ -48,7 +48,7 @@ static inline uint32_t mbedtls_get_unaligned_uint32( void const *p ) */ static inline void mbedtls_put_unaligned_uint32( void *p, uint32_t x ) { - memcpy(p, &x, 4); + memcpy( p, &x, 4 ); } /** Byte Reading Macros diff --git a/library/common.h b/library/common.h index 9dbe21b880..943f84c489 100644 --- a/library/common.h +++ b/library/common.h @@ -89,10 +89,10 @@ extern void (*mbedtls_test_hook_test_fail)( const char * test, int line, const c inline void mbedtls_xor( unsigned char *r, unsigned char const *a, unsigned char const *b, size_t n ) { size_t i; - for ( i = 0; (i + 4) < n; i+= 4 ) + for ( i = 0; ( i + 4 ) < n; i+= 4 ) { - uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i); - mbedtls_put_unaligned_uint32(r + i, x); + uint32_t x = mbedtls_get_unaligned_uint32( a + i ) ^ mbedtls_get_unaligned_uint32( b + i ); + mbedtls_put_unaligned_uint32( r + i, x ); } for ( ; i < n; i++ ) { From 66433444fcd6fcd45b4d96c9a95e0a97e0ca3135 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 24 Nov 2022 20:07:39 +0000 Subject: [PATCH 33/40] Fix static inline linker issues Signed-off-by: Dave Rodgman --- library/alignment.h | 4 ++-- library/platform_util.c | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/library/alignment.h b/library/alignment.h index a5b71d306f..755cde3846 100644 --- a/library/alignment.h +++ b/library/alignment.h @@ -32,7 +32,7 @@ * * \param p pointer to 4 bytes of data */ -static inline uint32_t mbedtls_get_unaligned_uint32( void const *p ) +inline uint32_t mbedtls_get_unaligned_uint32( void const *p ) { uint32_t r; memcpy( &r, p, 4 ); @@ -46,7 +46,7 @@ static inline uint32_t mbedtls_get_unaligned_uint32( void const *p ) * \param p pointer to 4 bytes of data * \param x data to write */ -static inline void mbedtls_put_unaligned_uint32( void *p, uint32_t x ) +inline void mbedtls_put_unaligned_uint32( void *p, uint32_t x ) { memcpy( p, &x, 4 ); } diff --git a/library/platform_util.c b/library/platform_util.c index 8fba664d27..7843609e1f 100644 --- a/library/platform_util.c +++ b/library/platform_util.c @@ -144,7 +144,11 @@ void (*mbedtls_test_hook_test_fail)( const char *, int, const char *); #endif /* MBEDTLS_TEST_HOOKS */ /* - * Provide an external definition of mbedtls_xor so that the compiler - * has the option to not inline it + * Provide external definitions of some inline functions so that the compiler + * has the option to not inline them */ extern inline void mbedtls_xor( unsigned char *r, unsigned char const *a, unsigned char const *b, size_t n ); + +extern inline uint32_t mbedtls_get_unaligned_uint32( void const *p ); + +extern inline void mbedtls_put_unaligned_uint32( void *p, uint32_t x ); \ No newline at end of file From c58858865b1b706ff2c1699b215d76bf827a78a1 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 24 Nov 2022 20:35:04 +0000 Subject: [PATCH 34/40] Fix off-by-one error Signed-off-by: Dave Rodgman --- library/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/common.h b/library/common.h index 943f84c489..c17506416b 100644 --- a/library/common.h +++ b/library/common.h @@ -89,7 +89,7 @@ extern void (*mbedtls_test_hook_test_fail)( const char * test, int line, const c inline void mbedtls_xor( unsigned char *r, unsigned char const *a, unsigned char const *b, size_t n ) { size_t i; - for ( i = 0; ( i + 4 ) < n; i+= 4 ) + for ( i = 0; ( i + 4 ) <= n; i += 4 ) { uint32_t x = mbedtls_get_unaligned_uint32( a + i ) ^ mbedtls_get_unaligned_uint32( b + i ); mbedtls_put_unaligned_uint32( r + i, x ); From aaf69fd6826d9c5c6ffa05a220ad1674602fcee2 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 24 Nov 2022 20:40:28 +0000 Subject: [PATCH 35/40] Fix missing newline Signed-off-by: Dave Rodgman --- library/platform_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/platform_util.c b/library/platform_util.c index 7843609e1f..9d7323b3a4 100644 --- a/library/platform_util.c +++ b/library/platform_util.c @@ -151,4 +151,4 @@ extern inline void mbedtls_xor( unsigned char *r, unsigned char const *a, unsign extern inline uint32_t mbedtls_get_unaligned_uint32( void const *p ); -extern inline void mbedtls_put_unaligned_uint32( void *p, uint32_t x ); \ No newline at end of file +extern inline void mbedtls_put_unaligned_uint32( void *p, uint32_t x ); From 875d2383d026f8c6adc8a00c0fdfc6f327ea29e3 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 24 Nov 2022 20:43:15 +0000 Subject: [PATCH 36/40] Improve documentation Signed-off-by: Dave Rodgman --- library/alignment.h | 1 + 1 file changed, 1 insertion(+) diff --git a/library/alignment.h b/library/alignment.h index 755cde3846..dedfdc9e77 100644 --- a/library/alignment.h +++ b/library/alignment.h @@ -31,6 +31,7 @@ * be aligned. * * \param p pointer to 4 bytes of data + * \return Data at the given address */ inline uint32_t mbedtls_get_unaligned_uint32( void const *p ) { From 7a910a8be0b4ea105223cd51a6e701d496d0756e Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 24 Nov 2022 21:17:40 +0000 Subject: [PATCH 37/40] Minor formatting tweaks Signed-off-by: Dave Rodgman --- library/alignment.h | 6 +++--- library/common.h | 2 +- tests/suites/test_suite_common.function | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/library/alignment.h b/library/alignment.h index dedfdc9e77..e7f11da404 100644 --- a/library/alignment.h +++ b/library/alignment.h @@ -33,10 +33,10 @@ * \param p pointer to 4 bytes of data * \return Data at the given address */ -inline uint32_t mbedtls_get_unaligned_uint32( void const *p ) +inline uint32_t mbedtls_get_unaligned_uint32( const void *p ) { uint32_t r; - memcpy( &r, p, 4 ); + memcpy( &r, p, sizeof( r ) ); return r; } @@ -49,7 +49,7 @@ inline uint32_t mbedtls_get_unaligned_uint32( void const *p ) */ inline void mbedtls_put_unaligned_uint32( void *p, uint32_t x ) { - memcpy( p, &x, 4 ); + memcpy( p, &x, sizeof( x ) ); } /** Byte Reading Macros diff --git a/library/common.h b/library/common.h index c17506416b..2cc44fb71d 100644 --- a/library/common.h +++ b/library/common.h @@ -86,7 +86,7 @@ extern void (*mbedtls_test_hook_test_fail)( const char * test, int line, const c * \param b Pointer to input (buffer of at least \p n bytes) * \param n Number of bytes to process. */ -inline void mbedtls_xor( unsigned char *r, unsigned char const *a, unsigned char const *b, size_t n ) +inline void mbedtls_xor( unsigned char *r, const unsigned char *a, const unsigned char *b, size_t n ) { size_t i; for ( i = 0; ( i + 4 ) <= n; i += 4 ) diff --git a/tests/suites/test_suite_common.function b/tests/suites/test_suite_common.function index c8a7a52abc..4444a52ce6 100644 --- a/tests/suites/test_suite_common.function +++ b/tests/suites/test_suite_common.function @@ -82,9 +82,9 @@ void mbedtls_xor( int len ) ASSERT_COMPARE( r1 + r_off, n, r2 + r_off, n ); } exit: - if ( a != NULL ) mbedtls_free( a ); - if ( a != NULL ) mbedtls_free( b ); - if ( r1 != NULL ) mbedtls_free( r1 ); - if ( r2 != NULL ) mbedtls_free( r2 ); + mbedtls_free( a ); + mbedtls_free( b ); + mbedtls_free( r1 ); + mbedtls_free( r2 ); } /* END_CASE */ From b8c4a0d940421c08253234e0207721076fe50bb4 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 24 Nov 2022 21:18:55 +0000 Subject: [PATCH 38/40] Minor formatting tweaks Signed-off-by: Dave Rodgman --- library/platform_util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/platform_util.c b/library/platform_util.c index 9d7323b3a4..9c18dd502a 100644 --- a/library/platform_util.c +++ b/library/platform_util.c @@ -147,8 +147,8 @@ void (*mbedtls_test_hook_test_fail)( const char *, int, const char *); * Provide external definitions of some inline functions so that the compiler * has the option to not inline them */ -extern inline void mbedtls_xor( unsigned char *r, unsigned char const *a, unsigned char const *b, size_t n ); +extern inline void mbedtls_xor( unsigned char *r, const unsigned char *a, const unsigned char *b, size_t n ); -extern inline uint32_t mbedtls_get_unaligned_uint32( void const *p ); +extern inline uint32_t mbedtls_get_unaligned_uint32( const void *p ); extern inline void mbedtls_put_unaligned_uint32( void *p, uint32_t x ); From 8f6583d8363086433cb1d8a86f5683589e9f9a74 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 25 Nov 2022 09:16:41 +0000 Subject: [PATCH 39/40] Fix for MSVC unsupported #inline keyword Signed-off-by: Dave Rodgman --- library/alignment.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/alignment.h b/library/alignment.h index e7f11da404..986fdaa95c 100644 --- a/library/alignment.h +++ b/library/alignment.h @@ -26,6 +26,11 @@ #include #include +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + /** * Read the unsigned 32 bits integer from the given address, which need not * be aligned. From a616afeae41225b7e79ae8f872f2fda8ab880ab8 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 25 Nov 2022 17:11:45 +0000 Subject: [PATCH 40/40] Remove redundant inline workarounds Signed-off-by: Dave Rodgman --- library/alignment.h | 5 +---- library/common.h | 5 ----- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/library/alignment.h b/library/alignment.h index 986fdaa95c..de1ab91487 100644 --- a/library/alignment.h +++ b/library/alignment.h @@ -26,10 +26,7 @@ #include #include -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif +#include "mbedtls/build_info.h" /** * Read the unsigned 32 bits integer from the given address, which need not diff --git a/library/common.h b/library/common.h index 97d180aefb..9d3b8fe933 100644 --- a/library/common.h +++ b/library/common.h @@ -30,11 +30,6 @@ #include #include -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - /** Helper to define a function as static except when building invasive tests. * * If a function is only used inside its own source file and should be