Merge pull request #8528 from yanrayw/issue/6933/parse-max_early_data_size

TLS1.3 EarlyData: client: parse max_early_data_size
diff --git a/ChangeLog.d/8060.txt b/ChangeLog.d/8060.txt
new file mode 100644
index 0000000..a5fd93c
--- /dev/null
+++ b/ChangeLog.d/8060.txt
@@ -0,0 +1,4 @@
+Features
+    * The CCM and GCM modules no longer depend on MBEDTLS_CIPHER_C. People who
+      use CCM and GCM but don't need the Cipher API can now disable
+      MBEDTLS_CIPHER_C in order to save code size.
diff --git a/ChangeLog.d/add-block-cipher-no-decrypt.txt b/ChangeLog.d/add-block-cipher-no-decrypt.txt
new file mode 100644
index 0000000..d05bf86
--- /dev/null
+++ b/ChangeLog.d/add-block-cipher-no-decrypt.txt
@@ -0,0 +1,6 @@
+Features
+   * Enable the new option MBEDTLS_BLOCK_CIPHER_NO_DECRYPT to omit
+     the decryption direction of block ciphers (AES, ARIA, Camellia).
+     This affects both the low-level modules and the high-level APIs
+     (the cipher and PSA interfaces). This option is incompatible with modes
+     that use the decryption direction (ECB in PSA, CBC, XTS, KW) and with DES.
diff --git a/ChangeLog.d/armv8-aesce.txt b/ChangeLog.d/armv8-aesce.txt
new file mode 100644
index 0000000..ec5889c
--- /dev/null
+++ b/ChangeLog.d/armv8-aesce.txt
@@ -0,0 +1,3 @@
+Features
+   * Support use of Armv8-A Cryptographic Extensions for hardware acclerated
+     AES when compiling for Thumb (T32) or 32-bit Arm (A32).
diff --git a/configs/config-tfm.h b/configs/config-tfm.h
index 191e4c4..85b677b 100644
--- a/configs/config-tfm.h
+++ b/configs/config-tfm.h
@@ -21,16 +21,6 @@
 /* MBEDTLS_PSA_CRYPTO_SPM needs third-party files, so disable it. */
 #undef MBEDTLS_PSA_CRYPTO_SPM
 
-/* TF-M provides its own dummy implementations to save code size.
- * We don't have any way to disable the tests that need these feature,
- * so we just keep AES decryption enabled. We will resolve this through
- * an official way to disable AES decryption, then this deviation
- * will no longer be needed:
- * https://github.com/Mbed-TLS/mbedtls/issues/7368
- */
-#undef MBEDTLS_AES_SETKEY_DEC_ALT
-#undef MBEDTLS_AES_DECRYPT_ALT
-
 /* Use built-in platform entropy functions (TF-M provides its own). */
 #undef MBEDTLS_NO_PLATFORM_ENTROPY
 
@@ -38,3 +28,35 @@
  * but using the native allocator is faster and works better with
  * memory management analysis frameworks such as ASan. */
 #undef MBEDTLS_MEMORY_BUFFER_ALLOC_C
+
+// This macro is enabled in TFM Medium but is disabled here because it is
+// incompatible with baremetal builds in Mbed TLS.
+#undef MBEDTLS_PSA_CRYPTO_STORAGE_C
+
+// This macro is enabled in TFM Medium but is disabled here because it is
+// incompatible with baremetal builds in Mbed TLS.
+#undef MBEDTLS_ENTROPY_NV_SEED
+
+// These platform-related TF-M settings are not useful here.
+#undef MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+#undef MBEDTLS_PLATFORM_STD_MEM_HDR
+#undef MBEDTLS_PLATFORM_SNPRINTF_MACRO
+#undef MBEDTLS_PLATFORM_PRINTF_ALT
+#undef MBEDTLS_PLATFORM_STD_EXIT_SUCCESS
+#undef MBEDTLS_PLATFORM_STD_EXIT_FAILURE
+
+/*
+ * In order to get an example config that works cleanly out-of-the-box
+ * for both baremetal and non-baremetal builds, we detect baremetal builds
+ * and set this variable automatically.
+ */
+#if defined(__IAR_SYSTEMS_ICC__) || defined(__ARM_EABI__)
+#define MBEDTLS_NO_PLATFORM_ENTROPY
+#endif
+
+/***********************************************************************
+ * Local changes to crypto config below this delimiter
+ **********************************************************************/
+
+// We expect TF-M to pick this up soon
+#define MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
diff --git a/configs/ext/crypto_config_profile_medium.h b/configs/ext/crypto_config_profile_medium.h
index 682835a..63ed470 100644
--- a/configs/ext/crypto_config_profile_medium.h
+++ b/configs/ext/crypto_config_profile_medium.h
@@ -50,7 +50,7 @@
 //#define PSA_WANT_ALG_CFB                        1
 //#define PSA_WANT_ALG_CHACHA20_POLY1305          1
 //#define PSA_WANT_ALG_CTR                        1
-#define PSA_WANT_ALG_DETERMINISTIC_ECDSA        1
+//#define PSA_WANT_ALG_DETERMINISTIC_ECDSA        1
 //#define PSA_WANT_ALG_ECB_NO_PADDING             1
 #define PSA_WANT_ALG_ECDH                       1
 #define PSA_WANT_ALG_ECDSA                      1
@@ -105,33 +105,27 @@
 //#define PSA_WANT_KEY_TYPE_CAMELLIA              1
 //#define PSA_WANT_KEY_TYPE_CHACHA20              1
 //#define PSA_WANT_KEY_TYPE_DES                   1
-#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC    1
+//#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR          1 /* Deprecated */
+#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY        1
+#define PSA_WANT_KEY_TYPE_RAW_DATA              1
+//#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR          1 /* Deprecated */
+//#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY        1
+
+/*
+ * The following symbols extend and deprecate the legacy
+ * PSA_WANT_KEY_TYPE_xxx_KEY_PAIR ones. They include the usage of that key in
+ * the name's suffix. "_USE" is the most generic and it can be used to describe
+ * a generic suport, whereas other ones add more features on top of that and
+ * they are more specific.
+ */
+#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC      1
 #define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT   1
 #define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT   1
 #define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1
-#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE   1
-#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY        1
-#define PSA_WANT_KEY_TYPE_RAW_DATA              1
-//#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR          1
-//#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY        1
+//#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE   1
 
-/***********************************************************************
- * Local edits below this delimiter
- **********************************************************************/
-
-/* Between Mbed TLS 3.4 and 3.5, the PSA_WANT_KEY_TYPE_RSA_KEY_PAIR macro
- * (commented-out above) has been replaced with the following new macros: */
-//#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC      1
-//#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT     1
-//#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT     1
-//#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE   1
-//#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_DERIVE     1 /* Not supported */
-
-/* Between Mbed TLS 3.4 and 3.5, the following macros have been added: */
-//#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC       1
-//#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT    1
-//#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT    1
-//#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE  1
-//#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_DERIVE    1 // Not supported
+#ifdef CRYPTO_HW_ACCELERATOR
+#include "crypto_accelerator_config.h"
+#endif
 
 #endif /* PROFILE_M_PSA_CRYPTO_CONFIG_H */
diff --git a/configs/ext/tfm_mbedcrypto_config_profile_medium.h b/configs/ext/tfm_mbedcrypto_config_profile_medium.h
index 34a3bd4..beebddf 100644
--- a/configs/ext/tfm_mbedcrypto_config_profile_medium.h
+++ b/configs/ext/tfm_mbedcrypto_config_profile_medium.h
@@ -15,6 +15,8 @@
 #ifndef PROFILE_M_MBEDTLS_CONFIG_H
 #define PROFILE_M_MBEDTLS_CONFIG_H
 
+//#include "config_tfm.h"
+
 #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
 #define _CRT_SECURE_NO_DEPRECATE 1
 #endif
@@ -81,44 +83,6 @@
  */
 
 /**
- * \def MBEDTLS_MD2_PROCESS_ALT
- *
- * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you
- * alternate core implementation of symmetric crypto or hash function. Keep in
- * mind that function prototypes should remain the same.
- *
- * This replaces only one function. The header file from mbed TLS is still
- * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags.
- *
- * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will
- * no longer provide the mbedtls_sha1_process() function, but it will still provide
- * the other function (using your mbedtls_sha1_process() function) and the definition
- * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible
- * with this definition.
- *
- * \note Because of a signature change, the core AES encryption and decryption routines are
- *       currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt,
- *       respectively. When setting up alternative implementations, these functions should
- *       be overridden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt
- *       must stay untouched.
- *
- * \note If you use the AES_xxx_ALT macros, then is is recommended to also set
- *       MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES
- *       tables.
- *
- * Uncomment a macro to enable alternate implementation of the corresponding
- * function.
- *
- * \warning   MD2, MD4, MD5, DES and SHA-1 are considered weak and their use
- *            constitutes a security risk. If possible, we recommend avoiding
- *            dependencies on them, and considering stronger message digests
- *            and ciphers instead.
- *
- */
-#define MBEDTLS_AES_SETKEY_DEC_ALT
-#define MBEDTLS_AES_DECRYPT_ALT
-
-/**
  * \def MBEDTLS_AES_ROM_TABLES
  *
  * Use precomputed AES tables stored in ROM.
@@ -172,21 +136,6 @@
 #define MBEDTLS_ECP_NIST_OPTIM
 
 /**
- * \def MBEDTLS_ERROR_STRERROR_DUMMY
- *
- * Enable a dummy error function to make use of mbedtls_strerror() in
- * third party libraries easier when MBEDTLS_ERROR_C is disabled
- * (no effect when MBEDTLS_ERROR_C is enabled).
- *
- * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're
- * not using mbedtls_strerror() or error_strerror() in your application.
- *
- * Disable if you run into name conflicts and want to really remove the
- * mbedtls_strerror()
- */
-#define MBEDTLS_ERROR_STRERROR_DUMMY
-
-/**
  * \def MBEDTLS_NO_PLATFORM_ENTROPY
  *
  * Do not use built-in platform entropy functions.
@@ -223,26 +172,7 @@
  * \note The entropy collector will write to the seed file before entropy is
  *       given to an external source, to update it.
  */
-// This macro is enabled in TFM Medium but is disabled here because it is
-// incompatible with baremetal builds in Mbed TLS.
-//#define MBEDTLS_ENTROPY_NV_SEED
-
-/* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
- *
- * Enable key identifiers that encode a key owner identifier.
- *
- * This is only meaningful when building the library as part of a
- * multi-client service. When you activate this option, you must provide an
- * implementation of the type mbedtls_key_owner_id_t and a translation from
- * mbedtls_svc_key_id_t to file name in all the storage backends that you
- * you wish to support.
- *
- * Note that while this define has been removed from TF-M's copy of this config
- * file, TF-M still passes this option to Mbed TLS during the build via CMake.
- * Therefore we keep it in our copy. See discussion on PR #7426 for more info.
- *
- */
-#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
+#define MBEDTLS_ENTROPY_NV_SEED
 
 /**
  * \def MBEDTLS_PSA_CRYPTO_SPM
@@ -326,6 +256,23 @@
 #define MBEDTLS_AES_C
 
 /**
+ * \def MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+ *
+ * Use only 128-bit keys in AES operations to save ROM.
+ *
+ * Uncomment this macro to remove support for AES operations that use 192-
+ * or 256-bit keys.
+ *
+ * Uncommenting this macro reduces the size of AES code by ~300 bytes
+ * on v8-M/Thumb2.
+ *
+ * Module:  library/aes.c
+ *
+ * Requires: MBEDTLS_AES_C
+ */
+#define MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+
+/**
  * \def MBEDTLS_CIPHER_C
  *
  * Enable the generic cipher layer.
@@ -367,18 +314,6 @@
 #define MBEDTLS_ENTROPY_C
 
 /**
- * \def MBEDTLS_ERROR_C
- *
- * Enable error code to error string conversion.
- *
- * Module:  library/error.c
- * Caller:
- *
- * This module enables mbedtls_strerror().
- */
-#define MBEDTLS_ERROR_C
-
-/**
  * \def MBEDTLS_HKDF_C
  *
  * Enable the HKDF algorithm (RFC 5869).
@@ -391,40 +326,7 @@
  * This module adds support for the Hashed Message Authentication Code
  * (HMAC)-based key derivation function (HKDF).
  */
-#define MBEDTLS_HKDF_C /* Used for HUK deriviation */
-
-/**
- * \def MBEDTLS_MD_C
- *
- * Enable the generic layer for message digest (hashing) and HMAC.
- *
- * Requires: one of: MBEDTLS_MD5_C, MBEDTLS_RIPEMD160_C, MBEDTLS_SHA1_C,
- *                   MBEDTLS_SHA224_C, MBEDTLS_SHA256_C, MBEDTLS_SHA384_C,
- *                   MBEDTLS_SHA512_C, or MBEDTLS_PSA_CRYPTO_C with at least
- *                   one hash.
- * Module:  library/md.c
- * Caller:  library/constant_time.c
- *          library/ecdsa.c
- *          library/ecjpake.c
- *          library/hkdf.c
- *          library/hmac_drbg.c
- *          library/pk.c
- *          library/pkcs5.c
- *          library/pkcs12.c
- *          library/psa_crypto_ecp.c
- *          library/psa_crypto_rsa.c
- *          library/rsa.c
- *          library/ssl_cookie.c
- *          library/ssl_msg.c
- *          library/ssl_tls.c
- *          library/x509.c
- *          library/x509_crt.c
- *          library/x509write_crt.c
- *          library/x509write_csr.c
- *
- * Uncomment to enable generic message digest wrappers.
- */
-#define MBEDTLS_MD_C
+//#define MBEDTLS_HKDF_C /* Used for HUK deriviation */
 
 /**
  * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C
@@ -462,6 +364,15 @@
  */
 #define MBEDTLS_PLATFORM_C
 
+#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+#define MBEDTLS_PLATFORM_STD_MEM_HDR   <stdlib.h>
+
+#include <stdio.h>
+
+#define MBEDTLS_PLATFORM_SNPRINTF_MACRO      snprintf
+#define MBEDTLS_PLATFORM_PRINTF_ALT
+#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS  EXIT_SUCCESS
+#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE  EXIT_FAILURE
 
 /**
  * \def MBEDTLS_PSA_CRYPTO_C
@@ -486,9 +397,7 @@
  *           either MBEDTLS_PSA_ITS_FILE_C or a native implementation of
  *           the PSA ITS interface
  */
-// This macro is enabled in TFM Medium but is disabled here because it is
-// incompatible with baremetal builds in Mbed TLS.
-//#define MBEDTLS_PSA_CRYPTO_STORAGE_C
+#define MBEDTLS_PSA_CRYPTO_STORAGE_C
 
 /* \} name SECTION: mbed TLS modules */
 
@@ -592,6 +501,47 @@
 /* ECP options */
 #define MBEDTLS_ECP_FIXED_POINT_OPTIM        0 /**< Disable fixed-point speed-up */
 
+/**
+ * Uncomment to enable p256-m. This is an alternative implementation of
+ * key generation, ECDH and (randomized) ECDSA on the curve SECP256R1.
+ * Compared to the default implementation:
+ *
+ * - p256-m has a much smaller code size and RAM footprint.
+ * - p256-m is only available via the PSA API. This includes the pk module
+ *   when #MBEDTLS_USE_PSA_CRYPTO is enabled.
+ * - p256-m does not support deterministic ECDSA, EC-JPAKE, custom protocols
+ *   over the core arithmetic, or deterministic derivation of keys.
+ *
+ * We recommend enabling this option if your application uses the PSA API
+ * and the only elliptic curve support it needs is ECDH and ECDSA over
+ * SECP256R1.
+ *
+ * If you enable this option, you do not need to enable any ECC-related
+ * MBEDTLS_xxx option. You do need to separately request support for the
+ * cryptographic mechanisms through the PSA API:
+ * - #MBEDTLS_PSA_CRYPTO_C and #MBEDTLS_PSA_CRYPTO_CONFIG for PSA-based
+ *   configuration;
+ * - #MBEDTLS_USE_PSA_CRYPTO if you want to use p256-m from PK, X.509 or TLS;
+ * - #PSA_WANT_ECC_SECP_R1_256;
+ * - #PSA_WANT_ALG_ECDH and/or #PSA_WANT_ALG_ECDSA as needed;
+ * - #PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY, #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC,
+ *   #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT,
+ *   #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT and/or
+ *   #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE as needed.
+ *
+ * \note To benefit from the smaller code size of p256-m, make sure that you
+ *       do not enable any ECC-related option not supported by p256-m: this
+ *       would cause the built-in ECC implementation to be built as well, in
+ *       order to provide the required option.
+ *       Make sure #PSA_WANT_ALG_DETERMINISTIC_ECDSA, #PSA_WANT_ALG_JPAKE and
+ *       #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE, and curves other than
+ *       SECP256R1 are disabled as they are not supported by this driver.
+ *       Also, avoid defining #MBEDTLS_PK_PARSE_EC_COMPRESSED or
+ *       #MBEDTLS_PK_PARSE_EC_EXTENDED as those currently require a subset of
+ *       the built-in ECC implementation, see docs/driver-only-builds.md.
+ */
+#define MBEDTLS_PSA_P256M_DRIVER_ENABLED
+
 /* \} name SECTION: Customisation configuration options */
 
 #if CRYPTO_NV_SEED
@@ -599,7 +549,7 @@
 #endif /* CRYPTO_NV_SEED */
 
 #if !defined(CRYPTO_HW_ACCELERATOR) && defined(MBEDTLS_ENTROPY_NV_SEED)
-#include "mbedtls_entropy_nv_seed_config.h"
+//#include "mbedtls_entropy_nv_seed_config.h"
 #endif
 
 #ifdef CRYPTO_HW_ACCELERATOR
diff --git a/include/mbedtls/aes.h b/include/mbedtls/aes.h
index 77ecffd..d5eb1fd 100644
--- a/include/mbedtls/aes.h
+++ b/include/mbedtls/aes.h
@@ -155,6 +155,7 @@
 int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
                            unsigned int keybits);
 
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
 /**
  * \brief          This function sets the decryption key.
  *
@@ -173,6 +174,7 @@
 MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
                            unsigned int keybits);
+#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
 
 #if defined(MBEDTLS_CIPHER_MODE_XTS)
 /**
@@ -592,6 +594,7 @@
                                  const unsigned char input[16],
                                  unsigned char output[16]);
 
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
 /**
  * \brief           Internal AES block decryption function. This is only
  *                  exposed to allow overriding it using see
@@ -607,6 +610,7 @@
 int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
                                  const unsigned char input[16],
                                  unsigned char output[16]);
+#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
 
 #if defined(MBEDTLS_SELF_TEST)
 /**
diff --git a/include/mbedtls/aria.h b/include/mbedtls/aria.h
index abb8a3d..c685fc3 100644
--- a/include/mbedtls/aria.h
+++ b/include/mbedtls/aria.h
@@ -98,6 +98,7 @@
                             const unsigned char *key,
                             unsigned int keybits);
 
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
 /**
  * \brief          This function sets the decryption key.
  *
@@ -116,6 +117,7 @@
 int mbedtls_aria_setkey_dec(mbedtls_aria_context *ctx,
                             const unsigned char *key,
                             unsigned int keybits);
+#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
 
 /**
  * \brief          This function performs an ARIA single-block encryption or
diff --git a/include/mbedtls/build_info.h b/include/mbedtls/build_info.h
index 44ecacf..7a70e25 100644
--- a/include/mbedtls/build_info.h
+++ b/include/mbedtls/build_info.h
@@ -62,6 +62,11 @@
 #define MBEDTLS_ARCH_IS_X86
 #endif
 
+#if !defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64) && \
+    (defined(_M_ARM64) || defined(_M_ARM64EC))
+#define MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64
+#endif
+
 /* This is defined if the architecture is Armv8-A, or higher */
 #if !defined(MBEDTLS_ARCH_IS_ARMV8_A)
 #if defined(__ARM_ARCH) && defined(__ARM_ARCH_PROFILE)
diff --git a/include/mbedtls/camellia.h b/include/mbedtls/camellia.h
index 6c674fe..557f472 100644
--- a/include/mbedtls/camellia.h
+++ b/include/mbedtls/camellia.h
@@ -81,6 +81,7 @@
                                 const unsigned char *key,
                                 unsigned int keybits);
 
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
 /**
  * \brief          Perform a CAMELLIA key schedule operation for decryption.
  *
@@ -96,6 +97,7 @@
 int mbedtls_camellia_setkey_dec(mbedtls_camellia_context *ctx,
                                 const unsigned char *key,
                                 unsigned int keybits);
+#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
 
 /**
  * \brief          Perform a CAMELLIA-ECB block encryption/decryption operation.
diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h
index a98111b..8bf8c32 100644
--- a/include/mbedtls/ccm.h
+++ b/include/mbedtls/ccm.h
@@ -40,6 +40,10 @@
 
 #include "mbedtls/cipher.h"
 
+#if !defined(MBEDTLS_CIPHER_C)
+#include "mbedtls/block_cipher.h"
+#endif
+
 #define MBEDTLS_CCM_DECRYPT       0
 #define MBEDTLS_CCM_ENCRYPT       1
 #define MBEDTLS_CCM_STAR_DECRYPT  2
@@ -80,7 +84,11 @@
                                               #MBEDTLS_CCM_DECRYPT or
                                               #MBEDTLS_CCM_STAR_ENCRYPT or
                                               #MBEDTLS_CCM_STAR_DECRYPT. */
+#if defined(MBEDTLS_CIPHER_C)
     mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx);    /*!< The cipher context used. */
+#else
+    mbedtls_block_cipher_context_t MBEDTLS_PRIVATE(block_cipher_ctx);    /*!< The cipher context used. */
+#endif
     int MBEDTLS_PRIVATE(state);              /*!< Working value holding context's
                                                   state. Used for chunked data input */
 }
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 951db31..9b5b646 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -171,6 +171,36 @@
 #error "MBEDTLS_NIST_KW_C defined, but not all prerequisites"
 #endif
 
+#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) && defined(MBEDTLS_PSA_CRYPTO_CONFIG)
+#if defined(PSA_WANT_ALG_CBC_NO_PADDING)
+#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and PSA_WANT_ALG_CBC_NO_PADDING cannot be defined simultaneously"
+#endif
+#if defined(PSA_WANT_ALG_CBC_PKCS7)
+#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and PSA_WANT_ALG_CBC_PKCS7 cannot be defined simultaneously"
+#endif
+#if defined(PSA_WANT_ALG_ECB_NO_PADDING)
+#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and PSA_WANT_ALG_ECB_NO_PADDING cannot be defined simultaneously"
+#endif
+#if defined(PSA_WANT_KEY_TYPE_DES)
+#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and PSA_WANT_KEY_TYPE_DES cannot be defined simultaneously"
+#endif
+#endif
+
+#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and MBEDTLS_CIPHER_MODE_CBC cannot be defined simultaneously"
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and MBEDTLS_CIPHER_MODE_XTS cannot be defined simultaneously"
+#endif
+#if defined(MBEDTLS_DES_C)
+#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and MBEDTLS_DES_C cannot be defined simultaneously"
+#endif
+#if defined(MBEDTLS_NIST_KW_C)
+#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and MBEDTLS_NIST_KW_C cannot be defined simultaneously"
+#endif
+#endif
+
 #if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C)
 #error "MBEDTLS_ECDH_C defined, but not all prerequisites"
 #endif
@@ -306,19 +336,11 @@
 #error "MBEDTLS_CCM_C defined, but not all prerequisites"
 #endif
 
-#if defined(MBEDTLS_CCM_C) && !defined(MBEDTLS_CIPHER_C)
-#error "MBEDTLS_CCM_C defined, but not all prerequisites"
-#endif
-
 #if defined(MBEDTLS_GCM_C) && (                                        \
     !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) && !defined(MBEDTLS_ARIA_C) )
 #error "MBEDTLS_GCM_C defined, but not all prerequisites"
 #endif
 
-#if defined(MBEDTLS_GCM_C) && !defined(MBEDTLS_CIPHER_C)
-#error "MBEDTLS_GCM_C defined, but not all prerequisites"
-#endif
-
 #if defined(MBEDTLS_CHACHAPOLY_C) && !defined(MBEDTLS_CHACHA20_C)
 #error "MBEDTLS_CHACHAPOLY_C defined, but not all prerequisites"
 #endif
@@ -763,9 +785,8 @@
 #error "MBEDTLS_PSA_CRYPTO_C defined, but not all prerequisites (missing RNG)"
 #endif
 
-#if defined(MBEDTLS_PSA_CRYPTO_C) && \
-    (defined(PSA_HAVE_SOFT_BLOCK_CIPHER) || defined(PSA_HAVE_SOFT_BLOCK_AEAD)) && \
-    !defined(MBEDTLS_CIPHER_C)
+#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_HAVE_SOFT_BLOCK_MODE) && \
+    defined(PSA_HAVE_SOFT_BLOCK_CIPHER) && !defined(MBEDTLS_CIPHER_C)
 #error "MBEDTLS_PSA_CRYPTO_C defined, but not all prerequisites"
 #endif
 
diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h
index 2596baa..815b5bb 100644
--- a/include/mbedtls/cipher.h
+++ b/include/mbedtls/cipher.h
@@ -480,7 +480,7 @@
     if (info == NULL) {
         return 0;
     } else {
-        return info->MBEDTLS_PRIVATE(key_bitlen) << MBEDTLS_KEY_BITLEN_SHIFT;
+        return ((size_t) info->MBEDTLS_PRIVATE(key_bitlen)) << MBEDTLS_KEY_BITLEN_SHIFT;
     }
 }
 
diff --git a/include/mbedtls/config_adjust_legacy_crypto.h b/include/mbedtls/config_adjust_legacy_crypto.h
index c60e1e3..e66d67a 100644
--- a/include/mbedtls/config_adjust_legacy_crypto.h
+++ b/include/mbedtls/config_adjust_legacy_crypto.h
@@ -22,8 +22,8 @@
 #ifndef MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H
 #define MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H
 
-/* Temporary hack to pacify check_names.py.
- * (GCM and CCM still hard-depend on CIPHER_C for now.) */
+/* GCM_C and CCM_C can either depend on (in order of preference) CIPHER_C or
+ * BLOCK_CIPHER_C. If the former is not defined, auto-enable the latter. */
 #if (defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C)) && \
     !defined(MBEDTLS_CIPHER_C)
 #define MBEDTLS_BLOCK_CIPHER_C
diff --git a/include/mbedtls/config_adjust_psa_from_legacy.h b/include/mbedtls/config_adjust_psa_from_legacy.h
index 60b00c1..b841875 100644
--- a/include/mbedtls/config_adjust_psa_from_legacy.h
+++ b/include/mbedtls/config_adjust_psa_from_legacy.h
@@ -25,9 +25,11 @@
 
 #if defined(MBEDTLS_CCM_C)
 #define MBEDTLS_PSA_BUILTIN_ALG_CCM 1
-#define MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG 1
 #define PSA_WANT_ALG_CCM 1
+#if defined(MBEDTLS_CIPHER_C)
+#define MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG 1
 #define PSA_WANT_ALG_CCM_STAR_NO_TAG 1
+#endif /* MBEDTLS_CIPHER_C */
 #endif /* MBEDTLS_CCM_C */
 
 #if defined(MBEDTLS_CMAC_C)
@@ -247,8 +249,9 @@
 #endif
 #endif
 
-#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) || \
-    defined(MBEDTLS_ARIA_C) || defined(MBEDTLS_CAMELLIA_C)
+#if (defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) || \
+    defined(MBEDTLS_ARIA_C) || defined(MBEDTLS_CAMELLIA_C)) && \
+    defined(MBEDTLS_CIPHER_C)
 #define MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING 1
 #define PSA_WANT_ALG_ECB_NO_PADDING 1
 #endif
diff --git a/include/mbedtls/gcm.h b/include/mbedtls/gcm.h
index 837cecc..3925f68 100644
--- a/include/mbedtls/gcm.h
+++ b/include/mbedtls/gcm.h
@@ -24,6 +24,10 @@
 
 #include "mbedtls/cipher.h"
 
+#if !defined(MBEDTLS_CIPHER_C)
+#include "mbedtls/block_cipher.h"
+#endif
+
 #include <stdint.h>
 
 #define MBEDTLS_GCM_ENCRYPT     1
@@ -46,7 +50,11 @@
  * \brief          The GCM context structure.
  */
 typedef struct mbedtls_gcm_context {
+#if defined(MBEDTLS_CIPHER_C)
     mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx);  /*!< The cipher context used. */
+#else
+    mbedtls_block_cipher_context_t MBEDTLS_PRIVATE(block_cipher_ctx);  /*!< The cipher context used. */
+#endif
     uint64_t MBEDTLS_PRIVATE(HL)[16];                      /*!< Precalculated HTable low. */
     uint64_t MBEDTLS_PRIVATE(HH)[16];                      /*!< Precalculated HTable high. */
     uint64_t MBEDTLS_PRIVATE(len);                         /*!< The total length of the encrypted data. */
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index a4e90c5..96a3e43 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -2238,7 +2238,7 @@
 /**
  * \def MBEDTLS_AESCE_C
  *
- * Enable AES cryptographic extension support on 64-bit Arm.
+ * Enable AES cryptographic extension support on Armv8.
  *
  * Module:  library/aesce.c
  * Caller:  library/aes.c
@@ -2249,13 +2249,15 @@
  *          system, Armv8-A Cryptographic Extensions must be supported by
  *          the CPU when this option is enabled.
  *
- * \note    Minimum compiler versions for this feature are Clang 4.0,
- *          armclang 6.6, GCC 6.0 or MSVC 2019 version 16.11.2.
+ * \note    Minimum compiler versions for this feature when targeting aarch64
+ *          are Clang 4.0; armclang 6.6; GCC 6.0; or MSVC 2019 version 16.11.2.
+ *          Minimum compiler versions for this feature when targeting 32-bit
+ *          Arm or Thumb are Clang 11.0; armclang 6.20; or GCC 6.0.
  *
  * \note \c CFLAGS must be set to a minimum of \c -march=armv8-a+crypto for
  * armclang <= 6.9
  *
- * This module adds support for the AES Armv8-A Cryptographic Extensions on Aarch64 systems.
+ * This module adds support for the AES Armv8-A Cryptographic Extensions on Armv8 systems.
  */
 #define MBEDTLS_AESCE_C
 
@@ -2375,6 +2377,28 @@
 #define MBEDTLS_BASE64_C
 
 /**
+ * \def MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
+ *
+ * Remove decryption operation for AES, ARIA and Camellia block cipher.
+ *
+ * \note  This feature is incompatible with insecure block cipher,
+ *        MBEDTLS_DES_C, and cipher modes which always require decryption
+ *        operation, MBEDTLS_CIPHER_MODE_CBC, MBEDTLS_CIPHER_MODE_XTS and
+ *        MBEDTLS_NIST_KW_C. When #MBEDTLS_PSA_CRYPTO_CONFIG is enabled,
+ *        this feature is incompatible with following supported PSA equivalence,
+ *        PSA_WANT_ALG_ECB_NO_PADDING, PSA_WANT_ALG_CBC_NO_PADDING,
+ *        PSA_WANT_ALG_CBC_PKCS7 and PSA_WANT_KEY_TYPE_DES.
+ *
+ * Module:  library/aes.c
+ *          library/aesce.c
+ *          library/aesni.c
+ *          library/aria.c
+ *          library/camellia.c
+ *          library/cipher.c
+ */
+//#define MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
+
+/**
  * \def MBEDTLS_BIGNUM_C
  *
  * Enable the multi-precision integer library.
diff --git a/include/mbedtls/threading.h b/include/mbedtls/threading.h
index ed16a23..b504233 100644
--- a/include/mbedtls/threading.h
+++ b/include/mbedtls/threading.h
@@ -28,10 +28,14 @@
 #include <pthread.h>
 typedef struct mbedtls_threading_mutex_t {
     pthread_mutex_t MBEDTLS_PRIVATE(mutex);
-    /* is_valid is 0 after a failed init or a free, and nonzero after a
-     * successful init. This field is not considered part of the public
-     * API of Mbed TLS and may change without notice. */
-    char MBEDTLS_PRIVATE(is_valid);
+
+    /* WARNING - state should only be accessed when holding the mutex lock in
+     * tests/src/threading_helpers.c, otherwise corruption can occur.
+     * state will be 0 after a failed init or a free, and nonzero after a
+     * successful init. This field is for testing only and thus not considered
+     * part of the public API of Mbed TLS and may change without notice.*/
+    char MBEDTLS_PRIVATE(state);
+
 } mbedtls_threading_mutex_t;
 #endif
 
