Merge pull request #6664 from davidhorstmann-arm/2.28-fix-typo-unsupported
[Backport 2.28] Fix typo 'unsupoported' -> 'unsupported'
diff --git a/.travis.yml b/.travis.yml
index 2b41c28..cdf74c7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -27,8 +27,44 @@
- tests/scripts/all.sh -k build_arm_linux_gnueabi_gcc_arm5vte build_arm_none_eabi_gcc_m0plus
- name: full configuration
+ os: linux
+ dist: focal
+ addons:
+ apt:
+ packages:
+ - clang-10
+ - gnutls-bin
script:
- - tests/scripts/all.sh -k test_full_cmake_gcc_asan
+ # Do a manual build+test sequence rather than using all.sh,
+ # because there's no all.sh component that does what we want,
+ # which is a build with Clang >= 10 and ASan, running all the SSL
+ # testing.
+ # - The clang executable in the default PATH is Clang 7 on
+ # Travis's focal instances, but we want Clang >= 10.
+ # - Running all the SSL testing requires a specific set of
+ # OpenSSL and GnuTLS versions and we don't want to bother
+ # with those on Travis.
+ # So we explicitly select clang-10 as the compiler, and we
+ # have ad hoc restrictions on SSL testing based on what is
+ # passing at the time of writing. We will remove these limitations
+ # gradually.
+ - make CC=clang-10 CFLAGS='-Werror -Wall -Wextra -fsanitize=address,undefined -fno-sanitize-recover=all -O2' LDFLAGS='-Werror -Wall -Wextra -fsanitize=address,undefined -fno-sanitize-recover=all'
+ - make test
+ - programs/test/selftest
+ - tests/scripts/test_psa_constant_names.py
+ # Exclude a few test cases that are failing mysteriously.
+ # https://github.com/Mbed-TLS/mbedtls/issues/6660
+ - tests/ssl-opt.sh -e 'Fallback SCSV:\ .*list'
+ # Modern OpenSSL does not support fixed ECDH, null or ancient ciphers.
+ - tests/compat.sh -p OpenSSL -e 'NULL\|ECDH-\|DES\|RC4'
+ - tests/scripts/travis-log-failure.sh
+ # GnuTLS supports CAMELLIA but compat.sh doesn't properly enable it.
+ # Modern GnuTLS does not support DES.
+ # One NULL cipher suite is strangely missing in pre-1.2 protocol
+ # versions (it works with (D)TLS1.2, but don't bother).
+ - tests/compat.sh -p GnuTLS -e 'CAMELLIA\|DES\|TLS-RSA-WITH-NULL-SHA256'
+ - tests/scripts/travis-log-failure.sh
+ - tests/context-info.sh
- name: Windows
os: windows
diff --git a/ChangeLog.d/psa-ecb-ub.txt b/ChangeLog.d/psa-ecb-ub.txt
new file mode 100644
index 0000000..9d725ac
--- /dev/null
+++ b/ChangeLog.d/psa-ecb-ub.txt
@@ -0,0 +1,3 @@
+Bugfix
+ * Fix undefined behavior (typically harmless in practice) in PSA ECB
+ encryption and decryption.
diff --git a/library/aria.c b/library/aria.c
index 924f952..5e52eea 100644
--- a/library/aria.c
+++ b/library/aria.c
@@ -37,11 +37,6 @@
#include "mbedtls/platform_util.h"
-#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
- !defined(inline) && !defined(__cplusplus)
-#define inline __inline
-#endif
-
/* Parameter validation macros */
#define ARIA_VALIDATE_RET( cond ) \
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ARIA_BAD_INPUT_DATA )
diff --git a/library/chacha20.c b/library/chacha20.c
index 44d1612..bd07014 100644
--- a/library/chacha20.c
+++ b/library/chacha20.c
@@ -36,11 +36,6 @@
#if !defined(MBEDTLS_CHACHA20_ALT)
-#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
- !defined(inline) && !defined(__cplusplus)
-#define inline __inline
-#endif
-
/* Parameter validation macros */
#define CHACHA20_VALIDATE_RET( cond ) \
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA )
diff --git a/library/common.h b/library/common.h
index c064724..1663d50 100644
--- a/library/common.h
+++ b/library/common.h
@@ -29,8 +29,15 @@
#include "mbedtls/config.h"
#endif
+#include <stddef.h>
#include <stdint.h>
+/* Define `inline` on some non-C99-compliant compilers. */
+#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
@@ -52,6 +59,44 @@
#define MBEDTLS_STATIC_TESTABLE static
#endif
+/** Return an offset into a buffer.
+ *
+ * This is just the addition of an offset to a pointer, except that this
+ * function also accepts an offset of 0 into a buffer whose pointer is null.
+ * (`p + n` has undefined behavior when `p` is null, even when `n == 0`.
+ * A null pointer is a valid buffer pointer when the size is 0, for example
+ * as the result of `malloc(0)` on some platforms.)
+ *
+ * \param p Pointer to a buffer of at least n bytes.
+ * This may be \p NULL if \p n is zero.
+ * \param n An offset in bytes.
+ * \return Pointer to offset \p n in the buffer \p p.
+ * Note that this is only a valid pointer if the size of the
+ * buffer is at least \p n + 1.
+ */
+static inline unsigned char *mbedtls_buffer_offset(
+ unsigned char *p, size_t n )
+{
+ return( p == NULL ? NULL : p + n );
+}
+
+/** Return an offset into a read-only buffer.
+ *
+ * Similar to mbedtls_buffer_offset(), but for const pointers.
+ *
+ * \param p Pointer to a buffer of at least n bytes.
+ * This may be \p NULL if \p n is zero.
+ * \param n An offset in bytes.
+ * \return Pointer to offset \p n in the buffer \p p.
+ * Note that this is only a valid pointer if the size of the
+ * buffer is at least \p n + 1.
+ */
+static inline const unsigned char *mbedtls_buffer_offset_const(
+ const unsigned char *p, size_t n )
+{
+ return( p == NULL ? NULL : p + n );
+}
+
/** Byte Reading Macros
*
* Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th
diff --git a/library/debug.c b/library/debug.c
index 0cc5af8..353b4bf 100644
--- a/library/debug.c
+++ b/library/debug.c
@@ -30,11 +30,6 @@
#include <stdio.h>
#include <string.h>
-#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
- !defined(inline) && !defined(__cplusplus)
-#define inline __inline
-#endif
-
#define DEBUG_BUF_SIZE 512
static int debug_threshold = 0;
diff --git a/library/ecp.c b/library/ecp.c
index 80adc55..ad19e05 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -104,11 +104,6 @@
#endif
#endif /* MBEDTLS_ECP_NO_INTERNAL_RNG */
-#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
- !defined(inline) && !defined(__cplusplus)
-#define inline __inline
-#endif
-
#if defined(MBEDTLS_SELF_TEST)
/*
* Counts of point addition and doubling, and field multiplications.
diff --git a/library/ecp_curves.c b/library/ecp_curves.c
index 2199be6..47761ee 100644
--- a/library/ecp_curves.c
+++ b/library/ecp_curves.c
@@ -38,11 +38,6 @@
#define ECP_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
-#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
- !defined(inline) && !defined(__cplusplus)
-#define inline __inline
-#endif
-
#define ECP_MPI_INIT(s, n, p) {s, (n), (mbedtls_mpi_uint *)(p)}
#define ECP_MPI_INIT_ARRAY(x) \
diff --git a/library/mps_reader.c b/library/mps_reader.c
index 9af5073..b304db3 100644
--- a/library/mps_reader.c
+++ b/library/mps_reader.c
@@ -29,11 +29,6 @@
#include <string.h>
-#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
- !defined(inline) && !defined(__cplusplus)
-#define inline __inline
-#endif
-
#if defined(MBEDTLS_MPS_ENABLE_TRACE)
static int mbedtls_mps_trace_id = MBEDTLS_MPS_TRACE_BIT_READER;
#endif /* MBEDTLS_MPS_ENABLE_TRACE */
diff --git a/library/poly1305.c b/library/poly1305.c
index f38f48a..a1c5b19 100644
--- a/library/poly1305.c
+++ b/library/poly1305.c
@@ -32,11 +32,6 @@
#if !defined(MBEDTLS_POLY1305_ALT)
-#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
- !defined(inline) && !defined(__cplusplus)
-#define inline __inline
-#endif
-
/* Parameter validation macros */
#define POLY1305_VALIDATE_RET( cond ) \
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index f76c829..10c7d1e 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -3638,8 +3638,8 @@
status = psa_driver_wrapper_cipher_encrypt(
&attributes, slot->key.data, slot->key.bytes,
alg, local_iv, default_iv_length, input, input_length,
- output + default_iv_length, output_size - default_iv_length,
- output_length );
+ mbedtls_buffer_offset( output, default_iv_length ),
+ output_size - default_iv_length, output_length );
exit:
unlock_status = psa_unlock_key_slot( slot );
diff --git a/library/psa_crypto_cipher.c b/library/psa_crypto_cipher.c
index 38962cd..13006fa 100644
--- a/library/psa_crypto_cipher.c
+++ b/library/psa_crypto_cipher.c
@@ -514,9 +514,10 @@
if( status != PSA_SUCCESS )
goto exit;
- status = mbedtls_psa_cipher_finish( &operation, output + update_output_length,
- output_size - update_output_length,
- &finish_output_length );
+ status = mbedtls_psa_cipher_finish(
+ &operation,
+ mbedtls_buffer_offset( output, update_output_length ),
+ output_size - update_output_length, &finish_output_length );
if( status != PSA_SUCCESS )
goto exit;
@@ -560,17 +561,20 @@
goto exit;
}
- status = mbedtls_psa_cipher_update( &operation, input + operation.iv_length,
- input_length - operation.iv_length,
- output, output_size, &olength );
+ status = mbedtls_psa_cipher_update(
+ &operation,
+ mbedtls_buffer_offset_const( input, operation.iv_length ),
+ input_length - operation.iv_length,
+ output, output_size, &olength );
if( status != PSA_SUCCESS )
goto exit;
accumulated_length = olength;
- status = mbedtls_psa_cipher_finish( &operation, output + accumulated_length,
- output_size - accumulated_length,
- &olength );
+ status = mbedtls_psa_cipher_finish(
+ &operation,
+ mbedtls_buffer_offset( output, accumulated_length ),
+ output_size - accumulated_length, &olength );
if( status != PSA_SUCCESS )
goto exit;
diff --git a/tests/compat.sh b/tests/compat.sh
index 9d95518..6791c55 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -934,6 +934,20 @@
G_CLIENT_ARGS="-p $PORT --debug 3 $G_MODE"
G_CLIENT_PRIO="NONE:$G_PRIO_MODE:+COMP-NULL:+CURVE-ALL:+SIGN-ALL"
+ # Newer versions of OpenSSL have a syntax to enable all "ciphers", even
+ # low-security ones. This covers not just cipher suites but also protocol
+ # versions. It is necessary, for example, to use (D)TLS 1.0/1.1 on
+ # OpenSSL 1.1.1f from Ubuntu 20.04. The syntax was only introduced in
+ # OpenSSL 1.1.0 (21e0c1d23afff48601eb93135defddae51f7e2e3) and I can't find
+ # a way to discover it from -help, so check the openssl version.
+ case $($OPENSSL_CMD version) in
+ "OpenSSL 0"*|"OpenSSL 1.0"*) :;;
+ *)
+ O_CLIENT_ARGS="$O_CLIENT_ARGS -cipher ALL@SECLEVEL=0"
+ O_SERVER_ARGS="$O_SERVER_ARGS -cipher ALL@SECLEVEL=0"
+ ;;
+ esac
+
if [ "X$VERIFY" = "XYES" ];
then
M_SERVER_ARGS="$M_SERVER_ARGS ca_file=data_files/test-ca_cat12.crt auth_mode=required"
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index fbf3bf7..c1fffa9 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -1493,6 +1493,20 @@
O_LEGACY_CLI="$O_LEGACY_CLI -connect 127.0.0.1:+SRV_PORT"
fi
+# Newer versions of OpenSSL have a syntax to enable all "ciphers", even
+# low-security ones. This covers not just cipher suites but also protocol
+# versions. It is necessary, for example, to use (D)TLS 1.0/1.1 on
+# OpenSSL 1.1.1f from Ubuntu 20.04. The syntax was only introduced in
+# OpenSSL 1.1.0 (21e0c1d23afff48601eb93135defddae51f7e2e3) and I can't find
+# a way to discover it from -help, so check the openssl version.
+case $($OPENSSL_CMD version) in
+ "OpenSSL 0"*|"OpenSSL 1.0"*) :;;
+ *)
+ O_CLI="$O_CLI -cipher ALL@SECLEVEL=0"
+ O_SRV="$O_SRV -cipher ALL@SECLEVEL=0"
+ ;;
+esac
+
if [ -n "${OPENSSL_NEXT:-}" ]; then
O_NEXT_SRV="$O_NEXT_SRV -accept $SRV_PORT"
O_NEXT_CLI="$O_NEXT_CLI -connect 127.0.0.1:+SRV_PORT"
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index f9e9093..0f4e313 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -4,6 +4,7 @@
#include "mbedtls/asn1.h"
#include "mbedtls/asn1write.h"
#include "mbedtls/oid.h"
+#include "common.h"
/* For MBEDTLS_CTR_DRBG_MAX_REQUEST, knowing that psa_generate_random()
* uses mbedtls_ctr_drbg internally. */
@@ -2658,7 +2659,7 @@
TEST_LE_U( length, output_buffer_size );
output_length += length;
PSA_ASSERT( psa_cipher_finish( &operation,
- output + output_length,
+ mbedtls_buffer_offset( output, output_length ),
output_buffer_size - output_length,
&length ) );
output_length += length;
@@ -2676,7 +2677,7 @@
TEST_LE_U( length, output_buffer_size );
output_length += length;
PSA_ASSERT( psa_cipher_finish( &operation,
- output + output_length,
+ mbedtls_buffer_offset( output, output_length ),
output_buffer_size - output_length,
&length ) );
output_length += length;