diff --git a/library/aes.c b/library/aes.c
index 05f4c3c..f4b9739 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -23,9 +23,9 @@
 #include "mbedtls/error.h"
 
 #if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
-#if !((defined(MBEDTLS_ARCH_IS_ARM64) && defined(MBEDTLS_AESCE_C)) || \
-    (defined(MBEDTLS_ARCH_IS_X64)   && defined(MBEDTLS_AESNI_C)) || \
-    (defined(MBEDTLS_ARCH_IS_X86)   && defined(MBEDTLS_AESNI_C)))
+#if !((defined(MBEDTLS_ARCH_IS_ARMV8_A) && defined(MBEDTLS_AESCE_C)) || \
+    (defined(MBEDTLS_ARCH_IS_X64)       && defined(MBEDTLS_AESNI_C)) || \
+    (defined(MBEDTLS_ARCH_IS_X86)       && defined(MBEDTLS_AESNI_C)))
 #error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
 #endif
 #endif
@@ -54,6 +54,16 @@
 
 #include "mbedtls/platform.h"
 
+/*
+ * This is a convenience shorthand macro to check if we need reverse S-box and
+ * reverse tables. It's private and only defined in this file.
+ */
+#if (!defined(MBEDTLS_AES_DECRYPT_ALT) || \
+    (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY))) && \
+    !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
+#define MBEDTLS_AES_NEED_REVERSE_TABLES
+#endif
+
 #if !defined(MBEDTLS_AES_ALT)
 
 #if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
@@ -389,7 +399,9 @@
      * generate the forward and reverse S-boxes
      */
     FSb[0x00] = 0x63;
+#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
     RSb[0x63] = 0x00;
+#endif
 
     for (i = 1; i < 256; i++) {
         x = pow[255 - log[i]];
@@ -401,7 +413,9 @@
         x ^= y ^ 0x63;
 
         FSb[i] = x;
+#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
         RSb[x] = (unsigned char) i;
+#endif
     }
 
     /*
@@ -423,10 +437,9 @@
         FT3[i] = ROTL8(FT2[i]);
 #endif /* !MBEDTLS_AES_FEWER_TABLES */
 
+#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
         x = RSb[i];
 
-#if !defined(MBEDTLS_AES_DECRYPT_ALT) || \
-        (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY))
         RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
                  ((uint32_t) MUL(0x09, x) <<  8) ^
                  ((uint32_t) MUL(0x0D, x) << 16) ^
@@ -437,8 +450,7 @@
         RT2[i] = ROTL8(RT1[i]);
         RT3[i] = ROTL8(RT2[i]);
 #endif /* !MBEDTLS_AES_FEWER_TABLES */
-#endif \
-        /* !defined(MBEDTLS_AES_DECRYPT_ALT) || (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)) */
+#endif /* MBEDTLS_AES_NEED_REVERSE_TABLES */
     }
 }
 
@@ -670,7 +682,7 @@
 /*
  * AES key schedule (decryption)
  */
-#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
+#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
 int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
                            unsigned int keybits)
 {
@@ -739,7 +751,7 @@
 
     return ret;
 }
-#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
+#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT && !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
 
 #if defined(MBEDTLS_CIPHER_MODE_XTS)
 static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
@@ -928,7 +940,7 @@
 /*
  * AES-ECB block decryption
  */
-#if !defined(MBEDTLS_AES_DECRYPT_ALT)
+#if !defined(MBEDTLS_AES_DECRYPT_ALT) && !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
 int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
                                  const unsigned char input[16],
                                  unsigned char output[16])
@@ -985,7 +997,7 @@
 
     return 0;
 }
-#endif /* !MBEDTLS_AES_DECRYPT_ALT */
+#endif /* !MBEDTLS_AES_DECRYPT_ALT && !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
 
 /* VIA Padlock and our intrinsics-based implementation of AESNI require
  * the round keys to be aligned on a 16-byte boundary. We take care of this
@@ -1040,13 +1052,15 @@
 #endif
 
 #if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
-    if (mode == MBEDTLS_AES_ENCRYPT) {
-        return mbedtls_internal_aes_encrypt(ctx, input, output);
-    } else {
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
+    if (mode == MBEDTLS_AES_DECRYPT) {
         return mbedtls_internal_aes_decrypt(ctx, input, output);
-    }
+    } else
 #endif
-
+    {
+        return mbedtls_internal_aes_encrypt(ctx, input, output);
+    }
+#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
 }
 
 #if defined(MBEDTLS_CIPHER_MODE_CBC)
@@ -1472,6 +1486,7 @@
  *
  * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
  */
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
 static const unsigned char aes_test_ecb_dec[][16] =
 {
     { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
@@ -1483,6 +1498,7 @@
       0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
 #endif
 };
+#endif
 
 static const unsigned char aes_test_ecb_enc[][16] =
 {
@@ -1864,7 +1880,7 @@
      */
     {
         static const int num_tests =
-            sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
+            sizeof(aes_test_ecb_enc) / sizeof(*aes_test_ecb_enc);
 
         for (i = 0; i < num_tests << 1; i++) {
             u = i >> 1;
@@ -1875,13 +1891,24 @@
                 mbedtls_printf("  AES-ECB-%3u (%s): ", keybits,
                                (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
             }
+#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
+            if (mode == MBEDTLS_AES_DECRYPT) {
+                if (verbose != 0) {
+                    mbedtls_printf("skipped\n");
+                }
+                continue;
+            }
+#endif
 
             memset(buf, 0, 16);
 
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
             if (mode == MBEDTLS_AES_DECRYPT) {
                 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
                 aes_tests = aes_test_ecb_dec[u];
-            } else {
+            } else
+#endif
+            {
                 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
                 aes_tests = aes_test_ecb_enc[u];
             }
diff --git a/library/aesce.c b/library/aesce.c
index f2bdce2..eaaa5b5 100644
--- a/library/aesce.c
+++ b/library/aesce.c
@@ -5,8 +5,17 @@
  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
  */
 
-#if defined(__aarch64__) && !defined(__ARM_FEATURE_CRYPTO) && \
-    defined(__clang__) && __clang_major__ >= 4
+#if defined(__clang__) &&  (__clang_major__ >= 4)
+
+/* Ideally, we would simply use MBEDTLS_ARCH_IS_ARMV8_A in the following #if,
+ * but that is defined by build_info.h, and we need this block to happen first. */
+#if defined(__ARM_ARCH)
+#if __ARM_ARCH >= 8
+#define MBEDTLS_AESCE_ARCH_IS_ARMV8_A
+#endif
+#endif
+
+#if defined(MBEDTLS_AESCE_ARCH_IS_ARMV8_A) && !defined(__ARM_FEATURE_CRYPTO)
 /* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
  *
  * The intrinsic declaration are guarded by predefined ACLE macros in clang:
@@ -14,7 +23,7 @@
  * By defining the macros ourselves we gain access to those declarations without
  * requiring -march on the command line.
  *
- * `arm_neon.h` could be included by any header file, so we put these defines
+ * `arm_neon.h` is included by common.h, so we put these defines
  * at the top of this file, before any includes.
  */
 #define __ARM_FEATURE_CRYPTO 1
@@ -27,6 +36,8 @@
 #define MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG
 #endif
 
+#endif /* defined(__clang__) &&  (__clang_major__ >= 4) */
+
 #include <string.h>
 #include "common.h"
 
@@ -34,12 +45,14 @@
 
 #include "aesce.h"
 
-#if defined(MBEDTLS_ARCH_IS_ARM64)
+#if defined(MBEDTLS_AESCE_HAVE_CODE)
 
 /* Compiler version checks. */
 #if defined(__clang__)
-#   if __clang_major__ < 4
-#       error "Minimum version of Clang for MBEDTLS_AESCE_C is 4.0."
+#   if defined(MBEDTLS_ARCH_IS_ARM32) && (__clang_major__ < 11)
+#       error "Minimum version of Clang for MBEDTLS_AESCE_C on 32-bit Arm or Thumb is 11.0."
+#   elif defined(MBEDTLS_ARCH_IS_ARM64) && (__clang_major__ < 4)
+#       error "Minimum version of Clang for MBEDTLS_AESCE_C on aarch64 is 4.0."
 #   endif
 #elif defined(__GNUC__)
 #   if __GNUC__ < 6
@@ -52,12 +65,15 @@
 #   if _MSC_VER < 1929
 #       error "Minimum version of MSVC for MBEDTLS_AESCE_C is 2019 version 16.11.2."
 #   endif
-#endif
-
-#ifdef __ARM_NEON
-#include <arm_neon.h>
-#else
-#error "Target does not support NEON instructions"
+#elif defined(__ARMCC_VERSION)
+#    if defined(MBEDTLS_ARCH_IS_ARM32) && (__ARMCC_VERSION < 6200002)
+/* TODO: We haven't verified armclang for 32-bit Arm/Thumb prior to 6.20.
+ * If someone verified that, please update this and document of
+ * `MBEDTLS_AESCE_C` in `mbedtls_config.h`. */
+#         error "Minimum version of armclang for MBEDTLS_AESCE_C on 32-bit Arm is 6.20."
+#    elif defined(MBEDTLS_ARCH_IS_ARM64) && (__ARMCC_VERSION < 6060000)
+#         error "Minimum version of armclang for MBEDTLS_AESCE_C on aarch64 is 6.6."
+#    endif
 #endif
 
 #if !(defined(__ARM_FEATURE_CRYPTO) || defined(__ARM_FEATURE_AES)) || \
@@ -84,8 +100,19 @@
 
 #if defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
 
-#include <asm/hwcap.h>
 #include <sys/auxv.h>
+#if !defined(HWCAP_NEON)
+#define HWCAP_NEON  (1 << 12)
+#endif
+#if !defined(HWCAP2_AES)
+#define HWCAP2_AES  (1 << 0)
+#endif
+#if !defined(HWCAP_AES)
+#define HWCAP_AES   (1 << 3)
+#endif
+#if !defined(HWCAP_ASIMD)
+#define HWCAP_ASIMD (1 << 1)
+#endif
 
 signed char mbedtls_aesce_has_support_result = -1;
 
@@ -102,6 +129,16 @@
      * once, but that is harmless.
      */
     if (mbedtls_aesce_has_support_result == -1) {
+#if defined(MBEDTLS_ARCH_IS_ARM32)
+        unsigned long auxval  = getauxval(AT_HWCAP);
+        unsigned long auxval2 = getauxval(AT_HWCAP2);
+        if (((auxval  & HWCAP_NEON) == HWCAP_NEON) &&
+            ((auxval2 & HWCAP2_AES) == HWCAP2_AES)) {
+            mbedtls_aesce_has_support_result = 1;
+        } else {
+            mbedtls_aesce_has_support_result = 0;
+        }
+#else
         unsigned long auxval = getauxval(AT_HWCAP);
         if ((auxval & (HWCAP_ASIMD | HWCAP_AES)) ==
             (HWCAP_ASIMD | HWCAP_AES)) {
@@ -109,6 +146,7 @@
         } else {
             mbedtls_aesce_has_support_result = 0;
         }
+#endif
     }
     return mbedtls_aesce_has_support_result;
 }
@@ -187,6 +225,7 @@
 /* Two rounds of AESCE decryption */
 #define AESCE_DECRYPT_ROUND_X2        AESCE_DECRYPT_ROUND; AESCE_DECRYPT_ROUND
 
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
 static uint8x16_t aesce_decrypt_block(uint8x16_t block,
                                       unsigned char *keys,
                                       int rounds)
@@ -218,6 +257,7 @@
 
     return block;
 }
+#endif
 
 /*
  * AES-ECB block en(de)cryption
@@ -230,10 +270,15 @@
     uint8x16_t block = vld1q_u8(&input[0]);
     unsigned char *keys = (unsigned char *) (ctx->buf + ctx->rk_offset);
 
-    if (mode == MBEDTLS_AES_ENCRYPT) {
-        block = aesce_encrypt_block(block, keys, ctx->nr);
-    } else {
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
+    if (mode == MBEDTLS_AES_DECRYPT) {
         block = aesce_decrypt_block(block, keys, ctx->nr);
+    } else
+#else
+    (void) mode;
+#endif
+    {
+        block = aesce_encrypt_block(block, keys, ctx->nr);
     }
     vst1q_u8(&output[0], block);
 
@@ -243,6 +288,7 @@
 /*
  * Compute decryption round keys from encryption round keys
  */
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
 void mbedtls_aesce_inverse_key(unsigned char *invkey,
                                const unsigned char *fwdkey,
                                int nr)
@@ -257,6 +303,7 @@
     vst1q_u8(invkey + i * 16, vld1q_u8(fwdkey + j * 16));
 
 }
+#endif
 
 static inline uint32_t aes_rot_word(uint32_t word)
 {
@@ -300,7 +347,7 @@
          rki + key_len_in_words < rko_end;
          rki += key_len_in_words) {
 
-        size_t iteration = (rki - (uint32_t *) rk) / key_len_in_words;
+        size_t iteration = (size_t) (rki - (uint32_t *) rk) / key_len_in_words;
         uint32_t *rko;
         rko = rki + key_len_in_words;
         rko[0] = aes_rot_word(aes_sub_word(rki[key_len_in_words - 1]));
@@ -353,24 +400,91 @@
 
 #if defined(MBEDTLS_GCM_C)
 
-#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ == 5
-/* Some intrinsics are not available for GCC 5.X. */
-#define vreinterpretq_p64_u8(a) ((poly64x2_t) a)
-#define vreinterpretq_u8_p128(a) ((uint8x16_t) a)
-static inline poly64_t vget_low_p64(poly64x2_t __a)
+#if defined(MBEDTLS_ARCH_IS_ARM32)
+
+#if defined(__clang__)
+/* On clang for A32/T32, work around some missing intrinsics and types which are listed in
+ * [ACLE](https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#polynomial-1)
+ * These are only required for GCM.
+ */
+#define vreinterpretq_u64_p64(a) ((uint64x2_t) a)
+
+typedef uint8x16_t poly128_t;
+
+static inline poly128_t vmull_p64(poly64_t a, poly64_t b)
 {
-    uint64x2_t tmp = (uint64x2_t) (__a);
-    uint64x1_t lo = vcreate_u64(vgetq_lane_u64(tmp, 0));
-    return (poly64_t) (lo);
+    poly128_t r;
+    asm ("vmull.p64 %[r], %[a], %[b]" : [r] "=w" (r) : [a] "w" (a), [b] "w" (b) :);
+    return r;
 }
-#endif /* !__clang__ && __GNUC__ && __GNUC__ == 5*/
+
+/* This is set to cause some more missing intrinsics to be defined below */
+#define COMMON_MISSING_INTRINSICS
+
+static inline poly128_t vmull_high_p64(poly64x2_t a, poly64x2_t b)
+{
+    return vmull_p64((poly64_t) (vget_high_u64((uint64x2_t) a)),
+                     (poly64_t) (vget_high_u64((uint64x2_t) b)));
+}
+
+#endif /* defined(__clang__) */
+
+static inline uint8x16_t vrbitq_u8(uint8x16_t x)
+{
+    /* There is no vrbitq_u8 instruction in A32/T32, so provide
+     * an equivalent non-Neon implementation. Reverse bit order in each
+     * byte with 4x rbit, rev. */
+    asm ("ldm  %[p], { r2-r5 } \n\t"
+         "rbit r2, r2          \n\t"
+         "rev  r2, r2          \n\t"
+         "rbit r3, r3          \n\t"
+         "rev  r3, r3          \n\t"
+         "rbit r4, r4          \n\t"
+         "rev  r4, r4          \n\t"
+         "rbit r5, r5          \n\t"
+         "rev  r5, r5          \n\t"
+         "stm  %[p], { r2-r5 } \n\t"
+         :
+         /* Output: 16 bytes of memory pointed to by &x */
+         "+m" (*(uint8_t(*)[16]) &x)
+         :
+         [p] "r" (&x)
+         :
+         "r2", "r3", "r4", "r5"
+         );
+    return x;
+}
+
+#endif /* defined(MBEDTLS_ARCH_IS_ARM32) */
+
+#if defined(MBEDTLS_COMPILER_IS_GCC) && __GNUC__ == 5
+/* Some intrinsics are not available for GCC 5.X. */
+#define COMMON_MISSING_INTRINSICS
+#endif /* MBEDTLS_COMPILER_IS_GCC && __GNUC__ == 5 */
+
+
+#if defined(COMMON_MISSING_INTRINSICS)
+
+/* Missing intrinsics common to both GCC 5, and Clang on 32-bit */
+
+#define vreinterpretq_p64_u8(a)  ((poly64x2_t) a)
+#define vreinterpretq_u8_p128(a) ((uint8x16_t) a)
+
+static inline poly64x1_t vget_low_p64(poly64x2_t a)
+{
+    uint64x1_t r = vget_low_u64(vreinterpretq_u64_p64(a));
+    return (poly64x1_t) r;
+
+}
+
+#endif /* COMMON_MISSING_INTRINSICS */
 
 /* vmull_p64/vmull_high_p64 wrappers.
  *
  * Older compilers miss some intrinsic functions for `poly*_t`. We use
  * uint8x16_t and uint8x16x3_t as input/output parameters.
  */
-#if defined(__GNUC__) && !defined(__clang__)
+#if defined(MBEDTLS_COMPILER_IS_GCC)
 /* GCC reports incompatible type error without cast. GCC think poly64_t and
  * poly64x1_t are different, that is different with MSVC and Clang. */
 #define MBEDTLS_VMULL_P64(a, b) vmull_p64((poly64_t) a, (poly64_t) b)
@@ -379,14 +493,15 @@
  * error with/without cast. And I think poly64_t and poly64x1_t are same, no
  * cast for clang also. */
 #define MBEDTLS_VMULL_P64(a, b) vmull_p64(a, b)
-#endif
+#endif /* MBEDTLS_COMPILER_IS_GCC */
+
 static inline uint8x16_t pmull_low(uint8x16_t a, uint8x16_t b)
 {
 
     return vreinterpretq_u8_p128(
         MBEDTLS_VMULL_P64(
-            vget_low_p64(vreinterpretq_p64_u8(a)),
-            vget_low_p64(vreinterpretq_p64_u8(b))
+            (poly64_t) vget_low_p64(vreinterpretq_p64_u8(a)),
+            (poly64_t) vget_low_p64(vreinterpretq_p64_u8(b))
             ));
 }
 
@@ -455,7 +570,7 @@
     /* use 'asm' as an optimisation barrier to prevent loading MODULO from
      * memory. It is for GNUC compatible compilers.
      */
-    asm ("" : "+w" (r));
+    asm volatile ("" : "+w" (r));
 #endif
     uint8x16_t const MODULO = vreinterpretq_u8_u64(vshrq_n_u64(r, 64 - 8));
     uint8x16_t h, m, l; /* input high/middle/low 128b */
@@ -498,6 +613,6 @@
 #undef MBEDTLS_POP_TARGET_PRAGMA
 #endif
 
-#endif /* MBEDTLS_ARCH_IS_ARM64 */
+#endif /* MBEDTLS_AESCE_HAVE_CODE */
 
 #endif /* MBEDTLS_AESCE_C */
diff --git a/library/aesce.h b/library/aesce.h
index 9206a6b..a14d085 100644
--- a/library/aesce.h
+++ b/library/aesce.h
@@ -2,7 +2,7 @@
  * \file aesce.h
  *
  * \brief Support hardware AES acceleration on Armv8-A processors with
- *        the Armv8-A Cryptographic Extension in AArch64 execution state.
+ *        the Armv8-A Cryptographic Extension.
  *
  * \warning These functions are only for internal use by other library
  *          functions; you must not call them directly.
@@ -15,12 +15,18 @@
 #define MBEDTLS_AESCE_H
 
 #include "mbedtls/build_info.h"
+#include "common.h"
 
 #include "mbedtls/aes.h"
 
 
-#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_ARCH_IS_ARM64)
+#if defined(MBEDTLS_AESCE_C) \
+    && defined(MBEDTLS_ARCH_IS_ARMV8_A) && defined(MBEDTLS_HAVE_NEON_INTRINSICS) \
+    && (defined(MBEDTLS_COMPILER_IS_GCC) || defined(__clang__) || defined(MSC_VER))
 
+/* MBEDTLS_AESCE_HAVE_CODE is defined if we have a suitable target platform, and a
+ * potentially suitable compiler (compiler version & flags are not checked when defining
+ * this). */
 #define MBEDTLS_AESCE_HAVE_CODE
 
 #ifdef __cplusplus
@@ -87,6 +93,7 @@
                             const unsigned char b[16]);
 
 
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
 /**
  * \brief           Internal round key inversion. This function computes
  *                  decryption round keys from the encryption round keys.
@@ -98,6 +105,7 @@
 void mbedtls_aesce_inverse_key(unsigned char *invkey,
                                const unsigned char *fwdkey,
                                int nr);
+#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
 
 /**
  * \brief           Internal key expansion for encryption
@@ -116,6 +124,13 @@
 }
 #endif
 
-#endif /* MBEDTLS_AESCE_C && MBEDTLS_ARCH_IS_ARM64 */
+#else
+
+#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY) && defined(MBEDTLS_ARCH_IS_ARMV8_A)
+#error "AES hardware acceleration not supported on this platform / compiler"
+#endif
+
+#endif /* MBEDTLS_AESCE_C && MBEDTLS_ARCH_IS_ARMV8_A && MBEDTLS_HAVE_NEON_INTRINSICS &&
+          (MBEDTLS_COMPILER_IS_GCC || __clang__ || MSC_VER) */
 
 #endif /* MBEDTLS_AESCE_H */
diff --git a/library/aesni.c b/library/aesni.c
index b92c73c..9da9f1b 100644
--- a/library/aesni.c
+++ b/library/aesni.c
@@ -94,14 +94,19 @@
     ++rk;
     --nr;
 
-    if (mode == 0) {
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
+    if (mode == MBEDTLS_AES_DECRYPT) {
         while (nr != 0) {
             state = _mm_aesdec_si128(state, *rk);
             ++rk;
             --nr;
         }
         state = _mm_aesdeclast_si128(state, *rk);
-    } else {
+    } else
+#else
+    (void) mode;
+#endif
+    {
         while (nr != 0) {
             state = _mm_aesenc_si128(state, *rk);
             ++rk;
@@ -218,6 +223,7 @@
 /*
  * Compute decryption round keys from encryption round keys
  */
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
 void mbedtls_aesni_inverse_key(unsigned char *invkey,
                                const unsigned char *fwdkey, int nr)
 {
@@ -230,6 +236,7 @@
     }
     *ik = *fk;
 }
+#endif
 
 /*
  * Key expansion, 128-bit case
@@ -465,6 +472,7 @@
          "jnz       1b              \n\t"
          "movdqu    (%1), %%xmm1    \n\t" // load round key
          AESENCLAST(xmm1_xmm0)            // last round
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
          "jmp       3f              \n\t"
 
          "2:                        \n\t" // decryption loop
@@ -475,6 +483,7 @@
          "jnz       2b              \n\t"
          "movdqu    (%1), %%xmm1    \n\t" // load round key
          AESDECLAST(xmm1_xmm0)            // last round
+#endif
 
          "3:                        \n\t"
          "movdqu    %%xmm0, (%4)    \n\t" // export output
@@ -601,6 +610,7 @@
 /*
  * Compute decryption round keys from encryption round keys
  */
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
 void mbedtls_aesni_inverse_key(unsigned char *invkey,
                                const unsigned char *fwdkey, int nr)
 {
@@ -620,6 +630,7 @@
 
     memcpy(ik, fk, 16);
 }
+#endif
 
 /*
  * Key expansion, 128-bit case
diff --git a/library/aesni.h b/library/aesni.h
index e22ae16..59e27af 100644
--- a/library/aesni.h
+++ b/library/aesni.h
@@ -119,6 +119,7 @@
                             const unsigned char a[16],
                             const unsigned char b[16]);
 
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
 /**
  * \brief           Internal round key inversion. This function computes
  *                  decryption round keys from the encryption round keys.
@@ -133,6 +134,7 @@
 void mbedtls_aesni_inverse_key(unsigned char *invkey,
                                const unsigned char *fwdkey,
                                int nr);
+#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
 
 /**
  * \brief           Internal key expansion for encryption
@@ -155,6 +157,6 @@
 #endif
 
 #endif /* MBEDTLS_AESNI_HAVE_CODE */
-#endif  /* MBEDTLS_AESNI_C */
+#endif  /* MBEDTLS_AESNI_C && (MBEDTLS_ARCH_IS_X64 || MBEDTLS_ARCH_IS_X86) */
 
 #endif /* MBEDTLS_AESNI_H */
diff --git a/library/alignment.h b/library/alignment.h
index 4bca10e..4aab8e0 100644
--- a/library/alignment.h
+++ b/library/alignment.h
@@ -23,11 +23,16 @@
  * efficient when this is not defined.
  */
 #if defined(__ARM_FEATURE_UNALIGNED) \
-    || defined(__i386__) || defined(__amd64__) || defined(__x86_64__)
+    || defined(MBEDTLS_ARCH_IS_X86) || defined(MBEDTLS_ARCH_IS_X64) \
+    || defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
 /*
  * __ARM_FEATURE_UNALIGNED is defined where appropriate by armcc, gcc 7, clang 9
  * (and later versions) for Arm v7 and later; all x86 platforms should have
  * efficient unaligned access.
+ *
+ * https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#alignment
+ * specifies that on Windows-on-Arm64, unaligned access is safe (except for uncached
+ * device memory).
  */
 #define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS
 #endif
diff --git a/library/aria.c b/library/aria.c
index 07a434f..ba12578 100644
--- a/library/aria.c
+++ b/library/aria.c
@@ -413,6 +413,7 @@
 /*
  * Set decryption key
  */
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
 int mbedtls_aria_setkey_dec(mbedtls_aria_context *ctx,
                             const unsigned char *key, unsigned int keybits)
 {
@@ -442,6 +443,7 @@
 
     return 0;
 }
+#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
 
 /*
  * Encrypt a block
@@ -872,12 +874,18 @@
         /* test ECB decryption */
         if (verbose) {
             mbedtls_printf("  ARIA-ECB-%d (dec): ", 128 + 64 * i);
+#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
+            mbedtls_printf("skipped\n");
+#endif
         }
+
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
         mbedtls_aria_setkey_dec(&ctx, aria_test1_ecb_key, 128 + 64 * i);
         mbedtls_aria_crypt_ecb(&ctx, aria_test1_ecb_ct[i], blk);
         ARIA_SELF_TEST_ASSERT(
             memcmp(blk, aria_test1_ecb_pt, MBEDTLS_ARIA_BLOCKSIZE)
             != 0);
+#endif
     }
     if (verbose) {
         mbedtls_printf("\n");
diff --git a/library/base64.c b/library/base64.c
index a58717d..9677dee 100644
--- a/library/base64.c
+++ b/library/base64.c
@@ -116,7 +116,7 @@
         *p++ = '=';
     }
 
-    *olen = p - dst;
+    *olen = (size_t) (p - dst);
     *p = 0;
 
     return 0;
@@ -225,7 +225,7 @@
         }
     }
 
-    *olen = p - dst;
+    *olen = (size_t) (p - dst);
 
     return 0;
 }
diff --git a/library/bignum.c b/library/bignum.c
index 09ce030..1869137 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -102,7 +102,8 @@
  * about whether the assignment was made or not.
  * (Leaking information about the respective sizes of X and Y is ok however.)
  */
-#if defined(_MSC_VER) && defined(_M_ARM64) && (_MSC_FULL_VER < 193131103)
+#if defined(_MSC_VER) && defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64) && \
+    (_MSC_FULL_VER < 193131103)
 /*
  * MSVC miscompiles this function if it's inlined prior to Visual Studio 2022 version 17.1. See:
  * https://developercommunity.visualstudio.com/t/c-compiler-miscompiles-part-of-mbedtls-library-on/1646989
@@ -701,7 +702,7 @@
     }
 
     *p++ = '\0';
-    *olen = p - buf;
+    *olen = (size_t) (p - buf);
 
 cleanup:
 
diff --git a/library/camellia.c b/library/camellia.c
index 86c8bbf..b1c0a08 100644
--- a/library/camellia.c
+++ b/library/camellia.c
@@ -399,6 +399,7 @@
 /*
  * Camellia key schedule (decryption)
  */
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
 int mbedtls_camellia_setkey_dec(mbedtls_camellia_context *ctx,
                                 const unsigned char *key,
                                 unsigned int keybits)
@@ -444,6 +445,7 @@
 
     return ret;
 }
+#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
 
 /*
  * Camellia-ECB block encryption/decryption
@@ -888,14 +890,26 @@
                            (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
         }
 
+#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
+        if (v == MBEDTLS_CAMELLIA_DECRYPT) {
+            if (verbose != 0) {
+                mbedtls_printf("skipped\n");
+            }
+            continue;
+        }
+#endif
+
         for (i = 0; i < CAMELLIA_TESTS_ECB; i++) {
             memcpy(key, camellia_test_ecb_key[u][i], 16 + 8 * u);
 
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
             if (v == MBEDTLS_CAMELLIA_DECRYPT) {
                 mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64);
                 memcpy(src, camellia_test_ecb_cipher[u][i], 16);
                 memcpy(dst, camellia_test_ecb_plain[i], 16);
-            } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
+            } else
+#endif
+            { /* MBEDTLS_CAMELLIA_ENCRYPT */
                 mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64);
                 memcpy(src, camellia_test_ecb_plain[i], 16);
                 memcpy(dst, camellia_test_ecb_cipher[u][i], 16);
diff --git a/library/ccm.c b/library/ccm.c
index 2cccd28..6700dc7 100644
--- a/library/ccm.c
+++ b/library/ccm.c
@@ -23,6 +23,10 @@
 #include "mbedtls/error.h"
 #include "mbedtls/constant_time.h"
 
+#if !defined(MBEDTLS_CIPHER_C)
+#include "block_cipher_internal.h"
+#endif
+
 #include <string.h>
 
 #if defined(MBEDTLS_PLATFORM_C)
@@ -51,6 +55,8 @@
                        unsigned int keybits)
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+#if defined(MBEDTLS_CIPHER_C)
     const mbedtls_cipher_info_t *cipher_info;
 
     cipher_info = mbedtls_cipher_info_from_values(cipher, keybits,
@@ -73,6 +79,17 @@
                                      MBEDTLS_ENCRYPT)) != 0) {
         return ret;
     }
+#else
+    mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
+
+    if ((ret = mbedtls_block_cipher_setup(&ctx->block_cipher_ctx, cipher)) != 0) {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    if ((ret = mbedtls_block_cipher_setkey(&ctx->block_cipher_ctx, key, keybits)) != 0) {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+#endif
 
     return 0;
 }
@@ -85,7 +102,11 @@
     if (ctx == NULL) {
         return;
     }
+#if defined(MBEDTLS_CIPHER_C)
     mbedtls_cipher_free(&ctx->cipher_ctx);
+#else
+    mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
+#endif
     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ccm_context));
 }
 
@@ -104,12 +125,16 @@
                              const unsigned char *input,
                              unsigned char *output)
 {
-    size_t olen = 0;
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char tmp_buf[16] = { 0 };
 
-    if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->ctr, 16, tmp_buf,
-                                     &olen)) != 0) {
+#if defined(MBEDTLS_CIPHER_C)
+    size_t olen = 0;
+    ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->ctr, 16, tmp_buf, &olen);
+#else
+    ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->ctr, tmp_buf);
+#endif
+    if (ret != 0) {
         ctx->state |= CCM_STATE__ERROR;
         mbedtls_platform_zeroize(tmp_buf, sizeof(tmp_buf));
         return ret;
@@ -132,7 +157,10 @@
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char i;
-    size_t len_left, olen;
+    size_t len_left;
+#if defined(MBEDTLS_CIPHER_C)
+    size_t olen;
+#endif
 
     /* length calculation can be done only after both
      * mbedtls_ccm_starts() and mbedtls_ccm_set_lengths() have been executed
@@ -178,7 +206,12 @@
     }
 
     /* Start CBC-MAC with first block*/
-    if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen)) != 0) {
+#if defined(MBEDTLS_CIPHER_C)
+    ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen);
+#else
+    ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ctx->y);
+#endif
+    if (ret != 0) {
         ctx->state |= CCM_STATE__ERROR;
         return ret;
     }
@@ -258,7 +291,10 @@
                           size_t add_len)
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    size_t olen, use_len, offset;
+    size_t use_len, offset;
+#if defined(MBEDTLS_CIPHER_C)
+    size_t olen;
+#endif
 
     if (ctx->state & CCM_STATE__ERROR) {
         return MBEDTLS_ERR_CCM_BAD_INPUT;
@@ -298,8 +334,12 @@
             add += use_len;
 
             if (use_len + offset == 16 || ctx->processed == ctx->add_len) {
-                if ((ret =
-                         mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen)) != 0) {
+#if defined(MBEDTLS_CIPHER_C)
+                ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen);
+#else
+                ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ctx->y);
+#endif
+                if (ret != 0) {
                     ctx->state |= CCM_STATE__ERROR;
                     return ret;
                 }
@@ -322,7 +362,10 @@
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char i;
-    size_t use_len, offset, olen;
+    size_t use_len, offset;
+#if defined(MBEDTLS_CIPHER_C)
+    size_t olen;
+#endif
 
     unsigned char local_output[16];
 
@@ -360,8 +403,12 @@
             mbedtls_xor(ctx->y + offset, ctx->y + offset, input, use_len);
 
             if (use_len + offset == 16 || ctx->processed == ctx->plaintext_len) {
-                if ((ret =
-                         mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen)) != 0) {
+#if defined(MBEDTLS_CIPHER_C)
+                ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen);
+#else
+                ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ctx->y);
+#endif
+                if (ret != 0) {
                     ctx->state |= CCM_STATE__ERROR;
                     goto exit;
                 }
@@ -391,8 +438,12 @@
             memcpy(output, local_output, use_len);
 
             if (use_len + offset == 16 || ctx->processed == ctx->plaintext_len) {
-                if ((ret =
-                         mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen)) != 0) {
+#if defined(MBEDTLS_CIPHER_C)
+                ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen);
+#else
+                ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ctx->y);
+#endif
+                if (ret != 0) {
                     ctx->state |= CCM_STATE__ERROR;
                     goto exit;
                 }
diff --git a/library/cipher.c b/library/cipher.c
index c8217b9..0683677 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -310,6 +310,12 @@
     if (ctx->cipher_info == NULL) {
         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     }
+#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
+    if (MBEDTLS_MODE_ECB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) &&
+        MBEDTLS_DECRYPT == operation) {
+        return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
+    }
+#endif
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
     if (ctx->psa_enabled == 1) {
@@ -377,6 +383,7 @@
     ctx->key_bitlen = key_bitlen;
     ctx->operation = operation;
 
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
     /*
      * For OFB, CFB and CTR mode always use the encryption key schedule
      */
@@ -392,6 +399,12 @@
         return mbedtls_cipher_get_base(ctx->cipher_info)->setkey_dec_func(ctx->cipher_ctx, key,
                                                                           ctx->key_bitlen);
     }
+#else
+    if (operation == MBEDTLS_ENCRYPT || operation == MBEDTLS_DECRYPT) {
+        return mbedtls_cipher_get_base(ctx->cipher_info)->setkey_enc_func(ctx->cipher_ctx, key,
+                                                                          ctx->key_bitlen);
+    }
+#endif
 
     return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
 }
diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c
index ef3aa8d..c173899 100644
--- a/library/cipher_wrap.c
+++ b/library/cipher_wrap.c
@@ -226,11 +226,13 @@
 }
 #endif /* MBEDTLS_CIPHER_MODE_XTS */
 
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
 static int aes_setkey_dec_wrap(void *ctx, const unsigned char *key,
                                unsigned int key_bitlen)
 {
     return mbedtls_aes_setkey_dec((mbedtls_aes_context *) ctx, key, key_bitlen);
 }
+#endif
 
 static int aes_setkey_enc_wrap(void *ctx, const unsigned char *key,
                                unsigned int key_bitlen)
@@ -279,7 +281,9 @@
     NULL,
 #endif
     aes_setkey_enc_wrap,
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
     aes_setkey_dec_wrap,
+#endif
     aes_ctx_alloc,
     aes_ctx_free
 };
@@ -591,7 +595,9 @@
 #endif
 #if defined(MBEDTLS_GCM_C)
     gcm_aes_setkey_wrap,
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
     gcm_aes_setkey_wrap,
+#endif
     gcm_ctx_alloc,
     gcm_ctx_free,
 #else
@@ -673,7 +679,9 @@
 #endif
 #if defined(MBEDTLS_CCM_C)
     ccm_aes_setkey_wrap,
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
     ccm_aes_setkey_wrap,
+#endif
     ccm_ctx_alloc,
     ccm_ctx_free,
 #else
@@ -799,11 +807,13 @@
 }
 #endif /* MBEDTLS_CIPHER_MODE_CTR */
 
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
 static int camellia_setkey_dec_wrap(void *ctx, const unsigned char *key,
                                     unsigned int key_bitlen)
 {
     return mbedtls_camellia_setkey_dec((mbedtls_camellia_context *) ctx, key, key_bitlen);
 }
+#endif
 
 static int camellia_setkey_enc_wrap(void *ctx, const unsigned char *key,
                                     unsigned int key_bitlen)
@@ -853,7 +863,9 @@
     NULL,
 #endif
     camellia_setkey_enc_wrap,
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
     camellia_setkey_dec_wrap,
+#endif
     camellia_ctx_alloc,
     camellia_ctx_free
 };
@@ -1026,7 +1038,9 @@
     NULL,
 #endif
     gcm_camellia_setkey_wrap,
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
     gcm_camellia_setkey_wrap,
+#endif
     gcm_ctx_alloc,
     gcm_ctx_free,
 };
@@ -1095,7 +1109,9 @@
     NULL,
 #endif
     ccm_camellia_setkey_wrap,
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
     ccm_camellia_setkey_wrap,
+#endif
     ccm_ctx_alloc,
     ccm_ctx_free,
 };
@@ -1209,11 +1225,13 @@
 }
 #endif /* MBEDTLS_CIPHER_MODE_CTR */
 
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
 static int aria_setkey_dec_wrap(void *ctx, const unsigned char *key,
                                 unsigned int key_bitlen)
 {
     return mbedtls_aria_setkey_dec((mbedtls_aria_context *) ctx, key, key_bitlen);
 }
+#endif
 
 static int aria_setkey_enc_wrap(void *ctx, const unsigned char *key,
                                 unsigned int key_bitlen)
@@ -1263,7 +1281,9 @@
     NULL,
 #endif
     aria_setkey_enc_wrap,
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
     aria_setkey_dec_wrap,
+#endif
     aria_ctx_alloc,
     aria_ctx_free
 };
@@ -1436,7 +1456,9 @@
     NULL,
 #endif
     gcm_aria_setkey_wrap,
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
     gcm_aria_setkey_wrap,
+#endif
     gcm_ctx_alloc,
     gcm_ctx_free,
 };
@@ -1505,7 +1527,9 @@
     NULL,
 #endif
     ccm_aria_setkey_wrap,
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
     ccm_aria_setkey_wrap,
+#endif
     ccm_ctx_alloc,
     ccm_ctx_free,
 };
@@ -1925,7 +1949,9 @@
     chacha20_stream_wrap,
 #endif
     chacha20_setkey_wrap,
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
     chacha20_setkey_wrap,
+#endif
     chacha20_ctx_alloc,
     chacha20_ctx_free
 };
@@ -2000,7 +2026,9 @@
     NULL,
 #endif
     chachapoly_setkey_wrap,
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
     chachapoly_setkey_wrap,
+#endif
     chachapoly_ctx_alloc,
     chachapoly_ctx_free
 };
@@ -2068,7 +2096,9 @@
     null_crypt_stream,
 #endif
     null_setkey,
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
     null_setkey,
+#endif
     null_ctx_alloc,
     null_ctx_free
 };
diff --git a/library/cipher_wrap.h b/library/cipher_wrap.h
index a9254fd..f229151 100644
--- a/library/cipher_wrap.h
+++ b/library/cipher_wrap.h
@@ -125,9 +125,11 @@
     int (*setkey_enc_func)(void *ctx, const unsigned char *key,
                            unsigned int key_bitlen);
 
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
     /** Set key for decryption purposes */
     int (*setkey_dec_func)(void *ctx, const unsigned char *key,
                            unsigned int key_bitlen);
+#endif
 
     /** Allocate a new context */
     void * (*ctx_alloc_func)(void);
diff --git a/library/common.h b/library/common.h
index c20f6b2..e532777 100644
--- a/library/common.h
+++ b/library/common.h
@@ -21,7 +21,20 @@
 
 #if defined(__ARM_NEON)
 #include <arm_neon.h>
-#endif /* __ARM_NEON */
+#define MBEDTLS_HAVE_NEON_INTRINSICS
+#elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
+#include <arm64_neon.h>
+#define MBEDTLS_HAVE_NEON_INTRINSICS
+#endif
+
+
+#if defined(__GNUC__) && !defined(__ARMCC_VERSION) && !defined(__clang__) \
+    && !defined(__llvm__) && !defined(__INTEL_COMPILER)
+/* Defined if the compiler really is gcc and not clang, etc */
+#define MBEDTLS_COMPILER_IS_GCC
+#define MBEDTLS_GCC_VERSION \
+    (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+#endif
 
 /** Helper to define a function as static except when building invasive tests.
  *
@@ -169,14 +182,16 @@
 {
     size_t i = 0;
 #if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)
-#if defined(__ARM_NEON)
+#if defined(MBEDTLS_HAVE_NEON_INTRINSICS) && \
+    (!(defined(MBEDTLS_COMPILER_IS_GCC) && MBEDTLS_GCC_VERSION < 70300))
+    /* Old GCC versions generate a warning here, so disable the NEON path for these compilers */
     for (; (i + 16) <= n; i += 16) {
         uint8x16_t v1 = vld1q_u8(a + i);
         uint8x16_t v2 = vld1q_u8(b + i);
         uint8x16_t x = veorq_u8(v1, v2);
         vst1q_u8(r + i, x);
     }
-#elif defined(__amd64__) || defined(__x86_64__) || defined(__aarch64__)
+#elif defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_ARM64)
     /* This codepath probably only makes sense on architectures with 64-bit registers */
     for (; (i + 8) <= n; i += 8) {
         uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i);
@@ -215,7 +230,7 @@
 {
     size_t i = 0;
 #if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)
-#if defined(__amd64__) || defined(__x86_64__) || defined(__aarch64__)
+#if defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_ARM64)
     /* This codepath probably only makes sense on architectures with 64-bit registers */
     for (; (i + 8) <= n; i += 8) {
         uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i);
@@ -324,12 +339,6 @@
 #define MBEDTLS_ASSUME(x)       do { } while (0)
 #endif
 
-#if defined(__GNUC__) && !defined(__ARMCC_VERSION) && !defined(__clang__) \
-    && !defined(__llvm__) && !defined(__INTEL_COMPILER)
-/* Defined if the compiler really is gcc and not clang, etc */
-#define MBEDTLS_COMPILER_IS_GCC
-#endif
-
 /* For gcc -Os, override with -O2 for a given function.
  *
  * This will not affect behaviour for other optimisation settings, e.g. -O0.
diff --git a/library/constant_time_impl.h b/library/constant_time_impl.h
index 18a967b..2a4574b 100644
--- a/library/constant_time_impl.h
+++ b/library/constant_time_impl.h
@@ -31,7 +31,7 @@
  * Disable -Wredundant-decls so that gcc does not warn about this. This is re-enabled
  * at the bottom of this file.
  */
-#ifdef __GNUC__
+#if defined(MBEDTLS_COMPILER_IS_GCC) && (__GNUC__ > 4)
     #pragma GCC diagnostic push
     #pragma GCC diagnostic ignored "-Wredundant-decls"
 #endif
@@ -548,7 +548,7 @@
     return (mbedtls_ct_condition_t) (~x);
 }
 
-#ifdef __GNUC__
+#if defined(MBEDTLS_COMPILER_IS_GCC) && (__GNUC__ > 4)
 /* Restore warnings for -Wredundant-decls on gcc */
     #pragma GCC diagnostic pop
 #endif
diff --git a/library/debug.c b/library/debug.c
index c7bbd41..a9d58e5 100644
--- a/library/debug.c
+++ b/library/debug.c
@@ -366,7 +366,7 @@
     start = text;
     for (cur = text; *cur != '\0'; cur++) {
         if (*cur == '\n') {
-            size_t len = cur - start + 1;
+            size_t len = (size_t) (cur - start) + 1;
             if (len > DEBUG_BUF_SIZE - 1) {
                 len = DEBUG_BUF_SIZE - 1;
             }
diff --git a/library/dhm.c b/library/dhm.c
index 3daf0c2..bcc07f5 100644
--- a/library/dhm.c
+++ b/library/dhm.c
@@ -48,10 +48,10 @@
         return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
     }
 
-    n = ((*p)[0] << 8) | (*p)[1];
+    n = MBEDTLS_GET_UINT16_BE(*p, 0);
     (*p) += 2;
 
-    if ((int) (end - *p) < n) {
+    if ((size_t) (end - *p) < (size_t) n) {
         return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
     }
 
@@ -257,7 +257,7 @@
     DHM_MPI_EXPORT(&ctx->G, n2);
     DHM_MPI_EXPORT(&ctx->GX, n3);
 
-    *olen = p - output;
+    *olen = (size_t) (p - output);
 
 cleanup:
     if (ret != 0 && ret > -128) {
diff --git a/library/ecdh.c b/library/ecdh.c
index e060b18..52b1617 100644
--- a/library/ecdh.c
+++ b/library/ecdh.c
@@ -363,7 +363,7 @@
                                      const unsigned char *end)
 {
     return mbedtls_ecp_tls_read_point(&ctx->grp, &ctx->Qp, buf,
-                                      end - *buf);
+                                      (size_t) (end - *buf));
 }
 
 /*
@@ -379,7 +379,7 @@
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     mbedtls_ecp_group_id grp_id;
-    if ((ret = mbedtls_ecp_tls_read_group_id(&grp_id, buf, end - *buf))
+    if ((ret = mbedtls_ecp_tls_read_group_id(&grp_id, buf, (size_t) (end - *buf)))
         != 0) {
         return ret;
     }
diff --git a/library/ecjpake.c b/library/ecjpake.c
index fb13a39..cdf5d7e 100644
--- a/library/ecjpake.c
+++ b/library/ecjpake.c
@@ -168,7 +168,7 @@
     }
 
     ret = mbedtls_ecp_point_write_binary(grp, P, pf,
-                                         &len, *p + 4, end - (*p + 4));
+                                         &len, *p + 4, (size_t) (end - (*p + 4)));
     if (ret != 0) {
         return ret;
     }
@@ -226,7 +226,7 @@
 
     /* Compute hash */
     MBEDTLS_MPI_CHK(mbedtls_ecjpake_compute_hash(md_type,
-                                                 buf, p - buf, hash));
+                                                 buf, (size_t) (p - buf), hash));
 
     /* Turn it into an integer mod n */
     MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(h, hash,
@@ -269,7 +269,7 @@
         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
     }
 
-    MBEDTLS_MPI_CHK(mbedtls_ecp_tls_read_point(grp, &V, p, end - *p));
+    MBEDTLS_MPI_CHK(mbedtls_ecp_tls_read_point(grp, &V, p, (size_t) (end - *p)));
 
     if (end < *p || (size_t) (end - *p) < 1) {
         ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
@@ -346,7 +346,7 @@
 
     /* Write it out */
     MBEDTLS_MPI_CHK(mbedtls_ecp_tls_write_point(grp, &V,
-                                                pf, &len, *p, end - *p));
+                                                pf, &len, *p, (size_t) (end - *p)));
     *p += len;
 
     len = mbedtls_mpi_size(&h);   /* actually r */
@@ -392,7 +392,7 @@
      *     ECSchnorrZKP zkp;
      * } ECJPAKEKeyKP;
      */
-    MBEDTLS_MPI_CHK(mbedtls_ecp_tls_read_point(grp, X, p, end - *p));
+    MBEDTLS_MPI_CHK(mbedtls_ecp_tls_read_point(grp, X, p, (size_t) (end - *p)));
     if (mbedtls_ecp_is_zero(X)) {
         ret = MBEDTLS_ERR_ECP_INVALID_KEY;
         goto cleanup;
@@ -431,7 +431,7 @@
     MBEDTLS_MPI_CHK(mbedtls_ecp_gen_keypair_base((mbedtls_ecp_group *) grp, G, x, X,
                                                  f_rng, p_rng));
     MBEDTLS_MPI_CHK(mbedtls_ecp_tls_write_point(grp, X,
-                                                pf, &len, *p, end - *p));
+                                                pf, &len, *p, (size_t) (end - *p)));
     *p += len;
 
     /* Generate and write proof */
@@ -504,7 +504,7 @@
     MBEDTLS_MPI_CHK(ecjpake_kkp_write(md_type, grp, pf, G, xm2, Xb, id,
                                       &p, end, f_rng, p_rng));
 
-    *olen = p - buf;
+    *olen = (size_t) (p - buf);
 
 cleanup:
     return ret;
@@ -693,7 +693,7 @@
             goto cleanup;
         }
         MBEDTLS_MPI_CHK(mbedtls_ecp_tls_write_group(&ctx->grp, &ec_len,
-                                                    p, end - p));
+                                                    p, (size_t) (end - p)));
         p += ec_len;
     }
 
@@ -702,7 +702,7 @@
         goto cleanup;
     }
     MBEDTLS_MPI_CHK(mbedtls_ecp_tls_write_point(&ctx->grp, &Xm,
-                                                ctx->point_format, &ec_len, p, end - p));
+                                                ctx->point_format, &ec_len, p, (size_t) (end - p)));
     p += ec_len;
 
     MBEDTLS_MPI_CHK(ecjpake_zkp_write(ctx->md_type, &ctx->grp,
@@ -710,7 +710,7 @@
                                       &G, &xm, &Xm, ID_MINE,
                                       &p, end, f_rng, p_rng));
 
-    *olen = p - buf;
+    *olen = (size_t) (p - buf);
 
 cleanup:
     mbedtls_ecp_point_free(&G);
diff --git a/library/entropy_poll.c b/library/entropy_poll.c
index e8c669f..de2e038 100644
--- a/library/entropy_poll.c
+++ b/library/entropy_poll.c
@@ -88,7 +88,7 @@
     memset(buf, 0, buflen);
 #endif
 #endif
-    return syscall(SYS_getrandom, buf, buflen, flags);
+    return (int) syscall(SYS_getrandom, buf, buflen, flags);
 }
 #endif /* SYS_getrandom */
 #endif /* __linux__ || __midipix__ */
@@ -102,7 +102,7 @@
 #define HAVE_GETRANDOM
 static int getrandom_wrapper(void *buf, size_t buflen, unsigned int flags)
 {
-    return getrandom(buf, buflen, flags);
+    return (int) getrandom(buf, buflen, flags);
 }
 #endif /* (__FreeBSD__ && __FreeBSD_version >= 1200000) ||
           (__DragonFly__ && __DragonFly_version >= 500700) */
@@ -156,7 +156,7 @@
 #if defined(HAVE_GETRANDOM)
     ret = getrandom_wrapper(output, len, 0);
     if (ret >= 0) {
-        *olen = ret;
+        *olen = (size_t) ret;
         return 0;
     } else if (errno != ENOSYS) {
         return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
diff --git a/library/gcm.c b/library/gcm.c
index 42fd020..8181ec8 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -25,6 +25,10 @@
 #include "mbedtls/error.h"
 #include "mbedtls/constant_time.h"
 
+#if !defined(MBEDTLS_CIPHER_C)
+#include "block_cipher_internal.h"
+#endif
+
 #include <string.h>
 
 #if defined(MBEDTLS_AESNI_C)
@@ -59,10 +63,16 @@
     uint64_t hi, lo;
     uint64_t vl, vh;
     unsigned char h[16];
-    size_t olen = 0;
 
     memset(h, 0, 16);
-    if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, h, 16, h, &olen)) != 0) {
+
+#if defined(MBEDTLS_CIPHER_C)
+    size_t olen = 0;
+    ret = mbedtls_cipher_update(&ctx->cipher_ctx, h, 16, h, &olen);
+#else
+    ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, h, h);
+#endif
+    if (ret != 0) {
         return ret;
     }
 
@@ -124,12 +134,14 @@
                        unsigned int keybits)
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    const mbedtls_cipher_info_t *cipher_info;
 
     if (keybits != 128 && keybits != 192 && keybits != 256) {
         return MBEDTLS_ERR_GCM_BAD_INPUT;
     }
 
+#if defined(MBEDTLS_CIPHER_C)
+    const mbedtls_cipher_info_t *cipher_info;
+
     cipher_info = mbedtls_cipher_info_from_values(cipher, keybits,
                                                   MBEDTLS_MODE_ECB);
     if (cipher_info == NULL) {
@@ -150,6 +162,17 @@
                                      MBEDTLS_ENCRYPT)) != 0) {
         return ret;
     }
+#else
+    mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
+
+    if ((ret = mbedtls_block_cipher_setup(&ctx->block_cipher_ctx, cipher)) != 0) {
+        return ret;
+    }
+
+    if ((ret = mbedtls_block_cipher_setkey(&ctx->block_cipher_ctx, key, keybits)) != 0) {
+        return ret;
+    }
+#endif
 
     if ((ret = gcm_gen_table(ctx)) != 0) {
         return ret;
@@ -252,8 +275,11 @@
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char work_buf[16];
     const unsigned char *p;
-    size_t use_len, olen = 0;
+    size_t use_len;
     uint64_t iv_bits;
+#if defined(MBEDTLS_CIPHER_C)
+    size_t olen = 0;
+#endif
 
     /* IV is limited to 2^64 bits, so 2^61 bytes */
     /* IV is not allowed to be zero length */
@@ -293,8 +319,13 @@
         gcm_mult(ctx, ctx->y, ctx->y);
     }
 
-    if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16,
-                                     ctx->base_ectr, &olen)) != 0) {
+
+#if defined(MBEDTLS_CIPHER_C)
+    ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr, &olen);
+#else
+    ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ctx->base_ectr);
+#endif
+    if (ret != 0) {
         return ret;
     }
 
@@ -386,11 +417,15 @@
                     const unsigned char *input,
                     unsigned char *output)
 {
-    size_t olen = 0;
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 
-    if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ectr,
-                                     &olen)) != 0) {
+#if defined(MBEDTLS_CIPHER_C)
+    size_t olen = 0;
+    ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ectr, &olen);
+#else
+    ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ectr);
+#endif
+    if (ret != 0) {
         mbedtls_platform_zeroize(ectr, 16);
         return ret;
     }
@@ -614,7 +649,11 @@
     if (ctx == NULL) {
         return;
     }
+#if defined(MBEDTLS_CIPHER_C)
     mbedtls_cipher_free(&ctx->cipher_ctx);
+#else
+    mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
+#endif
     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_gcm_context));
 }
 
diff --git a/library/lmots.c b/library/lmots.c
index e09e3e5..c7091b4 100644
--- a/library/lmots.c
+++ b/library/lmots.c
@@ -69,29 +69,6 @@
 int (*mbedtls_lmots_sign_private_key_invalidated_hook)(unsigned char *) = NULL;
 #endif /* defined(MBEDTLS_TEST_HOOKS) */
 
-void mbedtls_lms_unsigned_int_to_network_bytes(unsigned int val, size_t len,
-                                               unsigned char *bytes)
-{
-    size_t idx;
-
-    for (idx = 0; idx < len; idx++) {
-        bytes[idx] = (val >> ((len - 1 - idx) * 8)) & 0xFF;
-    }
-}
-
-unsigned int mbedtls_lms_network_bytes_to_unsigned_int(size_t len,
-                                                       const unsigned char *bytes)
-{
-    size_t idx;
-    unsigned int val = 0;
-
-    for (idx = 0; idx < len; idx++) {
-        val |= ((unsigned int) bytes[idx]) << (8 * (len - 1 - idx));
-    }
-
-    return val;
-}
-
 /* Calculate the checksum digits that are appended to the end of the LMOTS digit
  * string. See NIST SP800-208 section 3.1 or RFC8554 Algorithm 2 for details of
  * the checksum algorithm.
@@ -191,8 +168,7 @@
     }
 
     checksum = lmots_checksum_calculate(params, out);
-    mbedtls_lms_unsigned_int_to_network_bytes(checksum, CHECKSUM_LEN,
-                                              out + MBEDTLS_LMOTS_N_HASH_LEN(params->type));
+    MBEDTLS_PUT_UINT16_BE(checksum, out, MBEDTLS_LMOTS_N_HASH_LEN(params->type));
 
 exit:
     psa_hash_abort(&op);
@@ -281,17 +257,13 @@
                 goto exit;
             }
 
-            mbedtls_lms_unsigned_int_to_network_bytes(i_digit_idx,
-                                                      I_DIGIT_IDX_LEN,
-                                                      i_digit_idx_bytes);
+            MBEDTLS_PUT_UINT16_BE(i_digit_idx, i_digit_idx_bytes, 0);
             status = psa_hash_update(&op, i_digit_idx_bytes, I_DIGIT_IDX_LEN);
             if (status != PSA_SUCCESS) {
                 goto exit;
             }
 
-            mbedtls_lms_unsigned_int_to_network_bytes(j_hash_idx,
-                                                      J_HASH_IDX_LEN,
-                                                      j_hash_idx_bytes);
+            j_hash_idx_bytes[0] = (uint8_t) j_hash_idx;
             status = psa_hash_update(&op, j_hash_idx_bytes, J_HASH_IDX_LEN);
             if (status != PSA_SUCCESS) {
                 goto exit;
@@ -425,11 +397,8 @@
         return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
     }
 
-    ctx->params.type =
-        (mbedtls_lmots_algorithm_type_t) mbedtls_lms_network_bytes_to_unsigned_int(
-            MBEDTLS_LMOTS_TYPE_LEN,
-            key +
-            MBEDTLS_LMOTS_SIG_TYPE_OFFSET);
+    ctx->params.type = (mbedtls_lmots_algorithm_type_t)
+                       MBEDTLS_GET_UINT32_BE(key, MBEDTLS_LMOTS_SIG_TYPE_OFFSET);
 
     if (key_len != MBEDTLS_LMOTS_PUBLIC_KEY_LEN(ctx->params.type)) {
         return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
@@ -464,9 +433,7 @@
         return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
     }
 
-    mbedtls_lms_unsigned_int_to_network_bytes(ctx->params.type,
-                                              MBEDTLS_LMOTS_TYPE_LEN,
-                                              key + MBEDTLS_LMOTS_SIG_TYPE_OFFSET);
+    MBEDTLS_PUT_UINT32_BE(ctx->params.type, key, MBEDTLS_LMOTS_SIG_TYPE_OFFSET);
 
     memcpy(key + PUBLIC_KEY_I_KEY_ID_OFFSET,
            ctx->params.I_key_identifier,
@@ -559,9 +526,7 @@
         return MBEDTLS_ERR_LMS_VERIFY_FAILED;
     }
 
-    if (mbedtls_lms_network_bytes_to_unsigned_int(MBEDTLS_LMOTS_TYPE_LEN,
-                                                  sig + MBEDTLS_LMOTS_SIG_TYPE_OFFSET) !=
-        MBEDTLS_LMOTS_SHA256_N32_W8) {
+    if (MBEDTLS_GET_UINT32_BE(sig, MBEDTLS_LMOTS_SIG_TYPE_OFFSET) != MBEDTLS_LMOTS_SHA256_N32_W8) {
         return MBEDTLS_ERR_LMS_VERIFY_FAILED;
     }
 
@@ -607,7 +572,7 @@
     size_t output_hash_len;
     unsigned int i_digit_idx;
     unsigned char i_digit_idx_bytes[2];
-    unsigned char const_bytes[1];
+    unsigned char const_bytes[1] = { 0xFF };
 
     if (ctx->have_private_key) {
         return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
@@ -623,12 +588,7 @@
            I_key_identifier,
            sizeof(ctx->params.I_key_identifier));
 
-    mbedtls_lms_unsigned_int_to_network_bytes(q_leaf_identifier,
-                                              MBEDTLS_LMOTS_Q_LEAF_ID_LEN,
-                                              ctx->params.q_leaf_identifier);
-
-    mbedtls_lms_unsigned_int_to_network_bytes(0xFF, sizeof(const_bytes),
-                                              const_bytes);
+    MBEDTLS_PUT_UINT32_BE(q_leaf_identifier, ctx->params.q_leaf_identifier, 0);
 
     for (i_digit_idx = 0;
          i_digit_idx < MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(ctx->params.type);
@@ -652,8 +612,7 @@
             goto exit;
         }
 
-        mbedtls_lms_unsigned_int_to_network_bytes(i_digit_idx, I_DIGIT_IDX_LEN,
-                                                  i_digit_idx_bytes);
+        MBEDTLS_PUT_UINT16_BE(i_digit_idx, i_digit_idx_bytes, 0);
         status = psa_hash_update(&op, i_digit_idx_bytes, I_DIGIT_IDX_LEN);
         if (status != PSA_SUCCESS) {
             goto exit;
@@ -774,9 +733,7 @@
         goto exit;
     }
 
-    mbedtls_lms_unsigned_int_to_network_bytes(ctx->params.type,
-                                              MBEDTLS_LMOTS_TYPE_LEN,
-                                              sig + MBEDTLS_LMOTS_SIG_TYPE_OFFSET);
+    MBEDTLS_PUT_UINT32_BE(ctx->params.type, sig, MBEDTLS_LMOTS_SIG_TYPE_OFFSET);
 
     /* Test hook to check if sig is being written to before we invalidate the
      * private key.
diff --git a/library/lmots.h b/library/lmots.h
index 8e495c9..cf92d32 100644
--- a/library/lmots.h
+++ b/library/lmots.h
@@ -44,29 +44,6 @@
 extern int (*mbedtls_lmots_sign_private_key_invalidated_hook)(unsigned char *);
 #endif /* defined(MBEDTLS_TEST_HOOKS) */
 
-/**
- * \brief                    This function converts an unsigned int into a
- *                           network-byte-order (big endian) string.
- *
- * \param val                The unsigned integer value
- * \param len                The length of the string.
- * \param bytes              The string to output into.
- */
-void mbedtls_lms_unsigned_int_to_network_bytes(unsigned int val, size_t len,
-                                               unsigned char *bytes);
-
-/**
- * \brief                    This function converts a network-byte-order
- *                           (big endian) string into an unsigned integer.
- *
- * \param len                The length of the string.
- * \param bytes              The string.
- *
- * \return                   The corresponding LMS error code.
- */
-unsigned int mbedtls_lms_network_bytes_to_unsigned_int(size_t len,
-                                                       const unsigned char *bytes);
-
 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
 /**
  * \brief                    This function converts a \ref psa_status_t to a
diff --git a/library/lms.c b/library/lms.c
index 0c470a0..08fe753 100644
--- a/library/lms.c
+++ b/library/lms.c
@@ -112,7 +112,7 @@
         goto exit;
     }
 
-    mbedtls_lms_unsigned_int_to_network_bytes(r_node_idx, 4, r_node_idx_bytes);
+    MBEDTLS_PUT_UINT32_BE(r_node_idx, r_node_idx_bytes, 0);
     status = psa_hash_update(&op, r_node_idx_bytes, 4);
     if (status != PSA_SUCCESS) {
         goto exit;
@@ -186,7 +186,7 @@
         goto exit;
     }
 
-    mbedtls_lms_unsigned_int_to_network_bytes(r_node_idx, 4, r_node_idx_bytes);
+    MBEDTLS_PUT_UINT32_BE(r_node_idx, r_node_idx_bytes, 0);
     status = psa_hash_update(&op, r_node_idx_bytes, 4);
     if (status != PSA_SUCCESS) {
         goto exit;
@@ -237,10 +237,7 @@
     mbedtls_lms_algorithm_type_t type;
     mbedtls_lmots_algorithm_type_t otstype;
 
-    type = (mbedtls_lms_algorithm_type_t) mbedtls_lms_network_bytes_to_unsigned_int(
-        MBEDTLS_LMS_TYPE_LEN,
-        key +
-        PUBLIC_KEY_TYPE_OFFSET);
+    type = (mbedtls_lms_algorithm_type_t) MBEDTLS_GET_UINT32_BE(key, PUBLIC_KEY_TYPE_OFFSET);
     if (type != MBEDTLS_LMS_SHA256_M32_H10) {
         return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
     }
@@ -250,10 +247,8 @@
         return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
     }
 
-    otstype = (mbedtls_lmots_algorithm_type_t) mbedtls_lms_network_bytes_to_unsigned_int(
-        MBEDTLS_LMOTS_TYPE_LEN,
-        key +
-        PUBLIC_KEY_OTSTYPE_OFFSET);
+    otstype = (mbedtls_lmots_algorithm_type_t)
+              MBEDTLS_GET_UINT32_BE(key, PUBLIC_KEY_OTSTYPE_OFFSET);
     if (otstype != MBEDTLS_LMOTS_SHA256_N32_W8) {
         return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
     }
@@ -282,12 +277,8 @@
         return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
     }
 
-    mbedtls_lms_unsigned_int_to_network_bytes(
-        ctx->params.type,
-        MBEDTLS_LMS_TYPE_LEN, key + PUBLIC_KEY_TYPE_OFFSET);
-    mbedtls_lms_unsigned_int_to_network_bytes(ctx->params.otstype,
-                                              MBEDTLS_LMOTS_TYPE_LEN,
-                                              key + PUBLIC_KEY_OTSTYPE_OFFSET);
+    MBEDTLS_PUT_UINT32_BE(ctx->params.type, key, PUBLIC_KEY_TYPE_OFFSET);
+    MBEDTLS_PUT_UINT32_BE(ctx->params.otstype, key, PUBLIC_KEY_OTSTYPE_OFFSET);
     memcpy(key + PUBLIC_KEY_I_KEY_ID_OFFSET,
            ctx->params.I_key_identifier,
            MBEDTLS_LMOTS_I_KEY_ID_LEN);
@@ -339,9 +330,7 @@
         return MBEDTLS_ERR_LMS_VERIFY_FAILED;
     }
 
-    if (mbedtls_lms_network_bytes_to_unsigned_int(MBEDTLS_LMOTS_TYPE_LEN,
-                                                  sig + SIG_OTS_SIG_OFFSET +
-                                                  MBEDTLS_LMOTS_SIG_TYPE_OFFSET)
+    if (MBEDTLS_GET_UINT32_BE(sig, SIG_OTS_SIG_OFFSET + MBEDTLS_LMOTS_SIG_TYPE_OFFSET)
         != MBEDTLS_LMOTS_SHA256_N32_W8) {
         return MBEDTLS_ERR_LMS_VERIFY_FAILED;
     }
@@ -350,15 +339,13 @@
         return MBEDTLS_ERR_LMS_VERIFY_FAILED;
     }
 
-    if (mbedtls_lms_network_bytes_to_unsigned_int(MBEDTLS_LMS_TYPE_LEN,
-                                                  sig + SIG_TYPE_OFFSET(ctx->params.otstype))
+    if (MBEDTLS_GET_UINT32_BE(sig, SIG_TYPE_OFFSET(ctx->params.otstype))
         != MBEDTLS_LMS_SHA256_M32_H10) {
         return MBEDTLS_ERR_LMS_VERIFY_FAILED;
     }
 
 
-    q_leaf_identifier = mbedtls_lms_network_bytes_to_unsigned_int(
-        MBEDTLS_LMOTS_Q_LEAF_ID_LEN, sig + SIG_Q_LEAF_ID_OFFSET);
+    q_leaf_identifier = MBEDTLS_GET_UINT32_BE(sig, SIG_Q_LEAF_ID_OFFSET);
 
     if (q_leaf_identifier >= MERKLE_TREE_LEAF_NODE_AM(ctx->params.type)) {
         return MBEDTLS_ERR_LMS_VERIFY_FAILED;
@@ -367,9 +354,7 @@
     memcpy(ots_params.I_key_identifier,
            ctx->params.I_key_identifier,
            MBEDTLS_LMOTS_I_KEY_ID_LEN);
-    mbedtls_lms_unsigned_int_to_network_bytes(q_leaf_identifier,
-                                              MBEDTLS_LMOTS_Q_LEAF_ID_LEN,
-                                              ots_params.q_leaf_identifier);
+    MBEDTLS_PUT_UINT32_BE(q_leaf_identifier, ots_params.q_leaf_identifier, 0);
     ots_params.type = ctx->params.otstype;
 
     ret = mbedtls_lmots_calculate_public_key_candidate(&ots_params,
@@ -505,7 +490,7 @@
     unsigned int height;
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 
-    tree = mbedtls_calloc(MERKLE_TREE_NODE_AM(ctx->params.type),
+    tree = mbedtls_calloc((size_t) MERKLE_TREE_NODE_AM(ctx->params.type),
                           node_bytes);
     if (tree == NULL) {
         return MBEDTLS_ERR_LMS_ALLOC_FAILED;
@@ -530,7 +515,7 @@
 
 exit:
     mbedtls_zeroize_and_free(tree, node_bytes *
-                             MERKLE_TREE_NODE_AM(ctx->params.type));
+                             (size_t) MERKLE_TREE_NODE_AM(ctx->params.type));
 
     return ret;
 }
@@ -669,7 +654,7 @@
         return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
     }
 
-    tree = mbedtls_calloc(MERKLE_TREE_NODE_AM(priv_ctx->params.type),
+    tree = mbedtls_calloc((size_t) MERKLE_TREE_NODE_AM(priv_ctx->params.type),
                           node_bytes);
     if (tree == NULL) {
         return MBEDTLS_ERR_LMS_ALLOC_FAILED;
@@ -692,7 +677,7 @@
 
 exit:
     mbedtls_zeroize_and_free(tree, node_bytes *
-                             MERKLE_TREE_NODE_AM(priv_ctx->params.type));
+                             (size_t) MERKLE_TREE_NODE_AM(priv_ctx->params.type));
 
     return ret;
 }
@@ -753,12 +738,8 @@
         return ret;
     }
 
-    mbedtls_lms_unsigned_int_to_network_bytes(ctx->params.type,
-                                              MBEDTLS_LMS_TYPE_LEN,
-                                              sig + SIG_TYPE_OFFSET(ctx->params.otstype));
-    mbedtls_lms_unsigned_int_to_network_bytes(q_leaf_identifier,
-                                              MBEDTLS_LMOTS_Q_LEAF_ID_LEN,
-                                              sig + SIG_Q_LEAF_ID_OFFSET);
+    MBEDTLS_PUT_UINT32_BE(ctx->params.type, sig, SIG_TYPE_OFFSET(ctx->params.otstype));
+    MBEDTLS_PUT_UINT32_BE(q_leaf_identifier, sig, SIG_Q_LEAF_ID_OFFSET);
 
     ret = get_merkle_path(ctx,
                           MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + q_leaf_identifier,
diff --git a/library/oid.c b/library/oid.c
index 6184abe..d8339c1 100644
--- a/library/oid.c
+++ b/library/oid.c
@@ -1129,7 +1129,7 @@
         }
     }
 
-    encoded_len = out_ptr - oid->p;
+    encoded_len = (size_t) (out_ptr - oid->p);
     resized_mem = mbedtls_calloc(encoded_len, 1);
     if (resized_mem == NULL) {
         ret = MBEDTLS_ERR_ASN1_ALLOC_FAILED;
diff --git a/library/padlock.c b/library/padlock.c
index 1b03069..1f00691 100644
--- a/library/padlock.c
+++ b/library/padlock.c
@@ -96,6 +96,7 @@
     return 0;
 }
 
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
 /*
  * PadLock AES-CBC buffer en(de)cryption
  */
@@ -149,6 +150,7 @@
 
     return 0;
 }
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
 
 #endif /* MBEDTLS_VIA_PADLOCK_HAVE_CODE */
 
diff --git a/library/pem.c b/library/pem.c
index 9500ffc..539134c 100644
--- a/library/pem.c
+++ b/library/pem.c
@@ -298,7 +298,7 @@
     if (*end == '\n') {
         end++;
     }
-    *use_len = end - data;
+    *use_len = (size_t) (end - data);
 
     enc = 0;
 
@@ -383,7 +383,7 @@
         return MBEDTLS_ERR_PEM_INVALID_DATA;
     }
 
-    ret = mbedtls_base64_decode(NULL, 0, &len, s1, s2 - s1);
+    ret = mbedtls_base64_decode(NULL, 0, &len, s1, (size_t) (s2 - s1));
 
     if (ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER) {
         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PEM_INVALID_DATA, ret);
@@ -393,7 +393,7 @@
         return MBEDTLS_ERR_PEM_ALLOC_FAILED;
     }
 
-    if ((ret = mbedtls_base64_decode(buf, len, &len, s1, s2 - s1)) != 0) {
+    if ((ret = mbedtls_base64_decode(buf, len, &len, s1, (size_t) (s2 - s1))) != 0) {
         mbedtls_zeroize_and_free(buf, len);
         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PEM_INVALID_DATA, ret);
     }
@@ -508,7 +508,7 @@
     p += strlen(footer);
 
     *p++ = '\0';
-    *olen = p - buf;
+    *olen = (size_t) (p - buf);
 
     /* Clean any remaining data previously written to the buffer */
     memset(buf + *olen, 0, buf_len - *olen);
diff --git a/library/pkcs7.c b/library/pkcs7.c
index 36b49f5..0869c2e 100644
--- a/library/pkcs7.c
+++ b/library/pkcs7.c
@@ -316,7 +316,7 @@
         goto out;
     }
 
-    signer->issuer_raw.len =  *p - signer->issuer_raw.p;
+    signer->issuer_raw.len =  (size_t) (*p - signer->issuer_raw.p);
 
     ret = mbedtls_x509_get_serial(p, end_issuer_and_sn, &signer->serial);
     if (ret != 0) {
diff --git a/library/pkparse.c b/library/pkparse.c
index 3bb5f7b..edebf92 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -928,7 +928,7 @@
             ret = pk_use_ecparams(&alg_params, pk);
         }
         if (ret == 0) {
-            ret = pk_ecc_set_pubkey(pk, *p, end - *p);
+            ret = pk_ecc_set_pubkey(pk, *p, (size_t) (end - *p));
             *p += end - *p;
         }
     } else
@@ -1233,7 +1233,7 @@
                                          MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
             }
 
-            if ((ret = pk_ecc_set_pubkey(pk, p, end2 - p)) == 0) {
+            if ((ret = pk_ecc_set_pubkey(pk, p, (size_t) (end2 - p))) == 0) {
                 pubkey_done = 1;
             } else {
                 /*
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index bbd6b24..1149940 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -1849,6 +1849,8 @@
     }
 #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
 
+    slot->status = PSA_SLOT_OCCUPIED;
+
     return PSA_SUCCESS;
 }
 
@@ -6625,7 +6627,7 @@
     memcpy(cur, data, data_length);
     cur += data_length;
 
-    status = psa_tls12_prf_set_key(prf, pms, cur - pms);
+    status = psa_tls12_prf_set_key(prf, pms, (size_t) (cur - pms));
 
     mbedtls_zeroize_and_free(pms, pms_len);
     return status;
diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h
index d406ce4..46c5775 100644
--- a/library/psa_crypto_core.h
+++ b/library/psa_crypto_core.h
@@ -33,12 +33,19 @@
  */
 int psa_can_do_hash(psa_algorithm_t hash_alg);
 
+typedef enum {
+    PSA_SLOT_EMPTY = 0,
+    PSA_SLOT_OCCUPIED,
+} psa_key_slot_status_t;
+
 /** The data structure representing a key slot, containing key material
  * and metadata for one key.
  */
 typedef struct {
     psa_core_key_attributes_t attr;
 
+    psa_key_slot_status_t status;
+
     /*
      * Number of locks on the key slot held by the library.
      *
@@ -88,7 +95,7 @@
  */
 static inline int psa_is_key_slot_occupied(const psa_key_slot_t *slot)
 {
-    return slot->attr.type != 0;
+    return slot->status == PSA_SLOT_OCCUPIED;
 }
 
 /** Test whether a key slot is locked.
diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c
index 3b8a319..5ecc3a7 100644
--- a/library/psa_crypto_slot_management.c
+++ b/library/psa_crypto_slot_management.c
@@ -237,11 +237,20 @@
         data = (psa_se_key_data_storage_t *) key_data;
         status = psa_copy_key_material_into_slot(
             slot, data->slot_number, sizeof(data->slot_number));
+
+        if (status == PSA_SUCCESS) {
+            slot->status = PSA_SLOT_OCCUPIED;
+        }
         goto exit;
     }
 #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
 
     status = psa_copy_key_material_into_slot(slot, key_data, key_data_length);
+    if (status != PSA_SUCCESS) {
+        goto exit;
+    }
+
+    slot->status = PSA_SLOT_OCCUPIED;
 
 exit:
     psa_free_persistent_key_data(key_data, key_data_length);
@@ -315,6 +324,7 @@
     /* Copy actual key length and core attributes into the slot on success */
     slot->key.bytes = key_buffer_length;
     slot->attr = attributes.core;
+    slot->status = PSA_SLOT_OCCUPIED;
 
 exit:
     if (status != PSA_SUCCESS) {
diff --git a/library/psa_its_file.c b/library/psa_its_file.c
index 3f32d7d..9567137 100644
--- a/library/psa_its_file.c
+++ b/library/psa_its_file.c
@@ -98,14 +98,9 @@
         return PSA_ERROR_DATA_CORRUPT;
     }
 
-    p_info->size = (header.size[0] |
-                    header.size[1] << 8 |
-                    header.size[2] << 16 |
-                    header.size[3] << 24);
-    p_info->flags = (header.flags[0] |
-                     header.flags[1] << 8 |
-                     header.flags[2] << 16 |
-                     header.flags[3] << 24);
+    p_info->size  = MBEDTLS_GET_UINT32_LE(header.size, 0);
+    p_info->flags = MBEDTLS_GET_UINT32_LE(header.flags, 0);
+
     return PSA_SUCCESS;
 }
 
diff --git a/library/rsa.c b/library/rsa.c
index 38c3dd6..1bf5d13 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -1620,12 +1620,12 @@
         goto cleanup;
     }
 
-    if (ilen - (p - buf) > output_max_len) {
+    if (ilen - ((size_t) (p - buf)) > output_max_len) {
         ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
         goto cleanup;
     }
 
-    *olen = ilen - (p - buf);
+    *olen = ilen - ((size_t) (p - buf));
     if (*olen != 0) {
         memcpy(output, p, *olen);
     }
@@ -2191,7 +2191,7 @@
         return MBEDTLS_ERR_RSA_INVALID_PADDING;
     }
 
-    observed_salt_len = hash_start - p;
+    observed_salt_len = (size_t) (hash_start - p);
 
     if (expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY &&
         observed_salt_len != (size_t) expected_salt_len) {
diff --git a/library/sha256.c b/library/sha256.c
index 45ad6d8..8788981 100644
--- a/library/sha256.c
+++ b/library/sha256.c
@@ -28,7 +28,7 @@
  * By defining the macros ourselves we gain access to those declarations without
  * requiring -march on the command line.
  *
- * `arm_neon.h` could be included by any header file, so we put these defines
+ * `arm_neon.h` is included by common.h, so we put these defines
  * at the top of this file, before any includes.
  */
 #define __ARM_FEATURE_CRYPTO 1
@@ -62,9 +62,7 @@
 
 #  if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
     defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
-#       ifdef __ARM_NEON
-#           include <arm_neon.h>
-#       else
+#       if !defined(MBEDTLS_HAVE_NEON_INTRINSICS)
 #           if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
 #               warning "Target does not support NEON instructions"
 #               undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
@@ -126,12 +124,7 @@
 #      include <signal.h>
 #    endif
 #  endif
-#elif defined(_M_ARM64)
-#  if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
-    defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
-#    include <arm64_neon.h>
-#  endif
-#else
+#elif !defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
 #  undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
 #  undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
 #endif
@@ -156,7 +149,7 @@
 {
     return 1;
 }
-#elif defined(_M_ARM64)
+#elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
 #define WIN32_LEAN_AND_MEAN
 #include <Windows.h>
 #include <processthreadsapi.h>
diff --git a/library/sha512.c b/library/sha512.c
index e7af121..6011254 100644
--- a/library/sha512.c
+++ b/library/sha512.c
@@ -19,7 +19,7 @@
  * By defining the macros ourselves we gain access to those declarations without
  * requiring -march on the command line.
  *
- * `arm_neon.h` could be included by any header file, so we put these defines
+ * `arm_neon.h` is included by common.h, so we put these defines
  * at the top of this file, before any includes.
  */
 #define __ARM_FEATURE_SHA512 1
@@ -48,9 +48,7 @@
 #  if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
     defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
 /* *INDENT-OFF* */
-#   ifdef __ARM_NEON
-#       include <arm_neon.h>
-#   else
+#   if !defined(MBEDTLS_HAVE_NEON_INTRINSICS)
 #       error "Target does not support NEON instructions"
 #   endif
 /*
@@ -109,12 +107,7 @@
 #      include <signal.h>
 #    endif
 #  endif
-#elif defined(_M_ARM64)
-#  if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
-    defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
-#    include <arm64_neon.h>
-#  endif
-#else
+#elif !defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
 #  undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
 #  undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
 #endif
@@ -142,7 +135,7 @@
                            NULL, 0);
     return ret == 0 && value != 0;
 }
-#elif defined(_M_ARM64)
+#elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
 /*
  * As of March 2022, there don't appear to be any PF_ARM_V8_* flags
  * available to pass to IsProcessorFeaturePresent() to check for
diff --git a/library/ssl_client.c b/library/ssl_client.c
index 0e87d86..55fe352 100644
--- a/library/ssl_client.c
+++ b/library/ssl_client.c
@@ -155,7 +155,7 @@
         p += protocol_name_len;
     }
 
-    *out_len = p - buf;
+    *out_len = (size_t) (p - buf);
 
     /* List length = *out_len - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */
     MBEDTLS_PUT_UINT16_BE(*out_len - 6, buf, 4);
@@ -285,7 +285,7 @@
     }
 
     /* Length of named_group_list */
-    named_group_list_len = p - named_group_list;
+    named_group_list_len = (size_t) (p - named_group_list);
     if (named_group_list_len == 0) {
         MBEDTLS_SSL_DEBUG_MSG(1, ("No group available."));
         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
@@ -301,7 +301,7 @@
     MBEDTLS_SSL_DEBUG_BUF(3, "Supported groups extension",
                           buf + 4, named_group_list_len + 2);
 
-    *out_len = p - buf;
+    *out_len = (size_t) (p - buf);
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
     mbedtls_ssl_tls13_set_hs_sent_ext_mask(
@@ -391,14 +391,14 @@
     }
 
     /* Write the cipher_suites length in number of bytes */
-    cipher_suites_len = p - cipher_suites;
+    cipher_suites_len = (size_t) (p - cipher_suites);
     MBEDTLS_PUT_UINT16_BE(cipher_suites_len, buf, 0);
     MBEDTLS_SSL_DEBUG_MSG(3,
                           ("client hello, got %" MBEDTLS_PRINTF_SIZET " cipher suites",
                            cipher_suites_len/2));
 
     /* Output the total length of cipher_suites field. */
-    *out_len = p - buf;
+    *out_len = (size_t) (p - buf);
 
     return 0;
 }
@@ -679,7 +679,7 @@
 #endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
 
     /* Write the length of the list of extensions. */
-    extensions_len = p - p_extensions_len - 2;
+    extensions_len = (size_t) (p - p_extensions_len) - 2;
 
     if (extensions_len == 0) {
         p = p_extensions_len;
@@ -691,12 +691,7 @@
                               p_extensions_len, extensions_len);
     }
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
-    MBEDTLS_SSL_PRINT_EXTS(
-        3, MBEDTLS_SSL_HS_CLIENT_HELLO, handshake->sent_extensions);
-#endif
-
-    *out_len = p - buf;
+    *out_len = (size_t) (p - buf);
     return 0;
 }
 
@@ -1006,6 +1001,11 @@
 #endif
     }
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+    MBEDTLS_SSL_PRINT_EXTS(
+        3, MBEDTLS_SSL_HS_CLIENT_HELLO, ssl->handshake->sent_extensions);
+#endif
+
 cleanup:
 
     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write client hello"));
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index c636ad4..eae192b 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -1409,7 +1409,7 @@
  * Write handshake message header
  */
 MBEDTLS_CHECK_RETURN_CRITICAL
-int mbedtls_ssl_start_handshake_msg(mbedtls_ssl_context *ssl, unsigned hs_type,
+int mbedtls_ssl_start_handshake_msg(mbedtls_ssl_context *ssl, unsigned char hs_type,
                                     unsigned char **buf, size_t *buf_len);
 
 MBEDTLS_CHECK_RETURN_CRITICAL
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index cffd1c9..48d0a03 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -848,7 +848,7 @@
         cur += 2;
     }
 
-    *add_data_len = cur - add_data;
+    *add_data_len = (size_t) (cur - add_data);
 }
 
 #if defined(MBEDTLS_SSL_HAVE_AEAD)
@@ -1212,7 +1212,7 @@
                                                    iv, transform->ivlen,
                                                    add_data, add_data_len,
                                                    data, rec->data_len, /* src */
-                                                   data, rec->buf_len - (data - rec->buf), /* dst */
+                                                   data, rec->buf_len - (size_t) (data - rec->buf), /* dst */
                                                    &rec->data_len,
                                                    transform->taglen)) != 0) {
             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_auth_encrypt_ext", ret);
@@ -1635,12 +1635,13 @@
             return ret;
         }
 #else
-        if ((ret = mbedtls_cipher_auth_decrypt_ext(&transform->cipher_ctx_dec,
-                                                   iv, transform->ivlen,
-                                                   add_data, add_data_len,
-                                                   data, rec->data_len + transform->taglen, /* src */
-                                                   data, rec->buf_len - (data - rec->buf), &olen, /* dst */
-                                                   transform->taglen)) != 0) {
+        if ((ret = mbedtls_cipher_auth_decrypt_ext
+                       (&transform->cipher_ctx_dec,
+                       iv, transform->ivlen,
+                       add_data, add_data_len,
+                       data, rec->data_len + transform->taglen, /* src */
+                       data, rec->buf_len - (size_t) (data - rec->buf), &olen, /* dst */
+                       transform->taglen)) != 0) {
             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_auth_decrypt_ext", ret);
 
             if (ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED) {
@@ -2228,7 +2229,7 @@
             MBEDTLS_SSL_DEBUG_MSG(2, ("timer has expired"));
             ret = MBEDTLS_ERR_SSL_TIMEOUT;
         } else {
-            len = in_buf_len - (ssl->in_hdr - ssl->in_buf);
+            len = in_buf_len - (size_t) (ssl->in_hdr - ssl->in_buf);
 
             if (mbedtls_ssl_is_handshake_over(ssl) == 0) {
                 timeout = ssl->handshake->retransmit_timeout;
@@ -2592,7 +2593,7 @@
         } else {
             const unsigned char * const p = ssl->handshake->cur_msg_p;
             const size_t hs_len = cur->len - 12;
-            const size_t frag_off = p - (cur->p + 12);
+            const size_t frag_off = (size_t) (p - (cur->p + 12));
             const size_t rem_len = hs_len - frag_off;
             size_t cur_hs_frag_len, max_hs_frag_len;
 
@@ -2730,7 +2731,7 @@
 /*
  * Handshake layer functions
  */
-int mbedtls_ssl_start_handshake_msg(mbedtls_ssl_context *ssl, unsigned hs_type,
+int mbedtls_ssl_start_handshake_msg(mbedtls_ssl_context *ssl, unsigned char hs_type,
                                     unsigned char **buf, size_t *buf_len)
 {
     /*
@@ -2969,9 +2970,9 @@
             mbedtls_record rec;
 
             rec.buf         = ssl->out_iv;
-            rec.buf_len     = out_buf_len - (ssl->out_iv - ssl->out_buf);
+            rec.buf_len     = out_buf_len - (size_t) (ssl->out_iv - ssl->out_buf);
             rec.data_len    = ssl->out_msglen;
-            rec.data_offset = ssl->out_msg - rec.buf;
+            rec.data_offset = (size_t) (ssl->out_msg - rec.buf);
 
             memcpy(&rec.ctr[0], ssl->out_ctr, sizeof(rec.ctr));
             mbedtls_ssl_write_version(rec.ver, ssl->conf->transport, tls_ver);
@@ -3096,16 +3097,12 @@
 
 static uint32_t ssl_get_hs_frag_len(mbedtls_ssl_context const *ssl)
 {
-    return (ssl->in_msg[9] << 16) |
-           (ssl->in_msg[10] << 8) |
-           ssl->in_msg[11];
+    return MBEDTLS_GET_UINT24_BE(ssl->in_msg, 9);
 }
 
 static uint32_t ssl_get_hs_frag_off(mbedtls_ssl_context const *ssl)
 {
-    return (ssl->in_msg[6] << 16) |
-           (ssl->in_msg[7] << 8) |
-           ssl->in_msg[8];
+    return MBEDTLS_GET_UINT24_BE(ssl->in_msg, 6);
 }
 
 MBEDTLS_CHECK_RETURN_CRITICAL
@@ -3218,9 +3215,7 @@
 
 static uint32_t ssl_get_hs_total_len(mbedtls_ssl_context const *ssl)
 {
-    return (ssl->in_msg[1] << 16) |
-           (ssl->in_msg[2] << 8) |
-           ssl->in_msg[3];
+    return MBEDTLS_GET_UINT24_BE(ssl->in_msg, 1);
 }
 
 int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl)
@@ -3241,7 +3236,7 @@
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-        unsigned int recv_msg_seq = (ssl->in_msg[4] << 8) | ssl->in_msg[5];
+        unsigned int recv_msg_seq = MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
 
         if (ssl_check_hs_header(ssl) != 0) {
             MBEDTLS_SSL_DEBUG_MSG(1, ("invalid handshake header"));
@@ -3594,7 +3589,7 @@
         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
     }
 
-    *olen = p - obuf;
+    *olen = (size_t) (p - obuf);
 
     /* Go back and fill length fields */
     obuf[27] = (unsigned char) (*olen - 28);
@@ -3856,8 +3851,7 @@
      */
 
     rec->data_offset = rec_hdr_len_offset + rec_hdr_len_len;
-    rec->data_len    = ((size_t) buf[rec_hdr_len_offset + 0] << 8) |
-                       ((size_t) buf[rec_hdr_len_offset + 1] << 0);
+    rec->data_len    = MBEDTLS_GET_UINT16_BE(buf, rec_hdr_len_offset);
     MBEDTLS_SSL_DEBUG_BUF(4, "input record header", buf, rec->data_offset);
 
     MBEDTLS_SSL_DEBUG_MSG(3, ("input record: msgtype = %u, "
@@ -3885,7 +3879,7 @@
      */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
-        rec_epoch = (rec->ctr[0] << 8) | rec->ctr[1];
+        rec_epoch = MBEDTLS_GET_UINT16_BE(rec->ctr, 0);
 
         /* Check that the datagram is large enough to contain a record
          * of the advertised length. */
@@ -3935,7 +3929,7 @@
 MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_check_client_reconnect(mbedtls_ssl_context *ssl)
 {
-    unsigned int rec_epoch = (ssl->in_ctr[0] << 8) | ssl->in_ctr[1];
+    unsigned int rec_epoch = MBEDTLS_GET_UINT16_BE(ssl->in_ctr, 0);
 
     /*
      * Check for an epoch 0 ClientHello. We can't use in_msg here to
@@ -4257,9 +4251,7 @@
     hs_buf = &hs->buffering.hs[0];
     if ((hs_buf->is_valid == 1) && (hs_buf->is_complete == 1)) {
         /* Synthesize a record containing the buffered HS message. */
-        size_t msg_len = (hs_buf->data[1] << 16) |
-                         (hs_buf->data[2] << 8) |
-                         hs_buf->data[3];
+        size_t msg_len = MBEDTLS_GET_UINT24_BE(hs_buf->data, 1);
 
         /* Double-check that we haven't accidentally buffered
          * a message that doesn't fit into the input buffer. */
@@ -4356,7 +4348,7 @@
         case MBEDTLS_SSL_MSG_HANDSHAKE:
         {
             unsigned recv_msg_seq_offset;
-            unsigned recv_msg_seq = (ssl->in_msg[4] << 8) | ssl->in_msg[5];
+            unsigned recv_msg_seq = MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
             mbedtls_ssl_hs_buffer *hs_buf;
             size_t msg_len = ssl->in_hslen - 12;
 
diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c
index 61c87be..8e7c145 100644
--- a/library/ssl_ticket.c
+++ b/library/ssl_ticket.c
@@ -341,7 +341,7 @@
 
     /* Dump session state */
     if ((ret = mbedtls_ssl_session_save(session,
-                                        state, end - state,
+                                        state, (size_t) (end - state),
                                         &clear_len)) != 0 ||
         (unsigned long) clear_len > 65535) {
         goto cleanup;
@@ -364,7 +364,7 @@
                                                /* Additional data: key name, IV and length */
                                                key_name, TICKET_ADD_DATA_LEN,
                                                state, clear_len,
-                                               state, end - state, &ciph_len,
+                                               state, (size_t) (end - state), &ciph_len,
                                                TICKET_AUTH_TAG_BYTES)) != 0) {
         goto cleanup;
     }
@@ -444,7 +444,7 @@
         goto cleanup;
     }
 
-    enc_len = (enc_len_p[0] << 8) | enc_len_p[1];
+    enc_len = MBEDTLS_GET_UINT16_BE(enc_len_p, 0);
 
     if (len != TICKET_MIN_LEN + enc_len) {
         ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 4364c1f..4daf2e7 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -3806,7 +3806,7 @@
     session->tls_version = (mbedtls_ssl_protocol_version) (0x0300 | *p++);
 
     /* Dispatch according to TLS version. */
-    remaining_len = (end - p);
+    remaining_len = (size_t) (end - p);
     switch (session->tls_version) {
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
         case MBEDTLS_SSL_VERSION_TLS1_2:
@@ -4517,7 +4517,7 @@
     }
 
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
-    used += 2 + ssl->transform->in_cid_len + ssl->transform->out_cid_len;
+    used += 2U + ssl->transform->in_cid_len + ssl->transform->out_cid_len;
     if (used <= buf_len) {
         *p++ = ssl->transform->in_cid_len;
         memcpy(p, ssl->transform->in_cid, ssl->transform->in_cid_len);
@@ -4798,7 +4798,7 @@
         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
     }
 
-    ssl->mtu = (p[0] << 8) | p[1];
+    ssl->mtu = MBEDTLS_GET_UINT16_BE(p, 0);
     p += 2;
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
@@ -5743,7 +5743,7 @@
                                  uint32_t *flags)
 {
     int ret = 0;
-    int usage = 0;
+    unsigned int usage = 0;
     const char *ext_oid;
     size_t ext_len;
 
@@ -6846,7 +6846,7 @@
 
         /* Write length only when we know the actual value */
         if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx,
-                                           p + 2, end - (p + 2), &len,
+                                           p + 2, (size_t) (end - (p + 2)), &len,
                                            ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret);
             return ret;
@@ -6863,7 +6863,7 @@
         size_t zlen;
 
         if ((ret = mbedtls_ecdh_calc_secret(&ssl->handshake->ecdh_ctx, &zlen,
-                                            p + 2, end - (p + 2),
+                                            p + 2, (size_t) (end - (p + 2)),
                                             ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_calc_secret", ret);
             return ret;
@@ -6896,7 +6896,7 @@
     memcpy(p, psk, psk_len);
     p += psk_len;
 
-    ssl->handshake->pmslen = p - ssl->handshake->premaster;
+    ssl->handshake->pmslen = (size_t) (p - ssl->handshake->premaster);
 
     return 0;
 }
@@ -7154,7 +7154,7 @@
     /*
      * Same message structure as in mbedtls_ssl_write_certificate()
      */
-    n = (ssl->in_msg[i+1] << 8) | ssl->in_msg[i+2];
+    n = MBEDTLS_GET_UINT16_BE(ssl->in_msg, i + 1);
 
     if (ssl->in_msg[i] != 0 ||
         ssl->in_hslen != n + 3 + mbedtls_ssl_hs_hdr_len(ssl)) {
@@ -7188,8 +7188,7 @@
         }
 
         /* Read length of the next CRT in the chain. */
-        n = ((unsigned int) ssl->in_msg[i + 1] << 8)
-            | (unsigned int) ssl->in_msg[i + 2];
+        n = MBEDTLS_GET_UINT16_BE(ssl->in_msg, i + 1);
         i += 3;
 
         if (n < 128 || i + n > ssl->in_hslen) {
@@ -7717,7 +7716,7 @@
                                          unsigned char *padbuf, size_t hlen,
                                          unsigned char *buf, int from)
 {
-    int len = 12;
+    unsigned int len = 12;
     const char *sender;
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_status_t status;
@@ -7917,7 +7916,8 @@
 
 int mbedtls_ssl_write_finished(mbedtls_ssl_context *ssl)
 {
-    int ret, hash_len;
+    int ret;
+    unsigned int hash_len;
 
     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write finished"));
 
@@ -9089,7 +9089,7 @@
         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
     }
 
-    session->ciphersuite = (p[0] << 8) | p[1];
+    session->ciphersuite = MBEDTLS_GET_UINT16_BE(p, 0);
     p += 2;
 
     session->id_len = *p++;
@@ -9125,7 +9125,7 @@
         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
     }
 
-    cert_len = (p[0] << 16) | (p[1] << 8) | p[2];
+    cert_len = MBEDTLS_GET_UINT24_BE(p, 0);
     p += 3;
 
     if (cert_len != 0) {
@@ -9197,7 +9197,7 @@
         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
     }
 
-    session->ticket_len = (p[0] << 16) | (p[1] << 8) | p[2];
+    session->ticket_len = MBEDTLS_GET_UINT24_BE(p, 0);
     p += 3;
 
     if (session->ticket_len != 0) {
@@ -9379,7 +9379,7 @@
     }
 
     /* Length of supported_signature_algorithms */
-    supported_sig_alg_len = p - supported_sig_alg;
+    supported_sig_alg_len = (size_t) (p - supported_sig_alg);
     if (supported_sig_alg_len == 0) {
         MBEDTLS_SSL_DEBUG_MSG(1, ("No signature algorithms defined."));
         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
@@ -9389,7 +9389,7 @@
     MBEDTLS_PUT_UINT16_BE(supported_sig_alg_len + 2, buf, 2);
     MBEDTLS_PUT_UINT16_BE(supported_sig_alg_len, buf, 4);
 
-    *out_len = p - buf;
+    *out_len = (size_t) (p - buf);
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
     mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_SIG_ALG);
diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c
index 9aa46bd..08549a8 100644
--- a/library/ssl_tls12_client.c
+++ b/library/ssl_tls12_client.c
@@ -607,7 +607,7 @@
     p += ext_len;
 #endif
 
-    *out_len = p - buf;
+    *out_len = (size_t) (p - buf);
 
     return 0;
 }
@@ -941,7 +941,7 @@
         return MBEDTLS_ERR_SSL_DECODE_ERROR;
     }
 
-    list_len = (buf[0] << 8) | buf[1];
+    list_len = MBEDTLS_GET_UINT16_BE(buf, 0);
     if (list_len != len - 2) {
         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
@@ -1304,8 +1304,7 @@
     }
 
     if (ssl->in_hslen > mbedtls_ssl_hs_hdr_len(ssl) + 39 + n) {
-        ext_len = ((buf[38 + n] <<  8)
-                   | (buf[39 + n]));
+        ext_len = MBEDTLS_GET_UINT16_BE(buf, 38 + n);
 
         if ((ext_len > 0 && ext_len < 4) ||
             ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl) + 40 + n + ext_len) {
@@ -1326,7 +1325,7 @@
     }
 
     /* ciphersuite (used later) */
-    i = (buf[35 + n] << 8) | buf[36 + n];
+    i = (int) MBEDTLS_GET_UINT16_BE(buf, n + 35);
 
     /*
      * Read and check compression
@@ -1447,10 +1446,8 @@
                            ext_len));
 
     while (ext_len) {
-        unsigned int ext_id   = ((ext[0] <<  8)
-                                 | (ext[1]));
-        unsigned int ext_size = ((ext[2] <<  8)
-                                 | (ext[3]));
+        unsigned int ext_id   = MBEDTLS_GET_UINT16_BE(ext, 0);
+        unsigned int ext_size = MBEDTLS_GET_UINT16_BE(ext, 2);
 
         if (ext_size + 4 > ext_len) {
             MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
@@ -1741,9 +1738,8 @@
     }
 
     /* Next two bytes are the namedcurve value */
-    tls_id = *(*p)++;
-    tls_id <<= 8;
-    tls_id |= *(*p)++;
+    tls_id = MBEDTLS_GET_UINT16_BE(*p, 0);
+    *p += 2;
 
     /* Check it's a curve we offered */
     if (mbedtls_ssl_check_curve_tls_id(ssl, tls_id) != 0) {
@@ -1883,7 +1879,7 @@
                               ("bad server key exchange message (psk_identity_hint length)"));
         return MBEDTLS_ERR_SSL_DECODE_ERROR;
     }
-    len = (*p)[0] << 8 | (*p)[1];
+    len = MBEDTLS_GET_UINT16_BE(*p, 0);
     *p += 2;
 
     if (end - (*p) < len) {
@@ -2174,7 +2170,7 @@
 #endif
     p   = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl);
     end = ssl->in_msg + ssl->in_hslen;
-    MBEDTLS_SSL_DEBUG_BUF(3,   "server key exchange", p, end - p);
+    MBEDTLS_SSL_DEBUG_BUF(3,   "server key exchange", p, (size_t) (end - p));
 
 #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
@@ -2299,7 +2295,7 @@
         mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
         mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
         unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl);
-        size_t params_len = p - params;
+        size_t params_len = (size_t) (p - params);
         void *rs_ctx = NULL;
         uint16_t sig_alg;
 
@@ -2357,7 +2353,7 @@
                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
             return MBEDTLS_ERR_SSL_DECODE_ERROR;
         }
-        sig_len = (p[0] << 8) | p[1];
+        sig_len = MBEDTLS_GET_UINT16_BE(p, 0);
         p += 2;
 
         if (p != end - sig_len) {
@@ -2585,8 +2581,7 @@
     }
 
     /* supported_signature_algorithms */
-    sig_alg_len = ((buf[mbedtls_ssl_hs_hdr_len(ssl) + 1 + n] <<  8)
-                   | (buf[mbedtls_ssl_hs_hdr_len(ssl) + 2 + n]));
+    sig_alg_len = MBEDTLS_GET_UINT16_BE(buf, mbedtls_ssl_hs_hdr_len(ssl) + 1 + n);
 
     /*
      * The furthest access in buf is in the loop few lines below:
@@ -2621,8 +2616,7 @@
     n += 2 + sig_alg_len;
 
     /* certificate_authorities */
-    dn_len = ((buf[mbedtls_ssl_hs_hdr_len(ssl) + 1 + n] <<  8)
-              | (buf[mbedtls_ssl_hs_hdr_len(ssl) + 2 + n]));
+    dn_len = MBEDTLS_GET_UINT16_BE(buf, mbedtls_ssl_hs_hdr_len(ssl) + 1 + n);
 
     n += dn_len;
     if (ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl) + 3 + n) {
@@ -3252,9 +3246,9 @@
     size_t hashlen;
     void *rs_ctx = NULL;
 #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
-    size_t out_buf_len = ssl->out_buf_len - (ssl->out_msg - ssl->out_buf);
+    size_t out_buf_len = ssl->out_buf_len - (size_t) (ssl->out_msg - ssl->out_buf);
 #else
-    size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN - (ssl->out_msg - ssl->out_buf);
+    size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN - (size_t) (ssl->out_msg - ssl->out_buf);
 #endif
 
     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate verify"));
@@ -3421,10 +3415,9 @@
 
     msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl);
 
-    lifetime = (((uint32_t) msg[0]) << 24) | (msg[1] << 16) |
-               (msg[2] << 8) | (msg[3]);
+    lifetime = MBEDTLS_GET_UINT32_BE(msg, 0);
 
-    ticket_len = (msg[4] << 8) | (msg[5]);
+    ticket_len = MBEDTLS_GET_UINT16_BE(msg, 4);
 
     if (ticket_len + 6 + mbedtls_ssl_hs_hdr_len(ssl) != ssl->in_hslen) {
         MBEDTLS_SSL_DEBUG_MSG(1, ("bad new session ticket message"));
diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c
index b007e5c..a07d0fb 100644
--- a/library/ssl_tls12_server.c
+++ b/library/ssl_tls12_server.c
@@ -192,7 +192,7 @@
                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
         return MBEDTLS_ERR_SSL_DECODE_ERROR;
     }
-    list_size = ((buf[0] << 8) | (buf[1]));
+    list_size = MBEDTLS_GET_UINT16_BE(buf, 0);
     if (list_size + 2 != len ||
         list_size % 2 != 0) {
         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
@@ -957,7 +957,7 @@
     }
 
     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, message len.: %d",
-                              (ssl->in_len[0] << 8) | ssl->in_len[1]));
+                              MBEDTLS_GET_UINT16_BE(ssl->in_len, 0)));
 
     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, protocol version: [%d:%d]",
                               buf[1], buf[2]));
@@ -993,7 +993,7 @@
     }
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
-    msg_len = (ssl->in_len[0] << 8) | ssl->in_len[1];
+    msg_len = MBEDTLS_GET_UINT16_BE(ssl->in_len, 0);
 
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
     if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) {
@@ -1251,8 +1251,7 @@
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
     ciph_offset = 35 + sess_len;
 
-    ciph_len = (buf[ciph_offset + 0] << 8)
-               | (buf[ciph_offset + 1]);
+    ciph_len = MBEDTLS_GET_UINT16_BE(buf, ciph_offset);
 
     if (ciph_len < 2 ||
         ciph_len + 2 + ciph_offset + 1 > msg_len || /* 1 for comp. alg. len */
@@ -1300,8 +1299,7 @@
             return MBEDTLS_ERR_SSL_DECODE_ERROR;
         }
 
-        ext_len = (buf[ext_offset + 0] << 8)
-                  | (buf[ext_offset + 1]);
+        ext_len = MBEDTLS_GET_UINT16_BE(buf, ext_offset);
 
         if (msg_len != ext_offset + 2 + ext_len) {
             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
@@ -1325,8 +1323,8 @@
                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
             return MBEDTLS_ERR_SSL_DECODE_ERROR;
         }
-        ext_id   = ((ext[0] <<  8) | (ext[1]));
-        ext_size = ((ext[2] <<  8) | (ext[3]));
+        ext_id   = MBEDTLS_GET_UINT16_BE(ext, 0);
+        ext_size = MBEDTLS_GET_UINT16_BE(ext, 2);
 
         if (ext_size + 4 > ext_len) {
             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
@@ -1858,7 +1856,7 @@
         *p++ = 0x00;
     }
 
-    *olen = p - buf;
+    *olen = (size_t) (p - buf);
 }
 
 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
@@ -1950,7 +1948,7 @@
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx,
-                                          p + 2, end - p - 2, &kkpp_len,
+                                          p + 2, (size_t) (end - p - 2), &kkpp_len,
                                           MBEDTLS_ECJPAKE_ROUND_ONE);
     if (ret != 0) {
         psa_destroy_key(ssl->handshake->psa_pake_password);
@@ -1960,7 +1958,7 @@
     }
 #else
     ret = mbedtls_ecjpake_write_round_one(&ssl->handshake->ecjpake_ctx,
-                                          p + 2, end - p - 2, &kkpp_len,
+                                          p + 2, (size_t) (end - p - 2), &kkpp_len,
                                           ssl->conf->f_rng, ssl->conf->p_rng);
     if (ret != 0) {
         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_write_round_one", ret);
@@ -2081,7 +2079,7 @@
 
     MBEDTLS_SSL_DEBUG_BUF(3, "cookie sent", cookie_len_byte + 1, *cookie_len_byte);
 
-    ssl->out_msglen  = p - ssl->out_msg;
+    ssl->out_msglen  = (size_t) (p - ssl->out_msg);
     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
     ssl->out_msg[0]  = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
 
@@ -2386,7 +2384,7 @@
         p += 2 + ext_len;
     }
 
-    ssl->out_msglen  = p - buf;
+    ssl->out_msglen  = (size_t) (p - buf);
     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
     ssl->out_msg[0]  = MBEDTLS_SSL_HS_SERVER_HELLO;
 
@@ -2570,12 +2568,12 @@
 
             MBEDTLS_SSL_DEBUG_BUF(3, "requested DN", p - dn_size, dn_size);
 
-            total_dn_size += 2 + dn_size;
+            total_dn_size += (unsigned short) (2 + dn_size);
             crt = crt->next;
         }
     }
 
-    ssl->out_msglen  = p - buf;
+    ssl->out_msglen  = (size_t) (p - buf);
     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
     ssl->out_msg[0]  = MBEDTLS_SSL_HS_CERTIFICATE_REQUEST;
     MBEDTLS_PUT_UINT16_BE(total_dn_size, ssl->out_msg, 4 + ct_len + sa_len);
@@ -2779,9 +2777,9 @@
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
 #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
-    size_t out_buf_len = ssl->out_buf_len - (ssl->out_msg - ssl->out_buf);
+    size_t out_buf_len = ssl->out_buf_len - (size_t) (ssl->out_msg - ssl->out_buf);
 #else
-    size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN - (ssl->out_msg - ssl->out_buf);
+    size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN - (size_t) (ssl->out_msg - ssl->out_buf);
 #endif
 #endif
 
@@ -3086,7 +3084,7 @@
             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
         }
 
-        size_t dig_signed_len = ssl->out_msg + ssl->out_msglen - dig_signed;
+        size_t dig_signed_len = (size_t) (ssl->out_msg + ssl->out_msglen - dig_signed);
         size_t hashlen = 0;
         unsigned char hash[MBEDTLS_MD_MAX_SIZE];
 
@@ -3101,8 +3099,8 @@
         mbedtls_pk_type_t sig_alg =
             mbedtls_ssl_get_ciphersuite_sig_pk_alg(ciphersuite_info);
 
-        unsigned int sig_hash =
-            mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg(
+        unsigned char sig_hash =
+            (unsigned char) mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg(
                 ssl, mbedtls_ssl_sig_from_pk_alg(sig_alg));
 
         mbedtls_md_type_t md_alg = mbedtls_ssl_md_alg_from_hash(sig_hash);
@@ -3360,7 +3358,7 @@
         return MBEDTLS_ERR_SSL_DECODE_ERROR;
     }
 
-    n = ((*p)[0] << 8) | (*p)[1];
+    n = MBEDTLS_GET_UINT16_BE(*p, 0);
     *p += 2;
 
     if (*p + n > end) {
@@ -3593,7 +3591,7 @@
         return MBEDTLS_ERR_SSL_DECODE_ERROR;
     }
 
-    n = ((*p)[0] << 8) | (*p)[1];
+    n = MBEDTLS_GET_UINT16_BE(*p, 0);
     *p += 2;
 
     if (n == 0 || n > end - *p) {
@@ -3763,7 +3761,7 @@
         handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
 #else
         if ((ret = mbedtls_ecdh_read_public(&ssl->handshake->ecdh_ctx,
-                                            p, end - p)) != 0) {
+                                            p, (size_t) (end - p))) != 0) {
             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_read_public", ret);
             return MBEDTLS_ERR_SSL_DECODE_ERROR;
         }
@@ -3976,7 +3974,7 @@
         }
 
         if ((ret = mbedtls_ecdh_read_public(&ssl->handshake->ecdh_ctx,
-                                            p, end - p)) != 0) {
+                                            p, (size_t) (end - p))) != 0) {
             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_read_public", ret);
             return MBEDTLS_ERR_SSL_DECODE_ERROR;
         }
@@ -4005,7 +4003,7 @@
     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
         if ((ret = mbedtls_psa_ecjpake_read_round(
-                 &ssl->handshake->psa_pake_ctx, p, end - p,
+                 &ssl->handshake->psa_pake_ctx, p, (size_t) (end - p),
                  MBEDTLS_ECJPAKE_ROUND_TWO)) != 0) {
             psa_destroy_key(ssl->handshake->psa_pake_password);
             psa_pake_abort(&ssl->handshake->psa_pake_ctx);
@@ -4015,7 +4013,7 @@
         }
 #else
         ret = mbedtls_ecjpake_read_round_two(&ssl->handshake->ecjpake_ctx,
-                                             p, end - p);
+                                             p, (size_t) (end - p));
         if (ret != 0) {
             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_two", ret);
             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
@@ -4189,7 +4187,7 @@
         return MBEDTLS_ERR_SSL_DECODE_ERROR;
     }
 
-    sig_len = (ssl->in_msg[i] << 8) | ssl->in_msg[i+1];
+    sig_len = MBEDTLS_GET_UINT16_BE(ssl->in_msg, i);
     i += 2;
 
     if (i + sig_len != ssl->in_hslen) {
diff --git a/library/threading.c b/library/threading.c
index 52fe8fc..873b507 100644
--- a/library/threading.c
+++ b/library/threading.c
@@ -56,28 +56,27 @@
         return;
     }
 
-    /* A nonzero value of is_valid indicates a successfully initialized
-     * mutex. This is a workaround for not being able to return an error
-     * code for this function. The lock/unlock functions return an error
-     * if is_valid is nonzero. The Mbed TLS unit test code uses this field
-     * to distinguish more states of the mutex; see
-     * tests/src/threading_helpers for details. */
-    mutex->is_valid = pthread_mutex_init(&mutex->mutex, NULL) == 0;
+    /* One problem here is that calling lock on a pthread mutex without first
+     * having initialised it is undefined behaviour. Obviously we cannot check
+     * this here in a thread safe manner without a significant performance
+     * hit, so state transitions are checked in tests only via the state
+     * variable. Please make sure any new mutex that gets added is exercised in
+     * tests; see tests/src/threading_helpers.c for more details. */
+    (void) pthread_mutex_init(&mutex->mutex, NULL);
 }
 
 static void threading_mutex_free_pthread(mbedtls_threading_mutex_t *mutex)
 {
-    if (mutex == NULL || !mutex->is_valid) {
+    if (mutex == NULL) {
         return;
     }
 
     (void) pthread_mutex_destroy(&mutex->mutex);
-    mutex->is_valid = 0;
 }
 
 static int threading_mutex_lock_pthread(mbedtls_threading_mutex_t *mutex)
 {
-    if (mutex == NULL || !mutex->is_valid) {
+    if (mutex == NULL) {
         return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA;
     }
 
@@ -90,7 +89,7 @@
 
 static int threading_mutex_unlock_pthread(mbedtls_threading_mutex_t *mutex)
 {
-    if (mutex == NULL || !mutex->is_valid) {
+    if (mutex == NULL) {
         return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA;
     }
 
diff --git a/library/x509_create.c b/library/x509_create.c
index 424cce1..8f31c3b 100644
--- a/library/x509_create.c
+++ b/library/x509_create.c
@@ -169,7 +169,7 @@
             return MBEDTLS_ERR_X509_INVALID_NAME;
         }
     }
-    *data_len = d - data;
+    *data_len = (size_t) (d - data);
     return 0;
 }
 
@@ -297,8 +297,8 @@
 
     while (c <= end) {
         if (in_attr_type && *c == '=') {
-            if ((attr_descr = x509_attr_descr_from_name(s, c - s)) == NULL) {
-                if ((mbedtls_oid_from_numeric_string(&oid, s, c - s)) != 0) {
+            if ((attr_descr = x509_attr_descr_from_name(s, (size_t) (c - s))) == NULL) {
+                if ((mbedtls_oid_from_numeric_string(&oid, s, (size_t) (c - s))) != 0) {
                     return MBEDTLS_ERR_X509_INVALID_NAME;
                 } else {
                     numericoid = 1;
@@ -322,7 +322,7 @@
                 /* We know that c >= s (loop invariant) and c != s (in this
                  * else branch), hence c - s - 1 >= 0. */
                 parse_ret = parse_attribute_value_hex_der_encoded(
-                    s + 1, c - s - 1,
+                    s + 1, (size_t) (c - s) - 1,
                     data, sizeof(data), &data_len, &tag);
                 if (parse_ret != 0) {
                     mbedtls_free(oid.p);
diff --git a/library/x509_crl.c b/library/x509_crl.c
index cad784e..fdbad23 100644
--- a/library/x509_crl.c
+++ b/library/x509_crl.c
@@ -367,7 +367,7 @@
     }
 
     end = p + len;
-    crl->tbs.len = end - crl->tbs.p;
+    crl->tbs.len = (size_t) (end - crl->tbs.p);
 
     /*
      * Version  ::=  INTEGER  OPTIONAL {  v1(0), v2(1)  }
@@ -411,7 +411,7 @@
         return ret;
     }
 
-    crl->issuer_raw.len = p - crl->issuer_raw.p;
+    crl->issuer_raw.len = (size_t) (p - crl->issuer_raw.p);
 
     /*
      * thisUpdate          Time
diff --git a/library/x509_crt.c b/library/x509_crt.c
index f41eb47..1fe4448 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -1108,7 +1108,7 @@
     }
 
     end = crt_end = p + len;
-    crt->raw.len = crt_end - buf;
+    crt->raw.len = (size_t) (crt_end - buf);
     if (make_copy != 0) {
         /* Create and populate a new buffer for the raw field. */
         crt->raw.p = p = mbedtls_calloc(1, crt->raw.len);
@@ -1138,7 +1138,7 @@
     }
 
     end = p + len;
-    crt->tbs.len = end - crt->tbs.p;
+    crt->tbs.len = (size_t) (end - crt->tbs.p);
 
     /*
      * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
@@ -1185,7 +1185,7 @@
         return ret;
     }
 
-    crt->issuer_raw.len = p - crt->issuer_raw.p;
+    crt->issuer_raw.len = (size_t) (p - crt->issuer_raw.p);
 
     /*
      * Validity ::= SEQUENCE {
@@ -1215,7 +1215,7 @@
         return ret;
     }
 
-    crt->subject_raw.len = p - crt->subject_raw.p;
+    crt->subject_raw.len = (size_t) (p - crt->subject_raw.p);
 
     /*
      * SubjectPublicKeyInfo
@@ -1225,7 +1225,7 @@
         mbedtls_x509_crt_free(crt);
         return ret;
     }
-    crt->pk_raw.len = p - crt->pk_raw.p;
+    crt->pk_raw.len = (size_t) (p - crt->pk_raw.p);
 
     /*
      *  issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
diff --git a/library/x509_csr.c b/library/x509_csr.c
index a293ec0..79b1589 100644
--- a/library/x509_csr.c
+++ b/library/x509_csr.c
@@ -328,7 +328,7 @@
     }
 
     end = p + len;
-    csr->cri.len = end - csr->cri.p;
+    csr->cri.len = (size_t) (end - csr->cri.p);
 
     /*
      *  Version  ::=  INTEGER {  v1(0) }
@@ -361,7 +361,7 @@
         return ret;
     }
 
-    csr->subject_raw.len = p - csr->subject_raw.p;
+    csr->subject_raw.len = (size_t) (p - csr->subject_raw.p);
 
     /*
      *  subjectPKInfo SubjectPublicKeyInfo
diff --git a/library/x509write_crt.c b/library/x509write_crt.c
index 4c019ee..44b6b17 100644
--- a/library/x509write_crt.c
+++ b/library/x509write_crt.c
@@ -481,7 +481,7 @@
      */
     MBEDTLS_ASN1_CHK_ADD(pub_len,
                          mbedtls_pk_write_pubkey_der(ctx->subject_key,
-                                                     buf, c - buf));
+                                                     buf, (size_t) (c - buf)));
     c -= pub_len;
     len += pub_len;
 
diff --git a/library/x509write_csr.c b/library/x509write_csr.c
index 4e39755..254da69 100644
--- a/library/x509write_csr.c
+++ b/library/x509write_csr.c
@@ -185,7 +185,7 @@
                              MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC));
 
     MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_pk_write_pubkey_der(ctx->key,
-                                                              buf, c - buf));
+                                                              buf, (size_t) (c - buf)));
     c -= pub_len;
     len += pub_len;
 
@@ -276,7 +276,7 @@
                              MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
 
     /* Zero the unused bytes at the start of buf */
-    memset(buf, 0, c2 - buf);
+    memset(buf, 0, (size_t) (c2 - buf));
 
     return (int) len;
 }
diff --git a/programs/pkey/dh_client.c b/programs/pkey/dh_client.c
index 946e049..0cb1562 100644
--- a/programs/pkey/dh_client.c
+++ b/programs/pkey/dh_client.c
@@ -44,6 +44,13 @@
                    "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_SHA1_C not defined.\n");
     mbedtls_exit(0);
 }
+
+#elif defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
+int main(void)
+{
+    mbedtls_printf("MBEDTLS_BLOCK_CIPHER_NO_DECRYPT defined.\n");
+    mbedtls_exit(0);
+}
 #else
 
 
diff --git a/programs/psa/psa_hash_demo.sh b/programs/psa/psa_hash_demo.sh
new file mode 100755
index 0000000..a26697c
--- /dev/null
+++ b/programs/psa/psa_hash_demo.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+. "${0%/*}/../demo_common.sh"
+
+msg <<'EOF'
+This program demonstrates the use of the PSA cryptography interface to
+compute a SHA-256 hash of a test string using the one-shot API call
+and also using the multi-part operation API.
+EOF
+
+depends_on MBEDTLS_PSA_CRYPTO_C PSA_WANT_ALG_SHA_256
+
+program="${0%/*}"/psa_hash
+
+"$program"
+
+cleanup
diff --git a/programs/ssl/ssl_test_lib.c b/programs/ssl/ssl_test_lib.c
index 6e0c615..b49dd67 100644
--- a/programs/ssl/ssl_test_lib.c
+++ b/programs/ssl/ssl_test_lib.c
@@ -435,6 +435,9 @@
 
 void test_hooks_free(void)
 {
+#if defined(MBEDTLS_TEST_MUTEX_USAGE)
+    mbedtls_test_mutex_usage_end();
+#endif
 }
 
 #endif /* MBEDTLS_TEST_HOOKS */
diff --git a/programs/test/metatest.c b/programs/test/metatest.c
index 2973cce..b8dffa9 100644
--- a/programs/test/metatest.c
+++ b/programs/test/metatest.c
@@ -46,6 +46,12 @@
  */
 volatile int false_but_the_compiler_does_not_know = 0;
 
+/* Hide calls to calloc/free from static checkers such as
+ * `gcc-12 -Wuse-after-free`, to avoid compile-time complaints about
+ * code where we do mean to cause a runtime error. */
+void * (* volatile calloc_but_the_compiler_does_not_know)(size_t, size_t) = mbedtls_calloc;
+void(*volatile free_but_the_compiler_does_not_know)(void *) = mbedtls_free;
+
 /* Set n bytes at the address p to all-bits-zero, in such a way that
  * the compiler should not know that p is all-bits-zero. */
 static void set_to_zero_but_the_compiler_does_not_know(volatile void *p, size_t n)
@@ -98,9 +104,9 @@
 void read_after_free(const char *name)
 {
     (void) name;
-    volatile char *p = mbedtls_calloc(1, 1);
+    volatile char *p = calloc_but_the_compiler_does_not_know(1, 1);
     *p = 'a';
-    mbedtls_free((void *) p);
+    free_but_the_compiler_does_not_know((void *) p);
     /* Undefined behavior (read after free) */
     mbedtls_printf("%u\n", (unsigned) *p);
 }
@@ -108,11 +114,11 @@
 void double_free(const char *name)
 {
     (void) name;
-    volatile char *p = mbedtls_calloc(1, 1);
+    volatile char *p = calloc_but_the_compiler_does_not_know(1, 1);
     *p = 'a';
-    mbedtls_free((void *) p);
+    free_but_the_compiler_does_not_know((void *) p);
     /* Undefined behavior (double free) */
-    mbedtls_free((void *) p);
+    free_but_the_compiler_does_not_know((void *) p);
 }
 
 void read_uninitialized_stack(const char *name)
@@ -132,7 +138,7 @@
 void memory_leak(const char *name)
 {
     (void) name;
-    volatile char *p = mbedtls_calloc(1, 1);
+    volatile char *p = calloc_but_the_compiler_does_not_know(1, 1);
     mbedtls_printf("%u\n", (unsigned) *p);
     /* Leak of a heap object */
 }
diff --git a/scripts/config.py b/scripts/config.py
index 4878d8b..d5fb85e 100755
--- a/scripts/config.py
+++ b/scripts/config.py
@@ -180,6 +180,7 @@
     #pylint: disable=line-too-long
     'MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH', # interacts with CTR_DRBG_128_BIT_KEY
     'MBEDTLS_AES_USE_HARDWARE_ONLY', # hardware dependency
+    'MBEDTLS_BLOCK_CIPHER_NO_DECRYPT', # incompatible with ECB in PSA, CBC/XTS/NIST_KW/DES
     'MBEDTLS_CTR_DRBG_USE_128_BIT_KEY', # interacts with ENTROPY_FORCE_SHA256
     'MBEDTLS_DEPRECATED_REMOVED', # conflicts with deprecated options
     'MBEDTLS_DEPRECATED_WARNING', # conflicts with deprecated options
diff --git a/scripts/mbedtls_dev/psa_information.py b/scripts/mbedtls_dev/psa_information.py
index 32e5009..b21a0cf 100644
--- a/scripts/mbedtls_dev/psa_information.py
+++ b/scripts/mbedtls_dev/psa_information.py
@@ -6,7 +6,8 @@
 #
 
 import re
-from typing import Dict, FrozenSet, List, Optional
+from collections import OrderedDict
+from typing import FrozenSet, List, Optional
 
 from . import macro_collector
 
@@ -86,22 +87,31 @@
     return sorted(psa_want_symbol(name) for name in used)
 
 # Define set of regular expressions and dependencies to optionally append
-# extra dependencies for test case.
-AES_128BIT_ONLY_DEP_REGEX = r'AES\s(192|256)'
-AES_128BIT_ONLY_DEP = ["!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH"]
+# extra dependencies for test case based on key description.
 
-DEPENDENCY_FROM_KEY = {
-    AES_128BIT_ONLY_DEP_REGEX: AES_128BIT_ONLY_DEP
-}#type: Dict[str, List[str]]
-def generate_key_dependencies(description: str) -> List[str]:
-    """Return additional dependencies based on pairs of REGEX and dependencies.
+# Skip AES test cases which require 192- or 256-bit key
+# if MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH defined
+AES_128BIT_ONLY_DEP_REGEX = re.compile(r'AES\s(192|256)')
+AES_128BIT_ONLY_DEP = ['!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH']
+# Skip AES/ARIA/CAMELLIA test cases which require decrypt operation in ECB mode
+# if MBEDTLS_BLOCK_CIPHER_NO_DECRYPT enabled.
+ECB_NO_PADDING_DEP_REGEX = re.compile(r'(AES|ARIA|CAMELLIA).*ECB_NO_PADDING')
+ECB_NO_PADDING_DEP = ['!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT']
+
+DEPENDENCY_FROM_DESCRIPTION = OrderedDict()
+DEPENDENCY_FROM_DESCRIPTION[AES_128BIT_ONLY_DEP_REGEX] = AES_128BIT_ONLY_DEP
+DEPENDENCY_FROM_DESCRIPTION[ECB_NO_PADDING_DEP_REGEX] = ECB_NO_PADDING_DEP
+def generate_deps_from_description(
+        description: str
+    ) -> List[str]:
+    """Return additional dependencies based on test case description and REGEX.
     """
-    deps = []
-    for regex, dep in DEPENDENCY_FROM_KEY.items():
+    dep_list = []
+    for regex, deps in DEPENDENCY_FROM_DESCRIPTION.items():
         if re.search(regex, description):
-            deps += dep
+            dep_list += deps
 
-    return deps
+    return dep_list
 
 # A temporary hack: at the time of writing, not all dependency symbols
 # are implemented yet. Skip test cases for which the dependency symbols are
diff --git a/scripts/prepare_release.sh b/scripts/prepare_release.sh
index 7f972e0..3b63ed9 100755
--- a/scripts/prepare_release.sh
+++ b/scripts/prepare_release.sh
@@ -39,11 +39,11 @@
 GITIGNORES=$(find . -name ".gitignore")
 for GITIGNORE in $GITIGNORES; do
     if [ -n "$unrelease" ]; then
-        sed -i '/###START_COMMENTED_GENERATED_FILES###/,/###END_COMMENTED_GENERATED_FILES###/s/^# //' $GITIGNORE
+        sed -i '/###START_COMMENTED_GENERATED_FILES###/,/###END_COMMENTED_GENERATED_FILES###/s/^#//' $GITIGNORE
         sed -i 's/###START_COMMENTED_GENERATED_FILES###/###START_GENERATED_FILES###/' $GITIGNORE
         sed -i 's/###END_COMMENTED_GENERATED_FILES###/###END_GENERATED_FILES###/' $GITIGNORE
     else
-        sed -i '/###START_GENERATED_FILES###/,/###END_GENERATED_FILES###/s/^/# /' $GITIGNORE
+        sed -i '/###START_GENERATED_FILES###/,/###END_GENERATED_FILES###/s/^/#/' $GITIGNORE
         sed -i 's/###START_GENERATED_FILES###/###START_COMMENTED_GENERATED_FILES###/' $GITIGNORE
         sed -i 's/###END_GENERATED_FILES###/###END_COMMENTED_GENERATED_FILES###/' $GITIGNORE
     fi
diff --git a/tests/include/test/helpers.h b/tests/include/test/helpers.h
index ba117fb..7c962a2 100644
--- a/tests/include/test/helpers.h
+++ b/tests/include/test/helpers.h
@@ -20,6 +20,21 @@
 
 #include "mbedtls/build_info.h"
 
+#if defined(__SANITIZE_ADDRESS__) /* gcc -fsanitize=address */
+#  define MBEDTLS_TEST_HAVE_ASAN
+#endif
+#if defined(__has_feature)
+#  if __has_feature(address_sanitizer) /* clang -fsanitize=address */
+#    define MBEDTLS_TEST_HAVE_ASAN
+#  endif
+#  if __has_feature(memory_sanitizer) /* clang -fsanitize=memory */
+#    define MBEDTLS_TEST_HAVE_MSAN
+#  endif
+#  if __has_feature(thread_sanitizer) /* clang -fsanitize=thread */
+#    define MBEDTLS_TEST_HAVE_TSAN
+#  endif
+#endif
+
 #if defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_PTHREAD) && \
     defined(MBEDTLS_TEST_HOOKS)
 #define MBEDTLS_TEST_MUTEX_USAGE
@@ -240,10 +255,18 @@
 #endif
 
 #if defined(MBEDTLS_TEST_MUTEX_USAGE)
-/** Permanently activate the mutex usage verification framework. See
- * threading_helpers.c for information. */
+/**
+ *  Activate the mutex usage verification framework. See threading_helpers.c for
+ *  information.
+ *  */
 void mbedtls_test_mutex_usage_init(void);
 
+/**
+ *  Deactivate the mutex usage verification framework. See threading_helpers.c
+ *  for information.
+ */
+void mbedtls_test_mutex_usage_end(void);
+
 /** Call this function after executing a test case to check for mutex usage
  * errors. */
 void mbedtls_test_mutex_usage_check(void);
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 929b093..462597b 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -163,6 +163,9 @@
     # basic-build-test.sh as well.
     RELEASE_SEED=1
 
+    # Specify character collation for regular expressions and sorting with C locale
+    export LC_COLLATE=C
+
     : ${MBEDTLS_TEST_OUTCOME_FILE=}
     : ${MBEDTLS_TEST_PLATFORM="$(uname -s | tr -c \\n0-9A-Za-z _)-$(uname -m | tr -c \\n0-9A-Za-z _)"}
     export MBEDTLS_TEST_OUTCOME_FILE
@@ -397,13 +400,12 @@
     FLAGS="$1"
 
     msg "build: ARM Compiler 6 ($FLAGS)"
+    make clean
     ARM_TOOL_VARIANT="ult" CC="$ARMC6_CC" AR="$ARMC6_AR" CFLAGS="$FLAGS" \
                     WARNING_CFLAGS='-Werror -xc -std=c99' make lib
 
     msg "size: ARM Compiler 6 ($FLAGS)"
     "$ARMC6_FROMELF" -z library/*.o
-
-    make clean
 }
 
 err_msg()
@@ -1047,10 +1049,12 @@
         grep -v MBEDTLS_PSA_ |
         sort -u > $found
 
-    # Expected ones with justification - keep in sorted order!
+    # Expected ones with justification - keep in sorted order by ASCII table!
     rm -f $expected
     # No PSA equivalent - WANT_KEY_TYPE_AES means all sizes
     echo "!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH" >> $expected
+    # No PSA equivalent - used to skip decryption tests in PSA-ECB, CBC/XTS/NIST_KW/DES
+    echo "!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT" >> $expected
     # This is used by import_rsa_made_up() in test_suite_psa_crypto in order
     # to build a fake RSA key of the wanted size based on
     # PSA_VENDOR_RSA_MAX_KEY_BITS. The legacy module is only used by
@@ -1541,9 +1545,7 @@
     # (currently ignored anyway because we completely disable PSA)
     scripts/config.py unset MBEDTLS_PSA_CRYPTO_CONFIG
     # Disable features that depend on CIPHER_C
-    scripts/config.py unset MBEDTLS_CCM_C
     scripts/config.py unset MBEDTLS_CMAC_C
-    scripts/config.py unset MBEDTLS_GCM_C
     scripts/config.py unset MBEDTLS_NIST_KW_C
     scripts/config.py unset MBEDTLS_PKCS12_C
     scripts/config.py unset MBEDTLS_PKCS5_C
@@ -1556,7 +1558,6 @@
     scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
     scripts/config.py unset MBEDTLS_LMS_C
     scripts/config.py unset MBEDTLS_LMS_PRIVATE
-    make CFLAGS='-DMBEDTLS_BLOCK_CIPHER_C'
 
     msg "test: full no CIPHER no PSA_CRYPTO_C"
     make test
@@ -1582,9 +1583,7 @@
         # on CIPHER_C so we disable them.
         # This does not hold for KEY_TYPE_CHACHA20 and ALG_CHACHA20_POLY1305
         # so we keep them enabled.
-        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_CCM
         scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_CCM_STAR_NO_TAG
-        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_GCM
         scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_CMAC
         scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_CBC_NO_PADDING
         scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_CBC_PKCS7
@@ -1593,27 +1592,19 @@
         scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_ECB_NO_PADDING
         scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_OFB
         scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_STREAM_CIPHER
-        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_KEY_TYPE_AES
         scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_KEY_TYPE_DES
-        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_KEY_TYPE_CAMELLIA
-        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_KEY_TYPE_ARIA
     else
         # Don't pull in cipher via PSA mechanisms
         scripts/config.py unset MBEDTLS_PSA_CRYPTO_CONFIG
         # Disable cipher modes/keys that make PSA depend on CIPHER_C.
         # Keep CHACHA20 and CHACHAPOLY enabled since they do not depend on CIPHER_C.
         scripts/config.py unset-all MBEDTLS_CIPHER_MODE
-        scripts/config.py unset MBEDTLS_AES_C
         scripts/config.py unset MBEDTLS_DES_C
-        scripts/config.py unset MBEDTLS_ARIA_C
-        scripts/config.py unset MBEDTLS_CAMELLIA_C
         # Dependencies on AES_C
         scripts/config.py unset MBEDTLS_CTR_DRBG_C
     fi
     # The following modules directly depends on CIPHER_C
-    scripts/config.py unset MBEDTLS_CCM_C
     scripts/config.py unset MBEDTLS_CMAC_C
-    scripts/config.py unset MBEDTLS_GCM_C
     scripts/config.py unset MBEDTLS_NIST_KW_C
     scripts/config.py unset MBEDTLS_PKCS12_C
     scripts/config.py unset MBEDTLS_PKCS5_C
@@ -3250,14 +3241,6 @@
     #
     # Enable filesystem I/O for the benefit of PK parse/write tests.
     echo "#define MBEDTLS_FS_IO" >> "$CONFIG_H"
-
-    # Config adjustments for features that are not supported
-    # when using only drivers / by p256-m
-    #
-    # Disable all the features that auto-enable ECP_LIGHT (see config_adjust_legacy_crypto.h)
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE
-    # Disable deterministic ECDSA as p256-m only does randomized
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_DETERMINISTIC_ECDSA
 }
 
 # Keep this in sync with component_test_tfm_config() as they are both meant
@@ -3267,8 +3250,8 @@
 
     common_tfm_config
 
-    # Build crypto library specifying we want to use P256M code for EC operations
-    make CFLAGS="$ASAN_CFLAGS -DMBEDTLS_PSA_P256M_DRIVER_ENABLED -I../tests/include/spe" LDFLAGS="$ASAN_CFLAGS"
+    # Build crypto library
+    make CFLAGS="$ASAN_CFLAGS -I../tests/include/spe" LDFLAGS="$ASAN_CFLAGS"
 
     # Make sure any built-in EC alg was not re-enabled by accident (additive config)
     not grep mbedtls_ecdsa_ library/ecdsa.o
@@ -3279,6 +3262,8 @@
     not grep mbedtls_rsa_ library/rsa.o
     not grep mbedtls_dhm_ library/dhm.o
     not grep mbedtls_mpi_ library/bignum.o
+    # Check that p256m was built
+    grep -q p256_ecdsa_ library/libmbedcrypto.a
 
     # Run the tests
     msg "test: TF-M config + p256m driver + accel ECDH(E)/ECDSA"
@@ -3291,9 +3276,16 @@
 component_test_tfm_config() {
     common_tfm_config
 
+    # Disable P256M driver, which is on by default, so that analyze_outcomes
+    # can compare this test with test_tfm_config_p256m_driver_accel_ec
+    echo "#undef MBEDTLS_PSA_P256M_DRIVER_ENABLED" >> "$CONFIG_H"
+
     msg "build: TF-M config"
     make CFLAGS='-Werror -Wall -Wextra -I../tests/include/spe' tests
 
+    # Check that p256m was not built
+    not grep p256_ecdsa_ library/libmbedcrypto.a
+
     msg "test: TF-M config"
     make test
 }
@@ -4113,17 +4105,14 @@
 
 
 support_build_tfm_armcc () {
-    armc6_cc="$ARMC6_BIN_DIR/armclang"
-    (check_tools "$armc6_cc" > /dev/null 2>&1)
+    support_build_armcc
 }
 
 component_build_tfm_armcc() {
     # test the TF-M configuration can build cleanly with various warning flags enabled
-    cp configs/ext/tfm_mbedcrypto_config_profile_medium.h "$CONFIG_H"
-    cp configs/ext/crypto_config_profile_medium.h "$CRYPTO_CONFIG_H"
+    cp configs/config-tfm.h "$CONFIG_H"
 
     msg "build: TF-M config, armclang armv7-m thumb2"
-    make clean
     armc6_build_test "--target=arm-arm-none-eabi -march=armv7-m -mthumb -Os -std=c99 -Werror -Wall -Wextra -Wwrite-strings -Wpointer-arith -Wimplicit-fallthrough -Wshadow -Wvla -Wformat=2 -Wno-format-nonliteral -Wshadow -Wasm-operand-widths -Wunused -I../tests/include/spe"
 }
 
@@ -4133,8 +4122,7 @@
     # TF-M configuration needs a TF-M platform. A tweaked version of
     # the configuration that works on mainstream platforms is in
     # configs/config-tfm.h, tested via test-ref-configs.pl.
-    cp configs/ext/tfm_mbedcrypto_config_profile_medium.h "$CONFIG_H"
-    cp configs/ext/crypto_config_profile_medium.h "$CRYPTO_CONFIG_H"
+    cp configs/config-tfm.h "$CONFIG_H"
 
     msg "build: TF-M config, clang, armv7-m thumb2"
     make lib CC="clang" CFLAGS="--target=arm-linux-gnueabihf -march=armv7-m -mthumb -Os -std=c99 -Werror -Wall -Wextra -Wwrite-strings -Wpointer-arith -Wimplicit-fallthrough -Wshadow -Wvla -Wformat=2 -Wno-format-nonliteral -Wshadow -Wasm-operand-widths -Wunused -I../tests/include/spe"
@@ -4238,6 +4226,7 @@
     # aes.o has many #if defined(...) guards that intersect in complex ways.
     # Test that all the combinations build cleanly.
 
+    MBEDTLS_ROOT_DIR="$PWD"
     msg "build: aes.o for all combinations of relevant config options"
 
     build_test_config_combos library/aes.o validate_aes_config_variations \
@@ -4245,6 +4234,23 @@
         "MBEDTLS_AES_ROM_TABLES" "MBEDTLS_AES_ENCRYPT_ALT" "MBEDTLS_AES_SETKEY_DEC_ALT" \
         "MBEDTLS_AES_FEWER_TABLES" "MBEDTLS_PADLOCK_C" "MBEDTLS_AES_USE_HARDWARE_ONLY" \
         "MBEDTLS_AESNI_C" "MBEDTLS_AESCE_C" "MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH"
+
+    cd "$MBEDTLS_ROOT_DIR"
+    msg "build: aes.o for all combinations of relevant config options + BLOCK_CIPHER_NO_DECRYPT"
+
+    # MBEDTLS_BLOCK_CIPHER_NO_DECRYPT is incompatible with ECB in PSA, CBC/XTS/NIST_KW/DES,
+    # manually set or unset those configurations to check
+    # MBEDTLS_BLOCK_CIPHER_NO_DECRYPT with various combinations in aes.o.
+    scripts/config.py set MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
+    scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
+    scripts/config.py unset MBEDTLS_CIPHER_MODE_XTS
+    scripts/config.py unset MBEDTLS_DES_C
+    scripts/config.py unset MBEDTLS_NIST_KW_C
+    build_test_config_combos library/aes.o validate_aes_config_variations \
+        "MBEDTLS_AES_SETKEY_ENC_ALT" "MBEDTLS_AES_DECRYPT_ALT" \
+        "MBEDTLS_AES_ROM_TABLES" "MBEDTLS_AES_ENCRYPT_ALT" "MBEDTLS_AES_SETKEY_DEC_ALT" \
+        "MBEDTLS_AES_FEWER_TABLES" "MBEDTLS_PADLOCK_C" "MBEDTLS_AES_USE_HARDWARE_ONLY" \
+        "MBEDTLS_AESNI_C" "MBEDTLS_AESCE_C" "MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH"
 }
 
 component_test_no_platform () {
@@ -4645,6 +4651,63 @@
     armc6_build_test "-O1 --target=aarch64-arm-none-eabi -march=armv8-a+crypto"
 }
 
+support_build_aes_armce() {
+    # clang >= 4 is required to build with AES extensions
+    ver="$(clang --version|grep version|sed -E 's#.*version ([0-9]+).*#\1#')"
+    [ "${ver}" -ge 11 ]
+}
+
+component_build_aes_armce () {
+    # Test variations of AES with Armv8 crypto extensions
+    scripts/config.py set MBEDTLS_AESCE_C
+    scripts/config.py set MBEDTLS_AES_USE_HARDWARE_ONLY
+
+    msg "MBEDTLS_AES_USE_HARDWARE_ONLY, clang, aarch64"
+    make -B library/aesce.o CC=clang CFLAGS="--target=aarch64-linux-gnu -march=armv8-a+crypto"
+
+    msg "MBEDTLS_AES_USE_HARDWARE_ONLY, clang, arm"
+    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a72+crypto -marm"
+
+    msg "MBEDTLS_AES_USE_HARDWARE_ONLY, clang, thumb"
+    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a32+crypto -mthumb"
+
+    scripts/config.py unset MBEDTLS_AES_USE_HARDWARE_ONLY
+
+    msg "no MBEDTLS_AES_USE_HARDWARE_ONLY, clang, aarch64"
+    make -B library/aesce.o CC=clang CFLAGS="--target=aarch64-linux-gnu -march=armv8-a+crypto"
+
+    msg "no MBEDTLS_AES_USE_HARDWARE_ONLY, clang, arm"
+    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a72+crypto -marm"
+
+    msg "no MBEDTLS_AES_USE_HARDWARE_ONLY, clang, thumb"
+    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a32+crypto -mthumb"
+
+    # test for presence of AES instructions
+    scripts/config.py set MBEDTLS_AES_USE_HARDWARE_ONLY
+    msg "clang, test A32 crypto instructions built"
+    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a72+crypto -marm -S"
+    grep -E 'aes[0-9a-z]+.[0-9]\s*[qv]' library/aesce.o
+    msg "clang, test T32 crypto instructions built"
+    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a32+crypto -mthumb -S"
+    grep -E 'aes[0-9a-z]+.[0-9]\s*[qv]' library/aesce.o
+    msg "clang, test aarch64 crypto instructions built"
+    make -B library/aesce.o CC=clang CFLAGS="--target=aarch64-linux-gnu -march=armv8-a -S"
+    grep -E 'aes[a-z]+\s*[qv]' library/aesce.o
+
+    # test for absence of AES instructions
+    scripts/config.py unset MBEDTLS_AES_USE_HARDWARE_ONLY
+    scripts/config.py unset MBEDTLS_AESCE_C
+    msg "clang, test A32 crypto instructions not built"
+    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a72+crypto -marm -S"
+    not grep -E 'aes[0-9a-z]+.[0-9]\s*[qv]' library/aesce.o
+    msg "clang, test T32 crypto instructions not built"
+    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a32+crypto -mthumb -S"
+    not grep -E 'aes[0-9a-z]+.[0-9]\s*[qv]' library/aesce.o
+    msg "clang, test aarch64 crypto instructions not built"
+    make -B library/aesce.o CC=clang CFLAGS="--target=aarch64-linux-gnu -march=armv8-a -S"
+    not grep -E 'aes[a-z]+\s*[qv]' library/aesce.o
+}
+
 support_build_sha_armce() {
     if command -v clang > /dev/null ; then
         # clang >= 4 is required to build with SHA extensions
@@ -4812,6 +4875,158 @@
     make test
 }
 
+# helper for common_block_cipher_no_decrypt() which:
+# - enable/disable the list of config options passed from -s/-u respectively.
+# - build
+# - test for tests_suite_xxx
+# - selftest
+#
+# Usage: helper_block_cipher_no_decrypt_build_test
+#        [-s set_opts] [-u unset_opts] [-c cflags] [-l ldflags] [option [...]]
+# Options:  -s set_opts     the list of config options to enable
+#           -u unset_opts   the list of config options to disable
+#           -c cflags       the list of options passed to CFLAGS
+#           -l ldflags      the list of options passed to LDFLAGS
+helper_block_cipher_no_decrypt_build_test () {
+    while [ $# -gt 0 ]; do
+        case "$1" in
+            -s)
+                shift; local set_opts="$1";;
+            -u)
+                shift; local unset_opts="$1";;
+            -c)
+                shift; local cflags="-Werror -Wall -Wextra $1";;
+            -l)
+                shift; local ldflags="$1";;
+        esac
+        shift
+    done
+    set_opts="${set_opts:-}"
+    unset_opts="${unset_opts:-}"
+    cflags="${cflags:-}"
+    ldflags="${ldflags:-}"
+
+    [ -n "$set_opts" ] && echo "Enabling: $set_opts" && scripts/config.py set-all $set_opts
+    [ -n "$unset_opts" ] && echo "Disabling: $unset_opts" && scripts/config.py unset-all $unset_opts
+
+    msg "build: default config + BLOCK_CIPHER_NO_DECRYPT${set_opts:+ + $set_opts}${unset_opts:+ - $unset_opts} with $cflags${ldflags:+, $ldflags}"
+    make clean
+    make CC=gcc CFLAGS="$cflags" LDFLAGS="$ldflags"
+
+    # Make sure we don't have mbedtls_xxx_setkey_dec in AES/ARIA/CAMELLIA
+    not grep mbedtls_aes_setkey_dec library/aes.o
+    not grep mbedtls_aria_setkey_dec library/aria.o
+    not grep mbedtls_camellia_setkey_dec library/camellia.o
+    # Make sure we don't have mbedtls_internal_aes_decrypt in AES
+    not grep mbedtls_internal_aes_decrypt library/aes.o
+    # Make sure we don't have mbedtls_aesni_inverse_key in AESNI
+    not grep mbedtls_aesni_inverse_key library/aesni.o
+
+    msg "test: default config + BLOCK_CIPHER_NO_DECRYPT${set_opts:+ + $set_opts}${unset_opts:+ - $unset_opts} with $cflags${ldflags:+, $ldflags}"
+    make test
+
+    msg "selftest: default config + BLOCK_CIPHER_NO_DECRYPT${set_opts:+ + $set_opts}${unset_opts:+ - $unset_opts} with $cflags${ldflags:+, $ldflags}"
+    programs/test/selftest
+}
+
+# This is a common configuration function used in:
+# - component_test_block_cipher_no_decrypt_aesni_legacy()
+# - component_test_block_cipher_no_decrypt_aesni_use_psa()
+# in order to test BLOCK_CIPHER_NO_DECRYPT with AESNI intrinsics,
+# AESNI assembly and AES C implementation on x86_64 and with AESNI intrinsics
+# on x86.
+common_block_cipher_no_decrypt () {
+    # test AESNI intrinsics
+    helper_block_cipher_no_decrypt_build_test \
+        -s "MBEDTLS_AESNI_C" \
+        -c "-mpclmul -msse2 -maes"
+
+    # test AESNI assembly
+    helper_block_cipher_no_decrypt_build_test \
+        -s "MBEDTLS_AESNI_C" \
+        -c "-mno-pclmul -mno-sse2 -mno-aes"
+
+    # test AES C implementation
+    helper_block_cipher_no_decrypt_build_test \
+        -u "MBEDTLS_AESNI_C"
+
+    # test AESNI intrinsics for i386 target
+    helper_block_cipher_no_decrypt_build_test \
+        -s "MBEDTLS_AESNI_C" \
+        -c "-m32 -mpclmul -msse2 -maes" \
+        -l "-m32"
+}
+
+# This is a configuration function used in component_test_block_cipher_no_decrypt_xxx:
+# usage: 0: no PSA crypto configuration
+#        1: use PSA crypto configuration
+config_block_cipher_no_decrypt () {
+    use_psa=$1
+
+    scripts/config.py set MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
+    scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
+    scripts/config.py unset MBEDTLS_CIPHER_MODE_XTS
+    scripts/config.py unset MBEDTLS_DES_C
+    scripts/config.py unset MBEDTLS_NIST_KW_C
+
+    if [ "$use_psa" -eq 1 ]; then
+        # Enable support for cryptographic mechanisms through the PSA API.
+        # Note: XTS, KW are not yet supported via the PSA API in Mbed TLS.
+        scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
+        scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_NO_PADDING
+        scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_PKCS7
+        scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_ECB_NO_PADDING
+        scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_KEY_TYPE_DES
+    fi
+}
+
+component_test_block_cipher_no_decrypt_aesni () {
+    config_block_cipher_no_decrypt 0
+    common_block_cipher_no_decrypt
+}
+
+component_test_block_cipher_no_decrypt_aesni_use_psa () {
+    config_block_cipher_no_decrypt 1
+    common_block_cipher_no_decrypt
+}
+
+support_test_block_cipher_no_decrypt_aesce_armcc () {
+    support_build_armcc
+}
+
+component_test_block_cipher_no_decrypt_aesce_armcc () {
+    scripts/config.py baremetal
+
+    # armc[56] don't support SHA-512 intrinsics
+    scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
+
+    # Stop armclang warning about feature detection for A64_CRYPTO.
+    # With this enabled, the library does build correctly under armclang,
+    # but in baremetal builds (as tested here), feature detection is
+    # unavailable, and the user is notified via a #warning. So enabling
+    # this feature would prevent us from building with -Werror on
+    # armclang. Tracked in #7198.
+    scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
+    scripts/config.py set MBEDTLS_HAVE_ASM
+
+    config_block_cipher_no_decrypt 1
+
+    # test AESCE baremetal build
+    scripts/config.py set MBEDTLS_AESCE_C
+    msg "build: default config + BLOCK_CIPHER_NO_DECRYPT with AESCE"
+    armc6_build_test "-O1 --target=aarch64-arm-none-eabi -march=armv8-a+crypto -Werror -Wall -Wextra"
+
+    # Make sure we don't have mbedtls_xxx_setkey_dec in AES/ARIA/CAMELLIA
+    not grep mbedtls_aes_setkey_dec library/aes.o
+    not grep mbedtls_aria_setkey_dec library/aria.o
+    not grep mbedtls_camellia_setkey_dec library/camellia.o
+    # Make sure we don't have mbedtls_internal_aes_decrypt in AES
+    not grep mbedtls_internal_aes_decrypt library/aes.o
+    # Make sure we don't have mbedtls_aesce_inverse_key and aesce_decrypt_block in AESCE
+    not grep mbedtls_aesce_inverse_key library/aesce.o
+    not grep aesce_decrypt_block library/aesce.o
+}
+
 component_test_ctr_drbg_aes_256_sha_256 () {
     msg "build: full + MBEDTLS_ENTROPY_FORCE_SHA256 (ASan build)"
     scripts/config.py full
@@ -5266,6 +5481,9 @@
     # armc[56] don't support SHA-512 intrinsics
     scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
 
+    # older versions of armcc/armclang don't support AESCE_C on 32-bit Arm
+    scripts/config.py unset MBEDTLS_AESCE_C
+
     # Stop armclang warning about feature detection for A64_CRYPTO.
     # With this enabled, the library does build correctly under armclang,
     # but in baremetal builds (as tested here), feature detection is
@@ -5281,8 +5499,6 @@
     msg "size: ARM Compiler 5"
     "$ARMC5_FROMELF" -z library/*.o
 
-    make clean
-
     # Compile mostly with -O1 since some Arm inline assembly is disabled for -O0.
 
     # ARM Compiler 6 - Target ARMv7-A
@@ -5300,14 +5516,18 @@
     # ARM Compiler 6 - Target ARMv8-M
     armc6_build_test "-O1 --target=arm-arm-none-eabi -march=armv8-m.main"
 
-    # ARM Compiler 6 - Target ARMv8.2-A - AArch64
-    armc6_build_test "-O1 --target=aarch64-arm-none-eabi -march=armv8.2-a+crypto"
-
     # ARM Compiler 6 - Target Cortex-M0 - no optimisation
     armc6_build_test "-O0 --target=arm-arm-none-eabi -mcpu=cortex-m0"
 
     # ARM Compiler 6 - Target Cortex-M0
     armc6_build_test "-Os --target=arm-arm-none-eabi -mcpu=cortex-m0"
+
+    # ARM Compiler 6 - Target ARMv8.2-A - AArch64
+    #
+    # Re-enable MBEDTLS_AESCE_C as this should be supported by the version of armclang
+    # that we have in our CI
+    scripts/config.py set MBEDTLS_AESCE_C
+    armc6_build_test "-O1 --target=aarch64-arm-none-eabi -march=armv8.2-a+crypto"
 }
 
 support_build_armcc () {
diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py
index a070b01..ca349d3 100755
--- a/tests/scripts/analyze_outcomes.py
+++ b/tests/scripts/analyze_outcomes.py
@@ -12,9 +12,36 @@
 import re
 import subprocess
 import os
+import typing
 
 import check_test_cases
 
+
+# `ComponentOutcomes` is a named tuple which is defined as:
+# ComponentOutcomes(
+#     successes = {
+#         "<suite_case>",
+#         ...
+#     },
+#     failures = {
+#         "<suite_case>",
+#         ...
+#     }
+# )
+# suite_case = "<suite>;<case>"
+ComponentOutcomes = typing.NamedTuple('ComponentOutcomes',
+                                      [('successes', typing.Set[str]),
+                                       ('failures', typing.Set[str])])
+
+# `Outcomes` is a representation of the outcomes file,
+# which defined as:
+# Outcomes = {
+#     "<component>": ComponentOutcomes,
+#     ...
+# }
+Outcomes = typing.Dict[str, ComponentOutcomes]
+
+
 class Results:
     """Process analysis results."""
 
@@ -40,35 +67,12 @@
     def _print_line(fmt, *args, **kwargs):
         sys.stderr.write((fmt + '\n').format(*args, **kwargs))
 
-class TestCaseOutcomes:
-    """The outcomes of one test case across many configurations."""
-    # pylint: disable=too-few-public-methods
-
-    def __init__(self):
-        # Collect a list of witnesses of the test case succeeding or failing.
-        # Currently we don't do anything with witnesses except count them.
-        # The format of a witness is determined by the read_outcome_file
-        # function; it's the platform and configuration joined by ';'.
-        self.successes = []
-        self.failures = []
-
-    def hits(self):
-        """Return the number of times a test case has been run.
-
-        This includes passes and failures, but not skips.
-        """
-        return len(self.successes) + len(self.failures)
-
-def execute_reference_driver_tests(results: Results, ref_component, driver_component, \
-                                   outcome_file):
+def execute_reference_driver_tests(results: Results, ref_component: str, driver_component: str, \
+                                   outcome_file: str) -> None:
     """Run the tests specified in ref_component and driver_component. Results
     are stored in the output_file and they will be used for the following
     coverage analysis"""
-    # If the outcome file already exists, we assume that the user wants to
-    # perform the comparison analysis again without repeating the tests.
-    if os.path.exists(outcome_file):
-        results.info("Outcome file ({}) already exists. Tests will be skipped.", outcome_file)
-        return
+    results.new_section("Test {} and {}", ref_component, driver_component)
 
     shell_command = "tests/scripts/all.sh --outcome-file " + outcome_file + \
                     " " + ref_component + " " + driver_component
@@ -78,24 +82,28 @@
     if ret_val != 0:
         results.error("failed to run reference/driver components")
 
-def analyze_coverage(results, outcomes, allow_list, full_coverage):
+def analyze_coverage(results: Results, outcomes: Outcomes,
+                     allow_list: typing.List[str], full_coverage: bool) -> None:
     """Check that all available test cases are executed at least once."""
     available = check_test_cases.collect_available_test_cases()
-    for key in available:
-        hits = outcomes[key].hits() if key in outcomes else 0
-        if hits == 0 and key not in allow_list:
+    for suite_case in available:
+        hit = any(suite_case in comp_outcomes.successes or
+                  suite_case in comp_outcomes.failures
+                  for comp_outcomes in outcomes.values())
+
+        if not hit and suite_case not in allow_list:
             if full_coverage:
-                results.error('Test case not executed: {}', key)
+                results.error('Test case not executed: {}', suite_case)
             else:
-                results.warning('Test case not executed: {}', key)
-        elif hits != 0 and key in allow_list:
+                results.warning('Test case not executed: {}', suite_case)
+        elif hit and suite_case in allow_list:
             # Test Case should be removed from the allow list.
             if full_coverage:
-                results.error('Allow listed test case was executed: {}', key)
+                results.error('Allow listed test case was executed: {}', suite_case)
             else:
-                results.warning('Allow listed test case was executed: {}', key)
+                results.warning('Allow listed test case was executed: {}', suite_case)
 
-def name_matches_pattern(name, str_or_re):
+def name_matches_pattern(name: str, str_or_re) -> bool:
     """Check if name matches a pattern, that may be a string or regex.
     - If the pattern is a string, name must be equal to match.
     - If the pattern is a regex, name must fully match.
@@ -103,24 +111,34 @@
     # The CI's python is too old for re.Pattern
     #if isinstance(str_or_re, re.Pattern):
     if not isinstance(str_or_re, str):
-        return str_or_re.fullmatch(name)
+        return str_or_re.fullmatch(name) is not None
     else:
         return str_or_re == name
 
-def analyze_driver_vs_reference(results: Results, outcomes,
-                                component_ref, component_driver,
-                                ignored_suites, ignored_tests=None):
-    """Check that all tests executed in the reference component are also
-    executed in the corresponding driver component.
+def analyze_driver_vs_reference(results: Results, outcomes: Outcomes,
+                                component_ref: str, component_driver: str,
+                                ignored_suites: typing.List[str], ignored_tests=None) -> None:
+    """Check that all tests passing in the reference component are also
+    passing in the corresponding driver component.
     Skip:
     - full test suites provided in ignored_suites list
     - only some specific test inside a test suite, for which the corresponding
       output string is provided
     """
-    seen_reference_passing = False
-    for key in outcomes:
-        # key is like "test_suite_foo.bar;Description of test case"
-        (full_test_suite, test_string) = key.split(';')
+    ref_outcomes = outcomes.get("component_" + component_ref)
+    driver_outcomes = outcomes.get("component_" + component_driver)
+
+    if ref_outcomes is None or driver_outcomes is None:
+        results.error("required components are missing: bad outcome file?")
+        return
+
+    if not ref_outcomes.successes:
+        results.error("no passing test in reference component: bad outcome file?")
+        return
+
+    for suite_case in ref_outcomes.successes:
+        # suite_case is like "test_suite_foo.bar;Description of test case"
+        (full_test_suite, test_string) = suite_case.split(';')
         test_suite = full_test_suite.split('.')[0] # retrieve main part of test suite name
 
         # Immediately skip fully-ignored test suites
@@ -136,67 +154,48 @@
                 if name_matches_pattern(test_string, str_or_re):
                     ignored = True
 
-        # Search for tests that run in reference component and not in driver component
-        driver_test_passed = False
-        reference_test_passed = False
-        for entry in outcomes[key].successes:
-            if component_driver in entry:
-                driver_test_passed = True
-            if component_ref in entry:
-                reference_test_passed = True
-                seen_reference_passing = True
-        if reference_test_passed and not driver_test_passed and not ignored:
-            results.error("PASS -> SKIP/FAIL: {}", key)
-        if ignored and driver_test_passed:
-            results.error("uselessly ignored: {}", key)
+        if not ignored and not suite_case in driver_outcomes.successes:
+            results.error("PASS -> SKIP/FAIL: {}", suite_case)
+        if ignored and suite_case in driver_outcomes.successes:
+            results.error("uselessly ignored: {}", suite_case)
 
-    if not seen_reference_passing:
-        results.error("no passing test in reference component: bad outcome file?")
-
-def analyze_outcomes(results: Results, outcomes, args):
+def analyze_outcomes(results: Results, outcomes: Outcomes, args) -> None:
     """Run all analyses on the given outcome collection."""
     analyze_coverage(results, outcomes, args['allow_list'],
                      args['full_coverage'])
 
-def read_outcome_file(outcome_file):
+def read_outcome_file(outcome_file: str) -> Outcomes:
     """Parse an outcome file and return an outcome collection.
-
-An outcome collection is a dictionary mapping keys to TestCaseOutcomes objects.
-The keys are the test suite name and the test case description, separated
-by a semicolon.
-"""
+    """
     outcomes = {}
     with open(outcome_file, 'r', encoding='utf-8') as input_file:
         for line in input_file:
-            (platform, config, suite, case, result, _cause) = line.split(';')
-            key = ';'.join([suite, case])
-            setup = ';'.join([platform, config])
-            if key not in outcomes:
-                outcomes[key] = TestCaseOutcomes()
+            (_platform, component, suite, case, result, _cause) = line.split(';')
+            # Note that `component` is not unique. If a test case passes on Linux
+            # and fails on FreeBSD, it'll end up in both the successes set and
+            # the failures set.
+            suite_case = ';'.join([suite, case])
+            if component not in outcomes:
+                outcomes[component] = ComponentOutcomes(set(), set())
             if result == 'PASS':
-                outcomes[key].successes.append(setup)
+                outcomes[component].successes.add(suite_case)
             elif result == 'FAIL':
-                outcomes[key].failures.append(setup)
+                outcomes[component].failures.add(suite_case)
+
     return outcomes
 
-def do_analyze_coverage(results: Results, outcome_file, args):
+def do_analyze_coverage(results: Results, outcomes: Outcomes, args) -> None:
     """Perform coverage analysis."""
     results.new_section("Analyze coverage")
-    outcomes = read_outcome_file(outcome_file)
     analyze_outcomes(results, outcomes, args)
 
-def do_analyze_driver_vs_reference(results: Results, outcome_file, args):
+def do_analyze_driver_vs_reference(results: Results, outcomes: Outcomes, args) -> None:
     """Perform driver vs reference analyze."""
     results.new_section("Analyze driver {} vs reference {}",
                         args['component_driver'], args['component_ref'])
 
-    execute_reference_driver_tests(results, args['component_ref'], \
-                                   args['component_driver'], outcome_file)
-
     ignored_suites = ['test_suite_' + x for x in args['ignored_suites']]
 
-    outcomes = read_outcome_file(outcome_file)
-
     analyze_driver_vs_reference(results, outcomes,
                                 args['component_ref'], args['component_driver'],
                                 ignored_suites, args['ignored_tests'])
@@ -232,6 +231,12 @@
                 'psa_crypto_low_hash.generated', # testing the builtins
             ],
             'ignored_tests': {
+                'test_suite_platform': [
+                    # Incompatible with sanitizers (e.g. ASan). If the driver
+                    # component uses a sanitizer but the reference component
+                    # doesn't, we have a PASS vs SKIP mismatch.
+                    'Check mbedtls_calloc overallocation',
+                ],
             }
         }
     },
@@ -255,6 +260,12 @@
                 'test_suite_pem': [
                     re.compile(r'PEM read .*(AES|DES|\bencrypt).*'),
                 ],
+                'test_suite_platform': [
+                    # Incompatible with sanitizers (e.g. ASan). If the driver
+                    # component uses a sanitizer but the reference component
+                    # doesn't, we have a PASS vs SKIP mismatch.
+                    'Check mbedtls_calloc overallocation',
+                ],
                 # Following tests depend on AES_C/DES_C but are not about
                 # them really, just need to know some error code is there.
                 'test_suite_error': [
@@ -282,7 +293,7 @@
                 'test_suite_pkparse': [
                     'Key ASN1 (Encrypted key PKCS12, trailing garbage data)',
                     'Key ASN1 (Encrypted key PKCS5, trailing garbage data)',
-                    re.compile(r'Parse RSA Key .*\(PKCS#8 encrypted .*\)'),
+                    re.compile(r'Parse (RSA|EC) Key .*\(.* ([Ee]ncrypted|password).*\)'),
                 ],
             }
         }
@@ -297,6 +308,12 @@
                 'ecdsa', 'ecdh', 'ecjpake',
             ],
             'ignored_tests': {
+                'test_suite_platform': [
+                    # Incompatible with sanitizers (e.g. ASan). If the driver
+                    # component uses a sanitizer but the reference component
+                    # doesn't, we have a PASS vs SKIP mismatch.
+                    'Check mbedtls_calloc overallocation',
+                ],
                 # This test wants a legacy function that takes f_rng, p_rng
                 # arguments, and uses legacy ECDSA for that. The test is
                 # really about the wrapper around the PSA RNG, not ECDSA.
@@ -330,6 +347,12 @@
                 'ecp', 'ecdsa', 'ecdh', 'ecjpake',
             ],
             'ignored_tests': {
+                'test_suite_platform': [
+                    # Incompatible with sanitizers (e.g. ASan). If the driver
+                    # component uses a sanitizer but the reference component
+                    # doesn't, we have a PASS vs SKIP mismatch.
+                    'Check mbedtls_calloc overallocation',
+                ],
                 # See ecp_light_only
                 'test_suite_random': [
                     'PSA classic wrapper: ECDSA signature (SECP256R1)',
@@ -363,6 +386,12 @@
                 'bignum.generated', 'bignum.misc',
             ],
             'ignored_tests': {
+                'test_suite_platform': [
+                    # Incompatible with sanitizers (e.g. ASan). If the driver
+                    # component uses a sanitizer but the reference component
+                    # doesn't, we have a PASS vs SKIP mismatch.
+                    'Check mbedtls_calloc overallocation',
+                ],
                 # See ecp_light_only
                 'test_suite_random': [
                     'PSA classic wrapper: ECDSA signature (SECP256R1)',
@@ -400,6 +429,12 @@
                 'bignum.generated', 'bignum.misc',
             ],
             'ignored_tests': {
+                'test_suite_platform': [
+                    # Incompatible with sanitizers (e.g. ASan). If the driver
+                    # component uses a sanitizer but the reference component
+                    # doesn't, we have a PASS vs SKIP mismatch.
+                    'Check mbedtls_calloc overallocation',
+                ],
                 # See ecp_light_only
                 'test_suite_random': [
                     'PSA classic wrapper: ECDSA signature (SECP256R1)',
@@ -431,7 +466,14 @@
             'component_ref': 'test_psa_crypto_config_reference_ffdh',
             'component_driver': 'test_psa_crypto_config_accel_ffdh',
             'ignored_suites': ['dhm'],
-            'ignored_tests': {}
+            'ignored_tests': {
+                'test_suite_platform': [
+                    # Incompatible with sanitizers (e.g. ASan). If the driver
+                    # component uses a sanitizer but the reference component
+                    # doesn't, we have a PASS vs SKIP mismatch.
+                    'Check mbedtls_calloc overallocation',
+                ],
+            }
         }
     },
     'analyze_driver_vs_reference_tfm_config': {
@@ -447,6 +489,12 @@
                 'bignum.generated', 'bignum.misc',
             ],
             'ignored_tests': {
+                'test_suite_platform': [
+                    # Incompatible with sanitizers (e.g. ASan). If the driver
+                    # component uses a sanitizer but the reference component
+                    # doesn't, we have a PASS vs SKIP mismatch.
+                    'Check mbedtls_calloc overallocation',
+                ],
                 # See ecp_light_only
                 'test_suite_random': [
                     'PSA classic wrapper: ECDSA signature (SECP256R1)',
@@ -493,10 +541,31 @@
 
         KNOWN_TASKS['analyze_coverage']['args']['full_coverage'] = options.full_coverage
 
+        # If the outcome file exists, parse it once and share the result
+        # among tasks to improve performance.
+        # Otherwise, it will be generated by execute_reference_driver_tests.
+        if not os.path.exists(options.outcomes):
+            if len(tasks_list) > 1:
+                sys.stderr.write("mutiple tasks found, please provide a valid outcomes file.\n")
+                sys.exit(2)
+
+            task_name = tasks_list[0]
+            task = KNOWN_TASKS[task_name]
+            if task['test_function'] != do_analyze_driver_vs_reference: # pylint: disable=comparison-with-callable
+                sys.stderr.write("please provide valid outcomes file for {}.\n".format(task_name))
+                sys.exit(2)
+
+            execute_reference_driver_tests(main_results,
+                                           task['args']['component_ref'],
+                                           task['args']['component_driver'],
+                                           options.outcomes)
+
+        outcomes = read_outcome_file(options.outcomes)
+
         for task in tasks_list:
             test_function = KNOWN_TASKS[task]['test_function']
             test_args = KNOWN_TASKS[task]['args']
-            test_function(main_results, options.outcomes, test_args)
+            test_function(main_results, outcomes, test_args)
 
         main_results.info("Overall results: {} warnings and {} errors",
                           main_results.warning_count, main_results.error_count)
diff --git a/tests/scripts/generate_psa_tests.py b/tests/scripts/generate_psa_tests.py
index 801f8da..fd278f8 100755
--- a/tests/scripts/generate_psa_tests.py
+++ b/tests/scripts/generate_psa_tests.py
@@ -496,7 +496,7 @@
             key.alg.string, key.alg2.string,
         )
         dependencies = psa_information.finish_family_dependencies(dependencies, key.bits)
-        dependencies += psa_information.generate_key_dependencies(key.description)
+        dependencies += psa_information.generate_deps_from_description(key.description)
         dependencies = psa_information.fix_key_pair_dependencies(dependencies, 'BASIC')
         tc.set_dependencies(dependencies)
         tc.set_function('key_storage_' + verb)
diff --git a/tests/src/threading_helpers.c b/tests/src/threading_helpers.c
index 6f405b0..5fbf65b 100644
--- a/tests/src/threading_helpers.c
+++ b/tests/src/threading_helpers.c
@@ -58,15 +58,15 @@
  * indicate the exact location of the problematic call. To locate the error,
  * use a debugger and set a breakpoint on mbedtls_test_mutex_usage_error().
  */
-enum value_of_mutex_is_valid_field {
-    /* Potential values for the is_valid field of mbedtls_threading_mutex_t.
+enum value_of_mutex_state_field {
+    /* Potential values for the state field of mbedtls_threading_mutex_t.
      * Note that MUTEX_FREED must be 0 and MUTEX_IDLE must be 1 for
      * compatibility with threading_mutex_init_pthread() and
      * threading_mutex_free_pthread(). MUTEX_LOCKED could be any nonzero
      * value. */
-    MUTEX_FREED = 0, //!< Set by threading_mutex_free_pthread
-    MUTEX_IDLE = 1, //!< Set by threading_mutex_init_pthread and by our unlock
-    MUTEX_LOCKED = 2, //!< Set by our lock
+    MUTEX_FREED = 0, //! < Set by mbedtls_test_wrap_mutex_free
+    MUTEX_IDLE = 1, //! < Set by mbedtls_test_wrap_mutex_init and by mbedtls_test_wrap_mutex_unlock
+    MUTEX_LOCKED = 2, //! < Set by mbedtls_test_wrap_mutex_lock
 };
 
 typedef struct {
@@ -77,10 +77,30 @@
 } mutex_functions_t;
 static mutex_functions_t mutex_functions;
 
-/** The total number of calls to mbedtls_mutex_init(), minus the total number
- * of calls to mbedtls_mutex_free().
+/**
+ *  The mutex used to guard live_mutexes below and access to the status variable
+ *  in every mbedtls_threading_mutex_t.
+ *  Note that we are not reporting any errors when locking and unlocking this
+ *  mutex. This is for a couple of reasons:
  *
- * Reset to 0 after each test case.
+ *  1. We have no real way of reporting any errors with this mutex - we cannot
+ *  report it back to the caller, as the failure was not that of the mutex
+ *  passed in. We could fail the test, but again this would indicate a problem
+ *  with the test code that did not exist.
+ *
+ *  2. Any failure to lock is unlikely to be intermittent, and will thus not
+ *  give false test results - the overall result would be to turn off the
+ *  testing. This is not a situation that is likely to happen with normal
+ *  testing and we still have TSan to fall back on should this happen.
+ */
+mbedtls_threading_mutex_t mbedtls_test_mutex_mutex;
+
+/**
+ *  The total number of calls to mbedtls_mutex_init(), minus the total number
+ *  of calls to mbedtls_mutex_free().
+ *
+ *  Do not read or write without holding mbedtls_test_mutex_mutex (above). Reset
+ *  to 0 after each test case.
  */
 static int live_mutexes;
 
@@ -88,6 +108,7 @@
                                            const char *msg)
 {
     (void) mutex;
+
     if (mbedtls_test_info.mutex_usage_error == NULL) {
         mbedtls_test_info.mutex_usage_error = msg;
     }
@@ -101,76 +122,92 @@
 static void mbedtls_test_wrap_mutex_init(mbedtls_threading_mutex_t *mutex)
 {
     mutex_functions.init(mutex);
-    if (mutex->is_valid) {
+
+    if (mutex_functions.lock(&mbedtls_test_mutex_mutex) == 0) {
+        mutex->state = MUTEX_IDLE;
         ++live_mutexes;
+
+        mutex_functions.unlock(&mbedtls_test_mutex_mutex);
     }
 }
 
 static void mbedtls_test_wrap_mutex_free(mbedtls_threading_mutex_t *mutex)
 {
-    switch (mutex->is_valid) {
-        case MUTEX_FREED:
-            mbedtls_test_mutex_usage_error(mutex, "free without init or double free");
-            break;
-        case MUTEX_IDLE:
-            /* Do nothing. The underlying free function will reset is_valid
-             * to 0. */
-            break;
-        case MUTEX_LOCKED:
-            mbedtls_test_mutex_usage_error(mutex, "free without unlock");
-            break;
-        default:
-            mbedtls_test_mutex_usage_error(mutex, "corrupted state");
-            break;
-    }
-    if (mutex->is_valid) {
-        --live_mutexes;
+    if (mutex_functions.lock(&mbedtls_test_mutex_mutex) == 0) {
+
+        switch (mutex->state) {
+            case MUTEX_FREED:
+                mbedtls_test_mutex_usage_error(mutex, "free without init or double free");
+                break;
+            case MUTEX_IDLE:
+                mutex->state = MUTEX_FREED;
+                --live_mutexes;
+                break;
+            case MUTEX_LOCKED:
+                mbedtls_test_mutex_usage_error(mutex, "free without unlock");
+                break;
+            default:
+                mbedtls_test_mutex_usage_error(mutex, "corrupted state");
+                break;
+        }
+
+        mutex_functions.unlock(&mbedtls_test_mutex_mutex);
     }
     mutex_functions.free(mutex);
 }
 
 static int mbedtls_test_wrap_mutex_lock(mbedtls_threading_mutex_t *mutex)
 {
+    /* Lock the passed in mutex first, so that the only way to change the state
+     * is to hold the passed in and internal mutex - otherwise we create a race
+     * condition. */
     int ret = mutex_functions.lock(mutex);
-    switch (mutex->is_valid) {
-        case MUTEX_FREED:
-            mbedtls_test_mutex_usage_error(mutex, "lock without init");
-            break;
-        case MUTEX_IDLE:
-            if (ret == 0) {
-                mutex->is_valid = 2;
-            }
-            break;
-        case MUTEX_LOCKED:
-            mbedtls_test_mutex_usage_error(mutex, "double lock");
-            break;
-        default:
-            mbedtls_test_mutex_usage_error(mutex, "corrupted state");
-            break;
+    if (mutex_functions.lock(&mbedtls_test_mutex_mutex) == 0) {
+        switch (mutex->state) {
+            case MUTEX_FREED:
+                mbedtls_test_mutex_usage_error(mutex, "lock without init");
+                break;
+            case MUTEX_IDLE:
+                if (ret == 0) {
+                    mutex->state = MUTEX_LOCKED;
+                }
+                break;
+            case MUTEX_LOCKED:
+                mbedtls_test_mutex_usage_error(mutex, "double lock");
+                break;
+            default:
+                mbedtls_test_mutex_usage_error(mutex, "corrupted state");
+                break;
+        }
+
+        mutex_functions.unlock(&mbedtls_test_mutex_mutex);
     }
     return ret;
 }
 
 static int mbedtls_test_wrap_mutex_unlock(mbedtls_threading_mutex_t *mutex)
 {
-    int ret = mutex_functions.unlock(mutex);
-    switch (mutex->is_valid) {
-        case MUTEX_FREED:
-            mbedtls_test_mutex_usage_error(mutex, "unlock without init");
-            break;
-        case MUTEX_IDLE:
-            mbedtls_test_mutex_usage_error(mutex, "unlock without lock");
-            break;
-        case MUTEX_LOCKED:
-            if (ret == 0) {
-                mutex->is_valid = MUTEX_IDLE;
-            }
-            break;
-        default:
-            mbedtls_test_mutex_usage_error(mutex, "corrupted state");
-            break;
+    /* Lock the internal mutex first and change state, so that the only way to
+     * change the state is to hold the passed in and internal mutex - otherwise
+     * we create a race condition. */
+    if (mutex_functions.lock(&mbedtls_test_mutex_mutex) == 0) {
+        switch (mutex->state) {
+            case MUTEX_FREED:
+                mbedtls_test_mutex_usage_error(mutex, "unlock without init");
+                break;
+            case MUTEX_IDLE:
+                mbedtls_test_mutex_usage_error(mutex, "unlock without lock");
+                break;
+            case MUTEX_LOCKED:
+                mutex->state = MUTEX_IDLE;
+                break;
+            default:
+                mbedtls_test_mutex_usage_error(mutex, "corrupted state");
+                break;
+        }
+        mutex_functions.unlock(&mbedtls_test_mutex_mutex);
     }
-    return ret;
+    return mutex_functions.unlock(mutex);
 }
 
 void mbedtls_test_mutex_usage_init(void)
@@ -183,6 +220,8 @@
     mbedtls_mutex_free = &mbedtls_test_wrap_mutex_free;
     mbedtls_mutex_lock = &mbedtls_test_wrap_mutex_lock;
     mbedtls_mutex_unlock = &mbedtls_test_wrap_mutex_unlock;
+
+    mutex_functions.init(&mbedtls_test_mutex_mutex);
 }
 
 void mbedtls_test_mutex_usage_check(void)
@@ -207,4 +246,14 @@
     mbedtls_test_info.mutex_usage_error = NULL;
 }
 
+void mbedtls_test_mutex_usage_end(void)
+{
+    mbedtls_mutex_init = mutex_functions.init;
+    mbedtls_mutex_free = mutex_functions.free;
+    mbedtls_mutex_lock = mutex_functions.lock;
+    mbedtls_mutex_unlock = mutex_functions.unlock;
+
+    mutex_functions.free(&mbedtls_test_mutex_mutex);
+}
+
 #endif /* MBEDTLS_TEST_MUTEX_USAGE */
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 42f9f5e..4762285 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -358,9 +358,18 @@
 
 # Space-separated list of ciphersuites supported by this build of
 # Mbed TLS.
-P_CIPHERSUITES=" $($P_CLI --help 2>/dev/null |
-                   grep 'TLS-\|TLS1-3' |
-                   tr -s ' \n' ' ')"
+P_CIPHERSUITES=""
+if [ "$LIST_TESTS" -eq 0 ]; then
+    P_CIPHERSUITES=" $($P_CLI help_ciphersuites 2>/dev/null |
+                       grep 'TLS-\|TLS1-3' |
+                       tr -s ' \n' ' ')"
+
+    if [ -z "${P_CIPHERSUITES# }" ]; then
+        echo >&2 "$0: fatal error: no cipher suites found!"
+        exit 125
+    fi
+fi
+
 requires_ciphersuite_enabled() {
     case $P_CIPHERSUITES in
         *" $1 "*) :;;
@@ -2332,7 +2341,6 @@
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_X509_CRT_PARSE_C
 requires_hash_alg SHA_256
-requires_config_enabled MBEDTLS_CCM_C
 run_test    "Opaque key for server authentication: invalid alg: ECDHE-ECDSA with ecdh" \
             "$P_SRV key_opaque=1 crt_file=data_files/server5.crt \
              key_file=data_files/server5.key key_opaque_algs=ecdh,none \
@@ -2386,7 +2394,6 @@
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_X509_CRT_PARSE_C
 requires_hash_alg SHA_384
-requires_config_enabled MBEDTLS_CCM_C
 requires_config_disabled MBEDTLS_X509_REMOVE_INFO
 run_test    "Opaque keys for server authentication: EC + RSA, force ECDHE-ECDSA" \
             "$P_SRV key_opaque=1 crt_file=data_files/server5.crt \
@@ -2566,7 +2573,6 @@
 requires_config_enabled MBEDTLS_X509_CRT_PARSE_C
 requires_config_enabled MBEDTLS_RSA_C
 requires_hash_alg SHA_384
-requires_config_enabled MBEDTLS_GCM_C
 requires_config_disabled MBEDTLS_X509_REMOVE_INFO
 run_test    "Opaque keys for server authentication: EC + RSA, force DHE-RSA" \
             "$P_SRV auth_mode=required key_opaque=1 crt_file=data_files/server5.crt \
@@ -9115,8 +9121,6 @@
 
 # Tests for ECC extensions (rfc 4492)
 
-requires_config_enabled MBEDTLS_AES_C
-requires_config_enabled MBEDTLS_CIPHER_MODE_CBC
 requires_hash_alg SHA_256
 requires_config_enabled MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
 run_test    "Force a non ECC ciphersuite in the client side" \
@@ -9128,8 +9132,6 @@
             -S "found supported elliptic curves extension" \
             -S "found supported point formats extension"
 
-requires_config_enabled MBEDTLS_AES_C
-requires_config_enabled MBEDTLS_CIPHER_MODE_CBC
 requires_hash_alg SHA_256
 requires_config_enabled MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
 run_test    "Force a non ECC ciphersuite in the server side" \
@@ -9139,8 +9141,6 @@
             -C "found supported_point_formats extension" \
             -S "server hello, supported_point_formats extension"
 
-requires_config_enabled MBEDTLS_AES_C
-requires_config_enabled MBEDTLS_CIPHER_MODE_CBC
 requires_hash_alg SHA_256
 run_test    "Force an ECC ciphersuite in the client side" \
             "$P_SRV debug_level=3" \
@@ -9151,8 +9151,6 @@
             -s "found supported elliptic curves extension" \
             -s "found supported point formats extension"
 
-requires_config_enabled MBEDTLS_AES_C
-requires_config_enabled MBEDTLS_CIPHER_MODE_CBC
 requires_hash_alg SHA_256
 run_test    "Force an ECC ciphersuite in the server side" \
             "$P_SRV debug_level=3 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256" \
@@ -9677,8 +9675,6 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
 requires_hash_alg SHA_256
-requires_config_enabled MBEDTLS_AES_C
-requires_config_enabled MBEDTLS_GCM_C
 requires_max_content_len 2048
 run_test    "DTLS fragmenting: both (MTU=512)" \
             -p "$P_PXY mtu=512" \
@@ -9707,8 +9703,6 @@
 not_with_valgrind
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
-requires_config_enabled MBEDTLS_AES_C
-requires_config_enabled MBEDTLS_GCM_C
 requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU: auto-reduction (not valgrind)" \
             -p "$P_PXY mtu=508" \
@@ -9730,8 +9724,6 @@
 only_with_valgrind
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
-requires_config_enabled MBEDTLS_AES_C
-requires_config_enabled MBEDTLS_GCM_C
 requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU: auto-reduction (with valgrind)" \
             -p "$P_PXY mtu=508" \
@@ -9782,8 +9774,6 @@
 not_with_valgrind # spurious autoreduction due to timeout
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
-requires_config_enabled MBEDTLS_AES_C
-requires_config_enabled MBEDTLS_GCM_C
 requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU, simple handshake (MTU=512)" \
             -p "$P_PXY mtu=512" \
@@ -9831,8 +9821,6 @@
 not_with_valgrind # spurious autoreduction due to timeout
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
-requires_config_enabled MBEDTLS_AES_C
-requires_config_enabled MBEDTLS_GCM_C
 requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU, simple handshake, nbio (MTU=512)" \
             -p "$P_PXY mtu=512" \
@@ -9866,8 +9854,6 @@
 not_with_valgrind # spurious autoreduction due to timeout
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
-requires_config_enabled MBEDTLS_AES_C
-requires_config_enabled MBEDTLS_GCM_C
 requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU, resumed handshake" \
             -p "$P_PXY mtu=1450" \
@@ -9895,7 +9881,6 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_hash_alg SHA_256
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
-requires_config_enabled MBEDTLS_CHACHAPOLY_C
 requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU, ChachaPoly renego" \
             -p "$P_PXY mtu=512" \
@@ -9909,7 +9894,7 @@
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
              exchanges=2 renegotiation=1 renegotiate=1 \
-             force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
+             force_ciphersuite=TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256 \
              hs_timeout=10000-60000 \
              mtu=512" \
             0 \
@@ -9925,8 +9910,6 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_hash_alg SHA_256
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
-requires_config_enabled MBEDTLS_AES_C
-requires_config_enabled MBEDTLS_GCM_C
 requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU, AES-GCM renego" \
             -p "$P_PXY mtu=512" \
@@ -9956,8 +9939,6 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_hash_alg SHA_256
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
-requires_config_enabled MBEDTLS_AES_C
-requires_config_enabled MBEDTLS_CCM_C
 requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU, AES-CCM renego" \
             -p "$P_PXY mtu=1024" \
@@ -9987,8 +9968,6 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_hash_alg SHA_256
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
-requires_config_enabled MBEDTLS_AES_C
-requires_config_enabled MBEDTLS_CIPHER_MODE_CBC
 requires_config_enabled MBEDTLS_SSL_ENCRYPT_THEN_MAC
 requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU, AES-CBC EtM renego" \
@@ -10019,8 +9998,6 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_hash_alg SHA_256
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
-requires_config_enabled MBEDTLS_AES_C
-requires_config_enabled MBEDTLS_CIPHER_MODE_CBC
 requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU, AES-CBC non-EtM renego" \
             -p "$P_PXY mtu=1024" \
@@ -10046,8 +10023,6 @@
 # Forcing ciphersuite for this test to fit the MTU of 512 with full config.
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
-requires_config_enabled MBEDTLS_AES_C
-requires_config_enabled MBEDTLS_GCM_C
 client_needs_more_time 2
 requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU + 3d" \
@@ -10069,8 +10044,6 @@
 # Forcing ciphersuite for this test to fit the MTU of 512 with full config.
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
-requires_config_enabled MBEDTLS_AES_C
-requires_config_enabled MBEDTLS_GCM_C
 client_needs_more_time 2
 requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU + 3d, nbio" \
diff --git a/tests/suites/host_test.function b/tests/suites/host_test.function
index d8ff49e..cc28697 100644
--- a/tests/suites/host_test.function
+++ b/tests/suites/host_test.function
@@ -772,6 +772,10 @@
     mbedtls_fprintf(stdout, " (%u / %u tests (%u skipped))\n",
                     total_tests - total_errors, total_tests, total_skipped);
 
+#if defined(MBEDTLS_TEST_MUTEX_USAGE)
+    mbedtls_test_mutex_usage_end();
+#endif
+
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
     !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC)
 #if defined(MBEDTLS_MEMORY_DEBUG)
diff --git a/tests/suites/test_suite_aes.function b/tests/suites/test_suite_aes.function
index d495b49..2ca3f7f 100644
--- a/tests/suites/test_suite_aes.function
+++ b/tests/suites/test_suite_aes.function
@@ -6,6 +6,7 @@
  * master, enc and dec must be AES context objects. They don't need to
  * be initialized, and are left freed.
  */
+#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
 static int test_copy(const data_t *key,
                      mbedtls_aes_context *master,
                      mbedtls_aes_context *enc,
@@ -55,6 +56,7 @@
      * with alternative implementations. */
     return 0;
 }
+#endif
 
 /* END_HEADER */
 
@@ -86,7 +88,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
 void aes_decrypt_ecb(data_t *key_str, data_t *src_str,
                      data_t *dst, int setkey_result)
 {
@@ -523,7 +525,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
 void aes_ecb_copy_context(data_t *key)
 {
     /* We test context copying multiple times, with different alignments
diff --git a/tests/suites/test_suite_aria.function b/tests/suites/test_suite_aria.function
index 579dddf..f1748d1 100644
--- a/tests/suites/test_suite_aria.function
+++ b/tests/suites/test_suite_aria.function
@@ -86,7 +86,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
 void aria_decrypt_ecb(data_t *key_str, data_t *src_str,
                       data_t *expected_output, int setkey_result)
 {
diff --git a/tests/suites/test_suite_camellia.function b/tests/suites/test_suite_camellia.function
index 1cef97a..6930679 100644
--- a/tests/suites/test_suite_camellia.function
+++ b/tests/suites/test_suite_camellia.function
@@ -67,7 +67,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
 void camellia_decrypt_ecb(data_t *key_str, data_t *src_str,
                           data_t *dst, int setkey_result)
 {
diff --git a/tests/suites/test_suite_cipher.aes.data b/tests/suites/test_suite_cipher.aes.data
index 92e9cdd..99a662b 100644
--- a/tests/suites/test_suite_cipher.aes.data
+++ b/tests/suites/test_suite_cipher.aes.data
@@ -1595,47 +1595,47 @@
 test_vec_ecb:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_ENCRYPT:"00000000000000000000000000000000":"fffffffffffffffffffffffff8000000":"2ca8209d63274cd9a29bb74bcd77683a":0
 
 AES-128-ECB Decrypt NIST KAT #1
-depends_on:MBEDTLS_AES_C
+depends_on:MBEDTLS_AES_C:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"00000000000000000000000000000000":"db4f1aa530967d6732ce4715eb0ee24b":"ff000000000000000000000000000000":0
 
 AES-128-ECB Decrypt NIST KAT #2
-depends_on:MBEDTLS_AES_C
+depends_on:MBEDTLS_AES_C:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"00000000000000000000000000000000":"a81738252621dd180a34f3455b4baa2f":"ff800000000000000000000000000000":0
 
 AES-128-ECB Decrypt NIST KAT #3
-depends_on:MBEDTLS_AES_C
+depends_on:MBEDTLS_AES_C:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"00000000000000000000000000000000":"77e2b508db7fd89234caf7939ee5621a":"ffc00000000000000000000000000000":0
 
 AES-128-ECB Decrypt NIST KAT #4
-depends_on:MBEDTLS_AES_C
+depends_on:MBEDTLS_AES_C:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"00000000000000000000000000000000":"dc43be40be0e53712f7e2bf5ca707209":"6a118a874519e64e9963798a503f1d35":0
 
 AES-128-ECB Decrypt NIST KAT #5
-depends_on:MBEDTLS_AES_C
+depends_on:MBEDTLS_AES_C:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"00000000000000000000000000000000":"92beedab1895a94faa69b632e5cc47ce":"cb9fceec81286ca3e989bd979b0cb284":0
 
 AES-128-ECB Decrypt NIST KAT #6
-depends_on:MBEDTLS_AES_C
+depends_on:MBEDTLS_AES_C:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"00000000000000000000000000000000":"459264f4798f6a78bacb89c15ed3d601":"b26aeb1874e47ca8358ff22378f09144":0
 
 AES-128-ECB Decrypt NIST KAT #7
-depends_on:MBEDTLS_AES_C
+depends_on:MBEDTLS_AES_C:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"b69418a85332240dc82492353956ae0c":"a303d940ded8f0baff6f75414cac5243":"00000000000000000000000000000000":0
 
 AES-128-ECB Decrypt NIST KAT #8
-depends_on:MBEDTLS_AES_C
+depends_on:MBEDTLS_AES_C:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"71b5c08a1993e1362e4d0ce9b22b78d5":"c2dabd117f8a3ecabfbb11d12194d9d0":"00000000000000000000000000000000":0
 
 AES-128-ECB Decrypt NIST KAT #9
-depends_on:MBEDTLS_AES_C
+depends_on:MBEDTLS_AES_C:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"e234cdca2606b81f29408d5f6da21206":"fff60a4740086b3b9c56195b98d91a7b":"00000000000000000000000000000000":0
 
 AES-128-ECB Decrypt NIST KAT #10
-depends_on:MBEDTLS_AES_C
+depends_on:MBEDTLS_AES_C:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"ffffffffffffffff0000000000000000":"84be19e053635f09f2665e7bae85b42d":"00000000000000000000000000000000":0
 
 AES-128-ECB Decrypt NIST KAT #11
-depends_on:MBEDTLS_AES_C
+depends_on:MBEDTLS_AES_C:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"ffffffffffffffff8000000000000000":"32cd652842926aea4aa6137bb2be2b5e":"00000000000000000000000000000000":0
 
 AES-192-ECB Encrypt NIST KAT #1
@@ -1687,51 +1687,51 @@
 test_vec_ecb:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_ENCRYPT:"fffffffffffffffffffffffffffe00000000000000000000":"00000000000000000000000000000000":"fd5548bcf3f42565f7efa94562528d46":0
 
 AES-192-ECB Decrypt NIST KAT #1
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"fffffffffffffffffffffffffffffffff000000000000000":"bb2852c891c5947d2ed44032c421b85f":"00000000000000000000000000000000":0
 
 AES-192-ECB Decrypt NIST KAT #2
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"fffffffffffffffffffffffffffffffff800000000000000":"1b9f5fbd5e8a4264c0a85b80409afa5e":"00000000000000000000000000000000":0
 
 AES-192-ECB Decrypt NIST KAT #3
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"fffffffffffffffffffffffffffffffffc00000000000000":"30dab809f85a917fe924733f424ac589":"00000000000000000000000000000000":0
 
 AES-192-ECB Decrypt NIST KAT #4
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"61257134a518a0d57d9d244d45f6498cbc32f2bafc522d79":"cfe4d74002696ccf7d87b14a2f9cafc9":"00000000000000000000000000000000":0
 
 AES-192-ECB Decrypt NIST KAT #5
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"b0ab0a6a818baef2d11fa33eac947284fb7d748cfb75e570":"d2eafd86f63b109b91f5dbb3a3fb7e13":"00000000000000000000000000000000":0
 
 AES-192-ECB Decrypt NIST KAT #6
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"ee053aa011c8b428cdcc3636313c54d6a03cac01c71579d6":"9b9fdd1c5975655f539998b306a324af":"00000000000000000000000000000000":0
 
 AES-192-ECB Decrypt NIST KAT #7
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"000000000000000000000000000000000000000000000000":"275cfc0413d8ccb70513c3859b1d0f72":"1b077a6af4b7f98229de786d7516b639":0
 
 AES-192-ECB Decrypt NIST KAT #8
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"000000000000000000000000000000000000000000000000":"c9b8135ff1b5adc413dfd053b21bd96d":"9c2d8842e5f48f57648205d39a239af1":0
 
 AES-192-ECB Decrypt NIST KAT #9
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"000000000000000000000000000000000000000000000000":"4a3650c3371ce2eb35e389a171427440":"bff52510095f518ecca60af4205444bb":0
 
 AES-192-ECB Decrypt NIST KAT #10
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"000000000000000000000000000000000000000000000000":"b2099795e88cc158fd75ea133d7e7fbe":"ffffffffffffffffffffc00000000000":0
 
 AES-192-ECB Decrypt NIST KAT #11
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"000000000000000000000000000000000000000000000000":"a6cae46fb6fadfe7a2c302a34242817b":"ffffffffffffffffffffe00000000000":0
 
 AES-192-ECB Decrypt NIST KAT #12
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"000000000000000000000000000000000000000000000000":"026a7024d6a902e0b3ffccbaa910cc3f":"fffffffffffffffffffff00000000000":0
 
 AES-256-ECB Encrypt NIST KAT #1
@@ -1783,51 +1783,51 @@
 test_vec_ecb:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_ENCRYPT:"ffffffffffffffffffffffffffffffffffffe000000000000000000000000000":"00000000000000000000000000000000":"dcf4e129136c1a4b7a0f38935cc34b2b":0
 
 AES-256-ECB Decrypt NIST KAT #1
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"fffffffffffffffffffffffffffffffffffffffffffffff00000000000000000":"edf61ae362e882ddc0167474a7a77f3a":"00000000000000000000000000000000":0
 
 AES-256-ECB Decrypt NIST KAT #2
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"fffffffffffffffffffffffffffffffffffffffffffffff80000000000000000":"6168b00ba7859e0970ecfd757efecf7c":"00000000000000000000000000000000":0
 
 AES-256-ECB Decrypt NIST KAT #3
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"fffffffffffffffffffffffffffffffffffffffffffffffc0000000000000000":"d1415447866230d28bb1ea18a4cdfd02":"00000000000000000000000000000000":0
 
 AES-256-ECB Decrypt NIST KAT #4
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"f8be9ba615c5a952cabbca24f68f8593039624d524c816acda2c9183bd917cb9":"a3944b95ca0b52043584ef02151926a8":"00000000000000000000000000000000":0
 
 AES-256-ECB Decrypt NIST KAT #5
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"797f8b3d176dac5b7e34a2d539c4ef367a16f8635f6264737591c5c07bf57a3e":"a74289fe73a4c123ca189ea1e1b49ad5":"00000000000000000000000000000000":0
 
 AES-256-ECB Decrypt NIST KAT #6
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"6838d40caf927749c13f0329d331f448e202c73ef52c5f73a37ca635d4c47707":"b91d4ea4488644b56cf0812fa7fcf5fc":"00000000000000000000000000000000":0
 
 AES-256-ECB Decrypt NIST KAT #7
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"623a52fcea5d443e48d9181ab32c7421":"761c1fe41a18acf20d241650611d90f1":0
 
 AES-256-ECB Decrypt NIST KAT #8
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"38f2c7ae10612415d27ca190d27da8b4":"8a560769d605868ad80d819bdba03771":0
 
 AES-256-ECB Decrypt NIST KAT #9
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"1bc704f1bce135ceb810341b216d7abe":"91fbef2d15a97816060bee1feaa49afe":0
 
 AES-256-ECB Decrypt NIST KAT #10
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"ddc6bf790c15760d8d9aeb6f9a75fd4e":"80000000000000000000000000000000":0
 
 AES-256-ECB Decrypt NIST KAT #11
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"0a6bdc6d4c1e6280301fd8e97ddbe601":"c0000000000000000000000000000000":0
 
 AES-256-ECB Decrypt NIST KAT #12
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_ecb:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"9b80eefb7ebe2d2b16247aa0efc72f5d":"e0000000000000000000000000000000":0
 
 AES-128-ECB crypt Encrypt NIST KAT #1
@@ -1843,15 +1843,15 @@
 test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_ENCRYPT:"00000000000000000000000000000000":"":"ffffffffffffffc00000000000000000":"3a4d354f02bb5a5e47d39666867f246a":0:0
 
 AES-128-ECB crypt Decrypt NIST KAT #1
-depends_on:MBEDTLS_AES_C
+depends_on:MBEDTLS_AES_C:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"00000000000000000000000000000000":"":"db4f1aa530967d6732ce4715eb0ee24b":"ff000000000000000000000000000000":0:0
 
 AES-128-ECB crypt Decrypt NIST KAT #2
-depends_on:MBEDTLS_AES_C
+depends_on:MBEDTLS_AES_C:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"b69418a85332240dc82492353956ae0c":"":"a303d940ded8f0baff6f75414cac5243":"00000000000000000000000000000000":0:0
 
 AES-128-ECB crypt Decrypt NIST KAT #3
-depends_on:MBEDTLS_AES_C
+depends_on:MBEDTLS_AES_C:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"ffffffffffffffff8000000000000000":"":"32cd652842926aea4aa6137bb2be2b5e":"00000000000000000000000000000000":0:0
 
 AES-192-ECB crypt Encrypt NIST KAT #1
@@ -1871,19 +1871,19 @@
 test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_ENCRYPT:"fffffffffffffffffffffffffff800000000000000000000":"":"00000000000000000000000000000000":"8dd274bd0f1b58ae345d9e7233f9b8f3":0:0
 
 AES-192-ECB crypt Decrypt NIST KAT #1
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"fffffffffffffffffffffffffffffffff000000000000000":"":"bb2852c891c5947d2ed44032c421b85f":"00000000000000000000000000000000":0:0
 
 AES-192-ECB crypt Decrypt NIST KAT #2
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"61257134a518a0d57d9d244d45f6498cbc32f2bafc522d79":"":"cfe4d74002696ccf7d87b14a2f9cafc9":"00000000000000000000000000000000":0:0
 
 AES-192-ECB crypt Decrypt NIST KAT #3
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"000000000000000000000000000000000000000000000000":"":"275cfc0413d8ccb70513c3859b1d0f72":"1b077a6af4b7f98229de786d7516b639":0:0
 
 AES-192-ECB crypt Decrypt NIST KAT #4
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"000000000000000000000000000000000000000000000000":"":"b2099795e88cc158fd75ea133d7e7fbe":"ffffffffffffffffffffc00000000000":0:0
 
 AES-256-ECB crypt Encrypt NIST KAT #1
@@ -1903,19 +1903,19 @@
 test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_ENCRYPT:"ffffffffffffffffffffffffffffffffffff8000000000000000000000000000":"":"00000000000000000000000000000000":"45d089c36d5c5a4efc689e3b0de10dd5":0:0
 
 AES-256-ECB crypt Decrypt NIST KAT #1
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"fffffffffffffffffffffffffffffffffffffffffffffff00000000000000000":"":"edf61ae362e882ddc0167474a7a77f3a":"00000000000000000000000000000000":0:0
 
 AES-256-ECB crypt Decrypt NIST KAT #2
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"f8be9ba615c5a952cabbca24f68f8593039624d524c816acda2c9183bd917cb9":"":"a3944b95ca0b52043584ef02151926a8":"00000000000000000000000000000000":0:0
 
 AES-256-ECB crypt Decrypt NIST KAT #3
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"":"623a52fcea5d443e48d9181ab32c7421":"761c1fe41a18acf20d241650611d90f1":0:0
 
 AES-256-ECB crypt Decrypt NIST KAT #4
-depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_AES_C:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"":"ddc6bf790c15760d8d9aeb6f9a75fd4e":"80000000000000000000000000000000":0:0
 
 AES-128-CBC crypt Encrypt NIST KAT #1
@@ -2127,19 +2127,19 @@
 test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_ENCRYPT:"00000000000000000000000000000000":"":"f34481ec3cc627bacd5dc3fb08f273e6":"0336763e966d92595a567cc9ce537f5e":0:1
 
 AES-128-ECB crypt Decrypt NIST KAT #1 PSA
-depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"00000000000000000000000000000000":"":"3ad78e726c1ec02b7ebfe92b23d9ec34":"80000000000000000000000000000000":0:1
 
 AES-128-ECB crypt Decrypt NIST KAT #2 PSA
-depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"ffffc000000000000000000000000000":"":"df556a33438db87bc41b1752c55e5e49":"00000000000000000000000000000000":0:1
 
 AES-128-ECB crypt Decrypt NIST KAT #3 PSA
-depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"10a58869d74be5a374cf867cfb473859":"":"6d251e6944b051e04eaa6fb4dbf78465":"00000000000000000000000000000000":0:1
 
 AES-128-ECB crypt Decrypt NIST KAT #4 PSA
-depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"00000000000000000000000000000000":"":"0336763e966d92595a567cc9ce537f5e":"f34481ec3cc627bacd5dc3fb08f273e6":0:1
 
 AES-192-ECB crypt Encrypt NIST KAT #1 PSA
@@ -2159,19 +2159,19 @@
 test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_ENCRYPT:"000000000000000000000000000000000000000000000000":"":"1b077a6af4b7f98229de786d7516b639":"275cfc0413d8ccb70513c3859b1d0f72":0:1
 
 AES-192-ECB crypt Decrypt NIST KAT #1 PSA
-depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"000000000000000000000000000000000000000000000000":"":"6cd02513e8d4dc986b4afe087a60bd0c":"80000000000000000000000000000000":0:1
 
 AES-192-ECB crypt Decrypt NIST KAT #2 PSA
-depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"ffe000000000000000000000000000000000000000000000":"":"7ababc4b3f516c9aafb35f4140b548f9":"00000000000000000000000000000000":0:1
 
 AES-192-ECB crypt Decrypt NIST KAT #3 PSA
-depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"e9f065d7c13573587f7875357dfbb16c53489f6a4bd0f7cd":"":"0956259c9cd5cfd0181cca53380cde06":"00000000000000000000000000000000":0:1
 
 AES-192-ECB crypt Decrypt NIST KAT #4 PSA
-depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"000000000000000000000000000000000000000000000000":"":"275cfc0413d8ccb70513c3859b1d0f72":"1b077a6af4b7f98229de786d7516b639":0:1
 
 AES-256-ECB crypt Encrypt NIST KAT #1 PSA
@@ -2191,19 +2191,19 @@
 test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_ENCRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"":"014730f80ac625fe84f026c60bfd547d":"5c9d844ed46f9885085e5d6a4f94c7d7":0:1
 
 AES-256-ECB crypt Decrypt NIST KAT #1 PSA
-depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"":"ddc6bf790c15760d8d9aeb6f9a75fd4e":"80000000000000000000000000000000":0:1
 
 AES-256-ECB crypt Decrypt NIST KAT #2 PSA
-depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"ffe0000000000000000000000000000000000000000000000000000000000000":"":"d1ccb9b1337002cbac42c520b5d67722":"00000000000000000000000000000000":0:1
 
 AES-256-ECB crypt Decrypt NIST KAT #3 PSA
-depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"c47b0294dbbbee0fec4757f22ffeee3587ca4730c3d33b691df38bab076bc558":"":"46f2fb342d6f0ab477476fc501242c5f":"00000000000000000000000000000000":0:1
 
 AES-256-ECB crypt Decrypt NIST KAT #4 PSA
-depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_ECB_NO_PADDING:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"":"5c9d844ed46f9885085e5d6a4f94c7d7":"014730f80ac625fe84f026c60bfd547d":0:1
 
 AES-128-CCM*-NO-TAG crypt Encrypt NIST VPT AES-128 #15
diff --git a/tests/suites/test_suite_pkparse.data b/tests/suites/test_suite_pkparse.data
index f82dcb5..7173511 100644
--- a/tests/suites/test_suite_pkparse.data
+++ b/tests/suites/test_suite_pkparse.data
@@ -1,77 +1,77 @@
 Parse RSA Key #1 (No password when required)
-depends_on:MBEDTLS_HAS_MD5_VIA_LOWLEVEL_OR_PSA :MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C
 pk_parse_keyfile_rsa:"data_files/test-ca.key":"NULL":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
 
 Parse RSA Key #2 (Correct password)
-depends_on:MBEDTLS_HAS_MD5_VIA_LOWLEVEL_OR_PSA :MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C
 pk_parse_keyfile_rsa:"data_files/test-ca.key":"PolarSSLTest":0
 
 Parse RSA Key #3 (Wrong password)
-depends_on:MBEDTLS_HAS_MD5_VIA_LOWLEVEL_OR_PSA :MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C
 pk_parse_keyfile_rsa:"data_files/test-ca.key":"PolarSSLWRONG":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
 
 Parse RSA Key #4 (DES Encrypted)
-depends_on:MBEDTLS_HAS_MD5_VIA_LOWLEVEL_OR_PSA :MBEDTLS_DES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_DES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC
 pk_parse_keyfile_rsa:"data_files/rsa_pkcs1_1024_des.pem":"testkey":0
 
 Parse RSA Key #5 (3DES Encrypted)
-depends_on:MBEDTLS_HAS_MD5_VIA_LOWLEVEL_OR_PSA :MBEDTLS_DES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_DES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC
 pk_parse_keyfile_rsa:"data_files/rsa_pkcs1_1024_3des.pem":"testkey":0
 
 Parse RSA Key #6 (AES-128 Encrypted)
-depends_on:MBEDTLS_HAS_MD5_VIA_LOWLEVEL_OR_PSA :MBEDTLS_AES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_AES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC
 pk_parse_keyfile_rsa:"data_files/rsa_pkcs1_1024_aes128.pem":"testkey":0
 
 Parse RSA Key #7 (AES-192 Encrypted)
-depends_on:MBEDTLS_HAS_MD5_VIA_LOWLEVEL_OR_PSA :MBEDTLS_AES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_AES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
 pk_parse_keyfile_rsa:"data_files/rsa_pkcs1_1024_aes192.pem":"testkey":0
 
 Parse RSA Key #8 (AES-256 Encrypted)
-depends_on:MBEDTLS_HAS_MD5_VIA_LOWLEVEL_OR_PSA :MBEDTLS_AES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_AES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
 pk_parse_keyfile_rsa:"data_files/rsa_pkcs1_1024_aes256.pem":"testkey":0
 
 Parse RSA Key #9 (2048-bit, DES Encrypted)
-depends_on:MBEDTLS_HAS_MD5_VIA_LOWLEVEL_OR_PSA :MBEDTLS_DES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_DES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC
 pk_parse_keyfile_rsa:"data_files/rsa_pkcs1_2048_des.pem":"testkey":0
 
 Parse RSA Key #10 (2048-bit, 3DES Encrypted)
-depends_on:MBEDTLS_HAS_MD5_VIA_LOWLEVEL_OR_PSA :MBEDTLS_DES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_DES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC
 pk_parse_keyfile_rsa:"data_files/rsa_pkcs1_2048_3des.pem":"testkey":0
 
 Parse RSA Key #11 (2048-bit, AES-128 Encrypted)
-depends_on:MBEDTLS_HAS_MD5_VIA_LOWLEVEL_OR_PSA :MBEDTLS_AES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_AES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC
 pk_parse_keyfile_rsa:"data_files/rsa_pkcs1_2048_aes128.pem":"testkey":0
 
 Parse RSA Key #12 (2048-bit, AES-192 Encrypted)
-depends_on:MBEDTLS_HAS_MD5_VIA_LOWLEVEL_OR_PSA :MBEDTLS_AES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_AES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
 pk_parse_keyfile_rsa:"data_files/rsa_pkcs1_2048_aes192.pem":"testkey":0
 
 Parse RSA Key #13 (2048-bit, AES-256 Encrypted)
-depends_on:MBEDTLS_HAS_MD5_VIA_LOWLEVEL_OR_PSA :MBEDTLS_AES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_AES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
 pk_parse_keyfile_rsa:"data_files/rsa_pkcs1_2048_aes256.pem":"testkey":0
 
 Parse RSA Key #14 (4096-bit, DES Encrypted)
-depends_on:MBEDTLS_HAS_MD5_VIA_LOWLEVEL_OR_PSA :MBEDTLS_DES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_DES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC
 pk_parse_keyfile_rsa:"data_files/rsa_pkcs1_4096_des.pem":"testkey":0
 
 Parse RSA Key #15 (4096-bit, 3DES Encrypted)
-depends_on:MBEDTLS_HAS_MD5_VIA_LOWLEVEL_OR_PSA :MBEDTLS_DES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_DES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC
 pk_parse_keyfile_rsa:"data_files/rsa_pkcs1_4096_3des.pem":"testkey":0
 
 Parse RSA Key #16 (4096-bit, AES-128 Encrypted)
-depends_on:MBEDTLS_HAS_MD5_VIA_LOWLEVEL_OR_PSA :MBEDTLS_AES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_AES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC
 pk_parse_keyfile_rsa:"data_files/rsa_pkcs1_4096_aes128.pem":"testkey":0
 
 Parse RSA Key #17 (4096-bit, AES-192 Encrypted)
-depends_on:MBEDTLS_HAS_MD5_VIA_LOWLEVEL_OR_PSA :MBEDTLS_AES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_AES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
 pk_parse_keyfile_rsa:"data_files/rsa_pkcs1_4096_aes192.pem":"testkey":0
 
 Parse RSA Key #18 (4096-bit, AES-256 Encrypted)
-depends_on:MBEDTLS_HAS_MD5_VIA_LOWLEVEL_OR_PSA :MBEDTLS_AES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_AES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
 pk_parse_keyfile_rsa:"data_files/rsa_pkcs1_4096_aes256.pem":"testkey":0
 
 Parse RSA Key #19 (PKCS#8 wrapped)
-depends_on:MBEDTLS_HAS_MD5_VIA_LOWLEVEL_OR_PSA :MBEDTLS_PEM_PARSE_C
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_PEM_PARSE_C
 pk_parse_keyfile_rsa:"data_files/format_gen.key":"":0
 
 Parse RSA Key #20 (PKCS#8 encrypted SHA1-3DES)
@@ -1003,7 +1003,7 @@
 pk_parse_keyfile_ec:"data_files/ec_prv.sec1.comp.pem":"NULL":0
 
 Parse EC Key #3 (SEC1 PEM encrypted)
-depends_on:MBEDTLS_DES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_HAVE_SECP192R1:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_MD5_VIA_LOWLEVEL_OR_PSA
+depends_on:MBEDTLS_DES_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_HAVE_SECP192R1:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD_CAN_MD5
 pk_parse_keyfile_ec:"data_files/ec_prv.sec1.pw.pem":"polar":0
 
 Parse EC Key #4 (PKCS8 DER)
diff --git a/tests/suites/test_suite_pkparse.function b/tests/suites/test_suite_pkparse.function
index 64a3175..d416b87 100644
--- a/tests/suites/test_suite_pkparse.function
+++ b/tests/suites/test_suite_pkparse.function
@@ -34,13 +34,13 @@
     res = mbedtls_pk_parse_keyfile(&ctx, key_file, pwd,
                                    mbedtls_test_rnd_std_rand, NULL);
 
-    TEST_ASSERT(res == result);
+    TEST_EQUAL(res, result);
 
     if (res == 0) {
         mbedtls_rsa_context *rsa;
         TEST_ASSERT(mbedtls_pk_can_do(&ctx, MBEDTLS_PK_RSA));
         rsa = mbedtls_pk_rsa(ctx);
-        TEST_ASSERT(mbedtls_rsa_check_privkey(rsa) == 0);
+        TEST_EQUAL(mbedtls_rsa_check_privkey(rsa), 0);
     }
 
 exit:
@@ -61,13 +61,13 @@
 
     res = mbedtls_pk_parse_public_keyfile(&ctx, key_file);
 
-    TEST_ASSERT(res == result);
+    TEST_EQUAL(res, result);
 
     if (res == 0) {
         mbedtls_rsa_context *rsa;
         TEST_ASSERT(mbedtls_pk_can_do(&ctx, MBEDTLS_PK_RSA));
         rsa = mbedtls_pk_rsa(ctx);
-        TEST_ASSERT(mbedtls_rsa_check_pubkey(rsa) == 0);
+        TEST_EQUAL(mbedtls_rsa_check_pubkey(rsa), 0);
     }
 
 exit:
@@ -83,11 +83,11 @@
     int res;
 
     mbedtls_pk_init(&ctx);
-    USE_PSA_INIT();
+    MD_OR_USE_PSA_INIT();
 
     res = mbedtls_pk_parse_public_keyfile(&ctx, key_file);
 
-    TEST_ASSERT(res == result);
+    TEST_EQUAL(res, result);
 
     if (res == 0) {
         TEST_ASSERT(mbedtls_pk_can_do(&ctx, MBEDTLS_PK_ECKEY));
@@ -98,13 +98,13 @@
 #else
         const mbedtls_ecp_keypair *eckey;
         eckey = mbedtls_pk_ec_ro(ctx);
-        TEST_ASSERT(mbedtls_ecp_check_pubkey(&eckey->grp, &eckey->Q) == 0);
+        TEST_EQUAL(mbedtls_ecp_check_pubkey(&eckey->grp, &eckey->Q), 0);
 #endif
     }
 
 exit:
     mbedtls_pk_free(&ctx);
-    USE_PSA_DONE();
+    MD_OR_USE_PSA_DONE();
 }
 /* END_CASE */
 
@@ -115,18 +115,18 @@
     int res;
 
     mbedtls_pk_init(&ctx);
-    USE_PSA_INIT();
+    MD_OR_USE_PSA_INIT();
 
     res = mbedtls_pk_parse_keyfile(&ctx, key_file, password,
                                    mbedtls_test_rnd_std_rand, NULL);
 
-    TEST_ASSERT(res == result);
+    TEST_EQUAL(res, result);
 
     if (res == 0) {
         TEST_ASSERT(mbedtls_pk_can_do(&ctx, MBEDTLS_PK_ECKEY));
 #if defined(MBEDTLS_ECP_C)
         const mbedtls_ecp_keypair *eckey = mbedtls_pk_ec_ro(ctx);
-        TEST_ASSERT(mbedtls_ecp_check_privkey(&eckey->grp, &eckey->d) == 0);
+        TEST_EQUAL(mbedtls_ecp_check_privkey(&eckey->grp, &eckey->d), 0);
 #else
         /* PSA keys are already checked on import so nothing to do here. */
 #endif
@@ -134,7 +134,7 @@
 
 exit:
     mbedtls_pk_free(&ctx);
-    USE_PSA_DONE();
+    MD_OR_USE_PSA_DONE();
 }
 /* END_CASE */
 
diff --git a/tests/suites/test_suite_platform.data b/tests/suites/test_suite_platform.data
index 4d57450..653d254 100644
--- a/tests/suites/test_suite_platform.data
+++ b/tests/suites/test_suite_platform.data
@@ -6,4 +6,10 @@
 time_get_seconds:
 
 Check mbedtls_calloc overallocation
+# This test case exercises an integer overflow in calloc. Under Asan, with
+# a modern Clang, this triggers an ASan/MSan/TSan complaint. The complaint
+# can be avoided with e.g. ASAN_OPTIONS=allocator_may_return_null=1,
+# but this has to be set in the environment before the program starts,
+# and could hide other errors.
+depends_on:!MBEDTLS_TEST_HAVE_ASAN:!MBEDTLS_TEST_HAVE_MSAN:!MBEDTLS_TEST_HAVE_TSAN
 check_mbedtls_calloc_overallocation:SIZE_MAX/2:SIZE_MAX/2
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index c7aab88..e239a44 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -2267,15 +2267,15 @@
 cipher_encrypt_fail:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee223":PSA_ERROR_INVALID_ARGUMENT
 
 PSA symmetric encrypt: AES-ECB, 0 bytes, good
-depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 cipher_alg_without_iv:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":""
 
 PSA symmetric encrypt: AES-ECB, 16 bytes, good
-depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 cipher_alg_without_iv:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a":"3ad77bb40d7a3660a89ecaf32466ef97"
 
 PSA symmetric encrypt: AES-ECB, 32 bytes, good
-depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 cipher_alg_without_iv:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a3ad77bb40d7a3660a89ecaf32466ef97":"3ad77bb40d7a3660a89ecaf32466ef972249a2638c6f1c755a84f9681a9f08c1"
 
 PSA symmetric encrypt: 2-key 3DES-ECB, 8 bytes, good
@@ -2411,7 +2411,7 @@
 cipher_decrypt_fail:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":PSA_ERROR_INVALID_ARGUMENT
 
 PSA symmetric decrypt: AES-ECB, input too short (15 bytes)
-depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 cipher_decrypt_fail:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"396ee84fb75fdbb5c2b13c7fe5a654":PSA_ERROR_INVALID_ARGUMENT
 
 PSA symmetric decrypt: AES-CBC-nopad, input too short (5 bytes)
@@ -2423,15 +2423,15 @@
 cipher_decrypt_fail:PSA_ALG_CCM_STAR_NO_TAG:PSA_KEY_TYPE_AES:"19ebfde2d5468ba0a3031bde629b11fd":"5a8aa485c316e9":"2a2a2a2a2a2a2a2a":PSA_ERROR_INVALID_ARGUMENT
 
 PSA symmetric decrypt: AES-ECB, 0 bytes, good
-depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 cipher_decrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"":""
 
 PSA symmetric decrypt: AES-ECB, 16 bytes, good
-depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 cipher_decrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"396ee84fb75fdbb5c2b13c7fe5a654aa":"63cecc46a382414d5fa7d2b79387437f"
 
 PSA symmetric decrypt: AES-ECB, 32 bytes, good
-depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 cipher_decrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"3ad77bb40d7a3660a89ecaf32466ef972249a2638c6f1c755a84f9681a9f08c1":"6bc1bee22e409f96e93d7e117393172a3ad77bb40d7a3660a89ecaf32466ef97"
 
 PSA symmetric decrypt: AES-CBC-nopad, 16 bytes, good
@@ -2487,15 +2487,15 @@
 cipher_decrypt:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f":"000000000000004a00000000":"fb6d7b60e9e67669b607a9b94a606bdca678d44f0ebf24cbd623efd69cc2bdc0f615ac19d0366a8d00e3d6728f5ee01d61d74ab77edc17a7621f2268eea12e656e2e359a2568f98041ba0728dd0d6981e97e7aec1d4360c20a27afccfd9fae0bf91b65c5524733ab8f593dabcd62b3571639d624e65152ab8f530c359f0861d807ca0dbf500d6a6156a38e088a22b65e52bc514d16ccf806818ce91ab77937365af90bbf74a35be6b40b8eedf2785e42874d":"546865205246432037353339207465737420766563746f72207573657320636f756e7465723d312c2062757420505341207573657320636f756e7465723d302e4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e"
 
 PSA symmetric decrypt multipart: AES-ECB, 0 bytes, good
-depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"":0:0:0:"":PSA_SUCCESS
 
 PSA symmetric decrypt multipart: AES-ECB, 16 bytes, good
-depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"396ee84fb75fdbb5c2b13c7fe5a654aa":16:16:0:"63cecc46a382414d5fa7d2b79387437f":PSA_SUCCESS
 
 PSA symmetric decrypt multipart: AES-ECB, 32 bytes, good
-depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"3ad77bb40d7a3660a89ecaf32466ef972249a2638c6f1c755a84f9681a9f08c1":32:32:0:"6bc1bee22e409f96e93d7e117393172a3ad77bb40d7a3660a89ecaf32466ef97":PSA_SUCCESS
 
 PSA symmetric decrypt multipart: AES-CBC-nopad, 16 bytes, good
@@ -2519,7 +2519,7 @@
 cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"396ee84fb75fdbb5c2b13c7fe5a654aa":16:16:0:"dd3b5e5319b7591daab1e1a92687feb2":PSA_SUCCESS
 
 PSA symmetric decrypt multipart: AES-ECB, input too short (15 bytes)
-depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"396ee84fb75fdbb5c2b13c7fe5a654":0:0:0:"63cecc46a382414d5fa7d2b7938743":PSA_ERROR_INVALID_ARGUMENT
 
 PSA symmetric decrypt multipart: AES-CBC-nopad, input too short (5 bytes)
@@ -2551,7 +2551,7 @@
 cipher_decrypt_multipart:PSA_ALG_CCM_STAR_NO_TAG:PSA_KEY_TYPE_AES:"197afb02ffbd8f699dacae87094d5243":"5a8aa485c316e9403aff859fbb":"4a550134f94455979ec4bf89ad2bd80d25a77ae94e456134":10:10:14:"a16a2e741f1cd9717285b6d882c1fc53655e9773761ad697":PSA_SUCCESS
 
 PSA symmetric encrypt/decrypt: AES-ECB, 16 bytes, good
-depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 cipher_verify_output:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a"
 
 PSA symmetric encrypt/decrypt: AES-CBC-nopad, 16 bytes, good
@@ -2663,15 +2663,15 @@
 cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":16:16:0:"8f9408fe80a81d3e813da3c7b0b2bd32":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-ECB, 16+16 bytes
-depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"3ad77bb40d7a3660a89ecaf32466ef9755ed5e9e066820fa52c729886d18854c":16:16:16:"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-ECB, 11+21 bytes
-depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"3ad77bb40d7a3660a89ecaf32466ef9755ed5e9e066820fa52c729886d18854c":11:0:32:"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-ECB, 28+4 bytes
-depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"3ad77bb40d7a3660a89ecaf32466ef9755ed5e9e066820fa52c729886d18854c":28:16:16:"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CBC-nopad, 7+9 bytes
@@ -2735,7 +2735,7 @@
 cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":16:16:0:"8f9408fe80a81d3e813da3c7b0b2bd32":PSA_SUCCESS
 
 PSA symmetric encrypt/decrypt multipart: AES-ECB, 16 bytes, good
-depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
 cipher_verify_output_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a":16
 
 PSA symmetric encrypt/decrypt multipart: AES-CBC-nopad, 16 bytes, good
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index 85776cc..05571a1 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -1145,21 +1145,21 @@
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
-void ssl_set_hostname_twice(char *hostname0, char *hostname1)
+void ssl_set_hostname_twice(char *input_hostname0, char *input_hostname1)
 {
-    const char *hostname;
+    const char *output_hostname;
     mbedtls_ssl_context ssl;
 
     mbedtls_ssl_init(&ssl);
     USE_PSA_INIT();
 
-    TEST_ASSERT(mbedtls_ssl_set_hostname(&ssl, hostname0) == 0);
-    hostname = mbedtls_ssl_get_hostname(&ssl);
-    TEST_ASSERT(strcmp(hostname0, hostname) == 0);
+    TEST_ASSERT(mbedtls_ssl_set_hostname(&ssl, input_hostname0) == 0);
+    output_hostname = mbedtls_ssl_get_hostname(&ssl);
+    TEST_ASSERT(strcmp(input_hostname0, output_hostname) == 0);
 
-    TEST_ASSERT(mbedtls_ssl_set_hostname(&ssl, hostname1) == 0);
-    hostname = mbedtls_ssl_get_hostname(&ssl);
-    TEST_ASSERT(strcmp(hostname1, hostname) == 0);
+    TEST_ASSERT(mbedtls_ssl_set_hostname(&ssl, input_hostname1) == 0);
+    output_hostname = mbedtls_ssl_get_hostname(&ssl);
+    TEST_ASSERT(strcmp(input_hostname1, output_hostname) == 0);
 
 exit:
     mbedtls_ssl_free(&ssl);